diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/codec/SkCodec.cpp | 13 | ||||
-rw-r--r-- | src/codec/SkJpegCodec.cpp | 40 | ||||
-rw-r--r-- | src/codec/SkJpegCodec.h | 2 | ||||
-rw-r--r-- | src/codec/SkPngCodec.cpp | 37 | ||||
-rw-r--r-- | src/codec/SkPngCodec.h | 1 | ||||
-rw-r--r-- | src/codec/SkWebpCodec.cpp | 16 |
6 files changed, 56 insertions, 53 deletions
diff --git a/src/codec/SkCodec.cpp b/src/codec/SkCodec.cpp index 84afc2bdee..b6ce65e7b2 100644 --- a/src/codec/SkCodec.cpp +++ b/src/codec/SkCodec.cpp @@ -9,6 +9,7 @@ #include "SkCodec.h" #include "SkCodecPriv.h" #include "SkColorSpace.h" +#include "SkColorSpaceXform.h" #include "SkData.h" #include "SkGifCodec.h" #include "SkHalf.h" @@ -483,3 +484,15 @@ void SkCodec::fillIncompleteImage(const SkImageInfo& info, void* dst, size_t row } } } + +bool SkCodec::initializeColorXform(const SkImageInfo& dstInfo) { + fColorXform = nullptr; + if (needs_color_xform(dstInfo, fSrcInfo)) { + fColorXform = SkColorSpaceXform::New(fSrcInfo.colorSpace(), dstInfo.colorSpace()); + if (!fColorXform) { + return false; + } + } + + return true; +} diff --git a/src/codec/SkJpegCodec.cpp b/src/codec/SkJpegCodec.cpp index 6863855d3b..b9ae454a62 100644 --- a/src/codec/SkJpegCodec.cpp +++ b/src/codec/SkJpegCodec.cpp @@ -347,7 +347,6 @@ bool SkJpegCodec::onRewind() { fSwizzleSrcRow = nullptr; fColorXformSrcRow = nullptr; fStorage.reset(); - fColorXform.reset(nullptr); return true; } @@ -384,7 +383,7 @@ bool SkJpegCodec::setOutputColorSpace(const SkImageInfo& dstInfo) { case kBGRA_8888_SkColorType: if (isCMYK) { fDecoderMgr->dinfo()->out_color_space = JCS_CMYK; - } else if (fColorXform) { + } else if (this->colorXform()) { // Our color transformation code requires RGBA order inputs, but it'll swizzle // to BGRA for us. fDecoderMgr->dinfo()->out_color_space = JCS_EXT_RGBA; @@ -393,7 +392,7 @@ bool SkJpegCodec::setOutputColorSpace(const SkImageInfo& dstInfo) { } return true; case kRGB_565_SkColorType: - if (fColorXform) { + if (this->colorXform()) { return false; } @@ -405,16 +404,15 @@ bool SkJpegCodec::setOutputColorSpace(const SkImageInfo& dstInfo) { } return true; case kGray_8_SkColorType: - if (fColorXform || JCS_GRAYSCALE != encodedColorType) { + if (this->colorXform() || JCS_GRAYSCALE != encodedColorType) { return false; } fDecoderMgr->dinfo()->out_color_space = JCS_GRAYSCALE; return true; case kRGBA_F16_SkColorType: - if (!fColorXform) { - return false; - } + SkASSERT(this->colorXform()); + if (!dstInfo.colorSpace()->gammaIsLinear()) { return false; } @@ -483,7 +481,7 @@ int SkJpegCodec::readRows(const SkImageInfo& dstInfo, void* dst, size_t rowBytes // subsetting. // When fColorXformSrcRow is non-null, it means that we need to color xform and that // we cannot color xform "in place" (many times we can, but not when the dst is F16). - // In this case, we will color xform from fColorXformSrc into the dst. + // In this case, we will color xform from fColorXformSrcRow into the dst. JSAMPLE* decodeDst = (JSAMPLE*) dst; uint32_t* swizzleDst = (uint32_t*) dst; size_t decodeDstRowBytes = rowBytes; @@ -518,10 +516,10 @@ int SkJpegCodec::readRows(const SkImageInfo& dstInfo, void* dst, size_t rowBytes fSwizzler->swizzle(swizzleDst, decodeDst); } - if (fColorXform) { - SkAssertResult(fColorXform->apply(select_xform_format(dstInfo.colorType()), dst, - SkColorSpaceXform::kRGBA_8888_ColorFormat, swizzleDst, - dstWidth, kOpaque_SkAlphaType)); + if (this->colorXform()) { + SkAssertResult(this->colorXform()->apply(select_xform_format(dstInfo.colorType()), dst, + SkColorSpaceXform::kRGBA_8888_ColorFormat, swizzleDst, dstWidth, + kOpaque_SkAlphaType)); dst = SkTAddOffset<void>(dst, rowBytes); } @@ -552,7 +550,9 @@ SkCodec::Result SkJpegCodec::onGetPixels(const SkImageInfo& dstInfo, return fDecoderMgr->returnFailure("setjmp", kInvalidInput); } - this->initializeColorXform(dstInfo); + if (!this->initializeColorXform(dstInfo)) { + return kInvalidConversion; + } // Check if we can decode to the requested destination and set the output color space if (!this->setOutputColorSpace(dstInfo)) { @@ -590,12 +590,12 @@ void SkJpegCodec::allocateStorage(const SkImageInfo& dstInfo) { if (fSwizzler) { swizzleBytes = get_row_bytes(fDecoderMgr->dinfo()); dstWidth = fSwizzler->swizzleWidth(); - SkASSERT(!fColorXform || SkIsAlign4(swizzleBytes)); + SkASSERT(!this->colorXform() || SkIsAlign4(swizzleBytes)); } size_t xformBytes = 0; if (kRGBA_F16_SkColorType == dstInfo.colorType()) { - SkASSERT(fColorXform); + SkASSERT(this->colorXform()); xformBytes = dstWidth * sizeof(uint32_t); } @@ -634,12 +634,6 @@ void SkJpegCodec::initializeSwizzler(const SkImageInfo& dstInfo, const Options& SkASSERT(fSwizzler); } -void SkJpegCodec::initializeColorXform(const SkImageInfo& dstInfo) { - if (needs_color_xform(dstInfo, this->getInfo())) { - fColorXform = SkColorSpaceXform::New(this->getInfo().colorSpace(), dstInfo.colorSpace()); - } -} - SkSampler* SkJpegCodec::getSampler(bool createIfNecessary) { if (!createIfNecessary || fSwizzler) { SkASSERT(!fSwizzler || (fSwizzleSrcRow && fStorage.get() == fSwizzleSrcRow)); @@ -659,7 +653,9 @@ SkCodec::Result SkJpegCodec::onStartScanlineDecode(const SkImageInfo& dstInfo, return kInvalidInput; } - this->initializeColorXform(dstInfo); + if (!this->initializeColorXform(dstInfo)) { + return kInvalidConversion; + } // Check if we can decode to the requested destination and set the output color space if (!this->setOutputColorSpace(dstInfo)) { diff --git a/src/codec/SkJpegCodec.h b/src/codec/SkJpegCodec.h index 30425eea3f..402f466b79 100644 --- a/src/codec/SkJpegCodec.h +++ b/src/codec/SkJpegCodec.h @@ -107,7 +107,6 @@ private: bool setOutputColorSpace(const SkImageInfo& dst); void initializeSwizzler(const SkImageInfo& dstInfo, const Options& options); - void initializeColorXform(const SkImageInfo& dstInfo); void allocateStorage(const SkImageInfo& dstInfo); int readRows(const SkImageInfo& dstInfo, void* dst, size_t rowBytes, int count); @@ -137,7 +136,6 @@ private: SkIRect fSwizzlerSubset; SkAutoTDelete<SkSwizzler> fSwizzler; - std::unique_ptr<SkColorSpaceXform> fColorXform; sk_sp<SkData> fICCData; diff --git a/src/codec/SkPngCodec.cpp b/src/codec/SkPngCodec.cpp index 50c107172a..23c74e2122 100644 --- a/src/codec/SkPngCodec.cpp +++ b/src/codec/SkPngCodec.cpp @@ -224,14 +224,14 @@ bool SkPngCodec::createColorTable(const SkImageInfo& dstInfo, int* ctableCount) // Contents depend on tableColorType and our choice of if/when to premultiply: // { kPremul, kUnpremul, kOpaque } x { RGBA, BGRA } SkPMColor colorTable[256]; - SkColorType tableColorType = fColorXform ? kRGBA_8888_SkColorType : dstInfo.colorType(); + SkColorType tableColorType = this->colorXform() ? kRGBA_8888_SkColorType : dstInfo.colorType(); png_bytep alphas; int numColorsWithAlpha = 0; if (png_get_tRNS(fPng_ptr, fInfo_ptr, &alphas, &numColorsWithAlpha, nullptr)) { // If we are performing a color xform, it will handle the premultiply. Otherwise, // we'll do it here. - bool premultiply = !fColorXform && needs_premul(dstInfo, this->getInfo()); + bool premultiply = !this->colorXform() && needs_premul(dstInfo, this->getInfo()); // Choose which function to use to create the color table. If the final destination's // colortype is unpremultiplied, the color table will store unpremultiplied colors. @@ -266,15 +266,14 @@ bool SkPngCodec::createColorTable(const SkImageInfo& dstInfo, int* ctableCount) // If we are not decoding to F16, we can color xform now and store the results // in the color table. - if (fColorXform && kRGBA_F16_SkColorType != dstInfo.colorType()) { + if (this->colorXform() && kRGBA_F16_SkColorType != dstInfo.colorType()) { SkColorSpaceXform::ColorFormat xformColorFormat = is_rgba(dstInfo.colorType()) ? SkColorSpaceXform::kRGBA_8888_ColorFormat : SkColorSpaceXform::kBGRA_8888_ColorFormat; SkAlphaType xformAlphaType = select_xform_alpha(dstInfo.alphaType(), this->getInfo().alphaType()); - SkAssertResult(fColorXform->apply(xformColorFormat, colorTable, - SkColorSpaceXform::kRGBA_8888_ColorFormat, colorTable, - numColors, xformAlphaType)); + SkAssertResult(this->colorXform()->apply(xformColorFormat, colorTable, + SkColorSpaceXform::kRGBA_8888_ColorFormat, colorTable, numColors, xformAlphaType)); } // Pad the color table with the last color in the table (or black) in the case that @@ -442,13 +441,13 @@ void SkPngCodec::applyXformRow(void* dst, const void* src) { fSwizzler->swizzle(dst, (const uint8_t*) src); break; case kColorOnly_XformMode: - SkAssertResult(fColorXform->apply(fXformColorFormat, dst, srcColorFormat, src, - fXformWidth, fXformAlphaType)); + SkAssertResult(this->colorXform()->apply(fXformColorFormat, dst, srcColorFormat, src, + fXformWidth, fXformAlphaType)); break; case kSwizzleColor_XformMode: fSwizzler->swizzle(fColorXformSrcRow, (const uint8_t*) src); - SkAssertResult(fColorXform->apply(fXformColorFormat, dst, srcColorFormat, fColorXformSrcRow, - fXformWidth, fXformAlphaType)); + SkAssertResult(this->colorXform()->apply(fXformColorFormat, dst, srcColorFormat, + fColorXformSrcRow, fXformWidth, fXformAlphaType)); break; } } @@ -1065,20 +1064,18 @@ bool SkPngCodec::initializeXforms(const SkImageInfo& dstInfo, const Options& opt } png_read_update_info(fPng_ptr, fInfo_ptr); - // Reset fSwizzler and fColorXform. We can't do this in onRewind() because the + // Reset fSwizzler and this->colorXform(). We can't do this in onRewind() because the // interlaced scanline decoder may need to rewind. fSwizzler.reset(nullptr); - fColorXform = nullptr; - if (needs_color_xform(dstInfo, this->getInfo())) { - fColorXform = SkColorSpaceXform::New(this->getInfo().colorSpace(), dstInfo.colorSpace()); - SkASSERT(fColorXform); + if (!this->initializeColorXform(dstInfo)) { + return false; } // If the image is RGBA and we have a color xform, we can skip the swizzler. // FIXME (msarett): - // Support more input types to fColorXform (ex: RGB, Gray) and skip the swizzler more often. - if (fColorXform && SkEncodedInfo::kRGBA_Color == this->getEncodedInfo().color() && + // Support more input types to this->colorXform() (ex: RGB, Gray) and skip the swizzler more often. + if (this->colorXform() && SkEncodedInfo::kRGBA_Color == this->getEncodedInfo().color() && !options.fSubset) { fXformMode = kColorOnly_XformMode; @@ -1126,7 +1123,9 @@ void SkPngCodec::initializeSwizzler(const SkImageInfo& dstInfo, const Options& o SkImageInfo swizzlerInfo = dstInfo; Options swizzlerOptions = options; fXformMode = kSwizzleOnly_XformMode; - if (fColorXform && apply_xform_on_decode(dstInfo.colorType(), this->getEncodedInfo().color())) { + if (this->colorXform() && + apply_xform_on_decode(dstInfo.colorType(), this->getEncodedInfo().color())) + { swizzlerInfo = swizzlerInfo.makeColorType(kRGBA_8888_SkColorType); if (kPremul_SkAlphaType == dstInfo.alphaType()) { swizzlerInfo = swizzlerInfo.makeAlphaType(kUnpremul_SkAlphaType); @@ -1247,7 +1246,7 @@ uint64_t SkPngCodec::onGetFillValue(const SkImageInfo& dstInfo) const { SkAlphaType alphaType = select_xform_alpha(dstInfo.alphaType(), this->getInfo().alphaType()); return get_color_table_fill_value(dstInfo.colorType(), alphaType, colorPtr, 0, - fColorXform.get()); + this->colorXform()); } return INHERITED::onGetFillValue(dstInfo); } diff --git a/src/codec/SkPngCodec.h b/src/codec/SkPngCodec.h index 1fc451757e..c10f17464c 100644 --- a/src/codec/SkPngCodec.h +++ b/src/codec/SkPngCodec.h @@ -98,7 +98,6 @@ protected: // These are stored here so they can be used both by normal decoding and scanline decoding. SkAutoTUnref<SkColorTable> fColorTable; // May be unpremul. SkAutoTDelete<SkSwizzler> fSwizzler; - std::unique_ptr<SkColorSpaceXform> fColorXform; SkAutoTMalloc<uint8_t> fStorage; uint32_t* fColorXformSrcRow; const int fBitDepth; diff --git a/src/codec/SkWebpCodec.cpp b/src/codec/SkWebpCodec.cpp index 443a4a0732..746e9b79ad 100644 --- a/src/codec/SkWebpCodec.cpp +++ b/src/codec/SkWebpCodec.cpp @@ -197,10 +197,8 @@ SkCodec::Result SkWebpCodec::onGetPixels(const SkImageInfo& dstInfo, void* dst, return kInvalidConversion; } - std::unique_ptr<SkColorSpaceXform> colorXform = nullptr; - if (needs_color_xform(dstInfo, this->getInfo())) { - colorXform = SkColorSpaceXform::New(this->getInfo().colorSpace(), dstInfo.colorSpace()); - SkASSERT(colorXform); + if (!this->initializeColorXform(dstInfo)) { + return kInvalidConversion; } WebPDecoderConfig config; @@ -262,7 +260,7 @@ SkCodec::Result SkWebpCodec::onGetPixels(const SkImageInfo& dstInfo, void* dst, // color transform swizzle if necessary. // Lossy webp is encoded as YUV (so RGBA and BGRA are the same cost). Lossless webp is // encoded as BGRA. This means decoding to BGRA is either faster or the same cost as RGBA. - config.output.colorspace = colorXform ? MODE_BGRA : + config.output.colorspace = this->colorXform() ? MODE_BGRA : webp_decode_mode(dstInfo.colorType(), dstInfo.alphaType() == kPremul_SkAlphaType); config.output.is_external_memory = 1; @@ -307,7 +305,7 @@ SkCodec::Result SkWebpCodec::onGetPixels(const SkImageInfo& dstInfo, void* dst, return kInvalidInput; } - if (colorXform) { + if (this->colorXform()) { SkColorSpaceXform::ColorFormat dstColorFormat = select_xform_format(dstInfo.colorType()); SkAlphaType xformAlphaType = select_xform_alpha(dstInfo.alphaType(), this->getInfo().alphaType()); @@ -315,9 +313,9 @@ SkCodec::Result SkWebpCodec::onGetPixels(const SkImageInfo& dstInfo, void* dst, uint32_t* src = (uint32_t*) config.output.u.RGBA.rgba; size_t srcRowBytes = config.output.u.RGBA.stride; for (int y = 0; y < rowsDecoded; y++) { - SkAssertResult(colorXform->apply(dstColorFormat, dst, - SkColorSpaceXform::kBGRA_8888_ColorFormat, src, - dstInfo.width(), xformAlphaType)); + SkAssertResult(this->colorXform()->apply(dstColorFormat, dst, + SkColorSpaceXform::kBGRA_8888_ColorFormat, src, dstInfo.width(), + xformAlphaType)); dst = SkTAddOffset<void>(dst, rowBytes); src = SkTAddOffset<uint32_t>(src, srcRowBytes); } |