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

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

Issue 26210007: Image decoder fixes (mostly) around A8. (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: 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
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 356 matching lines...) Expand 10 before | Expand all | Expand 10 after
367 png_set_interlace_handling(png_ptr) : 1; 367 png_set_interlace_handling(png_ptr) : 1;
368 368
369 /* Optional call to gamma correct and add the background to the palette 369 /* Optional call to gamma correct and add the background to the palette
370 * and update info structure. REQUIRED if you are expecting libpng to 370 * and update info structure. REQUIRED if you are expecting libpng to
371 * update the palette for you (ie you selected such a transform above). 371 * update the palette for you (ie you selected such a transform above).
372 */ 372 */
373 png_read_update_info(png_ptr, info_ptr); 373 png_read_update_info(png_ptr, info_ptr);
374 374
375 if ((SkBitmap::kA8_Config == config || SkBitmap::kIndex8_Config == config) 375 if ((SkBitmap::kA8_Config == config || SkBitmap::kIndex8_Config == config)
376 && 1 == sampleSize) { 376 && 1 == sampleSize) {
377 // A8 is only allowed if the original was GRAY. 377 if (SkBitmap::kA8_Config == config) {
378 SkASSERT(config != SkBitmap::kA8_Config 378 // For an A8 bitmap, we assume there is an alpha for speed. It is
379 || PNG_COLOR_TYPE_GRAY == colorType); 379 // possible the bitmap is opaque, but that is an unlikely use case
380 // since it would not be very interesting.
381 reallyHasAlpha = true;
382 // A8 is only allowed if the original was GRAY.
383 SkASSERT(PNG_COLOR_TYPE_GRAY == colorType);
384 }
380 for (int i = 0; i < number_passes; i++) { 385 for (int i = 0; i < number_passes; i++) {
381 for (png_uint_32 y = 0; y < origHeight; y++) { 386 for (png_uint_32 y = 0; y < origHeight; y++) {
382 uint8_t* bmRow = decodedBitmap->getAddr8(0, y); 387 uint8_t* bmRow = decodedBitmap->getAddr8(0, y);
383 png_read_rows(png_ptr, &bmRow, png_bytepp_NULL, 1); 388 png_read_rows(png_ptr, &bmRow, png_bytepp_NULL, 1);
384 } 389 }
385 } 390 }
386 } else { 391 } else {
387 SkScaledBitmapSampler::SrcConfig sc; 392 SkScaledBitmapSampler::SrcConfig sc;
388 int srcBytesPerPixel = 4; 393 int srcBytesPerPixel = 4;
389 394
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
452 } 457 }
453 } 458 }
454 459
455 /* read rest of file, and get additional chunks in info_ptr - REQUIRED */ 460 /* read rest of file, and get additional chunks in info_ptr - REQUIRED */
456 png_read_end(png_ptr, info_ptr); 461 png_read_end(png_ptr, info_ptr);
457 462
458 if (0 != theTranspColor) { 463 if (0 != theTranspColor) {
459 reallyHasAlpha |= substituteTranspColor(decodedBitmap, theTranspColor); 464 reallyHasAlpha |= substituteTranspColor(decodedBitmap, theTranspColor);
460 } 465 }
461 if (reallyHasAlpha && this->getRequireUnpremultipliedColors() && 466 if (reallyHasAlpha && this->getRequireUnpremultipliedColors() &&
462 SkBitmap::kARGB_8888_Config != decodedBitmap->config()) { 467 SkBitmap::kARGB_8888_Config != decodedBitmap->config() &&
468 SkBitmap::kA8_Config != decodedBitmap->config()) {
463 // If the caller wants an unpremultiplied bitmap, and we let them get 469 // If the caller wants an unpremultiplied bitmap, and we let them get
464 // away with a config other than 8888, and it has alpha after all, 470 // away with a config other than 8888, and it has alpha after all,
465 // return false, since the result will have premultiplied colors. 471 // return false, since the result will have premultiplied colors.
472 // The exception is A8, where there is nothing to premultiply.
466 return false; 473 return false;
467 } 474 }
468 if (SkBitmap::kA8_Config == decodedBitmap->config()) {
469 reallyHasAlpha = true;
470 }
471 decodedBitmap->setIsOpaque(!reallyHasAlpha); 475 decodedBitmap->setIsOpaque(!reallyHasAlpha);
472 return true; 476 return true;
473 } 477 }
474 478
475 479
476 480
477 bool SkPNGImageDecoder::getBitmapConfig(png_structp png_ptr, png_infop info_ptr, 481 bool SkPNGImageDecoder::getBitmapConfig(png_structp png_ptr, png_infop info_ptr,
478 SkBitmap::Config* SK_RESTRICT configp, 482 SkBitmap::Config* SK_RESTRICT configp,
479 bool* SK_RESTRICT hasAlphap, 483 bool* SK_RESTRICT hasAlphap,
480 SkPMColor* SK_RESTRICT theTranspColorp) { 484 SkPMColor* SK_RESTRICT theTranspColorp) {
(...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after
831 #else 835 #else
832 // FIXME: This sets pass as desired, but also sets iwidth. Is that ok? 836 // FIXME: This sets pass as desired, but also sets iwidth. Is that ok?
833 png_set_interlaced_pass(png_ptr, 0); 837 png_set_interlaced_pass(png_ptr, 0);
834 #endif 838 #endif
835 png_read_update_info(png_ptr, info_ptr); 839 png_read_update_info(png_ptr, info_ptr);
836 840
837 int actualTop = rect.fTop; 841 int actualTop = rect.fTop;
838 842
839 if ((SkBitmap::kA8_Config == config || SkBitmap::kIndex8_Config == config) 843 if ((SkBitmap::kA8_Config == config || SkBitmap::kIndex8_Config == config)
840 && 1 == sampleSize) { 844 && 1 == sampleSize) {
841 // A8 is only allowed if the original was GRAY. 845 if (SkBitmap::kA8_Config == config) {
842 SkASSERT(config != SkBitmap::kA8_Config 846 // For an A8 bitmap, we assume there is an alpha for speed. It is
843 || PNG_COLOR_TYPE_GRAY == colorType); 847 // possible the bitmap is opaque, but that is an unlikely use case
848 // since it would not be very interesting.
849 reallyHasAlpha = true;
850 // A8 is only allowed if the original was GRAY.
851 SkASSERT(PNG_COLOR_TYPE_GRAY == colorType);
852 }
844 853
845 for (int i = 0; i < number_passes; i++) { 854 for (int i = 0; i < number_passes; i++) {
846 png_configure_decoder(png_ptr, &actualTop, i); 855 png_configure_decoder(png_ptr, &actualTop, i);
847 for (int j = 0; j < rect.fTop - actualTop; j++) { 856 for (int j = 0; j < rect.fTop - actualTop; j++) {
848 uint8_t* bmRow = decodedBitmap.getAddr8(0, 0); 857 uint8_t* bmRow = decodedBitmap.getAddr8(0, 0);
849 png_read_rows(png_ptr, &bmRow, png_bytepp_NULL, 1); 858 png_read_rows(png_ptr, &bmRow, png_bytepp_NULL, 1);
850 } 859 }
851 png_uint_32 bitmapHeight = (png_uint_32) decodedBitmap.height(); 860 png_uint_32 bitmapHeight = (png_uint_32) decodedBitmap.height();
852 for (png_uint_32 y = 0; y < bitmapHeight; y++) { 861 for (png_uint_32 y = 0; y < bitmapHeight; y++) {
853 uint8_t* bmRow = decodedBitmap.getAddr8(0, y); 862 uint8_t* bmRow = decodedBitmap.getAddr8(0, y);
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
924 if (y < height - 1) { 933 if (y < height - 1) {
925 skip_src_rows(png_ptr, srcRow, sampler.srcDY() - 1); 934 skip_src_rows(png_ptr, srcRow, sampler.srcDY() - 1);
926 } 935 }
927 } 936 }
928 } 937 }
929 } 938 }
930 939
931 if (0 != theTranspColor) { 940 if (0 != theTranspColor) {
932 reallyHasAlpha |= substituteTranspColor(&decodedBitmap, theTranspColor); 941 reallyHasAlpha |= substituteTranspColor(&decodedBitmap, theTranspColor);
933 } 942 }
934 if (SkBitmap::kA8_Config == decodedBitmap.config()) { 943 if (reallyHasAlpha && this->getRequireUnpremultipliedColors() &&
935 reallyHasAlpha = true; 944 SkBitmap::kARGB_8888_Config != decodedBitmap.config() &&
945 SkBitmap::kA8_Config != decodedBitmap.config()) {
946 // If the caller wants an unpremultiplied bitmap, and we let them get
947 // away with a config other than 8888, and it has alpha after all,
948 // return false, since the result will have premultiplied colors.
949 // The exception is A8, where there is nothing to premultiply.
reed1 2013/10/08 16:24:17 What is the config that - has alpha - has premul
scroggo 2013/10/10 21:46:59 4444 and Index8. Both of them COULD support unprem
reed1 2013/10/14 13:26:05 Thanks for the dox... I think the code is not as c
scroggo 2013/10/14 17:15:19 Yes. Latest code follows this pattern.
950 return false;
936 } 951 }
937 decodedBitmap.setIsOpaque(!reallyHasAlpha); 952 decodedBitmap.setIsOpaque(!reallyHasAlpha);
938 953
939 if (swapOnly) { 954 if (swapOnly) {
940 bm->swap(decodedBitmap); 955 bm->swap(decodedBitmap);
941 return true; 956 return true;
942 } 957 }
943 return this->cropBitmap(bm, &decodedBitmap, sampleSize, region.x(), region.y (), 958 return this->cropBitmap(bm, &decodedBitmap, sampleSize, region.x(), region.y (),
944 region.width(), region.height(), 0, rect.y()); 959 region.width(), region.height(), 0, rect.y());
945 } 960 }
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after
1242 return SkImageDecoder::kUnknown_Format; 1257 return SkImageDecoder::kUnknown_Format;
1243 } 1258 }
1244 1259
1245 SkImageEncoder* sk_libpng_efactory(SkImageEncoder::Type t) { 1260 SkImageEncoder* sk_libpng_efactory(SkImageEncoder::Type t) {
1246 return (SkImageEncoder::kPNG_Type == t) ? SkNEW(SkPNGImageEncoder) : NULL; 1261 return (SkImageEncoder::kPNG_Type == t) ? SkNEW(SkPNGImageEncoder) : NULL;
1247 } 1262 }
1248 1263
1249 static SkImageDecoder_DecodeReg gDReg(sk_libpng_dfactory); 1264 static SkImageDecoder_DecodeReg gDReg(sk_libpng_dfactory);
1250 static SkImageDecoder_FormatReg gFormatReg(get_format_png); 1265 static SkImageDecoder_FormatReg gFormatReg(get_format_png);
1251 static SkImageEncoder_EncodeReg gEReg(sk_libpng_efactory); 1266 static SkImageEncoder_EncodeReg gEReg(sk_libpng_efactory);
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698