]> Pileus Git - ~andy/gtk/blob - gdk-pixbuf/gdk-pixbuf-scale.c
GTK+-2.0.0 rc1
[~andy/gtk] / gdk-pixbuf / gdk-pixbuf-scale.c
1 /* GdkPixbuf library - Scaling and compositing functions
2  *
3  * Copyright (C) 1999 The Free Software Foundation
4  *
5  * Author: Owen Taylor <otaylor@redhat.com>
6  *
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.
11  *
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.
16  *
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.
21  */
22
23 #include <config.h>
24 #include <math.h>
25 #include "gdk-pixbuf-private.h"
26 #include "pixops/pixops.h"
27
28 \f
29
30 /**
31  * gdk_pixbuf_scale:
32  * @src: a #GdkPixbuf
33  * @dest: the #GdkPixbuf into which to render the results
34  * @dest_x: the left coordinate for region to render
35  * @dest_y: the top coordinate for region to render
36  * @dest_width: the width of the region to render
37  * @dest_height: the height of the region to render
38  * @offset_x: the offset in the X direction (currently rounded to an integer)
39  * @offset_y: the offset in the Y direction (currently rounded to an integer)
40  * @scale_x: the scale factor in the X direction
41  * @scale_y: the scale factor in the Y direction
42  * @interp_type: the interpolation type for the transformation.
43  * 
44  * Creates a transformation of the source image @src by scaling by
45  * @scale_x and @scale_y then translating by @offset_x and @offset_y,
46  * then renders the rectangle (@dest_x, @dest_y, @dest_width,
47  * @dest_height) of the resulting image onto the destination image
48  * replacing the previous contents.
49  *
50  * Try to use gdk_pixbuf_scale_simple() first, this function is
51  * the industrial-strength power tool you can fall back to if
52  * gdk_pixbuf_scale_simple() isn't powerful enough.
53  **/
54 void
55 gdk_pixbuf_scale (const GdkPixbuf *src,
56                   GdkPixbuf       *dest,
57                   int              dest_x,
58                   int              dest_y,
59                   int              dest_width,
60                   int              dest_height,
61                   double           offset_x,
62                   double           offset_y,
63                   double           scale_x,
64                   double           scale_y,
65                   GdkInterpType    interp_type)
66 {
67   g_return_if_fail (src != NULL);
68   g_return_if_fail (dest != NULL);
69   g_return_if_fail (dest_x >= 0 && dest_x + dest_width <= dest->width);
70   g_return_if_fail (dest_y >= 0 && dest_y + dest_height <= dest->height);
71
72   offset_x = floor (offset_x + 0.5);
73   offset_y = floor (offset_y + 0.5);
74   
75   pixops_scale (dest->pixels + dest_y * dest->rowstride + dest_x * dest->n_channels,
76                 dest_x - offset_x, dest_y - offset_y, 
77                 dest_x + dest_width - offset_x, dest_y + dest_height - offset_y,
78                 dest->rowstride, dest->n_channels, dest->has_alpha,
79                 src->pixels, src->width, src->height,
80                 src->rowstride, src->n_channels, src->has_alpha,
81                 scale_x, scale_y, interp_type);
82 }
83
84 /**
85  * gdk_pixbuf_composite:
86  * @src: a #GdkPixbuf
87  * @dest: the #GdkPixbuf into which to render the results
88  * @dest_x: the left coordinate for region to render
89  * @dest_y: the top coordinate for region to render
90  * @dest_width: the width of the region to render
91  * @dest_height: the height of the region to render
92  * @offset_x: the offset in the X direction (currently rounded to an integer)
93  * @offset_y: the offset in the Y direction (currently rounded to an integer)
94  * @scale_x: the scale factor in the X direction
95  * @scale_y: the scale factor in the Y direction
96  * @interp_type: the interpolation type for the transformation.
97  * @overall_alpha: overall alpha for source image (0..255)
98  * 
99  * Creates a transformation of the source image @src by scaling by
100  * @scale_x and @scale_y then translating by @offset_x and @offset_y,
101  * then composites the rectangle (@dest_x, @dest_y, @dest_width,
102  * @dest_height) of the resulting image onto the destination image.
103  **/
104 void
105 gdk_pixbuf_composite (const GdkPixbuf *src,
106                       GdkPixbuf       *dest,
107                       int              dest_x,
108                       int              dest_y,
109                       int              dest_width,
110                       int              dest_height,
111                       double           offset_x,
112                       double           offset_y,
113                       double           scale_x,
114                       double           scale_y,
115                       GdkInterpType    interp_type,
116                       int              overall_alpha)
117 {
118   g_return_if_fail (src != NULL);
119   g_return_if_fail (dest != NULL);
120   g_return_if_fail (dest_x >= 0 && dest_x + dest_width <= dest->width);
121   g_return_if_fail (dest_y >= 0 && dest_y + dest_height <= dest->height);
122   g_return_if_fail (overall_alpha >= 0 && overall_alpha <= 255);
123
124   offset_x = floor (offset_x + 0.5);
125   offset_y = floor (offset_y + 0.5);
126   pixops_composite (dest->pixels + dest_y * dest->rowstride + dest_x * dest->n_channels,
127                     dest_x - offset_x, dest_y - offset_y, 
128                     dest_x + dest_width - offset_x, dest_y + dest_height - offset_y,
129                     dest->rowstride, dest->n_channels, dest->has_alpha,
130                     src->pixels, src->width, src->height,
131                     src->rowstride, src->n_channels, src->has_alpha,
132                     scale_x, scale_y, interp_type, overall_alpha);
133 }
134
135 /**
136  * gdk_pixbuf_composite_color:
137  * @src: a #GdkPixbuf
138  * @dest: the #GdkPixbuf into which to render the results
139  * @dest_x: the left coordinate for region to render
140  * @dest_y: the top coordinate for region to render
141  * @dest_width: the width of the region to render
142  * @dest_height: the height of the region to render
143  * @offset_x: the offset in the X direction (currently rounded to an integer)
144  * @offset_y: the offset in the Y direction (currently rounded to an integer)
145  * @scale_x: the scale factor in the X direction
146  * @scale_y: the scale factor in the Y direction
147  * @interp_type: the interpolation type for the transformation.
148  * @overall_alpha: overall alpha for source image (0..255)
149  * @check_x: the X offset for the checkboard (origin of checkboard is at -@check_x, -@check_y)
150  * @check_y: the Y offset for the checkboard 
151  * @check_size: the size of checks in the checkboard (must be a power of two)
152  * @color1: the color of check at upper left
153  * @color2: the color of the other check
154  * 
155  * Creates a transformation of the source image @src by scaling by
156  * @scale_x and @scale_y then translating by @offset_x and @offset_y,
157  * then composites the rectangle (@dest_x ,@dest_y, @dest_width,
158  * @dest_height) of the resulting image with a checkboard of the
159  * colors @color1 and @color2 and renders it onto the destination
160  * image.
161  *
162  * See gdk_pixbuf_composite_color_simple() for a simpler variant of this
163  * function suitable for many tasks.
164  * 
165  **/
166 void
167 gdk_pixbuf_composite_color (const GdkPixbuf *src,
168                             GdkPixbuf       *dest,
169                             int              dest_x,
170                             int              dest_y,
171                             int              dest_width,
172                             int              dest_height,
173                             double           offset_x,
174                             double           offset_y,
175                             double           scale_x,
176                             double           scale_y,
177                             GdkInterpType    interp_type,
178                             int              overall_alpha,
179                             int              check_x,
180                             int              check_y,
181                             int              check_size,
182                             guint32          color1,
183                             guint32          color2)
184 {
185   g_return_if_fail (src != NULL);
186   g_return_if_fail (dest != NULL);
187   g_return_if_fail (dest_x >= 0 && dest_x + dest_width <= dest->width);
188   g_return_if_fail (dest_y >= 0 && dest_y + dest_height <= dest->height);
189   g_return_if_fail (overall_alpha >= 0 && overall_alpha <= 255);
190
191   offset_x = floor (offset_x + 0.5);
192   offset_y = floor (offset_y + 0.5);
193   
194   pixops_composite_color (dest->pixels + dest_y * dest->rowstride + dest_x * dest->n_channels,
195                           dest_x - offset_x, dest_y - offset_y, 
196                           dest_x + dest_width - offset_x, dest_y + dest_height - offset_y,
197                           dest->rowstride, dest->n_channels, dest->has_alpha,
198                           src->pixels, src->width, src->height,
199                           src->rowstride, src->n_channels, src->has_alpha,
200                           scale_x, scale_y, interp_type, overall_alpha, check_x, check_y,
201                           check_size, color1, color2);
202 }
203
204 /**
205  * gdk_pixbuf_scale_simple:
206  * @src: a #GdkPixbuf
207  * @dest_width: the width of destination image
208  * @dest_height: the height of destination image
209  * @interp_type: the interpolation type for the transformation.
210  *
211  * Create a new #GdkPixbuf containing a copy of @src scaled to
212  * @dest_width x @dest_height. Leaves @src unaffected.  @interp_type
213  * should be #GDK_INTERP_NEAREST if you want maximum speed (but when
214  * scaling down #GDK_INTERP_NEAREST is usually unusably ugly).  The
215  * default @interp_type should be #GDK_INTERP_BILINEAR which offers
216  * reasonable quality and speed.
217  *
218  * You can scale a sub-portion of @src by creating a sub-pixbuf
219  * pointing into @src; see gdk_pixbuf_new_subpixbuf().
220  *
221  * For more complicated scaling/compositing see gdk_pixbuf_scale()
222  * and gdk_pixbuf_composite().
223  * 
224  * Return value: the new #GdkPixbuf, or %NULL if not enough memory could be
225  * allocated for it.
226  **/
227 GdkPixbuf *
228 gdk_pixbuf_scale_simple (const GdkPixbuf *src,
229                          int              dest_width,
230                          int              dest_height,
231                          GdkInterpType    interp_type)
232 {
233   GdkPixbuf *dest;
234
235   g_return_val_if_fail (src != NULL, NULL);
236   g_return_val_if_fail (dest_width > 0, NULL);
237   g_return_val_if_fail (dest_height > 0, NULL);
238
239   dest = gdk_pixbuf_new (GDK_COLORSPACE_RGB, src->has_alpha, 8, dest_width, dest_height);
240   if (!dest)
241     return NULL;
242
243   gdk_pixbuf_scale (src, dest,  0, 0, dest_width, dest_height, 0, 0,
244                     (double) dest_width / src->width,
245                     (double) dest_height / src->height,
246                     interp_type);
247
248   return dest;
249 }
250
251 /**
252  * gdk_pixbuf_composite_color_simple:
253  * @src: a #GdkPixbuf
254  * @dest_width: the width of destination image
255  * @dest_height: the height of destination image
256  * @interp_type: the interpolation type for the transformation.
257  * @overall_alpha: overall alpha for source image (0..255)
258  * @check_size: the size of checks in the checkboard (must be a power of two)
259  * @color1: the color of check at upper left
260  * @color2: the color of the other check
261  * 
262  * Creates a new #GdkPixbuf by scaling @src to @dest_width x
263  * @dest_height and compositing the result with a checkboard of colors
264  * @color1 and @color2.
265  * 
266  * Return value: the new #GdkPixbuf, or %NULL if not enough memory could be
267  * allocated for it.
268  **/
269 GdkPixbuf *
270 gdk_pixbuf_composite_color_simple (const GdkPixbuf *src,
271                                    int              dest_width,
272                                    int              dest_height,
273                                    GdkInterpType    interp_type,
274                                    int              overall_alpha,
275                                    int              check_size,
276                                    guint32          color1,
277                                    guint32          color2)
278 {
279   GdkPixbuf *dest;
280
281   g_return_val_if_fail (src != NULL, NULL);
282   g_return_val_if_fail (dest_width > 0, NULL);
283   g_return_val_if_fail (dest_height > 0, NULL);
284   g_return_val_if_fail (overall_alpha >= 0 && overall_alpha <= 255, NULL);
285
286   dest = gdk_pixbuf_new (GDK_COLORSPACE_RGB, src->has_alpha, 8, dest_width, dest_height);
287   if (!dest)
288     return NULL;
289
290   gdk_pixbuf_composite_color (src, dest, 0, 0, dest_width, dest_height, 0, 0,
291                               (double) dest_width / src->width,
292                               (double) dest_height / src->height,
293                               interp_type, overall_alpha, 0, 0, check_size, color1, color2);
294
295   return dest;
296 }