summaryrefslogtreecommitdiffstats
path: root/ui
diff options
context:
space:
mode:
authorhbono@chromium.org <hbono@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-03-09 09:11:13 +0000
committerhbono@chromium.org <hbono@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-03-09 09:11:13 +0000
commit0d885e70223c417d706b4398ffa872e60b74d370 (patch)
tree3661986e8196ac573598ed5f68066d404d758ab9 /ui
parent8e231cc30bd613645a2425e7f7579564960effd9 (diff)
downloadchromium_src-0d885e70223c417d706b4398ffa872e60b74d370.zip
chromium_src-0d885e70223c417d706b4398ffa872e60b74d370.tar.gz
chromium_src-0d885e70223c417d706b4398ffa872e60b74d370.tar.bz2
Optimizes JPEGCodec for libjpeg-turbo
Libjpeg-turbo can use RGBA and BGRA pixels used by Chromium as its input or output. This change uses these converters to avoid memory copies when the output format is RGBA or BGRA. BUG=none TEST=none Review URL: http://codereview.chromium.org/6603010 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@77444 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui')
-rw-r--r--ui/gfx/codec/jpeg_codec.cc73
1 files changed, 73 insertions, 0 deletions
diff --git a/ui/gfx/codec/jpeg_codec.cc b/ui/gfx/codec/jpeg_codec.cc
index 0558c93..757686b 100644
--- a/ui/gfx/codec/jpeg_codec.cc
+++ b/ui/gfx/codec/jpeg_codec.cc
@@ -216,7 +216,31 @@ bool JPEGCodec::Encode(const unsigned char* input, ColorFormat format,
cinfo.image_width = w;
cinfo.image_height = h;
cinfo.input_components = 3;
+#ifdef JCS_EXTENSIONS
+ // Choose an input colorspace and return if it is an unsupported one. Since
+ // libjpeg-turbo supports all input formats used by Chromium (i.e. RGB, RGBA,
+ // and BGRA), we just map the input parameters to a colorspace used by
+ // libjpeg-turbo.
+ if (format == FORMAT_RGB) {
+ cinfo.input_components = 3;
+ cinfo.in_color_space = JCS_RGB;
+ } else if (format == FORMAT_RGBA ||
+ format == FORMAT_SkBitmap && SK_R32_SHIFT == 0) {
+ cinfo.input_components = 4;
+ cinfo.in_color_space = JCS_EXT_RGBX;
+ } else if (format == FORMAT_BGRA ||
+ format == FORMAT_SkBitmap && SK_B32_SHIFT == 0) {
+ cinfo.input_components = 4;
+ cinfo.in_color_space = JCS_EXT_BGRX;
+ } else {
+ // We can exit this function without calling jpeg_destroy_compress() because
+ // CompressDestroyer automaticaly calls it.
+ NOTREACHED() << "Invalid pixel format";
+ return false;
+ }
+#else
cinfo.in_color_space = JCS_RGB;
+#endif
cinfo.data_precision = 8;
jpeg_set_defaults(&cinfo);
@@ -235,6 +259,15 @@ bool JPEGCodec::Encode(const unsigned char* input, ColorFormat format,
jpeg_start_compress(&cinfo, 1);
// feed it the rows, doing necessary conversions for the color format
+#ifdef JCS_EXTENSIONS
+ // This function already returns when the input format is not supported by
+ // libjpeg-turbo and needs conversion. Therefore, we just encode lines without
+ // conversions.
+ while (cinfo.next_scanline < cinfo.image_height) {
+ const unsigned char* row = &input[cinfo.next_scanline * row_byte_width];
+ jpeg_write_scanlines(&cinfo, const_cast<unsigned char**>(&row), 1);
+ }
+#else
if (format == FORMAT_RGB) {
// no conversion necessary
while (cinfo.next_scanline < cinfo.image_height) {
@@ -264,6 +297,7 @@ bool JPEGCodec::Encode(const unsigned char* input, ColorFormat format,
}
delete[] row;
}
+#endif
jpeg_finish_compress(&cinfo);
return true;
@@ -446,7 +480,31 @@ bool JPEGCodec::Decode(const unsigned char* input, size_t input_size,
case JCS_GRAYSCALE:
case JCS_RGB:
case JCS_YCbCr:
+#ifdef JCS_EXTENSIONS
+ // Choose an output colorspace and return if it is an unsupported one.
+ // Same as JPEGCodec::Encode(), libjpeg-turbo supports all input formats
+ // used by Chromium (i.e. RGB, RGBA, and BGRA) and we just map the input
+ // parameters to a colorspace.
+ if (format == FORMAT_RGB) {
+ cinfo.out_color_space = JCS_RGB;
+ cinfo.output_components = 3;
+ } else if (format == FORMAT_RGBA ||
+ format == FORMAT_SkBitmap && SK_R32_SHIFT == 0) {
+ cinfo.out_color_space = JCS_EXT_RGBX;
+ cinfo.output_components = 4;
+ } else if (format == FORMAT_BGRA ||
+ format == FORMAT_SkBitmap && SK_B32_SHIFT == 0) {
+ cinfo.out_color_space = JCS_EXT_BGRX;
+ cinfo.output_components = 4;
+ } else {
+ // We can exit this function without calling jpeg_destroy_decompress()
+ // because DecompressDestroyer automaticaly calls it.
+ NOTREACHED() << "Invalid pixel format";
+ return false;
+ }
+#else
cinfo.out_color_space = JCS_RGB;
+#endif
break;
case JCS_CMYK:
case JCS_YCCK:
@@ -456,7 +514,9 @@ bool JPEGCodec::Decode(const unsigned char* input, size_t input_size,
// care about these anyway.
return false;
}
+#ifndef JCS_EXTENSIONS
cinfo.output_components = 3;
+#endif
jpeg_calc_output_dimensions(&cinfo);
*w = cinfo.output_width;
@@ -468,6 +528,18 @@ bool JPEGCodec::Decode(const unsigned char* input, size_t input_size,
// how to align row lengths as we do for the compressor.
int row_read_stride = cinfo.output_width * cinfo.output_components;
+#ifdef JCS_EXTENSIONS
+ // Create memory for a decoded image and write decoded lines to the memory
+ // without conversions same as JPEGCodec::Encode().
+ int row_write_stride = row_read_stride;
+ output->resize(row_write_stride * cinfo.output_height);
+
+ for (int row = 0; row < static_cast<int>(cinfo.output_height); row++) {
+ unsigned char* rowptr = &(*output)[row * row_write_stride];
+ if (!jpeg_read_scanlines(&cinfo, &rowptr, 1))
+ return false;
+ }
+#else
if (format == FORMAT_RGB) {
// easy case, row needs no conversion
int row_write_stride = row_read_stride;
@@ -508,6 +580,7 @@ bool JPEGCodec::Decode(const unsigned char* input, size_t input_size,
converter(rowptr, *w, &(*output)[row * row_write_stride]);
}
}
+#endif
jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);