Leptonica 1.82.0
Image processing and image analysis suite
pixtiling.c
Go to the documentation of this file.
1/*====================================================================*
2 - Copyright (C) 2001 Leptonica. All rights reserved.
3 -
4 - Redistribution and use in source and binary forms, with or without
5 - modification, are permitted provided that the following conditions
6 - are met:
7 - 1. Redistributions of source code must retain the above copyright
8 - notice, this list of conditions and the following disclaimer.
9 - 2. Redistributions in binary form must reproduce the above
10 - copyright notice, this list of conditions and the following
11 - disclaimer in the documentation and/or other materials
12 - provided with the distribution.
13 -
14 - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
15 - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
16 - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
17 - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ANY
18 - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22 - OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
23 - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 *====================================================================*/
26
87#ifdef HAVE_CONFIG_H
88#include <config_auto.h>
89#endif /* HAVE_CONFIG_H */
90
91#include "allheaders.h"
92
122PIXTILING *
124 l_int32 nx,
125 l_int32 ny,
126 l_int32 w,
127 l_int32 h,
128 l_int32 xoverlap,
129 l_int32 yoverlap)
130{
131l_int32 width, height;
132PIXTILING *pt;
133
134 PROCNAME("pixTilingCreate");
135
136 if (!pixs)
137 return (PIXTILING *)ERROR_PTR("pixs not defined", procName, NULL);
138 if (nx < 1 && w < 1)
139 return (PIXTILING *)ERROR_PTR("invalid width spec", procName, NULL);
140 if (ny < 1 && h < 1)
141 return (PIXTILING *)ERROR_PTR("invalid height spec", procName, NULL);
142
143 /* Find the tile width and number of tiles. All tiles except the
144 * rightmost ones have the same width. The width of the
145 * rightmost ones are at least the width of the others and
146 * less than twice that width. Ditto for tile height. */
147 pixGetDimensions(pixs, &width, &height, NULL);
148 if (nx == 0)
149 nx = L_MAX(1, width / w);
150 w = width / nx; /* possibly reset */
151 if (ny == 0)
152 ny = L_MAX(1, height / h);
153 h = height / ny; /* possibly reset */
154 if (xoverlap > w || yoverlap > h) {
155 L_INFO("tile width = %d, tile height = %d\n", procName, w, h);
156 return (PIXTILING *)ERROR_PTR("overlap too large", procName, NULL);
157 }
158
159 pt = (PIXTILING *)LEPT_CALLOC(1, sizeof(PIXTILING));
160 pt->pix = pixClone(pixs);
161 pt->xoverlap = xoverlap;
162 pt->yoverlap = yoverlap;
163 pt->nx = nx;
164 pt->ny = ny;
165 pt->w = w;
166 pt->h = h;
167 pt->strip = TRUE;
168 return pt;
169}
170
171
178void
180{
181PIXTILING *pt;
182
183 PROCNAME("pixTilingDestroy");
184
185 if (ppt == NULL) {
186 L_WARNING("ptr address is null!\n", procName);
187 return;
188 }
189
190 if ((pt = *ppt) == NULL)
191 return;
192
193 pixDestroy(&pt->pix);
194 LEPT_FREE(pt);
195 *ppt = NULL;
196}
197
198
207l_ok
209 l_int32 *pnx,
210 l_int32 *pny)
211{
212 PROCNAME("pixTilingGetCount");
213
214 if (!pt)
215 return ERROR_INT("pt not defined", procName, 1);
216 if (pnx) *pnx = pt->nx;
217 if (pny) *pny = pt->ny;
218 return 0;
219}
220
221
230l_ok
232 l_int32 *pw,
233 l_int32 *ph)
234{
235 PROCNAME("pixTilingGetSize");
236
237 if (!pt)
238 return ERROR_INT("pt not defined", procName, 1);
239 if (pw) *pw = pt->w;
240 if (ph) *ph = pt->h;
241 return 0;
242}
243
244
254PIX *
256 l_int32 i,
257 l_int32 j)
258{
259l_int32 wpix, hpix, wt, ht, nx, ny;
260l_int32 xoverlap, yoverlap, wtlast, htlast;
261l_int32 left, top, xtraleft, xtraright, xtratop, xtrabot, width, height;
262BOX *box;
263PIX *pixs, *pixt, *pixd;
264
265 PROCNAME("pixTilingGetTile");
266
267 if (!pt)
268 return (PIX *)ERROR_PTR("pt not defined", procName, NULL);
269 if ((pixs = pt->pix) == NULL)
270 return (PIX *)ERROR_PTR("pix not found", procName, NULL);
271 pixTilingGetCount(pt, &nx, &ny);
272 if (i < 0 || i >= ny)
273 return (PIX *)ERROR_PTR("invalid row index i", procName, NULL);
274 if (j < 0 || j >= nx)
275 return (PIX *)ERROR_PTR("invalid column index j", procName, NULL);
276
277 /* Grab the tile with as much overlap as exists within the
278 * input pix. First, compute the (left, top) coordinates. */
279 pixGetDimensions(pixs, &wpix, &hpix, NULL);
280 pixTilingGetSize(pt, &wt, &ht);
281 xoverlap = pt->xoverlap;
282 yoverlap = pt->yoverlap;
283 wtlast = wpix - wt * (nx - 1);
284 htlast = hpix - ht * (ny - 1);
285 left = L_MAX(0, j * wt - xoverlap);
286 top = L_MAX(0, i * ht - yoverlap);
287
288 /* Get the width and height of the tile, including whatever
289 * overlap is available. */
290 if (nx == 1)
291 width = wpix;
292 else if (j == 0)
293 width = wt + xoverlap;
294 else if (j == nx - 1)
295 width = wtlast + xoverlap;
296 else
297 width = wt + 2 * xoverlap;
298
299 if (ny == 1)
300 height = hpix;
301 else if (i == 0)
302 height = ht + yoverlap;
303 else if (i == ny - 1)
304 height = htlast + yoverlap;
305 else
306 height = ht + 2 * yoverlap;
307 box = boxCreate(left, top, width, height);
308 pixt = pixClipRectangle(pixs, box, NULL);
309 boxDestroy(&box);
310
311 /* If no overlap, do not add any special case borders */
312 if (xoverlap == 0 && yoverlap == 0)
313 return pixt;
314
315 /* Add overlap as a mirrored border, in the 8 special cases where
316 * the tile touches the border of the input pix. The xtratop (etc)
317 * parameters are required where the tile is either full width
318 * or full height. */
319 xtratop = xtrabot = xtraleft = xtraright = 0;
320 if (nx == 1)
321 xtraleft = xtraright = xoverlap;
322 if (ny == 1)
323 xtratop = xtrabot = yoverlap;
324 if (i == 0 && j == 0)
325 pixd = pixAddMirroredBorder(pixt, xoverlap, xtraright,
326 yoverlap, xtrabot);
327 else if (i == 0 && j == nx - 1)
328 pixd = pixAddMirroredBorder(pixt, xtraleft, xoverlap,
329 yoverlap, xtrabot);
330 else if (i == ny - 1 && j == 0)
331 pixd = pixAddMirroredBorder(pixt, xoverlap, xtraright,
332 xtratop, yoverlap);
333 else if (i == ny - 1 && j == nx - 1)
334 pixd = pixAddMirroredBorder(pixt, xtraleft, xoverlap,
335 xtratop, yoverlap);
336 else if (i == 0)
337 pixd = pixAddMirroredBorder(pixt, 0, 0, yoverlap, xtrabot);
338 else if (i == ny - 1)
339 pixd = pixAddMirroredBorder(pixt, 0, 0, xtratop, yoverlap);
340 else if (j == 0)
341 pixd = pixAddMirroredBorder(pixt, xoverlap, xtraright, 0, 0);
342 else if (j == nx - 1)
343 pixd = pixAddMirroredBorder(pixt, xtraleft, xoverlap, 0, 0);
344 else
345 pixd = pixClone(pixt);
346 pixDestroy(&pixt);
347
348 return pixd;
349}
350
351
367l_ok
369{
370 PROCNAME("pixTilingNoStripOnPaint");
371
372 if (!pt)
373 return ERROR_INT("pt not defined", procName, 1);
374 pt->strip = FALSE;
375 return 0;
376}
377
378
389l_ok
391 l_int32 i,
392 l_int32 j,
393 PIX *pixs,
394 PIXTILING *pt)
395{
396l_int32 w, h;
397
398 PROCNAME("pixTilingPaintTile");
399
400 if (!pixd)
401 return ERROR_INT("pixd not defined", procName, 1);
402 if (!pixs)
403 return ERROR_INT("pixs not defined", procName, 1);
404 if (!pt)
405 return ERROR_INT("pt not defined", procName, 1);
406 if (i < 0 || i >= pt->ny)
407 return ERROR_INT("invalid row index i", procName, 1);
408 if (j < 0 || j >= pt->nx)
409 return ERROR_INT("invalid column index j", procName, 1);
410
411 /* Strip added border pixels off if requested */
412 pixGetDimensions(pixs, &w, &h, NULL);
413 if (pt->strip == TRUE) {
414 pixRasterop(pixd, j * pt->w, i * pt->h,
415 w - 2 * pt->xoverlap, h - 2 * pt->yoverlap, PIX_SRC,
416 pixs, pt->xoverlap, pt->yoverlap);
417 } else {
418 pixRasterop(pixd, j * pt->w, i * pt->h, w, h, PIX_SRC, pixs, 0, 0);
419 }
420
421 return 0;
422}
void boxDestroy(BOX **pbox)
boxDestroy()
Definition: boxbasic.c:282
BOX * boxCreate(l_int32 x, l_int32 y, l_int32 w, l_int32 h)
boxCreate()
Definition: boxbasic.c:172
void pixDestroy(PIX **ppix)
pixDestroy()
Definition: pix1.c:621
l_ok pixGetDimensions(const PIX *pix, l_int32 *pw, l_int32 *ph, l_int32 *pd)
pixGetDimensions()
Definition: pix1.c:1113
PIX * pixClone(PIX *pixs)
pixClone()
Definition: pix1.c:593
PIX * pixAddMirroredBorder(PIX *pixs, l_int32 left, l_int32 right, l_int32 top, l_int32 bot)
pixAddMirroredBorder()
Definition: pix2.c:2101
PIX * pixClipRectangle(PIX *pixs, BOX *box, BOX **pboxc)
pixClipRectangle()
Definition: pix5.c:1026
#define PIX_SRC
Definition: pix.h:330
l_ok pixTilingNoStripOnPaint(PIXTILING *pt)
pixTilingNoStripOnPaint()
Definition: pixtiling.c:368
l_ok pixTilingGetCount(PIXTILING *pt, l_int32 *pnx, l_int32 *pny)
pixTilingGetCount()
Definition: pixtiling.c:208
l_ok pixTilingGetSize(PIXTILING *pt, l_int32 *pw, l_int32 *ph)
pixTilingGetSize()
Definition: pixtiling.c:231
PIXTILING * pixTilingCreate(PIX *pixs, l_int32 nx, l_int32 ny, l_int32 w, l_int32 h, l_int32 xoverlap, l_int32 yoverlap)
pixTilingCreate()
Definition: pixtiling.c:123
void pixTilingDestroy(PIXTILING **ppt)
pixTilingDestroy()
Definition: pixtiling.c:179
l_ok pixTilingPaintTile(PIX *pixd, l_int32 i, l_int32 j, PIX *pixs, PIXTILING *pt)
pixTilingPaintTile()
Definition: pixtiling.c:390
PIX * pixTilingGetTile(PIXTILING *pt, l_int32 i, l_int32 j)
pixTilingGetTile()
Definition: pixtiling.c:255
l_ok pixRasterop(PIX *pixd, l_int32 dx, l_int32 dy, l_int32 dw, l_int32 dh, l_int32 op, PIX *pixs, l_int32 sx, l_int32 sy)
pixRasterop()
Definition: rop.c:204
Definition: pix.h:481
Definition: pix.h:559
l_int32 yoverlap
Definition: pix.h:566
l_int32 nx
Definition: pix.h:561
l_int32 w
Definition: pix.h:563
l_int32 xoverlap
Definition: pix.h:565
struct Pix * pix
Definition: pix.h:560
l_int32 h
Definition: pix.h:564
l_int32 strip
Definition: pix.h:567
l_int32 ny
Definition: pix.h:562
Definition: pix.h:139