OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2006 The Android Open Source Project | 3 * Copyright 2006 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 "SkImageDecoder.h" | 10 #include "SkImageDecoder.h" |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
84 | 84 |
85 private: | 85 private: |
86 SkPNGImageIndex* fImageIndex; | 86 SkPNGImageIndex* fImageIndex; |
87 | 87 |
88 bool onDecodeInit(SkStream* stream, png_structp *png_ptrp, png_infop *info_p
trp); | 88 bool onDecodeInit(SkStream* stream, png_structp *png_ptrp, png_infop *info_p
trp); |
89 bool decodePalette(png_structp png_ptr, png_infop info_ptr, | 89 bool decodePalette(png_structp png_ptr, png_infop info_ptr, |
90 bool * SK_RESTRICT hasAlphap, bool *reallyHasAlphap, | 90 bool * SK_RESTRICT hasAlphap, bool *reallyHasAlphap, |
91 SkColorTable **colorTablep); | 91 SkColorTable **colorTablep); |
92 bool getBitmapConfig(png_structp png_ptr, png_infop info_ptr, | 92 bool getBitmapConfig(png_structp png_ptr, png_infop info_ptr, |
93 SkBitmap::Config *config, bool *hasAlpha, | 93 SkBitmap::Config *config, bool *hasAlpha, |
94 bool *doDither, SkPMColor *theTranspColor); | 94 SkPMColor *theTranspColor); |
95 | 95 |
96 typedef SkImageDecoder INHERITED; | 96 typedef SkImageDecoder INHERITED; |
97 }; | 97 }; |
98 | 98 |
99 #ifndef png_jmpbuf | 99 #ifndef png_jmpbuf |
100 # define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf) | 100 # define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf) |
101 #endif | 101 #endif |
102 | 102 |
103 #define PNG_BYTES_TO_CHECK 4 | 103 #define PNG_BYTES_TO_CHECK 4 |
104 | 104 |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
287 | 287 |
288 PNGAutoClean autoClean(png_ptr, info_ptr); | 288 PNGAutoClean autoClean(png_ptr, info_ptr); |
289 | 289 |
290 png_uint_32 origWidth, origHeight; | 290 png_uint_32 origWidth, origHeight; |
291 int bitDepth, colorType, interlaceType; | 291 int bitDepth, colorType, interlaceType; |
292 png_get_IHDR(png_ptr, info_ptr, &origWidth, &origHeight, &bitDepth, | 292 png_get_IHDR(png_ptr, info_ptr, &origWidth, &origHeight, &bitDepth, |
293 &colorType, &interlaceType, int_p_NULL, int_p_NULL); | 293 &colorType, &interlaceType, int_p_NULL, int_p_NULL); |
294 | 294 |
295 SkBitmap::Config config; | 295 SkBitmap::Config config; |
296 bool hasAlpha = false; | 296 bool hasAlpha = false; |
297 bool doDither = this->getDitherImage(); | |
298 SkPMColor theTranspColor = 0; // 0 tells us not to try to match | 297 SkPMColor theTranspColor = 0; // 0 tells us not to try to match |
299 | 298 |
300 if (!getBitmapConfig(png_ptr, info_ptr, &config, &hasAlpha, &doDither, &theT
ranspColor)) { | 299 if (!this->getBitmapConfig(png_ptr, info_ptr, &config, &hasAlpha, &theTransp
Color)) { |
301 return false; | 300 return false; |
302 } | 301 } |
303 | 302 |
304 const int sampleSize = this->getSampleSize(); | 303 const int sampleSize = this->getSampleSize(); |
305 SkScaledBitmapSampler sampler(origWidth, origHeight, sampleSize); | 304 SkScaledBitmapSampler sampler(origWidth, origHeight, sampleSize); |
306 decodedBitmap->setConfig(config, sampler.scaledWidth(), sampler.scaledHeight
()); | 305 decodedBitmap->setConfig(config, sampler.scaledWidth(), sampler.scaledHeight
()); |
307 | 306 |
308 if (SkImageDecoder::kDecodeBounds_Mode == mode) { | 307 if (SkImageDecoder::kDecodeBounds_Mode == mode) { |
309 return true; | 308 return true; |
310 } | 309 } |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
370 sc = SkScaledBitmapSampler::kRGBA; | 369 sc = SkScaledBitmapSampler::kRGBA; |
371 } else { | 370 } else { |
372 sc = SkScaledBitmapSampler::kRGBX; | 371 sc = SkScaledBitmapSampler::kRGBX; |
373 } | 372 } |
374 | 373 |
375 /* We have to pass the colortable explicitly, since we may have one | 374 /* We have to pass the colortable explicitly, since we may have one |
376 even if our decodedBitmap doesn't, due to the request that we | 375 even if our decodedBitmap doesn't, due to the request that we |
377 upscale png's palette to a direct model | 376 upscale png's palette to a direct model |
378 */ | 377 */ |
379 SkAutoLockColors ctLock(colorTable); | 378 SkAutoLockColors ctLock(colorTable); |
380 if (!sampler.begin(decodedBitmap, sc, doDither, ctLock.colors(), | 379 if (!sampler.begin(decodedBitmap, sc, *this, ctLock.colors())) { |
381 this->getRequireUnpremultipliedColors())) { | |
382 return false; | 380 return false; |
383 } | 381 } |
384 const int height = decodedBitmap->height(); | 382 const int height = decodedBitmap->height(); |
385 | 383 |
386 if (number_passes > 1) { | 384 if (number_passes > 1) { |
387 SkAutoMalloc storage(origWidth * origHeight * srcBytesPerPixel); | 385 SkAutoMalloc storage(origWidth * origHeight * srcBytesPerPixel); |
388 uint8_t* base = (uint8_t*)storage.get(); | 386 uint8_t* base = (uint8_t*)storage.get(); |
389 size_t rowBytes = origWidth * srcBytesPerPixel; | 387 size_t rowBytes = origWidth * srcBytesPerPixel; |
390 | 388 |
391 for (int i = 0; i < number_passes; i++) { | 389 for (int i = 0; i < number_passes; i++) { |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
439 } | 437 } |
440 decodedBitmap->setIsOpaque(!reallyHasAlpha); | 438 decodedBitmap->setIsOpaque(!reallyHasAlpha); |
441 return true; | 439 return true; |
442 } | 440 } |
443 | 441 |
444 | 442 |
445 | 443 |
446 bool SkPNGImageDecoder::getBitmapConfig(png_structp png_ptr, png_infop info_ptr, | 444 bool SkPNGImageDecoder::getBitmapConfig(png_structp png_ptr, png_infop info_ptr, |
447 SkBitmap::Config* SK_RESTRICT configp, | 445 SkBitmap::Config* SK_RESTRICT configp, |
448 bool* SK_RESTRICT hasAlphap, | 446 bool* SK_RESTRICT hasAlphap, |
449 bool* SK_RESTRICT doDitherp, | |
450 SkPMColor* SK_RESTRICT theTranspColorp)
{ | 447 SkPMColor* SK_RESTRICT theTranspColorp)
{ |
451 png_uint_32 origWidth, origHeight; | 448 png_uint_32 origWidth, origHeight; |
452 int bitDepth, colorType; | 449 int bitDepth, colorType; |
453 png_get_IHDR(png_ptr, info_ptr, &origWidth, &origHeight, &bitDepth, | 450 png_get_IHDR(png_ptr, info_ptr, &origWidth, &origHeight, &bitDepth, |
454 &colorType, int_p_NULL, int_p_NULL, int_p_NULL); | 451 &colorType, int_p_NULL, int_p_NULL, int_p_NULL); |
455 | 452 |
456 // check for sBIT chunk data, in case we should disable dithering because | 453 // check for sBIT chunk data, in case we should disable dithering because |
457 // our data is not truely 8bits per component | 454 // our data is not truely 8bits per component |
458 png_color_8p sig_bit; | 455 png_color_8p sig_bit; |
459 if (*doDitherp && png_get_sBIT(png_ptr, info_ptr, &sig_bit)) { | 456 if (this->getDitherImage() && png_get_sBIT(png_ptr, info_ptr, &sig_bit)) { |
460 #if 0 | 457 #if 0 |
461 SkDebugf("----- sBIT %d %d %d %d\n", sig_bit->red, sig_bit->green, | 458 SkDebugf("----- sBIT %d %d %d %d\n", sig_bit->red, sig_bit->green, |
462 sig_bit->blue, sig_bit->alpha); | 459 sig_bit->blue, sig_bit->alpha); |
463 #endif | 460 #endif |
464 // 0 seems to indicate no information available | 461 // 0 seems to indicate no information available |
465 if (pos_le(sig_bit->red, SK_R16_BITS) && | 462 if (pos_le(sig_bit->red, SK_R16_BITS) && |
466 pos_le(sig_bit->green, SK_G16_BITS) && | 463 pos_le(sig_bit->green, SK_G16_BITS) && |
467 pos_le(sig_bit->blue, SK_B16_BITS)) { | 464 pos_le(sig_bit->blue, SK_B16_BITS)) { |
468 *doDitherp = false; | 465 this->setDitherImage(false); |
469 } | 466 } |
470 } | 467 } |
471 | 468 |
472 if (colorType == PNG_COLOR_TYPE_PALETTE) { | 469 if (colorType == PNG_COLOR_TYPE_PALETTE) { |
473 bool paletteHasAlpha = hasTransparencyInPalette(png_ptr, info_ptr); | 470 bool paletteHasAlpha = hasTransparencyInPalette(png_ptr, info_ptr); |
474 *configp = this->getPrefConfig(kIndex_SrcDepth, paletteHasAlpha); | 471 *configp = this->getPrefConfig(kIndex_SrcDepth, paletteHasAlpha); |
475 // now see if we can upscale to their requested config | 472 // now see if we can upscale to their requested config |
476 if (!canUpscalePaletteToConfig(*configp, paletteHasAlpha)) { | 473 if (!canUpscalePaletteToConfig(*configp, paletteHasAlpha)) { |
477 *configp = SkBitmap::kIndex8_Config; | 474 *configp = SkBitmap::kIndex8_Config; |
478 } | 475 } |
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
717 SkIRect rect = SkIRect::MakeWH(origWidth, origHeight); | 714 SkIRect rect = SkIRect::MakeWH(origWidth, origHeight); |
718 | 715 |
719 if (!rect.intersect(region)) { | 716 if (!rect.intersect(region)) { |
720 // If the requested region is entirely outside the image, just | 717 // If the requested region is entirely outside the image, just |
721 // returns false | 718 // returns false |
722 return false; | 719 return false; |
723 } | 720 } |
724 | 721 |
725 SkBitmap::Config config; | 722 SkBitmap::Config config; |
726 bool hasAlpha = false; | 723 bool hasAlpha = false; |
727 bool doDither = this->getDitherImage(); | |
728 SkPMColor theTranspColor = 0; // 0 tells us not to try to match | 724 SkPMColor theTranspColor = 0; // 0 tells us not to try to match |
729 | 725 |
730 if (!getBitmapConfig(png_ptr, info_ptr, &config, &hasAlpha, &doDither, &theT
ranspColor)) { | 726 if (!this->getBitmapConfig(png_ptr, info_ptr, &config, &hasAlpha, &theTransp
Color)) { |
731 return false; | 727 return false; |
732 } | 728 } |
733 | 729 |
734 const int sampleSize = this->getSampleSize(); | 730 const int sampleSize = this->getSampleSize(); |
735 SkScaledBitmapSampler sampler(origWidth, rect.height(), sampleSize); | 731 SkScaledBitmapSampler sampler(origWidth, rect.height(), sampleSize); |
736 | 732 |
737 SkBitmap decodedBitmap; | 733 SkBitmap decodedBitmap; |
738 decodedBitmap.setConfig(config, sampler.scaledWidth(), sampler.scaledHeight(
)); | 734 decodedBitmap.setConfig(config, sampler.scaledWidth(), sampler.scaledHeight(
)); |
739 | 735 |
740 // from here down we are concerned with colortables and pixels | 736 // from here down we are concerned with colortables and pixels |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
827 sc = SkScaledBitmapSampler::kRGBA; | 823 sc = SkScaledBitmapSampler::kRGBA; |
828 } else { | 824 } else { |
829 sc = SkScaledBitmapSampler::kRGBX; | 825 sc = SkScaledBitmapSampler::kRGBX; |
830 } | 826 } |
831 | 827 |
832 /* We have to pass the colortable explicitly, since we may have one | 828 /* We have to pass the colortable explicitly, since we may have one |
833 even if our decodedBitmap doesn't, due to the request that we | 829 even if our decodedBitmap doesn't, due to the request that we |
834 upscale png's palette to a direct model | 830 upscale png's palette to a direct model |
835 */ | 831 */ |
836 SkAutoLockColors ctLock(colorTable); | 832 SkAutoLockColors ctLock(colorTable); |
837 if (!sampler.begin(&decodedBitmap, sc, doDither, ctLock.colors(), | 833 if (!sampler.begin(&decodedBitmap, sc, *this, ctLock.colors())) { |
838 this->getRequireUnpremultipliedColors())) { | |
839 return false; | 834 return false; |
840 } | 835 } |
841 const int height = decodedBitmap.height(); | 836 const int height = decodedBitmap.height(); |
842 | 837 |
843 if (number_passes > 1) { | 838 if (number_passes > 1) { |
844 SkAutoMalloc storage(origWidth * origHeight * srcBytesPerPixel); | 839 SkAutoMalloc storage(origWidth * origHeight * srcBytesPerPixel); |
845 uint8_t* base = (uint8_t*)storage.get(); | 840 uint8_t* base = (uint8_t*)storage.get(); |
846 size_t rb = origWidth * srcBytesPerPixel; | 841 size_t rb = origWidth * srcBytesPerPixel; |
847 | 842 |
848 for (int i = 0; i < number_passes; i++) { | 843 for (int i = 0; i < number_passes; i++) { |
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1197 return SkImageDecoder::kUnknown_Format; | 1192 return SkImageDecoder::kUnknown_Format; |
1198 } | 1193 } |
1199 | 1194 |
1200 SkImageEncoder* sk_libpng_efactory(SkImageEncoder::Type t) { | 1195 SkImageEncoder* sk_libpng_efactory(SkImageEncoder::Type t) { |
1201 return (SkImageEncoder::kPNG_Type == t) ? SkNEW(SkPNGImageEncoder) : NULL; | 1196 return (SkImageEncoder::kPNG_Type == t) ? SkNEW(SkPNGImageEncoder) : NULL; |
1202 } | 1197 } |
1203 | 1198 |
1204 static SkImageDecoder_DecodeReg gDReg(sk_libpng_dfactory); | 1199 static SkImageDecoder_DecodeReg gDReg(sk_libpng_dfactory); |
1205 static SkImageDecoder_FormatReg gFormatReg(get_format_png); | 1200 static SkImageDecoder_FormatReg gFormatReg(get_format_png); |
1206 static SkImageEncoder_EncodeReg gEReg(sk_libpng_efactory); | 1201 static SkImageEncoder_EncodeReg gEReg(sk_libpng_efactory); |
OLD | NEW |