| 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 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 87 fPng_ptr = nullptr; | 87 fPng_ptr = nullptr; |
| 88 fInfo_ptr = nullptr; | 88 fInfo_ptr = nullptr; |
| 89 } | 89 } |
| 90 | 90 |
| 91 private: | 91 private: |
| 92 png_structp fPng_ptr; | 92 png_structp fPng_ptr; |
| 93 png_infop fInfo_ptr; | 93 png_infop fInfo_ptr; |
| 94 }; | 94 }; |
| 95 #define AutoCleanPng(...) SK_REQUIRE_LOCAL_VAR(AutoCleanPng) | 95 #define AutoCleanPng(...) SK_REQUIRE_LOCAL_VAR(AutoCleanPng) |
| 96 | 96 |
| 97 static inline SkAlphaType xform_alpha_type(SkAlphaType dstAlphaType, SkAlphaType
srcAlphaType) { | |
| 98 return (kOpaque_SkAlphaType == srcAlphaType) ? kOpaque_SkAlphaType : dstAlph
aType; | |
| 99 } | |
| 100 | |
| 101 // Note: SkColorTable claims to store SkPMColors, which is not necessarily the c
ase here. | 97 // Note: SkColorTable claims to store SkPMColors, which is not necessarily the c
ase here. |
| 102 bool SkPngCodec::createColorTable(const SkImageInfo& dstInfo, int* ctableCount)
{ | 98 bool SkPngCodec::createColorTable(const SkImageInfo& dstInfo, int* ctableCount)
{ |
| 103 | 99 |
| 104 int numColors; | 100 int numColors; |
| 105 png_color* palette; | 101 png_color* palette; |
| 106 if (!png_get_PLTE(fPng_ptr, fInfo_ptr, &palette, &numColors)) { | 102 if (!png_get_PLTE(fPng_ptr, fInfo_ptr, &palette, &numColors)) { |
| 107 return false; | 103 return false; |
| 108 } | 104 } |
| 109 | 105 |
| 110 // Contents depend on tableColorType and our choice of if/when to premultipl
y: | 106 // Contents depend on tableColorType and our choice of if/when to premultipl
y: |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 148 SkOpts::RGB_to_BGR1(colorTable + numColorsWithAlpha, palette, | 144 SkOpts::RGB_to_BGR1(colorTable + numColorsWithAlpha, palette, |
| 149 numColors - numColorsWithAlpha); | 145 numColors - numColorsWithAlpha); |
| 150 } | 146 } |
| 151 } | 147 } |
| 152 | 148 |
| 153 // If we are not decoding to F16, we can color xform now and store the resul
ts | 149 // If we are not decoding to F16, we can color xform now and store the resul
ts |
| 154 // in the color table. | 150 // in the color table. |
| 155 if (fColorXform && kRGBA_F16_SkColorType != dstInfo.colorType()) { | 151 if (fColorXform && kRGBA_F16_SkColorType != dstInfo.colorType()) { |
| 156 SkColorType xformColorType = is_rgba(dstInfo.colorType()) ? | 152 SkColorType xformColorType = is_rgba(dstInfo.colorType()) ? |
| 157 kRGBA_8888_SkColorType : kBGRA_8888_SkColorType; | 153 kRGBA_8888_SkColorType : kBGRA_8888_SkColorType; |
| 158 SkAlphaType xformAlphaType = xform_alpha_type(dstInfo.alphaType(), | 154 SkAlphaType xformAlphaType = select_alpha_xform(dstInfo.alphaType(), |
| 159 this->getInfo().alphaType(
)); | 155 this->getInfo().alphaTyp
e()); |
| 160 fColorXform->apply(colorTable, colorTable, numColors, xformColorType, xf
ormAlphaType); | 156 fColorXform->apply(colorTable, colorTable, numColors, xformColorType, xf
ormAlphaType); |
| 161 } | 157 } |
| 162 | 158 |
| 163 // Pad the color table with the last color in the table (or black) in the ca
se that | 159 // Pad the color table with the last color in the table (or black) in the ca
se that |
| 164 // invalid pixel indices exceed the number of colors in the table. | 160 // invalid pixel indices exceed the number of colors in the table. |
| 165 const int maxColors = 1 << fBitDepth; | 161 const int maxColors = 1 << fBitDepth; |
| 166 if (numColors < maxColors) { | 162 if (numColors < maxColors) { |
| 167 SkPMColor lastColor = numColors > 0 ? colorTable[numColors - 1] : SK_Col
orBLACK; | 163 SkPMColor lastColor = numColors > 0 ? colorTable[numColors - 1] : SK_Col
orBLACK; |
| 168 sk_memset32(colorTable + numColors, lastColor, maxColors - numColors); | 164 sk_memset32(colorTable + numColors, lastColor, maxColors - numColors); |
| 169 } | 165 } |
| (...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 440 override { | 436 override { |
| 441 SkASSERT(0 == startRow); | 437 SkASSERT(0 == startRow); |
| 442 | 438 |
| 443 // Assume that an error in libpng indicates an incomplete input. | 439 // Assume that an error in libpng indicates an incomplete input. |
| 444 int y = 0; | 440 int y = 0; |
| 445 if (setjmp(png_jmpbuf((png_struct*)fPng_ptr))) { | 441 if (setjmp(png_jmpbuf((png_struct*)fPng_ptr))) { |
| 446 SkCodecPrintf("Failed to read row.\n"); | 442 SkCodecPrintf("Failed to read row.\n"); |
| 447 return y; | 443 return y; |
| 448 } | 444 } |
| 449 | 445 |
| 450 SkAlphaType xformAlphaType = xform_alpha_type(dstInfo.alphaType(), | 446 SkAlphaType xformAlphaType = select_alpha_xform(dstInfo.alphaType(), |
| 451 this->getInfo().alphaType(
)); | 447 this->getInfo().alphaTyp
e()); |
| 452 int width = fSwizzler ? fSwizzler->swizzleWidth() : dstInfo.width(); | 448 int width = fSwizzler ? fSwizzler->swizzleWidth() : dstInfo.width(); |
| 453 | 449 |
| 454 for (; y < count; y++) { | 450 for (; y < count; y++) { |
| 455 png_read_row(fPng_ptr, fSwizzlerSrcRow, nullptr); | 451 png_read_row(fPng_ptr, fSwizzlerSrcRow, nullptr); |
| 456 this->applyXformRow(dst, fSwizzlerSrcRow, dstInfo.colorType(), xform
AlphaType, width); | 452 this->applyXformRow(dst, fSwizzlerSrcRow, dstInfo.colorType(), xform
AlphaType, width); |
| 457 dst = SkTAddOffset<void>(dst, rowBytes); | 453 dst = SkTAddOffset<void>(dst, rowBytes); |
| 458 } | 454 } |
| 459 | 455 |
| 460 return y; | 456 return y; |
| 461 } | 457 } |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 526 for (int y = 0; y < count; y++) { | 522 for (int y = 0; y < count; y++) { |
| 527 png_read_row(fPng_ptr, srcRow, nullptr); | 523 png_read_row(fPng_ptr, srcRow, nullptr); |
| 528 srcRow += fSrcRowBytes; | 524 srcRow += fSrcRowBytes; |
| 529 } | 525 } |
| 530 // Discard rows that we don't need. | 526 // Discard rows that we don't need. |
| 531 for (int y = 0; y < this->getInfo().height() - startRow - count; y++
) { | 527 for (int y = 0; y < this->getInfo().height() - startRow - count; y++
) { |
| 532 png_read_row(fPng_ptr, fSwizzlerSrcRow, nullptr); | 528 png_read_row(fPng_ptr, fSwizzlerSrcRow, nullptr); |
| 533 } | 529 } |
| 534 } | 530 } |
| 535 | 531 |
| 536 SkAlphaType xformAlphaType = xform_alpha_type(dstInfo.alphaType(), | 532 SkAlphaType xformAlphaType = select_alpha_xform(dstInfo.alphaType(), |
| 537 this->getInfo().alphaType(
)); | 533 this->getInfo().alphaTyp
e()); |
| 538 int width = fSwizzler ? fSwizzler->swizzleWidth() : dstInfo.width(); | 534 int width = fSwizzler ? fSwizzler->swizzleWidth() : dstInfo.width(); |
| 539 srcRow = storage.get(); | 535 srcRow = storage.get(); |
| 540 for (int y = 0; y < count; y++) { | 536 for (int y = 0; y < count; y++) { |
| 541 this->applyXformRow(dst, srcRow, dstInfo.colorType(), xformAlphaType
, width); | 537 this->applyXformRow(dst, srcRow, dstInfo.colorType(), xformAlphaType
, width); |
| 542 srcRow = SkTAddOffset<uint8_t>(srcRow, fSrcRowBytes); | 538 srcRow = SkTAddOffset<uint8_t>(srcRow, fSrcRowBytes); |
| 543 dst = SkTAddOffset<void>(dst, rowBytes); | 539 dst = SkTAddOffset<void>(dst, rowBytes); |
| 544 } | 540 } |
| 545 | 541 |
| 546 return count; | 542 return count; |
| 547 } | 543 } |
| (...skipping 397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 945 SkCodec* outCodec; | 941 SkCodec* outCodec; |
| 946 if (read_header(stream, chunkReader, &outCodec, nullptr, nullptr)) { | 942 if (read_header(stream, chunkReader, &outCodec, nullptr, nullptr)) { |
| 947 // Codec has taken ownership of the stream. | 943 // Codec has taken ownership of the stream. |
| 948 SkASSERT(outCodec); | 944 SkASSERT(outCodec); |
| 949 streamDeleter.release(); | 945 streamDeleter.release(); |
| 950 return outCodec; | 946 return outCodec; |
| 951 } | 947 } |
| 952 | 948 |
| 953 return nullptr; | 949 return nullptr; |
| 954 } | 950 } |
| OLD | NEW |