Add powerbox hook
[gtk-with-powerbox.git] / gdk-pixbuf / gdk-pixbuf-scale.c
blob4ede8d868a930129648a6ec5acbaccf64a9a7c9e
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.
23 #include "config.h"
24 #include <math.h>
25 #include <string.h>
26 #include "gdk-pixbuf-private.h"
27 #include "pixops/pixops.h"
28 #include "gdk-pixbuf-alias.h"
32 /**
33 * gdk_pixbuf_scale:
34 * @src: a #GdkPixbuf
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.
59 **/
60 void
61 gdk_pixbuf_scale (const GdkPixbuf *src,
62 GdkPixbuf *dest,
63 int dest_x,
64 int dest_y,
65 int dest_width,
66 int dest_height,
67 double offset_x,
68 double offset_y,
69 double scale_x,
70 double scale_y,
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);
88 /**
89 * gdk_pixbuf_composite:
90 * @src: a #GdkPixbuf
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
112 * to infinity.
114 * <figure id="pixbuf-composite-diagram">
115 * <title>Compositing of pixbufs</title>
116 * <graphic fileref="composite.png" format="PNG"/>
117 * </figure>
119 void
120 gdk_pixbuf_composite (const GdkPixbuf *src,
121 GdkPixbuf *dest,
122 int dest_x,
123 int dest_y,
124 int dest_width,
125 int dest_height,
126 double offset_x,
127 double offset_y,
128 double scale_x,
129 double scale_y,
130 GdkInterpType interp_type,
131 int overall_alpha)
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:
152 * @src: a #GdkPixbuf
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
175 * image.
177 * See gdk_pixbuf_composite_color_simple() for a simpler variant of this
178 * function suitable for many tasks.
181 void
182 gdk_pixbuf_composite_color (const GdkPixbuf *src,
183 GdkPixbuf *dest,
184 int dest_x,
185 int dest_y,
186 int dest_width,
187 int dest_height,
188 double offset_x,
189 double offset_y,
190 double scale_x,
191 double scale_y,
192 GdkInterpType interp_type,
193 int overall_alpha,
194 int check_x,
195 int check_y,
196 int check_size,
197 guint32 color1,
198 guint32 color2)
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:
221 * @src: a #GdkPixbuf
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
240 * allocated for it.
242 GdkPixbuf *
243 gdk_pixbuf_scale_simple (const GdkPixbuf *src,
244 int dest_width,
245 int dest_height,
246 GdkInterpType interp_type)
248 GdkPixbuf *dest;
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);
255 if (!dest)
256 return NULL;
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,
261 interp_type);
263 return dest;
267 * gdk_pixbuf_composite_color_simple:
268 * @src: a #GdkPixbuf
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
282 * allocated for it.
284 GdkPixbuf *
285 gdk_pixbuf_composite_color_simple (const GdkPixbuf *src,
286 int dest_width,
287 int dest_height,
288 GdkInterpType interp_type,
289 int overall_alpha,
290 int check_size,
291 guint32 color1,
292 guint32 color2)
294 GdkPixbuf *dest;
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);
302 if (!dest)
303 return NULL;
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);
310 return dest;
313 #define OFFSET(pb, x, y) ((x) * (pb)->n_channels + (y) * (pb)->rowstride)
316 * gdk_pixbuf_rotate_simple:
317 * @src: a #GdkPixbuf
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
324 * allocated for it.
326 * Since: 2.6
328 GdkPixbuf *
329 gdk_pixbuf_rotate_simple (const GdkPixbuf *src,
330 GdkPixbufRotation angle)
332 GdkPixbuf *dest;
333 guchar *p, *q;
334 gint x, y;
336 switch (angle % 360)
338 case 0:
339 dest = gdk_pixbuf_copy (src);
340 break;
341 case 90:
342 dest = gdk_pixbuf_new (src->colorspace,
343 src->has_alpha,
344 src->bits_per_sample,
345 src->height,
346 src->width);
347 if (!dest)
348 return NULL;
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);
359 break;
360 case 180:
361 dest = gdk_pixbuf_new (src->colorspace,
362 src->has_alpha,
363 src->bits_per_sample,
364 src->width,
365 src->height);
366 if (!dest)
367 return NULL;
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);
378 break;
379 case 270:
380 dest = gdk_pixbuf_new (src->colorspace,
381 src->has_alpha,
382 src->bits_per_sample,
383 src->height,
384 src->width);
385 if (!dest)
386 return NULL;
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);
397 break;
398 default:
399 dest = NULL;
400 g_warning ("gdk_pixbuf_rotate_simple() can only rotate "
401 "by multiples of 90 degrees");
402 g_assert_not_reached ();
405 return dest;
409 * gdk_pixbuf_flip:
410 * @src: a #GdkPixbuf
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
417 * allocated for it.
419 * Since: 2.6
421 GdkPixbuf *
422 gdk_pixbuf_flip (const GdkPixbuf *src,
423 gboolean horizontal)
425 GdkPixbuf *dest;
426 guchar *p, *q;
427 gint x, y;
429 dest = gdk_pixbuf_new (src->colorspace,
430 src->has_alpha,
431 src->bits_per_sample,
432 src->width,
433 src->height);
434 if (!dest)
435 return NULL;
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);
459 return dest;
462 #define __GDK_PIXBUF_SCALE_C__
463 #include "gdk-pixbuf-aliasdef.c"