Just add new safe size apis
Update skia (and then hide the older versions) to come later
Inspired by https://skia-review.googlesource.com/c/skia/+/52665
Bug: skia:
Change-Id: I15c7395557fb49c4163cb3b323b5428abd2c752d
Reviewed-on: https://skia-review.googlesource.com/53520
Reviewed-by: Florin Malita <fmalita@chromium.org>
Commit-Queue: Mike Reed <reed@google.com>
diff --git a/include/core/SkBitmap.h b/include/core/SkBitmap.h
index 7425eb0..5b4e1a6 100644
--- a/include/core/SkBitmap.h
+++ b/include/core/SkBitmap.h
@@ -141,6 +141,12 @@
*/
void* getPixels() const { return fPixels; }
+ /**
+ * 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); }
+
/** 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.
diff --git a/include/core/SkImageInfo.h b/include/core/SkImageInfo.h
index f659bf7..c47dbb2 100644
--- a/include/core/SkImageInfo.h
+++ b/include/core/SkImageInfo.h
@@ -315,6 +315,21 @@
return sk_64_asS32(size);
}
+ /**
+ * 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());
return rowBytes >= rb;
diff --git a/include/core/SkPixmap.h b/include/core/SkPixmap.h
index aa43b34..8115756 100644
--- a/include/core/SkPixmap.h
+++ b/include/core/SkPixmap.h
@@ -229,6 +229,12 @@
*/
size_t getSafeSize() const { return fInfo.getSafeSize(fRowBytes); }
+ /**
+ * 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
without alpha in each pixel; for other SkColorType, returns true if all
diff --git a/src/core/SkImageInfo.cpp b/src/core/SkImageInfo.cpp
index 1baf0b7..c610b82 100644
--- a/src/core/SkImageInfo.cpp
+++ b/src/core/SkImageInfo.cpp
@@ -6,6 +6,7 @@
*/
#include "SkImageInfo.h"
+#include "SkSafeMath.h"
#include "SkReadBuffer.h"
#include "SkWriteBuffer.h"
@@ -70,6 +71,16 @@
///////////////////////////////////////////////////////////////////////////////////////////////////
+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 6928f38..50ee91c 100644
--- a/src/core/SkMallocPixelRef.cpp
+++ b/src/core/SkMallocPixelRef.cpp
@@ -35,9 +35,9 @@
}
- sk_sp<SkPixelRef> SkMallocPixelRef::MakeUsing(void*(*alloc)(size_t),
- const SkImageInfo& info,
- size_t requestedRowBytes) {
+sk_sp<SkPixelRef> SkMallocPixelRef::MakeUsing(void*(*alloc)(size_t),
+ const SkImageInfo& info,
+ size_t requestedRowBytes) {
if (!is_valid(info)) {
return nullptr;
}
@@ -65,13 +65,14 @@
size_t size = sk_64_asS32(bigSize);
SkASSERT(size >= info.getSafeSize(rowBytes));
+ SkASSERT(info.getSafeSize(rowBytes) == info.computeByteSize(rowBytes));
void* addr = alloc(size);
if (nullptr == addr) {
return nullptr;
}
- return sk_sp<SkPixelRef>(new SkMallocPixelRef(info, addr, rowBytes,
- sk_free_releaseproc, nullptr));
+ return sk_sp<SkPixelRef>(new SkMallocPixelRef(info, addr, rowBytes,
+ sk_free_releaseproc, nullptr));
}
sk_sp<SkPixelRef> SkMallocPixelRef::MakeAllocate(const SkImageInfo& info,