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

Unified Diff: third_party/WebKit/Source/platform/image-decoders/jpeg/JPEGImageDecoder.cpp

Issue 1403393004: JPEGImageDecoder RGB565 and downsample support and related Skia imagegenerator changes Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: 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
Index: third_party/WebKit/Source/platform/image-decoders/jpeg/JPEGImageDecoder.cpp
diff --git a/third_party/WebKit/Source/platform/image-decoders/jpeg/JPEGImageDecoder.cpp b/third_party/WebKit/Source/platform/image-decoders/jpeg/JPEGImageDecoder.cpp
index a77a3f4bff35338403be10a21d71786f4ac15189..083a5499e6d90909e0eb54ee0520639c856c81c6 100644
--- a/third_party/WebKit/Source/platform/image-decoders/jpeg/JPEGImageDecoder.cpp
+++ b/third_party/WebKit/Source/platform/image-decoders/jpeg/JPEGImageDecoder.cpp
@@ -65,7 +65,7 @@ inline J_COLOR_SPACE rgbOutputColorSpace() { return JCS_EXT_RGBA; }
#else // Output little-endian BGRA pixels.
inline J_COLOR_SPACE rgbOutputColorSpace() { return JCS_EXT_BGRA; }
#endif
-inline bool turboSwizzled(J_COLOR_SPACE colorSpace) { return colorSpace == JCS_EXT_RGBA || colorSpace == JCS_EXT_BGRA; }
+inline bool turboSwizzled(J_COLOR_SPACE colorSpace) { return colorSpace == JCS_EXT_RGBA || colorSpace == JCS_EXT_BGRA || colorSpace == JCS_RGB565; }
inline bool colorSpaceHasAlpha(J_COLOR_SPACE colorSpace) { return turboSwizzled(colorSpace); }
#else
inline J_COLOR_SPACE rgbOutputColorSpace() { return JCS_RGB; }
@@ -472,6 +472,23 @@ public:
default:
return m_decoder->setFailed();
}
+ if (m_decoder->decodeToRGB565Enabled()) {
+ if (m_info.out_color_space == rgbOutputColorSpace()) {
+ // the rest would need to be converted manually on write
+#if defined (JCS_ALPHA_EXTENSIONS)
+ m_info.out_color_space = JCS_RGB565;
+#else
+ m_info.out_color_space = JCS_RGB;
scroggo_chromium 2015/10/19 20:41:36 Isn't that the same as rgbOutputColorSpace when JC
aleksandar.stojiljkovic 2015/10/20 09:51:12 Correct, not needed to set to same.
+#endif
+#if USE(QCMSLIB)
+ // if there is colorprofile, use JCS_RGB as QCMS is not supporting RGB565
+ // conversion, RGB->RGB565 happens in outputRows<>()
+ if (!m_decoder->ignoresGammaAndColorProfile())
+ m_info.out_color_space = JCS_RGB;
+#endif
+ }
+ }
+ // fell through
scroggo_chromium 2015/10/19 20:41:36 nit: Other places in this file say "FALL THROUGH".
aleksandar.stojiljkovic 2015/10/20 09:51:12 Done.
m_state = JPEG_START_DECOMPRESS;
@@ -588,6 +605,7 @@ public:
case JPEG_DECOMPRESS_PROGRESSIVE:
if (m_state == JPEG_DECOMPRESS_PROGRESSIVE) {
+
scroggo_chromium 2015/10/19 20:41:36 Why the extra line here?
int status = 0;
do {
decoder_error_mgr* err = reinterpret_cast_ptr<decoder_error_mgr*>(m_info.err);
@@ -780,6 +798,7 @@ void term_source(j_decompress_ptr jd)
JPEGImageDecoder::JPEGImageDecoder(AlphaOption alphaOption, GammaAndColorProfileOption colorOptions, size_t maxDecodedBytes)
: ImageDecoder(alphaOption, colorOptions, maxDecodedBytes)
, m_hasColorProfile(false)
+ , m_decodeToRGB565(false)
{
}
@@ -841,6 +860,30 @@ bool JPEGImageDecoder::canDecodeToYUV()
return isSizeAvailable() && m_reader->info()->out_color_space == JCS_YCbCr;
}
+bool JPEGImageDecoder::canDecodeToRGB565()
+{
+ // Calling isSizeAvailable() ensures the reader is created and the output
scroggo_chromium 2015/10/19 20:41:36 I do not follow how this comment applies.
aleksandar.stojiljkovic 2015/10/20 09:51:12 Didn't do cleanup after copy paste. Also decoding
+ // color space is set.
+#if defined(JCS_ALPHA_EXTENSIONS)
+ return true;
+#else
+ return false;
+#endif
+}
+
+bool JPEGImageDecoder::setDecodeRGB565Enabled(const bool enable)
+{
+#if defined(JCS_ALPHA_EXTENSIONS)
+ m_decodeToRGB565 = enable;
scroggo_chromium 2015/10/19 20:41:36 Should m_decodeToRGB565 only be defined if JCS_ALP
aleksandar.stojiljkovic 2015/10/20 09:51:12 Done.
+ return true;
+#else
+ if (!enable)
scroggo_chromium 2015/10/19 20:41:36 Can this just be: return !enable and then drop
aleksandar.stojiljkovic 2015/10/20 09:51:12 Done.
+ return true;
+#endif
+ return false;
+}
+
+
bool JPEGImageDecoder::decodeToYUV()
{
if (!hasImagePlanes())
@@ -856,18 +899,18 @@ void JPEGImageDecoder::setImagePlanes(PassOwnPtr<ImagePlanes> imagePlanes)
m_imagePlanes = imagePlanes;
}
-template <J_COLOR_SPACE colorSpace> void setPixel(ImageFrame& buffer, ImageFrame::PixelData* pixel, JSAMPARRAY samples, int column)
+template <J_COLOR_SPACE colorSpace, class T> void setPixel(ImageFrame& buffer, T* pixel, JSAMPARRAY samples, int column)
{
ASSERT_NOT_REACHED();
}
-template <> void setPixel<JCS_RGB>(ImageFrame& buffer, ImageFrame::PixelData* pixel, JSAMPARRAY samples, int column)
+template <> void setPixel<JCS_RGB, ImageFrame::PixelData>(ImageFrame& buffer, ImageFrame::PixelData* pixel, JSAMPARRAY samples, int column)
{
JSAMPLE* jsample = *samples + column * 3;
buffer.setRGBARaw(pixel, jsample[0], jsample[1], jsample[2], 255);
}
-template <> void setPixel<JCS_CMYK>(ImageFrame& buffer, ImageFrame::PixelData* pixel, JSAMPARRAY samples, int column)
+template <> void setPixel<JCS_CMYK, ImageFrame::PixelData>(ImageFrame& buffer, ImageFrame::PixelData* pixel, JSAMPARRAY samples, int column)
{
JSAMPLE* jsample = *samples + column * 4;
@@ -884,7 +927,30 @@ template <> void setPixel<JCS_CMYK>(ImageFrame& buffer, ImageFrame::PixelData* p
buffer.setRGBARaw(pixel, jsample[0] * k / 255, jsample[1] * k / 255, jsample[2] * k / 255, 255);
}
-template <J_COLOR_SPACE colorSpace> bool outputRows(JPEGImageReader* reader, ImageFrame& buffer)
+template <> void setPixel<JCS_RGB, ImageFrame::PixelData16>(ImageFrame& buffer, ImageFrame::PixelData16* pixel, JSAMPARRAY samples, int column)
+{
+ JSAMPLE* jsample = *samples + column * 3;
+ buffer.setRGB565(pixel, jsample[0], jsample[1], jsample[2]);
+}
+
+template <> void setPixel<JCS_CMYK, ImageFrame::PixelData16>(ImageFrame& buffer, ImageFrame::PixelData16* pixel, JSAMPARRAY samples, int column)
+{
+ JSAMPLE* jsample = *samples + column * 4;
+
+ // Source is 'Inverted CMYK', output is RGB.
+ // See: http://www.easyrgb.com/math.php?MATH=M12#text12
+ // Or: http://www.ilkeratalay.com/colorspacesfaq.php#rgb
+ // From CMYK to CMY:
+ // X = X * (1 - K ) + K [for X = C, M, or Y]
+ // Thus, from Inverted CMYK to CMY is:
+ // X = (1-iX) * (1 - (1-iK)) + (1-iK) => 1 - iX*iK
+ // From CMY (0..1) to RGB (0..1):
+ // R = 1 - C => 1 - (1 - iC*iK) => iC*iK [G and B similar]
+ unsigned k = jsample[3];
+ buffer.setRGB565(pixel, jsample[0] * k / 255, jsample[1] * k / 255, jsample[2] * k / 255);
+}
+
+template <J_COLOR_SPACE colorSpace, class T> bool outputRows(JPEGImageReader* reader, ImageFrame& buffer)
{
JSAMPARRAY samples = reader->samples();
jpeg_decompress_struct* info = reader->info();
@@ -901,9 +967,9 @@ template <J_COLOR_SPACE colorSpace> bool outputRows(JPEGImageReader* reader, Ima
if (reader->colorTransform() && colorSpace == JCS_RGB)
qcms_transform_data(reader->colorTransform(), *samples, *samples, width);
#endif
- ImageFrame::PixelData* pixel = buffer.getAddr(0, y);
+ T* pixel = buffer.getAddrT<T>(0, y);
for (int x = 0; x < width; ++pixel, ++x)
- setPixel<colorSpace>(buffer, pixel, samples, x);
+ setPixel<colorSpace, T>(buffer, pixel, samples, x);
}
buffer.setPixelsChanged(true);
@@ -1005,11 +1071,13 @@ bool JPEGImageDecoder::outputScanlines()
ASSERT(info->output_width == static_cast<JDIMENSION>(m_decodedSize.width()));
ASSERT(info->output_height == static_cast<JDIMENSION>(m_decodedSize.height()));
- if (!buffer.setSize(info->output_width, info->output_height))
+ if (!buffer.setSize(info->output_width, info->output_height, decodeToRGB565Enabled()
+ ? ImageFrame::RGB565 : ImageFrame::RGBA8888))
return setFailed();
buffer.setStatus(ImageFrame::FramePartial);
// The buffer is transparent outside the decoded area while the image is
// loading. The image will be marked fully opaque in complete().
+ // for RGB565 this would just fail, having bitmap opaque during decoding
scroggo_chromium 2015/10/19 20:41:36 So doesn't this need to say something like if (!56
aleksandar.stojiljkovic 2015/10/20 09:51:12 Done.
buffer.setHasAlpha(true);
// For JPEGs, the frame always fills the entire image.
@@ -1019,9 +1087,12 @@ bool JPEGImageDecoder::outputScanlines()
#if defined(TURBO_JPEG_RGB_SWIZZLE)
if (turboSwizzled(info->out_color_space)) {
while (info->output_scanline < info->output_height) {
- unsigned char* row = reinterpret_cast_ptr<unsigned char*>(buffer.getAddr(0, info->output_scanline));
- if (jpeg_read_scanlines(info, &row, 1) != 1)
+ unsigned char* row = decodeToRGB565Enabled()
+ ? reinterpret_cast_ptr<unsigned char*>(buffer.getAddrT<ImageFrame::PixelData16>(0, info->output_scanline))
+ : reinterpret_cast_ptr<unsigned char*>(buffer.getAddr(0, info->output_scanline));
+ if (jpeg_read_scanlines(info, &row, 1) != 1) {
return false;
+ }
#if USE(QCMSLIB)
if (qcms_transform* transform = m_reader->colorTransform())
qcms_transform_data_type(transform, row, row, info->output_width, rgbOutputColorSpace() == JCS_EXT_BGRA ? QCMS_OUTPUT_BGRX : QCMS_OUTPUT_RGBX);
@@ -1034,9 +1105,13 @@ bool JPEGImageDecoder::outputScanlines()
switch (info->out_color_space) {
case JCS_RGB:
- return outputRows<JCS_RGB>(m_reader.get(), buffer);
+ if (decodeToRGB565Enabled())
+ return outputRows<JCS_RGB, ImageFrame::PixelData16>(m_reader.get(), buffer);
+ return outputRows<JCS_RGB, ImageFrame::PixelData>(m_reader.get(), buffer);
case JCS_CMYK:
- return outputRows<JCS_CMYK>(m_reader.get(), buffer);
+ if (decodeToRGB565Enabled())
+ return outputRows<JCS_CMYK, ImageFrame::PixelData16>(m_reader.get(), buffer);
+ return outputRows<JCS_CMYK, ImageFrame::PixelData>(m_reader.get(), buffer);
default:
ASSERT_NOT_REACHED();
}

Powered by Google App Engine
This is Rietveld 408576698