diff options
Diffstat (limited to 'src/images/SkPNGImageEncoder.cpp')
-rw-r--r-- | src/images/SkPNGImageEncoder.cpp | 46 |
1 files changed, 23 insertions, 23 deletions
diff --git a/src/images/SkPNGImageEncoder.cpp b/src/images/SkPNGImageEncoder.cpp index 9f5ebd27ab..b57c32a0fc 100644 --- a/src/images/SkPNGImageEncoder.cpp +++ b/src/images/SkPNGImageEncoder.cpp @@ -51,8 +51,10 @@ static void set_icc(png_structp png_ptr, png_infop info_ptr, sk_sp<SkData> icc) png_set_iCCP(png_ptr, info_ptr, name, 0, iccPtr, icc->size()); } -static transform_scanline_proc choose_proc(const SkImageInfo& info) { - const bool isGammaEncoded = info.gammaCloseToSRGB(); +static transform_scanline_proc choose_proc(const SkImageInfo& info, + SkTransferFunctionBehavior unpremulBehavior) { + const bool isSRGBTransferFn = + (SkTransferFunctionBehavior::kRespect == unpremulBehavior) && info.gammaCloseToSRGB(); switch (info.colorType()) { case kRGBA_8888_SkColorType: switch (info.alphaType()) { @@ -61,8 +63,8 @@ static transform_scanline_proc choose_proc(const SkImageInfo& info) { case kUnpremul_SkAlphaType: return transform_scanline_memcpy; case kPremul_SkAlphaType: - return isGammaEncoded ? transform_scanline_srgbA : - transform_scanline_rgbA; + return isSRGBTransferFn ? transform_scanline_srgbA : + transform_scanline_rgbA; default: SkASSERT(false); return nullptr; @@ -74,8 +76,8 @@ static transform_scanline_proc choose_proc(const SkImageInfo& info) { case kUnpremul_SkAlphaType: return transform_scanline_BGRA; case kPremul_SkAlphaType: - return isGammaEncoded ? transform_scanline_sbgrA : - transform_scanline_bgrA; + return isSRGBTransferFn ? transform_scanline_sbgrA : + transform_scanline_bgrA; default: SkASSERT(false); return nullptr; @@ -118,14 +120,15 @@ static transform_scanline_proc choose_proc(const SkImageInfo& info) { opaque, the return value will always be 0. */ static inline int pack_palette(SkColorTable* ctable, png_color* SK_RESTRICT palette, - png_byte* SK_RESTRICT alphas, const SkImageInfo& info) { + png_byte* SK_RESTRICT alphas, const SkImageInfo& info, + SkTransferFunctionBehavior unpremulBehavior) { const SkPMColor* colors = ctable->readColors(); const int count = ctable->count(); SkPMColor storage[256]; if (kPremul_SkAlphaType == info.alphaType()) { // Unpremultiply the colors. const SkImageInfo rgbaInfo = info.makeColorType(kRGBA_8888_SkColorType); - transform_scanline_proc proc = choose_proc(rgbaInfo); + transform_scanline_proc proc = choose_proc(rgbaInfo, unpremulBehavior); proc((char*) storage, (const char*) colors, ctable->count(), 4, nullptr); colors = storage; } @@ -174,17 +177,13 @@ static inline int pack_palette(SkColorTable* ctable, png_color* SK_RESTRICT pale return numWithAlpha; } -static bool do_encode(SkWStream*, const SkPixmap&, int, int, png_color_8&); +static bool do_encode(SkWStream*, const SkPixmap&, int, int, png_color_8&, + SkTransferFunctionBehavior unpremulBehavior); -bool SkEncodeImageAsPNG(SkWStream* stream, const SkPixmap& src, const SkEncodeOptions& opts) { - SkASSERT(!src.colorSpace() || src.colorSpace()->gammaCloseToSRGB() || - src.colorSpace()->gammaIsLinear()); - - SkPixmap pixmap = src; - if (SkTransferFunctionBehavior::kIgnore == opts.fUnpremulBehavior) { - pixmap.setColorSpace(nullptr); - } else { - if (!pixmap.colorSpace()) { +bool SkEncodeImageAsPNG(SkWStream* stream, const SkPixmap& pixmap, const SkEncodeOptions& opts) { + if (SkTransferFunctionBehavior::kRespect == opts.fUnpremulBehavior) { + if (!pixmap.colorSpace() || (!pixmap.colorSpace()->gammaCloseToSRGB() && + !pixmap.colorSpace()->gammaIsLinear())) { return false; } } @@ -276,7 +275,7 @@ bool SkEncodeImageAsPNG(SkWStream* stream, const SkPixmap& src, const SkEncodeOp // or 4 bit indices. } - return do_encode(stream, pixmap, pngColorType, bitDepth, sig_bit); + return do_encode(stream, pixmap, pngColorType, bitDepth, sig_bit, opts.fUnpremulBehavior); } static int num_components(int pngColorType) { @@ -294,8 +293,8 @@ static int num_components(int pngColorType) { } } -static bool do_encode(SkWStream* stream, const SkPixmap& pixmap, - int pngColorType, int bitDepth, png_color_8& sig_bit) { +static bool do_encode(SkWStream* stream, const SkPixmap& pixmap, int pngColorType, int bitDepth, + png_color_8& sig_bit, SkTransferFunctionBehavior unpremulBehavior) { png_structp png_ptr; png_infop info_ptr; @@ -340,7 +339,8 @@ static bool do_encode(SkWStream* stream, const SkPixmap& pixmap, if (kIndex_8_SkColorType == pixmap.colorType()) { SkColorTable* colorTable = pixmap.ctable(); SkASSERT(colorTable); - int numTrans = pack_palette(colorTable, paletteColors, trans, pixmap.info()); + int numTrans = pack_palette(colorTable, paletteColors, trans, pixmap.info(), + unpremulBehavior); png_set_PLTE(png_ptr, info_ptr, paletteColors, colorTable->count()); if (numTrans > 0) { png_set_tRNS(png_ptr, info_ptr, trans, numTrans, nullptr); @@ -371,7 +371,7 @@ static bool do_encode(SkWStream* stream, const SkPixmap& pixmap, SkAutoSTMalloc<1024, char> rowStorage(pixmap.width() * pngBytesPerPixel); char* storage = rowStorage.get(); const char* srcImage = (const char*)pixmap.addr(); - transform_scanline_proc proc = choose_proc(pixmap.info()); + transform_scanline_proc proc = choose_proc(pixmap.info(), unpremulBehavior); for (int y = 0; y < pixmap.height(); y++) { png_bytep row_ptr = (png_bytep)storage; proc(storage, srcImage, pixmap.width(), SkColorTypeBytesPerPixel(pixmap.colorType()), |