[gthumb: 67/129] cairo-io-jpeg: rotate the image without creating a new surface and scale to the requested size
- From: Paolo Bacchilega <paobac src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gthumb: 67/129] cairo-io-jpeg: rotate the image without creating a new surface and scale to the requested size
- Date: Wed, 27 Apr 2011 20:56:00 +0000 (UTC)
commit b450e0e4efcd011d60e03d2ff94fdd0df695a195
Author: Paolo Bacchilega <paobac src gnome org>
Date: Sun Apr 24 11:11:12 2011 +0200
cairo-io-jpeg: rotate the image without creating a new surface and scale to the requested size
extensions/cairo_io/cairo-io-jpeg.c | 97 +++++++++++++++++++++++++---------
1 files changed, 71 insertions(+), 26 deletions(-)
---
diff --git a/extensions/cairo_io/cairo-io-jpeg.c b/extensions/cairo_io/cairo-io-jpeg.c
index 3051698..f9445b3 100644
--- a/extensions/cairo_io/cairo-io-jpeg.c
+++ b/extensions/cairo_io/cairo-io-jpeg.c
@@ -27,11 +27,13 @@
#include <jpeglib.h>
#include <gthumb.h>
#include <extensions/jpeg_utils/jmemorysrc.h>
+#include <extensions/jpeg_utils/jpeg-exif-orientation.h>
#include "cairo-io-jpeg.h"
/* error handler data */
+
struct error_handler_data {
struct jpeg_error_mgr pub;
sigjmp_buf setjmp_buffer;
@@ -142,12 +144,17 @@ _cairo_image_surface_create_from_jpeg (GthFileData *file_data,
GError **error)
{
GthImage *image;
+ GthTransform orientation;
+ int destination_width;
+ int destination_height;
+ int line_start;
+ int line_step;
+ int pixel_step;
void *in_buffer;
gsize in_buffer_size;
struct error_handler_data jsrcerr;
struct jpeg_decompress_struct srcinfo;
cairo_surface_t *surface;
- int surface_stride;
unsigned char *surface_row;
JSAMPARRAY buffer;
int buffer_stride;
@@ -185,16 +192,8 @@ _cairo_image_surface_create_from_jpeg (GthFileData *file_data,
jpeg_read_header (&srcinfo, TRUE);
- /* 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 = srcinfo.jpeg_color_space; /* make all the color space conversions manually */
- /* FIXME
if (requested_size > 0) {
for (srcinfo.scale_denom = 16; srcinfo.scale_denom >= 1; srcinfo.scale_denom--) {
jpeg_calc_output_dimensions (&srcinfo);
@@ -207,13 +206,22 @@ _cairo_image_surface_create_from_jpeg (GthFileData *file_data,
if (srcinfo.scale_denom == 0)
srcinfo.scale_denom = srcinfo.scale_num;
}
- */
jpeg_start_decompress (&srcinfo);
- surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, srcinfo.output_width, srcinfo.output_height);
- surface_stride = cairo_image_surface_get_stride (surface);
- surface_row = cairo_image_surface_get_data (surface);
+ orientation = _jpeg_exif_orientation (in_buffer, in_buffer_size);
+ _cairo_image_surface_transform_get_steps (CAIRO_FORMAT_ARGB32,
+ srcinfo.output_width,
+ srcinfo.output_height,
+ orientation,
+ &destination_width,
+ &destination_height,
+ &line_start,
+ &line_step,
+ &pixel_step);
+
+ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, destination_width, destination_height);
+ surface_row = cairo_image_surface_get_data (surface) + line_start;
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);
@@ -258,11 +266,11 @@ _cairo_image_surface_create_from_jpeg (GthFileData *file_data,
p_surface[CAIRO_BLUE] = cmyk_tab[ki + y];
p_surface[CAIRO_ALPHA] = 0xff;
- p_surface += 4;
+ p_surface += pixel_step;
p_buffer += 4 /*srcinfo.output_components*/;
}
- surface_row += surface_stride;
+ surface_row += line_step;
buffer_row += buffer_stride;
}
}
@@ -288,11 +296,11 @@ _cairo_image_surface_create_from_jpeg (GthFileData *file_data,
p_surface[CAIRO_BLUE] = p_buffer[0];
p_surface[CAIRO_ALPHA] = 0xff;
- p_surface += 4;
+ p_surface += pixel_step;
p_buffer += 1 /*srcinfo.output_components*/;
}
- surface_row += surface_stride;
+ surface_row += line_step;
buffer_row += buffer_stride;
}
}
@@ -318,11 +326,11 @@ _cairo_image_surface_create_from_jpeg (GthFileData *file_data,
p_surface[CAIRO_BLUE] = p_buffer[2];
p_surface[CAIRO_ALPHA] = 0xff;
- p_surface += 4;
+ p_surface += pixel_step;
p_buffer += 3 /*srcinfo.output_components*/;
}
- surface_row += surface_stride;
+ surface_row += line_step;
buffer_row += buffer_stride;
}
}
@@ -365,11 +373,11 @@ _cairo_image_surface_create_from_jpeg (GthFileData *file_data,
p_surface[CAIRO_BLUE] = range_limit[Y + b_cb_tab[Cb]];
p_surface[CAIRO_ALPHA] = 0xff;
- p_surface += 4;
+ p_surface += pixel_step;
p_buffer += 3 /*srcinfo.output_components*/;
}
- surface_row += surface_stride;
+ surface_row += line_step;
buffer_row += buffer_stride;
}
}
@@ -422,11 +430,11 @@ _cairo_image_surface_create_from_jpeg (GthFileData *file_data,
p_surface[CAIRO_BLUE] = cmyk_tab[Ki + y];
p_surface[CAIRO_ALPHA] = 0xff;
- p_surface += 4;
+ p_surface += pixel_step;
p_buffer += 4 /*srcinfo.output_components*/;
}
- surface_row += surface_stride;
+ surface_row += line_step;
buffer_row += buffer_stride;
}
}
@@ -444,12 +452,49 @@ _cairo_image_surface_create_from_jpeg (GthFileData *file_data,
}
if (! g_cancellable_is_cancelled (cancellable)) {
- jpeg_finish_decompress (&srcinfo);
- jpeg_destroy_decompress (&srcinfo);
+ /* Scale to the requested size */
+
+ if (requested_size > 0) {
+ cairo_surface_t *scaled;
+ int width;
+ int height;
+
+ width = destination_width;
+ height = destination_height;
+ scale_keeping_ratio (&width, &height, requested_size, requested_size, TRUE);
+ scaled = _cairo_image_surface_scale_to (surface, width, height, CAIRO_FILTER_BILINEAR);
+
+ cairo_surface_destroy (surface);
+ surface = scaled;
+ }
- /* FIXME: scale to the requested size */
+ /* Set the original dimensions */
+
+ if ((orientation == GTH_TRANSFORM_ROTATE_90)
+ || (orientation == GTH_TRANSFORM_ROTATE_270)
+ || (orientation == GTH_TRANSFORM_TRANSPOSE)
+ || (orientation == GTH_TRANSFORM_TRANSVERSE))
+ {
+ if (original_width != NULL)
+ *original_width = srcinfo.image_height;
+ if (original_height != NULL)
+ *original_height = srcinfo.image_width;
+ }
+ else {
+ if (original_width != NULL)
+ *original_width = srcinfo.image_width;
+ if (original_height != NULL)
+ *original_height = srcinfo.image_height;
+ }
+
+ /*_cairo_image_surface_set_attribute_int (surface, "Image::Rotation", rotation); FIXME*/
+
+ /* FIXME _cairo_image_surface_set_attribute (surface, "Jpeg::ColorSpace", jpeg_color_space_name (srcinfo.jpeg_color_space)); */
gth_image_set_cairo_surface (image, surface);
+
+ jpeg_finish_decompress (&srcinfo);
+ jpeg_destroy_decompress (&srcinfo);
}
else
jpeg_destroy ((j_common_ptr) &srcinfo);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]