[gthumb: 63/129] cairo-io-jpeg: added color space convertion
- From: Paolo Bacchilega <paobac src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gthumb: 63/129] cairo-io-jpeg: added color space convertion
- Date: Wed, 27 Apr 2011 20:55:40 +0000 (UTC)
commit ec6698ab8bf5108a4c2c31435cf7c05f292d9dbe
Author: Paolo Bacchilega <paobac src gnome org>
Date: Sat Apr 23 16:40:02 2011 +0200
cairo-io-jpeg: added color space convertion
extensions/cairo_io/cairo-io-jpeg.c | 202 +++++++++++++++++++++++++++++------
1 files changed, 169 insertions(+), 33 deletions(-)
---
diff --git a/extensions/cairo_io/cairo-io-jpeg.c b/extensions/cairo_io/cairo-io-jpeg.c
index 17c499b..4a2ae06 100644
--- a/extensions/cairo_io/cairo-io-jpeg.c
+++ b/extensions/cairo_io/cairo-io-jpeg.c
@@ -94,14 +94,24 @@ _cairo_image_surface_create_from_jpeg (GthFileData *file_data,
unsigned char *surface_row;
JSAMPARRAY buffer;
int buffer_stride;
+ JDIMENSION n_lines;
JSAMPARRAY buffer_row;
+ int l;
unsigned char *p_surface;
unsigned char *p_buffer;
- JDIMENSION nlines;
- int x, l;
+ int x;
image = gth_image_new ();
+ if (! g_load_file_in_buffer (file_data->file,
+ &in_buffer,
+ &in_buffer_size,
+ cancellable,
+ error))
+ {
+ return image;
+ }
+
srcinfo.err = jpeg_std_error (&(jsrcerr.pub));
jsrcerr.pub.error_exit = fatal_error_handler;
jsrcerr.pub.output_message = output_message_handler;
@@ -114,27 +124,17 @@ _cairo_image_surface_create_from_jpeg (GthFileData *file_data,
return image;
}
- if (! g_load_file_in_buffer (file_data->file,
- &in_buffer,
- &in_buffer_size,
- error))
- {
- jpeg_destroy_decompress (&srcinfo);
- return image;
- }
-
_jpeg_memory_src (&srcinfo, in_buffer, in_buffer_size);
jpeg_read_header (&srcinfo, TRUE);
- /* FIXME: read the orientation flags and rotate the image */
+ /* FIXME: read the orientation flag and rotate the image */
if (original_width != NULL)
*original_width = srcinfo.image_width;
if (original_height != NULL)
*original_height = srcinfo.image_height;
- srcinfo.out_color_space = JCS_RGB;
/* FIXME
if (requested_size > 0) {
for (srcinfo.scale_denom = 16; srcinfo.scale_denom >= 1; srcinfo.scale_denom--) {
@@ -159,33 +159,169 @@ _cairo_image_surface_create_from_jpeg (GthFileData *file_data,
buffer_stride = srcinfo.output_width * srcinfo.output_components;
buffer = (*srcinfo.mem->alloc_sarray) ((j_common_ptr) &srcinfo, JPOOL_IMAGE, buffer_stride, srcinfo.rec_outbuf_height);
- while (srcinfo.output_scanline < srcinfo.output_height) {
- nlines = jpeg_read_scanlines (&srcinfo, buffer, srcinfo.rec_outbuf_height);
- buffer_row = buffer;
- for (l = 0; l < nlines; l++) {
- p_surface = surface_row;
- p_buffer = buffer_row[l];
- for (x = 0; x < srcinfo.output_width; x++) {
- p_surface[CAIRO_RED] = p_buffer[0];
- p_surface[CAIRO_GREEN] = p_buffer[1];
- p_surface[CAIRO_BLUE] = p_buffer[2];
- p_surface[CAIRO_ALPHA] = 0xff;
-
- p_surface += 4;
- p_buffer += srcinfo.output_components;
+ switch (srcinfo.out_color_space) {
+ case JCS_CMYK:
+ {
+ static unsigned char *tab = NULL; /* table with pre-multiplied values */
+ int ki;
+
+ while (srcinfo.output_scanline < srcinfo.output_height) {
+ if (g_cancellable_is_cancelled (cancellable))
+ break;
+
+ n_lines = jpeg_read_scanlines (&srcinfo, buffer, srcinfo.rec_outbuf_height);
+
+ if (tab == NULL) {
+ int v, k, i;
+ double k1;
+
+ /* tab[k * 256 + v] = v * k / 255.0 */
+
+ tab = g_new (unsigned char, 256 * 256);
+ i = 0;
+ for (k = 0; k <= 255; k++) {
+ k1 = (double) k / 255.0;
+ for (v = 0; v <= 255; v++)
+ tab[i++] = (double) v * k1;
+ }
+ }
+
+ buffer_row = buffer;
+ for (l = 0; l < n_lines; l++) {
+ p_surface = surface_row;
+ p_buffer = buffer_row[l];
+
+ for (x = 0; x < srcinfo.output_width; x++) {
+ ki = p_buffer[3] << 8; /* ki = k * 256 */
+ p_surface[CAIRO_RED] = tab[ki + p_buffer[0]];
+ p_surface[CAIRO_GREEN] = tab[ki + p_buffer[1]];
+ p_surface[CAIRO_BLUE] = tab[ki + p_buffer[2]];
+ p_surface[CAIRO_ALPHA] = 0xff;
+
+ p_surface += 4;
+ p_buffer += 4 /*srcinfo.output_components*/;
+ }
+
+ surface_row += surface_stride;
+ buffer_row += buffer_stride;
+ }
}
+ }
+ break;
+
+ case JCS_GRAYSCALE:
+ {
+ while (srcinfo.output_scanline < srcinfo.output_height) {
+ if (g_cancellable_is_cancelled (cancellable))
+ break;
+
+ n_lines = jpeg_read_scanlines (&srcinfo, buffer, srcinfo.rec_outbuf_height);
+
+ buffer_row = buffer;
+ for (l = 0; l < n_lines; l++) {
+ p_surface = surface_row;
+ p_buffer = buffer_row[l];
+
+ for (x = 0; x < srcinfo.output_width; x++) {
+ p_surface[CAIRO_RED] = p_buffer[0];
+ p_surface[CAIRO_GREEN] = p_buffer[0];
+ p_surface[CAIRO_BLUE] = p_buffer[0];
+ p_surface[CAIRO_ALPHA] = 0xff;
+
+ p_surface += 4;
+ p_buffer += 1 /*srcinfo.output_components*/;
+ }
+
+ surface_row += surface_stride;
+ buffer_row += buffer_stride;
+ }
+ }
+ }
+ break;
+
+ case JCS_RGB:
+ {
+ while (srcinfo.output_scanline < srcinfo.output_height) {
+ if (g_cancellable_is_cancelled (cancellable))
+ break;
+
+ n_lines = jpeg_read_scanlines (&srcinfo, buffer, srcinfo.rec_outbuf_height);
+
+ buffer_row = buffer;
+ for (l = 0; l < n_lines; l++) {
+ p_surface = surface_row;
+ p_buffer = buffer_row[l];
+
+ for (x = 0; x < srcinfo.output_width; x++) {
+ p_surface[CAIRO_RED] = p_buffer[0];
+ p_surface[CAIRO_GREEN] = p_buffer[1];
+ p_surface[CAIRO_BLUE] = p_buffer[2];
+ p_surface[CAIRO_ALPHA] = 0xff;
+
+ p_surface += 4;
+ p_buffer += 3 /*srcinfo.output_components*/;
+ }
+
+ surface_row += surface_stride;
+ buffer_row += buffer_stride;
+ }
+ }
+ }
+ break;
+
+ case JCS_YCbCr:
+ {
+ double Y, Cb, Cr;
+
+ while (srcinfo.output_scanline < srcinfo.output_height) {
+ if (g_cancellable_is_cancelled (cancellable))
+ break;
+
+ n_lines = jpeg_read_scanlines (&srcinfo, buffer, srcinfo.rec_outbuf_height);
- surface_row += surface_stride;
- buffer_row += buffer_stride;
+ buffer_row = buffer;
+ for (l = 0; l < n_lines; l++) {
+ p_surface = surface_row;
+ p_buffer = buffer_row[l];
+
+ for (x = 0; x < srcinfo.output_width; x++) {
+ Y = (double) p_buffer[0];
+ Cb = (double) p_buffer[1];
+ Cr = (double) p_buffer[2];
+
+ p_surface[CAIRO_RED] = Y + 1.402 * (Cr - 128);
+ p_surface[CAIRO_GREEN] = Y - 0.34414 * (Cb - 128) - 0.71414 * (Cr - 128);
+ p_surface[CAIRO_BLUE] = Y + 1.772 * (Cb - 128);
+ p_surface[CAIRO_ALPHA] = 0xff;
+
+ p_surface += 4;
+ p_buffer += 3 /*srcinfo.output_components*/;
+ }
+
+ surface_row += surface_stride;
+ buffer_row += buffer_stride;
+ }
+ }
}
+ break;
+
+ case JCS_YCCK:
+ case JCS_UNKNOWN:
+ default:
+ /* FIXME: ? */
+ break;
}
- jpeg_finish_decompress (&srcinfo);
- jpeg_destroy_decompress (&srcinfo);
+ if (! g_cancellable_is_cancelled (cancellable)) {
+ jpeg_finish_decompress (&srcinfo);
+ jpeg_destroy_decompress (&srcinfo);
- /* FIXME: scale to the requested size */
+ /* FIXME: scale to the requested size */
- gth_image_set_cairo_surface (image, surface);
+ gth_image_set_cairo_surface (image, surface);
+ }
+ else
+ jpeg_destroy ((j_common_ptr) &srcinfo);
cairo_surface_destroy (surface);
g_free (in_buffer);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]