Leptonica 1.82.0
Image processing and image analysis suite
rop.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
49#ifdef HAVE_CONFIG_H
50#include <config_auto.h>
51#endif /* HAVE_CONFIG_H */
52
53#include <string.h>
54#include "allheaders.h"
55
56static l_int32 checkRasteropCrop(l_int32 pixw, l_int32 pixh, l_int32 dx,
57 l_int32 dy, l_int32 dw, l_int32 dh);
58
59
60/*--------------------------------------------------------------------*
61 * General rasterop (basic pix interface) *
62 *--------------------------------------------------------------------*/
203l_ok
205 l_int32 dx,
206 l_int32 dy,
207 l_int32 dw,
208 l_int32 dh,
209 l_int32 op,
210 PIX *pixs,
211 l_int32 sx,
212 l_int32 sy)
213{
214l_int32 dpw, dph, dpd, spw, sph, spd;
215
216 PROCNAME("pixRasterop");
217
218 if (!pixd)
219 return ERROR_INT("pixd not defined", procName, 1);
220
221 if (op == PIX_DST) /* no-op */
222 return 0;
223
224 pixGetDimensions(pixd, &dpw, &dph, &dpd);
225#if 0
226 if (checkRasteropCrop(dpw, dph, dx, dy, dw, dh)) {
227 L_WARNING("dest crop box out of bounds\n", procName);
228 return 1;
229 }
230#endif
231
232 /* Check if operation is only on dest */
233 if (op == PIX_CLR || op == PIX_SET || op == PIX_NOT(PIX_DST)) {
234 rasteropUniLow(pixGetData(pixd), dpw, dph, dpd, pixGetWpl(pixd),
235 dx, dy, dw, dh, op);
236 return 0;
237 }
238
239 /* Two-image rasterop; the depths must match */
240 if (!pixs)
241 return ERROR_INT("pixs not defined", procName, 1);
242 pixGetDimensions(pixs, &spw, &sph, &spd);
243 if (dpd != spd)
244 return ERROR_INT("depths of pixs and pixd differ", procName, 1);
245#if 0
246 if (checkRasteropCrop(spw, sph, sx, sy, dw, dh)) {
247 L_WARNING("source crop box out of bounds\n", procName);
248 return 1;
249 }
250#endif
251
252 rasteropLow(pixGetData(pixd), dpw, dph, dpd, pixGetWpl(pixd),
253 dx, dy, dw, dh, op,
254 pixGetData(pixs), spw, sph, pixGetWpl(pixs), sx, sy);
255 return 0;
256}
257
258
259/*--------------------------------------------------------------------*
260 * In-place full band translation *
261 *--------------------------------------------------------------------*/
282l_ok
284 l_int32 bx,
285 l_int32 bw,
286 l_int32 vshift,
287 l_int32 incolor)
288{
289l_int32 w, h, d, index, op;
290PIX *pixt;
291PIXCMAP *cmap;
292
293 PROCNAME("pixRasteropVip");
294
295 if (!pixd)
296 return ERROR_INT("pixd not defined", procName, 1);
297 if (incolor != L_BRING_IN_WHITE && incolor != L_BRING_IN_BLACK)
298 return ERROR_INT("invalid value for incolor", procName, 1);
299 if (bw <= 0)
300 return ERROR_INT("bw must be > 0", procName, 1);
301
302 if (vshift == 0)
303 return 0;
304
305 pixGetDimensions(pixd, &w, &h, &d);
306 rasteropVipLow(pixGetData(pixd), w, h, d, pixGetWpl(pixd), bx, bw, vshift);
307
308 cmap = pixGetColormap(pixd);
309 if (!cmap) {
310 if ((d == 1 && incolor == L_BRING_IN_BLACK) ||
311 (d > 1 && incolor == L_BRING_IN_WHITE))
312 op = PIX_SET;
313 else
314 op = PIX_CLR;
315
316 /* Set the pixels brought in at top or bottom */
317 if (vshift > 0)
318 pixRasterop(pixd, bx, 0, bw, vshift, op, NULL, 0, 0);
319 else /* vshift < 0 */
320 pixRasterop(pixd, bx, h + vshift, bw, -vshift, op, NULL, 0, 0);
321 return 0;
322 }
323
324 /* Get the nearest index and fill with that */
325 if (incolor == L_BRING_IN_BLACK)
326 pixcmapGetRankIntensity(cmap, 0.0, &index);
327 else /* white */
328 pixcmapGetRankIntensity(cmap, 1.0, &index);
329 pixt = pixCreate(bw, L_ABS(vshift), d);
330 pixSetAllArbitrary(pixt, index);
331 if (vshift > 0)
332 pixRasterop(pixd, bx, 0, bw, vshift, PIX_SRC, pixt, 0, 0);
333 else /* vshift < 0 */
334 pixRasterop(pixd, bx, h + vshift, bw, -vshift, PIX_SRC, pixt, 0, 0);
335 pixDestroy(&pixt);
336 return 0;
337}
338
339
360l_ok
362 l_int32 by,
363 l_int32 bh,
364 l_int32 hshift,
365 l_int32 incolor)
366{
367l_int32 w, h, d, index, op;
368PIX *pixt;
369PIXCMAP *cmap;
370
371 PROCNAME("pixRasteropHip");
372
373 if (!pixd)
374 return ERROR_INT("pixd not defined", procName, 1);
375 if (incolor != L_BRING_IN_WHITE && incolor != L_BRING_IN_BLACK)
376 return ERROR_INT("invalid value for incolor", procName, 1);
377 if (bh <= 0)
378 return ERROR_INT("bh must be > 0", procName, 1);
379
380 if (hshift == 0)
381 return 0;
382
383 pixGetDimensions(pixd, &w, &h, &d);
384 rasteropHipLow(pixGetData(pixd), h, d, pixGetWpl(pixd), by, bh, hshift);
385
386 cmap = pixGetColormap(pixd);
387 if (!cmap) {
388 if ((d == 1 && incolor == L_BRING_IN_BLACK) ||
389 (d > 1 && incolor == L_BRING_IN_WHITE))
390 op = PIX_SET;
391 else
392 op = PIX_CLR;
393
394 /* Set the pixels brought in at left or right */
395 if (hshift > 0)
396 pixRasterop(pixd, 0, by, hshift, bh, op, NULL, 0, 0);
397 else /* hshift < 0 */
398 pixRasterop(pixd, w + hshift, by, -hshift, bh, op, NULL, 0, 0);
399 return 0;
400 }
401
402 /* Get the nearest index and fill with that */
403 if (incolor == L_BRING_IN_BLACK)
404 pixcmapGetRankIntensity(cmap, 0.0, &index);
405 else /* white */
406 pixcmapGetRankIntensity(cmap, 1.0, &index);
407 pixt = pixCreate(L_ABS(hshift), bh, d);
408 pixSetAllArbitrary(pixt, index);
409 if (hshift > 0)
410 pixRasterop(pixd, 0, by, hshift, bh, PIX_SRC, pixt, 0, 0);
411 else /* hshift < 0 */
412 pixRasterop(pixd, w + hshift, by, -hshift, bh, PIX_SRC, pixt, 0, 0);
413 pixDestroy(&pixt);
414 return 0;
415}
416
417
418/*--------------------------------------------------------------------*
419 * Full image translation (general and in-place) *
420 *--------------------------------------------------------------------*/
444PIX *
446 PIX *pixs,
447 l_int32 hshift,
448 l_int32 vshift,
449 l_int32 incolor)
450{
451 PROCNAME("pixTranslate");
452
453 if (!pixs)
454 return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
455
456 /* Prepare pixd for in-place operation */
457 if ((pixd = pixCopy(pixd, pixs)) == NULL)
458 return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
459
460 pixRasteropIP(pixd, hshift, vshift, incolor);
461 return pixd;
462}
463
464
474l_ok
476 l_int32 hshift,
477 l_int32 vshift,
478 l_int32 incolor)
479{
480l_int32 w, h;
481
482 PROCNAME("pixRasteropIP");
483
484 if (!pixd)
485 return ERROR_INT("pixd not defined", procName, 1);
486
487 pixGetDimensions(pixd, &w, &h, NULL);
488 pixRasteropHip(pixd, 0, h, hshift, incolor);
489 pixRasteropVip(pixd, 0, w, vshift, incolor);
490
491 return 0;
492}
493
494
495/*--------------------------------------------------------------------*
496 * Full image rasterop with no shifts *
497 *--------------------------------------------------------------------*/
515l_ok
517 PIX *pixs,
518 l_int32 op)
519{
520 PROCNAME("pixRasteropFullImage");
521
522 if (!pixd)
523 return ERROR_INT("pixd not defined", procName, 1);
524 if (!pixs)
525 return ERROR_INT("pixs not defined", procName, 1);
526
527 pixRasterop(pixd, 0, 0, pixGetWidth(pixd), pixGetHeight(pixd), op,
528 pixs, 0, 0);
529 return 0;
530}
531
532
533/*--------------------------------------------------------------------*
534 * Checking for invalid crop box *
535 *--------------------------------------------------------------------*/
552static l_int32
553checkRasteropCrop(l_int32 pixw,
554 l_int32 pixh,
555 l_int32 x,
556 l_int32 y,
557 l_int32 w,
558 l_int32 h)
559{
560 PROCNAME("checkRasteropCrop");
561
562 if (pixw < 1 || pixh < 1 || w < 1 || h < 1)
563 return ERROR_INT("dimension is <= 0", procName, 1);
564
565 if (x + w <= 0 || y + h <= 0)
566 return ERROR_INT("box to left or above pix", procName, 1);
567
568 if (x >= pixw || y >= pixh)
569 return ERROR_INT("box to right or below pix", procName, 1);
570
571 return 0;
572}
l_ok pixcmapGetRankIntensity(PIXCMAP *cmap, l_float32 rankval, l_int32 *pindex)
pixcmapGetRankIntensity()
Definition: colormap.c:1302
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 * pixCreate(l_int32 width, l_int32 height, l_int32 depth)
pixCreate()
Definition: pix1.c:315
PIX * pixCopy(PIX *pixd, const PIX *pixs)
pixCopy()
Definition: pix1.c:705
l_uint32 * pixGetData(PIX *pix)
pixGetData()
Definition: pix1.c:1763
l_ok pixSetAllArbitrary(PIX *pix, l_uint32 val)
pixSetAllArbitrary()
Definition: pix2.c:951
#define PIX_DST
Definition: pix.h:331
#define PIX_SRC
Definition: pix.h:330
#define PIX_CLR
Definition: pix.h:333
#define PIX_NOT(op)
Definition: pix.h:332
#define PIX_SET
Definition: pix.h:334
@ L_BRING_IN_BLACK
Definition: pix.h:870
@ L_BRING_IN_WHITE
Definition: pix.h:869
l_ok pixRasteropHip(PIX *pixd, l_int32 by, l_int32 bh, l_int32 hshift, l_int32 incolor)
pixRasteropHip()
Definition: rop.c:361
l_ok pixRasteropIP(PIX *pixd, l_int32 hshift, l_int32 vshift, l_int32 incolor)
pixRasteropIP()
Definition: rop.c:475
l_ok pixRasteropFullImage(PIX *pixd, PIX *pixs, l_int32 op)
pixRasteropFullImage()
Definition: rop.c:516
PIX * pixTranslate(PIX *pixd, PIX *pixs, l_int32 hshift, l_int32 vshift, l_int32 incolor)
pixTranslate()
Definition: rop.c:445
l_ok pixRasteropVip(PIX *pixd, l_int32 bx, l_int32 bw, l_int32 vshift, l_int32 incolor)
pixRasteropVip()
Definition: rop.c:283
static l_int32 checkRasteropCrop(l_int32 pixw, l_int32 pixh, l_int32 dx, l_int32 dy, l_int32 dw, l_int32 dh)
checkRasteropCrop()
Definition: rop.c:553
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
void rasteropHipLow(l_uint32 *data, l_int32 pixh, l_int32 depth, l_int32 wpl, l_int32 y, l_int32 h, l_int32 shift)
rasteropHipLow()
Definition: roplow.c:2386
void rasteropUniLow(l_uint32 *datad, l_int32 dpixw, l_int32 dpixh, l_int32 depth, l_int32 dwpl, l_int32 dx, l_int32 dy, l_int32 dw, l_int32 dh, l_int32 op)
rasteropUniLow()
Definition: roplow.c:128
void rasteropVipLow(l_uint32 *data, l_int32 pixw, l_int32 pixh, l_int32 depth, l_int32 wpl, l_int32 x, l_int32 w, l_int32 shift)
rasteropVipLow()
Definition: roplow.c:2173
void rasteropLow(l_uint32 *datad, l_int32 dpixw, l_int32 dpixh, l_int32 depth, l_int32 dwpl, l_int32 dx, l_int32 dy, l_int32 dw, l_int32 dh, l_int32 op, l_uint32 *datas, l_int32 spixw, l_int32 spixh, l_int32 swpl, l_int32 sx, l_int32 sy)
rasteropLow()
Definition: roplow.c:485
Definition: pix.h:139