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 |