1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/src/core/SkMallocPixelRef.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,248 @@ 1.4 +/* 1.5 + * Copyright 2011 Google Inc. 1.6 + * 1.7 + * Use of this source code is governed by a BSD-style license that can be 1.8 + * found in the LICENSE file. 1.9 + */ 1.10 + 1.11 +#include "SkMallocPixelRef.h" 1.12 +#include "SkBitmap.h" 1.13 +#include "SkReadBuffer.h" 1.14 +#include "SkWriteBuffer.h" 1.15 + 1.16 +// assumes ptr was allocated via sk_malloc 1.17 +static void sk_free_releaseproc(void* ptr, void*) { 1.18 + sk_free(ptr); 1.19 +} 1.20 + 1.21 +static bool is_valid(const SkImageInfo& info, SkColorTable* ctable) { 1.22 + if (info.fWidth < 0 || 1.23 + info.fHeight < 0 || 1.24 + (unsigned)info.fColorType > (unsigned)kLastEnum_SkColorType || 1.25 + (unsigned)info.fAlphaType > (unsigned)kLastEnum_SkAlphaType) 1.26 + { 1.27 + return false; 1.28 + } 1.29 + 1.30 + // these seem like good checks, but currently we have (at least) tests 1.31 + // that expect the pixelref to succeed even when there is a mismatch 1.32 + // with colortables. fix? 1.33 +#if 0 1.34 + if (kIndex8_SkColorType == info.fColorType && NULL == ctable) { 1.35 + return false; 1.36 + } 1.37 + if (kIndex8_SkColorType != info.fColorType && NULL != ctable) { 1.38 + return false; 1.39 + } 1.40 +#endif 1.41 + return true; 1.42 +} 1.43 + 1.44 +SkMallocPixelRef* SkMallocPixelRef::NewDirect(const SkImageInfo& info, 1.45 + void* addr, 1.46 + size_t rowBytes, 1.47 + SkColorTable* ctable) { 1.48 + if (!is_valid(info, ctable)) { 1.49 + return NULL; 1.50 + } 1.51 + return SkNEW_ARGS(SkMallocPixelRef, 1.52 + (info, addr, rowBytes, ctable, NULL, NULL)); 1.53 +} 1.54 + 1.55 +SkMallocPixelRef* SkMallocPixelRef::NewAllocate(const SkImageInfo& info, 1.56 + size_t requestedRowBytes, 1.57 + SkColorTable* ctable) { 1.58 + if (!is_valid(info, ctable)) { 1.59 + return NULL; 1.60 + } 1.61 + 1.62 + int32_t minRB = SkToS32(info.minRowBytes()); 1.63 + if (minRB < 0) { 1.64 + return NULL; // allocation will be too large 1.65 + } 1.66 + if (requestedRowBytes > 0 && (int32_t)requestedRowBytes < minRB) { 1.67 + return NULL; // cannot meet requested rowbytes 1.68 + } 1.69 + 1.70 + int32_t rowBytes; 1.71 + if (requestedRowBytes) { 1.72 + rowBytes = SkToS32(requestedRowBytes); 1.73 + } else { 1.74 + rowBytes = minRB; 1.75 + } 1.76 + 1.77 + int64_t bigSize = (int64_t)info.fHeight * rowBytes; 1.78 + if (!sk_64_isS32(bigSize)) { 1.79 + return NULL; 1.80 + } 1.81 + 1.82 + size_t size = sk_64_asS32(bigSize); 1.83 + SkASSERT(size >= info.getSafeSize(rowBytes)); 1.84 + void* addr = sk_malloc_flags(size, 0); 1.85 + if (NULL == addr) { 1.86 + return NULL; 1.87 + } 1.88 + 1.89 + return SkNEW_ARGS(SkMallocPixelRef, 1.90 + (info, addr, rowBytes, ctable, 1.91 + sk_free_releaseproc, NULL)); 1.92 +} 1.93 + 1.94 +SkMallocPixelRef* SkMallocPixelRef::NewWithProc(const SkImageInfo& info, 1.95 + size_t rowBytes, 1.96 + SkColorTable* ctable, 1.97 + void* addr, 1.98 + SkMallocPixelRef::ReleaseProc proc, 1.99 + void* context) { 1.100 + if (!is_valid(info, ctable)) { 1.101 + return NULL; 1.102 + } 1.103 + return SkNEW_ARGS(SkMallocPixelRef, 1.104 + (info, addr, rowBytes, ctable, proc, context)); 1.105 +} 1.106 + 1.107 +static void sk_data_releaseproc(void*, void* dataPtr) { 1.108 + (static_cast<SkData*>(dataPtr))->unref(); 1.109 +} 1.110 + 1.111 +SkMallocPixelRef* SkMallocPixelRef::NewWithData(const SkImageInfo& info, 1.112 + size_t rowBytes, 1.113 + SkColorTable* ctable, 1.114 + SkData* data, 1.115 + size_t offset) { 1.116 + SkASSERT(data != NULL); 1.117 + SkASSERT(offset <= data->size()); 1.118 + if (!is_valid(info, ctable)) { 1.119 + return NULL; 1.120 + } 1.121 + if ((rowBytes < info.minRowBytes()) 1.122 + || ((data->size() - offset) < info.getSafeSize(rowBytes))) { 1.123 + return NULL; 1.124 + } 1.125 + data->ref(); 1.126 + const void* ptr = static_cast<const void*>(data->bytes() + offset); 1.127 + SkMallocPixelRef* pr 1.128 + = SkNEW_ARGS(SkMallocPixelRef, 1.129 + (info, const_cast<void*>(ptr), rowBytes, ctable, 1.130 + sk_data_releaseproc, static_cast<void*>(data))); 1.131 + SkASSERT(pr != NULL); 1.132 + // We rely on the immutability of the pixels to make the 1.133 + // const_cast okay. 1.134 + pr->setImmutable(); 1.135 + return pr; 1.136 +} 1.137 + 1.138 +/////////////////////////////////////////////////////////////////////////////// 1.139 + 1.140 +SkMallocPixelRef::SkMallocPixelRef(const SkImageInfo& info, void* storage, 1.141 + size_t rowBytes, SkColorTable* ctable, 1.142 + bool ownsPixels) 1.143 + : INHERITED(info) 1.144 + , fReleaseProc(ownsPixels ? sk_free_releaseproc : NULL) 1.145 + , fReleaseProcContext(NULL) { 1.146 + // This constructor is now DEPRICATED. 1.147 + SkASSERT(is_valid(info, ctable)); 1.148 + SkASSERT(rowBytes >= info.minRowBytes()); 1.149 + 1.150 + if (kIndex_8_SkColorType != info.fColorType) { 1.151 + ctable = NULL; 1.152 + } 1.153 + 1.154 + fStorage = storage; 1.155 + fCTable = ctable; 1.156 + fRB = rowBytes; 1.157 + SkSafeRef(ctable); 1.158 + 1.159 + this->setPreLocked(fStorage, rowBytes, fCTable); 1.160 +} 1.161 + 1.162 +SkMallocPixelRef::SkMallocPixelRef(const SkImageInfo& info, void* storage, 1.163 + size_t rowBytes, SkColorTable* ctable, 1.164 + SkMallocPixelRef::ReleaseProc proc, 1.165 + void* context) 1.166 + : INHERITED(info) 1.167 + , fReleaseProc(proc) 1.168 + , fReleaseProcContext(context) 1.169 +{ 1.170 + SkASSERT(is_valid(info, ctable)); 1.171 + SkASSERT(rowBytes >= info.minRowBytes()); 1.172 + 1.173 + if (kIndex_8_SkColorType != info.fColorType) { 1.174 + ctable = NULL; 1.175 + } 1.176 + 1.177 + fStorage = storage; 1.178 + fCTable = ctable; 1.179 + fRB = rowBytes; 1.180 + SkSafeRef(ctable); 1.181 + 1.182 + this->setPreLocked(fStorage, rowBytes, fCTable); 1.183 +} 1.184 + 1.185 + 1.186 +SkMallocPixelRef::~SkMallocPixelRef() { 1.187 + SkSafeUnref(fCTable); 1.188 + if (fReleaseProc != NULL) { 1.189 + fReleaseProc(fStorage, fReleaseProcContext); 1.190 + } 1.191 +} 1.192 + 1.193 +bool SkMallocPixelRef::onNewLockPixels(LockRec* rec) { 1.194 + rec->fPixels = fStorage; 1.195 + rec->fRowBytes = fRB; 1.196 + rec->fColorTable = fCTable; 1.197 + return true; 1.198 +} 1.199 + 1.200 +void SkMallocPixelRef::onUnlockPixels() { 1.201 + // nothing to do 1.202 +} 1.203 + 1.204 +size_t SkMallocPixelRef::getAllocatedSizeInBytes() const { 1.205 + return this->info().getSafeSize(fRB); 1.206 +} 1.207 + 1.208 +void SkMallocPixelRef::flatten(SkWriteBuffer& buffer) const { 1.209 + this->INHERITED::flatten(buffer); 1.210 + 1.211 + buffer.write32(SkToU32(fRB)); 1.212 + 1.213 + // TODO: replace this bulk write with a chunky one that can trim off any 1.214 + // trailing bytes on each scanline (in case rowbytes > width*size) 1.215 + size_t size = this->info().getSafeSize(fRB); 1.216 + buffer.writeByteArray(fStorage, size); 1.217 + buffer.writeBool(fCTable != NULL); 1.218 + if (fCTable) { 1.219 + fCTable->writeToBuffer(buffer); 1.220 + } 1.221 +} 1.222 + 1.223 +SkMallocPixelRef::SkMallocPixelRef(SkReadBuffer& buffer) 1.224 + : INHERITED(buffer, NULL) 1.225 + , fReleaseProc(sk_free_releaseproc) 1.226 + , fReleaseProcContext(NULL) 1.227 +{ 1.228 + fRB = buffer.read32(); 1.229 + size_t size = buffer.isValid() ? this->info().getSafeSize(fRB) : 0; 1.230 + if (buffer.validateAvailable(size)) { 1.231 + fStorage = sk_malloc_throw(size); 1.232 + buffer.readByteArray(fStorage, size); 1.233 + } else { 1.234 + fStorage = NULL; 1.235 + } 1.236 + 1.237 + if (buffer.readBool()) { 1.238 + fCTable = SkNEW_ARGS(SkColorTable, (buffer)); 1.239 + } else { 1.240 + fCTable = NULL; 1.241 + } 1.242 + 1.243 + this->setPreLocked(fStorage, fRB, fCTable); 1.244 +} 1.245 + 1.246 +/////////////////////////////////////////////////////////////////////////////// 1.247 + 1.248 +SkPixelRef* SkMallocPixelRef::PRFactory::create(const SkImageInfo& info, 1.249 + SkColorTable* ctable) { 1.250 + return SkMallocPixelRef::NewAllocate(info, info.minRowBytes(), ctable); 1.251 +}