Leptonica  1.83.1
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 #include "pix_internal.h"
93 
123 PIXTILING *
125  l_int32 nx,
126  l_int32 ny,
127  l_int32 w,
128  l_int32 h,
129  l_int32 xoverlap,
130  l_int32 yoverlap)
131 {
132 l_int32 width, height;
133 PIXTILING *pt;
134 
135  if (!pixs)
136  return (PIXTILING *)ERROR_PTR("pixs not defined", __func__, NULL);
137  if (nx < 1 && w < 1)
138  return (PIXTILING *)ERROR_PTR("invalid width spec", __func__, NULL);
139  if (ny < 1 && h < 1)
140  return (PIXTILING *)ERROR_PTR("invalid height spec", __func__, NULL);
141 
142  /* Find the tile width and number of tiles. All tiles except the
143  * rightmost ones have the same width. The width of the
144  * rightmost ones are at least the width of the others and
145  * less than twice that width. Ditto for tile height. */
146  pixGetDimensions(pixs, &width, &height, NULL);
147  if (nx == 0)
148  nx = L_MAX(1, width / w);
149  w = width / nx; /* possibly reset */
150  if (ny == 0)
151  ny = L_MAX(1, height / h);
152  h = height / ny; /* possibly reset */
153  if (xoverlap > w || yoverlap > h) {
154  L_INFO("tile width = %d, tile height = %d\n", __func__, w, h);
155  return (PIXTILING *)ERROR_PTR("overlap too large", __func__, NULL);
156  }
157 
158  pt = (PIXTILING *)LEPT_CALLOC(1, sizeof(PIXTILING));
159  pt->pix = pixClone(pixs);
160  pt->xoverlap = xoverlap;
161  pt->yoverlap = yoverlap;
162  pt->nx = nx;
163  pt->ny = ny;
164  pt->w = w;
165  pt->h = h;
166  pt->strip = TRUE;
167  return pt;
168 }
169 
170 
177 void
179 {
180 PIXTILING *pt;
181 
182  if (ppt == NULL) {
183  L_WARNING("ptr address is null!\n", __func__);
184  return;
185  }
186 
187  if ((pt = *ppt) == NULL)
188  return;
189 
190  pixDestroy(&pt->pix);
191  LEPT_FREE(pt);
192  *ppt = NULL;
193 }
194 
195 
204 l_ok
206  l_int32 *pnx,
207  l_int32 *pny)
208 {
209  if (!pt)
210  return ERROR_INT("pt not defined", __func__, 1);
211  if (pnx) *pnx = pt->nx;
212  if (pny) *pny = pt->ny;
213  return 0;
214 }
215 
216 
225 l_ok
227  l_int32 *pw,
228  l_int32 *ph)
229 {
230  if (!pt)
231  return ERROR_INT("pt not defined", __func__, 1);
232  if (pw) *pw = pt->w;
233  if (ph) *ph = pt->h;
234  return 0;
235 }
236 
237 
247 PIX *
249  l_int32 i,
250  l_int32 j)
251 {
252 l_int32 wpix, hpix, wt, ht, nx, ny;
253 l_int32 xoverlap, yoverlap, wtlast, htlast;
254 l_int32 left, top, xtraleft, xtraright, xtratop, xtrabot, width, height;
255 BOX *box;
256 PIX *pixs, *pixt, *pixd;
257 
258  if (!pt)
259  return (PIX *)ERROR_PTR("pt not defined", __func__, NULL);
260  if ((pixs = pt->pix) == NULL)
261  return (PIX *)ERROR_PTR("pix not found", __func__, NULL);
262  pixTilingGetCount(pt, &nx, &ny);
263  if (i < 0 || i >= ny)
264  return (PIX *)ERROR_PTR("invalid row index i", __func__, NULL);
265  if (j < 0 || j >= nx)
266  return (PIX *)ERROR_PTR("invalid column index j", __func__, NULL);
267 
268  /* Grab the tile with as much overlap as exists within the
269  * input pix. First, compute the (left, top) coordinates. */
270  pixGetDimensions(pixs, &wpix, &hpix, NULL);
271  pixTilingGetSize(pt, &wt, &ht);
272  xoverlap = pt->xoverlap;
273  yoverlap = pt->yoverlap;
274  wtlast = wpix - wt * (nx - 1);
275  htlast = hpix - ht * (ny - 1);
276  left = L_MAX(0, j * wt - xoverlap);
277  top = L_MAX(0, i * ht - yoverlap);
278 
279  /* Get the width and height of the tile, including whatever
280  * overlap is available. */
281  if (nx == 1)
282  width = wpix;
283  else if (j == 0)
284  width = wt + xoverlap;
285  else if (j == nx - 1)
286  width = wtlast + xoverlap;
287  else
288  width = wt + 2 * xoverlap;
289 
290  if (ny == 1)
291  height = hpix;
292  else if (i == 0)
293  height = ht + yoverlap;
294  else if (i == ny - 1)
295  height = htlast + yoverlap;
296  else
297  height = ht + 2 * yoverlap;
298  box = boxCreate(left, top, width, height);
299  pixt = pixClipRectangle(pixs, box, NULL);
300  boxDestroy(&box);
301 
302  /* If no overlap, do not add any special case borders */
303  if (xoverlap == 0 && yoverlap == 0)
304  return pixt;
305 
306  /* Add overlap as a mirrored border, in the 8 special cases where
307  * the tile touches the border of the input pix. The xtratop (etc)
308  * parameters are required where the tile is either full width
309  * or full height. */
310  xtratop = xtrabot = xtraleft = xtraright = 0;
311  if (nx == 1)
312  xtraleft = xtraright = xoverlap;
313  if (ny == 1)
314  xtratop = xtrabot = yoverlap;
315  if (i == 0 && j == 0)
316  pixd = pixAddMirroredBorder(pixt, xoverlap, xtraright,
317  yoverlap, xtrabot);
318  else if (i == 0 && j == nx - 1)
319  pixd = pixAddMirroredBorder(pixt, xtraleft, xoverlap,
320  yoverlap, xtrabot);
321  else if (i == ny - 1 && j == 0)
322  pixd = pixAddMirroredBorder(pixt, xoverlap, xtraright,
323  xtratop, yoverlap);
324  else if (i == ny - 1 && j == nx - 1)
325  pixd = pixAddMirroredBorder(pixt, xtraleft, xoverlap,
326  xtratop, yoverlap);
327  else if (i == 0)
328  pixd = pixAddMirroredBorder(pixt, 0, 0, yoverlap, xtrabot);
329  else if (i == ny - 1)
330  pixd = pixAddMirroredBorder(pixt, 0, 0, xtratop, yoverlap);
331  else if (j == 0)
332  pixd = pixAddMirroredBorder(pixt, xoverlap, xtraright, 0, 0);
333  else if (j == nx - 1)
334  pixd = pixAddMirroredBorder(pixt, xtraleft, xoverlap, 0, 0);
335  else
336  pixd = pixClone(pixt);
337  pixDestroy(&pixt);
338 
339  return pixd;
340 }
341 
342 
358 l_ok
360 {
361  if (!pt)
362  return ERROR_INT("pt not defined", __func__, 1);
363  pt->strip = FALSE;
364  return 0;
365 }
366 
367 
378 l_ok
380  l_int32 i,
381  l_int32 j,
382  PIX *pixs,
383  PIXTILING *pt)
384 {
385 l_int32 w, h;
386 
387  if (!pixd)
388  return ERROR_INT("pixd not defined", __func__, 1);
389  if (!pixs)
390  return ERROR_INT("pixs not defined", __func__, 1);
391  if (!pt)
392  return ERROR_INT("pt not defined", __func__, 1);
393  if (i < 0 || i >= pt->ny)
394  return ERROR_INT("invalid row index i", __func__, 1);
395  if (j < 0 || j >= pt->nx)
396  return ERROR_INT("invalid column index j", __func__, 1);
397 
398  /* Strip added border pixels off if requested */
399  pixGetDimensions(pixs, &w, &h, NULL);
400  if (pt->strip == TRUE) {
401  pixRasterop(pixd, j * pt->w, i * pt->h,
402  w - 2 * pt->xoverlap, h - 2 * pt->yoverlap, PIX_SRC,
403  pixs, pt->xoverlap, pt->yoverlap);
404  } else {
405  pixRasterop(pixd, j * pt->w, i * pt->h, w, h, PIX_SRC, pixs, 0, 0);
406  }
407 
408  return 0;
409 }
void boxDestroy(BOX **pbox)
boxDestroy()
Definition: boxbasic.c:273
BOX * boxCreate(l_int32 x, l_int32 y, l_int32 w, l_int32 h)
boxCreate()
Definition: boxbasic.c:171
void pixDestroy(PIX **ppix)
pixDestroy()
Definition: pix1.c:608
l_ok pixGetDimensions(const PIX *pix, l_int32 *pw, l_int32 *ph, l_int32 *pd)
pixGetDimensions()
Definition: pix1.c:1074
PIX * pixClone(PIX *pixs)
pixClone()
Definition: pix1.c:582
PIX * pixAddMirroredBorder(PIX *pixs, l_int32 left, l_int32 right, l_int32 top, l_int32 bot)
pixAddMirroredBorder()
Definition: pix2.c:2100
PIX * pixClipRectangle(PIX *pixs, BOX *box, BOX **pboxc)
pixClipRectangle()
Definition: pix5.c:994
#define PIX_SRC
Definition: pix.h:444
l_ok pixTilingNoStripOnPaint(PIXTILING *pt)
pixTilingNoStripOnPaint()
Definition: pixtiling.c:359
l_ok pixTilingGetCount(PIXTILING *pt, l_int32 *pnx, l_int32 *pny)
pixTilingGetCount()
Definition: pixtiling.c:205
l_ok pixTilingGetSize(PIXTILING *pt, l_int32 *pw, l_int32 *ph)
pixTilingGetSize()
Definition: pixtiling.c:226
PIX * pixTilingGetTile(PIXTILING *pt, l_int32 i, l_int32 j)
pixTilingGetTile()
Definition: pixtiling.c:248
void pixTilingDestroy(PIXTILING **ppt)
pixTilingDestroy()
Definition: pixtiling.c:178
l_ok pixTilingPaintTile(PIX *pixd, l_int32 i, l_int32 j, PIX *pixs, PIXTILING *pt)
pixTilingPaintTile()
Definition: pixtiling.c:379
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:124
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
l_int32 yoverlap
Definition: pix_internal.h:335
l_int32 nx
Definition: pix_internal.h:330
l_int32 w
Definition: pix_internal.h:332
l_int32 xoverlap
Definition: pix_internal.h:334
struct Pix * pix
Definition: pix_internal.h:329
l_int32 h
Definition: pix_internal.h:333
l_int32 strip
Definition: pix_internal.h:336
l_int32 ny
Definition: pix_internal.h:331