Fix bug handling CMYK images without color profiles
We need the swizzler to convert CMYK->RGB in some cases where we do have a color xform. BUG=skia: Change-Id: Id467ad03df64368fd5a6c3bd5461566582eb492e Reviewed-on: https://skia-review.googlesource.com/8973 Commit-Queue: Matt Sarett <msarett@google.com> Reviewed-by: Leon Scroggins <scroggo@google.com>
This commit is contained in:
parent
443ec1b794
commit
7f15b682f4
@ -1 +1 @@
|
||||
21
|
||||
22
|
File diff suppressed because it is too large
Load Diff
@ -550,6 +550,22 @@ int SkJpegCodec::readRows(const SkImageInfo& dstInfo, void* dst, size_t rowBytes
|
||||
return count;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is a bit tricky. We only need the swizzler to do format conversion if the jpeg is
|
||||
* encoded as CMYK.
|
||||
* And even then we still may not need it. If the jpeg has a CMYK color space and a color
|
||||
* xform, the color xform will handle the CMYK->RGB conversion.
|
||||
*/
|
||||
static inline bool needs_swizzler_to_convert_from_cmyk(J_COLOR_SPACE jpegColorType,
|
||||
const SkImageInfo& srcInfo, bool hasColorSpaceXform) {
|
||||
if (JCS_CMYK != jpegColorType) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool hasCMYKColorSpace = as_CSB(srcInfo.colorSpace())->onIsCMYK();
|
||||
return !hasCMYKColorSpace || !hasColorSpaceXform;
|
||||
}
|
||||
|
||||
/*
|
||||
* Performs the jpeg decode
|
||||
*/
|
||||
@ -587,9 +603,9 @@ SkCodec::Result SkJpegCodec::onGetPixels(const SkImageInfo& dstInfo,
|
||||
// If it's not, we want to know because it means our strategy is not optimal.
|
||||
SkASSERT(1 == dinfo->rec_outbuf_height);
|
||||
|
||||
J_COLOR_SPACE colorSpace = dinfo->out_color_space;
|
||||
if (JCS_CMYK == colorSpace && nullptr == this->colorXform()) {
|
||||
this->initializeSwizzler(dstInfo, options);
|
||||
if (needs_swizzler_to_convert_from_cmyk(dinfo->out_color_space, this->getInfo(),
|
||||
this->colorXform())) {
|
||||
this->initializeSwizzler(dstInfo, options, true);
|
||||
}
|
||||
|
||||
this->allocateStorage(dstInfo);
|
||||
@ -628,15 +644,10 @@ void SkJpegCodec::allocateStorage(const SkImageInfo& dstInfo) {
|
||||
}
|
||||
}
|
||||
|
||||
void SkJpegCodec::initializeSwizzler(const SkImageInfo& dstInfo, const Options& options) {
|
||||
// libjpeg-turbo will handle format conversion from YUV to RGBA, BGRA, or 565. fColorXform
|
||||
// will handle format conversion from CMYK. We only need the swizzler to perform format
|
||||
// conversion when we have a CMYK image without a fColorXform.
|
||||
bool skipFormatConversion = this->colorXform() ||
|
||||
(JCS_CMYK != fDecoderMgr->dinfo()->out_color_space);
|
||||
|
||||
void SkJpegCodec::initializeSwizzler(const SkImageInfo& dstInfo, const Options& options,
|
||||
bool needsCMYKToRGB) {
|
||||
SkEncodedInfo swizzlerInfo = this->getEncodedInfo();
|
||||
if (!skipFormatConversion) {
|
||||
if (needsCMYKToRGB) {
|
||||
swizzlerInfo = SkEncodedInfo::Make(SkEncodedInfo::kInvertedCMYK_Color,
|
||||
swizzlerInfo.alpha(),
|
||||
swizzlerInfo.bitsPerComponent());
|
||||
@ -653,13 +664,13 @@ void SkJpegCodec::initializeSwizzler(const SkImageInfo& dstInfo, const Options&
|
||||
}
|
||||
|
||||
SkImageInfo swizzlerDstInfo = dstInfo;
|
||||
if (kRGBA_F16_SkColorType == dstInfo.colorType()) {
|
||||
// The color xform will handle conversion to F16. It will be expecting RGBA 8888 input.
|
||||
if (this->colorXform()) {
|
||||
// The color xform will be expecting RGBA 8888 input.
|
||||
swizzlerDstInfo = swizzlerDstInfo.makeColorType(kRGBA_8888_SkColorType);
|
||||
}
|
||||
|
||||
fSwizzler.reset(SkSwizzler::CreateSwizzler(swizzlerInfo, nullptr, swizzlerDstInfo,
|
||||
swizzlerOptions, nullptr, skipFormatConversion));
|
||||
swizzlerOptions, nullptr, !needsCMYKToRGB));
|
||||
SkASSERT(fSwizzler);
|
||||
}
|
||||
|
||||
@ -669,7 +680,9 @@ SkSampler* SkJpegCodec::getSampler(bool createIfNecessary) {
|
||||
return fSwizzler.get();
|
||||
}
|
||||
|
||||
this->initializeSwizzler(this->dstInfo(), this->options());
|
||||
bool needsCMYKToRGB = needs_swizzler_to_convert_from_cmyk(
|
||||
fDecoderMgr->dinfo()->out_color_space, this->getInfo(), this->colorXform());
|
||||
this->initializeSwizzler(this->dstInfo(), this->options(), needsCMYKToRGB);
|
||||
this->allocateStorage(this->dstInfo());
|
||||
return fSwizzler.get();
|
||||
}
|
||||
@ -696,6 +709,8 @@ SkCodec::Result SkJpegCodec::onStartScanlineDecode(const SkImageInfo& dstInfo,
|
||||
return kInvalidInput;
|
||||
}
|
||||
|
||||
bool needsCMYKToRGB = needs_swizzler_to_convert_from_cmyk(
|
||||
fDecoderMgr->dinfo()->out_color_space, this->getInfo(), this->colorXform());
|
||||
if (options.fSubset) {
|
||||
uint32_t startX = options.fSubset->x();
|
||||
uint32_t width = options.fSubset->width();
|
||||
@ -729,13 +744,13 @@ SkCodec::Result SkJpegCodec::onStartScanlineDecode(const SkImageInfo& dstInfo,
|
||||
// subset that we request.
|
||||
if (startX != (uint32_t) options.fSubset->x() ||
|
||||
width != (uint32_t) options.fSubset->width()) {
|
||||
this->initializeSwizzler(dstInfo, options);
|
||||
this->initializeSwizzler(dstInfo, options, needsCMYKToRGB);
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure we have a swizzler if we are converting from CMYK.
|
||||
if (!fSwizzler && JCS_CMYK == fDecoderMgr->dinfo()->out_color_space) {
|
||||
this->initializeSwizzler(dstInfo, options);
|
||||
if (!fSwizzler && needsCMYKToRGB) {
|
||||
this->initializeSwizzler(dstInfo, options, true);
|
||||
}
|
||||
|
||||
this->allocateStorage(dstInfo);
|
||||
|
@ -111,7 +111,8 @@ private:
|
||||
*/
|
||||
bool setOutputColorSpace(const SkImageInfo& dst);
|
||||
|
||||
void initializeSwizzler(const SkImageInfo& dstInfo, const Options& options);
|
||||
void initializeSwizzler(const SkImageInfo& dstInfo, const Options& options,
|
||||
bool needsCMYKToRGB);
|
||||
void allocateStorage(const SkImageInfo& dstInfo);
|
||||
int readRows(const SkImageInfo& dstInfo, void* dst, size_t rowBytes, int count, const Options&);
|
||||
|
||||
|
@ -52,6 +52,8 @@ public:
|
||||
bool onGammaIsLinear() const override { return false; }
|
||||
bool onIsNumericalTransferFn(SkColorSpaceTransferFn* coeffs) const override { return false; }
|
||||
|
||||
bool onIsCMYK() const override { return kCMYK_ICCTypeFlag == fICCType; }
|
||||
|
||||
sk_sp<SkColorSpace> makeLinearGamma() override {
|
||||
// TODO: Analyze the extrema of our projection into XYZ and use suitable primaries?
|
||||
// For now, just fall back to a default, because we don't have a good answer.
|
||||
|
@ -164,6 +164,8 @@ public:
|
||||
|
||||
virtual bool onIsNumericalTransferFn(SkColorSpaceTransferFn* coeffs) const = 0;
|
||||
|
||||
virtual bool onIsCMYK() const { return false; }
|
||||
|
||||
/**
|
||||
* Returns a color space with the same gamut as this one, but with a linear gamma.
|
||||
* For color spaces whose gamut can not be described in terms of XYZ D50, returns
|
||||
|
Loading…
Reference in New Issue
Block a user