Leptonica  1.83.1
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  if (!pixd)
217  return ERROR_INT("pixd not defined", __func__, 1);
218 
219  if (op == PIX_DST) /* no-op */
220  return 0;
221 
222  pixGetDimensions(pixd, &dpw, &dph, &dpd);
223 #if 0
224  if (checkRasteropCrop(dpw, dph, dx, dy, dw, dh)) {
225  L_WARNING("dest crop box out of bounds\n", __func__);
226  return 1;
227  }
228 #endif
229 
230  /* Check if operation is only on dest */
231  if (op == PIX_CLR || op == PIX_SET || op == PIX_NOT(PIX_DST)) {
232  rasteropUniLow(pixGetData(pixd), dpw, dph, dpd, pixGetWpl(pixd),
233  dx, dy, dw, dh, op);
234  return 0;
235  }
236 
237  /* Two-image rasterop; the depths must match */
238  if (!pixs)
239  return ERROR_INT("pixs not defined", __func__, 1);
240  pixGetDimensions(pixs, &spw, &sph, &spd);
241  if (dpd != spd)
242  return ERROR_INT("depths of pixs and pixd differ", __func__, 1);
243 #if 0
244  if (checkRasteropCrop(spw, sph, sx, sy, dw, dh)) {
245  L_WARNING("source crop box out of bounds\n", __func__);
246  return 1;
247  }
248 #endif
249 
250  rasteropLow(pixGetData(pixd), dpw, dph, dpd, pixGetWpl(pixd),
251  dx, dy, dw, dh, op,
252  pixGetData(pixs), spw, sph, pixGetWpl(pixs), sx, sy);
253  return 0;
254 }
255 
256 
257 /*--------------------------------------------------------------------*
258  * In-place full band translation *
259  *--------------------------------------------------------------------*/
280 l_ok
282  l_int32 bx,
283  l_int32 bw,
284  l_int32 vshift,
285  l_int32 incolor)
286 {
287 l_int32 w, h, d, index, op;
288 PIX *pixt;
289 PIXCMAP *cmap;
290 
291  if (!pixd)
292  return ERROR_INT("pixd not defined", __func__, 1);
293  if (incolor != L_BRING_IN_WHITE && incolor != L_BRING_IN_BLACK)
294  return ERROR_INT("invalid value for incolor", __func__, 1);
295  if (bw <= 0)
296  return ERROR_INT("bw must be > 0", __func__, 1);
297 
298  if (vshift == 0)
299  return 0;
300 
301  pixGetDimensions(pixd, &w, &h, &d);
302  rasteropVipLow(pixGetData(pixd), w, h, d, pixGetWpl(pixd), bx, bw, vshift);
303 
304  cmap = pixGetColormap(pixd);
305  if (!cmap) {
306  if ((d == 1 && incolor == L_BRING_IN_BLACK) ||
307  (d > 1 && incolor == L_BRING_IN_WHITE))
308  op = PIX_SET;
309  else
310  op = PIX_CLR;
311 
312  /* Set the pixels brought in at top or bottom */
313  if (vshift > 0)
314  pixRasterop(pixd, bx, 0, bw, vshift, op, NULL, 0, 0);
315  else /* vshift < 0 */
316  pixRasterop(pixd, bx, h + vshift, bw, -vshift, op, NULL, 0, 0);
317  return 0;
318  }
319 
320  /* Get the nearest index and fill with that */
321  if (incolor == L_BRING_IN_BLACK)
322  pixcmapGetRankIntensity(cmap, 0.0, &index);
323  else /* white */
324  pixcmapGetRankIntensity(cmap, 1.0, &index);
325  pixt = pixCreate(bw, L_ABS(vshift), d);
326  pixSetAllArbitrary(pixt, index);
327  if (vshift > 0)
328  pixRasterop(pixd, bx, 0, bw, vshift, PIX_SRC, pixt, 0, 0);
329  else /* vshift < 0 */
330  pixRasterop(pixd, bx, h + vshift, bw, -vshift, PIX_SRC, pixt, 0, 0);
331  pixDestroy(&pixt);
332  return 0;
333 }
334 
335 
356 l_ok
358  l_int32 by,
359  l_int32 bh,
360  l_int32 hshift,
361  l_int32 incolor)
362 {
363 l_int32 w, h, d, index, op;
364 PIX *pixt;
365 PIXCMAP *cmap;
366 
367  if (!pixd)
368  return ERROR_INT("pixd not defined", __func__, 1);
369  if (incolor != L_BRING_IN_WHITE && incolor != L_BRING_IN_BLACK)
370  return ERROR_INT("invalid value for incolor", __func__, 1);
371  if (bh <= 0)
372  return ERROR_INT("bh must be > 0", __func__, 1);
373 
374  if (hshift == 0)
375  return 0;
376 
377  pixGetDimensions(pixd, &w, &h, &d);
378  rasteropHipLow(pixGetData(pixd), h, d, pixGetWpl(pixd), by, bh, hshift);
379 
380  cmap = pixGetColormap(pixd);
381  if (!cmap) {
382  if ((d == 1 && incolor == L_BRING_IN_BLACK) ||
383  (d > 1 && incolor == L_BRING_IN_WHITE))
384  op = PIX_SET;
385  else
386  op = PIX_CLR;
387 
388  /* Set the pixels brought in at left or right */
389  if (hshift > 0)
390  pixRasterop(pixd, 0, by, hshift, bh, op, NULL, 0, 0);
391  else /* hshift < 0 */
392  pixRasterop(pixd, w + hshift, by, -hshift, bh, op, NULL, 0, 0);
393  return 0;
394  }
395 
396  /* Get the nearest index and fill with that */
397  if (incolor == L_BRING_IN_BLACK)
398  pixcmapGetRankIntensity(cmap, 0.0, &index);
399  else /* white */
400  pixcmapGetRankIntensity(cmap, 1.0, &index);
401  pixt = pixCreate(L_ABS(hshift), bh, d);
402  pixSetAllArbitrary(pixt, index);
403  if (hshift > 0)
404  pixRasterop(pixd, 0, by, hshift, bh, PIX_SRC, pixt, 0, 0);
405  else /* hshift < 0 */
406  pixRasterop(pixd, w + hshift, by, -hshift, bh, PIX_SRC, pixt, 0, 0);
407  pixDestroy(&pixt);
408  return 0;
409 }
410 
411 
412 /*--------------------------------------------------------------------*
413  * Full image translation (general and in-place) *
414  *--------------------------------------------------------------------*/
438 PIX *
440  PIX *pixs,
441  l_int32 hshift,
442  l_int32 vshift,
443  l_int32 incolor)
444 {
445  if (!pixs)
446  return (PIX *)ERROR_PTR("pixs not defined", __func__, NULL);
447 
448  /* Prepare pixd for in-place operation */
449  if ((pixd = pixCopy(pixd, pixs)) == NULL)
450  return (PIX *)ERROR_PTR("pixd not made", __func__, NULL);
451 
452  pixRasteropIP(pixd, hshift, vshift, incolor);
453  return pixd;
454 }
455 
456 
466 l_ok
468  l_int32 hshift,
469  l_int32 vshift,
470  l_int32 incolor)
471 {
472 l_int32 w, h;
473 
474  if (!pixd)
475  return ERROR_INT("pixd not defined", __func__, 1);
476 
477  pixGetDimensions(pixd, &w, &h, NULL);
478  pixRasteropHip(pixd, 0, h, hshift, incolor);
479  pixRasteropVip(pixd, 0, w, vshift, incolor);
480 
481  return 0;
482 }
483 
484 
485 /*--------------------------------------------------------------------*
486  * Full image rasterop with no shifts *
487  *--------------------------------------------------------------------*/
505 l_ok
507  PIX *pixs,
508  l_int32 op)
509 {
510  if (!pixd)
511  return ERROR_INT("pixd not defined", __func__, 1);
512  if (!pixs)
513  return ERROR_INT("pixs not defined", __func__, 1);
514 
515  pixRasterop(pixd, 0, 0, pixGetWidth(pixd), pixGetHeight(pixd), op,
516  pixs, 0, 0);
517  return 0;
518 }
519 
520 
521 /*--------------------------------------------------------------------*
522  * Checking for invalid crop box *
523  *--------------------------------------------------------------------*/
540 static l_int32
541 checkRasteropCrop(l_int32 pixw,
542  l_int32 pixh,
543  l_int32 x,
544  l_int32 y,
545  l_int32 w,
546  l_int32 h)
547 {
548  if (pixw < 1 || pixh < 1 || w < 1 || h < 1)
549  return ERROR_INT("dimension is <= 0", __func__, 1);
550 
551  if (x + w <= 0 || y + h <= 0)
552  return ERROR_INT("box to left or above pix", __func__, 1);
553 
554  if (x >= pixw || y >= pixh)
555  return ERROR_INT("box to right or below pix", __func__, 1);
556 
557  return 0;
558 }
l_ok pixcmapGetRankIntensity(PIXCMAP *cmap, l_float32 rankval, l_int32 *pindex)
pixcmapGetRankIntensity()
Definition: colormap.c:1243
l_uint32 * pixGetData(PIX *pix)
pixGetData()
Definition: pix1.c:1642
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 * pixCopy(PIX *pixd, const PIX *pixs)
pixCopy()
Definition: pix1.c:689
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:929
#define PIX_DST
Definition: pix.h:445
#define PIX_SRC
Definition: pix.h:444
#define PIX_CLR
Definition: pix.h:447
#define PIX_NOT(op)
Definition: pix.h:446
#define PIX_SET
Definition: pix.h:448
@ L_BRING_IN_BLACK
Definition: pix.h:663
@ L_BRING_IN_WHITE
Definition: pix.h:662
PIX * pixTranslate(PIX *pixd, PIX *pixs, l_int32 hshift, l_int32 vshift, l_int32 incolor)
pixTranslate()
Definition: rop.c:439
l_ok pixRasteropHip(PIX *pixd, l_int32 by, l_int32 bh, l_int32 hshift, l_int32 incolor)
pixRasteropHip()
Definition: rop.c:357
l_ok pixRasteropIP(PIX *pixd, l_int32 hshift, l_int32 vshift, l_int32 incolor)
pixRasteropIP()
Definition: rop.c:467
l_ok pixRasteropFullImage(PIX *pixd, PIX *pixs, l_int32 op)
pixRasteropFullImage()
Definition: rop.c:506
l_ok pixRasteropVip(PIX *pixd, l_int32 bx, l_int32 bw, l_int32 vshift, l_int32 incolor)
pixRasteropVip()
Definition: rop.c:281
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:541
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