| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "SkMallocPixelRef.h" | 8 #include "SkMallocPixelRef.h" |
| 9 #include "SkBitmap.h" | 9 #include "SkBitmap.h" |
| 10 #include "SkFlattenableBuffers.h" | 10 #include "SkFlattenableBuffers.h" |
| 11 | 11 |
| 12 // assumes ptr was allocated via sk_malloc |
| 13 static void sk_free_releaseproc(void* ptr, void*) { |
| 14 sk_free(ptr); |
| 15 } |
| 16 |
| 12 static bool is_valid(const SkImageInfo& info, SkColorTable* ctable) { | 17 static bool is_valid(const SkImageInfo& info, SkColorTable* ctable) { |
| 13 if (info.fWidth < 0 || | 18 if (info.fWidth < 0 || |
| 14 info.fHeight < 0 || | 19 info.fHeight < 0 || |
| 15 (unsigned)info.fColorType > (unsigned)kLastEnum_SkColorType || | 20 (unsigned)info.fColorType > (unsigned)kLastEnum_SkColorType || |
| 16 (unsigned)info.fAlphaType > (unsigned)kLastEnum_SkAlphaType) | 21 (unsigned)info.fAlphaType > (unsigned)kLastEnum_SkAlphaType) |
| 17 { | 22 { |
| 18 return false; | 23 return false; |
| 19 } | 24 } |
| 20 | 25 |
| 21 // these seem like good checks, but currently we have (at least) tests | 26 // these seem like good checks, but currently we have (at least) tests |
| (...skipping 10 matching lines...) Expand all Loading... |
| 32 return true; | 37 return true; |
| 33 } | 38 } |
| 34 | 39 |
| 35 SkMallocPixelRef* SkMallocPixelRef::NewDirect(const SkImageInfo& info, | 40 SkMallocPixelRef* SkMallocPixelRef::NewDirect(const SkImageInfo& info, |
| 36 void* addr, | 41 void* addr, |
| 37 size_t rowBytes, | 42 size_t rowBytes, |
| 38 SkColorTable* ctable) { | 43 SkColorTable* ctable) { |
| 39 if (!is_valid(info, ctable)) { | 44 if (!is_valid(info, ctable)) { |
| 40 return NULL; | 45 return NULL; |
| 41 } | 46 } |
| 42 return SkNEW_ARGS(SkMallocPixelRef, (info, addr, rowBytes, ctable, false)); | 47 return SkNEW_ARGS(SkMallocPixelRef, |
| 48 (info, addr, rowBytes, ctable, NULL, NULL)); |
| 43 } | 49 } |
| 44 | 50 |
| 45 SkMallocPixelRef* SkMallocPixelRef::NewAllocate(const SkImageInfo& info, | 51 SkMallocPixelRef* SkMallocPixelRef::NewAllocate(const SkImageInfo& info, |
| 46 size_t requestedRowBytes, | 52 size_t requestedRowBytes, |
| 47 SkColorTable* ctable) { | 53 SkColorTable* ctable) { |
| 48 if (!is_valid(info, ctable)) { | 54 if (!is_valid(info, ctable)) { |
| 49 return NULL; | 55 return NULL; |
| 50 } | 56 } |
| 51 | 57 |
| 52 int32_t minRB = info.minRowBytes(); | 58 int32_t minRB = info.minRowBytes(); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 63 } else { | 69 } else { |
| 64 rowBytes = minRB; | 70 rowBytes = minRB; |
| 65 } | 71 } |
| 66 | 72 |
| 67 int64_t bigSize = (int64_t)info.fHeight * rowBytes; | 73 int64_t bigSize = (int64_t)info.fHeight * rowBytes; |
| 68 if (!sk_64_isS32(bigSize)) { | 74 if (!sk_64_isS32(bigSize)) { |
| 69 return NULL; | 75 return NULL; |
| 70 } | 76 } |
| 71 | 77 |
| 72 size_t size = sk_64_asS32(bigSize); | 78 size_t size = sk_64_asS32(bigSize); |
| 79 SkASSERT(size >= info.getSafeSize(rowBytes)); |
| 73 void* addr = sk_malloc_flags(size, 0); | 80 void* addr = sk_malloc_flags(size, 0); |
| 74 if (NULL == addr) { | 81 if (NULL == addr) { |
| 75 return NULL; | 82 return NULL; |
| 76 } | 83 } |
| 77 | 84 |
| 78 return SkNEW_ARGS(SkMallocPixelRef, (info, addr, rowBytes, ctable, true)); | 85 return SkNEW_ARGS(SkMallocPixelRef, |
| 86 (info, addr, rowBytes, ctable, |
| 87 sk_free_releaseproc, NULL)); |
| 88 } |
| 89 |
| 90 SkMallocPixelRef* SkMallocPixelRef::NewWithProc(const SkImageInfo& info, |
| 91 size_t rowBytes, |
| 92 SkColorTable* ctable, |
| 93 void* addr, |
| 94 SkMallocPixelRef::ReleaseProc pr
oc, |
| 95 void* context) { |
| 96 if (!is_valid(info, ctable)) { |
| 97 return NULL; |
| 98 } |
| 99 return SkNEW_ARGS(SkMallocPixelRef, |
| 100 (info, addr, rowBytes, ctable, proc, context)); |
| 101 } |
| 102 |
| 103 static void sk_data_releaseproc(void*, void* dataPtr) { |
| 104 (static_cast<SkData*>(dataPtr))->unref(); |
| 105 } |
| 106 |
| 107 SkMallocPixelRef* SkMallocPixelRef::NewWithData(const SkImageInfo& info, |
| 108 size_t rowBytes, |
| 109 SkColorTable* ctable, |
| 110 SkData* data, |
| 111 size_t offset) { |
| 112 SkASSERT(data != NULL); |
| 113 SkASSERT(offset <= data->size()); |
| 114 if (!is_valid(info, ctable)) { |
| 115 return NULL; |
| 116 } |
| 117 if ((rowBytes < info.minRowBytes()) |
| 118 || ((data->size() - offset) < info.getSafeSize(rowBytes))) { |
| 119 return NULL; |
| 120 } |
| 121 data->ref(); |
| 122 const void* ptr = static_cast<const void*>(data->bytes() + offset); |
| 123 SkMallocPixelRef* pr |
| 124 = SkNEW_ARGS(SkMallocPixelRef, |
| 125 (info, const_cast<void*>(ptr), rowBytes, ctable, |
| 126 sk_data_releaseproc, static_cast<void*>(data))); |
| 127 SkASSERT(pr != NULL); |
| 128 // We rely on the immutability of the pixels to make the |
| 129 // const_cast okay. |
| 130 pr->setImmutable(); |
| 131 return pr; |
| 79 } | 132 } |
| 80 | 133 |
| 81 /////////////////////////////////////////////////////////////////////////////// | 134 /////////////////////////////////////////////////////////////////////////////// |
| 82 | 135 |
| 83 SkMallocPixelRef::SkMallocPixelRef(const SkImageInfo& info, void* storage, | 136 SkMallocPixelRef::SkMallocPixelRef(const SkImageInfo& info, void* storage, |
| 84 size_t rowBytes, SkColorTable* ctable, | 137 size_t rowBytes, SkColorTable* ctable, |
| 85 bool ownsPixels) | 138 bool ownsPixels) |
| 86 : INHERITED(info) | 139 : INHERITED(info) |
| 87 , fOwnPixels(ownsPixels) | 140 , fReleaseProc(ownsPixels ? sk_free_releaseproc : NULL) |
| 141 , fReleaseProcContext(NULL) { |
| 142 // This constructor is now DEPRICATED. |
| 143 SkASSERT(is_valid(info, ctable)); |
| 144 SkASSERT(rowBytes >= info.minRowBytes()); |
| 145 |
| 146 if (kIndex_8_SkColorType != info.fColorType) { |
| 147 ctable = NULL; |
| 148 } |
| 149 |
| 150 fStorage = storage; |
| 151 fCTable = ctable; |
| 152 fRB = rowBytes; |
| 153 SkSafeRef(ctable); |
| 154 |
| 155 this->setPreLocked(fStorage, fCTable); |
| 156 } |
| 157 |
| 158 SkMallocPixelRef::SkMallocPixelRef(const SkImageInfo& info, void* storage, |
| 159 size_t rowBytes, SkColorTable* ctable, |
| 160 SkMallocPixelRef::ReleaseProc proc, |
| 161 void* context) |
| 162 : INHERITED(info) |
| 163 , fReleaseProc(proc) |
| 164 , fReleaseProcContext(context) |
| 88 { | 165 { |
| 89 SkASSERT(is_valid(info, ctable)); | 166 SkASSERT(is_valid(info, ctable)); |
| 90 SkASSERT(rowBytes >= info.minRowBytes()); | 167 SkASSERT(rowBytes >= info.minRowBytes()); |
| 91 | 168 |
| 92 if (kIndex_8_SkColorType != info.fColorType) { | 169 if (kIndex_8_SkColorType != info.fColorType) { |
| 93 ctable = NULL; | 170 ctable = NULL; |
| 94 } | 171 } |
| 95 | 172 |
| 96 fStorage = storage; | 173 fStorage = storage; |
| 97 fCTable = ctable; | 174 fCTable = ctable; |
| 98 fRB = rowBytes; | 175 fRB = rowBytes; |
| 99 SkSafeRef(ctable); | 176 SkSafeRef(ctable); |
| 100 | 177 |
| 101 this->setPreLocked(fStorage, fCTable); | 178 this->setPreLocked(fStorage, fCTable); |
| 102 } | 179 } |
| 103 | 180 |
| 181 |
| 104 SkMallocPixelRef::~SkMallocPixelRef() { | 182 SkMallocPixelRef::~SkMallocPixelRef() { |
| 105 SkSafeUnref(fCTable); | 183 SkSafeUnref(fCTable); |
| 106 if (fOwnPixels) { | 184 if (fReleaseProc != NULL) { |
| 107 sk_free(fStorage); | 185 fReleaseProc(fStorage, fReleaseProcContext); |
| 108 } | 186 } |
| 109 } | 187 } |
| 110 | 188 |
| 111 void* SkMallocPixelRef::onLockPixels(SkColorTable** ctable) { | 189 void* SkMallocPixelRef::onLockPixels(SkColorTable** ctable) { |
| 112 *ctable = fCTable; | 190 *ctable = fCTable; |
| 113 return fStorage; | 191 return fStorage; |
| 114 } | 192 } |
| 115 | 193 |
| 116 void SkMallocPixelRef::onUnlockPixels() { | 194 void SkMallocPixelRef::onUnlockPixels() { |
| 117 // nothing to do | 195 // nothing to do |
| (...skipping 13 matching lines...) Expand all Loading... |
| 131 size_t size = this->info().getSafeSize(fRB); | 209 size_t size = this->info().getSafeSize(fRB); |
| 132 buffer.writeByteArray(fStorage, size); | 210 buffer.writeByteArray(fStorage, size); |
| 133 buffer.writeBool(fCTable != NULL); | 211 buffer.writeBool(fCTable != NULL); |
| 134 if (fCTable) { | 212 if (fCTable) { |
| 135 fCTable->writeToBuffer(buffer); | 213 fCTable->writeToBuffer(buffer); |
| 136 } | 214 } |
| 137 } | 215 } |
| 138 | 216 |
| 139 SkMallocPixelRef::SkMallocPixelRef(SkFlattenableReadBuffer& buffer) | 217 SkMallocPixelRef::SkMallocPixelRef(SkFlattenableReadBuffer& buffer) |
| 140 : INHERITED(buffer, NULL) | 218 : INHERITED(buffer, NULL) |
| 141 , fOwnPixels(true) | 219 , fReleaseProc(sk_free_releaseproc) |
| 220 , fReleaseProcContext(NULL) |
| 142 { | 221 { |
| 143 fRB = buffer.read32(); | 222 fRB = buffer.read32(); |
| 144 size_t size = buffer.isValid() ? this->info().getSafeSize(fRB) : 0; | 223 size_t size = buffer.isValid() ? this->info().getSafeSize(fRB) : 0; |
| 145 if (buffer.validateAvailable(size)) { | 224 if (buffer.validateAvailable(size)) { |
| 146 fStorage = sk_malloc_throw(size); | 225 fStorage = sk_malloc_throw(size); |
| 147 buffer.readByteArray(fStorage, size); | 226 buffer.readByteArray(fStorage, size); |
| 148 } else { | 227 } else { |
| 149 fStorage = NULL; | 228 fStorage = NULL; |
| 150 } | 229 } |
| 151 | 230 |
| 152 if (buffer.readBool()) { | 231 if (buffer.readBool()) { |
| 153 fCTable = SkNEW_ARGS(SkColorTable, (buffer)); | 232 fCTable = SkNEW_ARGS(SkColorTable, (buffer)); |
| 154 } else { | 233 } else { |
| 155 fCTable = NULL; | 234 fCTable = NULL; |
| 156 } | 235 } |
| 157 | 236 |
| 158 this->setPreLocked(fStorage, fCTable); | 237 this->setPreLocked(fStorage, fCTable); |
| 159 } | 238 } |
| OLD | NEW |