[gthumb: 65/129] added the _cairo_image_surface_transform_get_steps() function



commit fded97c804459495d2dbc8863befc17fcf6518e3
Author: Paolo Bacchilega <paobac src gnome org>
Date:   Sun Apr 24 11:01:50 2011 +0200

    added the _cairo_image_surface_transform_get_steps() function
    
    simplified _cairo_image_surface_transform using _cairo_image_surface_transform_get_steps

 gthumb/cairo-utils.c |  258 +++++++++++++++++++++++++------------------------
 gthumb/cairo-utils.h |    9 ++
 2 files changed, 141 insertions(+), 126 deletions(-)
---
diff --git a/gthumb/cairo-utils.c b/gthumb/cairo-utils.c
index c8f0766..f8a3727 100644
--- a/gthumb/cairo-utils.c
+++ b/gthumb/cairo-utils.c
@@ -306,159 +306,165 @@ _cairo_image_surface_scale_to (cairo_surface_t *surface,
 }
 
 
-cairo_surface_t *
-_cairo_image_surface_transform (cairo_surface_t *source,
-				GthTransform     transform)
+void
+_cairo_image_surface_transform_get_steps (cairo_format_t  format,
+					  int             width,
+					  int             height,
+					  GthTransform    transform,
+					  int            *destination_width_p,
+					  int            *destination_height_p,
+					  int            *line_start_p,
+					  int            *line_step_p,
+					  int            *pixel_step_p)
 {
-	cairo_surface_t *destination = NULL;
-	cairo_format_t   format;
-	int              width;
-	int              height;
-	int              source_stride;
-	int              destination_stride;
-	unsigned char   *p_source_line;
-	unsigned char   *p_destination_line;
-	unsigned char   *p_source;
-	unsigned char   *p_destination;
-	int              x;
-
-	if (source == NULL)
-		return NULL;
-
-	format = cairo_image_surface_get_format (source);
-	width = cairo_image_surface_get_width (source);
-	height = cairo_image_surface_get_height (source);
-	source_stride = cairo_image_surface_get_stride (source);
+	int destination_stride;
+	int destination_width = 0;
+	int destination_height = 0;
+	int line_start = 0;
+	int line_step = 0;
+	int pixel_step = 0;
 
 	switch (transform) {
 	case GTH_TRANSFORM_NONE:
-		destination = _cairo_image_surface_copy (source);
+	default:
+		destination_width = width;
+		destination_height = height;
+		destination_stride = cairo_format_stride_for_width (format, destination_width);
+		line_start = 0;
+		line_step = destination_stride;
+		pixel_step = 4;
 		break;
 
 	case GTH_TRANSFORM_FLIP_H:
-		destination = cairo_image_surface_create (format, width, height);
-		destination_stride = cairo_image_surface_get_stride (destination);
-		p_source_line = cairo_image_surface_get_data (source);
-		p_destination_line = cairo_image_surface_get_data (destination) + ((width - 1) * 4);
-		while (height-- > 0) {
-			p_source = p_source_line;
-			p_destination = p_destination_line;
-			for (x = 0; x < width; x++) {
-				memcpy (p_destination, p_source, 4);
-				p_source += 4;
-				p_destination -= 4;
-			}
-			p_source_line += source_stride;
-			p_destination_line += destination_stride;
-		}
+		destination_width = width;
+		destination_height = height;
+		destination_stride = cairo_format_stride_for_width (format, destination_width);
+		line_start = (destination_width - 1) * 4;
+		line_step = destination_stride;
+		pixel_step = -4;
 		break;
 
 	case GTH_TRANSFORM_ROTATE_180:
-		destination = cairo_image_surface_create (format, width, height);
-		destination_stride = cairo_image_surface_get_stride (destination);
-		p_source_line = cairo_image_surface_get_data (source);
-		p_destination_line = cairo_image_surface_get_data (destination) + ((height - 1) * destination_stride) + ((width - 1) * 4);
-		while (height-- > 0) {
-			p_source = p_source_line;
-			p_destination = p_destination_line;
-			for (x = 0; x < width; x++) {
-				memcpy (p_destination, p_source, 4);
-				p_source += 4;
-				p_destination -= 4;
-			}
-			p_source_line += source_stride;
-			p_destination_line -= destination_stride;
-		}
+		destination_width = width;
+		destination_height = height;
+		destination_stride = cairo_format_stride_for_width (format, destination_width);
+		line_start = ((destination_height - 1) * destination_stride) + ((destination_width - 1) * 4);
+		line_step = -destination_stride;
+		pixel_step = -4;
 		break;
 
 	case GTH_TRANSFORM_FLIP_V:
-		destination = cairo_image_surface_create (format, width, height);
-		destination_stride = cairo_image_surface_get_stride (destination);
-		g_return_val_if_fail (source_stride == destination_stride, NULL);
-		p_source_line = cairo_image_surface_get_data (source);
-		p_destination_line = cairo_image_surface_get_data (destination) + ((height - 1) * destination_stride);
-		while (height-- > 0) {
-			memcpy (p_destination_line, p_source_line, source_stride);
-			p_source_line += source_stride;
-			p_destination_line -= destination_stride;
-		}
+		destination_width = width;
+		destination_height = height;
+		destination_stride = cairo_format_stride_for_width (format, destination_width);
+		line_start = (destination_height - 1) * destination_stride;
+		line_step = -destination_stride;
+		pixel_step = 4;
 		break;
 
 	case GTH_TRANSFORM_TRANSPOSE:
-		destination = cairo_image_surface_create (format, height, width);
-		destination_stride = cairo_image_surface_get_stride (destination);
-		p_source_line = cairo_image_surface_get_data (source);
-		p_destination_line = cairo_image_surface_get_data (destination);
-		while (height-- > 0) {
-			p_source = p_source_line;
-			p_destination = p_destination_line;
-			for (x = 0; x < width; x++) {
-				memcpy (p_destination, p_source, 4);
-				p_source += 4;
-				p_destination += destination_stride;
-			}
-			p_source_line += source_stride;
-			p_destination_line += 4;
-		}
+		destination_width = height;
+		destination_height = width;
+		destination_stride = cairo_format_stride_for_width (format, destination_width);
+		line_start = 0;
+		line_step = 4;
+		pixel_step = destination_stride;
 		break;
 
 	case GTH_TRANSFORM_ROTATE_90:
-		destination = cairo_image_surface_create (format, height, width);
-		destination_stride = cairo_image_surface_get_stride (destination);
-		p_source_line = cairo_image_surface_get_data (source);
-		p_destination_line = cairo_image_surface_get_data (destination) + ((height - 1) * 4);
-		while (height-- > 0) {
-			p_source = p_source_line;
-			p_destination = p_destination_line;
-			for (x = 0; x < width; x++) {
-				memcpy (p_destination, p_source, 4);
-				p_source += 4;
-				p_destination += destination_stride;
-			}
-			p_source_line += source_stride;
-			p_destination_line -= 4;
-		}
+		destination_width = height;
+		destination_height = width;
+		destination_stride = cairo_format_stride_for_width (format, destination_width);
+		line_start = (destination_width - 1) * 4;
+		line_step = -4;
+		pixel_step = destination_stride;
 		break;
 
 	case GTH_TRANSFORM_TRANSVERSE:
-		destination = cairo_image_surface_create (format, height, width);
-		destination_stride = cairo_image_surface_get_stride (destination);
-		p_source_line = cairo_image_surface_get_data (source);
-		p_destination_line = cairo_image_surface_get_data (destination) + ((width - 1) * destination_stride) + ((height - 1) * 4);
-		while (height-- > 0) {
-			p_source = p_source_line;
-			p_destination = p_destination_line;
-			for (x = 0; x < width; x++) {
-				memcpy (p_destination, p_source, 4);
-				p_source += 4;
-				p_destination -= destination_stride;
-			}
-			p_source_line += source_stride;
-			p_destination_line -= 4;
-		}
+		destination_width = height;
+		destination_height = width;
+		destination_stride = cairo_format_stride_for_width (format, destination_width);
+		line_start = ((destination_height - 1) * destination_stride) + ((destination_width - 1) * 4);
+		line_step = -4;
+		pixel_step = -destination_stride;
 		break;
 
 	case GTH_TRANSFORM_ROTATE_270:
-		destination = cairo_image_surface_create (format, height, width);
-		destination_stride = cairo_image_surface_get_stride (destination);
-		p_source_line = cairo_image_surface_get_data (source);
-		p_destination_line = cairo_image_surface_get_data (destination) + ((width - 1) * destination_stride);
-		while (height-- > 0) {
-			p_source = p_source_line;
-			p_destination = p_destination_line;
-			for (x = 0; x < width; x++) {
-				memcpy (p_destination, p_source, 4);
-				p_source += 4;
-				p_destination -= destination_stride;
-			}
-			p_source_line += source_stride;
-			p_destination_line += 4;
-		}
+		destination_width = height;
+		destination_height = width;
+		destination_stride = cairo_format_stride_for_width (format, destination_width);
+		line_start = (destination_height - 1) * destination_stride;
+		line_step = 4;
+		pixel_step = -destination_stride;
 		break;
+	}
 
-	default:
-		g_warning ("_cairo_image_surface_transform: unknown transformation value %d", transform);
-		break;
+	if (destination_width_p != NULL)
+		*destination_width_p = destination_width;
+	if (destination_height_p != NULL)
+		*destination_height_p = destination_height;
+	if (line_start_p != NULL)
+		*line_start_p = line_start;
+	if (line_step_p != NULL)
+		*line_step_p = line_step;
+	if (pixel_step_p != NULL)
+		*pixel_step_p = pixel_step;
+}
+
+
+cairo_surface_t *
+_cairo_image_surface_transform (cairo_surface_t *source,
+				GthTransform     transform)
+{
+	cairo_surface_t *destination = NULL;
+	cairo_format_t   format;
+	int              width;
+	int              height;
+	int              source_stride;
+	int              destination_width;
+	int              destination_height;
+	int              line_start;
+	int              line_step;
+	int              pixel_step;
+	int              destination_stride;
+	unsigned char   *p_source_line;
+	unsigned char   *p_destination_line;
+	unsigned char   *p_source;
+	unsigned char   *p_destination;
+	int              x;
+
+	if (source == NULL)
+		return NULL;
+
+	format = cairo_image_surface_get_format (source);
+	width = cairo_image_surface_get_width (source);
+	height = cairo_image_surface_get_height (source);
+	source_stride = cairo_image_surface_get_stride (source);
+
+	_cairo_image_surface_transform_get_steps (format,
+						  width,
+						  height,
+						  transform,
+						  &destination_width,
+						  &destination_height,
+						  &line_start,
+						  &line_step,
+						  &pixel_step);
+
+	destination = cairo_image_surface_create (format, destination_width, destination_height);
+	destination_stride = cairo_image_surface_get_stride (destination);
+	p_source_line = cairo_image_surface_get_data (source);
+	p_destination_line = cairo_image_surface_get_data (destination) + line_start;
+	while (height-- > 0) {
+		p_source = p_source_line;
+		p_destination = p_destination_line;
+		for (x = 0; x < width; x++) {
+			memcpy (p_destination, p_source, 4);
+			p_source += 4;
+			p_destination += pixel_step;
+		}
+		p_source_line += source_stride;
+		p_destination_line += line_step;
 	}
 
 	return destination;
diff --git a/gthumb/cairo-utils.h b/gthumb/cairo-utils.h
index 8f01308..21d6f03 100644
--- a/gthumb/cairo-utils.h
+++ b/gthumb/cairo-utils.h
@@ -147,6 +147,15 @@ cairo_surface_t *  _cairo_image_surface_scale_to            (cairo_surface_t   *
 							     int                width,
 							     int                height,
 							     cairo_filter_t     filter);
+void               _cairo_image_surface_transform_get_steps (cairo_format_t     format,
+							     int                width,
+							     int                height,
+							     GthTransform       transform,
+							     int               *destination_width_p,
+							     int               *destination_height_p,
+							     int               *line_start_p,
+							     int               *line_step_p,
+							     int               *pixel_step_p);
 cairo_surface_t *  _cairo_image_surface_transform           (cairo_surface_t   *surface,
 							     GthTransform       transform);
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]