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 
122 PIXTILING *
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 {
131 l_int32 width, height;
132 PIXTILING *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 
178 void
180 {
181 PIXTILING *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 
207 l_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 
230 l_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 
254 PIX *
256  l_int32 i,
257  l_int32 j)
258 {
259 l_int32 wpix, hpix, wt, ht, nx, ny;
260 l_int32 xoverlap, yoverlap, wtlast, htlast;
261 l_int32 left, top, xtraleft, xtraright, xtratop, xtrabot, width, height;
262 BOX *box;
263 PIX *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 
367 l_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 
389 l_ok
391  l_int32 i,
392  l_int32 j,
393  PIX *pixs,
394  PIXTILING *pt)
395 {
396 l_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
PIX * pixTilingGetTile(PIXTILING *pt, l_int32 i, l_int32 j)
pixTilingGetTile()
Definition: pixtiling.c:255
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
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
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