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

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

Issue 338493005: stop using SkBitmap::Config (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 6 years, 6 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
OLDNEW
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 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 #endif 93 #endif
94 virtual bool onDecode(SkStream* stream, SkBitmap* bm, Mode) SK_OVERRIDE; 94 virtual bool 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 getBitmapConfig(png_structp, png_infop, SkColorType*, bool* hasAlpha, 103 bool getBitmapColorType(png_structp, png_infop, SkColorType*, bool* hasAlpha ,
104 SkPMColor* theTranspColor); 104 SkPMColor* theTranspColor);
105 105
106 typedef SkImageDecoder INHERITED; 106 typedef SkImageDecoder INHERITED;
107 }; 107 };
108 108
109 #ifndef png_jmpbuf 109 #ifndef png_jmpbuf
110 # define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf) 110 # define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf)
111 #endif 111 #endif
112 112
113 #define PNG_BYTES_TO_CHECK 4 113 #define PNG_BYTES_TO_CHECK 4
114 114
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
159 uint8_t* tmp = storage; 159 uint8_t* tmp = storage;
160 png_read_rows(png_ptr, &tmp, png_bytepp_NULL, 1); 160 png_read_rows(png_ptr, &tmp, png_bytepp_NULL, 1);
161 } 161 }
162 } 162 }
163 163
164 static bool pos_le(int value, int max) { 164 static bool pos_le(int value, int max) {
165 return value > 0 && value <= max; 165 return value > 0 && value <= max;
166 } 166 }
167 167
168 static bool substituteTranspColor(SkBitmap* bm, SkPMColor match) { 168 static bool substituteTranspColor(SkBitmap* bm, SkPMColor match) {
169 SkASSERT(bm->config() == SkBitmap::kARGB_8888_Config); 169 SkASSERT(bm->colorType() == kN32_SkColorType);
170 170
171 bool reallyHasAlpha = false; 171 bool reallyHasAlpha = false;
172 172
173 for (int y = bm->height() - 1; y >= 0; --y) { 173 for (int y = bm->height() - 1; y >= 0; --y) {
174 SkPMColor* p = bm->getAddr32(0, y); 174 SkPMColor* p = bm->getAddr32(0, y);
175 for (int x = bm->width() - 1; x >= 0; --x) { 175 for (int x = bm->width() - 1; x >= 0; --x) {
176 if (match == *p) { 176 if (match == *p) {
177 *p = 0; 177 *p = 0;
178 reallyHasAlpha = true; 178 reallyHasAlpha = true;
179 } 179 }
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
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->getBitmapConfig(png_ptr, info_ptr, &colorType, &hasAlpha, &theTra nspColor)) { 324 if (!this->getBitmapColorType(png_ptr, info_ptr, &colorType, &hasAlpha, &the TranspColor)) {
325 return false; 325 return false;
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
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
455 } 455 }
456 } 456 }
457 457
458 /* read rest of file, and get additional chunks in info_ptr - REQUIRED */ 458 /* read rest of file, and get additional chunks in info_ptr - REQUIRED */
459 png_read_end(png_ptr, info_ptr); 459 png_read_end(png_ptr, info_ptr);
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->config()) { 465 switch (decodedBitmap->colorType()) {
466 case SkBitmap::kIndex8_Config: 466 case kIndex_8_SkColorType:
467 // Fall through. 467 // Fall through.
468 case SkBitmap::kARGB_4444_Config: 468 case kARGB_4444_SkColorType:
469 // We have chosen not to support unpremul for these configs. 469 // We have chosen not to support unpremul for these colortypes.
470 return false; 470 return false;
471 default: { 471 default: {
472 // Fall through to finish the decode. This config 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 true;
484 } 484 }
485 485
486 486
487 487
488 bool SkPNGImageDecoder::getBitmapConfig(png_structp png_ptr, png_infop info_ptr, 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 theTranspColorp) { 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;
494 png_get_IHDR(png_ptr, info_ptr, &origWidth, &origHeight, &bitDepth, 494 png_get_IHDR(png_ptr, info_ptr, &origWidth, &origHeight, &bitDepth,
495 &colorType, int_p_NULL, int_p_NULL, int_p_NULL); 495 &colorType, int_p_NULL, int_p_NULL, int_p_NULL);
496 496
497 // check for sBIT chunk data, in case we should disable dithering because 497 // check for sBIT chunk data, in case we should disable dithering because
498 // our data is not truely 8bits per component 498 // our data is not truely 8bits per component
499 png_color_8p sig_bit; 499 png_color_8p sig_bit;
500 if (this->getDitherImage() && png_get_sBIT(png_ptr, info_ptr, &sig_bit)) { 500 if (this->getDitherImage() && png_get_sBIT(png_ptr, info_ptr, &sig_bit)) {
501 #if 0 501 #if 0
502 SkDebugf("----- sBIT %d %d %d %d\n", sig_bit->red, sig_bit->green, 502 SkDebugf("----- sBIT %d %d %d %d\n", sig_bit->red, sig_bit->green,
503 sig_bit->blue, sig_bit->alpha); 503 sig_bit->blue, sig_bit->alpha);
504 #endif 504 #endif
505 // 0 seems to indicate no information available 505 // 0 seems to indicate no information available
506 if (pos_le(sig_bit->red, SK_R16_BITS) && 506 if (pos_le(sig_bit->red, SK_R16_BITS) &&
507 pos_le(sig_bit->green, SK_G16_BITS) && 507 pos_le(sig_bit->green, SK_G16_BITS) &&
508 pos_le(sig_bit->blue, SK_B16_BITS)) { 508 pos_le(sig_bit->blue, SK_B16_BITS)) {
509 this->setDitherImage(false); 509 this->setDitherImage(false);
510 } 510 }
511 } 511 }
512 512
513 if (colorType == PNG_COLOR_TYPE_PALETTE) { 513 if (colorType == PNG_COLOR_TYPE_PALETTE) {
514 bool paletteHasAlpha = hasTransparencyInPalette(png_ptr, info_ptr); 514 bool paletteHasAlpha = hasTransparencyInPalette(png_ptr, info_ptr);
515 *colorTypep = this->getPrefColorType(kIndex_SrcDepth, paletteHasAlpha); 515 *colorTypep = this->getPrefColorType(kIndex_SrcDepth, paletteHasAlpha);
516 // now see if we can upscale to their requested config 516 // now see if we can upscale to their requested colortype
517 if (!canUpscalePaletteToConfig(*colorTypep, paletteHasAlpha)) { 517 if (!canUpscalePaletteToConfig(*colorTypep, paletteHasAlpha)) {
518 *colorTypep = kIndex_8_SkColorType; 518 *colorTypep = kIndex_8_SkColorType;
519 } 519 }
520 } else { 520 } else {
521 png_color_16p transpColor = NULL; 521 png_color_16p transpColor = NULL;
522 int numTransp = 0; 522 int numTransp = 0;
523 523
524 png_get_tRNS(png_ptr, info_ptr, NULL, &numTransp, &transpColor); 524 png_get_tRNS(png_ptr, info_ptr, NULL, &numTransp, &transpColor);
525 525
526 bool valid = png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS); 526 bool valid = png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS);
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
607 } 607 }
608 } 608 }
609 609
610 #ifdef SK_SUPPORT_LEGACY_IMAGEDECODER_CHOOSER 610 #ifdef SK_SUPPORT_LEGACY_IMAGEDECODER_CHOOSER
611 if (!this->chooseFromOneChoice(*colorTypep, origWidth, origHeight)) { 611 if (!this->chooseFromOneChoice(*colorTypep, origWidth, origHeight)) {
612 return false; 612 return false;
613 } 613 }
614 #endif 614 #endif
615 615
616 // If the image has alpha and the decoder wants unpremultiplied 616 // If the image has alpha and the decoder wants unpremultiplied
617 // colors, the only supported config is 8888. 617 // colors, the only supported colortype is 8888.
618 if (this->getRequireUnpremultipliedColors() && *hasAlphap) { 618 if (this->getRequireUnpremultipliedColors() && *hasAlphap) {
619 *colorTypep = kN32_SkColorType; 619 *colorTypep = kN32_SkColorType;
620 } 620 }
621 621
622 if (fImageIndex != NULL) { 622 if (fImageIndex != NULL) {
623 if (kUnknown_SkColorType == fImageIndex->fColorType) { 623 if (kUnknown_SkColorType == fImageIndex->fColorType) {
624 // This is the first time for this subset decode. From now on, 624 // This is the first time for this subset decode. From now on,
625 // all decodes must be in the same config. 625 // all decodes must be in the same colortype.
626 fImageIndex->fColorType = *colorTypep; 626 fImageIndex->fColorType = *colorTypep;
627 } else if (fImageIndex->fColorType != *colorTypep) { 627 } else if (fImageIndex->fColorType != *colorTypep) {
628 // Requesting a different colortype for a subsequent decode is not 628 // Requesting a different colortype for a subsequent decode is not
629 // supported. Report failure before we make changes to png_ptr. 629 // supported. Report failure before we make changes to png_ptr.
630 return false; 630 return false;
631 } 631 }
632 } 632 }
633 633
634 bool convertGrayToRGB = PNG_COLOR_TYPE_GRAY == colorType && *colorTypep != k Alpha_8_SkColorType; 634 bool convertGrayToRGB = PNG_COLOR_TYPE_GRAY == colorType && *colorTypep != k Alpha_8_SkColorType;
635 635
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
678 678
679 // check for bad images that might make us crash 679 // check for bad images that might make us crash
680 if (numTrans > numPalette) { 680 if (numTrans > numPalette) {
681 numTrans = numPalette; 681 numTrans = numPalette;
682 } 682 }
683 683
684 int index = 0; 684 int index = 0;
685 int transLessThanFF = 0; 685 int transLessThanFF = 0;
686 686
687 // Choose which function to use to create the color table. If the final dest ination's 687 // Choose which function to use to create the color table. If the final dest ination's
688 // config is unpremultiplied, the color table will store unpremultiplied col ors. 688 // colortype is unpremultiplied, the color table will store unpremultiplied colors.
689 PackColorProc proc; 689 PackColorProc proc;
690 if (this->getRequireUnpremultipliedColors()) { 690 if (this->getRequireUnpremultipliedColors()) {
691 proc = &SkPackARGB32NoCheck; 691 proc = &SkPackARGB32NoCheck;
692 } else { 692 } else {
693 proc = &SkPreMultiplyARGB; 693 proc = &SkPreMultiplyARGB;
694 } 694 }
695 for (; index < numTrans; index++) { 695 for (; index < numTrans; index++) {
696 transLessThanFF |= (int)*trans - 0xFF; 696 transLessThanFF |= (int)*trans - 0xFF;
697 *colorPtr++ = proc(*trans++, palette->red, palette->green, palette->blue ); 697 *colorPtr++ = proc(*trans++, palette->red, palette->green, palette->blue );
698 palette++; 698 palette++;
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
778 if (!rect.intersect(region)) { 778 if (!rect.intersect(region)) {
779 // If the requested region is entirely outside the image, just 779 // If the requested region is entirely outside the image, just
780 // returns false 780 // returns false
781 return false; 781 return false;
782 } 782 }
783 783
784 SkColorType colorType; 784 SkColorType colorType;
785 bool hasAlpha = false; 785 bool hasAlpha = false;
786 SkPMColor theTranspColor = 0; // 0 tells us not to try to match 786 SkPMColor theTranspColor = 0; // 0 tells us not to try to match
787 787
788 if (!this->getBitmapConfig(png_ptr, info_ptr, &colorType, &hasAlpha, &theTra nspColor)) { 788 if (!this->getBitmapColorType(png_ptr, info_ptr, &colorType, &hasAlpha, &the TranspColor)) {
789 return false; 789 return false;
790 } 790 }
791 791
792 const int sampleSize = this->getSampleSize(); 792 const int sampleSize = this->getSampleSize();
793 SkScaledBitmapSampler sampler(origWidth, rect.height(), sampleSize); 793 SkScaledBitmapSampler sampler(origWidth, rect.height(), sampleSize);
794 794
795 SkBitmap decodedBitmap; 795 SkBitmap decodedBitmap;
796 decodedBitmap.setInfo(SkImageInfo::Make(sampler.scaledWidth(), sampler.scale dHeight(), 796 decodedBitmap.setInfo(SkImageInfo::Make(sampler.scaledWidth(), sampler.scale dHeight(),
797 colorType, kPremul_SkAlphaType)); 797 colorType, kPremul_SkAlphaType));
798 798
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
991 #include "SkColorPriv.h" 991 #include "SkColorPriv.h"
992 #include "SkUnPreMultiply.h" 992 #include "SkUnPreMultiply.h"
993 993
994 static void sk_write_fn(png_structp png_ptr, png_bytep data, png_size_t len) { 994 static void sk_write_fn(png_structp png_ptr, png_bytep data, png_size_t len) {
995 SkWStream* sk_stream = (SkWStream*)png_get_io_ptr(png_ptr); 995 SkWStream* sk_stream = (SkWStream*)png_get_io_ptr(png_ptr);
996 if (!sk_stream->write(data, len)) { 996 if (!sk_stream->write(data, len)) {
997 png_error(png_ptr, "sk_write_fn Error!"); 997 png_error(png_ptr, "sk_write_fn Error!");
998 } 998 }
999 } 999 }
1000 1000
1001 static transform_scanline_proc choose_proc(SkBitmap::Config config, 1001 static transform_scanline_proc choose_proc(SkColorType ct, bool hasAlpha) {
1002 bool hasAlpha) {
1003 // we don't care about search on alpha if we're kIndex8, since only the 1002 // we don't care about search on alpha if we're kIndex8, since only the
1004 // colortable packing cares about that distinction, not the pixels 1003 // colortable packing cares about that distinction, not the pixels
1005 if (SkBitmap::kIndex8_Config == config) { 1004 if (kIndex_8_SkColorType == ct) {
1006 hasAlpha = false; // we store false in the table entries for kIndex8 1005 hasAlpha = false; // we store false in the table entries for kIndex8
1007 } 1006 }
1008 1007
1009 static const struct { 1008 static const struct {
1010 SkBitmap::Config fConfig; 1009 SkColorType fColorType;
1011 bool fHasAlpha; 1010 bool fHasAlpha;
1012 transform_scanline_proc fProc; 1011 transform_scanline_proc fProc;
1013 } gMap[] = { 1012 } gMap[] = {
1014 { SkBitmap::kRGB_565_Config, false, transform_scanline_565 }, 1013 { kRGB_565_SkColorType, false, transform_scanline_565 },
1015 { SkBitmap::kARGB_8888_Config, false, transform_scanline_888 }, 1014 { kN32_SkColorType, false, transform_scanline_888 },
1016 { SkBitmap::kARGB_8888_Config, true, transform_scanline_8888 }, 1015 { kN32_SkColorType, true, transform_scanline_8888 },
1017 { SkBitmap::kARGB_4444_Config, false, transform_scanline_444 }, 1016 { kARGB_4444_SkColorType, false, transform_scanline_444 },
1018 { SkBitmap::kARGB_4444_Config, true, transform_scanline_4444 }, 1017 { kARGB_4444_SkColorType, true, transform_scanline_4444 },
1019 { SkBitmap::kIndex8_Config, false, transform_scanline_memcpy }, 1018 { kIndex_8_SkColorType, false, transform_scanline_memcpy },
1020 }; 1019 };
1021 1020
1022 for (int i = SK_ARRAY_COUNT(gMap) - 1; i >= 0; --i) { 1021 for (int i = SK_ARRAY_COUNT(gMap) - 1; i >= 0; --i) {
1023 if (gMap[i].fConfig == config && gMap[i].fHasAlpha == hasAlpha) { 1022 if (gMap[i].fColorType == ct && gMap[i].fHasAlpha == hasAlpha) {
1024 return gMap[i].fProc; 1023 return gMap[i].fProc;
1025 } 1024 }
1026 } 1025 }
1027 sk_throw(); 1026 sk_throw();
1028 return NULL; 1027 return NULL;
1029 } 1028 }
1030 1029
1031 // return the minimum legal bitdepth (by png standards) for this many colortable 1030 // return the minimum legal bitdepth (by png standards) for this many colortable
1032 // entries. SkBitmap always stores in 8bits per pixel, but for colorcount <= 16, 1031 // entries. SkBitmap always stores in 8bits per pixel, but for colorcount <= 16,
1033 // we can use fewer bits per in png 1032 // we can use fewer bits per in png
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
1100 } 1099 }
1101 return num_trans; 1100 return num_trans;
1102 } 1101 }
1103 1102
1104 class SkPNGImageEncoder : public SkImageEncoder { 1103 class SkPNGImageEncoder : public SkImageEncoder {
1105 protected: 1104 protected:
1106 virtual bool onEncode(SkWStream* stream, const SkBitmap& bm, int quality) SK _OVERRIDE; 1105 virtual bool onEncode(SkWStream* stream, const SkBitmap& bm, int quality) SK _OVERRIDE;
1107 private: 1106 private:
1108 bool doEncode(SkWStream* stream, const SkBitmap& bm, 1107 bool doEncode(SkWStream* stream, const SkBitmap& bm,
1109 const bool& hasAlpha, int colorType, 1108 const bool& hasAlpha, int colorType,
1110 int bitDepth, SkBitmap::Config config, 1109 int bitDepth, SkColorType ct,
1111 png_color_8& sig_bit); 1110 png_color_8& sig_bit);
1112 1111
1113 typedef SkImageEncoder INHERITED; 1112 typedef SkImageEncoder INHERITED;
1114 }; 1113 };
1115 1114
1116 bool SkPNGImageEncoder::onEncode(SkWStream* stream, const SkBitmap& bitmap, 1115 bool SkPNGImageEncoder::onEncode(SkWStream* stream, const SkBitmap& bitmap, int /*quality*/) {
1117 int /*quality*/) { 1116 SkColorType ct = bitmap.colorType();
1118 SkBitmap::Config config = bitmap.config();
1119 1117
1120 const bool hasAlpha = !bitmap.isOpaque(); 1118 const bool hasAlpha = !bitmap.isOpaque();
1121 int colorType = PNG_COLOR_MASK_COLOR; 1119 int colorType = PNG_COLOR_MASK_COLOR;
1122 int bitDepth = 8; // default for color 1120 int bitDepth = 8; // default for color
1123 png_color_8 sig_bit; 1121 png_color_8 sig_bit;
1124 1122
1125 switch (config) { 1123 switch (ct) {
1126 case SkBitmap::kIndex8_Config: 1124 case kIndex_8_SkColorType:
1127 colorType |= PNG_COLOR_MASK_PALETTE; 1125 colorType |= PNG_COLOR_MASK_PALETTE;
1128 // fall through to the ARGB_8888 case 1126 // fall through to the ARGB_8888 case
1129 case SkBitmap::kARGB_8888_Config: 1127 case kN32_SkColorType:
1130 sig_bit.red = 8; 1128 sig_bit.red = 8;
1131 sig_bit.green = 8; 1129 sig_bit.green = 8;
1132 sig_bit.blue = 8; 1130 sig_bit.blue = 8;
1133 sig_bit.alpha = 8; 1131 sig_bit.alpha = 8;
1134 break; 1132 break;
1135 case SkBitmap::kARGB_4444_Config: 1133 case kARGB_4444_SkColorType:
1136 sig_bit.red = 4; 1134 sig_bit.red = 4;
1137 sig_bit.green = 4; 1135 sig_bit.green = 4;
1138 sig_bit.blue = 4; 1136 sig_bit.blue = 4;
1139 sig_bit.alpha = 4; 1137 sig_bit.alpha = 4;
1140 break; 1138 break;
1141 case SkBitmap::kRGB_565_Config: 1139 case kRGB_565_SkColorType:
1142 sig_bit.red = 5; 1140 sig_bit.red = 5;
1143 sig_bit.green = 6; 1141 sig_bit.green = 6;
1144 sig_bit.blue = 5; 1142 sig_bit.blue = 5;
1145 sig_bit.alpha = 0; 1143 sig_bit.alpha = 0;
1146 break; 1144 break;
1147 default: 1145 default:
1148 return false; 1146 return false;
1149 } 1147 }
1150 1148
1151 if (hasAlpha) { 1149 if (hasAlpha) {
(...skipping 14 matching lines...) Expand all
1166 // we must do this after we have locked the pixels 1164 // we must do this after we have locked the pixels
1167 SkColorTable* ctable = bitmap.getColorTable(); 1165 SkColorTable* ctable = bitmap.getColorTable();
1168 if (NULL != ctable) { 1166 if (NULL != ctable) {
1169 if (ctable->count() == 0) { 1167 if (ctable->count() == 0) {
1170 return false; 1168 return false;
1171 } 1169 }
1172 // check if we can store in fewer than 8 bits 1170 // check if we can store in fewer than 8 bits
1173 bitDepth = computeBitDepth(ctable->count()); 1171 bitDepth = computeBitDepth(ctable->count());
1174 } 1172 }
1175 1173
1176 return doEncode(stream, bitmap, hasAlpha, colorType, 1174 return doEncode(stream, bitmap, hasAlpha, colorType, bitDepth, ct, sig_bit);
1177 bitDepth, config, sig_bit);
1178 } 1175 }
1179 1176
1180 bool SkPNGImageEncoder::doEncode(SkWStream* stream, const SkBitmap& bitmap, 1177 bool SkPNGImageEncoder::doEncode(SkWStream* stream, const SkBitmap& bitmap,
1181 const bool& hasAlpha, int colorType, 1178 const bool& hasAlpha, int colorType,
1182 int bitDepth, SkBitmap::Config config, 1179 int bitDepth, SkColorType ct,
1183 png_color_8& sig_bit) { 1180 png_color_8& sig_bit) {
1184 1181
1185 png_structp png_ptr; 1182 png_structp png_ptr;
1186 png_infop info_ptr; 1183 png_infop info_ptr;
1187 1184
1188 png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, sk_error_fn, 1185 png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, sk_error_fn,
1189 NULL); 1186 NULL);
1190 if (NULL == png_ptr) { 1187 if (NULL == png_ptr) {
1191 return false; 1188 return false;
1192 } 1189 }
(...skipping 24 matching lines...) Expand all
1217 */ 1214 */
1218 1215
1219 png_set_IHDR(png_ptr, info_ptr, bitmap.width(), bitmap.height(), 1216 png_set_IHDR(png_ptr, info_ptr, bitmap.width(), bitmap.height(),
1220 bitDepth, colorType, 1217 bitDepth, colorType,
1221 PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, 1218 PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE,
1222 PNG_FILTER_TYPE_BASE); 1219 PNG_FILTER_TYPE_BASE);
1223 1220
1224 // set our colortable/trans arrays if needed 1221 // set our colortable/trans arrays if needed
1225 png_color paletteColors[256]; 1222 png_color paletteColors[256];
1226 png_byte trans[256]; 1223 png_byte trans[256];
1227 if (SkBitmap::kIndex8_Config == config) { 1224 if (kIndex_8_SkColorType == ct) {
1228 SkColorTable* ct = bitmap.getColorTable(); 1225 SkColorTable* ct = bitmap.getColorTable();
1229 int numTrans = pack_palette(ct, paletteColors, trans, hasAlpha); 1226 int numTrans = pack_palette(ct, paletteColors, trans, hasAlpha);
1230 png_set_PLTE(png_ptr, info_ptr, paletteColors, ct->count()); 1227 png_set_PLTE(png_ptr, info_ptr, paletteColors, ct->count());
1231 if (numTrans > 0) { 1228 if (numTrans > 0) {
1232 png_set_tRNS(png_ptr, info_ptr, trans, numTrans, NULL); 1229 png_set_tRNS(png_ptr, info_ptr, trans, numTrans, NULL);
1233 } 1230 }
1234 } 1231 }
1235 1232
1236 png_set_sBIT(png_ptr, info_ptr, &sig_bit); 1233 png_set_sBIT(png_ptr, info_ptr, &sig_bit);
1237 png_write_info(png_ptr, info_ptr); 1234 png_write_info(png_ptr, info_ptr);
1238 1235
1239 const char* srcImage = (const char*)bitmap.getPixels(); 1236 const char* srcImage = (const char*)bitmap.getPixels();
1240 SkAutoSMalloc<1024> rowStorage(bitmap.width() << 2); 1237 SkAutoSMalloc<1024> rowStorage(bitmap.width() << 2);
1241 char* storage = (char*)rowStorage.get(); 1238 char* storage = (char*)rowStorage.get();
1242 transform_scanline_proc proc = choose_proc(config, hasAlpha); 1239 transform_scanline_proc proc = choose_proc(ct, hasAlpha);
1243 1240
1244 for (int y = 0; y < bitmap.height(); y++) { 1241 for (int y = 0; y < bitmap.height(); y++) {
1245 png_bytep row_ptr = (png_bytep)storage; 1242 png_bytep row_ptr = (png_bytep)storage;
1246 proc(srcImage, bitmap.width(), storage); 1243 proc(srcImage, bitmap.width(), storage);
1247 png_write_rows(png_ptr, &row_ptr, 1); 1244 png_write_rows(png_ptr, &row_ptr, 1);
1248 srcImage += bitmap.rowBytes(); 1245 srcImage += bitmap.rowBytes();
1249 } 1246 }
1250 1247
1251 png_write_end(png_ptr, info_ptr); 1248 png_write_end(png_ptr, info_ptr);
1252 1249
(...skipping 30 matching lines...) Expand all
1283 return SkImageDecoder::kUnknown_Format; 1280 return SkImageDecoder::kUnknown_Format;
1284 } 1281 }
1285 1282
1286 SkImageEncoder* sk_libpng_efactory(SkImageEncoder::Type t) { 1283 SkImageEncoder* sk_libpng_efactory(SkImageEncoder::Type t) {
1287 return (SkImageEncoder::kPNG_Type == t) ? SkNEW(SkPNGImageEncoder) : NULL; 1284 return (SkImageEncoder::kPNG_Type == t) ? SkNEW(SkPNGImageEncoder) : NULL;
1288 } 1285 }
1289 1286
1290 static SkImageDecoder_DecodeReg gDReg(sk_libpng_dfactory); 1287 static SkImageDecoder_DecodeReg gDReg(sk_libpng_dfactory);
1291 static SkImageDecoder_FormatReg gFormatReg(get_format_png); 1288 static SkImageDecoder_FormatReg gFormatReg(get_format_png);
1292 static SkImageEncoder_EncodeReg gEReg(sk_libpng_efactory); 1289 static SkImageEncoder_EncodeReg gEReg(sk_libpng_efactory);
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698