Leptonica 1.85.0
Image processing and image analysis suite
Loading...
Searching...
No Matches
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
123PIXTILING *
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{
132l_int32 width, height;
133PIXTILING *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
177void
179{
180PIXTILING *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
204l_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
225l_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
247PIX *
249 l_int32 i,
250 l_int32 j)
251{
252l_int32 wpix, hpix, wt, ht, nx, ny;
253l_int32 xoverlap, yoverlap, wtlast, htlast;
254l_int32 left, top, xtraleft, xtraright, xtratop, xtrabot, width, height;
255BOX *box;
256PIX *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
358l_ok
360{
361 if (!pt)
362 return ERROR_INT("pt not defined", __func__, 1);
363 pt->strip = FALSE;
364 return 0;
365}
366
367
378l_ok
380 l_int32 i,
381 l_int32 j,
382 PIX *pixs,
383 PIXTILING *pt)
384{
385l_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}
#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
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
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
PIX * pixTilingGetTile(PIXTILING *pt, l_int32 i, l_int32 j)
pixTilingGetTile()
Definition pixtiling.c:248
l_int32 yoverlap
l_int32 nx
l_int32 w
l_int32 xoverlap
struct Pix * pix
l_int32 h
l_int32 strip
l_int32 ny