| Index: src/codec/SkPngCodec.cpp
|
| diff --git a/src/codec/SkPngCodec.cpp b/src/codec/SkPngCodec.cpp
|
| index 8ae2360f2570f5addb6cfb37fc4bea8e6b0483f7..33c3b6095b9b29276bc949d0c23cb88382b55adb 100644
|
| --- a/src/codec/SkPngCodec.cpp
|
| +++ b/src/codec/SkPngCodec.cpp
|
| @@ -279,7 +279,7 @@ sk_sp<SkColorSpace> read_color_space(png_structp png_ptr, png_infop info_ptr) {
|
| // png_structp on success.
|
| // @param info_ptrp Optional output variable. If non-NULL, will be set to a new
|
| // png_infop on success;
|
| -// @param imageInfo Optional output variable. If non-NULL, will be set to
|
| +// @param info 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,7 +290,8 @@ sk_sp<SkColorSpace> read_color_space(png_structp png_ptr, png_infop info_ptr) {
|
| // 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,
|
| - SkImageInfo* imageInfo, int* bitDepthPtr, int* numberPassesPtr) {
|
| + int* width, int* height, SkEncodedInfo* info, 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);
|
| @@ -348,8 +349,8 @@ static bool read_header(SkStream* stream, SkPngChunkReader* chunkReader,
|
| // 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.
|
| - SkColorType colorType = kUnknown_SkColorType;
|
| - SkAlphaType alphaType = kUnknown_SkAlphaType;
|
| + SkEncodedInfo::Color color;
|
| + SkEncodedInfo::Alpha alpha;
|
| switch (encodedColorType) {
|
| case PNG_COLOR_TYPE_PALETTE:
|
| // Extract multiple pixels with bit depths of 1, 2, and 4 from a single
|
| @@ -359,20 +360,21 @@ static bool read_header(SkStream* stream, SkPngChunkReader* chunkReader,
|
| png_set_packing(png_ptr);
|
| }
|
|
|
| - 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;
|
| + 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;
|
| 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);
|
| - alphaType = kUnpremul_SkAlphaType;
|
| + color = SkEncodedInfo::kRGBA_Color;
|
| + alpha = SkEncodedInfo::kBinary_Alpha;
|
| } else {
|
| - alphaType = kOpaque_SkAlphaType;
|
| + color = SkEncodedInfo::kRGB_Color;
|
| + alpha = SkEncodedInfo::kOpaque_Alpha;
|
| }
|
| - colorType = kN32_SkColorType;
|
| break;
|
| case PNG_COLOR_TYPE_GRAY:
|
| // Expand grayscale images to the full 8 bits from 1, 2, or 4 bits/pixel.
|
| @@ -383,29 +385,26 @@ static bool read_header(SkStream* stream, SkPngChunkReader* chunkReader,
|
|
|
| if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
|
| png_set_tRNS_to_alpha(png_ptr);
|
| -
|
| - // We will recommend kN32 here since we do not support kGray
|
| - // with alpha.
|
| - colorType = kN32_SkColorType;
|
| - alphaType = kUnpremul_SkAlphaType;
|
| + color = SkEncodedInfo::kGrayAlpha_Color;
|
| + alpha = SkEncodedInfo::kBinary_Alpha;
|
| } else {
|
| - colorType = kGray_8_SkColorType;
|
| - alphaType = kOpaque_SkAlphaType;
|
| + color = SkEncodedInfo::kGray_Color;
|
| + alpha = SkEncodedInfo::kOpaque_Alpha;
|
| }
|
| break;
|
| case PNG_COLOR_TYPE_GRAY_ALPHA:
|
| - // We will recommend kN32 here since we do not support anything
|
| - // similar to GRAY_ALPHA.
|
| - colorType = kN32_SkColorType;
|
| - alphaType = kUnpremul_SkAlphaType;
|
| + color = SkEncodedInfo::kGrayAlpha_Color;
|
| + alpha = SkEncodedInfo::kUnpremul_Alpha;
|
| break;
|
| case PNG_COLOR_TYPE_RGBA:
|
| - colorType = kN32_SkColorType;
|
| - alphaType = kUnpremul_SkAlphaType;
|
| + color = SkEncodedInfo::kRGBA_Color;
|
| + alpha = SkEncodedInfo::kUnpremul_Alpha;
|
| 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);
|
| @@ -413,13 +412,14 @@ static bool read_header(SkStream* stream, SkPngChunkReader* chunkReader,
|
| *numberPassesPtr = numberPasses;
|
| }
|
|
|
| - SkColorProfileType profileType = kLinear_SkColorProfileType;
|
| - if (png_get_valid(png_ptr, info_ptr, PNG_INFO_sRGB)) {
|
| - profileType = kSRGB_SkColorProfileType;
|
| + if (info) {
|
| + *info = SkEncodedInfo::Make(color, alpha, 8);
|
| }
|
| -
|
| - if (imageInfo) {
|
| - *imageInfo = SkImageInfo::Make(origWidth, origHeight, colorType, alphaType, profileType);
|
| + if (width) {
|
| + *width = origWidth;
|
| + }
|
| + if (height) {
|
| + *height = origHeight;
|
| }
|
| autoClean.release();
|
| if (png_ptrp) {
|
| @@ -432,10 +432,10 @@ static bool read_header(SkStream* stream, SkPngChunkReader* chunkReader,
|
| return true;
|
| }
|
|
|
| -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)
|
| +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)
|
| , fPngChunkReader(SkSafeRef(chunkReader))
|
| , fPng_ptr(png_ptr)
|
| , fInfo_ptr(info_ptr)
|
| @@ -538,7 +538,7 @@ bool SkPngCodec::onRewind() {
|
| 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,10 +644,11 @@ uint32_t SkPngCodec::onGetFillValue(SkColorType colorType) const {
|
| // Subclass of SkPngCodec which supports scanline decoding
|
| class SkPngScanlineDecoder : public SkPngCodec {
|
| public:
|
| - SkPngScanlineDecoder(const SkImageInfo& srcInfo, SkStream* stream,
|
| + SkPngScanlineDecoder(int width, int height, const SkEncodedInfo& info, SkStream* stream,
|
| SkPngChunkReader* chunkReader, png_structp png_ptr, png_infop info_ptr, int bitDepth,
|
| sk_sp<SkColorSpace> colorSpace)
|
| - : INHERITED(srcInfo, stream, chunkReader, png_ptr, info_ptr, bitDepth, 1, colorSpace)
|
| + : INHERITED(width, height, info, stream, chunkReader, png_ptr, info_ptr, bitDepth, 1,
|
| + colorSpace)
|
| , fSrcRow(nullptr)
|
| {}
|
|
|
| @@ -710,11 +711,11 @@ private:
|
|
|
| class SkPngInterlacedScanlineDecoder : public SkPngCodec {
|
| public:
|
| - 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)
|
| + 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)
|
| , fHeight(-1)
|
| , fCanSkipRewind(false)
|
| {
|
| @@ -836,23 +837,24 @@ SkCodec* SkPngCodec::NewFromStream(SkStream* stream, SkPngChunkReader* chunkRead
|
| SkAutoTDelete<SkStream> streamDeleter(stream);
|
| png_structp png_ptr;
|
| png_infop info_ptr;
|
| - SkImageInfo imageInfo;
|
| + int width, height;
|
| + SkEncodedInfo imageInfo;
|
| int bitDepth;
|
| int numberPasses;
|
|
|
| - if (!read_header(stream, chunkReader, &png_ptr, &info_ptr, &imageInfo, &bitDepth,
|
| - &numberPasses)) {
|
| + if (!read_header(stream, chunkReader, &png_ptr, &info_ptr, &width, &height, &imageInfo,
|
| + &bitDepth, &numberPasses)) {
|
| return nullptr;
|
| }
|
|
|
| auto colorSpace = read_color_space(png_ptr, info_ptr);
|
|
|
| if (1 == numberPasses) {
|
| - return new SkPngScanlineDecoder(imageInfo, streamDeleter.release(), chunkReader,
|
| - png_ptr, info_ptr, bitDepth, colorSpace);
|
| + return new SkPngScanlineDecoder(width, height, imageInfo, streamDeleter.release(),
|
| + chunkReader, png_ptr, info_ptr, bitDepth, colorSpace);
|
| }
|
|
|
| - return new SkPngInterlacedScanlineDecoder(imageInfo, streamDeleter.release(), chunkReader,
|
| - png_ptr, info_ptr, bitDepth, numberPasses,
|
| - colorSpace);
|
| + return new SkPngInterlacedScanlineDecoder(width, height, imageInfo, streamDeleter.release(),
|
| + chunkReader, png_ptr, info_ptr, bitDepth,
|
| + numberPasses, colorSpace);
|
| }
|
|
|