| 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 |