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 (src
!= NULL
);
74 g_return_if_fail (dest
!= NULL
);
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 (src
!= NULL
);
134 g_return_if_fail (dest
!= NULL
);
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 (src
!= NULL
);
201 g_return_if_fail (dest
!= NULL
);
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 (src
!= NULL
, 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 (src
!= NULL
, 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"