]> git.ipfire.org Git - thirdparty/cups.git/blame - filter/image-zoom.c
Update copyright notices, addresses, etc.
[thirdparty/cups.git] / filter / image-zoom.c
CommitLineData
720086df 1/*
c9d3f842 2 * "$Id$"
720086df 3 *
ed19bd98 4 * Image zoom routines for the Common UNIX Printing System (CUPS).
720086df 5 *
c9d3f842 6 * Copyright 1993-2005 by Easy Software Products.
720086df 7 *
ed19bd98 8 * These coded instructions, statements, and computer programs are the
9 * property of Easy Software Products and are protected by Federal
10 * copyright law. Distribution and use rights are outlined in the file
11 * "LICENSE.txt" which should have been included with this file. If this
12 * file is missing or damaged please contact Easy Software Products
13 * at:
14 *
15 * Attn: CUPS Licensing Information
16 * Easy Software Products
17 * 44141 Airport View Drive, Suite 204
c9d3f842 18 * Hollywood, Maryland 20636 USA
ed19bd98 19 *
9639c4de 20 * Voice: (301) 373-9600
ed19bd98 21 * EMail: cups-info@cups.org
22 * WWW: http://www.cups.org
720086df 23 *
dab1a4d8 24 * This file is subject to the Apple OS-Developed Software exception.
25 *
720086df 26 * Contents:
27 *
28 * ImageZoomAlloc() - Allocate a pixel zoom record...
29 * ImageZoomFill() - Fill a zoom record with image data utilizing bilinear
30 * interpolation.
31 * ImageZoomQFill() - Fill a zoom record quickly using nearest-neighbor
32 * sampling.
33 * ImageZoomFree() - Free a zoom record...
720086df 34 */
35
36/*
37 * Include necessary headers...
38 */
39
40#include "image.h"
41
42
43/*
44 * 'ZoomAlloc()' - Allocate a pixel zoom record...
45 */
46
47izoom_t *
f9ccdd05 48ImageZoomAlloc(image_t *img, /* I - Image to zoom */
720086df 49 int x0, /* I - Upper-lefthand corner */
50 int y0, /* I - ... */
51 int x1, /* I - Lower-righthand corner */
52 int y1, /* I - ... */
53 int xsize, /* I - Final width of image */
54 int ysize, /* I - Final height of image */
55 int rotated) /* I - Non-zero if image is rotated 90 degs */
56{
57 izoom_t *z; /* New zoom record */
a05e4307 58 int flip; /* Flip on X axis? */
720086df 59
60
099f4d77 61 if (xsize > IMAGE_MAX_WIDTH ||
62 ysize > IMAGE_MAX_HEIGHT ||
63 (x1 - x0) > IMAGE_MAX_WIDTH ||
64 (y1 - y0) > IMAGE_MAX_HEIGHT)
65 return (NULL); /* Protect against integer overflow */
66
720086df 67 if ((z = (izoom_t *)calloc(1, sizeof(izoom_t))) == NULL)
68 return (NULL);
69
f9ccdd05 70 z->img = img;
71 z->row = 0;
72 z->depth = ImageGetDepth(img);
73 z->rotated = rotated;
720086df 74
a05e4307 75 if (xsize < 0)
76 {
77 flip = 1;
78 xsize = -xsize;
79 }
80 else
81 {
82 flip = 0;
83 }
84
720086df 85 if (rotated)
86 {
f9ccdd05 87 z->xorig = x1;
88 z->yorig = y0;
89 z->width = y1 - y0 + 1;
90 z->height = x1 - x0 + 1;
8db57375 91 z->xsize = xsize;
92 z->ysize = ysize;
f9ccdd05 93 z->xmod = z->width % z->xsize;
94 z->xstep = z->width / z->xsize;
95 z->xincr = 1;
96 z->ymod = z->height % z->ysize;
97 z->ystep = z->height / z->ysize;
98 z->yincr = 1;
99 z->instep = z->xstep * z->depth;
100 z->inincr = z->xincr * z->depth;
101
102 if (z->width < img->ysize)
103 z->xmax = z->width;
720086df 104 else
f9ccdd05 105 z->xmax = z->width - 1;
720086df 106
f9ccdd05 107 if (z->height < img->xsize)
108 z->ymax = z->height;
720086df 109 else
f9ccdd05 110 z->ymax = z->height - 1;
720086df 111 }
112 else
113 {
f9ccdd05 114 z->xorig = x0;
115 z->yorig = y0;
116 z->width = x1 - x0 + 1;
117 z->height = y1 - y0 + 1;
118 z->xsize = xsize;
119 z->ysize = ysize;
120 z->xmod = z->width % z->xsize;
121 z->xstep = z->width / z->xsize;
122 z->xincr = 1;
123 z->ymod = z->height % z->ysize;
124 z->ystep = z->height / z->ysize;
125 z->yincr = 1;
126 z->instep = z->xstep * z->depth;
127 z->inincr = z->xincr * z->depth;
128
129 if (z->width < img->xsize)
130 z->xmax = z->width;
131 else
132 z->xmax = z->width - 1;
720086df 133
f9ccdd05 134 if (z->height < img->ysize)
135 z->ymax = z->height;
136 else
137 z->ymax = z->height - 1;
ed19bd98 138 }
720086df 139
a05e4307 140 if (flip)
141 {
142 z->instep = -z->instep;
143 z->inincr = -z->inincr;
144 }
145
f9ccdd05 146 if ((z->rows[0] = (ib_t *)malloc(z->xsize * z->depth)) == NULL)
147 {
148 free(z);
149 return (NULL);
ed19bd98 150 }
720086df 151
f9ccdd05 152 if ((z->rows[1] = (ib_t *)malloc(z->xsize * z->depth)) == NULL)
153 {
154 free(z->rows[0]);
155 free(z);
156 return (NULL);
ed19bd98 157 }
720086df 158
f9ccdd05 159 if ((z->in = (ib_t *)malloc(z->width * z->depth)) == NULL)
160 {
161 free(z->rows[0]);
162 free(z->rows[1]);
163 free(z);
164 return (NULL);
ed19bd98 165 }
720086df 166
167 return (z);
168}
169
170
171/*
172 * 'ImageZoomFill()' - Fill a zoom record with image data utilizing bilinear
173 * interpolation.
174 */
175
176void
177ImageZoomFill(izoom_t *z, /* I - Zoom record to fill */
6de9968b 178 int iy) /* I - Zoom image row */
720086df 179{
f9ccdd05 180 ib_t *r, /* Row pointer */
181 *inptr; /* Pixel pointer */
182 int xerr0, /* X error counter */
183 xerr1; /* ... */
184 int ix,
185 x,
186 count,
187 z_depth,
188 z_xstep,
189 z_xincr,
190 z_instep,
191 z_inincr,
192 z_xmax,
193 z_xmod,
194 z_xsize;
720086df 195
196
197 if (iy > z->ymax)
198 iy = z->ymax;
199
200 z->row ^= 1;
201
f9ccdd05 202 z_depth = z->depth;
720086df 203 z_xsize = z->xsize;
f9ccdd05 204 z_xmax = z->xmax;
205 z_xmod = z->xmod;
206 z_xstep = z->xstep;
207 z_xincr = z->xincr;
208 z_instep = z->instep;
209 z_inincr = z->inincr;
210
211 if (z->rotated)
212 ImageGetCol(z->img, z->xorig - iy, z->yorig, z->width, z->in);
213 else
214 ImageGetRow(z->img, z->xorig, z->yorig + iy, z->width, z->in);
215
f9ccdd05 216 if (z_inincr < 0)
217 inptr = z->in + (z->width - 1) * z_depth;
218 else
219 inptr = z->in;
720086df 220
f9ccdd05 221 for (x = z_xsize, xerr0 = z_xsize, xerr1 = 0, ix = 0, r = z->rows[z->row];
222 x > 0;
223 x --)
720086df 224 {
f9ccdd05 225 if (ix < z_xmax)
226 {
227 for (count = 0; count < z_depth; count ++)
228 *r++ = (inptr[count] * xerr0 + inptr[z_depth + count] * xerr1) / z_xsize;
229 }
230 else
231 {
232 for (count = 0; count < z_depth; count ++)
233 *r++ = inptr[count];
ed19bd98 234 }
720086df 235
f9ccdd05 236 ix += z_xstep;
237 inptr += z_instep;
238 xerr0 -= z_xmod;
239 xerr1 += z_xmod;
240
241 if (xerr0 <= 0)
720086df 242 {
f9ccdd05 243 xerr0 += z_xsize;
244 xerr1 -= z_xsize;
245 ix += z_xincr;
246 inptr += z_inincr;
ed19bd98 247 }
248 }
720086df 249}
250
251
252/*
253 * 'ImageZoomQFill()' - Fill a zoom record quickly using nearest-neighbor sampling.
254 */
255
256void
257ImageZoomQFill(izoom_t *z, /* I - Zoom record to fill */
6de9968b 258 int iy) /* I - Zoom image row */
720086df 259{
f9ccdd05 260 ib_t *r, /* Row pointer */
261 *inptr; /* Pixel pointer */
262 int xerr0; /* X error counter */
263 int ix,
264 x,
265 count,
266 z_depth,
267 z_xstep,
268 z_xincr,
269 z_instep,
270 z_inincr,
f9ccdd05 271 z_xmod,
272 z_xsize;
720086df 273
274
275 if (iy > z->ymax)
276 iy = z->ymax;
277
f9ccdd05 278 z->row ^= 1;
720086df 279
f9ccdd05 280 z_depth = z->depth;
720086df 281 z_xsize = z->xsize;
f9ccdd05 282 z_xmod = z->xmod;
283 z_xstep = z->xstep;
284 z_xincr = z->xincr;
285 z_instep = z->instep;
286 z_inincr = z->inincr;
287
288 if (z->rotated)
289 ImageGetCol(z->img, z->xorig - iy, z->yorig, z->width, z->in);
290 else
291 ImageGetRow(z->img, z->xorig, z->yorig + iy, z->width, z->in);
292
f9ccdd05 293 if (z_inincr < 0)
294 inptr = z->in + (z->width - 1) * z_depth;
295 else
296 inptr = z->in;
297
298 for (x = z_xsize, xerr0 = z_xsize, ix = 0, r = z->rows[z->row];
299 x > 0;
300 x --)
720086df 301 {
f9ccdd05 302 for (count = 0; count < z_depth; count ++)
303 *r++ = inptr[count];
304
305 ix += z_xstep;
306 inptr += z_instep;
307 xerr0 -= z_xmod;
720086df 308
f9ccdd05 309 if (xerr0 <= 0)
720086df 310 {
f9ccdd05 311 xerr0 += z_xsize;
312 ix += z_xincr;
313 inptr += z_inincr;
ed19bd98 314 }
315 }
720086df 316}
317
318
319/*
320 * 'ImageZoomFree()' - Free a zoom record...
321 */
322
323void
324ImageZoomFree(izoom_t *z) /* I - Zoom record to free */
325{
326 free(z->rows[0]);
327 free(z->rows[1]);
f9ccdd05 328 free(z->in);
720086df 329 free(z);
330}
331
332
333/*
c9d3f842 334 * End of "$Id$".
720086df 335 */