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