Bug 1023336, part 2 - Use the new BufferSizeFromStrideAndHeight helper where appropriate in Moz2D code. r=Bas

This commit is contained in:
Jonathan Watt 2014-06-13 22:03:52 +01:00
parent 5792c05685
commit 5aec590cc0
6 changed files with 103 additions and 28 deletions

View File

@ -4,7 +4,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/gfx/Blur.h"
#include "Blur.h"
#include <algorithm>
#include <math.h>
@ -14,6 +14,7 @@
#include "mozilla/Constants.h"
#include "2D.h"
#include "DataSurfaceHelpers.h"
#include "Tools.h"
using namespace std;
@ -383,9 +384,9 @@ AlphaBoxBlur::AlphaBoxBlur(const Rect& aRect,
// We need to leave room for an additional 3 bytes for a potential overrun
// in our blurring code.
CheckedInt<int32_t> size = CheckedInt<int32_t>(mStride) * mRect.height + 3;
if (size.isValid()) {
mSurfaceAllocationSize = size.value();
size_t size = BufferSizeFromStrideAndHeight(mStride, mRect.height, 3);
if (size != 0) {
mSurfaceAllocationSize = size;
}
}
}
@ -403,9 +404,9 @@ AlphaBoxBlur::AlphaBoxBlur(const Rect& aRect,
{
IntRect intRect;
if (aRect.ToIntRect(&intRect)) {
CheckedInt<int32_t> minDataSize = CheckedInt<int32_t>(intRect.width)*intRect.height;
if (minDataSize.isValid()) {
mSurfaceAllocationSize = minDataSize.value();
size_t minDataSize = BufferSizeFromStrideAndHeight(intRect.width, intRect.height);
if (minDataSize != 0) {
mSurfaceAllocationSize = minDataSize;
}
}
}
@ -528,7 +529,13 @@ AlphaBoxBlur::Blur(uint8_t* aData)
// We need to leave room for an additional 12 bytes for a maximum overrun
// of 3 pixels in the blurring code.
AlignedArray<uint32_t> integralImage((integralImageStride / 4) * integralImageSize.height + 12);
size_t bufLen = BufferSizeFromStrideAndHeight(integralImageStride, integralImageSize.height, 12);
if (bufLen == 0) {
return;
}
// bufLen is a byte count, but here we want a multiple of 32-bit ints, so
// we divide by 4.
AlignedArray<uint32_t> integralImage((bufLen / 4) + ((bufLen % 4) ? 1 : 0));
if (!integralImage) {
return;

View File

@ -37,6 +37,8 @@ CopySurfaceDataToPackedArray(uint8_t* aSrc, uint8_t* aDst, IntSize aSrcSize,
{
MOZ_ASSERT(aBytesPerPixel > 0,
"Negative stride for aDst not currently supported");
MOZ_ASSERT(BufferSizeFromStrideAndHeight(aSrcStride, aSrcSize.height) > 0,
"How did we end up with a surface with such a big buffer?");
int packedStride = aSrcSize.width * aBytesPerPixel;

View File

@ -3,7 +3,9 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "BorrowedContext.h"
#include "DataSurfaceHelpers.h"
#include "DrawTargetCG.h"
#include "Logging.h"
#include "SourceSurfaceCG.h"
#include "Rect.h"
#include "ScaledFontMac.h"
@ -13,6 +15,7 @@
#include "MacIOSurface.h"
#include "FilterNodeSoftware.h"
#include "mozilla/Assertions.h"
#include "mozilla/Types.h" // for decltype
#include "mozilla/FloatingPoint.h"
using namespace std;
@ -1297,6 +1300,7 @@ DrawTargetCG::Init(BackendType aType,
// 32767 is the maximum size supported by cairo
// we clamp to that to make it easier to interoperate
aSize.width > 32767 || aSize.height > 32767) {
gfxWarning() << "Failed to Init() DrawTargetCG because of bad size.";
mColorSpace = nullptr;
mCg = nullptr;
return false;
@ -1309,9 +1313,17 @@ DrawTargetCG::Init(BackendType aType,
if (aData == nullptr && aType != BackendType::COREGRAPHICS_ACCELERATED) {
// XXX: Currently, Init implicitly clears, that can often be a waste of time
mData.Realloc(aStride * aSize.height);
size_t bufLen = BufferSizeFromStrideAndHeight(aStride, aSize.height);
if (bufLen == 0) {
mColorSpace = nullptr;
mCg = nullptr;
return false;
}
static_assert(sizeof(decltype(mData[0])) == 1,
"mData.Realloc() takes an object count, so its objects must be 1-byte sized if we use bufLen");
mData.Realloc(/* actually an object count */ bufLen);
aData = static_cast<unsigned char*>(mData);
memset(aData, 0, aStride * aSize.height);
memset(aData, 0, bufLen);
}
mSize = aSize;

View File

@ -5,6 +5,7 @@
#include "ImageScaling.h"
#include "2D.h"
#include "DataSurfaceHelpers.h"
#include <math.h>
#include <algorithm>
@ -77,7 +78,13 @@ ImageHalfScaler::ScaleForSize(const IntSize &aSize)
delete [] mDataStorage;
// Allocate 15 bytes extra to make sure we can get 16 byte alignment. We
// should add tools for this, see bug 751696.
mDataStorage = new uint8_t[internalSurfSize.height * mStride + 15];
size_t bufLen = BufferSizeFromStrideAndHeight(mStride, internalSurfSize.height, 15);
if (bufLen == 0) {
mSize.SizeTo(0, 0);
mDataStorage = nullptr;
return;
}
mDataStorage = new uint8_t[bufLen];
if (uintptr_t(mDataStorage) % 16) {
// Our storage does not start at a 16-byte boundary. Make sure mData does!

View File

@ -6,6 +6,8 @@
#include "SourceSurfaceCG.h"
#include "DrawTargetCG.h"
#include "DataSourceSurfaceWrapper.h"
#include "DataSurfaceHelpers.h"
#include "mozilla/Types.h" // for decltype
#include "MacIOSurface.h"
#include "Tools.h"
@ -88,9 +90,13 @@ CreateCGImage(void *aInfo,
MOZ_CRASH();
}
size_t bufLen = BufferSizeFromStrideAndHeight(aStride, aSize.height);
if (bufLen == 0) {
return nullptr;
}
CGDataProviderRef dataProvider = CGDataProviderCreateWithData(aInfo,
aData,
aSize.height * aStride,
bufLen,
releaseCallback);
CGImageRef image;
@ -130,10 +136,16 @@ SourceSurfaceCG::InitFromData(unsigned char *aData,
{
assert(aSize.width >= 0 && aSize.height >= 0);
void *data = malloc(aStride * aSize.height);
size_t bufLen = BufferSizeFromStrideAndHeight(aStride, aSize.height);
if (bufLen == 0) {
mImage = nullptr;
return false;
}
void *data = malloc(bufLen);
// Copy all the data except the stride padding on the very last
// row since we can't guarantee that is readable.
memcpy(data, aData, aStride * (aSize.height - 1) + (aSize.width * BytesPerPixel(aFormat)));
memcpy(data, aData, bufLen - aStride + (aSize.width * BytesPerPixel(aFormat)));
mFormat = aFormat;
mImage = CreateCGImage(data, data, aSize, aStride, aFormat);
@ -167,8 +179,14 @@ DataSourceSurfaceCG::InitFromData(unsigned char *aData,
return false;
}
void *data = malloc(aStride * aSize.height);
memcpy(data, aData, aStride * (aSize.height - 1) + (aSize.width * BytesPerPixel(aFormat)));
size_t bufLen = BufferSizeFromStrideAndHeight(aStride, aSize.height);
if (bufLen == 0) {
mImage = nullptr;
return false;
}
void *data = malloc(bufLen);
memcpy(data, aData, bufLen - aStride + (aSize.width * BytesPerPixel(aFormat)));
mFormat = aFormat;
mImage = CreateCGImage(data, data, aSize, aStride, aFormat);
@ -300,13 +318,21 @@ SourceSurfaceCGBitmapContext::DrawTargetWillChange()
size_t stride = CGBitmapContextGetBytesPerRow(mCg);
size_t height = CGBitmapContextGetHeight(mCg);
mDataHolder.Realloc(stride * height);
mData = mDataHolder;
size_t bufLen = BufferSizeFromStrideAndHeight(stride, height);
if (bufLen == 0) {
mDataHolder.Dealloc();
mData = nullptr;
} else {
static_assert(sizeof(decltype(mDataHolder[0])) == 1,
"mDataHolder.Realloc() takes an object count, so its objects must be 1-byte sized if we use bufLen");
mDataHolder.Realloc(/* actually an object count */ bufLen);
mData = mDataHolder;
// copy out the data from the CGBitmapContext
// we'll maintain ownership of mData until
// we transfer it to mImage
memcpy(mData, CGBitmapContextGetData(mCg), stride*height);
// copy out the data from the CGBitmapContext
// we'll maintain ownership of mData until
// we transfer it to mImage
memcpy(mData, CGBitmapContextGetData(mCg), bufLen);
}
// drop the current image for the data associated with the CGBitmapContext
if (mImage)

View File

@ -4,7 +4,10 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "SourceSurfaceRawData.h"
#include "DataSurfaceHelpers.h"
#include "Logging.h"
#include "mozilla/Types.h" // for decltype
namespace mozilla {
namespace gfx {
@ -29,10 +32,19 @@ bool
SourceSurfaceAlignedRawData::Init(const IntSize &aSize,
SurfaceFormat aFormat)
{
mStride = GetAlignedStride<16>(aSize.width * BytesPerPixel(aFormat));
mArray.Realloc(mStride * aSize.height);
mSize = aSize;
mFormat = aFormat;
mStride = GetAlignedStride<16>(aSize.width * BytesPerPixel(aFormat));
size_t bufLen = BufferSizeFromStrideAndHeight(mStride, aSize.height);
if (bufLen > 0) {
static_assert(sizeof(decltype(mArray[0])) == 1,
"mArray.Realloc() takes an object count, so its objects must be 1-byte sized if we use bufLen");
mArray.Realloc(/* actually an object count */ bufLen);
mSize = aSize;
} else {
mArray.Dealloc();
mSize.SizeTo(0, 0);
}
return mArray != nullptr;
}
@ -42,10 +54,19 @@ SourceSurfaceAlignedRawData::InitWithStride(const IntSize &aSize,
SurfaceFormat aFormat,
int32_t aStride)
{
mStride = aStride;
mArray.Realloc(mStride * aSize.height);
mSize = aSize;
mFormat = aFormat;
mStride = aStride;
size_t bufLen = BufferSizeFromStrideAndHeight(mStride, aSize.height);
if (bufLen > 0) {
static_assert(sizeof(decltype(mArray[0])) == 1,
"mArray.Realloc() takes an object count, so its objects must be 1-byte sized if we use bufLen");
mArray.Realloc(/* actually an object count */ bufLen);
mSize = aSize;
} else {
mArray.Dealloc();
mSize.SizeTo(0, 0);
}
return mArray != nullptr;
}