Index: src/core/SkBitmap.cpp |
diff --git a/src/core/SkBitmap.cpp b/src/core/SkBitmap.cpp |
index 11c7cbd69c289991ea25c8894a6b62037ec34a2c..d4c3a47d81f42519dbb08c15c9fbb6ad5cbcb4cf 100644 |
--- a/src/core/SkBitmap.cpp |
+++ b/src/core/SkBitmap.cpp |
@@ -24,6 +24,10 @@ |
#include "SkPackBits.h" |
#include <new> |
+static bool isPos32Bits(const Sk64& value) { |
+ return !value.isNeg() && value.is32(); |
+} |
+ |
struct MipLevel { |
void* fPixels; |
uint32_t fRowBytes; |
@@ -40,12 +44,14 @@ |
if (levelCount < 0) { |
return NULL; |
} |
- int64_t size = (levelCount + 1) * sizeof(MipLevel); |
- size += sizeof(MipMap) + pixelSize; |
- if (!sk_64_isS32(size)) { |
+ Sk64 size; |
+ size.setMul(levelCount + 1, sizeof(MipLevel)); |
+ size.add(sizeof(MipMap)); |
+ size.add(SkToS32(pixelSize)); |
+ if (!isPos32Bits(size)) { |
return NULL; |
} |
- MipMap* mm = (MipMap*)sk_malloc_throw(sk_64_asS32(size)); |
+ MipMap* mm = (MipMap*)sk_malloc_throw(size.get32()); |
mm->fRefCnt = 1; |
mm->fLevelCount = levelCount; |
return mm; |
@@ -179,49 +185,58 @@ |
return 0; |
} |
- int64_t rowBytes = 0; |
+ Sk64 rowBytes; |
+ rowBytes.setZero(); |
switch (c) { |
case kNo_Config: |
break; |
case kA8_Config: |
case kIndex8_Config: |
- rowBytes = width; |
+ rowBytes.set(width); |
break; |
case kRGB_565_Config: |
case kARGB_4444_Config: |
- rowBytes = width << 1; |
+ rowBytes.set(width); |
+ rowBytes.shiftLeft(1); |
break; |
case kARGB_8888_Config: |
- rowBytes = width << 2; |
+ rowBytes.set(width); |
+ rowBytes.shiftLeft(2); |
break; |
default: |
SkDEBUGFAIL("unknown config"); |
break; |
} |
- return sk_64_isS32(rowBytes) ? sk_64_asS32(rowBytes) : 0; |
-} |
- |
-int64_t SkBitmap::ComputeSize64(Config config, int width, int height) { |
- int64_t rowBytes = sk_64_mul(ComputeBytesPerPixel(config), width); |
- return rowBytes * height; |
+ return isPos32Bits(rowBytes) ? rowBytes.get32() : 0; |
+} |
+ |
+Sk64 SkBitmap::ComputeSize64(Config c, int width, int height) { |
+ Sk64 size; |
+ size.setMul(SkToS32(SkBitmap::ComputeRowBytes(c, width)), height); |
+ return size; |
} |
size_t SkBitmap::ComputeSize(Config c, int width, int height) { |
- int64_t size = SkBitmap::ComputeSize64(c, width, height); |
- return sk_64_isS32(size) ? sk_64_asS32(size) : 0; |
-} |
- |
-int64_t SkBitmap::ComputeSafeSize64(Config config, |
- uint32_t width, |
- uint32_t height, |
- size_t rowBytes) { |
- int64_t safeSize = 0; |
+ Sk64 size = SkBitmap::ComputeSize64(c, width, height); |
+ return isPos32Bits(size) ? size.get32() : 0; |
+} |
+ |
+Sk64 SkBitmap::ComputeSafeSize64(Config config, |
+ uint32_t width, |
+ uint32_t height, |
+ size_t rowBytes) { |
+ Sk64 safeSize; |
+ safeSize.setZero(); |
if (height > 0) { |
- int64_t lastRow = sk_64_mul(ComputeBytesPerPixel(config), width); |
- safeSize = sk_64_mul(height - 1, rowBytes) + lastRow; |
- } |
- SkASSERT(safeSize >= 0); |
+ // TODO: Handle the case where the return value from |
+ // ComputeRowBytes is more than 31 bits. |
+ safeSize.set(SkToS32(ComputeRowBytes(config, width))); |
+ Sk64 sizeAllButLastRow; |
+ sizeAllButLastRow.setMul(height - 1, SkToS32(rowBytes)); |
+ safeSize.add(sizeAllButLastRow); |
+ } |
+ SkASSERT(!safeSize.isNeg()); |
return safeSize; |
} |
@@ -229,13 +244,8 @@ |
uint32_t width, |
uint32_t height, |
size_t rowBytes) { |
- int64_t safeSize = ComputeSafeSize64(config, width, height, rowBytes); |
- int32_t safeSize32 = (int32_t)safeSize; |
- |
- if (safeSize32 != safeSize) { |
- safeSize32 = 0; |
- } |
- return safeSize32; |
+ Sk64 safeSize = ComputeSafeSize64(config, width, height, rowBytes); |
+ return (safeSize.is32() ? safeSize.get32() : 0); |
} |
void SkBitmap::getBounds(SkRect* bounds) const { |
@@ -546,6 +556,10 @@ |
// faster. The computation is meant to be identical. |
return (fHeight ? ((fHeight - 1) * fRowBytes) + |
ComputeRowBytes(this->config(), fWidth): 0); |
+} |
+ |
+Sk64 SkBitmap::getSafeSize64() const { |
+ return ComputeSafeSize64(this->config(), fWidth, fHeight, fRowBytes); |
} |
bool SkBitmap::copyPixelsTo(void* const dst, size_t dstSize, |