| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 Google Inc. |
| 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 "SkBitmap.h" | 8 #include "SkBitmap.h" |
| 9 #include "SkCodecPriv.h" | 9 #include "SkCodecPriv.h" |
| 10 #include "SkColorPriv.h" | 10 #include "SkColorPriv.h" |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 79 fPng_ptr = nullptr; | 79 fPng_ptr = nullptr; |
| 80 fInfo_ptr = nullptr; | 80 fInfo_ptr = nullptr; |
| 81 } | 81 } |
| 82 | 82 |
| 83 private: | 83 private: |
| 84 png_structp fPng_ptr; | 84 png_structp fPng_ptr; |
| 85 png_infop fInfo_ptr; | 85 png_infop fInfo_ptr; |
| 86 }; | 86 }; |
| 87 #define AutoCleanPng(...) SK_REQUIRE_LOCAL_VAR(AutoCleanPng) | 87 #define AutoCleanPng(...) SK_REQUIRE_LOCAL_VAR(AutoCleanPng) |
| 88 | 88 |
| 89 // Method for coverting to either an SkPMColor or a similarly packed | |
| 90 // unpremultiplied color. | |
| 91 typedef uint32_t (*PackColorProc)(U8CPU a, U8CPU r, U8CPU g, U8CPU b); | |
| 92 | |
| 93 // Note: SkColorTable claims to store SkPMColors, which is not necessarily | 89 // Note: SkColorTable claims to store SkPMColors, which is not necessarily |
| 94 // the case here. | 90 // the case here. |
| 95 // TODO: If we add support for non-native swizzles, we'll need to handle that he
re. | 91 // TODO: If we add support for non-native swizzles, we'll need to handle that he
re. |
| 96 bool SkPngCodec::decodePalette(bool premultiply, int* ctableCount) { | 92 bool SkPngCodec::createColorTable(SkColorType dstColorType, bool premultiply, in
t* ctableCount) { |
| 97 | 93 |
| 98 int numColors; | 94 int numColors; |
| 99 png_color* palette; | 95 png_color* palette; |
| 100 if (!png_get_PLTE(fPng_ptr, fInfo_ptr, &palette, &numColors)) { | 96 if (!png_get_PLTE(fPng_ptr, fInfo_ptr, &palette, &numColors)) { |
| 101 return false; | 97 return false; |
| 102 } | 98 } |
| 103 | 99 |
| 104 // Note: These are not necessarily SkPMColors. | 100 // Note: These are not necessarily SkPMColors. |
| 105 SkPMColor colorPtr[256]; | 101 SkPMColor colorPtr[256]; |
| 106 | 102 |
| 107 png_bytep alphas; | 103 png_bytep alphas; |
| 108 int numColorsWithAlpha = 0; | 104 int numColorsWithAlpha = 0; |
| 109 if (png_get_tRNS(fPng_ptr, fInfo_ptr, &alphas, &numColorsWithAlpha, nullptr)
) { | 105 if (png_get_tRNS(fPng_ptr, fInfo_ptr, &alphas, &numColorsWithAlpha, nullptr)
) { |
| 110 // Choose which function to use to create the color table. If the final
destination's | 106 // Choose which function to use to create the color table. If the final
destination's |
| 111 // colortype is unpremultiplied, the color table will store unpremultipl
ied colors. | 107 // colortype is unpremultiplied, the color table will store unpremultipl
ied colors. |
| 112 PackColorProc proc; | 108 PackColorProc proc = choose_pack_color_proc(premultiply, dstColorType); |
| 113 if (premultiply) { | |
| 114 proc = &SkPremultiplyARGBInline; | |
| 115 } else { | |
| 116 proc = &SkPackARGB32NoCheck; | |
| 117 } | |
| 118 | 109 |
| 119 for (int i = 0; i < numColorsWithAlpha; i++) { | 110 for (int i = 0; i < numColorsWithAlpha; i++) { |
| 120 // We don't have a function in SkOpts that combines a set of alphas
with a set | 111 // We don't have a function in SkOpts that combines a set of alphas
with a set |
| 121 // of RGBs. We could write one, but it's hardly worth it, given tha
t this | 112 // of RGBs. We could write one, but it's hardly worth it, given tha
t this |
| 122 // is such a small fraction of the total decode time. | 113 // is such a small fraction of the total decode time. |
| 123 colorPtr[i] = proc(alphas[i], palette->red, palette->green, palette-
>blue); | 114 colorPtr[i] = proc(alphas[i], palette->red, palette->green, palette-
>blue); |
| 124 palette++; | 115 palette++; |
| 125 } | 116 } |
| 126 } | 117 } |
| 127 | 118 |
| 128 if (numColorsWithAlpha < numColors) { | 119 if (numColorsWithAlpha < numColors) { |
| 129 // The optimized code depends on a 3-byte png_color struct with the colo
rs | 120 // The optimized code depends on a 3-byte png_color struct with the colo
rs |
| 130 // in RGB order. These checks make sure it is safe to use. | 121 // in RGB order. These checks make sure it is safe to use. |
| 131 static_assert(3 == sizeof(png_color), "png_color struct has changed. Op
ts are broken."); | 122 static_assert(3 == sizeof(png_color), "png_color struct has changed. Op
ts are broken."); |
| 132 #ifdef SK_DEBUG | 123 #ifdef SK_DEBUG |
| 133 SkASSERT(&palette->red < &palette->green); | 124 SkASSERT(&palette->red < &palette->green); |
| 134 SkASSERT(&palette->green < &palette->blue); | 125 SkASSERT(&palette->green < &palette->blue); |
| 135 #endif | 126 #endif |
| 136 | 127 |
| 137 #ifdef SK_PMCOLOR_IS_RGBA | 128 if (is_rgba(dstColorType)) { |
| 138 SkOpts::RGB_to_RGB1(colorPtr + numColorsWithAlpha, palette, numColors -
numColorsWithAlpha); | 129 SkOpts::RGB_to_RGB1(colorPtr + numColorsWithAlpha, palette, |
| 139 #else | 130 numColors - numColorsWithAlpha); |
| 140 SkOpts::RGB_to_BGR1(colorPtr + numColorsWithAlpha, palette, numColors -
numColorsWithAlpha); | 131 } else { |
| 141 #endif | 132 SkOpts::RGB_to_BGR1(colorPtr + numColorsWithAlpha, palette, |
| 133 numColors - numColorsWithAlpha); |
| 134 } |
| 142 } | 135 } |
| 143 | 136 |
| 144 // Pad the color table with the last color in the table (or black) in the ca
se that | 137 // Pad the color table with the last color in the table (or black) in the ca
se that |
| 145 // invalid pixel indices exceed the number of colors in the table. | 138 // invalid pixel indices exceed the number of colors in the table. |
| 146 const int maxColors = 1 << fBitDepth; | 139 const int maxColors = 1 << fBitDepth; |
| 147 if (numColors < maxColors) { | 140 if (numColors < maxColors) { |
| 148 SkPMColor lastColor = numColors > 0 ? colorPtr[numColors - 1] : SK_Color
BLACK; | 141 SkPMColor lastColor = numColors > 0 ? colorPtr[numColors - 1] : SK_Color
BLACK; |
| 149 sk_memset32(colorPtr + numColors, lastColor, maxColors - numColors); | 142 sk_memset32(colorPtr + numColors, lastColor, maxColors - numColors); |
| 150 } | 143 } |
| 151 | 144 |
| (...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 467 int* ctableCount) { | 460 int* ctableCount) { |
| 468 // FIXME: Could we use the return value of setjmp to specify the type of | 461 // FIXME: Could we use the return value of setjmp to specify the type of |
| 469 // error? | 462 // error? |
| 470 if (setjmp(png_jmpbuf(fPng_ptr))) { | 463 if (setjmp(png_jmpbuf(fPng_ptr))) { |
| 471 SkCodecPrintf("setjmp long jump!\n"); | 464 SkCodecPrintf("setjmp long jump!\n"); |
| 472 return kInvalidInput; | 465 return kInvalidInput; |
| 473 } | 466 } |
| 474 png_read_update_info(fPng_ptr, fInfo_ptr); | 467 png_read_update_info(fPng_ptr, fInfo_ptr); |
| 475 | 468 |
| 476 if (SkEncodedInfo::kPalette_Color == this->getEncodedInfo().color()) { | 469 if (SkEncodedInfo::kPalette_Color == this->getEncodedInfo().color()) { |
| 477 if (!this->decodePalette(kPremul_SkAlphaType == requestedInfo.alphaType(
), ctableCount)) { | 470 if (!this->createColorTable(requestedInfo.colorType(), |
| 471 kPremul_SkAlphaType == requestedInfo.alphaType(), ctableCount))
{ |
| 478 return kInvalidInput; | 472 return kInvalidInput; |
| 479 } | 473 } |
| 480 } | 474 } |
| 481 | 475 |
| 482 // Copy the color table to the client if they request kIndex8 mode | 476 // Copy the color table to the client if they request kIndex8 mode |
| 483 copy_color_table(requestedInfo, fColorTable, ctable, ctableCount); | 477 copy_color_table(requestedInfo, fColorTable, ctable, ctableCount); |
| 484 | 478 |
| 485 // Create the swizzler. SkPngCodec retains ownership of the color table. | 479 // Create the swizzler. SkPngCodec retains ownership of the color table. |
| 486 const SkPMColor* colors = get_color_ptr(fColorTable.get()); | 480 const SkPMColor* colors = get_color_ptr(fColorTable.get()); |
| 487 fSwizzler.reset(SkSwizzler::CreateSwizzler(this->getEncodedInfo(), colors, r
equestedInfo, | 481 fSwizzler.reset(SkSwizzler::CreateSwizzler(this->getEncodedInfo(), colors, r
equestedInfo, |
| (...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 824 | 818 |
| 825 if (1 == numberPasses) { | 819 if (1 == numberPasses) { |
| 826 return new SkPngScanlineDecoder(width, height, imageInfo, streamDeleter.
release(), | 820 return new SkPngScanlineDecoder(width, height, imageInfo, streamDeleter.
release(), |
| 827 chunkReader, png_ptr, info_ptr, bitDepth
, colorSpace); | 821 chunkReader, png_ptr, info_ptr, bitDepth
, colorSpace); |
| 828 } | 822 } |
| 829 | 823 |
| 830 return new SkPngInterlacedScanlineDecoder(width, height, imageInfo, streamDe
leter.release(), | 824 return new SkPngInterlacedScanlineDecoder(width, height, imageInfo, streamDe
leter.release(), |
| 831 chunkReader, png_ptr, info_ptr, bi
tDepth, | 825 chunkReader, png_ptr, info_ptr, bi
tDepth, |
| 832 numberPasses, colorSpace); | 826 numberPasses, colorSpace); |
| 833 } | 827 } |
| OLD | NEW |