| Index: src/codec/SkPngCodec.cpp
|
| diff --git a/src/codec/SkPngCodec.cpp b/src/codec/SkPngCodec.cpp
|
| index 33c3b6095b9b29276bc949d0c23cb88382b55adb..8ae2360f2570f5addb6cfb37fc4bea8e6b0483f7 100644
|
| --- a/src/codec/SkPngCodec.cpp
|
| +++ b/src/codec/SkPngCodec.cpp
|
| @@ -279,7 +279,7 @@
|
| // png_structp on success.
|
| // @param info_ptrp Optional output variable. If non-NULL, will be set to a new
|
| // png_infop on success;
|
| -// @param info Optional output variable. If non-NULL, will be set to
|
| +// @param imageInfo Optional output variable. If non-NULL, will be set to
|
| // reflect the properties of the encoded image on success.
|
| // @param bitDepthPtr Optional output variable. If non-NULL, will be set to the
|
| // bit depth of the encoded image on success.
|
| @@ -290,8 +290,7 @@
|
| // If it returns false, the passed in fields (except stream) are unchanged.
|
| static bool read_header(SkStream* stream, SkPngChunkReader* chunkReader,
|
| png_structp* png_ptrp, png_infop* info_ptrp,
|
| - int* width, int* height, SkEncodedInfo* info, int* bitDepthPtr,
|
| - int* numberPassesPtr) {
|
| + SkImageInfo* imageInfo, int* bitDepthPtr, int* numberPassesPtr) {
|
| // The image is known to be a PNG. Decode enough to know the SkImageInfo.
|
| png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr,
|
| sk_error_fn, sk_warning_fn);
|
| @@ -349,8 +348,8 @@
|
| // Now determine the default colorType and alphaType and set the required transforms.
|
| // Often, we depend on SkSwizzler to perform any transforms that we need. However, we
|
| // still depend on libpng for many of the rare and PNG-specific cases.
|
| - SkEncodedInfo::Color color;
|
| - SkEncodedInfo::Alpha alpha;
|
| + SkColorType colorType = kUnknown_SkColorType;
|
| + SkAlphaType alphaType = kUnknown_SkAlphaType;
|
| switch (encodedColorType) {
|
| case PNG_COLOR_TYPE_PALETTE:
|
| // Extract multiple pixels with bit depths of 1, 2, and 4 from a single
|
| @@ -360,21 +359,20 @@
|
| png_set_packing(png_ptr);
|
| }
|
|
|
| - color = SkEncodedInfo::kPalette_Color;
|
| - // Set the alpha depending on if a transparency chunk exists.
|
| - alpha = png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS) ?
|
| - SkEncodedInfo::kUnpremul_Alpha : SkEncodedInfo::kOpaque_Alpha;
|
| + colorType = kIndex_8_SkColorType;
|
| + // Set the alpha type depending on if a transparency chunk exists.
|
| + alphaType = png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS) ?
|
| + kUnpremul_SkAlphaType : kOpaque_SkAlphaType;
|
| break;
|
| case PNG_COLOR_TYPE_RGB:
|
| if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
|
| // Convert to RGBA if transparency chunk exists.
|
| png_set_tRNS_to_alpha(png_ptr);
|
| - color = SkEncodedInfo::kRGBA_Color;
|
| - alpha = SkEncodedInfo::kBinary_Alpha;
|
| + alphaType = kUnpremul_SkAlphaType;
|
| } else {
|
| - color = SkEncodedInfo::kRGB_Color;
|
| - alpha = SkEncodedInfo::kOpaque_Alpha;
|
| - }
|
| + alphaType = kOpaque_SkAlphaType;
|
| + }
|
| + colorType = kN32_SkColorType;
|
| break;
|
| case PNG_COLOR_TYPE_GRAY:
|
| // Expand grayscale images to the full 8 bits from 1, 2, or 4 bits/pixel.
|
| @@ -385,26 +383,29 @@
|
|
|
| if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
|
| png_set_tRNS_to_alpha(png_ptr);
|
| - color = SkEncodedInfo::kGrayAlpha_Color;
|
| - alpha = SkEncodedInfo::kBinary_Alpha;
|
| +
|
| + // We will recommend kN32 here since we do not support kGray
|
| + // with alpha.
|
| + colorType = kN32_SkColorType;
|
| + alphaType = kUnpremul_SkAlphaType;
|
| } else {
|
| - color = SkEncodedInfo::kGray_Color;
|
| - alpha = SkEncodedInfo::kOpaque_Alpha;
|
| + colorType = kGray_8_SkColorType;
|
| + alphaType = kOpaque_SkAlphaType;
|
| }
|
| break;
|
| case PNG_COLOR_TYPE_GRAY_ALPHA:
|
| - color = SkEncodedInfo::kGrayAlpha_Color;
|
| - alpha = SkEncodedInfo::kUnpremul_Alpha;
|
| + // We will recommend kN32 here since we do not support anything
|
| + // similar to GRAY_ALPHA.
|
| + colorType = kN32_SkColorType;
|
| + alphaType = kUnpremul_SkAlphaType;
|
| break;
|
| case PNG_COLOR_TYPE_RGBA:
|
| - color = SkEncodedInfo::kRGBA_Color;
|
| - alpha = SkEncodedInfo::kUnpremul_Alpha;
|
| + colorType = kN32_SkColorType;
|
| + alphaType = kUnpremul_SkAlphaType;
|
| break;
|
| default:
|
| // All the color types have been covered above.
|
| SkASSERT(false);
|
| - color = SkEncodedInfo::kRGBA_Color;
|
| - alpha = SkEncodedInfo::kUnpremul_Alpha;
|
| }
|
|
|
| int numberPasses = png_set_interlace_handling(png_ptr);
|
| @@ -412,14 +413,13 @@
|
| *numberPassesPtr = numberPasses;
|
| }
|
|
|
| - if (info) {
|
| - *info = SkEncodedInfo::Make(color, alpha, 8);
|
| - }
|
| - if (width) {
|
| - *width = origWidth;
|
| - }
|
| - if (height) {
|
| - *height = origHeight;
|
| + SkColorProfileType profileType = kLinear_SkColorProfileType;
|
| + if (png_get_valid(png_ptr, info_ptr, PNG_INFO_sRGB)) {
|
| + profileType = kSRGB_SkColorProfileType;
|
| + }
|
| +
|
| + if (imageInfo) {
|
| + *imageInfo = SkImageInfo::Make(origWidth, origHeight, colorType, alphaType, profileType);
|
| }
|
| autoClean.release();
|
| if (png_ptrp) {
|
| @@ -432,10 +432,10 @@
|
| return true;
|
| }
|
|
|
| -SkPngCodec::SkPngCodec(int width, int height, const SkEncodedInfo& info, SkStream* stream,
|
| - SkPngChunkReader* chunkReader, png_structp png_ptr, png_infop info_ptr,
|
| - int bitDepth, int numberPasses, sk_sp<SkColorSpace> colorSpace)
|
| - : INHERITED(width, height, info, stream, colorSpace)
|
| +SkPngCodec::SkPngCodec(const SkImageInfo& info, SkStream* stream, SkPngChunkReader* chunkReader,
|
| + png_structp png_ptr, png_infop info_ptr, int bitDepth, int numberPasses,
|
| + sk_sp<SkColorSpace> colorSpace)
|
| + : INHERITED(info, stream, colorSpace)
|
| , fPngChunkReader(SkSafeRef(chunkReader))
|
| , fPng_ptr(png_ptr)
|
| , fInfo_ptr(info_ptr)
|
| @@ -538,7 +538,7 @@
|
| png_structp png_ptr;
|
| png_infop info_ptr;
|
| if (!read_header(this->stream(), fPngChunkReader.get(), &png_ptr, &info_ptr,
|
| - nullptr, nullptr, nullptr, nullptr, nullptr)) {
|
| + nullptr, nullptr, nullptr)) {
|
| return false;
|
| }
|
|
|
| @@ -644,11 +644,10 @@
|
| // Subclass of SkPngCodec which supports scanline decoding
|
| class SkPngScanlineDecoder : public SkPngCodec {
|
| public:
|
| - SkPngScanlineDecoder(int width, int height, const SkEncodedInfo& info, SkStream* stream,
|
| + SkPngScanlineDecoder(const SkImageInfo& srcInfo, SkStream* stream,
|
| SkPngChunkReader* chunkReader, png_structp png_ptr, png_infop info_ptr, int bitDepth,
|
| sk_sp<SkColorSpace> colorSpace)
|
| - : INHERITED(width, height, info, stream, chunkReader, png_ptr, info_ptr, bitDepth, 1,
|
| - colorSpace)
|
| + : INHERITED(srcInfo, stream, chunkReader, png_ptr, info_ptr, bitDepth, 1, colorSpace)
|
| , fSrcRow(nullptr)
|
| {}
|
|
|
| @@ -711,11 +710,11 @@
|
|
|
| class SkPngInterlacedScanlineDecoder : public SkPngCodec {
|
| public:
|
| - SkPngInterlacedScanlineDecoder(int width, int height, const SkEncodedInfo& info,
|
| - SkStream* stream, SkPngChunkReader* chunkReader, png_structp png_ptr,
|
| - png_infop info_ptr, int bitDepth, int numberPasses, sk_sp<SkColorSpace> colorSpace)
|
| - : INHERITED(width, height, info, stream, chunkReader, png_ptr, info_ptr, bitDepth,
|
| - numberPasses, colorSpace)
|
| + SkPngInterlacedScanlineDecoder(const SkImageInfo& srcInfo, SkStream* stream,
|
| + SkPngChunkReader* chunkReader, png_structp png_ptr, png_infop info_ptr,
|
| + int bitDepth, int numberPasses, sk_sp<SkColorSpace> colorSpace)
|
| + : INHERITED(srcInfo, stream, chunkReader, png_ptr, info_ptr, bitDepth, numberPasses,
|
| + colorSpace)
|
| , fHeight(-1)
|
| , fCanSkipRewind(false)
|
| {
|
| @@ -837,24 +836,23 @@
|
| SkAutoTDelete<SkStream> streamDeleter(stream);
|
| png_structp png_ptr;
|
| png_infop info_ptr;
|
| - int width, height;
|
| - SkEncodedInfo imageInfo;
|
| + SkImageInfo imageInfo;
|
| int bitDepth;
|
| int numberPasses;
|
|
|
| - if (!read_header(stream, chunkReader, &png_ptr, &info_ptr, &width, &height, &imageInfo,
|
| - &bitDepth, &numberPasses)) {
|
| + if (!read_header(stream, chunkReader, &png_ptr, &info_ptr, &imageInfo, &bitDepth,
|
| + &numberPasses)) {
|
| return nullptr;
|
| }
|
|
|
| auto colorSpace = read_color_space(png_ptr, info_ptr);
|
|
|
| if (1 == numberPasses) {
|
| - return new SkPngScanlineDecoder(width, height, imageInfo, streamDeleter.release(),
|
| - chunkReader, png_ptr, info_ptr, bitDepth, colorSpace);
|
| - }
|
| -
|
| - return new SkPngInterlacedScanlineDecoder(width, height, imageInfo, streamDeleter.release(),
|
| - chunkReader, png_ptr, info_ptr, bitDepth,
|
| - numberPasses, colorSpace);
|
| -}
|
| + return new SkPngScanlineDecoder(imageInfo, streamDeleter.release(), chunkReader,
|
| + png_ptr, info_ptr, bitDepth, colorSpace);
|
| + }
|
| +
|
| + return new SkPngInterlacedScanlineDecoder(imageInfo, streamDeleter.release(), chunkReader,
|
| + png_ptr, info_ptr, bitDepth, numberPasses,
|
| + colorSpace);
|
| +}
|
|
|