Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(234)

Side by Side Diff: src/images/SkImageDecoder_libpng.cpp

Issue 24269006: Add an option on SkImageDecoder to skip writing 0s. (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Rebase, plus update the benchmark Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/images/SkImageDecoder_libjpeg.cpp ('k') | src/images/SkImageRef_ashmem.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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);
OLDNEW
« no previous file with comments | « src/images/SkImageDecoder_libjpeg.cpp ('k') | src/images/SkImageRef_ashmem.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698