aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/images/SkPNGImageEncoder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/images/SkPNGImageEncoder.cpp')
-rw-r--r--src/images/SkPNGImageEncoder.cpp46
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()),