diff options
author | hbono@chromium.org <hbono@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-03-09 09:11:13 +0000 |
---|---|---|
committer | hbono@chromium.org <hbono@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-03-09 09:11:13 +0000 |
commit | 0d885e70223c417d706b4398ffa872e60b74d370 (patch) | |
tree | 3661986e8196ac573598ed5f68066d404d758ab9 /ui | |
parent | 8e231cc30bd613645a2425e7f7579564960effd9 (diff) | |
download | chromium_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.cc | 73 |
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); |