aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/core/SkBitmap.h6
-rw-r--r--include/core/SkImageInfo.h15
-rw-r--r--include/core/SkPixmap.h6
-rw-r--r--src/core/SkImageInfo.cpp11
-rw-r--r--src/core/SkMallocPixelRef.cpp11
5 files changed, 44 insertions, 5 deletions
diff --git a/include/core/SkBitmap.h b/include/core/SkBitmap.h
index 7425eb03d5..5b4e1a6863 100644
--- a/include/core/SkBitmap.h
+++ b/include/core/SkBitmap.h
@@ -141,6 +141,12 @@ public:
*/
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 f659bf7742..c47dbb28b1 100644
--- a/include/core/SkImageInfo.h
+++ b/include/core/SkImageInfo.h
@@ -315,6 +315,21 @@ public:
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 aa43b3441f..8115756b91 100644
--- a/include/core/SkPixmap.h
+++ b/include/core/SkPixmap.h
@@ -229,6 +229,12 @@ public:
*/
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 1baf0b77de..c610b82bdc 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 @@ static SkColorType stored_to_live(unsigned stored) {
///////////////////////////////////////////////////////////////////////////////////////////////////
+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..50ee91c676 100644
--- a/src/core/SkMallocPixelRef.cpp
+++ b/src/core/SkMallocPixelRef.cpp
@@ -35,9 +35,9 @@ sk_sp<SkPixelRef> SkMallocPixelRef::MakeDirect(const SkImageInfo& info,
}
- 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 @@ sk_sp<SkPixelRef> SkMallocPixelRef::MakeDirect(const SkImageInfo& info,
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,