OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2006 The Android Open Source Project | 2 * Copyright 2006 The Android Open Source Project |
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 "SkImageDecoder.h" | 8 #include "SkImageDecoder.h" |
9 #include "SkImageEncoder.h" | 9 #include "SkImageEncoder.h" |
10 #include "SkColor.h" | 10 #include "SkColor.h" |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
84 | 84 |
85 virtual ~SkPNGImageDecoder() { | 85 virtual ~SkPNGImageDecoder() { |
86 SkDELETE(fImageIndex); | 86 SkDELETE(fImageIndex); |
87 } | 87 } |
88 | 88 |
89 protected: | 89 protected: |
90 #ifdef SK_BUILD_FOR_ANDROID | 90 #ifdef SK_BUILD_FOR_ANDROID |
91 virtual bool onBuildTileIndex(SkStreamRewindable *stream, int *width, int *h
eight) SK_OVERRIDE; | 91 virtual bool onBuildTileIndex(SkStreamRewindable *stream, int *width, int *h
eight) SK_OVERRIDE; |
92 virtual bool onDecodeSubset(SkBitmap* bitmap, const SkIRect& region) SK_OVER
RIDE; | 92 virtual bool onDecodeSubset(SkBitmap* bitmap, const SkIRect& region) SK_OVER
RIDE; |
93 #endif | 93 #endif |
94 virtual bool onDecode(SkStream* stream, SkBitmap* bm, Mode) SK_OVERRIDE; | 94 virtual Result onDecode(SkStream* stream, SkBitmap* bm, Mode) SK_OVERRIDE; |
95 | 95 |
96 private: | 96 private: |
97 SkPNGImageIndex* fImageIndex; | 97 SkPNGImageIndex* fImageIndex; |
98 | 98 |
99 bool onDecodeInit(SkStream* stream, png_structp *png_ptrp, png_infop *info_p
trp); | 99 bool onDecodeInit(SkStream* stream, png_structp *png_ptrp, png_infop *info_p
trp); |
100 bool decodePalette(png_structp png_ptr, png_infop info_ptr, | 100 bool decodePalette(png_structp png_ptr, png_infop info_ptr, |
101 bool * SK_RESTRICT hasAlphap, bool *reallyHasAlphap, | 101 bool * SK_RESTRICT hasAlphap, bool *reallyHasAlphap, |
102 SkColorTable **colorTablep); | 102 SkColorTable **colorTablep); |
103 bool getBitmapColorType(png_structp, png_infop, SkColorType*, bool* hasAlpha
, | 103 bool getBitmapColorType(png_structp, png_infop, SkColorType*, bool* hasAlpha
, |
104 SkPMColor* theTranspColor); | 104 SkPMColor* theTranspColor); |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
290 png_set_packing(png_ptr); | 290 png_set_packing(png_ptr); |
291 } | 291 } |
292 /* Expand grayscale images to the full 8 bits from 1, 2, or 4 bits/pixel */ | 292 /* Expand grayscale images to the full 8 bits from 1, 2, or 4 bits/pixel */ |
293 if (colorType == PNG_COLOR_TYPE_GRAY && bitDepth < 8) { | 293 if (colorType == PNG_COLOR_TYPE_GRAY && bitDepth < 8) { |
294 png_set_expand_gray_1_2_4_to_8(png_ptr); | 294 png_set_expand_gray_1_2_4_to_8(png_ptr); |
295 } | 295 } |
296 | 296 |
297 return true; | 297 return true; |
298 } | 298 } |
299 | 299 |
300 bool SkPNGImageDecoder::onDecode(SkStream* sk_stream, SkBitmap* decodedBitmap, | 300 SkImageDecoder::Result SkPNGImageDecoder::onDecode(SkStream* sk_stream, SkBitmap
* decodedBitmap, |
301 Mode mode) { | 301 Mode mode) { |
302 png_structp png_ptr; | 302 png_structp png_ptr; |
303 png_infop info_ptr; | 303 png_infop info_ptr; |
304 | 304 |
305 if (!onDecodeInit(sk_stream, &png_ptr, &info_ptr)) { | 305 if (!onDecodeInit(sk_stream, &png_ptr, &info_ptr)) { |
306 return false; | 306 return kFailure; |
307 } | 307 } |
308 | 308 |
309 PNGAutoClean autoClean(png_ptr, info_ptr); | 309 PNGAutoClean autoClean(png_ptr, info_ptr); |
310 | 310 |
311 if (setjmp(png_jmpbuf(png_ptr))) { | 311 if (setjmp(png_jmpbuf(png_ptr))) { |
312 return false; | 312 return kFailure; |
313 } | 313 } |
314 | 314 |
315 png_uint_32 origWidth, origHeight; | 315 png_uint_32 origWidth, origHeight; |
316 int bitDepth, pngColorType, interlaceType; | 316 int bitDepth, pngColorType, interlaceType; |
317 png_get_IHDR(png_ptr, info_ptr, &origWidth, &origHeight, &bitDepth, | 317 png_get_IHDR(png_ptr, info_ptr, &origWidth, &origHeight, &bitDepth, |
318 &pngColorType, &interlaceType, int_p_NULL, int_p_NULL); | 318 &pngColorType, &interlaceType, int_p_NULL, int_p_NULL); |
319 | 319 |
320 SkColorType colorType; | 320 SkColorType colorType; |
321 bool hasAlpha = false; | 321 bool hasAlpha = false; |
322 SkPMColor theTranspColor = 0; // 0 tells us not to try to match | 322 SkPMColor theTranspColor = 0; // 0 tells us not to try to match |
323 | 323 |
324 if (!this->getBitmapColorType(png_ptr, info_ptr, &colorType, &hasAlpha, &the
TranspColor)) { | 324 if (!this->getBitmapColorType(png_ptr, info_ptr, &colorType, &hasAlpha, &the
TranspColor)) { |
325 return false; | 325 return kFailure; |
326 } | 326 } |
327 | 327 |
328 SkAlphaType alphaType = this->getRequireUnpremultipliedColors() ? | 328 SkAlphaType alphaType = this->getRequireUnpremultipliedColors() ? |
329 kUnpremul_SkAlphaType : kPremul_SkAlphaType; | 329 kUnpremul_SkAlphaType : kPremul_SkAlphaType; |
330 const int sampleSize = this->getSampleSize(); | 330 const int sampleSize = this->getSampleSize(); |
331 SkScaledBitmapSampler sampler(origWidth, origHeight, sampleSize); | 331 SkScaledBitmapSampler sampler(origWidth, origHeight, sampleSize); |
332 decodedBitmap->setInfo(SkImageInfo::Make(sampler.scaledWidth(), sampler.scal
edHeight(), | 332 decodedBitmap->setInfo(SkImageInfo::Make(sampler.scaledWidth(), sampler.scal
edHeight(), |
333 colorType, alphaType)); | 333 colorType, alphaType)); |
334 | 334 |
335 if (SkImageDecoder::kDecodeBounds_Mode == mode) { | 335 if (SkImageDecoder::kDecodeBounds_Mode == mode) { |
336 return true; | 336 return kSuccess; |
337 } | 337 } |
338 | 338 |
339 // from here down we are concerned with colortables and pixels | 339 // from here down we are concerned with colortables and pixels |
340 | 340 |
341 // we track if we actually see a non-opaque pixels, since sometimes a PNG se
ts its colortype | 341 // we track if we actually see a non-opaque pixels, since sometimes a PNG se
ts its colortype |
342 // to |= PNG_COLOR_MASK_ALPHA, but all of its pixels are in fact opaque. We
care, since we | 342 // to |= PNG_COLOR_MASK_ALPHA, but all of its pixels are in fact opaque. We
care, since we |
343 // draw lots faster if we can flag the bitmap has being opaque | 343 // draw lots faster if we can flag the bitmap has being opaque |
344 bool reallyHasAlpha = false; | 344 bool reallyHasAlpha = false; |
345 SkColorTable* colorTable = NULL; | 345 SkColorTable* colorTable = NULL; |
346 | 346 |
347 if (pngColorType == PNG_COLOR_TYPE_PALETTE) { | 347 if (pngColorType == PNG_COLOR_TYPE_PALETTE) { |
348 decodePalette(png_ptr, info_ptr, &hasAlpha, &reallyHasAlpha, &colorTable
); | 348 decodePalette(png_ptr, info_ptr, &hasAlpha, &reallyHasAlpha, &colorTable
); |
349 } | 349 } |
350 | 350 |
351 SkAutoUnref aur(colorTable); | 351 SkAutoUnref aur(colorTable); |
352 | 352 |
353 if (!this->allocPixelRef(decodedBitmap, | 353 if (!this->allocPixelRef(decodedBitmap, |
354 kIndex_8_SkColorType == colorType ? colorTable : NU
LL)) { | 354 kIndex_8_SkColorType == colorType ? colorTable : NU
LL)) { |
355 return false; | 355 return kFailure; |
356 } | 356 } |
357 | 357 |
358 SkAutoLockPixels alp(*decodedBitmap); | 358 SkAutoLockPixels alp(*decodedBitmap); |
359 | 359 |
360 /* Turn on interlace handling. REQUIRED if you are not using | 360 /* Turn on interlace handling. REQUIRED if you are not using |
361 * png_read_image(). To see how to handle interlacing passes, | 361 * png_read_image(). To see how to handle interlacing passes, |
362 * see the png_read_row() method below: | 362 * see the png_read_row() method below: |
363 */ | 363 */ |
364 const int number_passes = (interlaceType != PNG_INTERLACE_NONE) ? | 364 const int number_passes = (interlaceType != PNG_INTERLACE_NONE) ? |
365 png_set_interlace_handling(png_ptr) : 1; | 365 png_set_interlace_handling(png_ptr) : 1; |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
403 } else { | 403 } else { |
404 sc = SkScaledBitmapSampler::kRGBX; | 404 sc = SkScaledBitmapSampler::kRGBX; |
405 } | 405 } |
406 | 406 |
407 /* We have to pass the colortable explicitly, since we may have one | 407 /* We have to pass the colortable explicitly, since we may have one |
408 even if our decodedBitmap doesn't, due to the request that we | 408 even if our decodedBitmap doesn't, due to the request that we |
409 upscale png's palette to a direct model | 409 upscale png's palette to a direct model |
410 */ | 410 */ |
411 SkAutoLockColors ctLock(colorTable); | 411 SkAutoLockColors ctLock(colorTable); |
412 if (!sampler.begin(decodedBitmap, sc, *this, ctLock.colors())) { | 412 if (!sampler.begin(decodedBitmap, sc, *this, ctLock.colors())) { |
413 return false; | 413 return kFailure; |
414 } | 414 } |
415 const int height = decodedBitmap->height(); | 415 const int height = decodedBitmap->height(); |
416 | 416 |
417 if (number_passes > 1) { | 417 if (number_passes > 1) { |
418 SkAutoMalloc storage(origWidth * origHeight * srcBytesPerPixel); | 418 SkAutoMalloc storage(origWidth * origHeight * srcBytesPerPixel); |
419 uint8_t* base = (uint8_t*)storage.get(); | 419 uint8_t* base = (uint8_t*)storage.get(); |
420 size_t rowBytes = origWidth * srcBytesPerPixel; | 420 size_t rowBytes = origWidth * srcBytesPerPixel; |
421 | 421 |
422 for (int i = 0; i < number_passes; i++) { | 422 for (int i = 0; i < number_passes; i++) { |
423 uint8_t* row = base; | 423 uint8_t* row = base; |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
460 | 460 |
461 if (0 != theTranspColor) { | 461 if (0 != theTranspColor) { |
462 reallyHasAlpha |= substituteTranspColor(decodedBitmap, theTranspColor); | 462 reallyHasAlpha |= substituteTranspColor(decodedBitmap, theTranspColor); |
463 } | 463 } |
464 if (reallyHasAlpha && this->getRequireUnpremultipliedColors()) { | 464 if (reallyHasAlpha && this->getRequireUnpremultipliedColors()) { |
465 switch (decodedBitmap->colorType()) { | 465 switch (decodedBitmap->colorType()) { |
466 case kIndex_8_SkColorType: | 466 case kIndex_8_SkColorType: |
467 // Fall through. | 467 // Fall through. |
468 case kARGB_4444_SkColorType: | 468 case kARGB_4444_SkColorType: |
469 // We have chosen not to support unpremul for these colortypes. | 469 // We have chosen not to support unpremul for these colortypes. |
470 return false; | 470 return kFailure; |
471 default: { | 471 default: { |
472 // Fall through to finish the decode. This colortype either | 472 // Fall through to finish the decode. This colortype either |
473 // supports unpremul or it is irrelevant because it has no | 473 // supports unpremul or it is irrelevant because it has no |
474 // alpha (or only alpha). | 474 // alpha (or only alpha). |
475 // These brackets prevent a warning. | 475 // These brackets prevent a warning. |
476 } | 476 } |
477 } | 477 } |
478 } | 478 } |
479 | 479 |
480 if (!reallyHasAlpha) { | 480 if (!reallyHasAlpha) { |
481 decodedBitmap->setAlphaType(kOpaque_SkAlphaType); | 481 decodedBitmap->setAlphaType(kOpaque_SkAlphaType); |
482 } | 482 } |
483 return true; | 483 return kSuccess; |
484 } | 484 } |
485 | 485 |
486 | 486 |
487 | 487 |
488 bool SkPNGImageDecoder::getBitmapColorType(png_structp png_ptr, png_infop info_p
tr, | 488 bool SkPNGImageDecoder::getBitmapColorType(png_structp png_ptr, png_infop info_p
tr, |
489 SkColorType* colorTypep, | 489 SkColorType* colorTypep, |
490 bool* hasAlphap, | 490 bool* hasAlphap, |
491 SkPMColor* SK_RESTRICT theTranspColor
p) { | 491 SkPMColor* SK_RESTRICT theTranspColor
p) { |
492 png_uint_32 origWidth, origHeight; | 492 png_uint_32 origWidth, origHeight; |
493 int bitDepth, colorType; | 493 int bitDepth, colorType; |
(...skipping 774 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1268 return SkImageDecoder::kUnknown_Format; | 1268 return SkImageDecoder::kUnknown_Format; |
1269 } | 1269 } |
1270 | 1270 |
1271 SkImageEncoder* sk_libpng_efactory(SkImageEncoder::Type t) { | 1271 SkImageEncoder* sk_libpng_efactory(SkImageEncoder::Type t) { |
1272 return (SkImageEncoder::kPNG_Type == t) ? SkNEW(SkPNGImageEncoder) : NULL; | 1272 return (SkImageEncoder::kPNG_Type == t) ? SkNEW(SkPNGImageEncoder) : NULL; |
1273 } | 1273 } |
1274 | 1274 |
1275 static SkImageDecoder_DecodeReg gDReg(sk_libpng_dfactory); | 1275 static SkImageDecoder_DecodeReg gDReg(sk_libpng_dfactory); |
1276 static SkImageDecoder_FormatReg gFormatReg(get_format_png); | 1276 static SkImageDecoder_FormatReg gFormatReg(get_format_png); |
1277 static SkImageEncoder_EncodeReg gEReg(sk_libpng_efactory); | 1277 static SkImageEncoder_EncodeReg gEReg(sk_libpng_efactory); |
OLD | NEW |