1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2011 Google Inc. 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#include "include/core/SkMallocPixelRef.h" 9cb93a386Sopenharmony_ci 10cb93a386Sopenharmony_ci#include "include/core/SkData.h" 11cb93a386Sopenharmony_ci#include "include/core/SkImageInfo.h" 12cb93a386Sopenharmony_ci#include "include/private/SkMalloc.h" 13cb93a386Sopenharmony_ci 14cb93a386Sopenharmony_cistatic bool is_valid(const SkImageInfo& info) { 15cb93a386Sopenharmony_ci if (info.width() < 0 || info.height() < 0 || 16cb93a386Sopenharmony_ci (unsigned)info.colorType() > (unsigned)kLastEnum_SkColorType || 17cb93a386Sopenharmony_ci (unsigned)info.alphaType() > (unsigned)kLastEnum_SkAlphaType) 18cb93a386Sopenharmony_ci { 19cb93a386Sopenharmony_ci return false; 20cb93a386Sopenharmony_ci } 21cb93a386Sopenharmony_ci return true; 22cb93a386Sopenharmony_ci} 23cb93a386Sopenharmony_ci 24cb93a386Sopenharmony_cisk_sp<SkPixelRef> SkMallocPixelRef::MakeAllocate(const SkImageInfo& info, size_t rowBytes) { 25cb93a386Sopenharmony_ci if (rowBytes == 0) { 26cb93a386Sopenharmony_ci rowBytes = info.minRowBytes(); 27cb93a386Sopenharmony_ci // rowBytes can still be zero, if it overflowed (width * bytesPerPixel > size_t) 28cb93a386Sopenharmony_ci // or if colortype is unknown 29cb93a386Sopenharmony_ci } 30cb93a386Sopenharmony_ci if (!is_valid(info) || !info.validRowBytes(rowBytes)) { 31cb93a386Sopenharmony_ci return nullptr; 32cb93a386Sopenharmony_ci } 33cb93a386Sopenharmony_ci size_t size = info.computeByteSize(rowBytes); 34cb93a386Sopenharmony_ci if (SkImageInfo::ByteSizeOverflowed(size)) { 35cb93a386Sopenharmony_ci return nullptr; 36cb93a386Sopenharmony_ci } 37cb93a386Sopenharmony_ci#if defined(SK_BUILD_FOR_FUZZER) 38cb93a386Sopenharmony_ci if (size > 100000) { 39cb93a386Sopenharmony_ci return nullptr; 40cb93a386Sopenharmony_ci } 41cb93a386Sopenharmony_ci#endif 42cb93a386Sopenharmony_ci void* addr = sk_calloc_canfail(size); 43cb93a386Sopenharmony_ci if (nullptr == addr) { 44cb93a386Sopenharmony_ci return nullptr; 45cb93a386Sopenharmony_ci } 46cb93a386Sopenharmony_ci 47cb93a386Sopenharmony_ci struct PixelRef final : public SkPixelRef { 48cb93a386Sopenharmony_ci PixelRef(int w, int h, void* s, size_t r) : SkPixelRef(w, h, s, r) {} 49cb93a386Sopenharmony_ci ~PixelRef() override { sk_free(this->pixels()); } 50cb93a386Sopenharmony_ci }; 51cb93a386Sopenharmony_ci return sk_sp<SkPixelRef>(new PixelRef(info.width(), info.height(), addr, rowBytes)); 52cb93a386Sopenharmony_ci} 53cb93a386Sopenharmony_ci 54cb93a386Sopenharmony_cisk_sp<SkPixelRef> SkMallocPixelRef::MakeWithData(const SkImageInfo& info, 55cb93a386Sopenharmony_ci size_t rowBytes, 56cb93a386Sopenharmony_ci sk_sp<SkData> data) { 57cb93a386Sopenharmony_ci SkASSERT(data != nullptr); 58cb93a386Sopenharmony_ci if (!is_valid(info)) { 59cb93a386Sopenharmony_ci return nullptr; 60cb93a386Sopenharmony_ci } 61cb93a386Sopenharmony_ci // TODO: what should we return if computeByteSize returns 0? 62cb93a386Sopenharmony_ci // - the info was empty? 63cb93a386Sopenharmony_ci // - we overflowed computing the size? 64cb93a386Sopenharmony_ci if ((rowBytes < info.minRowBytes()) || (data->size() < info.computeByteSize(rowBytes))) { 65cb93a386Sopenharmony_ci return nullptr; 66cb93a386Sopenharmony_ci } 67cb93a386Sopenharmony_ci struct PixelRef final : public SkPixelRef { 68cb93a386Sopenharmony_ci sk_sp<SkData> fData; 69cb93a386Sopenharmony_ci PixelRef(int w, int h, void* s, size_t r, sk_sp<SkData> d) 70cb93a386Sopenharmony_ci : SkPixelRef(w, h, s, r), fData(std::move(d)) {} 71cb93a386Sopenharmony_ci }; 72cb93a386Sopenharmony_ci void* pixels = const_cast<void*>(data->data()); 73cb93a386Sopenharmony_ci sk_sp<SkPixelRef> pr(new PixelRef(info.width(), info.height(), pixels, rowBytes, 74cb93a386Sopenharmony_ci std::move(data))); 75cb93a386Sopenharmony_ci pr->setImmutable(); // since we were created with (immutable) data 76cb93a386Sopenharmony_ci return pr; 77cb93a386Sopenharmony_ci} 78