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

Unified Diff: ui/gfx/codec/jpeg_codec.cc

Issue 2924733002: Revert of Delete FORMAT_RGB and legacy libjpeg support from gfx::JpegCodec (Closed)
Patch Set: Created 3 years, 6 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 | « ui/gfx/codec/jpeg_codec.h ('k') | ui/gfx/codec/jpeg_codec_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/gfx/codec/jpeg_codec.cc
diff --git a/ui/gfx/codec/jpeg_codec.cc b/ui/gfx/codec/jpeg_codec.cc
index 3dc5ad6235668d4323f8f0d8268561d6ea8674bc..6d926378bec130b53d70bbb510a1287f42b78a08 100644
--- a/ui/gfx/codec/jpeg_codec.cc
+++ b/ui/gfx/codec/jpeg_codec.cc
@@ -42,6 +42,17 @@
}
} // namespace
+
+// This method helps identify at run time which library chromium is using.
+JPEGCodec::LibraryVariant JPEGCodec::JpegLibraryVariant() {
+#if defined(USE_SYSTEM_LIBJPEG)
+ return SYSTEM_LIBJPEG;
+#elif defined(USE_LIBJPEG_TURBO)
+ return LIBJPEG_TURBO;
+#else
+ return IJG_LIBJPEG;
+#endif
+}
// Encoder ---------------------------------------------------------------------
//
@@ -133,6 +144,33 @@
state->out->resize(state->image_buffer_used);
}
+#if !defined(JCS_EXTENSIONS)
+// Converts RGBA to RGB (removing the alpha values) to prepare to send data to
+// libjpeg. This converts one row of data in rgba with the given width in
+// pixels the the given rgb destination buffer (which should have enough space
+// reserved for the final data).
+void StripAlpha(const unsigned char* rgba, int pixel_width, unsigned char* rgb)
+{
+ for (int x = 0; x < pixel_width; x++)
+ memcpy(&rgb[x * 3], &rgba[x * 4], 3);
+}
+
+// Converts BGRA to RGB by reordering the color components and dropping the
+// alpha. This converts one row of data in rgba with the given width in
+// pixels the the given rgb destination buffer (which should have enough space
+// reserved for the final data).
+void BGRAtoRGB(const unsigned char* bgra, int pixel_width, unsigned char* rgb)
+{
+ for (int x = 0; x < pixel_width; x++) {
+ const unsigned char* pixel_in = &bgra[x * 4];
+ unsigned char* pixel_out = &rgb[x * 3];
+ pixel_out[0] = pixel_in[2];
+ pixel_out[1] = pixel_in[1];
+ pixel_out[2] = pixel_in[0];
+ }
+}
+#endif // !defined(JCS_EXTENSIONS)
+
// This class destroys the given jpeg_compress object when it goes out of
// scope. It simplifies the error handling in Encode (and even applies to the
// success case).
@@ -166,6 +204,9 @@
CompressDestroyer destroyer;
destroyer.SetManagedObject(&cinfo);
output->clear();
+#if !defined(JCS_EXTENSIONS)
+ unsigned char* row_buffer = NULL;
+#endif
// We set up the normal JPEG error routines, then override error_exit.
// This must be done before the call to create_compress.
@@ -181,6 +222,9 @@
// goto using a call to longjmp." So we delete the CompressDestroyer's
// object manually instead.
destroyer.DestroyManagedObject();
+#if !defined(JCS_EXTENSIONS)
+ delete[] row_buffer;
+#endif
return false;
}
@@ -189,16 +233,22 @@
cinfo.image_width = w;
cinfo.image_height = h;
- cinfo.input_components = 4;
+ 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_RGBA ||
- (format == FORMAT_SkBitmap && SK_R32_SHIFT == 0)) {
+ 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
@@ -206,6 +256,9 @@
NOTREACHED() << "Invalid pixel format";
return false;
}
+#else
+ cinfo.in_color_space = JCS_RGB;
+#endif
cinfo.data_precision = 8;
jpeg_set_defaults(&cinfo);
@@ -224,6 +277,7 @@
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.
@@ -231,6 +285,37 @@
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) {
+ const unsigned char* row = &input[cinfo.next_scanline * row_byte_width];
+ jpeg_write_scanlines(&cinfo, const_cast<unsigned char**>(&row), 1);
+ }
+ } else {
+ // get the correct format converter
+ void (*converter)(const unsigned char* in, int w, unsigned char* rgb);
+ if (format == FORMAT_RGBA ||
+ (format == FORMAT_SkBitmap && SK_R32_SHIFT == 0)) {
+ converter = StripAlpha;
+ } else if (format == FORMAT_BGRA ||
+ (format == FORMAT_SkBitmap && SK_B32_SHIFT == 0)) {
+ converter = BGRAtoRGB;
+ } else {
+ NOTREACHED() << "Invalid pixel format";
+ return false;
+ }
+
+ // output row after converting
+ row_buffer = new unsigned char[w * 3];
+
+ while (cinfo.next_scanline < cinfo.image_height) {
+ converter(&input[cinfo.next_scanline * row_byte_width], w, row_buffer);
+ jpeg_write_scanlines(&cinfo, &row_buffer, 1);
+ }
+ delete[] row_buffer;
+ }
+#endif
jpeg_finish_compress(&cinfo);
return true;
@@ -313,6 +398,31 @@
void TermSource(j_decompress_ptr cinfo) {
}
+#if !defined(JCS_EXTENSIONS)
+// Converts one row of rgb data to rgba data by adding a fully-opaque alpha
+// value.
+void AddAlpha(const unsigned char* rgb, int pixel_width, unsigned char* rgba) {
+ for (int x = 0; x < pixel_width; x++) {
+ memcpy(&rgba[x * 4], &rgb[x * 3], 3);
+ rgba[x * 4 + 3] = 0xff;
+ }
+}
+
+// Converts one row of RGB data to BGRA by reordering the color components and
+// adding alpha values of 0xff.
+void RGBtoBGRA(const unsigned char* bgra, int pixel_width, unsigned char* rgb)
+{
+ for (int x = 0; x < pixel_width; x++) {
+ const unsigned char* pixel_in = &bgra[x * 3];
+ unsigned char* pixel_out = &rgb[x * 4];
+ pixel_out[0] = pixel_in[2];
+ pixel_out[1] = pixel_in[1];
+ pixel_out[2] = pixel_in[0];
+ pixel_out[3] = 0xff;
+ }
+}
+#endif // !defined(JCS_EXTENSIONS)
+
// This class destroys the given jpeg_decompress object when it goes out of
// scope. It simplifies the error handling in Decode (and even applies to the
// success case).
@@ -386,12 +496,16 @@
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_RGBA ||
- (format == FORMAT_SkBitmap && SK_R32_SHIFT == 0)) {
+ 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 ||
@@ -404,6 +518,9 @@
NOTREACHED() << "Invalid pixel format";
return false;
}
+#else
+ cinfo.out_color_space = JCS_RGB;
+#endif
break;
case JCS_CMYK:
case JCS_YCCK:
@@ -413,6 +530,9 @@
// care about these anyway.
return false;
}
+#ifndef JCS_EXTENSIONS
+ cinfo.output_components = 3;
+#endif
jpeg_calc_output_dimensions(&cinfo);
*w = cinfo.output_width;
@@ -424,6 +544,7 @@
// 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;
@@ -434,6 +555,49 @@
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;
+ 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 {
+ // Rows need conversion to output format: read into a temporary buffer and
+ // expand to the final one. Performance: we could avoid the extra
+ // allocation by doing the expansion in-place.
+ int row_write_stride;
+ void (*converter)(const unsigned char* rgb, int w, unsigned char* out);
+ if (format == FORMAT_RGBA ||
+ (format == FORMAT_SkBitmap && SK_R32_SHIFT == 0)) {
+ row_write_stride = cinfo.output_width * 4;
+ converter = AddAlpha;
+ } else if (format == FORMAT_BGRA ||
+ (format == FORMAT_SkBitmap && SK_B32_SHIFT == 0)) {
+ row_write_stride = cinfo.output_width * 4;
+ converter = RGBtoBGRA;
+ } else {
+ NOTREACHED() << "Invalid pixel format";
+ jpeg_destroy_decompress(&cinfo);
+ return false;
+ }
+
+ output->resize(row_write_stride * cinfo.output_height);
+
+ std::unique_ptr<unsigned char[]> row_data(
+ new unsigned char[row_read_stride]);
+ unsigned char* rowptr = row_data.get();
+ for (int row = 0; row < static_cast<int>(cinfo.output_height); row++) {
+ if (!jpeg_read_scanlines(&cinfo, &rowptr, 1))
+ return false;
+ converter(rowptr, *w, &(*output)[row * row_write_stride]);
+ }
+ }
+#endif
jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);
« no previous file with comments | « ui/gfx/codec/jpeg_codec.h ('k') | ui/gfx/codec/jpeg_codec_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698