diff options
Diffstat (limited to 'src/core/SkMallocPixelRef.cpp')
-rw-r--r-- | src/core/SkMallocPixelRef.cpp | 46 |
1 files changed, 19 insertions, 27 deletions
diff --git a/src/core/SkMallocPixelRef.cpp b/src/core/SkMallocPixelRef.cpp index 6928f38ee2..565a757ec2 100644 --- a/src/core/SkMallocPixelRef.cpp +++ b/src/core/SkMallocPixelRef.cpp @@ -35,37 +35,28 @@ sk_sp<SkPixelRef> SkMallocPixelRef::MakeDirect(const SkImageInfo& info, } - sk_sp<SkPixelRef> SkMallocPixelRef::MakeUsing(void*(*alloc)(size_t), - const SkImageInfo& info, - size_t requestedRowBytes) { - if (!is_valid(info)) { - return nullptr; - } - - // 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 +sk_sp<SkPixelRef> SkMallocPixelRef::MakeUsing(void*(*allocProc)(size_t), + const SkImageInfo& info, + size_t rowBytes) { + if (rowBytes == 0) { + rowBytes = info.minRowBytes(); } - int32_t rowBytes; - if (requestedRowBytes) { - rowBytes = SkToS32(requestedRowBytes); - } else { - rowBytes = minRB; + if (!is_valid(info) || !info.validRowBytes(rowBytes)) { + return nullptr; } - int64_t bigSize = (int64_t)info.height() * rowBytes; - if (!sk_64_isS32(bigSize)) { - return nullptr; + 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) { + size = info.computeByteSize(rowBytes); + 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 +98,11 @@ sk_sp<SkPixelRef> SkMallocPixelRef::MakeWithData(const SkImageInfo& info, size_t rowBytes, sk_sp<SkData> 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 |