1 /* GdkPixbuf library - Scaling and compositing functions
3 * Copyright (C) 1999 The Free Software Foundation
5 * Author: Owen Taylor <otaylor@redhat.com>
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
26 #include "gdk-pixbuf-private.h"
27 #include "pixops/pixops.h"
28 #include "gdk-pixbuf-alias.h"
35 * @dest: the #GdkPixbuf into which to render the results
36 * @dest_x: the left coordinate for region to render
37 * @dest_y: the top coordinate for region to render
38 * @dest_width: the width of the region to render
39 * @dest_height: the height of the region to render
40 * @offset_x: the offset in the X direction (currently rounded to an integer)
41 * @offset_y: the offset in the Y direction (currently rounded to an integer)
42 * @scale_x: the scale factor in the X direction
43 * @scale_y: the scale factor in the Y direction
44 * @interp_type: the interpolation type for the transformation.
46 * Creates a transformation of the source image @src by scaling by
47 * @scale_x and @scale_y then translating by @offset_x and @offset_y,
48 * then renders the rectangle (@dest_x, @dest_y, @dest_width,
49 * @dest_height) of the resulting image onto the destination image
50 * replacing the previous contents.
52 * Try to use gdk_pixbuf_scale_simple() first, this function is
53 * the industrial-strength power tool you can fall back to if
54 * gdk_pixbuf_scale_simple() isn't powerful enough.
56 * If the source rectangle overlaps the destination rectangle on the
57 * same pixbuf, it will be overwritten during the scaling which
58 * results in rendering artifacts.
61 gdk_pixbuf_scale (const GdkPixbuf *src,
71 GdkInterpType interp_type)
73 g_return_if_fail (GDK_IS_PIXBUF (src));
74 g_return_if_fail (GDK_IS_PIXBUF (dest));
75 g_return_if_fail (dest_x >= 0 && dest_x + dest_width <= dest->width);
76 g_return_if_fail (dest_y >= 0 && dest_y + dest_height <= dest->height);
78 offset_x = floor (offset_x + 0.5);
79 offset_y = floor (offset_y + 0.5);
81 _pixops_scale (dest->pixels, dest->width, dest->height, dest->rowstride,
82 dest->n_channels, dest->has_alpha, src->pixels, src->width,
83 src->height, src->rowstride, src->n_channels, src->has_alpha,
84 dest_x, dest_y, dest_width, dest_height, offset_x, offset_y,
85 scale_x, scale_y, (PixopsInterpType)interp_type);
89 * gdk_pixbuf_composite:
91 * @dest: the #GdkPixbuf into which to render the results
92 * @dest_x: the left coordinate for region to render
93 * @dest_y: the top coordinate for region to render
94 * @dest_width: the width of the region to render
95 * @dest_height: the height of the region to render
96 * @offset_x: the offset in the X direction (currently rounded to an integer)
97 * @offset_y: the offset in the Y direction (currently rounded to an integer)
98 * @scale_x: the scale factor in the X direction
99 * @scale_y: the scale factor in the Y direction
100 * @interp_type: the interpolation type for the transformation.
101 * @overall_alpha: overall alpha for source image (0..255)
103 * Creates a transformation of the source image @src by scaling by
104 * @scale_x and @scale_y then translating by @offset_x and @offset_y.
105 * This gives an image in the coordinates of the destination pixbuf.
106 * The rectangle (@dest_x, @dest_y, @dest_width, @dest_height)
107 * is then composited onto the corresponding rectangle of the
108 * original destination image.
110 * When the destination rectangle contains parts not in the source
111 * image, the data at the edges of the source image is replicated
114 * <figure id="pixbuf-composite-diagram">
115 * <title>Compositing of pixbufs</title>
116 * <graphic fileref="composite.png" format="PNG"/>
120 gdk_pixbuf_composite (const GdkPixbuf *src,
130 GdkInterpType interp_type,
133 g_return_if_fail (GDK_IS_PIXBUF (src));
134 g_return_if_fail (GDK_IS_PIXBUF (dest));
135 g_return_if_fail (dest_x >= 0 && dest_x + dest_width <= dest->width);
136 g_return_if_fail (dest_y >= 0 && dest_y + dest_height <= dest->height);
137 g_return_if_fail (overall_alpha >= 0 && overall_alpha <= 255);
139 offset_x = floor (offset_x + 0.5);
140 offset_y = floor (offset_y + 0.5);
142 _pixops_composite (dest->pixels, dest->width, dest->height, dest->rowstride,
143 dest->n_channels, dest->has_alpha, src->pixels,
144 src->width, src->height, src->rowstride, src->n_channels,
145 src->has_alpha, dest_x, dest_y, dest_width, dest_height,
146 offset_x, offset_y, scale_x, scale_y,
147 (PixopsInterpType)interp_type, overall_alpha);
151 * gdk_pixbuf_composite_color:
153 * @dest: the #GdkPixbuf into which to render the results
154 * @dest_x: the left coordinate for region to render
155 * @dest_y: the top coordinate for region to render
156 * @dest_width: the width of the region to render
157 * @dest_height: the height of the region to render
158 * @offset_x: the offset in the X direction (currently rounded to an integer)
159 * @offset_y: the offset in the Y direction (currently rounded to an integer)
160 * @scale_x: the scale factor in the X direction
161 * @scale_y: the scale factor in the Y direction
162 * @interp_type: the interpolation type for the transformation.
163 * @overall_alpha: overall alpha for source image (0..255)
164 * @check_x: the X offset for the checkboard (origin of checkboard is at -@check_x, -@check_y)
165 * @check_y: the Y offset for the checkboard
166 * @check_size: the size of checks in the checkboard (must be a power of two)
167 * @color1: the color of check at upper left
168 * @color2: the color of the other check
170 * Creates a transformation of the source image @src by scaling by
171 * @scale_x and @scale_y then translating by @offset_x and @offset_y,
172 * then composites the rectangle (@dest_x ,@dest_y, @dest_width,
173 * @dest_height) of the resulting image with a checkboard of the
174 * colors @color1 and @color2 and renders it onto the destination
177 * See gdk_pixbuf_composite_color_simple() for a simpler variant of this
178 * function suitable for many tasks.
182 gdk_pixbuf_composite_color (const GdkPixbuf *src,
192 GdkInterpType interp_type,
200 g_return_if_fail (GDK_IS_PIXBUF (src));
201 g_return_if_fail (GDK_IS_PIXBUF (dest));
202 g_return_if_fail (dest_x >= 0 && dest_x + dest_width <= dest->width);
203 g_return_if_fail (dest_y >= 0 && dest_y + dest_height <= dest->height);
204 g_return_if_fail (overall_alpha >= 0 && overall_alpha <= 255);
206 offset_x = floor (offset_x + 0.5);
207 offset_y = floor (offset_y + 0.5);
209 _pixops_composite_color (dest->pixels, dest_width, dest_height,
210 dest->rowstride, dest->n_channels, dest->has_alpha,
211 src->pixels, src->width, src->height,
212 src->rowstride, src->n_channels, src->has_alpha,
213 dest_x, dest_y, dest_width, dest_height, offset_x,
214 offset_y, scale_x, scale_y,
215 (PixopsInterpType)interp_type, overall_alpha,
216 check_x, check_y, check_size, color1, color2);
220 * gdk_pixbuf_scale_simple:
222 * @dest_width: the width of destination image
223 * @dest_height: the height of destination image
224 * @interp_type: the interpolation type for the transformation.
226 * Create a new #GdkPixbuf containing a copy of @src scaled to
227 * @dest_width x @dest_height. Leaves @src unaffected. @interp_type
228 * should be #GDK_INTERP_NEAREST if you want maximum speed (but when
229 * scaling down #GDK_INTERP_NEAREST is usually unusably ugly). The
230 * default @interp_type should be #GDK_INTERP_BILINEAR which offers
231 * reasonable quality and speed.
233 * You can scale a sub-portion of @src by creating a sub-pixbuf
234 * pointing into @src; see gdk_pixbuf_new_subpixbuf().
236 * For more complicated scaling/compositing see gdk_pixbuf_scale()
237 * and gdk_pixbuf_composite().
239 * Return value: the new #GdkPixbuf, or %NULL if not enough memory could be
243 gdk_pixbuf_scale_simple (const GdkPixbuf *src,
246 GdkInterpType interp_type)
250 g_return_val_if_fail (GDK_IS_PIXBUF (src), NULL);
251 g_return_val_if_fail (dest_width > 0, NULL);
252 g_return_val_if_fail (dest_height > 0, NULL);
254 dest = gdk_pixbuf_new (GDK_COLORSPACE_RGB, src->has_alpha, 8, dest_width, dest_height);
258 gdk_pixbuf_scale (src, dest, 0, 0, dest_width, dest_height, 0, 0,
259 (double) dest_width / src->width,
260 (double) dest_height / src->height,
267 * gdk_pixbuf_composite_color_simple:
269 * @dest_width: the width of destination image
270 * @dest_height: the height of destination image
271 * @interp_type: the interpolation type for the transformation.
272 * @overall_alpha: overall alpha for source image (0..255)
273 * @check_size: the size of checks in the checkboard (must be a power of two)
274 * @color1: the color of check at upper left
275 * @color2: the color of the other check
277 * Creates a new #GdkPixbuf by scaling @src to @dest_width x
278 * @dest_height and compositing the result with a checkboard of colors
279 * @color1 and @color2.
281 * Return value: the new #GdkPixbuf, or %NULL if not enough memory could be
285 gdk_pixbuf_composite_color_simple (const GdkPixbuf *src,
288 GdkInterpType interp_type,
296 g_return_val_if_fail (GDK_IS_PIXBUF (src), NULL);
297 g_return_val_if_fail (dest_width > 0, NULL);
298 g_return_val_if_fail (dest_height > 0, NULL);
299 g_return_val_if_fail (overall_alpha >= 0 && overall_alpha <= 255, NULL);
301 dest = gdk_pixbuf_new (GDK_COLORSPACE_RGB, src->has_alpha, 8, dest_width, dest_height);
305 gdk_pixbuf_composite_color (src, dest, 0, 0, dest_width, dest_height, 0, 0,
306 (double) dest_width / src->width,
307 (double) dest_height / src->height,
308 interp_type, overall_alpha, 0, 0, check_size, color1, color2);
313 #define OFFSET(pb, x, y) ((x) * (pb)->n_channels + (y) * (pb)->rowstride)
316 * gdk_pixbuf_rotate_simple:
318 * @angle: the angle to rotate by
320 * Rotates a pixbuf by a multiple of 90 degrees, and returns the
321 * result in a new pixbuf.
323 * Returns: the new #GdkPixbuf, or %NULL if not enough memory could be
329 gdk_pixbuf_rotate_simple (const GdkPixbuf *src,
330 GdkPixbufRotation angle)
339 dest = gdk_pixbuf_copy (src);
342 dest = gdk_pixbuf_new (src->colorspace,
344 src->bits_per_sample,
350 for (y = 0; y < src->height; y++)
352 for (x = 0; x < src->width; x++)
354 p = src->pixels + OFFSET (src, x, y);
355 q = dest->pixels + OFFSET (dest, y, src->width - x - 1);
356 memcpy (q, p, dest->n_channels);
361 dest = gdk_pixbuf_new (src->colorspace,
363 src->bits_per_sample,
369 for (y = 0; y < src->height; y++)
371 for (x = 0; x < src->width; x++)
373 p = src->pixels + OFFSET (src, x, y);
374 q = dest->pixels + OFFSET (dest, src->width - x - 1, src->height - y - 1);
375 memcpy (q, p, dest->n_channels);
380 dest = gdk_pixbuf_new (src->colorspace,
382 src->bits_per_sample,
388 for (y = 0; y < src->height; y++)
390 for (x = 0; x < src->width; x++)
392 p = src->pixels + OFFSET (src, x, y);
393 q = dest->pixels + OFFSET (dest, src->height - y - 1, x);
394 memcpy (q, p, dest->n_channels);
400 g_warning ("gdk_pixbuf_rotate_simple() can only rotate "
401 "by multiples of 90 degrees");
402 g_assert_not_reached ();
411 * @horizontal: %TRUE to flip horizontally, %FALSE to flip vertically
413 * Flips a pixbuf horizontally or vertically and returns the
414 * result in a new pixbuf.
416 * Returns: the new #GdkPixbuf, or %NULL if not enough memory could be
422 gdk_pixbuf_flip (const GdkPixbuf *src,
429 dest = gdk_pixbuf_new (src->colorspace,
431 src->bits_per_sample,
437 if (!horizontal) /* flip vertical */
439 for (y = 0; y < dest->height; y++)
441 p = src->pixels + OFFSET (src, 0, y);
442 q = dest->pixels + OFFSET (dest, 0, dest->height - y - 1);
443 memcpy (q, p, dest->rowstride);
446 else /* flip horizontal */
448 for (y = 0; y < dest->height; y++)
450 for (x = 0; x < dest->width; x++)
452 p = src->pixels + OFFSET (src, x, y);
453 q = dest->pixels + OFFSET (dest, dest->width - x - 1, y);
454 memcpy (q, p, dest->n_channels);
462 #define __GDK_PIXBUF_SCALE_C__
463 #include "gdk-pixbuf-aliasdef.c"