Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(73)

Unified Diff: src/codec/SkJpegCodec.cpp

Issue 1411083009: Use SkSwizzler to convert from CMYK (Closed) Base URL: https://skia.googlesource.com/skia.git@NewFromData
Patch Set: Add missing break statement Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | src/codec/SkSwizzler.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/codec/SkJpegCodec.cpp
diff --git a/src/codec/SkJpegCodec.cpp b/src/codec/SkJpegCodec.cpp
index 9975748cf4b4ce4010ea9dc79eca8cac6614fc93..6850a7782512aa0cc731982c7fb3cff61c93b0ec 100644
--- a/src/codec/SkJpegCodec.cpp
+++ b/src/codec/SkJpegCodec.cpp
@@ -23,69 +23,6 @@ extern "C" {
#include "jpeglib.h"
}
-/*
- * Convert a row of CMYK samples to RGBA in place.
- * Note that this method moves the row pointer.
- * @param width the number of pixels in the row that is being converted
- * CMYK is stored as four bytes per pixel
- */
-static void convert_CMYK_to_RGBA(uint8_t* row, uint32_t width) {
- // We will implement a crude conversion from CMYK -> RGB using formulas
- // from easyrgb.com.
- //
- // CMYK -> CMY
- // C = C * (1 - K) + K
- // M = M * (1 - K) + K
- // Y = Y * (1 - K) + K
- //
- // libjpeg actually gives us inverted CMYK, so we must subtract the
- // original terms from 1.
- // CMYK -> CMY
- // C = (1 - C) * (1 - (1 - K)) + (1 - K)
- // M = (1 - M) * (1 - (1 - K)) + (1 - K)
- // Y = (1 - Y) * (1 - (1 - K)) + (1 - K)
- //
- // Simplifying the above expression.
- // CMYK -> CMY
- // C = 1 - CK
- // M = 1 - MK
- // Y = 1 - YK
- //
- // CMY -> RGB
- // R = (1 - C) * 255
- // G = (1 - M) * 255
- // B = (1 - Y) * 255
- //
- // Therefore the full conversion is below. This can be verified at
- // www.rapidtables.com (assuming inverted CMYK).
- // CMYK -> RGB
- // R = C * K * 255
- // G = M * K * 255
- // B = Y * K * 255
- //
- // As a final note, we have treated the CMYK values as if they were on
- // a scale from 0-1, when in fact they are 8-bit ints scaling from 0-255.
- // We must divide each CMYK component by 255 to obtain the true conversion
- // we should perform.
- // CMYK -> RGB
- // R = C * K / 255
- // G = M * K / 255
- // B = Y * K / 255
- for (uint32_t x = 0; x < width; x++, row += 4) {
-#if defined(SK_PMCOLOR_IS_RGBA)
- row[0] = SkMulDiv255Round(row[0], row[3]);
- row[1] = SkMulDiv255Round(row[1], row[3]);
- row[2] = SkMulDiv255Round(row[2], row[3]);
-#else
- uint8_t tmp = row[0];
- row[0] = SkMulDiv255Round(row[2], row[3]);
- row[1] = SkMulDiv255Round(row[1], row[3]);
- row[2] = SkMulDiv255Round(tmp, row[3]);
-#endif
- row[3] = 0xFF;
- }
-}
-
bool SkJpegCodec::IsJpeg(SkStream* stream) {
static const uint8_t jpegSig[] = { 0xFF, 0xD8, 0xFF };
char buffer[sizeof(jpegSig)];
@@ -263,10 +200,7 @@ bool SkJpegCodec::setOutputColorSpace(const SkImageInfo& dst) {
return true;
case kRGB_565_SkColorType:
if (isCMYK) {
- // FIXME (msarett): We need to support 565 here. It's not hard to do, considering
- // we already convert CMYK to RGBA, I just need to do it. I think it might be
- // best to do this in SkSwizzler and also move convert_CMYK_to_RGBA into SkSwizzler.
- return false;
+ fDecoderMgr->dinfo()->out_color_space = JCS_CMYK;
} else {
#if defined(GOOGLE3)
return false;
@@ -365,9 +299,22 @@ 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);
+ if (JCS_CMYK == dinfo->out_color_space) {
+ this->initializeSwizzler(dstInfo, options);
+ }
+
// Perform the decode a single row at a time
uint32_t dstHeight = dstInfo.height();
- JSAMPLE* dstRow = (JSAMPLE*) dst;
+
+ JSAMPLE* dstRow;
+ if (fSwizzler) {
+ // write data to storage row, then sample using swizzler
+ dstRow = fSrcRow;
+ } else {
+ // write data directly to dst
+ dstRow = (JSAMPLE*) dst;
+ }
+
for (uint32_t y = 0; y < dstHeight; y++) {
// Read rows of the image
uint32_t lines = jpeg_read_scanlines(dinfo, &dstRow, 1);
@@ -379,13 +326,13 @@ SkCodec::Result SkJpegCodec::onGetPixels(const SkImageInfo& dstInfo,
return fDecoderMgr->returnFailure("Incomplete image data", kIncompleteInput);
}
- // Convert to RGBA if necessary
- if (JCS_CMYK == dinfo->out_color_space) {
- convert_CMYK_to_RGBA(dstRow, dstInfo.width());
+ if (fSwizzler) {
+ // use swizzler to sample row
+ fSwizzler->swizzle(dst, dstRow);
+ dst = SkTAddOffset<JSAMPLE>(dst, dstRowBytes);
+ } else {
+ dstRow = SkTAddOffset<JSAMPLE>(dstRow, dstRowBytes);
}
-
- // Move to the next row
- dstRow = SkTAddOffset<JSAMPLE>(dstRow, dstRowBytes);
}
return kSuccess;
@@ -393,26 +340,30 @@ SkCodec::Result SkJpegCodec::onGetPixels(const SkImageInfo& dstInfo,
void SkJpegCodec::initializeSwizzler(const SkImageInfo& dstInfo, const Options& options) {
SkSwizzler::SrcConfig srcConfig = SkSwizzler::kUnknown;
- switch (dstInfo.colorType()) {
- case kGray_8_SkColorType:
- srcConfig = SkSwizzler::kGray;
- break;
- case kRGBA_8888_SkColorType:
- srcConfig = SkSwizzler::kRGBX;
- break;
- case kBGRA_8888_SkColorType:
- srcConfig = SkSwizzler::kBGRX;
- break;
- case kRGB_565_SkColorType:
- srcConfig = SkSwizzler::kRGB_565;
- break;
- default:
- // This function should only be called if the colorType is supported by jpeg
+ if (JCS_CMYK == fDecoderMgr->dinfo()->out_color_space) {
+ srcConfig = SkSwizzler::kCMYK;
+ } else {
+ switch (dstInfo.colorType()) {
+ case kGray_8_SkColorType:
+ srcConfig = SkSwizzler::kGray;
+ break;
+ case kRGBA_8888_SkColorType:
+ srcConfig = SkSwizzler::kRGBX;
+ break;
+ case kBGRA_8888_SkColorType:
+ srcConfig = SkSwizzler::kBGRX;
+ break;
+ case kRGB_565_SkColorType:
+ srcConfig = SkSwizzler::kRGB_565;
+ break;
+ default:
+ // This function should only be called if the colorType is supported by jpeg
#if defined(GOOGLE3)
- SK_CRASH();
+ SK_CRASH();
#else
- SkASSERT(false);
+ SkASSERT(false);
#endif
+ }
}
fSwizzler.reset(SkSwizzler::CreateSwizzler(srcConfig, nullptr, dstInfo, options));
@@ -454,8 +405,9 @@ SkCodec::Result SkJpegCodec::onStartScanlineDecode(const SkImageInfo& dstInfo,
return kInvalidInput;
}
- // We will need a swizzler if we are performing a subset decode
- if (options.fSubset) {
+ // We will need a swizzler if we are performing a subset decode or
+ // converting from CMYK.
+ if (options.fSubset || JCS_CMYK == fDecoderMgr->dinfo()->out_color_space) {
this->initializeSwizzler(dstInfo, options);
}
@@ -485,12 +437,7 @@ int SkJpegCodec::onGetScanlines(void* dst, int count, size_t rowBytes) {
return y;
}
- // Convert to RGBA if necessary
- if (JCS_CMYK == fDecoderMgr->dinfo()->out_color_space) {
- convert_CMYK_to_RGBA(dstRow, fDecoderMgr->dinfo()->output_width);
- }
-
- if(fSwizzler) {
+ if (fSwizzler) {
// use swizzler to sample row
fSwizzler->swizzle(dst, dstRow);
dst = SkTAddOffset<JSAMPLE>(dst, rowBytes);
« no previous file with comments | « no previous file | src/codec/SkSwizzler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698