OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2008 The Android Open Source Project | 3 * Copyright 2008 The Android Open Source Project |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 | 8 |
9 | 9 |
10 #include "SkBitmap.h" | 10 #include "SkBitmap.h" |
11 #include "SkColorPriv.h" | 11 #include "SkColorPriv.h" |
12 #include "SkDither.h" | 12 #include "SkDither.h" |
13 #include "SkFlattenable.h" | 13 #include "SkFlattenable.h" |
14 #include "SkImagePriv.h" | 14 #include "SkImagePriv.h" |
15 #include "SkMallocPixelRef.h" | 15 #include "SkMallocPixelRef.h" |
16 #include "SkMask.h" | 16 #include "SkMask.h" |
17 #include "SkReadBuffer.h" | 17 #include "SkReadBuffer.h" |
18 #include "SkWriteBuffer.h" | 18 #include "SkWriteBuffer.h" |
19 #include "SkPixelRef.h" | 19 #include "SkPixelRef.h" |
20 #include "SkThread.h" | 20 #include "SkThread.h" |
21 #include "SkUnPreMultiply.h" | 21 #include "SkUnPreMultiply.h" |
22 #include "SkUtils.h" | 22 #include "SkUtils.h" |
23 #include "SkValidationUtils.h" | 23 #include "SkValidationUtils.h" |
24 #include "SkPackBits.h" | 24 #include "SkPackBits.h" |
25 #include <new> | 25 #include <new> |
26 | 26 |
| 27 static bool reset_return_false(SkBitmap* bm) { |
| 28 bm->reset(); |
| 29 return false; |
| 30 } |
| 31 |
27 struct MipLevel { | 32 struct MipLevel { |
28 void* fPixels; | 33 void* fPixels; |
29 uint32_t fRowBytes; | 34 uint32_t fRowBytes; |
30 uint32_t fWidth, fHeight; | 35 uint32_t fWidth, fHeight; |
31 }; | 36 }; |
32 | 37 |
33 struct SkBitmap::MipMap : SkNoncopyable { | 38 struct SkBitmap::MipMap : SkNoncopyable { |
34 int32_t fRefCnt; | 39 int32_t fRefCnt; |
35 int fLevelCount; | 40 int fLevelCount; |
36 // MipLevel fLevel[fLevelCount]; | 41 // MipLevel fLevel[fLevelCount]; |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
118 return *this; | 123 return *this; |
119 } | 124 } |
120 | 125 |
121 void SkBitmap::swap(SkBitmap& other) { | 126 void SkBitmap::swap(SkBitmap& other) { |
122 SkTSwap(fColorTable, other.fColorTable); | 127 SkTSwap(fColorTable, other.fColorTable); |
123 SkTSwap(fPixelRef, other.fPixelRef); | 128 SkTSwap(fPixelRef, other.fPixelRef); |
124 SkTSwap(fPixelRefOrigin, other.fPixelRefOrigin); | 129 SkTSwap(fPixelRefOrigin, other.fPixelRefOrigin); |
125 SkTSwap(fPixelLockCount, other.fPixelLockCount); | 130 SkTSwap(fPixelLockCount, other.fPixelLockCount); |
126 SkTSwap(fMipMap, other.fMipMap); | 131 SkTSwap(fMipMap, other.fMipMap); |
127 SkTSwap(fPixels, other.fPixels); | 132 SkTSwap(fPixels, other.fPixels); |
| 133 SkTSwap(fInfo, other.fInfo); |
128 SkTSwap(fRowBytes, other.fRowBytes); | 134 SkTSwap(fRowBytes, other.fRowBytes); |
129 SkTSwap(fWidth, other.fWidth); | |
130 SkTSwap(fHeight, other.fHeight); | |
131 SkTSwap(fConfig, other.fConfig); | |
132 SkTSwap(fAlphaType, other.fAlphaType); | |
133 SkTSwap(fFlags, other.fFlags); | 135 SkTSwap(fFlags, other.fFlags); |
134 SkTSwap(fBytesPerPixel, other.fBytesPerPixel); | |
135 | 136 |
136 SkDEBUGCODE(this->validate();) | 137 SkDEBUGCODE(this->validate();) |
137 } | 138 } |
138 | 139 |
139 void SkBitmap::reset() { | 140 void SkBitmap::reset() { |
140 this->freePixels(); | 141 this->freePixels(); |
141 sk_bzero(this, sizeof(*this)); | 142 sk_bzero(this, sizeof(*this)); |
142 } | 143 } |
143 | 144 |
| 145 SkBitmap::Config SkBitmap::config() const { |
| 146 return SkColorTypeToBitmapConfig(fInfo.colorType()); |
| 147 } |
| 148 |
144 int SkBitmap::ComputeBytesPerPixel(SkBitmap::Config config) { | 149 int SkBitmap::ComputeBytesPerPixel(SkBitmap::Config config) { |
145 int bpp; | 150 int bpp; |
146 switch (config) { | 151 switch (config) { |
147 case kNo_Config: | 152 case kNo_Config: |
148 bpp = 0; // not applicable | 153 bpp = 0; // not applicable |
149 break; | 154 break; |
150 case kA8_Config: | 155 case kA8_Config: |
151 case kIndex8_Config: | 156 case kIndex8_Config: |
152 bpp = 1; | 157 bpp = 1; |
153 break; | 158 break; |
154 case kRGB_565_Config: | 159 case kRGB_565_Config: |
155 case kARGB_4444_Config: | 160 case kARGB_4444_Config: |
156 bpp = 2; | 161 bpp = 2; |
157 break; | 162 break; |
158 case kARGB_8888_Config: | 163 case kARGB_8888_Config: |
159 bpp = 4; | 164 bpp = 4; |
160 break; | 165 break; |
161 default: | 166 default: |
162 SkDEBUGFAIL("unknown config"); | 167 SkDEBUGFAIL("unknown config"); |
163 bpp = 0; // error | 168 bpp = 0; // error |
164 break; | 169 break; |
165 } | 170 } |
166 return bpp; | 171 return bpp; |
167 } | 172 } |
168 | 173 |
169 size_t SkBitmap::ComputeRowBytes(Config c, int width) { | 174 size_t SkBitmap::ComputeRowBytes(Config c, int width) { |
170 if (width < 0) { | 175 return SkColorTypeMinRowBytes(SkBitmapConfigToColorType(c), width); |
171 return 0; | |
172 } | |
173 | |
174 int64_t rowBytes = 0; | |
175 | |
176 switch (c) { | |
177 case kNo_Config: | |
178 break; | |
179 case kA8_Config: | |
180 case kIndex8_Config: | |
181 rowBytes = width; | |
182 break; | |
183 case kRGB_565_Config: | |
184 case kARGB_4444_Config: | |
185 // assign and then shift, so we don't overflow int | |
186 rowBytes = width; | |
187 rowBytes <<= 1; | |
188 break; | |
189 case kARGB_8888_Config: | |
190 // assign and then shift, so we don't overflow int | |
191 rowBytes = width; | |
192 rowBytes <<= 2; | |
193 break; | |
194 default: | |
195 SkDEBUGFAIL("unknown config"); | |
196 break; | |
197 } | |
198 return sk_64_isS32(rowBytes) ? sk_64_asS32(rowBytes) : 0; | |
199 } | 176 } |
200 | 177 |
201 int64_t SkBitmap::ComputeSize64(Config config, int width, int height) { | 178 int64_t SkBitmap::ComputeSize64(Config config, int width, int height) { |
202 int64_t rowBytes = sk_64_mul(ComputeBytesPerPixel(config), width); | 179 SkColorType ct = SkBitmapConfigToColorType(config); |
| 180 int64_t rowBytes = sk_64_mul(SkColorTypeBytesPerPixel(ct), width); |
203 return rowBytes * height; | 181 return rowBytes * height; |
204 } | 182 } |
205 | 183 |
206 size_t SkBitmap::ComputeSize(Config c, int width, int height) { | 184 size_t SkBitmap::ComputeSize(Config c, int width, int height) { |
207 int64_t size = SkBitmap::ComputeSize64(c, width, height); | 185 int64_t size = SkBitmap::ComputeSize64(c, width, height); |
208 return sk_64_isS32(size) ? sk_64_asS32(size) : 0; | 186 return sk_64_isS32(size) ? sk_64_asS32(size) : 0; |
209 } | 187 } |
210 | 188 |
211 int64_t SkBitmap::ComputeSafeSize64(Config config, | 189 int64_t SkBitmap::ComputeSafeSize64(Config config, |
212 uint32_t width, | 190 uint32_t width, |
213 uint32_t height, | 191 uint32_t height, |
214 size_t rowBytes) { | 192 size_t rowBytes) { |
215 int64_t safeSize = 0; | 193 SkImageInfo info = SkImageInfo::Make(width, height, |
216 if (height > 0) { | 194 SkBitmapConfigToColorType(config), |
217 int64_t lastRow = sk_64_mul(ComputeBytesPerPixel(config), width); | 195 kPremul_SkAlphaType); |
218 safeSize = sk_64_mul(height - 1, rowBytes) + lastRow; | 196 return info.getSafeSize64(rowBytes); |
219 } | |
220 SkASSERT(safeSize >= 0); | |
221 return safeSize; | |
222 } | 197 } |
223 | 198 |
224 size_t SkBitmap::ComputeSafeSize(Config config, | 199 size_t SkBitmap::ComputeSafeSize(Config config, |
225 uint32_t width, | 200 uint32_t width, |
226 uint32_t height, | 201 uint32_t height, |
227 size_t rowBytes) { | 202 size_t rowBytes) { |
228 int64_t safeSize = ComputeSafeSize64(config, width, height, rowBytes); | 203 int64_t safeSize = ComputeSafeSize64(config, width, height, rowBytes); |
229 int32_t safeSize32 = (int32_t)safeSize; | 204 int32_t safeSize32 = (int32_t)safeSize; |
230 | 205 |
231 if (safeSize32 != safeSize) { | 206 if (safeSize32 != safeSize) { |
232 safeSize32 = 0; | 207 safeSize32 = 0; |
233 } | 208 } |
234 return safeSize32; | 209 return safeSize32; |
235 } | 210 } |
236 | 211 |
237 void SkBitmap::getBounds(SkRect* bounds) const { | 212 void SkBitmap::getBounds(SkRect* bounds) const { |
238 SkASSERT(bounds); | 213 SkASSERT(bounds); |
239 bounds->set(0, 0, | 214 bounds->set(0, 0, |
240 SkIntToScalar(fWidth), SkIntToScalar(fHeight)); | 215 SkIntToScalar(fInfo.fWidth), SkIntToScalar(fInfo.fHeight)); |
241 } | 216 } |
242 | 217 |
243 void SkBitmap::getBounds(SkIRect* bounds) const { | 218 void SkBitmap::getBounds(SkIRect* bounds) const { |
244 SkASSERT(bounds); | 219 SkASSERT(bounds); |
245 bounds->set(0, 0, fWidth, fHeight); | 220 bounds->set(0, 0, fInfo.fWidth, fInfo.fHeight); |
246 } | 221 } |
247 | 222 |
248 /////////////////////////////////////////////////////////////////////////////// | 223 /////////////////////////////////////////////////////////////////////////////// |
249 | 224 |
250 static bool validate_alphaType(SkBitmap::Config config, SkAlphaType alphaType, | 225 static bool validate_alphaType(SkColorType colorType, SkAlphaType alphaType, |
251 SkAlphaType* canonical = NULL) { | 226 SkAlphaType* canonical = NULL) { |
252 switch (config) { | 227 switch (colorType) { |
253 case SkBitmap::kNo_Config: | 228 case kUnknown_SkColorType: |
254 alphaType = kIgnore_SkAlphaType; | 229 alphaType = kIgnore_SkAlphaType; |
255 break; | 230 break; |
256 case SkBitmap::kA8_Config: | 231 case kAlpha_8_SkColorType: |
257 if (kUnpremul_SkAlphaType == alphaType) { | 232 if (kUnpremul_SkAlphaType == alphaType) { |
258 alphaType = kPremul_SkAlphaType; | 233 alphaType = kPremul_SkAlphaType; |
259 } | 234 } |
260 // fall-through | 235 // fall-through |
261 case SkBitmap::kIndex8_Config: | 236 case kIndex_8_SkColorType: |
262 case SkBitmap::kARGB_4444_Config: | 237 case kARGB_4444_SkColorType: |
263 case SkBitmap::kARGB_8888_Config: | 238 case kRGBA_8888_SkColorType: |
| 239 case kBGRA_8888_SkColorType: |
264 if (kIgnore_SkAlphaType == alphaType) { | 240 if (kIgnore_SkAlphaType == alphaType) { |
265 return false; | 241 return false; |
266 } | 242 } |
267 break; | 243 break; |
268 case SkBitmap::kRGB_565_Config: | 244 case kRGB_565_SkColorType: |
269 alphaType = kOpaque_SkAlphaType; | 245 alphaType = kOpaque_SkAlphaType; |
270 break; | 246 break; |
271 default: | 247 default: |
272 return false; | 248 return false; |
273 } | 249 } |
274 if (canonical) { | 250 if (canonical) { |
275 *canonical = alphaType; | 251 *canonical = alphaType; |
276 } | 252 } |
277 return true; | 253 return true; |
278 } | 254 } |
279 | 255 |
| 256 bool SkBitmap::setConfig(const SkImageInfo& info, size_t rowBytes) { |
| 257 // require that rowBytes fit in 31bits |
| 258 int64_t mrb = info.minRowBytes64(); |
| 259 if ((int32_t)mrb != mrb) { |
| 260 return reset_return_false(this); |
| 261 } |
| 262 if ((ssize_t)rowBytes != (int32_t)rowBytes) { |
| 263 return reset_return_false(this); |
| 264 } |
| 265 |
| 266 if (info.isEmpty()) { |
| 267 return reset_return_false(this); |
| 268 } |
| 269 |
| 270 if (kUnknown_SkColorType == info.colorType()) { |
| 271 rowBytes = 0; |
| 272 } else if (0 == rowBytes) { |
| 273 rowBytes = (size_t)mrb; |
| 274 } else if (rowBytes < info.minRowBytes()) { |
| 275 return reset_return_false(this); |
| 276 } |
| 277 |
| 278 this->freePixels(); |
| 279 |
| 280 fInfo = info; |
| 281 fRowBytes = SkToU32(rowBytes); |
| 282 return true; |
| 283 } |
| 284 |
280 bool SkBitmap::setConfig(Config config, int width, int height, size_t rowBytes, | 285 bool SkBitmap::setConfig(Config config, int width, int height, size_t rowBytes, |
281 SkAlphaType alphaType) { | 286 SkAlphaType alphaType) { |
282 if ((width | height) < 0) { | 287 SkColorType ct = SkBitmapConfigToColorType(config); |
283 goto BAD_CONFIG; | 288 return this->setConfig(SkImageInfo::Make(width, height, ct, alphaType), |
284 } | 289 rowBytes); |
285 if (rowBytes == 0) { | |
286 rowBytes = SkBitmap::ComputeRowBytes(config, width); | |
287 if (0 == rowBytes && kNo_Config != config && width > 0) { | |
288 goto BAD_CONFIG; | |
289 } | |
290 } | |
291 | |
292 if (!validate_alphaType(config, alphaType, &alphaType)) { | |
293 goto BAD_CONFIG; | |
294 } | |
295 | |
296 this->freePixels(); | |
297 | |
298 fConfig = SkToU8(config); | |
299 fAlphaType = SkToU8(alphaType); | |
300 fWidth = width; | |
301 fHeight = height; | |
302 fRowBytes = SkToU32(rowBytes); | |
303 | |
304 fBytesPerPixel = (uint8_t)ComputeBytesPerPixel(config); | |
305 | |
306 SkDEBUGCODE(this->validate();) | |
307 return true; | |
308 | |
309 // if we got here, we had an error, so we reset the bitmap to empty | |
310 BAD_CONFIG: | |
311 this->reset(); | |
312 return false; | |
313 } | |
314 | |
315 bool SkBitmap::setConfig(const SkImageInfo& info, size_t rowBytes) { | |
316 return this->setConfig(SkImageInfoToBitmapConfig(info), info.fWidth, | |
317 info.fHeight, rowBytes, info.fAlphaType); | |
318 } | 290 } |
319 | 291 |
320 bool SkBitmap::setAlphaType(SkAlphaType alphaType) { | 292 bool SkBitmap::setAlphaType(SkAlphaType alphaType) { |
321 if (!validate_alphaType(this->config(), alphaType, &alphaType)) { | 293 if (!validate_alphaType(fInfo.fColorType, alphaType, &alphaType)) { |
322 return false; | 294 return false; |
323 } | 295 } |
324 if (fAlphaType != alphaType) { | 296 if (fInfo.fAlphaType != alphaType) { |
325 fAlphaType = SkToU8(alphaType); | 297 fInfo.fAlphaType = alphaType; |
326 if (fPixelRef) { | 298 if (fPixelRef) { |
327 fPixelRef->changeAlphaType(alphaType); | 299 fPixelRef->changeAlphaType(alphaType); |
328 } | 300 } |
329 } | 301 } |
330 return true; | 302 return true; |
331 } | 303 } |
332 | 304 |
333 void SkBitmap::updatePixelsFromRef() const { | 305 void SkBitmap::updatePixelsFromRef() const { |
334 if (NULL != fPixelRef) { | 306 if (NULL != fPixelRef) { |
335 if (fPixelLockCount > 0) { | 307 if (fPixelLockCount > 0) { |
336 SkASSERT(fPixelRef->isLocked()); | 308 SkASSERT(fPixelRef->isLocked()); |
337 | 309 |
338 void* p = fPixelRef->pixels(); | 310 void* p = fPixelRef->pixels(); |
339 if (NULL != p) { | 311 if (NULL != p) { |
340 p = (char*)p | 312 p = (char*)p |
341 + fPixelRefOrigin.fY * fRowBytes | 313 + fPixelRefOrigin.fY * fRowBytes |
342 + fPixelRefOrigin.fX * fBytesPerPixel; | 314 + fPixelRefOrigin.fX * fInfo.bytesPerPixel(); |
343 } | 315 } |
344 fPixels = p; | 316 fPixels = p; |
345 fColorTable = fPixelRef->colorTable(); | 317 fColorTable = fPixelRef->colorTable(); |
346 } else { | 318 } else { |
347 SkASSERT(0 == fPixelLockCount); | 319 SkASSERT(0 == fPixelLockCount); |
348 fPixels = NULL; | 320 fPixels = NULL; |
349 fColorTable = NULL; | 321 fColorTable = NULL; |
350 } | 322 } |
351 } | 323 } |
352 } | 324 } |
(...skipping 19 matching lines...) Expand all Loading... |
372 case SkBitmap::kNo_Config: | 344 case SkBitmap::kNo_Config: |
373 default: | 345 default: |
374 return false; | 346 return false; |
375 } | 347 } |
376 if (ctOut) { | 348 if (ctOut) { |
377 *ctOut = ct; | 349 *ctOut = ct; |
378 } | 350 } |
379 return true; | 351 return true; |
380 } | 352 } |
381 | 353 |
382 bool SkBitmap::asImageInfo(SkImageInfo* info) const { | |
383 SkColorType ct; | |
384 if (!config_to_colorType(this->config(), &ct)) { | |
385 return false; | |
386 } | |
387 if (info) { | |
388 info->fWidth = fWidth; | |
389 info->fHeight = fHeight; | |
390 info->fAlphaType = this->alphaType(); | |
391 info->fColorType = ct; | |
392 } | |
393 return true; | |
394 } | |
395 | |
396 SkPixelRef* SkBitmap::setPixelRef(SkPixelRef* pr, int dx, int dy) { | 354 SkPixelRef* SkBitmap::setPixelRef(SkPixelRef* pr, int dx, int dy) { |
397 #ifdef SK_DEBUG | 355 #ifdef SK_DEBUG |
398 if (pr) { | 356 if (pr) { |
399 SkImageInfo info; | 357 SkImageInfo info; |
400 if (this->asImageInfo(&info)) { | 358 if (this->asImageInfo(&info)) { |
401 const SkImageInfo& prInfo = pr->info(); | 359 const SkImageInfo& prInfo = pr->info(); |
402 SkASSERT(info.fWidth <= prInfo.fWidth); | 360 SkASSERT(info.fWidth <= prInfo.fWidth); |
403 SkASSERT(info.fHeight <= prInfo.fHeight); | 361 SkASSERT(info.fHeight <= prInfo.fHeight); |
404 SkASSERT(info.fColorType == prInfo.fColorType); | 362 SkASSERT(info.fColorType == prInfo.fColorType); |
405 switch (prInfo.fAlphaType) { | 363 switch (prInfo.fAlphaType) { |
406 case kIgnore_SkAlphaType: | 364 case kIgnore_SkAlphaType: |
407 SkASSERT(fAlphaType == kIgnore_SkAlphaType); | 365 SkASSERT(fInfo.fAlphaType == kIgnore_SkAlphaType); |
408 break; | 366 break; |
409 case kOpaque_SkAlphaType: | 367 case kOpaque_SkAlphaType: |
410 case kPremul_SkAlphaType: | 368 case kPremul_SkAlphaType: |
411 SkASSERT(info.fAlphaType == kOpaque_SkAlphaType || | 369 SkASSERT(info.fAlphaType == kOpaque_SkAlphaType || |
412 info.fAlphaType == kPremul_SkAlphaType); | 370 info.fAlphaType == kPremul_SkAlphaType); |
413 break; | 371 break; |
414 case kUnpremul_SkAlphaType: | 372 case kUnpremul_SkAlphaType: |
415 SkASSERT(info.fAlphaType == kOpaque_SkAlphaType || | 373 SkASSERT(info.fAlphaType == kOpaque_SkAlphaType || |
416 info.fAlphaType == kUnpremul_SkAlphaType); | 374 info.fAlphaType == kUnpremul_SkAlphaType); |
417 break; | 375 break; |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
495 HeapAllocator stdalloc; | 453 HeapAllocator stdalloc; |
496 | 454 |
497 if (NULL == allocator) { | 455 if (NULL == allocator) { |
498 allocator = &stdalloc; | 456 allocator = &stdalloc; |
499 } | 457 } |
500 return allocator->allocPixelRef(this, ctable); | 458 return allocator->allocPixelRef(this, ctable); |
501 } | 459 } |
502 | 460 |
503 /////////////////////////////////////////////////////////////////////////////// | 461 /////////////////////////////////////////////////////////////////////////////// |
504 | 462 |
505 static bool reset_return_false(SkBitmap* bm) { | |
506 bm->reset(); | |
507 return false; | |
508 } | |
509 | |
510 bool SkBitmap::allocPixels(const SkImageInfo& info, SkPixelRefFactory* factory, | 463 bool SkBitmap::allocPixels(const SkImageInfo& info, SkPixelRefFactory* factory, |
511 SkColorTable* ctable) { | 464 SkColorTable* ctable) { |
512 if (kIndex_8_SkColorType == info.fColorType && NULL == ctable) { | 465 if (kIndex_8_SkColorType == info.fColorType && NULL == ctable) { |
513 return reset_return_false(this); | 466 return reset_return_false(this); |
514 } | 467 } |
515 if (!this->setConfig(info)) { | 468 if (!this->setConfig(info)) { |
516 return reset_return_false(this); | 469 return reset_return_false(this); |
517 } | 470 } |
518 | 471 |
519 SkMallocPixelRef::PRFactory defaultFactory; | 472 SkMallocPixelRef::PRFactory defaultFactory; |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
555 } | 508 } |
556 | 509 |
557 bool SkBitmap::allocConfigPixels(Config config, int width, int height, | 510 bool SkBitmap::allocConfigPixels(Config config, int width, int height, |
558 bool isOpaque) { | 511 bool isOpaque) { |
559 SkColorType ct; | 512 SkColorType ct; |
560 if (!config_to_colorType(config, &ct)) { | 513 if (!config_to_colorType(config, &ct)) { |
561 return false; | 514 return false; |
562 } | 515 } |
563 | 516 |
564 SkAlphaType at = isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType; | 517 SkAlphaType at = isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType; |
565 if (!validate_alphaType(config, at, &at)) { | |
566 return false; | |
567 } | |
568 | |
569 return this->allocPixels(SkImageInfo::Make(width, height, ct, at)); | 518 return this->allocPixels(SkImageInfo::Make(width, height, ct, at)); |
570 } | 519 } |
571 | 520 |
572 /////////////////////////////////////////////////////////////////////////////// | 521 /////////////////////////////////////////////////////////////////////////////// |
573 | 522 |
574 void SkBitmap::freePixels() { | 523 void SkBitmap::freePixels() { |
575 // if we're gonna free the pixels, we certainly need to free the mipmap | 524 // if we're gonna free the pixels, we certainly need to free the mipmap |
576 this->freeMipMap(); | 525 this->freeMipMap(); |
577 | 526 |
578 if (NULL != fPixelRef) { | 527 if (NULL != fPixelRef) { |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
630 } | 579 } |
631 | 580 |
632 dst->setPixelRef(pr)->unref(); | 581 dst->setPixelRef(pr)->unref(); |
633 // since we're already allocated, we lockPixels right away | 582 // since we're already allocated, we lockPixels right away |
634 dst->lockPixels(); | 583 dst->lockPixels(); |
635 return true; | 584 return true; |
636 } | 585 } |
637 | 586 |
638 /////////////////////////////////////////////////////////////////////////////// | 587 /////////////////////////////////////////////////////////////////////////////// |
639 | 588 |
640 size_t SkBitmap::getSafeSize() const { | |
641 // This is intended to be a size_t version of ComputeSafeSize64(), just | |
642 // faster. The computation is meant to be identical. | |
643 return (fHeight ? ((fHeight - 1) * fRowBytes) + | |
644 ComputeRowBytes(this->config(), fWidth): 0); | |
645 } | |
646 | |
647 bool SkBitmap::copyPixelsTo(void* const dst, size_t dstSize, | 589 bool SkBitmap::copyPixelsTo(void* const dst, size_t dstSize, |
648 size_t dstRowBytes, bool preserveDstPad) const { | 590 size_t dstRowBytes, bool preserveDstPad) const { |
649 | 591 |
650 if (0 == dstRowBytes) { | 592 if (0 == dstRowBytes) { |
651 dstRowBytes = fRowBytes; | 593 dstRowBytes = fRowBytes; |
652 } | 594 } |
653 | 595 |
654 if (dstRowBytes < ComputeRowBytes(this->config(), fWidth) || | 596 if (dstRowBytes < fInfo.minRowBytes() || |
655 dst == NULL || (getPixels() == NULL && pixelRef() == NULL)) | 597 dst == NULL || (getPixels() == NULL && pixelRef() == NULL)) { |
656 return false; | 598 return false; |
| 599 } |
657 | 600 |
658 if (!preserveDstPad && static_cast<uint32_t>(dstRowBytes) == fRowBytes) { | 601 if (!preserveDstPad && static_cast<uint32_t>(dstRowBytes) == fRowBytes) { |
659 size_t safeSize = this->getSafeSize(); | 602 size_t safeSize = this->getSafeSize(); |
660 if (safeSize > dstSize || safeSize == 0) | 603 if (safeSize > dstSize || safeSize == 0) |
661 return false; | 604 return false; |
662 else { | 605 else { |
663 SkAutoLockPixels lock(*this); | 606 SkAutoLockPixels lock(*this); |
664 // This implementation will write bytes beyond the end of each row, | 607 // This implementation will write bytes beyond the end of each row, |
665 // excluding the last row, if the bitmap's stride is greater than | 608 // excluding the last row, if the bitmap's stride is greater than |
666 // strictly required by the current config. | 609 // strictly required by the current config. |
667 memcpy(dst, getPixels(), safeSize); | 610 memcpy(dst, getPixels(), safeSize); |
668 | 611 |
669 return true; | 612 return true; |
670 } | 613 } |
671 } else { | 614 } else { |
672 // If destination has different stride than us, then copy line by line. | 615 // If destination has different stride than us, then copy line by line. |
673 if (ComputeSafeSize(this->config(), fWidth, fHeight, dstRowBytes) > | 616 if (fInfo.getSafeSize(dstRowBytes) > dstSize) { |
674 dstSize) | |
675 return false; | 617 return false; |
676 else { | 618 } else { |
677 // Just copy what we need on each line. | 619 // Just copy what we need on each line. |
678 size_t rowBytes = ComputeRowBytes(this->config(), fWidth); | 620 size_t rowBytes = fInfo.minRowBytes(); |
679 SkAutoLockPixels lock(*this); | 621 SkAutoLockPixels lock(*this); |
680 const uint8_t* srcP = reinterpret_cast<const uint8_t*>(getPixels()); | 622 const uint8_t* srcP = reinterpret_cast<const uint8_t*>(getPixels()); |
681 uint8_t* dstP = reinterpret_cast<uint8_t*>(dst); | 623 uint8_t* dstP = reinterpret_cast<uint8_t*>(dst); |
682 for (uint32_t row = 0; row < fHeight; | 624 for (int row = 0; row < fInfo.fHeight; |
683 row++, srcP += fRowBytes, dstP += dstRowBytes) { | 625 row++, srcP += fRowBytes, dstP += dstRowBytes) { |
684 memcpy(dstP, srcP, rowBytes); | 626 memcpy(dstP, srcP, rowBytes); |
685 } | 627 } |
686 | 628 |
687 return true; | 629 return true; |
688 } | 630 } |
689 } | 631 } |
690 } | 632 } |
691 | 633 |
692 /////////////////////////////////////////////////////////////////////////////// | 634 /////////////////////////////////////////////////////////////////////////////// |
(...skipping 23 matching lines...) Expand all Loading... |
716 } | 658 } |
717 } | 659 } |
718 | 660 |
719 void* SkBitmap::getAddr(int x, int y) const { | 661 void* SkBitmap::getAddr(int x, int y) const { |
720 SkASSERT((unsigned)x < (unsigned)this->width()); | 662 SkASSERT((unsigned)x < (unsigned)this->width()); |
721 SkASSERT((unsigned)y < (unsigned)this->height()); | 663 SkASSERT((unsigned)y < (unsigned)this->height()); |
722 | 664 |
723 char* base = (char*)this->getPixels(); | 665 char* base = (char*)this->getPixels(); |
724 if (base) { | 666 if (base) { |
725 base += y * this->rowBytes(); | 667 base += y * this->rowBytes(); |
726 switch (this->config()) { | 668 switch (this->colorType()) { |
727 case SkBitmap::kARGB_8888_Config: | 669 case kRGBA_8888_SkColorType: |
| 670 case kBGRA_8888_SkColorType: |
728 base += x << 2; | 671 base += x << 2; |
729 break; | 672 break; |
730 case SkBitmap::kARGB_4444_Config: | 673 case kARGB_4444_SkColorType: |
731 case SkBitmap::kRGB_565_Config: | 674 case kRGB_565_SkColorType: |
732 base += x << 1; | 675 base += x << 1; |
733 break; | 676 break; |
734 case SkBitmap::kA8_Config: | 677 case kAlpha_8_SkColorType: |
735 case SkBitmap::kIndex8_Config: | 678 case kIndex_8_SkColorType: |
736 base += x; | 679 base += x; |
737 break; | 680 break; |
738 break; | |
739 default: | 681 default: |
740 SkDEBUGFAIL("Can't return addr for config"); | 682 SkDEBUGFAIL("Can't return addr for config"); |
741 base = NULL; | 683 base = NULL; |
742 break; | 684 break; |
743 } | 685 } |
744 } | 686 } |
745 return base; | 687 return base; |
746 } | 688 } |
747 | 689 |
748 SkColor SkBitmap::getColor(int x, int y) const { | 690 SkColor SkBitmap::getColor(int x, int y) const { |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
866 U8CPU a, U8CPU r, U8CPU g, U8CPU b) const { | 808 U8CPU a, U8CPU r, U8CPU g, U8CPU b) const { |
867 #ifdef SK_DEBUG | 809 #ifdef SK_DEBUG |
868 SkDEBUGCODE(this->validate();) | 810 SkDEBUGCODE(this->validate();) |
869 SkASSERT(!area.isEmpty()); | 811 SkASSERT(!area.isEmpty()); |
870 { | 812 { |
871 SkIRect total = { 0, 0, this->width(), this->height() }; | 813 SkIRect total = { 0, 0, this->width(), this->height() }; |
872 SkASSERT(total.contains(area)); | 814 SkASSERT(total.contains(area)); |
873 } | 815 } |
874 #endif | 816 #endif |
875 | 817 |
876 if (kNo_Config == fConfig || kIndex8_Config == fConfig) { | 818 switch (fInfo.colorType()) { |
877 return; | 819 case kUnknown_SkColorType: |
| 820 case kIndex_8_SkColorType: |
| 821 return; // can't erase |
| 822 default: |
| 823 break; |
878 } | 824 } |
879 | 825 |
880 SkAutoLockPixels alp(*this); | 826 SkAutoLockPixels alp(*this); |
881 // perform this check after the lock call | 827 // perform this check after the lock call |
882 if (!this->readyToDraw()) { | 828 if (!this->readyToDraw()) { |
883 return; | 829 return; |
884 } | 830 } |
885 | 831 |
886 int height = area.height(); | 832 int height = area.height(); |
887 const int width = area.width(); | 833 const int width = area.width(); |
888 const int rowBytes = fRowBytes; | 834 const int rowBytes = fRowBytes; |
889 | 835 |
890 // make rgb premultiplied | 836 // make rgb premultiplied |
891 if (255 != a) { | 837 if (255 != a) { |
892 r = SkAlphaMul(r, a); | 838 r = SkAlphaMul(r, a); |
893 g = SkAlphaMul(g, a); | 839 g = SkAlphaMul(g, a); |
894 b = SkAlphaMul(b, a); | 840 b = SkAlphaMul(b, a); |
895 } | 841 } |
896 | 842 |
897 switch (fConfig) { | 843 switch (this->colorType()) { |
898 case kA8_Config: { | 844 case kAlpha_8_SkColorType: { |
899 uint8_t* p = this->getAddr8(area.fLeft, area.fTop); | 845 uint8_t* p = this->getAddr8(area.fLeft, area.fTop); |
900 while (--height >= 0) { | 846 while (--height >= 0) { |
901 memset(p, a, width); | 847 memset(p, a, width); |
902 p += rowBytes; | 848 p += rowBytes; |
903 } | 849 } |
904 break; | 850 break; |
905 } | 851 } |
906 case kARGB_4444_Config: | 852 case kARGB_4444_SkColorType: |
907 case kRGB_565_Config: { | 853 case kRGB_565_SkColorType: { |
908 uint16_t* p = this->getAddr16(area.fLeft, area.fTop);; | 854 uint16_t* p = this->getAddr16(area.fLeft, area.fTop);; |
909 uint16_t v; | 855 uint16_t v; |
910 | 856 |
911 if (kARGB_4444_Config == fConfig) { | 857 if (kARGB_4444_SkColorType == this->colorType()) { |
912 v = pack_8888_to_4444(a, r, g, b); | 858 v = pack_8888_to_4444(a, r, g, b); |
913 } else { | 859 } else { |
914 v = SkPackRGB16(r >> (8 - SK_R16_BITS), | 860 v = SkPackRGB16(r >> (8 - SK_R16_BITS), |
915 g >> (8 - SK_G16_BITS), | 861 g >> (8 - SK_G16_BITS), |
916 b >> (8 - SK_B16_BITS)); | 862 b >> (8 - SK_B16_BITS)); |
917 } | 863 } |
918 while (--height >= 0) { | 864 while (--height >= 0) { |
919 sk_memset16(p, v, width); | 865 sk_memset16(p, v, width); |
920 p = (uint16_t*)((char*)p + rowBytes); | 866 p = (uint16_t*)((char*)p + rowBytes); |
921 } | 867 } |
922 break; | 868 break; |
923 } | 869 } |
924 case kARGB_8888_Config: { | 870 case kPMColor_SkColorType: { |
| 871 // what to do about BGRA or RGBA (which ever is != PMColor ? |
| 872 // for now we don't support them. |
925 uint32_t* p = this->getAddr32(area.fLeft, area.fTop); | 873 uint32_t* p = this->getAddr32(area.fLeft, area.fTop); |
926 uint32_t v = SkPackARGB32(a, r, g, b); | 874 uint32_t v = SkPackARGB32(a, r, g, b); |
927 | 875 |
928 while (--height >= 0) { | 876 while (--height >= 0) { |
929 sk_memset32(p, v, width); | 877 sk_memset32(p, v, width); |
930 p = (uint32_t*)((char*)p + rowBytes); | 878 p = (uint32_t*)((char*)p + rowBytes); |
931 } | 879 } |
932 break; | 880 break; |
933 } | 881 } |
| 882 default: |
| 883 return; // no change, so don't call notifyPixelsChanged() |
934 } | 884 } |
935 | 885 |
936 this->notifyPixelsChanged(); | 886 this->notifyPixelsChanged(); |
937 } | 887 } |
938 | 888 |
939 void SkBitmap::eraseARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b) const { | 889 void SkBitmap::eraseARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b) const { |
940 SkIRect area = { 0, 0, this->width(), this->height() }; | 890 SkIRect area = { 0, 0, this->width(), this->height() }; |
941 if (!area.isEmpty()) { | 891 if (!area.isEmpty()) { |
942 this->internalErase(area, a, r, g, b); | 892 this->internalErase(area, a, r, g, b); |
943 } | 893 } |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1039 if (!this->canCopyTo(dstConfig)) { | 989 if (!this->canCopyTo(dstConfig)) { |
1040 return false; | 990 return false; |
1041 } | 991 } |
1042 | 992 |
1043 // if we have a texture, first get those pixels | 993 // if we have a texture, first get those pixels |
1044 SkBitmap tmpSrc; | 994 SkBitmap tmpSrc; |
1045 const SkBitmap* src = this; | 995 const SkBitmap* src = this; |
1046 | 996 |
1047 if (fPixelRef) { | 997 if (fPixelRef) { |
1048 SkIRect subset; | 998 SkIRect subset; |
1049 subset.setXYWH(fPixelRefOrigin.fX, fPixelRefOrigin.fY, fWidth, fHeight); | 999 subset.setXYWH(fPixelRefOrigin.fX, fPixelRefOrigin.fY, |
| 1000 fInfo.width(), fInfo.height()); |
1050 if (fPixelRef->readPixels(&tmpSrc, &subset)) { | 1001 if (fPixelRef->readPixels(&tmpSrc, &subset)) { |
1051 SkASSERT(tmpSrc.width() == this->width()); | 1002 SkASSERT(tmpSrc.width() == this->width()); |
1052 SkASSERT(tmpSrc.height() == this->height()); | 1003 SkASSERT(tmpSrc.height() == this->height()); |
1053 | 1004 |
1054 // did we get lucky and we can just return tmpSrc? | 1005 // did we get lucky and we can just return tmpSrc? |
1055 if (tmpSrc.config() == dstConfig && NULL == alloc) { | 1006 if (tmpSrc.config() == dstConfig && NULL == alloc) { |
1056 dst->swap(tmpSrc); | 1007 dst->swap(tmpSrc); |
1057 // If the result is an exact copy, clone the gen ID. | 1008 // If the result is an exact copy, clone the gen ID. |
1058 if (dst->pixelRef() && dst->pixelRef()->info() == fPixelRef->inf
o()) { | 1009 if (dst->pixelRef() && dst->pixelRef()->info() == fPixelRef->inf
o()) { |
1059 dst->pixelRef()->cloneGenID(*fPixelRef); | 1010 dst->pixelRef()->cloneGenID(*fPixelRef); |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1153 | 1104 |
1154 paint.setDither(true); | 1105 paint.setDither(true); |
1155 canvas.drawBitmap(*src, 0, 0, &paint); | 1106 canvas.drawBitmap(*src, 0, 0, &paint); |
1156 } | 1107 } |
1157 | 1108 |
1158 dst->swap(tmpDst); | 1109 dst->swap(tmpDst); |
1159 return true; | 1110 return true; |
1160 } | 1111 } |
1161 | 1112 |
1162 bool SkBitmap::deepCopyTo(SkBitmap* dst, Config dstConfig) const { | 1113 bool SkBitmap::deepCopyTo(SkBitmap* dst, Config dstConfig) const { |
| 1114 const SkColorType dstCT = SkBitmapConfigToColorType(dstConfig); |
| 1115 |
1163 if (!this->canCopyTo(dstConfig)) { | 1116 if (!this->canCopyTo(dstConfig)) { |
1164 return false; | 1117 return false; |
1165 } | 1118 } |
1166 | 1119 |
1167 // If we have a PixelRef, and it supports deep copy, use it. | 1120 // If we have a PixelRef, and it supports deep copy, use it. |
1168 // Currently supported only by texture-backed bitmaps. | 1121 // Currently supported only by texture-backed bitmaps. |
1169 if (fPixelRef) { | 1122 if (fPixelRef) { |
1170 SkPixelRef* pixelRef = fPixelRef->deepCopy(dstConfig); | 1123 SkPixelRef* pixelRef = fPixelRef->deepCopy(dstConfig); |
1171 if (pixelRef) { | 1124 if (pixelRef) { |
1172 uint32_t rowBytes; | 1125 uint32_t rowBytes; |
1173 if (dstConfig == fConfig) { | 1126 if (this->colorType() == dstCT) { |
1174 // Since there is no subset to pass to deepCopy, and deepCopy | 1127 // Since there is no subset to pass to deepCopy, and deepCopy |
1175 // succeeded, the new pixel ref must be identical. | 1128 // succeeded, the new pixel ref must be identical. |
1176 SkASSERT(fPixelRef->info() == pixelRef->info()); | 1129 SkASSERT(fPixelRef->info() == pixelRef->info()); |
1177 pixelRef->cloneGenID(*fPixelRef); | 1130 pixelRef->cloneGenID(*fPixelRef); |
1178 // Use the same rowBytes as the original. | 1131 // Use the same rowBytes as the original. |
1179 rowBytes = fRowBytes; | 1132 rowBytes = fRowBytes; |
1180 } else { | 1133 } else { |
1181 // With the new config, an appropriate fRowBytes will be compute
d by setConfig. | 1134 // With the new config, an appropriate fRowBytes will be compute
d by setConfig. |
1182 rowBytes = 0; | 1135 rowBytes = 0; |
1183 } | 1136 } |
1184 dst->setConfig(dstConfig, fWidth, fHeight, rowBytes); | 1137 |
| 1138 SkImageInfo info = fInfo; |
| 1139 info.fColorType = dstCT; |
| 1140 if (!dst->setConfig(info, rowBytes)) { |
| 1141 return false; |
| 1142 } |
1185 dst->setPixelRef(pixelRef, fPixelRefOrigin)->unref(); | 1143 dst->setPixelRef(pixelRef, fPixelRefOrigin)->unref(); |
1186 return true; | 1144 return true; |
1187 } | 1145 } |
1188 } | 1146 } |
1189 | 1147 |
1190 if (this->getTexture()) { | 1148 if (this->getTexture()) { |
1191 return false; | 1149 return false; |
1192 } else { | 1150 } else { |
1193 return this->copyTo(dst, dstConfig, NULL); | 1151 return this->copyTo(dst, dstConfig, NULL); |
1194 } | 1152 } |
(...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1577 } | 1535 } |
1578 | 1536 |
1579 /////////////////////////////////////////////////////////////////////////////// | 1537 /////////////////////////////////////////////////////////////////////////////// |
1580 | 1538 |
1581 enum { | 1539 enum { |
1582 SERIALIZE_PIXELTYPE_NONE, | 1540 SERIALIZE_PIXELTYPE_NONE, |
1583 SERIALIZE_PIXELTYPE_REF_DATA | 1541 SERIALIZE_PIXELTYPE_REF_DATA |
1584 }; | 1542 }; |
1585 | 1543 |
1586 void SkBitmap::flatten(SkWriteBuffer& buffer) const { | 1544 void SkBitmap::flatten(SkWriteBuffer& buffer) const { |
1587 buffer.writeInt(fWidth); | 1545 fInfo.flatten(buffer); |
1588 buffer.writeInt(fHeight); | |
1589 buffer.writeInt(fRowBytes); | 1546 buffer.writeInt(fRowBytes); |
1590 buffer.writeInt(fConfig); | |
1591 buffer.writeInt(fAlphaType); | |
1592 | 1547 |
1593 if (fPixelRef) { | 1548 if (fPixelRef) { |
1594 if (fPixelRef->getFactory()) { | 1549 if (fPixelRef->getFactory()) { |
1595 buffer.writeInt(SERIALIZE_PIXELTYPE_REF_DATA); | 1550 buffer.writeInt(SERIALIZE_PIXELTYPE_REF_DATA); |
1596 buffer.writeInt(fPixelRefOrigin.fX); | 1551 buffer.writeInt(fPixelRefOrigin.fX); |
1597 buffer.writeInt(fPixelRefOrigin.fY); | 1552 buffer.writeInt(fPixelRefOrigin.fY); |
1598 buffer.writeFlattenable(fPixelRef); | 1553 buffer.writeFlattenable(fPixelRef); |
1599 return; | 1554 return; |
1600 } | 1555 } |
1601 // if we get here, we can't record the pixels | 1556 // if we get here, we can't record the pixels |
1602 buffer.writeInt(SERIALIZE_PIXELTYPE_NONE); | 1557 buffer.writeInt(SERIALIZE_PIXELTYPE_NONE); |
1603 } else { | 1558 } else { |
1604 buffer.writeInt(SERIALIZE_PIXELTYPE_NONE); | 1559 buffer.writeInt(SERIALIZE_PIXELTYPE_NONE); |
1605 } | 1560 } |
1606 } | 1561 } |
1607 | 1562 |
1608 void SkBitmap::unflatten(SkReadBuffer& buffer) { | 1563 void SkBitmap::unflatten(SkReadBuffer& buffer) { |
1609 this->reset(); | 1564 this->reset(); |
1610 | 1565 |
1611 int width = buffer.readInt(); | 1566 SkImageInfo info; |
1612 int height = buffer.readInt(); | 1567 info.unflatten(buffer); |
1613 int rowBytes = buffer.readInt(); | 1568 size_t rowBytes = buffer.readInt(); |
1614 Config config = (Config)buffer.readInt(); | 1569 buffer.validate((info.width() >= 0) && (info.height() >= 0) && |
1615 SkAlphaType alphaType = (SkAlphaType)buffer.readInt(); | 1570 SkColorTypeIsValid(info.fColorType) && |
1616 buffer.validate((width >= 0) && (height >= 0) && (rowBytes >= 0) && | 1571 SkAlphaTypeIsValid(info.fAlphaType) && |
1617 SkIsValidConfig(config) && validate_alphaType(config, alphaT
ype)); | 1572 validate_alphaType(info.fColorType, info.fAlphaType) && |
| 1573 info.validRowBytes(rowBytes)); |
1618 | 1574 |
1619 bool configIsValid = this->setConfig(config, width, height, rowBytes, alphaT
ype); | 1575 bool configIsValid = this->setConfig(info, rowBytes); |
1620 // Note : Using (fRowBytes >= (fWidth * fBytesPerPixel)) in the following te
st can create false | 1576 buffer.validate(configIsValid); |
1621 // positives if the multiplication causes an integer overflow. Use th
e division instead. | |
1622 buffer.validate(configIsValid && (fBytesPerPixel > 0) && | |
1623 ((fRowBytes / fBytesPerPixel) >= fWidth)); | |
1624 | 1577 |
1625 int reftype = buffer.readInt(); | 1578 int reftype = buffer.readInt(); |
1626 if (buffer.validate((SERIALIZE_PIXELTYPE_REF_DATA == reftype) || | 1579 if (buffer.validate((SERIALIZE_PIXELTYPE_REF_DATA == reftype) || |
1627 (SERIALIZE_PIXELTYPE_NONE == reftype))) { | 1580 (SERIALIZE_PIXELTYPE_NONE == reftype))) { |
1628 switch (reftype) { | 1581 switch (reftype) { |
1629 case SERIALIZE_PIXELTYPE_REF_DATA: { | 1582 case SERIALIZE_PIXELTYPE_REF_DATA: { |
1630 SkIPoint origin; | 1583 SkIPoint origin; |
1631 origin.fX = buffer.readInt(); | 1584 origin.fX = buffer.readInt(); |
1632 origin.fY = buffer.readInt(); | 1585 origin.fY = buffer.readInt(); |
1633 size_t offset = origin.fY * rowBytes + origin.fX * fBytesPerPixe
l; | 1586 size_t offset = origin.fY * rowBytes + origin.fX * info.bytesPer
Pixel(); |
1634 SkPixelRef* pr = buffer.readPixelRef(); | 1587 SkPixelRef* pr = buffer.readPixelRef(); |
1635 if (!buffer.validate((NULL == pr) || | 1588 if (!buffer.validate((NULL == pr) || |
1636 (pr->getAllocatedSizeInBytes() >= (offset + this->getSafe
Size())))) { | 1589 (pr->getAllocatedSizeInBytes() >= (offset + this->getSafe
Size())))) { |
1637 origin.setZero(); | 1590 origin.setZero(); |
1638 } | 1591 } |
1639 SkSafeUnref(this->setPixelRef(pr, origin)); | 1592 SkSafeUnref(this->setPixelRef(pr, origin)); |
1640 break; | 1593 break; |
1641 } | 1594 } |
1642 case SERIALIZE_PIXELTYPE_NONE: | 1595 case SERIALIZE_PIXELTYPE_NONE: |
1643 break; | 1596 break; |
(...skipping 12 matching lines...) Expand all Loading... |
1656 } | 1609 } |
1657 | 1610 |
1658 SkBitmap::RLEPixels::~RLEPixels() { | 1611 SkBitmap::RLEPixels::~RLEPixels() { |
1659 sk_free(fYPtrs); | 1612 sk_free(fYPtrs); |
1660 } | 1613 } |
1661 | 1614 |
1662 /////////////////////////////////////////////////////////////////////////////// | 1615 /////////////////////////////////////////////////////////////////////////////// |
1663 | 1616 |
1664 #ifdef SK_DEBUG | 1617 #ifdef SK_DEBUG |
1665 void SkBitmap::validate() const { | 1618 void SkBitmap::validate() const { |
1666 SkASSERT(fConfig < kConfigCount); | 1619 fInfo.validate(); |
1667 SkASSERT(fRowBytes >= (unsigned)ComputeRowBytes((Config)fConfig, fWidth)); | 1620 SkASSERT(fInfo.validRowBytes(fRowBytes)); |
1668 uint8_t allFlags = kImageIsOpaque_Flag | kImageIsVolatile_Flag | kImageIsImm
utable_Flag; | 1621 uint8_t allFlags = kImageIsOpaque_Flag | kImageIsVolatile_Flag | kImageIsImm
utable_Flag; |
1669 #ifdef SK_BUILD_FOR_ANDROID | 1622 #ifdef SK_BUILD_FOR_ANDROID |
1670 allFlags |= kHasHardwareMipMap_Flag; | 1623 allFlags |= kHasHardwareMipMap_Flag; |
1671 #endif | 1624 #endif |
1672 SkASSERT(fFlags <= allFlags); | 1625 SkASSERT(fFlags <= allFlags); |
1673 SkASSERT(fPixelLockCount >= 0); | 1626 SkASSERT(fPixelLockCount >= 0); |
1674 SkASSERT((uint8_t)ComputeBytesPerPixel((Config)fConfig) == fBytesPerPixel); | |
1675 | 1627 |
1676 if (fPixels) { | 1628 if (fPixels) { |
1677 SkASSERT(fPixelRef); | 1629 SkASSERT(fPixelRef); |
1678 SkASSERT(fPixelLockCount > 0); | 1630 SkASSERT(fPixelLockCount > 0); |
1679 SkASSERT(fPixelRef->isLocked()); | 1631 SkASSERT(fPixelRef->isLocked()); |
1680 SkASSERT(fPixelRef->rowBytes() == fRowBytes); | 1632 SkASSERT(fPixelRef->rowBytes() == fRowBytes); |
1681 SkASSERT(fPixelRefOrigin.fX >= 0); | 1633 SkASSERT(fPixelRefOrigin.fX >= 0); |
1682 SkASSERT(fPixelRefOrigin.fY >= 0); | 1634 SkASSERT(fPixelRefOrigin.fY >= 0); |
1683 SkASSERT(fPixelRef->info().fWidth >= (int)fWidth + fPixelRefOrigin.fX); | 1635 SkASSERT(fPixelRef->info().width() >= (int)this->width() + fPixelRefOrig
in.fX); |
1684 SkASSERT(fPixelRef->info().fHeight >= (int)fHeight + fPixelRefOrigin.fY)
; | 1636 SkASSERT(fPixelRef->info().fHeight >= (int)this->height() + fPixelRefOri
gin.fY); |
1685 SkASSERT(fPixelRef->rowBytes() >= fWidth * fBytesPerPixel); | 1637 SkASSERT(fPixelRef->rowBytes() >= fInfo.minRowBytes()); |
1686 } else { | 1638 } else { |
1687 SkASSERT(NULL == fColorTable); | 1639 SkASSERT(NULL == fColorTable); |
1688 } | 1640 } |
1689 } | 1641 } |
1690 #endif | 1642 #endif |
1691 | 1643 |
1692 #ifdef SK_DEVELOPER | 1644 #ifdef SK_DEVELOPER |
1693 void SkBitmap::toString(SkString* str) const { | 1645 void SkBitmap::toString(SkString* str) const { |
1694 | 1646 |
1695 static const char* gConfigNames[kConfigCount] = { | 1647 static const char* gConfigNames[kConfigCount] = { |
(...skipping 25 matching lines...) Expand all Loading... |
1721 if (NULL != uri) { | 1673 if (NULL != uri) { |
1722 str->appendf(" uri:\"%s\"", uri); | 1674 str->appendf(" uri:\"%s\"", uri); |
1723 } else { | 1675 } else { |
1724 str->appendf(" pixelref:%p", pr); | 1676 str->appendf(" pixelref:%p", pr); |
1725 } | 1677 } |
1726 } | 1678 } |
1727 | 1679 |
1728 str->append(")"); | 1680 str->append(")"); |
1729 } | 1681 } |
1730 #endif | 1682 #endif |
| 1683 |
| 1684 /////////////////////////////////////////////////////////////////////////////// |
| 1685 |
| 1686 #ifdef SK_DEBUG |
| 1687 void SkImageInfo::validate() const { |
| 1688 SkASSERT(fWidth >= 0); |
| 1689 SkASSERT(fHeight >= 0); |
| 1690 SkASSERT(SkColorTypeIsValid(fColorType)); |
| 1691 SkASSERT(SkAlphaTypeIsValid(fAlphaType)); |
| 1692 } |
| 1693 #endif |
| 1694 |
OLD | NEW |