/** returns the product if it is positive and fits in 31 bits. Otherwise this returns 0. */ static int32_t safeMul32(int32_t a, int32_t b) { int64_t size = sk_64_mul(a, b); if (size > 0 && sk_64_isS32(size)) { return sk_64_asS32(size); } return 0; }
jbyteArray GraphicsJNI::allocateJavaPixelRef(JNIEnv* env, SkBitmap* bitmap, SkColorTable* ctable) { const SkImageInfo& info = bitmap->info(); if (info.fColorType == kUnknown_SkColorType) { doThrowIAE(env, "unknown bitmap configuration"); return NULL; } const int64_t size64 = bitmap->computeSize64(); if (!sk_64_isS32(size64)) { doThrowIAE(env, "bitmap size exceeds 32 bits"); return NULL; } const size_t size = sk_64_asS32(size64); jbyteArray arrayObj = (jbyteArray) env->CallObjectMethod(gVMRuntime, gVMRuntime_newNonMovableArray, gByte_class, size); if (env->ExceptionCheck() != 0) { return NULL; } SkASSERT(arrayObj); jbyte* addr = (jbyte*) env->CallLongMethod(gVMRuntime, gVMRuntime_addressOf, arrayObj); if (env->ExceptionCheck() != 0) { return NULL; } SkASSERT(addr); SkPixelRef* pr = new AndroidPixelRef(env, info, (void*) addr, bitmap->rowBytes(), arrayObj, ctable); bitmap->setPixelRef(pr)->unref(); // since we're already allocated, we lockPixels right away // HeapAllocator behaves this way too bitmap->lockPixels(); return arrayObj; }
bool SkRgnBuilder::init(int maxHeight, int maxTransitions, bool pathIsInverse) { if ((maxHeight | maxTransitions) < 0) { return false; } if (pathIsInverse) { // allow for additional X transitions to "invert" each scanline // [ L' ... normal transitions ... R' ] // maxTransitions += 2; } // compute the count with +1 and +3 slop for the working buffer int64_t count = sk_64_mul(maxHeight + 1, 3 + maxTransitions); if (pathIsInverse) { // allow for two "empty" rows for the top and bottom // [ Y, 1, L, R, S] == 5 (*2 for top and bottom) count += 10; } if (count < 0 || !sk_64_isS32(count)) { return false; } fStorageCount = sk_64_asS32(count); int64_t size = sk_64_mul(fStorageCount, sizeof(SkRegion::RunType)); if (size < 0 || !sk_64_isS32(size)) { return false; } fStorage = (SkRegion::RunType*)sk_malloc_flags(sk_64_asS32(size), 0); if (NULL == fStorage) { return false; } fCurrScanline = NULL; // signal empty collection fPrevScanline = NULL; // signal first scanline return true; }
sk_sp<SkPixelRef> SkMallocPixelRef::MakeUsing(void*(*alloc)(size_t), const SkImageInfo& info, size_t requestedRowBytes, sk_sp<SkColorTable> ctable) { if (!is_valid(info, ctable.get())) { 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 } int32_t rowBytes; if (requestedRowBytes) { rowBytes = SkToS32(requestedRowBytes); } else { rowBytes = minRB; } int64_t bigSize = (int64_t)info.height() * rowBytes; if (!sk_64_isS32(bigSize)) { return nullptr; } size_t size = sk_64_asS32(bigSize); SkASSERT(size >= info.getSafeSize(rowBytes)); void* addr = alloc(size); if (nullptr == addr) { return nullptr; } return sk_sp<SkPixelRef>(new SkMallocPixelRef(info, addr, rowBytes, std::move(ctable), sk_free_releaseproc, nullptr)); }
SkMallocPixelRef* SkMallocPixelRef::NewAllocate(const SkImageInfo& info, size_t requestedRowBytes, SkColorTable* ctable) { if (!is_valid(info, ctable)) { return NULL; } // only want to permit 31bits of rowBytes int64_t minRB = (int64_t)info.minRowBytes64(); if (minRB < 0 || !sk_64_isS32(minRB)) { return NULL; // allocation will be too large } if (requestedRowBytes > 0 && (int32_t)requestedRowBytes < minRB) { return NULL; // cannot meet requested rowbytes } int32_t rowBytes; if (requestedRowBytes) { rowBytes = SkToS32(requestedRowBytes); } else { rowBytes = minRB; } int64_t bigSize = (int64_t)info.height() * rowBytes; if (!sk_64_isS32(bigSize)) { return NULL; } size_t size = sk_64_asS32(bigSize); SkASSERT(size >= info.getSafeSize(rowBytes)); void* addr = sk_malloc_flags(size, 0); if (NULL == addr) { return NULL; } return new SkMallocPixelRef(info, addr, rowBytes, ctable, sk_free_releaseproc, NULL); }