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 
56 static 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  *--------------------------------------------------------------------*/
203 l_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 {
214 l_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  *--------------------------------------------------------------------*/
282 l_ok
284  l_int32 bx,
285  l_int32 bw,
286  l_int32 vshift,
287  l_int32 incolor)
288 {
289 l_int32 w, h, d, index, op;
290 PIX *pixt;
291 PIXCMAP *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 
360 l_ok
362  l_int32 by,
363  l_int32 bh,
364  l_int32 hshift,
365  l_int32 incolor)
366 {
367 l_int32 w, h, d, index, op;
368 PIX *pixt;
369 PIXCMAP *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  *--------------------------------------------------------------------*/
444 PIX *
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 
474 l_ok
476  l_int32 hshift,
477  l_int32 vshift,
478  l_int32 incolor)
479 {
480 l_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  *--------------------------------------------------------------------*/
515 l_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  *--------------------------------------------------------------------*/
552 static l_int32
553 checkRasteropCrop(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
l_uint32 * pixGetData(PIX *pix)
pixGetData()
Definition: pix1.c:1763
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 * pixCopy(PIX *pixd, const PIX *pixs)
pixCopy()
Definition: pix1.c:705
PIX * pixCreate(l_int32 width, l_int32 height, l_int32 depth)
pixCreate()
Definition: pix1.c:315
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
PIX * pixTranslate(PIX *pixd, PIX *pixs, l_int32 hshift, l_int32 vshift, l_int32 incolor)
pixTranslate()
Definition: rop.c:445
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
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