From 88757dacd4f532a0f647c02ae0ee596d31ab5c68 Mon Sep 17 00:00:00 2001 From: Mike Reed Date: Tue, 26 Sep 2017 17:46:02 -0400 Subject: guard old apis for querying byte-size of a bitmap/imageinfo/pixmap Now with legacy behavior for allocpixels This was reverted, so the current CL is a "fix" on top of ... https://skia-review.googlesource.com/c/skia/+/50980 Related update to Chrome (in preparation for this change) https://chromium-review.googlesource.com/c/chromium/src/+/685719 Bug: skia: Change-Id: I4b370ee7e95083ab27421f008132219c9c7b86e9 Reviewed-on: https://skia-review.googlesource.com/51341 Reviewed-by: Florin Malita Commit-Queue: Mike Reed --- bench/AndroidCodecBench.cpp | 2 +- bench/CodecBench.cpp | 2 +- bench/ColorCodecBench.cpp | 4 +-- bench/nanobench.cpp | 2 +- dm/DM.cpp | 4 +-- dm/DMSrcSink.cpp | 8 +++--- gn/flutter_defines.gni | 1 + include/core/SkBitmap.h | 12 +++++--- include/core/SkImageInfo.h | 17 ++++++++++++ include/core/SkPixmap.h | 8 ++++++ public.bzl | 1 + samplecode/SampleApp.cpp | 2 +- src/android/SkBitmapRegionCodec.cpp | 2 +- src/codec/SkIcoCodec.cpp | 2 +- src/codec/SkSampler.cpp | 4 +-- src/codec/SkWebpCodec.cpp | 2 +- src/core/SkAutoPixmapStorage.cpp | 4 +-- src/core/SkBitmap.cpp | 2 +- src/core/SkBitmapCache.cpp | 4 +-- src/core/SkImageInfo.cpp | 12 ++++++++ src/core/SkMallocPixelRef.cpp | 54 +++++++++++++++++++----------------- src/core/SkScalerContext.cpp | 2 +- src/core/SkSpecialImage.cpp | 2 +- src/gpu/ops/GrSmallPathRenderer.cpp | 4 +-- src/image/SkImage.cpp | 5 +++- src/image/SkImage_Gpu.cpp | 17 +++++------- src/image/SkImage_Raster.cpp | 4 +-- src/image/SkSurface_Raster.cpp | 2 +- src/utils/mac/SkCreateCGImageRef.cpp | 2 +- tests/CanvasTest.cpp | 2 +- tests/CodecTest.cpp | 4 +-- tests/DrawBitmapRectTest.cpp | 8 +++--- tests/Float16Test.cpp | 2 +- tests/ImageNewShaderTest.cpp | 4 +-- tests/ImageTest.cpp | 2 +- tests/MallocPixelRefTest.cpp | 6 ++-- tests/RecordingXfermodeTest.cpp | 4 +-- tests/ResourceCacheTest.cpp | 2 +- tests/SurfaceTest.cpp | 4 +-- tests/SwizzlerTest.cpp | 2 +- tests/WritePixelsTest.cpp | 2 +- 41 files changed, 137 insertions(+), 92 deletions(-) diff --git a/bench/AndroidCodecBench.cpp b/bench/AndroidCodecBench.cpp index d9abac63d8..886e875c6d 100644 --- a/bench/AndroidCodecBench.cpp +++ b/bench/AndroidCodecBench.cpp @@ -38,7 +38,7 @@ void AndroidCodecBench::onDelayedSetup() { fInfo = fInfo.makeAlphaType(kPremul_SkAlphaType); } - fPixelStorage.reset(fInfo.getSafeSize(fInfo.minRowBytes())); + fPixelStorage.reset(fInfo.computeMinByteSize()); } void AndroidCodecBench::onDraw(int n, SkCanvas* canvas) { diff --git a/bench/CodecBench.cpp b/bench/CodecBench.cpp index 29443746f7..708ab60870 100644 --- a/bench/CodecBench.cpp +++ b/bench/CodecBench.cpp @@ -43,7 +43,7 @@ void CodecBench::onDelayedSetup() { .makeAlphaType(fAlphaType) .makeColorSpace(nullptr); - fPixelStorage.reset(fInfo.getSafeSize(fInfo.minRowBytes())); + fPixelStorage.reset(fInfo.computeMinByteSize()); } void CodecBench::onDraw(int n, SkCanvas* canvas) { diff --git a/bench/ColorCodecBench.cpp b/bench/ColorCodecBench.cpp index 680c1d916f..1239e1d4fe 100644 --- a/bench/ColorCodecBench.cpp +++ b/bench/ColorCodecBench.cpp @@ -88,10 +88,10 @@ void ColorCodecBench::onDelayedSetup() { fDstSpace = static_cast(fDstSpace.get())->makeLinearGamma(); } - fDst.reset(fDstInfo.getSafeSize(fDstInfo.minRowBytes())); + fDst.reset(fDstInfo.computeMinByteSize()); if (FLAGS_xform_only) { - fSrc.reset(fSrcInfo.getSafeSize(fSrcInfo.minRowBytes())); + fSrc.reset(fSrcInfo.computeMinByteSize()); fSrcSpace = codec->getInfo().refColorSpace(); codec->getPixels(fSrcInfo, fSrc.get(), fSrcInfo.minRowBytes()); } diff --git a/bench/nanobench.cpp b/bench/nanobench.cpp index 04583309ce..2dc41bb8c0 100644 --- a/bench/nanobench.cpp +++ b/bench/nanobench.cpp @@ -887,7 +887,7 @@ public: SkImageInfo info = codec->getInfo().makeColorType(colorType).makeAlphaType(alphaType); const size_t rowBytes = info.minRowBytes(); - SkAutoMalloc storage(info.getSafeSize(rowBytes)); + SkAutoMalloc storage(info.computeByteSize(rowBytes)); const SkCodec::Result result = codec->getPixels( info, storage.get(), rowBytes); diff --git a/dm/DM.cpp b/dm/DM.cpp index 777a59345d..ea8ec2742e 100644 --- a/dm/DM.cpp +++ b/dm/DM.cpp @@ -1128,9 +1128,9 @@ struct Task { SkBitmap swizzle; SkAssertResult(sk_tool_utils::copy_to(&swizzle, kRGBA_8888_SkColorType, bitmap)); - hash.write(swizzle.getPixels(), swizzle.getSize()); + hash.write(swizzle.getPixels(), swizzle.computeByteSize()); } else { - hash.write(bitmap.getPixels(), bitmap.getSize()); + hash.write(bitmap.getPixels(), bitmap.computeByteSize()); } } SkMD5::Digest digest; diff --git a/dm/DMSrcSink.cpp b/dm/DMSrcSink.cpp index 2a0b59841c..0968aca705 100644 --- a/dm/DMSrcSink.cpp +++ b/dm/DMSrcSink.cpp @@ -454,7 +454,7 @@ Error CodecSrc::draw(SkCanvas* canvas) const { const int bpp = SkColorTypeBytesPerPixel(decodeInfo.colorType()); const size_t rowBytes = size.width() * bpp; - const size_t safeSize = decodeInfo.getSafeSize(rowBytes); + const size_t safeSize = decodeInfo.computeByteSize(rowBytes); SkAutoMalloc pixels(safeSize); SkCodec::Options options; @@ -1468,12 +1468,12 @@ static bool encode_png_base64(const SkBitmap& bitmap, SkString* dst) { static Error compare_bitmaps(const SkBitmap& reference, const SkBitmap& bitmap) { // The dimensions are a property of the Src only, and so should be identical. - SkASSERT(reference.getSize() == bitmap.getSize()); - if (reference.getSize() != bitmap.getSize()) { + SkASSERT(reference.computeByteSize() == bitmap.computeByteSize()); + if (reference.computeByteSize() != bitmap.computeByteSize()) { return "Dimensions don't match reference"; } // All SkBitmaps in DM are tight, so this comparison is easy. - if (0 != memcmp(reference.getPixels(), bitmap.getPixels(), reference.getSize())) { + if (0 != memcmp(reference.getPixels(), bitmap.getPixels(), reference.computeByteSize())) { SkString encoded; SkString errString("Pixels don't match reference"); if (encode_png_base64(reference, &encoded)) { diff --git a/gn/flutter_defines.gni b/gn/flutter_defines.gni index 13cf328462..8d8520edb3 100644 --- a/gn/flutter_defines.gni +++ b/gn/flutter_defines.gni @@ -5,4 +5,5 @@ flutter_defines = [ "SK_SUPPORT_LEGACY_IMAGE_ENCODE_API", "SK_SUPPORT_LEGACY_FONTMGR_API", + "SK_SUPPORT_LEGACY_SAFESIZE64", ] diff --git a/include/core/SkBitmap.h b/include/core/SkBitmap.h index 7425eb03d5..cea50b8886 100644 --- a/include/core/SkBitmap.h +++ b/include/core/SkBitmap.h @@ -141,10 +141,13 @@ public: */ void* getPixels() const { return fPixels; } - /** Return the byte size of the pixels, based on the height and rowBytes. - Note this truncates the result to 32bits. Call getSize64() to detect - if the real size exceeds 32bits. - */ + /** + * Returns the size (in bytes) of the bitmap's image buffer. + * If the calculation overflows, or if the height is 0, this returns 0. + */ + size_t computeByteSize() const { return fInfo.computeByteSize(fRowBytes); } + +#ifdef SK_SUPPORT_LEGACY_SAFESIZE64 size_t getSize() const { return fInfo.height() * fRowBytes; } /** Return the number of bytes from the pointer returned by getPixels() @@ -168,6 +171,7 @@ public: int64_t computeSafeSize64() const { return fInfo.getSafeSize64(fRowBytes); } +#endif /** Returns true if this bitmap is marked as immutable, meaning that the contents of its pixels will not change for the lifetime of the bitmap. diff --git a/include/core/SkImageInfo.h b/include/core/SkImageInfo.h index f659bf7742..e8a06cb0d1 100644 --- a/include/core/SkImageInfo.h +++ b/include/core/SkImageInfo.h @@ -300,6 +300,7 @@ public: void unflatten(SkReadBuffer&); void flatten(SkWriteBuffer&) const; +#ifdef SK_SUPPORT_LEGACY_SAFESIZE64 int64_t getSafeSize64(size_t rowBytes) const { if (0 == fHeight) { return 0; @@ -314,6 +315,22 @@ public: } return sk_64_asS32(size); } +#endif + + /** + * Returns the size (in bytes) of the image buffer that this info needs, given the specified + * rowBytes. The rowBytes must be >= this->minRowBytes(). + * If the calculation overflows, or if the height is 0, this returns 0. + */ + size_t computeByteSize(size_t rowBytes) const; + + /** + * Returns the minimum size (in bytes) of the image buffer that this info needs. + * If the calculation overflows, or if the height is 0, this returns 0. + */ + size_t computeMinByteSize() const { + return this->computeByteSize(this->minRowBytes()); + } bool validRowBytes(size_t rowBytes) const { uint64_t rb = sk_64_mul(fWidth, this->bytesPerPixel()); diff --git a/include/core/SkPixmap.h b/include/core/SkPixmap.h index aa43b3441f..f304bde933 100644 --- a/include/core/SkPixmap.h +++ b/include/core/SkPixmap.h @@ -206,6 +206,7 @@ public: */ int shiftPerPixel() const { return fInfo.shiftPerPixel(); } +#ifdef SK_SUPPORT_LEGACY_SAFESIZE64 /** Returns conservative memory required for pixel storage. Includes unused memory on last row when rowBytesAsPixels() exceeds width(). @@ -228,6 +229,13 @@ public: @return exact pixel storage size if size fits in signed 32 bits */ size_t getSafeSize() const { return fInfo.getSafeSize(fRowBytes); } +#endif + + /** + * Returns the size (in bytes) of the pixmap's image buffer. + * If the calculation overflows, or if the height is 0, this returns 0. + */ + size_t computeByteSize() const { return fInfo.computeByteSize(fRowBytes); } /** Returns true if all pixels are opaque. SkColorType determines how pixels are encoded, and whether pixel describes alpha. Returns true for SkColorType diff --git a/public.bzl b/public.bzl index e8325500a0..9b3afbe2bd 100644 --- a/public.bzl +++ b/public.bzl @@ -656,6 +656,7 @@ DEFINES_ALL = [ # Required for building dm. "GR_TEST_UTILS", # Staging flags for API changes + "SK_SUPPORT_LEGACY_SAFESIZE64", # Should remove after we update golden images "SK_WEBP_ENCODER_USE_DEFAULT_METHOD", # Experiment to diagnose image diffs in Google3 diff --git a/samplecode/SampleApp.cpp b/samplecode/SampleApp.cpp index 515bcd6a6b..dcca5a095e 100644 --- a/samplecode/SampleApp.cpp +++ b/samplecode/SampleApp.cpp @@ -344,7 +344,7 @@ public: // We made/have an off-screen surface. Extract the pixels exactly as we rendered them: SkImageInfo info = win->info(); size_t rowBytes = info.minRowBytes(); - size_t size = info.getSafeSize(rowBytes); + size_t size = info.computeByteSize(rowBytes); auto data = SkData::MakeUninitialized(size); SkASSERT(data); diff --git a/src/android/SkBitmapRegionCodec.cpp b/src/android/SkBitmapRegionCodec.cpp index f77c70264f..493e4b5672 100644 --- a/src/android/SkBitmapRegionCodec.cpp +++ b/src/android/SkBitmapRegionCodec.cpp @@ -96,7 +96,7 @@ bool SkBitmapRegionCodec::decodeRegion(SkBitmap* bitmap, SkBRDAllocator* allocat if (SubsetType::kPartiallyInside_SubsetType == type && SkCodec::kNo_ZeroInitialized == zeroInit) { void* pixels = bitmap->getPixels(); - size_t bytes = outInfo.getSafeSize(bitmap->rowBytes()); + size_t bytes = outInfo.computeByteSize(bitmap->rowBytes()); memset(pixels, 0, bytes); } diff --git a/src/codec/SkIcoCodec.cpp b/src/codec/SkIcoCodec.cpp index 74affe6709..da6d0c360c 100644 --- a/src/codec/SkIcoCodec.cpp +++ b/src/codec/SkIcoCodec.cpp @@ -173,7 +173,7 @@ std::unique_ptr SkIcoCodec::MakeFromStream(std::unique_ptr st int maxIndex = 0; for (int i = 0; i < codecs->count(); i++) { SkImageInfo info = codecs->operator[](i)->getInfo(); - size_t size = info.getSafeSize(info.minRowBytes()); + size_t size = info.computeMinByteSize(); if (size > maxSize) { maxSize = size; diff --git a/src/codec/SkSampler.cpp b/src/codec/SkSampler.cpp index c7d9a3ac23..d18410be3b 100644 --- a/src/codec/SkSampler.cpp +++ b/src/codec/SkSampler.cpp @@ -14,8 +14,8 @@ void SkSampler::Fill(const SkImageInfo& info, void* dst, size_t rowBytes, uint64_t colorOrIndex, SkCodec::ZeroInitialized zeroInit) { SkASSERT(dst != nullptr); - // Calculate bytes to fill. We use getSafeSize since the last row may not be padded. - const size_t bytesToFill = info.getSafeSize(rowBytes); + // Calculate bytes to fill. + const size_t bytesToFill = info.computeByteSize(rowBytes); const int width = info.width(); const int numRows = info.height(); diff --git a/src/codec/SkWebpCodec.cpp b/src/codec/SkWebpCodec.cpp index f7082de42a..864fa96a1d 100644 --- a/src/codec/SkWebpCodec.cpp +++ b/src/codec/SkWebpCodec.cpp @@ -542,7 +542,7 @@ SkCodec::Result SkWebpCodec::onGetPixels(const SkImageInfo& dstInfo, void* dst, config.output.u.RGBA.rgba = reinterpret_cast(webpDst.getAddr(dstX, dstY)); config.output.u.RGBA.stride = static_cast(webpDst.rowBytes()); - config.output.u.RGBA.size = webpDst.getSafeSize(); + config.output.u.RGBA.size = webpDst.computeByteSize(); SkAutoTCallVProc idec(WebPIDecode(nullptr, 0, &config)); if (!idec) { diff --git a/src/core/SkAutoPixmapStorage.cpp b/src/core/SkAutoPixmapStorage.cpp index be13e7197f..df0c0fa878 100644 --- a/src/core/SkAutoPixmapStorage.cpp +++ b/src/core/SkAutoPixmapStorage.cpp @@ -29,7 +29,7 @@ size_t SkAutoPixmapStorage::AllocSize(const SkImageInfo& info, size_t* rowBytes) if (rowBytes) { *rowBytes = rb; } - return info.getSafeSize(rb); + return info.computeByteSize(rb); } bool SkAutoPixmapStorage::tryAlloc(const SkImageInfo& info) { @@ -58,7 +58,7 @@ const SkData* SkAutoPixmapStorage::detachPixelsAsData() { return nullptr; } - auto data = SkData::MakeFromMalloc(fStorage, this->getSafeSize()); + auto data = SkData::MakeFromMalloc(fStorage, this->computeByteSize()); fStorage = nullptr; this->INHERITED::reset(); diff --git a/src/core/SkBitmap.cpp b/src/core/SkBitmap.cpp index c3bc4a9d63..4a82d54990 100644 --- a/src/core/SkBitmap.cpp +++ b/src/core/SkBitmap.cpp @@ -675,7 +675,7 @@ bool SkBitmap::ReadRawPixels(SkReadBuffer* buffer, SkBitmap* bitmap) { } // write_raw_pixels() always writes snug buffers with rowBytes == minRowBytes(). - size_t bytes = info.getSafeSize(info.minRowBytes()); + size_t bytes = info.computeMinByteSize(); if (!buffer->validate(bytes != 0)) { return false; } diff --git a/src/core/SkBitmapCache.cpp b/src/core/SkBitmapCache.cpp index b8767644a2..8d3991a9d5 100644 --- a/src/core/SkBitmapCache.cpp +++ b/src/core/SkBitmapCache.cpp @@ -160,7 +160,7 @@ public: const Key& getKey() const override { return fKey; } size_t bytesUsed() const override { - return sizeof(fKey) + fInfo.getSafeSize(fRowBytes); + return sizeof(fKey) + fInfo.computeByteSize(fRowBytes); } bool canBePurged() override { SkAutoMutexAcquire ama(fMutex); @@ -289,7 +289,7 @@ SkBitmapCache::RecPtr SkBitmapCache::Alloc(const SkBitmapCacheDesc& desc, const } const size_t rb = info.minRowBytes(); - size_t size = info.getSafeSize(rb); + size_t size = info.computeByteSize(rb); if (0 == size) { return nullptr; } diff --git a/src/core/SkImageInfo.cpp b/src/core/SkImageInfo.cpp index 1baf0b77de..353397e99d 100644 --- a/src/core/SkImageInfo.cpp +++ b/src/core/SkImageInfo.cpp @@ -70,6 +70,18 @@ static SkColorType stored_to_live(unsigned stored) { /////////////////////////////////////////////////////////////////////////////////////////////////// +#include "SkSafeMath.h" + +size_t SkImageInfo::computeByteSize(size_t rowBytes) const { + if (0 == fHeight) { + return 0; + } + SkSafeMath safe; + size_t bytes = safe.add(safe.mul(fHeight - 1, rowBytes), + safe.mul(fWidth, this->bytesPerPixel())); + return safe ? bytes : 0; +} + static bool alpha_type_is_valid(SkAlphaType alphaType) { return (alphaType >= kUnknown_SkAlphaType) && (alphaType <= kLastEnum_SkAlphaType); } diff --git a/src/core/SkMallocPixelRef.cpp b/src/core/SkMallocPixelRef.cpp index 6928f38ee2..bf9a99ff74 100644 --- a/src/core/SkMallocPixelRef.cpp +++ b/src/core/SkMallocPixelRef.cpp @@ -35,37 +35,38 @@ sk_sp SkMallocPixelRef::MakeDirect(const SkImageInfo& info, } - sk_sp SkMallocPixelRef::MakeUsing(void*(*alloc)(size_t), - const SkImageInfo& info, - size_t requestedRowBytes) { - if (!is_valid(info)) { - return nullptr; +sk_sp SkMallocPixelRef::MakeUsing(void*(*allocProc)(size_t), + const SkImageInfo& info, + size_t rowBytes) { + if (rowBytes == 0) { + rowBytes = info.minRowBytes(); } - // only want to permit 31bits of rowBytes - int64_t minRB = (int64_t)info.minRowBytes64(); - if (minRB < 0 || !sk_64_isS32(minRB)) { - return nullptr; // allocation will be too large - } - if (requestedRowBytes > 0 && (int32_t)requestedRowBytes < minRB) { - return nullptr; // cannot meet requested rowbytes + if (!is_valid(info) || !info.validRowBytes(rowBytes)) { + return nullptr; } - int32_t rowBytes; - if (requestedRowBytes) { - rowBytes = SkToS32(requestedRowBytes); - } else { - rowBytes = minRB; - } + size_t size = 0; + // if the info is empty, or rowBytes is 0 (which can be valid), then we don't need to compute + // a size. + if (!info.isEmpty() && rowBytes > 0) { +#ifdef SK_SUPPORT_LEGACY_SAFESIZE64 + int64_t bigSize = (int64_t)info.height() * rowBytes; + if (!sk_64_isS32(bigSize)) { + return nullptr; + } - int64_t bigSize = (int64_t)info.height() * rowBytes; - if (!sk_64_isS32(bigSize)) { - return nullptr; + size = sk_64_asS32(bigSize); + SkASSERT(size >= info.getSafeSize(rowBytes)); +#else + size = info.computeByteSize(rowBytes); +#endif + if (size == 0) { + return nullptr; // overflow + } } - size_t size = sk_64_asS32(bigSize); - SkASSERT(size >= info.getSafeSize(rowBytes)); - void* addr = alloc(size); + void* addr = allocProc(size); if (nullptr == addr) { return nullptr; } @@ -107,10 +108,11 @@ sk_sp SkMallocPixelRef::MakeWithData(const SkImageInfo& info, size_t rowBytes, sk_sp data) { SkASSERT(data != nullptr); - if (!is_valid(info)) { + if (!is_valid(info) || !info.validRowBytes(rowBytes)) { return nullptr; } - if ((rowBytes < info.minRowBytes()) || (data->size() < info.getSafeSize(rowBytes))) { + size_t sizeNeeded = info.computeByteSize(rowBytes); + if (sizeNeeded == 0 || sizeNeeded > data->size()) { return nullptr; } // must get this address before we call release diff --git a/src/core/SkScalerContext.cpp b/src/core/SkScalerContext.cpp index 98036cf8a0..460907f164 100644 --- a/src/core/SkScalerContext.cpp +++ b/src/core/SkScalerContext.cpp @@ -400,7 +400,7 @@ static void generateMask(const SkMask& mask, const SkPath& path, } else { dst.reset(info, mask.fImage, dstRB); } - sk_bzero(dst.writable_addr(), dst.getSafeSize()); + sk_bzero(dst.writable_addr(), dst.computeByteSize()); SkDraw draw; draw.fDst = dst; diff --git a/src/core/SkSpecialImage.cpp b/src/core/SkSpecialImage.cpp index db40329204..db4fadcce2 100644 --- a/src/core/SkSpecialImage.cpp +++ b/src/core/SkSpecialImage.cpp @@ -219,7 +219,7 @@ public: SkAlphaType alphaType() const override { return fBitmap.alphaType(); } - size_t getSize() const override { return fBitmap.getSize(); } + size_t getSize() const override { return fBitmap.computeByteSize(); } void onDraw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPaint* paint) const override { SkRect dst = SkRect::MakeXYWH(x, y, diff --git a/src/gpu/ops/GrSmallPathRenderer.cpp b/src/gpu/ops/GrSmallPathRenderer.cpp index fd868a1dfe..222f6626a7 100644 --- a/src/gpu/ops/GrSmallPathRenderer.cpp +++ b/src/gpu/ops/GrSmallPathRenderer.cpp @@ -455,7 +455,7 @@ private: devPathBounds.height()))) { return false; } - sk_bzero(dst.writable_addr(), dst.getSafeSize()); + sk_bzero(dst.writable_addr(), dst.computeByteSize()); // rasterize path SkPaint paint; @@ -562,7 +562,7 @@ private: devPathBounds.height()))) { return false; } - sk_bzero(dst.writable_addr(), dst.getSafeSize()); + sk_bzero(dst.writable_addr(), dst.computeByteSize()); // rasterize path SkPaint paint; diff --git a/src/image/SkImage.cpp b/src/image/SkImage.cpp index 3ac8ba80ca..705efaec30 100644 --- a/src/image/SkImage.cpp +++ b/src/image/SkImage.cpp @@ -422,7 +422,10 @@ sk_sp SkImageMakeRasterCopyAndAssignColorSpace(const SkImage* src, } size_t rowBytes = info.minRowBytes(); - size_t size = info.getSafeSize(rowBytes); + size_t size = info.computeByteSize(rowBytes); + if (size == 0) { + return nullptr; + } auto data = SkData::MakeUninitialized(size); if (!data) { return nullptr; diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp index d3a1865039..1a79d59356 100644 --- a/src/image/SkImage_Gpu.cpp +++ b/src/image/SkImage_Gpu.cpp @@ -518,7 +518,7 @@ sk_sp SkImage::makeNonTextureImage() const { } SkImageInfo info = as_IB(this)->onImageInfo(); size_t rowBytes = info.minRowBytes(); - size_t size = info.getSafeSize(rowBytes); + size_t size = info.computeByteSize(rowBytes); auto data = SkData::MakeUninitialized(size); if (!data) { return nullptr; @@ -667,7 +667,7 @@ size_t SkImage::getDeferredTextureImageData(const GrContextThreadSafeProxy& prox size_t pixelSize = 0; if (!isScaled && this->peekPixels(&pixmap) && pixmap.info().colorType() == dstColorType) { info = pixmap.info(); - pixelSize = SkAlign8(pixmap.getSafeSize()); + pixelSize = SkAlign8(pixmap.computeByteSize()); if (!dstColorSpace) { pixmap.setColorSpace(nullptr); info = info.makeColorSpace(nullptr); @@ -773,7 +773,7 @@ size_t SkImage::getDeferredTextureImageData(const GrContextThreadSafeProxy& prox void* pixels = pixelsAsCharPtr; memcpy(reinterpret_cast(SkAlign8(reinterpret_cast(pixelsAsCharPtr))), - pixmap.addr(), pixmap.getSafeSize()); + pixmap.addr(), pixmap.computeByteSize()); // If the context has sRGB support, and we're intending to render to a surface with an attached // color space, and the image has an sRGB-like color space attached, then use our gamma (sRGB) @@ -824,7 +824,7 @@ size_t SkImage::getDeferredTextureImageData(const GrContextThreadSafeProxy& prox } // Fill in the mipmap levels if they exist - char* mipLevelPtr = pixelsAsCharPtr + SkAlign8(pixmap.getSafeSize()); + char* mipLevelPtr = pixelsAsCharPtr + SkAlign8(pixmap.computeByteSize()); if (useMipMaps) { static_assert(std::is_standard_layout::value, @@ -845,13 +845,10 @@ size_t SkImage::getDeferredTextureImageData(const GrContextThreadSafeProxy& prox // Make sure the mipmap data starts before the end of the buffer SkASSERT(mipLevelPtr < bufferAsCharPtr + pixelOffset + pixelSize); // Make sure the mipmap data ends before the end of the buffer - SkASSERT(mipLevelPtr + mipLevel.fPixmap.getSafeSize() <= + SkASSERT(mipLevelPtr + mipLevel.fPixmap.computeByteSize() <= bufferAsCharPtr + pixelOffset + pixelSize); - // getSafeSize includes rowbyte padding except for the last row, - // right? - - memcpy(mipLevelPtr, mipLevel.fPixmap.addr(), mipLevel.fPixmap.getSafeSize()); + memcpy(mipLevelPtr, mipLevel.fPixmap.addr(), mipLevel.fPixmap.computeByteSize()); memcpy(bufferAsCharPtr + offsetof(DeferredTextureImage, fMipMapLevelData) + sizeof(MipMapLevelData) * (generatedMipLevelIndex + 1) + @@ -861,7 +858,7 @@ size_t SkImage::getDeferredTextureImageData(const GrContextThreadSafeProxy& prox sizeof(MipMapLevelData) * (generatedMipLevelIndex + 1) + offsetof(MipMapLevelData, fRowBytes), &rowBytes, sizeof(rowBytes)); - mipLevelPtr += SkAlign8(mipLevel.fPixmap.getSafeSize()); + mipLevelPtr += SkAlign8(mipLevel.fPixmap.computeByteSize()); } } return size; diff --git a/src/image/SkImage_Raster.cpp b/src/image/SkImage_Raster.cpp index bade1b6235..5258f64b3e 100644 --- a/src/image/SkImage_Raster.cpp +++ b/src/image/SkImage_Raster.cpp @@ -57,11 +57,11 @@ public: if (kUnknown_SkColorType == info.colorType()) { return false; } - if (rowBytes < info.minRowBytes()) { + if (!info.validRowBytes(rowBytes)) { return false; } - size_t size = info.getSafeSize(rowBytes); + size_t size = info.computeByteSize(rowBytes); if (0 == size) { return false; } diff --git a/src/image/SkSurface_Raster.cpp b/src/image/SkSurface_Raster.cpp index 38694876c3..e9d14fea7d 100644 --- a/src/image/SkSurface_Raster.cpp +++ b/src/image/SkSurface_Raster.cpp @@ -162,7 +162,7 @@ void SkSurface_Raster::onCopyOnWrite(ContentChangeMode mode) { fBitmap.allocPixels(); SkASSERT(prev.info() == fBitmap.info()); SkASSERT(prev.rowBytes() == fBitmap.rowBytes()); - memcpy(fBitmap.getPixels(), prev.getPixels(), fBitmap.getSafeSize()); + memcpy(fBitmap.getPixels(), prev.getPixels(), fBitmap.computeByteSize()); } SkASSERT(fBitmap.rowBytes() == fRowBytes); // be sure we always use the same value diff --git a/src/utils/mac/SkCreateCGImageRef.cpp b/src/utils/mac/SkCreateCGImageRef.cpp index fd55d91707..1514ba6e8a 100644 --- a/src/utils/mac/SkCreateCGImageRef.cpp +++ b/src/utils/mac/SkCreateCGImageRef.cpp @@ -132,7 +132,7 @@ CGImageRef SkCreateCGImageRefWithColorspace(const SkBitmap& bm, const int w = bitmap->width(); const int h = bitmap->height(); - const size_t s = bitmap->getSize(); + const size_t s = bitmap->computeByteSize(); // our provider "owns" the bitmap*, and will take care of deleting it CGDataProviderRef dataRef = CGDataProviderCreateWithData(bitmap, bitmap->getPixels(), s, diff --git a/tests/CanvasTest.cpp b/tests/CanvasTest.cpp index 7aaf554015..9b1e0c9bbb 100644 --- a/tests/CanvasTest.cpp +++ b/tests/CanvasTest.cpp @@ -573,7 +573,7 @@ static void TestOverrideStateConsistency(skiatest::Reporter* reporter, const Tes static void test_newraster(skiatest::Reporter* reporter) { SkImageInfo info = SkImageInfo::MakeN32Premul(10, 10); const size_t minRowBytes = info.minRowBytes(); - const size_t size = info.getSafeSize(minRowBytes); + const size_t size = info.computeByteSize(minRowBytes); SkAutoTMalloc storage(size); SkPMColor* baseAddr = storage.get(); sk_bzero(baseAddr, size); diff --git a/tests/CodecTest.cpp b/tests/CodecTest.cpp index f2551d2d95..6e253d29c6 100644 --- a/tests/CodecTest.cpp +++ b/tests/CodecTest.cpp @@ -588,7 +588,7 @@ static void test_dimensions(skiatest::Reporter* r, const char path[]) { // Set up for the decode size_t rowBytes = scaledDims.width() * sizeof(SkPMColor); - size_t totalBytes = scaledInfo.getSafeSize(rowBytes); + size_t totalBytes = scaledInfo.computeByteSize(rowBytes); SkAutoTMalloc pixels(totalBytes); SkAndroidCodec::AndroidOptions options; @@ -1015,7 +1015,7 @@ static void check_color_xform(skiatest::Reporter* r, const char* path) { .makeColorSpace(colorSpace); size_t rowBytes = dstInfo.minRowBytes(); - SkAutoMalloc pixelStorage(dstInfo.getSafeSize(rowBytes)); + SkAutoMalloc pixelStorage(dstInfo.computeByteSize(rowBytes)); SkCodec::Result result = codec->getAndroidPixels(dstInfo, pixelStorage.get(), rowBytes, &opts); REPORTER_ASSERT(r, SkCodec::kSuccess == result); } diff --git a/tests/DrawBitmapRectTest.cpp b/tests/DrawBitmapRectTest.cpp index 991290142e..8ad177f5c1 100644 --- a/tests/DrawBitmapRectTest.cpp +++ b/tests/DrawBitmapRectTest.cpp @@ -144,9 +144,10 @@ static void test_wacky_bitmapshader(skiatest::Reporter* reporter, SkBitmap bm; if (bm.tryAllocN32Pixels(width, height)) { - // allow this to fail silently, to test the code downstream + bm.eraseColor(SK_ColorRED); + } else { + shouldBeDrawn = false; } - bm.eraseColor(SK_ColorRED); matrix.setAll(0.0078740157f, 0, @@ -179,7 +180,7 @@ static void test_wacky_bitmapshader(skiatest::Reporter* reporter, * sign-extension bleed when packing the two values (X,Y) into our 32bit * slot. * - * This tests exercises the original setup, plus 3 more to ensure that we can, + * This tests exercises the original setup, plus 2 more to ensure that we can, * in fact, handle bitmaps at 64K-1 (assuming we don't exceed the total * memory allocation limit). */ @@ -192,7 +193,6 @@ static void test_giantrepeat_crbug118018(skiatest::Reporter* reporter) { { 0x1b294, 0x7f, false }, // crbug 118018 (width exceeds 64K) { 0xFFFF, 0x7f, true }, // should draw, test max width { 0x7f, 0xFFFF, true }, // should draw, test max height - { 0xFFFF, 0xFFFF, false }, // allocation fails (too much RAM) }; for (size_t i = 0; i < SK_ARRAY_COUNT(gTests); ++i) { diff --git a/tests/Float16Test.cpp b/tests/Float16Test.cpp index 64873c3fc8..e67d8f1e79 100644 --- a/tests/Float16Test.cpp +++ b/tests/Float16Test.cpp @@ -43,7 +43,7 @@ DEF_TEST(color_half_float, reporter) { SkAutoPixmapStorage pm; pm.alloc(info); - REPORTER_ASSERT(reporter, pm.getSafeSize() == SkToSizeT(w * h * sizeof(uint64_t))); + REPORTER_ASSERT(reporter, pm.computeByteSize() == SkToSizeT(w * h * sizeof(uint64_t))); SkColor4f c4 { 1, 0.5f, 0.25f, 0.5f }; pm.erase(c4); diff --git a/tests/ImageNewShaderTest.cpp b/tests/ImageNewShaderTest.cpp index 638fa078f0..ff80729d7b 100644 --- a/tests/ImageNewShaderTest.cpp +++ b/tests/ImageNewShaderTest.cpp @@ -17,8 +17,8 @@ #endif static void test_bitmap_equality(skiatest::Reporter* reporter, SkBitmap& bm1, SkBitmap& bm2) { - REPORTER_ASSERT(reporter, bm1.getSize() == bm2.getSize()); - REPORTER_ASSERT(reporter, 0 == memcmp(bm1.getPixels(), bm2.getPixels(), bm1.getSize())); + REPORTER_ASSERT(reporter, bm1.computeByteSize() == bm2.computeByteSize()); + REPORTER_ASSERT(reporter, 0 == memcmp(bm1.getPixels(), bm2.getPixels(), bm1.computeByteSize())); } static void paint_source(SkSurface* sourceSurface) { diff --git a/tests/ImageTest.cpp b/tests/ImageTest.cpp index 96b5b29405..9e0137f3cf 100644 --- a/tests/ImageTest.cpp +++ b/tests/ImageTest.cpp @@ -549,7 +549,7 @@ DEF_TEST(ImageEmpty, reporter) { DEF_TEST(ImageDataRef, reporter) { SkImageInfo info = SkImageInfo::MakeN32Premul(1, 1); size_t rowBytes = info.minRowBytes(); - size_t size = info.getSafeSize(rowBytes); + size_t size = info.computeByteSize(rowBytes); sk_sp data = SkData::MakeUninitialized(size); REPORTER_ASSERT(reporter, data->unique()); sk_sp image = SkImage::MakeRasterData(info, data, rowBytes); diff --git a/tests/MallocPixelRefTest.cpp b/tests/MallocPixelRefTest.cpp index 957c8b3948..ac080994e2 100644 --- a/tests/MallocPixelRefTest.cpp +++ b/tests/MallocPixelRefTest.cpp @@ -32,7 +32,7 @@ DEF_TEST(MallocPixelRef, reporter) { } { size_t rowBytes = info.minRowBytes() - 1; - size_t size = info.getSafeSize(rowBytes); + size_t size = info.computeByteSize(rowBytes); sk_sp data(SkData::MakeUninitialized(size)); sk_sp pr( SkMallocPixelRef::MakeWithData(info, rowBytes, data)); @@ -41,7 +41,7 @@ DEF_TEST(MallocPixelRef, reporter) { } { size_t rowBytes = info.minRowBytes() + 2; - size_t size = info.getSafeSize(rowBytes) - 1; + size_t size = info.computeByteSize(rowBytes) - 1; sk_sp data(SkData::MakeUninitialized(size)); sk_sp pr( SkMallocPixelRef::MakeWithData(info, rowBytes, data)); @@ -49,7 +49,7 @@ DEF_TEST(MallocPixelRef, reporter) { REPORTER_ASSERT(reporter, nullptr == pr.get()); } size_t rowBytes = info.minRowBytes() + 7; - size_t size = info.getSafeSize(rowBytes) + 9; + size_t size = info.computeByteSize(rowBytes) + 9; { SkAutoMalloc memory(size); sk_sp pr( diff --git a/tests/RecordingXfermodeTest.cpp b/tests/RecordingXfermodeTest.cpp index 20dccc6cc2..25e99ba23d 100644 --- a/tests/RecordingXfermodeTest.cpp +++ b/tests/RecordingXfermodeTest.cpp @@ -151,8 +151,8 @@ DEF_TEST(SkRecordingAccuracyXfermode, reporter) { const SkBitmap& goldenBM = golden.recordAndReplay(drawer, clip, mode); const SkBitmap& pictureBM = picture.recordAndReplay(drawer, clip, mode); - size_t pixelsSize = goldenBM.getSize(); - REPORTER_ASSERT(reporter, pixelsSize == pictureBM.getSize()); + size_t pixelsSize = goldenBM.computeByteSize(); + REPORTER_ASSERT(reporter, pixelsSize == pictureBM.computeByteSize()); // The pixel arrays should match. #if FINEGRAIN diff --git a/tests/ResourceCacheTest.cpp b/tests/ResourceCacheTest.cpp index b3d0bd56bb..af33f2d9bc 100644 --- a/tests/ResourceCacheTest.cpp +++ b/tests/ResourceCacheTest.cpp @@ -49,7 +49,7 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ResourceCacheCache, reporter, ctxInfo) { SkBitmap src; src.allocN32Pixels(size.width(), size.height()); src.eraseColor(SK_ColorBLACK); - size_t srcSize = src.getSize(); + size_t srcSize = src.computeByteSize(); size_t initialCacheSize; context->getResourceCacheUsage(nullptr, &initialCacheSize); diff --git a/tests/SurfaceTest.cpp b/tests/SurfaceTest.cpp index 202df58f3c..2fd987fdf6 100644 --- a/tests/SurfaceTest.cpp +++ b/tests/SurfaceTest.cpp @@ -50,7 +50,7 @@ static sk_sp create_direct_surface(SkAlphaType at = kPremul_SkAlphaTy *requestedInfo = info; } const size_t rowBytes = info.minRowBytes(); - void* storage = sk_malloc_throw(info.getSafeSize(rowBytes)); + void* storage = sk_malloc_throw(info.computeByteSize(rowBytes)); return SkSurface::MakeRasterDirectReleaseProc(info, storage, rowBytes, release_direct_surface_storage, storage); @@ -565,7 +565,7 @@ DEF_TEST(surface_rowbytes, reporter) { // Try some illegal rowByte values auto s = SkSurface::MakeRaster(info, 396, nullptr); // needs to be at least 400 REPORTER_ASSERT(reporter, nullptr == s); - s = SkSurface::MakeRaster(info, 1 << 30, nullptr); // allocation to large + s = SkSurface::MakeRaster(info, std::numeric_limits::max(), nullptr); REPORTER_ASSERT(reporter, nullptr == s); } diff --git a/tests/SwizzlerTest.cpp b/tests/SwizzlerTest.cpp index 655c97eadd..8950efb153 100644 --- a/tests/SwizzlerTest.cpp +++ b/tests/SwizzlerTest.cpp @@ -28,7 +28,7 @@ static void check_fill(skiatest::Reporter* r, // to test on different memory alignments. If offset is nonzero, we need to increase the // size of the memory we allocate in order to make sure that we have enough. We are // still allocating the smallest possible size. - const size_t totalBytes = imageInfo.getSafeSize(rowBytes) + offset; + const size_t totalBytes = imageInfo.computeByteSize(rowBytes) + offset; // Create fake image data where every byte has a value of 0 std::unique_ptr storage(new uint8_t[totalBytes]); diff --git a/tests/WritePixelsTest.cpp b/tests/WritePixelsTest.cpp index 81dcbe7f6d..7ea0aad12f 100644 --- a/tests/WritePixelsTest.cpp +++ b/tests/WritePixelsTest.cpp @@ -394,7 +394,7 @@ DEF_TEST(WritePixels, reporter) { const SkImageInfo info = SkImageInfo::MakeN32Premul(DEV_W, DEV_H); for (auto& tightRowBytes : { true, false }) { const size_t rowBytes = tightRowBytes ? info.minRowBytes() : 4 * DEV_W + 100; - const size_t size = info.getSafeSize(rowBytes); + const size_t size = info.computeByteSize(rowBytes); void* pixels = sk_malloc_throw(size); // if rowBytes isn't tight then set the padding to a known value if (!tightRowBytes) { -- cgit v1.2.3