Leptonica  1.77.0
Image processing and image analysis suite
pix2.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 
129 #include <string.h>
130 #include "allheaders.h"
131 
132 static const l_uint32 rmask32[] = {0x0,
133  0x00000001, 0x00000003, 0x00000007, 0x0000000f,
134  0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff,
135  0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff,
136  0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff,
137  0x0001ffff, 0x0003ffff, 0x0007ffff, 0x000fffff,
138  0x001fffff, 0x003fffff, 0x007fffff, 0x00ffffff,
139  0x01ffffff, 0x03ffffff, 0x07ffffff, 0x0fffffff,
140  0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff};
141 
142  /* This is a global that determines the default 8 bpp alpha mask values
143  * for rings at distance 1 and 2 from the border. Declare extern
144  * to use. To change the values, use l_setAlphaMaskBorder(). */
145 LEPT_DLL l_float32 AlphaMaskBorderVals[2] = {0.0, 0.5};
146 
147 
148 #ifndef NO_CONSOLE_IO
149 #define DEBUG_SERIALIZE 0
150 #endif /* ~NO_CONSOLE_IO */
151 
152 
153 /*-------------------------------------------------------------*
154  * Pixel poking *
155  *-------------------------------------------------------------*/
179 l_ok
181  l_int32 x,
182  l_int32 y,
183  l_uint32 *pval)
184 {
185 l_int32 w, h, d, wpl, val;
186 l_uint32 *line, *data;
187 
188  PROCNAME("pixGetPixel");
189 
190  if (!pval)
191  return ERROR_INT("&val not defined", procName, 1);
192  *pval = 0;
193  if (!pix)
194  return ERROR_INT("pix not defined", procName, 1);
195 
196  pixGetDimensions(pix, &w, &h, &d);
197  if (x < 0 || x >= w || y < 0 || y >= h)
198  return 2;
199 
200  wpl = pixGetWpl(pix);
201  data = pixGetData(pix);
202  line = data + y * wpl;
203  switch (d)
204  {
205  case 1:
206  val = GET_DATA_BIT(line, x);
207  break;
208  case 2:
209  val = GET_DATA_DIBIT(line, x);
210  break;
211  case 4:
212  val = GET_DATA_QBIT(line, x);
213  break;
214  case 8:
215  val = GET_DATA_BYTE(line, x);
216  break;
217  case 16:
218  val = GET_DATA_TWO_BYTES(line, x);
219  break;
220  case 32:
221  val = line[x];
222  break;
223  default:
224  return ERROR_INT("depth must be in {1,2,4,8,16,32} bpp", procName, 1);
225  }
226 
227  *pval = val;
228  return 0;
229 }
230 
231 
252 l_ok
254  l_int32 x,
255  l_int32 y,
256  l_uint32 val)
257 {
258 l_int32 w, h, d, wpl;
259 l_uint32 *line, *data;
260 
261  PROCNAME("pixSetPixel");
262 
263  if (!pix)
264  return ERROR_INT("pix not defined", procName, 1);
265  pixGetDimensions(pix, &w, &h, &d);
266  if (x < 0 || x >= w || y < 0 || y >= h)
267  return 2;
268 
269  data = pixGetData(pix);
270  wpl = pixGetWpl(pix);
271  line = data + y * wpl;
272  switch (d)
273  {
274  case 1:
275  if (val)
276  SET_DATA_BIT(line, x);
277  else
278  CLEAR_DATA_BIT(line, x);
279  break;
280  case 2:
281  SET_DATA_DIBIT(line, x, val);
282  break;
283  case 4:
284  SET_DATA_QBIT(line, x, val);
285  break;
286  case 8:
287  SET_DATA_BYTE(line, x, val);
288  break;
289  case 16:
290  SET_DATA_TWO_BYTES(line, x, val);
291  break;
292  case 32:
293  line[x] = val;
294  break;
295  default:
296  return ERROR_INT("depth must be in {1,2,4,8,16,32} bpp", procName, 1);
297  }
298 
299  return 0;
300 }
301 
302 
317 l_ok
319  l_int32 x,
320  l_int32 y,
321  l_int32 *prval,
322  l_int32 *pgval,
323  l_int32 *pbval)
324 {
325 l_int32 w, h, d, wpl;
326 l_uint32 *data, *ppixel;
327 
328  PROCNAME("pixGetRGBPixel");
329 
330  if (prval) *prval = 0;
331  if (pgval) *pgval = 0;
332  if (pbval) *pbval = 0;
333  if (!prval && !pgval && !pbval)
334  return ERROR_INT("no output requested", procName, 1);
335  if (!pix)
336  return ERROR_INT("pix not defined", procName, 1);
337  pixGetDimensions(pix, &w, &h, &d);
338  if (d != 32)
339  return ERROR_INT("pix not 32 bpp", procName, 1);
340  if (x < 0 || x >= w || y < 0 || y >= h)
341  return 2;
342 
343  wpl = pixGetWpl(pix);
344  data = pixGetData(pix);
345  ppixel = data + y * wpl + x;
346  if (prval) *prval = GET_DATA_BYTE(ppixel, COLOR_RED);
347  if (pgval) *pgval = GET_DATA_BYTE(ppixel, COLOR_GREEN);
348  if (pbval) *pbval = GET_DATA_BYTE(ppixel, COLOR_BLUE);
349  return 0;
350 }
351 
352 
367 l_ok
369  l_int32 x,
370  l_int32 y,
371  l_int32 rval,
372  l_int32 gval,
373  l_int32 bval)
374 {
375 l_int32 w, h, d, wpl;
376 l_uint32 pixel;
377 l_uint32 *data, *line;
378 
379  PROCNAME("pixSetRGBPixel");
380 
381  if (!pix)
382  return ERROR_INT("pix not defined", procName, 1);
383  pixGetDimensions(pix, &w, &h, &d);
384  if (d != 32)
385  return ERROR_INT("pix not 32 bpp", procName, 1);
386  if (x < 0 || x >= w || y < 0 || y >= h)
387  return 2;
388 
389  wpl = pixGetWpl(pix);
390  data = pixGetData(pix);
391  line = data + y * wpl;
392  composeRGBPixel(rval, gval, bval, &pixel);
393  *(line + x) = pixel;
394  return 0;
395 }
396 
397 
412 l_ok
414  l_uint32 *pval,
415  l_int32 *px,
416  l_int32 *py)
417 {
418 l_int32 w, h, x, y, rval, gval, bval;
419 l_uint32 val;
420 PIXCMAP *cmap;
421 
422  PROCNAME("pixGetRandomPixel");
423 
424  if (pval) *pval = 0;
425  if (px) *px = 0;
426  if (py) *py = 0;
427  if (!pval && !px && !py)
428  return ERROR_INT("no output requested", procName, 1);
429  if (!pix)
430  return ERROR_INT("pix not defined", procName, 1);
431 
432  pixGetDimensions(pix, &w, &h, NULL);
433  x = rand() % w;
434  y = rand() % h;
435  if (px) *px = x;
436  if (py) *py = y;
437  if (pval) {
438  pixGetPixel(pix, x, y, &val);
439  if ((cmap = pixGetColormap(pix)) != NULL) {
440  pixcmapGetColor(cmap, val, &rval, &gval, &bval);
441  composeRGBPixel(rval, gval, bval, pval);
442  } else {
443  *pval = val;
444  }
445  }
446 
447  return 0;
448 }
449 
450 
462 l_ok
464  l_int32 x,
465  l_int32 y)
466 {
467 l_int32 w, h, d, wpl;
468 l_uint32 *line, *data;
469 
470  PROCNAME("pixClearPixel");
471 
472  if (!pix)
473  return ERROR_INT("pix not defined", procName, 1);
474  if (pixGetColormap(pix))
475  L_WARNING("cmapped: setting to 0 may not be intended\n", procName);
476  pixGetDimensions(pix, &w, &h, &d);
477  if (x < 0 || x >= w || y < 0 || y >= h)
478  return 2;
479 
480  wpl = pixGetWpl(pix);
481  data = pixGetData(pix);
482  line = data + y * wpl;
483  switch (d)
484  {
485  case 1:
486  CLEAR_DATA_BIT(line, x);
487  break;
488  case 2:
489  CLEAR_DATA_DIBIT(line, x);
490  break;
491  case 4:
492  CLEAR_DATA_QBIT(line, x);
493  break;
494  case 8:
495  SET_DATA_BYTE(line, x, 0);
496  break;
497  case 16:
498  SET_DATA_TWO_BYTES(line, x, 0);
499  break;
500  case 32:
501  line[x] = 0;
502  break;
503  default:
504  return ERROR_INT("depth must be in {1,2,4,8,16,32} bpp", procName, 1);
505  }
506 
507  return 0;
508 }
509 
510 
522 l_ok
524  l_int32 x,
525  l_int32 y)
526 {
527 l_int32 w, h, d, wpl;
528 l_uint32 val;
529 l_uint32 *line, *data;
530 
531  PROCNAME("pixFlipPixel");
532 
533  if (!pix)
534  return ERROR_INT("pix not defined", procName, 1);
535  if (pixGetColormap(pix))
536  L_WARNING("cmapped: setting to 0 may not be intended\n", procName);
537  pixGetDimensions(pix, &w, &h, &d);
538  if (x < 0 || x >= w || y < 0 || y >= h)
539  return 2;
540 
541  data = pixGetData(pix);
542  wpl = pixGetWpl(pix);
543  line = data + y * wpl;
544  switch (d)
545  {
546  case 1:
547  val = GET_DATA_BIT(line, x);
548  if (val)
549  CLEAR_DATA_BIT(line, x);
550  else
551  SET_DATA_BIT(line, x);
552  break;
553  case 2:
554  val = GET_DATA_DIBIT(line, x);
555  val ^= 0x3;
556  SET_DATA_DIBIT(line, x, val);
557  break;
558  case 4:
559  val = GET_DATA_QBIT(line, x);
560  val ^= 0xf;
561  SET_DATA_QBIT(line, x, val);
562  break;
563  case 8:
564  val = GET_DATA_BYTE(line, x);
565  val ^= 0xff;
566  SET_DATA_BYTE(line, x, val);
567  break;
568  case 16:
569  val = GET_DATA_TWO_BYTES(line, x);
570  val ^= 0xffff;
571  SET_DATA_TWO_BYTES(line, x, val);
572  break;
573  case 32:
574  val = line[x] ^ 0xffffffff;
575  line[x] = val;
576  break;
577  default:
578  return ERROR_INT("depth must be in {1,2,4,8,16,32} bpp", procName, 1);
579  }
580 
581  return 0;
582 }
583 
584 
599 void
600 setPixelLow(l_uint32 *line,
601  l_int32 x,
602  l_int32 depth,
603  l_uint32 val)
604 {
605  switch (depth)
606  {
607  case 1:
608  if (val)
609  SET_DATA_BIT(line, x);
610  else
611  CLEAR_DATA_BIT(line, x);
612  break;
613  case 2:
614  SET_DATA_DIBIT(line, x, val);
615  break;
616  case 4:
617  SET_DATA_QBIT(line, x, val);
618  break;
619  case 8:
620  SET_DATA_BYTE(line, x, val);
621  break;
622  case 16:
623  SET_DATA_TWO_BYTES(line, x, val);
624  break;
625  case 32:
626  line[x] = val;
627  break;
628  default:
629  fprintf(stderr, "illegal depth in setPixelLow()\n");
630  }
631 
632  return;
633 }
634 
635 
636 /*-------------------------------------------------------------*
637  * Find black or white value *
638  *-------------------------------------------------------------*/
655 l_ok
657  l_int32 op,
658  l_uint32 *pval)
659 {
660 l_int32 d, val;
661 PIXCMAP *cmap;
662 
663  PROCNAME("pixGetBlackOrWhiteVal");
664 
665  if (!pval)
666  return ERROR_INT("&val not defined", procName, 1);
667  *pval = 0;
668  if (!pixs)
669  return ERROR_INT("pixs not defined", procName, 1);
670  if (op != L_GET_BLACK_VAL && op != L_GET_WHITE_VAL)
671  return ERROR_INT("invalid op", procName, 1);
672 
673  cmap = pixGetColormap(pixs);
674  d = pixGetDepth(pixs);
675  if (!cmap) {
676  if ((d == 1 && op == L_GET_WHITE_VAL) ||
677  (d > 1 && op == L_GET_BLACK_VAL)) { /* min val */
678  val = 0;
679  } else { /* max val */
680  val = (d == 32) ? 0xffffff00 : (1 << d) - 1;
681  }
682  } else { /* handle colormap */
683  if (op == L_GET_BLACK_VAL)
684  pixcmapAddBlackOrWhite(cmap, 0, &val);
685  else /* L_GET_WHITE_VAL */
686  pixcmapAddBlackOrWhite(cmap, 1, &val);
687  }
688  *pval = val;
689 
690  return 0;
691 }
692 
693 
694 /*-------------------------------------------------------------*
695  * Full image clear/set/set-to-arbitrary-value/invert *
696  *-------------------------------------------------------------*/
711 l_ok
713 {
714  PROCNAME("pixClearAll");
715 
716  if (!pix)
717  return ERROR_INT("pix not defined", procName, 1);
718 
719  pixRasterop(pix, 0, 0, pixGetWidth(pix), pixGetHeight(pix),
720  PIX_CLR, NULL, 0, 0);
721  return 0;
722 }
723 
724 
740 l_ok
742 {
743 l_int32 n;
744 PIXCMAP *cmap;
745 
746  PROCNAME("pixSetAll");
747 
748  if (!pix)
749  return ERROR_INT("pix not defined", procName, 1);
750  if ((cmap = pixGetColormap(pix)) != NULL) {
751  n = pixcmapGetCount(cmap);
752  if (n < cmap->nalloc) /* cmap is not full */
753  return ERROR_INT("cmap entry does not exist", procName, 1);
754  }
755 
756  pixRasterop(pix, 0, 0, pixGetWidth(pix), pixGetHeight(pix),
757  PIX_SET, NULL, 0, 0);
758  return 0;
759 }
760 
761 
783 l_ok
785  l_int32 grayval)
786 {
787 l_int32 d, spp, index;
788 l_uint32 val32;
789 PIX *alpha;
790 PIXCMAP *cmap;
791 
792  PROCNAME("pixSetAllGray");
793 
794  if (!pix)
795  return ERROR_INT("pix not defined", procName, 1);
796  if (grayval < 0) {
797  L_WARNING("grayval < 0; setting to 0\n", procName);
798  grayval = 0;
799  } else if (grayval > 255) {
800  L_WARNING("grayval > 255; setting to 255\n", procName);
801  grayval = 255;
802  }
803 
804  /* Handle the colormap case */
805  cmap = pixGetColormap(pix);
806  if (cmap) {
807  pixcmapAddNearestColor(cmap, grayval, grayval, grayval, &index);
808  pixSetAllArbitrary(pix, index);
809  return 0;
810  }
811 
812  /* Non-cmapped */
813  d = pixGetDepth(pix);
814  spp = pixGetSpp(pix);
815  if (d == 1) {
816  if (grayval < 128) /* black */
817  pixSetAll(pix);
818  else
819  pixClearAll(pix); /* white */
820  } else if (d < 8) {
821  grayval >>= 8 - d;
822  pixSetAllArbitrary(pix, grayval);
823  } else if (d == 8) {
824  pixSetAllArbitrary(pix, grayval);
825  } else if (d == 16) {
826  grayval |= (grayval << 8);
827  pixSetAllArbitrary(pix, grayval);
828  } else if (d == 32 && spp == 3) {
829  composeRGBPixel(grayval, grayval, grayval, &val32);
830  pixSetAllArbitrary(pix, val32);
831  } else if (d == 32 && spp == 4) {
832  alpha = pixGetRGBComponent(pix, L_ALPHA_CHANNEL);
833  composeRGBPixel(grayval, grayval, grayval, &val32);
834  pixSetAllArbitrary(pix, val32);
835  pixSetRGBComponent(pix, alpha, L_ALPHA_CHANNEL);
836  pixDestroy(&alpha);
837  } else {
838  L_ERROR("invalid depth: %d\n", procName, d);
839  return 1;
840  }
841 
842  return 0;
843 }
844 
845 
875 l_ok
877  l_uint32 val)
878 {
879 l_int32 n, i, j, w, h, d, wpl, npix;
880 l_uint32 maxval, wordval;
881 l_uint32 *data, *line;
882 PIXCMAP *cmap;
883 
884  PROCNAME("pixSetAllArbitrary");
885 
886  if (!pix)
887  return ERROR_INT("pix not defined", procName, 1);
888 
889  /* If colormapped, make sure that val is less than the size
890  * of the cmap array. */
891  if ((cmap = pixGetColormap(pix)) != NULL) {
892  n = pixcmapGetCount(cmap);
893  if (val >= n) {
894  L_WARNING("index not in colormap; using last color\n", procName);
895  val = n - 1;
896  }
897  }
898 
899  /* Make sure val isn't too large for the pixel depth.
900  * If it is too large, set the pixel color to white. */
901  pixGetDimensions(pix, &w, &h, &d);
902  if (d < 32) {
903  maxval = (1 << d) - 1;
904  if (val > maxval) {
905  L_WARNING("val = %d too large for depth; using maxval = %d\n",
906  procName, val, maxval);
907  val = maxval;
908  }
909  }
910 
911  /* Set up word to tile with */
912  wordval = 0;
913  npix = 32 / d; /* number of pixels per 32 bit word */
914  for (j = 0; j < npix; j++)
915  wordval |= (val << (j * d));
916  wpl = pixGetWpl(pix);
917  data = pixGetData(pix);
918  for (i = 0; i < h; i++) {
919  line = data + i * wpl;
920  for (j = 0; j < wpl; j++) {
921  *(line + j) = wordval;
922  }
923  }
924  return 0;
925 }
926 
927 
945 l_ok
947  l_int32 op)
948 {
949 l_int32 d, index;
950 PIXCMAP *cmap;
951 
952  PROCNAME("pixSetBlackOrWhite");
953 
954  if (!pixs)
955  return ERROR_INT("pix not defined", procName, 1);
956  if (op != L_SET_BLACK && op != L_SET_WHITE)
957  return ERROR_INT("invalid op", procName, 1);
958 
959  cmap = pixGetColormap(pixs);
960  d = pixGetDepth(pixs);
961  if (!cmap) {
962  if ((d == 1 && op == L_SET_BLACK) || (d > 1 && op == L_SET_WHITE))
963  pixSetAll(pixs);
964  else
965  pixClearAll(pixs);
966  } else { /* handle colormap */
967  if (op == L_SET_BLACK)
968  pixcmapAddBlackOrWhite(cmap, 0, &index);
969  else /* L_SET_WHITE */
970  pixcmapAddBlackOrWhite(cmap, 1, &index);
971  pixSetAllArbitrary(pixs, index);
972  }
973 
974  return 0;
975 }
976 
977 
992 l_ok
994  l_int32 comp,
995  l_int32 val)
996 {
997 l_int32 i, nwords;
998 l_uint32 mask1, mask2;
999 l_uint32 *data;
1000 
1001  PROCNAME("pixSetComponentArbitrary");
1002 
1003  if (!pix || pixGetDepth(pix) != 32)
1004  return ERROR_INT("pix not defined or not 32 bpp", procName, 1);
1005  if (comp != COLOR_RED && comp != COLOR_GREEN && comp != COLOR_BLUE &&
1006  comp != L_ALPHA_CHANNEL)
1007  return ERROR_INT("invalid component", procName, 1);
1008  if (val < 0 || val > 255)
1009  return ERROR_INT("val not in [0 ... 255]", procName, 1);
1010 
1011  mask1 = ~(255 << (8 * (3 - comp)));
1012  mask2 = val << (8 * (3 - comp));
1013  nwords = pixGetHeight(pix) * pixGetWpl(pix);
1014  data = pixGetData(pix);
1015  for (i = 0; i < nwords; i++) {
1016  data[i] &= mask1; /* clear out the component */
1017  data[i] |= mask2; /* insert the new component value */
1018  }
1019 
1020  return 0;
1021 }
1022 
1023 
1024 /*-------------------------------------------------------------*
1025  * Rectangular region clear/set/set-to-arbitrary-value *
1026  *-------------------------------------------------------------*/
1042 l_ok
1044  BOX *box)
1045 {
1046 l_int32 x, y, w, h;
1047 
1048  PROCNAME("pixClearInRect");
1049 
1050  if (!pix)
1051  return ERROR_INT("pix not defined", procName, 1);
1052  if (!box)
1053  return ERROR_INT("box not defined", procName, 1);
1054 
1055  boxGetGeometry(box, &x, &y, &w, &h);
1056  pixRasterop(pix, x, y, w, h, PIX_CLR, NULL, 0, 0);
1057  return 0;
1058 }
1059 
1060 
1077 l_ok
1079  BOX *box)
1080 {
1081 l_int32 n, x, y, w, h;
1082 PIXCMAP *cmap;
1083 
1084  PROCNAME("pixSetInRect");
1085 
1086  if (!pix)
1087  return ERROR_INT("pix not defined", procName, 1);
1088  if (!box)
1089  return ERROR_INT("box not defined", procName, 1);
1090  if ((cmap = pixGetColormap(pix)) != NULL) {
1091  n = pixcmapGetCount(cmap);
1092  if (n < cmap->nalloc) /* cmap is not full */
1093  return ERROR_INT("cmap entry does not exist", procName, 1);
1094  }
1095 
1096  boxGetGeometry(box, &x, &y, &w, &h);
1097  pixRasterop(pix, x, y, w, h, PIX_SET, NULL, 0, 0);
1098  return 0;
1099 }
1100 
1101 
1119 l_ok
1121  BOX *box,
1122  l_uint32 val)
1123 {
1124 l_int32 n, x, y, xstart, xend, ystart, yend, bw, bh, w, h, d, wpl, maxval;
1125 l_uint32 *data, *line;
1126 BOX *boxc;
1127 PIXCMAP *cmap;
1128 
1129  PROCNAME("pixSetInRectArbitrary");
1130 
1131  if (!pix)
1132  return ERROR_INT("pix not defined", procName, 1);
1133  if (!box)
1134  return ERROR_INT("box not defined", procName, 1);
1135  pixGetDimensions(pix, &w, &h, &d);
1136  if (d != 1 && d != 2 && d != 4 && d !=8 && d != 16 && d != 32)
1137  return ERROR_INT("depth must be in {1,2,4,8,16,32} bpp", procName, 1);
1138  if ((cmap = pixGetColormap(pix)) != NULL) {
1139  n = pixcmapGetCount(cmap);
1140  if (val >= n) {
1141  L_WARNING("index not in colormap; using last color\n", procName);
1142  val = n - 1;
1143  }
1144  }
1145 
1146  maxval = (d == 32) ? 0xffffff00 : (1 << d) - 1;
1147  if (val > maxval) val = maxval;
1148 
1149  /* Handle the simple cases: the min and max values */
1150  if (val == 0) {
1151  pixClearInRect(pix, box);
1152  return 0;
1153  }
1154  if (d == 1 ||
1155  (d == 2 && val == 3) ||
1156  (d == 4 && val == 0xf) ||
1157  (d == 8 && val == 0xff) ||
1158  (d == 16 && val == 0xffff) ||
1159  (d == 32 && ((val ^ 0xffffff00) >> 8 == 0))) {
1160  pixSetInRect(pix, box);
1161  return 0;
1162  }
1163 
1164  /* Find the overlap of box with the input pix */
1165  if ((boxc = boxClipToRectangle(box, w, h)) == NULL)
1166  return ERROR_INT("no overlap of box with image", procName, 1);
1167  boxGetGeometry(boxc, &xstart, &ystart, &bw, &bh);
1168  xend = xstart + bw - 1;
1169  yend = ystart + bh - 1;
1170  boxDestroy(&boxc);
1171 
1172  wpl = pixGetWpl(pix);
1173  data = pixGetData(pix);
1174  for (y = ystart; y <= yend; y++) {
1175  line = data + y * wpl;
1176  for (x = xstart; x <= xend; x++) {
1177  switch(d)
1178  {
1179  case 2:
1180  SET_DATA_DIBIT(line, x, val);
1181  break;
1182  case 4:
1183  SET_DATA_QBIT(line, x, val);
1184  break;
1185  case 8:
1186  SET_DATA_BYTE(line, x, val);
1187  break;
1188  case 16:
1189  SET_DATA_TWO_BYTES(line, x, val);
1190  break;
1191  case 32:
1192  line[x] = val;
1193  break;
1194  default:
1195  return ERROR_INT("depth not 2|4|8|16|32 bpp", procName, 1);
1196  }
1197  }
1198  }
1199 
1200  return 0;
1201 }
1202 
1203 
1220 l_ok
1222  BOX *box,
1223  l_uint32 val,
1224  l_float32 fract)
1225 {
1226 l_int32 i, j, bx, by, bw, bh, w, h, wpls;
1227 l_int32 prval, pgval, pbval, rval, gval, bval;
1228 l_uint32 val32;
1229 l_uint32 *datas, *lines;
1230 
1231  PROCNAME("pixBlendInRect");
1232 
1233  if (!pixs || pixGetDepth(pixs) != 32)
1234  return ERROR_INT("pixs not defined or not 32 bpp", procName, 1);
1235 
1236  extractRGBValues(val, &rval, &gval, &bval);
1237  pixGetDimensions(pixs, &w, &h, NULL);
1238  datas = pixGetData(pixs);
1239  wpls = pixGetWpl(pixs);
1240  if (!box) {
1241  for (i = 0; i < h; i++) { /* scan over box */
1242  lines = datas + i * wpls;
1243  for (j = 0; j < w; j++) {
1244  val32 = *(lines + j);
1245  extractRGBValues(val32, &prval, &pgval, &pbval);
1246  prval = (l_int32)((1. - fract) * prval + fract * rval);
1247  pgval = (l_int32)((1. - fract) * pgval + fract * gval);
1248  pbval = (l_int32)((1. - fract) * pbval + fract * bval);
1249  composeRGBPixel(prval, pgval, pbval, &val32);
1250  *(lines + j) = val32;
1251  }
1252  }
1253  return 0;
1254  }
1255 
1256  boxGetGeometry(box, &bx, &by, &bw, &bh);
1257  for (i = 0; i < bh; i++) { /* scan over box */
1258  if (by + i < 0 || by + i >= h) continue;
1259  lines = datas + (by + i) * wpls;
1260  for (j = 0; j < bw; j++) {
1261  if (bx + j < 0 || bx + j >= w) continue;
1262  val32 = *(lines + bx + j);
1263  extractRGBValues(val32, &prval, &pgval, &pbval);
1264  prval = (l_int32)((1. - fract) * prval + fract * rval);
1265  pgval = (l_int32)((1. - fract) * pgval + fract * gval);
1266  pbval = (l_int32)((1. - fract) * pbval + fract * bval);
1267  composeRGBPixel(prval, pgval, pbval, &val32);
1268  *(lines + bx + j) = val32;
1269  }
1270  }
1271  return 0;
1272 }
1273 
1274 
1275 /*-------------------------------------------------------------*
1276  * Set pad bits *
1277  *-------------------------------------------------------------*/
1306 l_ok
1308  l_int32 val)
1309 {
1310 l_int32 i, w, h, d, wpl, endbits, fullwords;
1311 l_uint32 mask;
1312 l_uint32 *data, *pword;
1313 
1314  PROCNAME("pixSetPadBits");
1315 
1316  if (!pix)
1317  return ERROR_INT("pix not defined", procName, 1);
1318 
1319  pixGetDimensions(pix, &w, &h, &d);
1320  if (d == 32) /* no padding exists for 32 bpp */
1321  return 0;
1322 
1323  data = pixGetData(pix);
1324  wpl = pixGetWpl(pix);
1325  endbits = 32 - (((l_int64)w * d) % 32);
1326  if (endbits == 32) /* no partial word */
1327  return 0;
1328  fullwords = (1LL * w * d) / 32;
1329  mask = rmask32[endbits];
1330  if (val == 0)
1331  mask = ~mask;
1332 
1333  for (i = 0; i < h; i++) {
1334  pword = data + i * wpl + fullwords;
1335  if (val == 0) /* clear */
1336  *pword = *pword & mask;
1337  else /* set */
1338  *pword = *pword | mask;
1339  }
1340 
1341  return 0;
1342 }
1343 
1344 
1366 l_ok
1368  l_int32 by,
1369  l_int32 bh,
1370  l_int32 val)
1371 {
1372 l_int32 i, w, h, d, wpl, endbits, fullwords;
1373 l_uint32 mask;
1374 l_uint32 *data, *pword;
1375 
1376  PROCNAME("pixSetPadBitsBand");
1377 
1378  if (!pix)
1379  return ERROR_INT("pix not defined", procName, 1);
1380 
1381  pixGetDimensions(pix, &w, &h, &d);
1382  if (d == 32) /* no padding exists for 32 bpp */
1383  return 0;
1384 
1385  if (by < 0)
1386  by = 0;
1387  if (by >= h)
1388  return ERROR_INT("start y not in image", procName, 1);
1389  if (by + bh > h)
1390  bh = h - by;
1391 
1392  data = pixGetData(pix);
1393  wpl = pixGetWpl(pix);
1394  endbits = 32 - (((l_int64)w * d) % 32);
1395  if (endbits == 32) /* no partial word */
1396  return 0;
1397  fullwords = (l_int64)w * d / 32;
1398 
1399  mask = rmask32[endbits];
1400  if (val == 0)
1401  mask = ~mask;
1402 
1403  for (i = by; i < by + bh; i++) {
1404  pword = data + i * wpl + fullwords;
1405  if (val == 0) /* clear */
1406  *pword = *pword & mask;
1407  else /* set */
1408  *pword = *pword | mask;
1409  }
1410 
1411  return 0;
1412 }
1413 
1414 
1415 /*-------------------------------------------------------------*
1416  * Set border pixels *
1417  *-------------------------------------------------------------*/
1438 l_ok
1440  l_int32 left,
1441  l_int32 right,
1442  l_int32 top,
1443  l_int32 bot,
1444  l_int32 op)
1445 {
1446 l_int32 w, h;
1447 
1448  PROCNAME("pixSetOrClearBorder");
1449 
1450  if (!pixs)
1451  return ERROR_INT("pixs not defined", procName, 1);
1452  if (op != PIX_SET && op != PIX_CLR)
1453  return ERROR_INT("op must be PIX_SET or PIX_CLR", procName, 1);
1454 
1455  pixGetDimensions(pixs, &w, &h, NULL);
1456  pixRasterop(pixs, 0, 0, left, h, op, NULL, 0, 0);
1457  pixRasterop(pixs, w - right, 0, right, h, op, NULL, 0, 0);
1458  pixRasterop(pixs, 0, 0, w, top, op, NULL, 0, 0);
1459  pixRasterop(pixs, 0, h - bot, w, bot, op, NULL, 0, 0);
1460 
1461  return 0;
1462 }
1463 
1464 
1487 l_ok
1489  l_int32 left,
1490  l_int32 right,
1491  l_int32 top,
1492  l_int32 bot,
1493  l_uint32 val)
1494 {
1495 l_int32 w, h, d, wpls, i, j, bstart, rstart;
1496 l_uint32 *datas, *lines;
1497 
1498  PROCNAME("pixSetBorderVal");
1499 
1500  if (!pixs)
1501  return ERROR_INT("pixs not defined", procName, 1);
1502  pixGetDimensions(pixs, &w, &h, &d);
1503  if (d != 8 && d != 16 && d != 32)
1504  return ERROR_INT("depth must be 8, 16 or 32 bpp", procName, 1);
1505 
1506  datas = pixGetData(pixs);
1507  wpls = pixGetWpl(pixs);
1508  if (d == 8) {
1509  val &= 0xff;
1510  for (i = 0; i < top; i++) {
1511  lines = datas + i * wpls;
1512  for (j = 0; j < w; j++)
1513  SET_DATA_BYTE(lines, j, val);
1514  }
1515  rstart = w - right;
1516  bstart = h - bot;
1517  for (i = top; i < bstart; i++) {
1518  lines = datas + i * wpls;
1519  for (j = 0; j < left; j++)
1520  SET_DATA_BYTE(lines, j, val);
1521  for (j = rstart; j < w; j++)
1522  SET_DATA_BYTE(lines, j, val);
1523  }
1524  for (i = bstart; i < h; i++) {
1525  lines = datas + i * wpls;
1526  for (j = 0; j < w; j++)
1527  SET_DATA_BYTE(lines, j, val);
1528  }
1529  } else if (d == 16) {
1530  val &= 0xffff;
1531  for (i = 0; i < top; i++) {
1532  lines = datas + i * wpls;
1533  for (j = 0; j < w; j++)
1534  SET_DATA_TWO_BYTES(lines, j, val);
1535  }
1536  rstart = w - right;
1537  bstart = h - bot;
1538  for (i = top; i < bstart; i++) {
1539  lines = datas + i * wpls;
1540  for (j = 0; j < left; j++)
1541  SET_DATA_TWO_BYTES(lines, j, val);
1542  for (j = rstart; j < w; j++)
1543  SET_DATA_TWO_BYTES(lines, j, val);
1544  }
1545  for (i = bstart; i < h; i++) {
1546  lines = datas + i * wpls;
1547  for (j = 0; j < w; j++)
1548  SET_DATA_TWO_BYTES(lines, j, val);
1549  }
1550  } else { /* d == 32 */
1551  for (i = 0; i < top; i++) {
1552  lines = datas + i * wpls;
1553  for (j = 0; j < w; j++)
1554  *(lines + j) = val;
1555  }
1556  rstart = w - right;
1557  bstart = h - bot;
1558  for (i = top; i < bstart; i++) {
1559  lines = datas + i * wpls;
1560  for (j = 0; j < left; j++)
1561  *(lines + j) = val;
1562  for (j = rstart; j < w; j++)
1563  *(lines + j) = val;
1564  }
1565  for (i = bstart; i < h; i++) {
1566  lines = datas + i * wpls;
1567  for (j = 0; j < w; j++)
1568  *(lines + j) = val;
1569  }
1570  }
1571 
1572  return 0;
1573 }
1574 
1575 
1591 l_ok
1593  l_int32 dist,
1594  l_uint32 val)
1595 {
1596 l_int32 w, h, d, i, j, xend, yend;
1597 
1598  PROCNAME("pixSetBorderRingVal");
1599 
1600  if (!pixs)
1601  return ERROR_INT("pixs not defined", procName, 1);
1602  if (dist < 1)
1603  return ERROR_INT("dist must be > 0", procName, 1);
1604  pixGetDimensions(pixs, &w, &h, &d);
1605  if (w < 2 * dist + 1 || h < 2 * dist + 1)
1606  return ERROR_INT("ring doesn't exist", procName, 1);
1607  if (d < 32 && (val >= (1 << d)))
1608  return ERROR_INT("invalid pixel value", procName, 1);
1609 
1610  xend = w - dist;
1611  yend = h - dist;
1612  for (j = dist - 1; j <= xend; j++)
1613  pixSetPixel(pixs, j, dist - 1, val);
1614  for (j = dist - 1; j <= xend; j++)
1615  pixSetPixel(pixs, j, yend, val);
1616  for (i = dist - 1; i <= yend; i++)
1617  pixSetPixel(pixs, dist - 1, i, val);
1618  for (i = dist - 1; i <= yend; i++)
1619  pixSetPixel(pixs, xend, i, val);
1620 
1621  return 0;
1622 }
1623 
1624 
1642 l_ok
1644  l_int32 left,
1645  l_int32 right,
1646  l_int32 top,
1647  l_int32 bot)
1648 {
1649 l_int32 i, j, w, h;
1650 
1651  PROCNAME("pixSetMirroredBorder");
1652 
1653  if (!pixs)
1654  return ERROR_INT("pixs not defined", procName, 1);
1655 
1656  pixGetDimensions(pixs, &w, &h, NULL);
1657  for (j = 0; j < left; j++)
1658  pixRasterop(pixs, left - 1 - j, top, 1, h - top - bot, PIX_SRC,
1659  pixs, left + j, top);
1660  for (j = 0; j < right; j++)
1661  pixRasterop(pixs, w - right + j, top, 1, h - top - bot, PIX_SRC,
1662  pixs, w - right - 1 - j, top);
1663  for (i = 0; i < top; i++)
1664  pixRasterop(pixs, 0, top - 1 - i, w, 1, PIX_SRC,
1665  pixs, 0, top + i);
1666  for (i = 0; i < bot; i++)
1667  pixRasterop(pixs, 0, h - bot + i, w, 1, PIX_SRC,
1668  pixs, 0, h - bot - 1 - i);
1669 
1670  return 0;
1671 }
1672 
1673 
1693 PIX *
1695  PIX *pixs,
1696  l_int32 left,
1697  l_int32 right,
1698  l_int32 top,
1699  l_int32 bot)
1700 {
1701 l_int32 w, h;
1702 
1703  PROCNAME("pixCopyBorder");
1704 
1705  if (!pixs)
1706  return (PIX *)ERROR_PTR("pixs not defined", procName, pixd);
1707 
1708  if (pixd) {
1709  if (pixd == pixs) {
1710  L_WARNING("same: nothing to do\n", procName);
1711  return pixd;
1712  } else if (!pixSizesEqual(pixs, pixd)) {
1713  return (PIX *)ERROR_PTR("pixs and pixd sizes differ",
1714  procName, pixd);
1715  }
1716  } else {
1717  if ((pixd = pixCreateTemplate(pixs)) == NULL)
1718  return (PIX *)ERROR_PTR("pixd not made", procName, pixd);
1719  }
1720 
1721  pixGetDimensions(pixs, &w, &h, NULL);
1722  pixRasterop(pixd, 0, 0, left, h, PIX_SRC, pixs, 0, 0);
1723  pixRasterop(pixd, w - right, 0, right, h, PIX_SRC, pixs, w - right, 0);
1724  pixRasterop(pixd, 0, 0, w, top, PIX_SRC, pixs, 0, 0);
1725  pixRasterop(pixd, 0, h - bot, w, bot, PIX_SRC, pixs, 0, h - bot);
1726  return pixd;
1727 }
1728 
1729 
1730 
1731 /*-------------------------------------------------------------*
1732  * Add and remove border *
1733  *-------------------------------------------------------------*/
1747 PIX *
1749  l_int32 npix,
1750  l_uint32 val)
1751 {
1752  PROCNAME("pixAddBorder");
1753 
1754  if (!pixs)
1755  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
1756  if (npix == 0)
1757  return pixClone(pixs);
1758  return pixAddBorderGeneral(pixs, npix, npix, npix, npix, val);
1759 }
1760 
1761 
1787 PIX *
1789  l_int32 left,
1790  l_int32 right,
1791  l_int32 top,
1792  l_int32 bot,
1793  l_int32 op)
1794 {
1795 l_uint32 val;
1796 
1797  PROCNAME("pixAddBlackOrWhiteBorder");
1798 
1799  if (!pixs)
1800  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
1801  if (op != L_GET_BLACK_VAL && op != L_GET_WHITE_VAL)
1802  return (PIX *)ERROR_PTR("invalid op", procName, NULL);
1803 
1804  pixGetBlackOrWhiteVal(pixs, op, &val);
1805  return pixAddBorderGeneral(pixs, left, right, top, bot, val);
1806 }
1807 
1808 
1841 PIX *
1843  l_int32 left,
1844  l_int32 right,
1845  l_int32 top,
1846  l_int32 bot,
1847  l_uint32 val)
1848 {
1849 l_int32 ws, hs, wd, hd, d, maxval, op;
1850 PIX *pixd;
1851 
1852  PROCNAME("pixAddBorderGeneral");
1853 
1854  if (!pixs)
1855  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
1856  if (left < 0 || right < 0 || top < 0 || bot < 0)
1857  return (PIX *)ERROR_PTR("negative border added!", procName, NULL);
1858 
1859  pixGetDimensions(pixs, &ws, &hs, &d);
1860  wd = ws + left + right;
1861  hd = hs + top + bot;
1862  if ((pixd = pixCreateNoInit(wd, hd, d)) == NULL)
1863  return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
1864  pixCopyResolution(pixd, pixs);
1865  pixCopyColormap(pixd, pixs);
1866 
1867  /* Set the new border pixels */
1868  maxval = (d == 32) ? 0xffffff00 : (1 << d) - 1;
1869  op = UNDEF;
1870  if (val == 0)
1871  op = PIX_CLR;
1872  else if (val >= maxval)
1873  op = PIX_SET;
1874  if (op == UNDEF) {
1875  pixSetAllArbitrary(pixd, val);
1876  } else { /* just set or clear the border pixels */
1877  pixRasterop(pixd, 0, 0, left, hd, op, NULL, 0, 0);
1878  pixRasterop(pixd, wd - right, 0, right, hd, op, NULL, 0, 0);
1879  pixRasterop(pixd, 0, 0, wd, top, op, NULL, 0, 0);
1880  pixRasterop(pixd, 0, hd - bot, wd, bot, op, NULL, 0, 0);
1881  }
1882 
1883  /* Copy pixs into the interior */
1884  pixRasterop(pixd, left, top, ws, hs, PIX_SRC, pixs, 0, 0);
1885  return pixd;
1886 }
1887 
1888 
1896 PIX *
1898  l_int32 npix)
1899 {
1900  PROCNAME("pixRemoveBorder");
1901 
1902  if (!pixs)
1903  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
1904  if (npix == 0)
1905  return pixClone(pixs);
1906  return pixRemoveBorderGeneral(pixs, npix, npix, npix, npix);
1907 }
1908 
1909 
1917 PIX *
1919  l_int32 left,
1920  l_int32 right,
1921  l_int32 top,
1922  l_int32 bot)
1923 {
1924 l_int32 ws, hs, wd, hd, d;
1925 PIX *pixd;
1926 
1927  PROCNAME("pixRemoveBorderGeneral");
1928 
1929  if (!pixs)
1930  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
1931  if (left < 0 || right < 0 || top < 0 || bot < 0)
1932  return (PIX *)ERROR_PTR("negative border removed!", procName, NULL);
1933 
1934  pixGetDimensions(pixs, &ws, &hs, &d);
1935  wd = ws - left - right;
1936  hd = hs - top - bot;
1937  if (wd <= 0)
1938  return (PIX *)ERROR_PTR("width must be > 0", procName, NULL);
1939  if (hd <= 0)
1940  return (PIX *)ERROR_PTR("height must be > 0", procName, NULL);
1941  if ((pixd = pixCreateNoInit(wd, hd, d)) == NULL)
1942  return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
1943  pixCopyResolution(pixd, pixs);
1944  pixCopySpp(pixd, pixs);
1945  pixCopyColormap(pixd, pixs);
1946 
1947  pixRasterop(pixd, 0, 0, wd, hd, PIX_SRC, pixs, left, top);
1948  if (pixGetDepth(pixs) == 32 && pixGetSpp(pixs) == 4)
1949  pixShiftAndTransferAlpha(pixd, pixs, -left, -top);
1950  return pixd;
1951 }
1952 
1953 
1970 PIX *
1972  l_int32 wd,
1973  l_int32 hd)
1974 {
1975 l_int32 w, h, top, bot, left, right, delta;
1976 
1977  PROCNAME("pixRemoveBorderToSize");
1978 
1979  if (!pixs)
1980  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
1981 
1982  pixGetDimensions(pixs, &w, &h, NULL);
1983  if ((wd <= 0 || wd >= w) && (hd <= 0 || hd >= h))
1984  return pixClone(pixs);
1985 
1986  left = right = (w - wd) / 2;
1987  delta = w - 2 * left - wd;
1988  right += delta;
1989  top = bot = (h - hd) / 2;
1990  delta = h - hd - 2 * top;
1991  bot += delta;
1992  if (wd <= 0 || wd > w)
1993  left = right = 0;
1994  else if (hd <= 0 || hd > h)
1995  top = bot = 0;
1996 
1997  return pixRemoveBorderGeneral(pixs, left, right, top, bot);
1998 }
1999 
2000 
2025 PIX *
2027  l_int32 left,
2028  l_int32 right,
2029  l_int32 top,
2030  l_int32 bot)
2031 {
2032 l_int32 i, j, w, h;
2033 PIX *pixd;
2034 
2035  PROCNAME("pixAddMirroredBorder");
2036 
2037  if (!pixs)
2038  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
2039  pixGetDimensions(pixs, &w, &h, NULL);
2040  if (left > w || right > w || top > h || bot > h)
2041  return (PIX *)ERROR_PTR("border too large", procName, NULL);
2042 
2043  /* Set pixels on left, right, top and bottom, in that order */
2044  pixd = pixAddBorderGeneral(pixs, left, right, top, bot, 0);
2045  for (j = 0; j < left; j++)
2046  pixRasterop(pixd, left - 1 - j, top, 1, h, PIX_SRC,
2047  pixd, left + j, top);
2048  for (j = 0; j < right; j++)
2049  pixRasterop(pixd, left + w + j, top, 1, h, PIX_SRC,
2050  pixd, left + w - 1 - j, top);
2051  for (i = 0; i < top; i++)
2052  pixRasterop(pixd, 0, top - 1 - i, left + w + right, 1, PIX_SRC,
2053  pixd, 0, top + i);
2054  for (i = 0; i < bot; i++)
2055  pixRasterop(pixd, 0, top + h + i, left + w + right, 1, PIX_SRC,
2056  pixd, 0, top + h - 1 - i);
2057 
2058  return pixd;
2059 }
2060 
2061 
2078 PIX *
2080  l_int32 left,
2081  l_int32 right,
2082  l_int32 top,
2083  l_int32 bot)
2084 {
2085 l_int32 w, h;
2086 PIX *pixd;
2087 
2088  PROCNAME("pixAddRepeatedBorder");
2089 
2090  if (!pixs)
2091  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
2092  pixGetDimensions(pixs, &w, &h, NULL);
2093  if (left > w || right > w || top > h || bot > h)
2094  return (PIX *)ERROR_PTR("border too large", procName, NULL);
2095 
2096  pixd = pixAddBorderGeneral(pixs, left, right, top, bot, 0);
2097 
2098  /* Set pixels on left, right, top and bottom, in that order */
2099  pixRasterop(pixd, 0, top, left, h, PIX_SRC, pixd, w, top);
2100  pixRasterop(pixd, left + w, top, right, h, PIX_SRC, pixd, left, top);
2101  pixRasterop(pixd, 0, 0, left + w + right, top, PIX_SRC, pixd, 0, h);
2102  pixRasterop(pixd, 0, top + h, left + w + right, bot, PIX_SRC, pixd, 0, top);
2103 
2104  return pixd;
2105 }
2106 
2107 
2134 PIX *
2136  l_int32 left,
2137  l_int32 right,
2138  l_int32 top,
2139  l_int32 bot)
2140 {
2141 l_int32 j, w, h;
2142 PIX *pixd;
2143 
2144  PROCNAME("pixAddMixedBorder");
2145 
2146  if (!pixs)
2147  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
2148  pixGetDimensions(pixs, &w, &h, NULL);
2149  if (left > w || right > w || top > h || bot > h)
2150  return (PIX *)ERROR_PTR("border too large", procName, NULL);
2151 
2152  /* Set mirrored pixels on left and right;
2153  * then set repeated pixels on top and bottom. */
2154  pixd = pixAddBorderGeneral(pixs, left, right, top, bot, 0);
2155  for (j = 0; j < left; j++)
2156  pixRasterop(pixd, left - 1 - j, top, 1, h, PIX_SRC,
2157  pixd, left + j, top);
2158  for (j = 0; j < right; j++)
2159  pixRasterop(pixd, left + w + j, top, 1, h, PIX_SRC,
2160  pixd, left + w - 1 - j, top);
2161  pixRasterop(pixd, 0, 0, left + w + right, top, PIX_SRC, pixd, 0, h);
2162  pixRasterop(pixd, 0, top + h, left + w + right, bot, PIX_SRC, pixd, 0, top);
2163 
2164  return pixd;
2165 }
2166 
2167 
2181 PIX *
2183  l_int32 left,
2184  l_int32 right,
2185  l_int32 top,
2186  l_int32 bot)
2187 {
2188 l_int32 i, j, w, h;
2189 PIX *pixd;
2190 
2191  PROCNAME("pixAddContinuedBorder");
2192 
2193  if (!pixs)
2194  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
2195 
2196  pixd = pixAddBorderGeneral(pixs, left, right, top, bot, 0);
2197  pixGetDimensions(pixs, &w, &h, NULL);
2198  for (j = 0; j < left; j++)
2199  pixRasterop(pixd, j, top, 1, h, PIX_SRC, pixd, left, top);
2200  for (j = 0; j < right; j++)
2201  pixRasterop(pixd, left + w + j, top, 1, h,
2202  PIX_SRC, pixd, left + w - 1, top);
2203  for (i = 0; i < top; i++)
2204  pixRasterop(pixd, 0, i, left + w + right, 1, PIX_SRC, pixd, 0, top);
2205  for (i = 0; i < bot; i++)
2206  pixRasterop(pixd, 0, top + h + i, left + w + right, 1,
2207  PIX_SRC, pixd, 0, top + h - 1);
2208 
2209  return pixd;
2210 }
2211 
2212 
2213 /*-------------------------------------------------------------------*
2214  * Helper functions using alpha *
2215  *-------------------------------------------------------------------*/
2224 l_ok
2226  PIX *pixs,
2227  l_float32 shiftx,
2228  l_float32 shifty)
2229 {
2230 l_int32 w, h;
2231 PIX *pix1, *pix2;
2232 
2233  PROCNAME("pixShiftAndTransferAlpha");
2234 
2235  if (!pixs || !pixd)
2236  return ERROR_INT("pixs and pixd not both defined", procName, 1);
2237  if (pixGetDepth(pixs) != 32 || pixGetSpp(pixs) != 4)
2238  return ERROR_INT("pixs not 32 bpp and 4 spp", procName, 1);
2239  if (pixGetDepth(pixd) != 32)
2240  return ERROR_INT("pixd not 32 bpp", procName, 1);
2241 
2242  if (shiftx == 0 && shifty == 0) {
2243  pixCopyRGBComponent(pixd, pixs, L_ALPHA_CHANNEL);
2244  return 0;
2245  }
2246 
2247  pix1 = pixGetRGBComponent(pixs, L_ALPHA_CHANNEL);
2248  pixGetDimensions(pixd, &w, &h, NULL);
2249  pix2 = pixCreate(w, h, 8);
2250  pixRasterop(pix2, 0, 0, w, h, PIX_SRC, pix1, -shiftx, -shifty);
2251  pixSetRGBComponent(pixd, pix2, L_ALPHA_CHANNEL);
2252  pixDestroy(&pix1);
2253  pixDestroy(&pix2);
2254  return 0;
2255 }
2256 
2257 
2275 PIX *
2277  l_uint32 val,
2278  l_int32 maxw)
2279 {
2280 l_int32 w, width;
2281 l_float32 scalefact;
2282 PIX *pix1, *pix2, *pixd;
2283 PIXA *pixa;
2284 PIXCMAP *cmap;
2285 
2286  PROCNAME("pixDisplayLayersRGBA");
2287 
2288  if (!pixs)
2289  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
2290  cmap = pixGetColormap(pixs);
2291  if (!cmap && !(pixGetDepth(pixs) == 32 && pixGetSpp(pixs) == 4))
2292  return (PIX *)ERROR_PTR("pixs not cmap and not 32 bpp rgba",
2293  procName, NULL);
2294  if ((w = pixGetWidth(pixs)) == 0)
2295  return (PIX *)ERROR_PTR("pixs width 0 !!", procName, NULL);
2296 
2297  if (cmap)
2299  else
2300  pix1 = pixCopy(NULL, pixs);
2301 
2302  /* Scale if necessary so the output width is not larger than maxw */
2303  scalefact = (maxw == 0) ? 1.0 : L_MIN(1.0, (l_float32)(maxw) / w);
2304  width = (l_int32)(scalefact * w);
2305 
2306  pixa = pixaCreate(3);
2307  pixSetSpp(pix1, 3);
2308  pixaAddPix(pixa, pix1, L_INSERT); /* show the rgb values */
2309  pix1 = pixGetRGBComponent(pixs, L_ALPHA_CHANNEL);
2310  pix2 = pixConvertTo32(pix1);
2311  pixaAddPix(pixa, pix2, L_INSERT); /* show the alpha channel */
2312  pixDestroy(&pix1);
2313  pix1 = pixAlphaBlendUniform(pixs, (val & 0xffffff00));
2314  pixaAddPix(pixa, pix1, L_INSERT); /* with %val color bg showing */
2315  pixd = pixaDisplayTiledInRows(pixa, 32, width, scalefact, 0, 25, 2);
2316  pixaDestroy(&pixa);
2317  return pixd;
2318 }
2319 
2320 
2321 /*-------------------------------------------------------------*
2322  * Color sample setting and extraction *
2323  *-------------------------------------------------------------*/
2347 PIX *
2349  PIX *pixg,
2350  PIX *pixb)
2351 {
2352 l_int32 wr, wg, wb, hr, hg, hb, dr, dg, db;
2353 PIX *pixd;
2354 
2355  PROCNAME("pixCreateRGBImage");
2356 
2357  if (!pixr)
2358  return (PIX *)ERROR_PTR("pixr not defined", procName, NULL);
2359  if (!pixg)
2360  return (PIX *)ERROR_PTR("pixg not defined", procName, NULL);
2361  if (!pixb)
2362  return (PIX *)ERROR_PTR("pixb not defined", procName, NULL);
2363  pixGetDimensions(pixr, &wr, &hr, &dr);
2364  pixGetDimensions(pixg, &wg, &hg, &dg);
2365  pixGetDimensions(pixb, &wb, &hb, &db);
2366  if (dr != 8 || dg != 8 || db != 8)
2367  return (PIX *)ERROR_PTR("input pix not all 8 bpp", procName, NULL);
2368  if (wr != wg || wr != wb)
2369  return (PIX *)ERROR_PTR("widths not the same", procName, NULL);
2370  if (hr != hg || hr != hb)
2371  return (PIX *)ERROR_PTR("heights not the same", procName, NULL);
2372 
2373  if ((pixd = pixCreate(wr, hr, 32)) == NULL)
2374  return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
2375  pixCopyResolution(pixd, pixr);
2376  pixSetRGBComponent(pixd, pixr, COLOR_RED);
2377  pixSetRGBComponent(pixd, pixg, COLOR_GREEN);
2378  pixSetRGBComponent(pixd, pixb, COLOR_BLUE);
2379 
2380  return pixd;
2381 }
2382 
2383 
2403 PIX *
2405  l_int32 comp)
2406 {
2407 l_int32 i, j, w, h, wpls, wpld, val;
2408 l_uint32 *lines, *lined;
2409 l_uint32 *datas, *datad;
2410 PIX *pixd;
2411 
2412  PROCNAME("pixGetRGBComponent");
2413 
2414  if (!pixs)
2415  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
2416  if (pixGetColormap(pixs))
2417  return pixGetRGBComponentCmap(pixs, comp);
2418  if (pixGetDepth(pixs) != 32)
2419  return (PIX *)ERROR_PTR("pixs not 32 bpp", procName, NULL);
2420  if (comp != COLOR_RED && comp != COLOR_GREEN &&
2421  comp != COLOR_BLUE && comp != L_ALPHA_CHANNEL)
2422  return (PIX *)ERROR_PTR("invalid comp", procName, NULL);
2423 
2424  pixGetDimensions(pixs, &w, &h, NULL);
2425  if ((pixd = pixCreate(w, h, 8)) == NULL)
2426  return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
2427  pixCopyResolution(pixd, pixs);
2428  wpls = pixGetWpl(pixs);
2429  wpld = pixGetWpl(pixd);
2430  datas = pixGetData(pixs);
2431  datad = pixGetData(pixd);
2432  for (i = 0; i < h; i++) {
2433  lines = datas + i * wpls;
2434  lined = datad + i * wpld;
2435  for (j = 0; j < w; j++) {
2436  val = GET_DATA_BYTE(lines + j, comp);
2437  SET_DATA_BYTE(lined, j, val);
2438  }
2439  }
2440 
2441  return pixd;
2442 }
2443 
2444 
2462 l_ok
2464  PIX *pixs,
2465  l_int32 comp)
2466 {
2467 l_uint8 srcbyte;
2468 l_int32 i, j, w, h, ws, hs, wd, hd;
2469 l_int32 wpls, wpld;
2470 l_uint32 *lines, *lined;
2471 l_uint32 *datas, *datad;
2472 
2473  PROCNAME("pixSetRGBComponent");
2474 
2475  if (!pixd)
2476  return ERROR_INT("pixd not defined", procName, 1);
2477  if (!pixs)
2478  return ERROR_INT("pixs not defined", procName, 1);
2479  if (pixGetDepth(pixd) != 32)
2480  return ERROR_INT("pixd not 32 bpp", procName, 1);
2481  if (pixGetDepth(pixs) != 8)
2482  return ERROR_INT("pixs not 8 bpp", procName, 1);
2483  if (comp != COLOR_RED && comp != COLOR_GREEN &&
2484  comp != COLOR_BLUE && comp != L_ALPHA_CHANNEL)
2485  return ERROR_INT("invalid comp", procName, 1);
2486  pixGetDimensions(pixs, &ws, &hs, NULL);
2487  pixGetDimensions(pixd, &wd, &hd, NULL);
2488  if (ws != wd || hs != hd)
2489  L_WARNING("images sizes not equal\n", procName);
2490  w = L_MIN(ws, wd);
2491  h = L_MIN(hs, hd);
2492  if (comp == L_ALPHA_CHANNEL)
2493  pixSetSpp(pixd, 4);
2494  datas = pixGetData(pixs);
2495  datad = pixGetData(pixd);
2496  wpls = pixGetWpl(pixs);
2497  wpld = pixGetWpl(pixd);
2498  for (i = 0; i < h; i++) {
2499  lines = datas + i * wpls;
2500  lined = datad + i * wpld;
2501  for (j = 0; j < w; j++) {
2502  srcbyte = GET_DATA_BYTE(lines, j);
2503  SET_DATA_BYTE(lined + j, comp, srcbyte);
2504  }
2505  }
2506 
2507  return 0;
2508 }
2509 
2510 
2524 PIX *
2526  l_int32 comp)
2527 {
2528 l_int32 i, j, w, h, val, index;
2529 l_int32 wplc, wpld;
2530 l_uint32 *linec, *lined;
2531 l_uint32 *datac, *datad;
2532 PIX *pixc, *pixd;
2533 PIXCMAP *cmap;
2534 RGBA_QUAD *cta;
2535 
2536  PROCNAME("pixGetRGBComponentCmap");
2537 
2538  if (!pixs)
2539  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
2540  if ((cmap = pixGetColormap(pixs)) == NULL)
2541  return (PIX *)ERROR_PTR("pixs not cmapped", procName, NULL);
2542  if (comp == L_ALPHA_CHANNEL)
2543  return (PIX *)ERROR_PTR("alpha in cmaps not supported", procName, NULL);
2544  if (comp != COLOR_RED && comp != COLOR_GREEN && comp != COLOR_BLUE)
2545  return (PIX *)ERROR_PTR("invalid comp", procName, NULL);
2546 
2547  /* If not 8 bpp, make a cmapped 8 bpp pix */
2548  if (pixGetDepth(pixs) == 8)
2549  pixc = pixClone(pixs);
2550  else
2551  pixc = pixConvertTo8(pixs, TRUE);
2552 
2553  pixGetDimensions(pixs, &w, &h, NULL);
2554  if ((pixd = pixCreateNoInit(w, h, 8)) == NULL) {
2555  pixDestroy(&pixc);
2556  return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
2557  }
2558  pixCopyResolution(pixd, pixs);
2559  wplc = pixGetWpl(pixc);
2560  wpld = pixGetWpl(pixd);
2561  datac = pixGetData(pixc);
2562  datad = pixGetData(pixd);
2563  cta = (RGBA_QUAD *)cmap->array;
2564 
2565  for (i = 0; i < h; i++) {
2566  linec = datac + i * wplc;
2567  lined = datad + i * wpld;
2568  if (comp == COLOR_RED) {
2569  for (j = 0; j < w; j++) {
2570  index = GET_DATA_BYTE(linec, j);
2571  val = cta[index].red;
2572  SET_DATA_BYTE(lined, j, val);
2573  }
2574  } else if (comp == COLOR_GREEN) {
2575  for (j = 0; j < w; j++) {
2576  index = GET_DATA_BYTE(linec, j);
2577  val = cta[index].green;
2578  SET_DATA_BYTE(lined, j, val);
2579  }
2580  } else if (comp == COLOR_BLUE) {
2581  for (j = 0; j < w; j++) {
2582  index = GET_DATA_BYTE(linec, j);
2583  val = cta[index].blue;
2584  SET_DATA_BYTE(lined, j, val);
2585  }
2586  }
2587  }
2588 
2589  pixDestroy(&pixc);
2590  return pixd;
2591 }
2592 
2593 
2609 l_ok
2611  PIX *pixs,
2612  l_int32 comp)
2613 {
2614 l_int32 i, j, w, h, ws, hs, wd, hd, val;
2615 l_int32 wpls, wpld;
2616 l_uint32 *lines, *lined;
2617 l_uint32 *datas, *datad;
2618 
2619  PROCNAME("pixCopyRGBComponent");
2620 
2621  if (!pixd && pixGetDepth(pixd) != 32)
2622  return ERROR_INT("pixd not defined or not 32 bpp", procName, 1);
2623  if (!pixs && pixGetDepth(pixs) != 32)
2624  return ERROR_INT("pixs not defined or not 32 bpp", procName, 1);
2625  if (comp != COLOR_RED && comp != COLOR_GREEN &&
2626  comp != COLOR_BLUE && comp != L_ALPHA_CHANNEL)
2627  return ERROR_INT("invalid component", procName, 1);
2628  pixGetDimensions(pixs, &ws, &hs, NULL);
2629  pixGetDimensions(pixd, &wd, &hd, NULL);
2630  if (ws != wd || hs != hd)
2631  L_WARNING("images sizes not equal\n", procName);
2632  w = L_MIN(ws, wd);
2633  h = L_MIN(hs, hd);
2634  if (comp == L_ALPHA_CHANNEL)
2635  pixSetSpp(pixd, 4);
2636  wpls = pixGetWpl(pixs);
2637  wpld = pixGetWpl(pixd);
2638  datas = pixGetData(pixs);
2639  datad = pixGetData(pixd);
2640  for (i = 0; i < h; i++) {
2641  lines = datas + i * wpls;
2642  lined = datad + i * wpld;
2643  for (j = 0; j < w; j++) {
2644  val = GET_DATA_BYTE(lines + j, comp);
2645  SET_DATA_BYTE(lined + j, comp, val);
2646  }
2647  }
2648  return 0;
2649 }
2650 
2651 
2670 l_ok
2671 composeRGBPixel(l_int32 rval,
2672  l_int32 gval,
2673  l_int32 bval,
2674  l_uint32 *ppixel)
2675 {
2676  PROCNAME("composeRGBPixel");
2677 
2678  if (!ppixel)
2679  return ERROR_INT("&pixel not defined", procName, 1);
2680 
2681  *ppixel = ((l_uint32)rval << L_RED_SHIFT) | (gval << L_GREEN_SHIFT) |
2682  (bval << L_BLUE_SHIFT);
2683  return 0;
2684 }
2685 
2686 
2701 l_ok
2702 composeRGBAPixel(l_int32 rval,
2703  l_int32 gval,
2704  l_int32 bval,
2705  l_int32 aval,
2706  l_uint32 *ppixel)
2707 {
2708  PROCNAME("composeRGBAPixel");
2709 
2710  if (!ppixel)
2711  return ERROR_INT("&pixel not defined", procName, 1);
2712 
2713  *ppixel = ((l_uint32)rval << L_RED_SHIFT) | (gval << L_GREEN_SHIFT) |
2714  (bval << L_BLUE_SHIFT) | aval;
2715  return 0;
2716 }
2717 
2718 
2736 void
2737 extractRGBValues(l_uint32 pixel,
2738  l_int32 *prval,
2739  l_int32 *pgval,
2740  l_int32 *pbval)
2741 {
2742  if (prval) *prval = (pixel >> L_RED_SHIFT) & 0xff;
2743  if (pgval) *pgval = (pixel >> L_GREEN_SHIFT) & 0xff;
2744  if (pbval) *pbval = (pixel >> L_BLUE_SHIFT) & 0xff;
2745  return;
2746 }
2747 
2748 
2759 void
2760 extractRGBAValues(l_uint32 pixel,
2761  l_int32 *prval,
2762  l_int32 *pgval,
2763  l_int32 *pbval,
2764  l_int32 *paval)
2765 {
2766  if (prval) *prval = (pixel >> L_RED_SHIFT) & 0xff;
2767  if (pgval) *pgval = (pixel >> L_GREEN_SHIFT) & 0xff;
2768  if (pbval) *pbval = (pixel >> L_BLUE_SHIFT) & 0xff;
2769  if (paval) *paval = (pixel >> L_ALPHA_SHIFT) & 0xff;
2770  return;
2771 }
2772 
2773 
2781 l_int32
2782 extractMinMaxComponent(l_uint32 pixel,
2783  l_int32 type)
2784 {
2785 l_int32 rval, gval, bval, val;
2786 
2787  extractRGBValues(pixel, &rval, &gval, &bval);
2788  if (type == L_CHOOSE_MIN) {
2789  val = L_MIN(rval, gval);
2790  val = L_MIN(val, bval);
2791  } else { /* type == L_CHOOSE_MAX */
2792  val = L_MAX(rval, gval);
2793  val = L_MAX(val, bval);
2794  }
2795  return val;
2796 }
2797 
2798 
2815 l_ok
2817  l_int32 row,
2818  l_uint8 *bufr,
2819  l_uint8 *bufg,
2820  l_uint8 *bufb)
2821 {
2822 l_uint32 *lines;
2823 l_int32 j, w, h;
2824 l_int32 wpls;
2825 
2826  PROCNAME("pixGetRGBLine");
2827 
2828  if (!pixs)
2829  return ERROR_INT("pixs not defined", procName, 1);
2830  if (pixGetDepth(pixs) != 32)
2831  return ERROR_INT("pixs not 32 bpp", procName, 1);
2832  if (!bufr || !bufg || !bufb)
2833  return ERROR_INT("buffer not defined", procName, 1);
2834 
2835  pixGetDimensions(pixs, &w, &h, NULL);
2836  if (row < 0 || row >= h)
2837  return ERROR_INT("row out of bounds", procName, 1);
2838  wpls = pixGetWpl(pixs);
2839  lines = pixGetData(pixs) + row * wpls;
2840 
2841  for (j = 0; j < w; j++) {
2842  bufr[j] = GET_DATA_BYTE(lines + j, COLOR_RED);
2843  bufg[j] = GET_DATA_BYTE(lines + j, COLOR_GREEN);
2844  bufb[j] = GET_DATA_BYTE(lines + j, COLOR_BLUE);
2845  }
2846 
2847  return 0;
2848 }
2849 
2850 
2851 /*-------------------------------------------------------------*
2852  * Pixel endian conversion *
2853  *-------------------------------------------------------------*/
2878 PIX *
2880 {
2881 l_uint32 *datas, *datad;
2882 l_int32 i, j, h, wpl;
2883 l_uint32 word;
2884 PIX *pixd;
2885 
2886  PROCNAME("pixEndianByteSwapNew");
2887 
2888 #ifdef L_BIG_ENDIAN
2889 
2890  return pixClone(pixs);
2891 
2892 #else /* L_LITTLE_ENDIAN */
2893 
2894  if (!pixs)
2895  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
2896 
2897  datas = pixGetData(pixs);
2898  wpl = pixGetWpl(pixs);
2899  h = pixGetHeight(pixs);
2900  pixd = pixCreateTemplate(pixs);
2901  datad = pixGetData(pixd);
2902  for (i = 0; i < h; i++) {
2903  for (j = 0; j < wpl; j++, datas++, datad++) {
2904  word = *datas;
2905  *datad = (word >> 24) |
2906  ((word >> 8) & 0x0000ff00) |
2907  ((word << 8) & 0x00ff0000) |
2908  (word << 24);
2909  }
2910  }
2911 
2912  return pixd;
2913 
2914 #endif /* L_BIG_ENDIAN */
2915 
2916 }
2917 
2918 
2941 l_ok
2943 {
2944 l_uint32 *data;
2945 l_int32 i, j, h, wpl;
2946 l_uint32 word;
2947 
2948  PROCNAME("pixEndianByteSwap");
2949 
2950 #ifdef L_BIG_ENDIAN
2951 
2952  return 0;
2953 
2954 #else /* L_LITTLE_ENDIAN */
2955 
2956  if (!pixs)
2957  return ERROR_INT("pixs not defined", procName, 1);
2958 
2959  data = pixGetData(pixs);
2960  wpl = pixGetWpl(pixs);
2961  h = pixGetHeight(pixs);
2962  for (i = 0; i < h; i++) {
2963  for (j = 0; j < wpl; j++, data++) {
2964  word = *data;
2965  *data = (word >> 24) |
2966  ((word >> 8) & 0x0000ff00) |
2967  ((word << 8) & 0x00ff0000) |
2968  (word << 24);
2969  }
2970  }
2971 
2972  return 0;
2973 
2974 #endif /* L_BIG_ENDIAN */
2975 
2976 }
2977 
2978 
2999 l_int32
3000 lineEndianByteSwap(l_uint32 *datad,
3001  l_uint32 *datas,
3002  l_int32 wpl)
3003 {
3004 l_int32 j;
3005 l_uint32 word;
3006 
3007  PROCNAME("lineEndianByteSwap");
3008 
3009  if (!datad || !datas)
3010  return ERROR_INT("datad and datas not both defined", procName, 1);
3011 
3012 #ifdef L_BIG_ENDIAN
3013 
3014  memcpy(datad, datas, 4 * wpl);
3015  return 0;
3016 
3017 #else /* L_LITTLE_ENDIAN */
3018 
3019  for (j = 0; j < wpl; j++, datas++, datad++) {
3020  word = *datas;
3021  *datad = (word >> 24) |
3022  ((word >> 8) & 0x0000ff00) |
3023  ((word << 8) & 0x00ff0000) |
3024  (word << 24);
3025  }
3026  return 0;
3027 
3028 #endif /* L_BIG_ENDIAN */
3029 
3030 }
3031 
3032 
3052 PIX *
3054 {
3055 l_uint32 *datas, *datad;
3056 l_int32 i, j, h, wpl;
3057 l_uint32 word;
3058 PIX *pixd;
3059 
3060  PROCNAME("pixEndianTwoByteSwapNew");
3061 
3062 #ifdef L_BIG_ENDIAN
3063 
3064  return pixClone(pixs);
3065 
3066 #else /* L_LITTLE_ENDIAN */
3067 
3068  if (!pixs)
3069  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
3070 
3071  datas = pixGetData(pixs);
3072  wpl = pixGetWpl(pixs);
3073  h = pixGetHeight(pixs);
3074  pixd = pixCreateTemplate(pixs);
3075  datad = pixGetData(pixd);
3076  for (i = 0; i < h; i++) {
3077  for (j = 0; j < wpl; j++, datas++, datad++) {
3078  word = *datas;
3079  *datad = (word << 16) | (word >> 16);
3080  }
3081  }
3082 
3083  return pixd;
3084 
3085 #endif /* L_BIG_ENDIAN */
3086 
3087 }
3088 
3089 
3105 l_ok
3107 {
3108 l_uint32 *data;
3109 l_int32 i, j, h, wpl;
3110 l_uint32 word;
3111 
3112  PROCNAME("pixEndianTwoByteSwap");
3113 
3114 #ifdef L_BIG_ENDIAN
3115 
3116  return 0;
3117 
3118 #else /* L_LITTLE_ENDIAN */
3119 
3120  if (!pixs)
3121  return ERROR_INT("pixs not defined", procName, 1);
3122 
3123  data = pixGetData(pixs);
3124  wpl = pixGetWpl(pixs);
3125  h = pixGetHeight(pixs);
3126  for (i = 0; i < h; i++) {
3127  for (j = 0; j < wpl; j++, data++) {
3128  word = *data;
3129  *data = (word << 16) | (word >> 16);
3130  }
3131  }
3132 
3133  return 0;
3134 
3135 #endif /* L_BIG_ENDIAN */
3136 
3137 }
3138 
3139 
3140 /*-------------------------------------------------------------*
3141  * Extract raster data as binary string *
3142  *-------------------------------------------------------------*/
3159 l_ok
3161  l_uint8 **pdata,
3162  size_t *pnbytes)
3163 {
3164 l_int32 w, h, d, wpl, i, j, rval, gval, bval;
3165 l_int32 databpl; /* bytes for each raster line in returned data */
3166 l_uint8 *line, *data; /* packed data in returned array */
3167 l_uint32 *rline, *rdata; /* data in pix raster */
3168 
3169  PROCNAME("pixGetRasterData");
3170 
3171  if (pdata) *pdata = NULL;
3172  if (pnbytes) *pnbytes = 0;
3173  if (!pdata || !pnbytes)
3174  return ERROR_INT("&data and &nbytes not both defined", procName, 1);
3175  if (!pixs)
3176  return ERROR_INT("pixs not defined", procName, 1);
3177  pixGetDimensions(pixs, &w, &h, &d);
3178  if (d != 1 && d != 2 && d != 4 && d != 8 && d != 16 && d != 32)
3179  return ERROR_INT("depth not in {1,2,4,8,16,32}", procName, 1);
3180  rdata = pixGetData(pixs);
3181  wpl = pixGetWpl(pixs);
3182  if (d == 1)
3183  databpl = (w + 7) / 8;
3184  else if (d == 2)
3185  databpl = (w + 3) / 4;
3186  else if (d == 4)
3187  databpl = (w + 1) / 2;
3188  else if (d == 8 || d == 16)
3189  databpl = w * (d / 8);
3190  else /* d == 32 bpp rgb */
3191  databpl = 3 * w;
3192  if ((data = (l_uint8 *)LEPT_CALLOC((size_t)databpl * h, sizeof(l_uint8)))
3193  == NULL)
3194  return ERROR_INT("data not allocated", procName, 1);
3195  *pdata = data;
3196  *pnbytes = (size_t)databpl * h;
3197 
3198  for (i = 0; i < h; i++) {
3199  rline = rdata + i * wpl;
3200  line = data + i * databpl;
3201  if (d <= 8) {
3202  for (j = 0; j < databpl; j++)
3203  line[j] = GET_DATA_BYTE(rline, j);
3204  } else if (d == 16) {
3205  for (j = 0; j < w; j++)
3206  line[2 * j] = GET_DATA_TWO_BYTES(rline, j);
3207  } else { /* d == 32 bpp rgb */
3208  for (j = 0; j < w; j++) {
3209  extractRGBValues(rline[j], &rval, &gval, &bval);
3210  *(line + 3 * j) = rval;
3211  *(line + 3 * j + 1) = gval;
3212  *(line + 3 * j + 2) = bval;
3213  }
3214  }
3215  }
3216 
3217  return 0;
3218 }
3219 
3220 
3221 /*-------------------------------------------------------------*
3222  * Test alpha component opaqueness *
3223  *-------------------------------------------------------------*/
3234 l_ok
3236  l_int32 *popaque)
3237 {
3238 l_int32 w, h, wpl, i, j, alpha;
3239 l_uint32 *data, *line;
3240 
3241  PROCNAME("pixAlphaIsOpaque");
3242 
3243  if (!popaque)
3244  return ERROR_INT("&opaque not defined", procName, 1);
3245  *popaque = FALSE;
3246  if (!pix)
3247  return ERROR_INT("&pix not defined", procName, 1);
3248  if (pixGetDepth(pix) != 32)
3249  return ERROR_INT("&pix not 32 bpp", procName, 1);
3250  if (pixGetSpp(pix) != 4)
3251  return ERROR_INT("&pix not 4 spp", procName, 1);
3252 
3253  data = pixGetData(pix);
3254  wpl = pixGetWpl(pix);
3255  pixGetDimensions(pix, &w, &h, NULL);
3256  for (i = 0; i < h; i++) {
3257  line = data + i * wpl;
3258  for (j = 0; j < w; j++) {
3259  alpha = GET_DATA_BYTE(line + j, L_ALPHA_CHANNEL);
3260  if (alpha ^ 0xff) /* not opaque */
3261  return 0;
3262  }
3263  }
3264 
3265  *popaque = TRUE;
3266  return 0;
3267 }
3268 
3269 
3270 /*-------------------------------------------------------------*
3271  * Setup helpers for 8 bpp byte processing *
3272  *-------------------------------------------------------------*/
3299 l_uint8 **
3301  l_int32 *pw,
3302  l_int32 *ph)
3303 {
3304 l_int32 w, h;
3305 
3306  PROCNAME("pixSetupByteProcessing");
3307 
3308  if (pw) *pw = 0;
3309  if (ph) *ph = 0;
3310  if (!pix || pixGetDepth(pix) != 8)
3311  return (l_uint8 **)ERROR_PTR("pix not defined or not 8 bpp",
3312  procName, NULL);
3313  pixGetDimensions(pix, &w, &h, NULL);
3314  if (pw) *pw = w;
3315  if (ph) *ph = h;
3316  if (pixGetColormap(pix))
3317  return (l_uint8 **)ERROR_PTR("pix has colormap", procName, NULL);
3318 
3319  pixEndianByteSwap(pix);
3320  return (l_uint8 **)pixGetLinePtrs(pix, NULL);
3321 }
3322 
3323 
3337 l_ok
3339  l_uint8 **lineptrs)
3340 {
3341  PROCNAME("pixCleanupByteProcessing");
3342 
3343  if (!pix)
3344  return ERROR_INT("pix not defined", procName, 1);
3345  if (!lineptrs)
3346  return ERROR_INT("lineptrs not defined", procName, 1);
3347 
3348  pixEndianByteSwap(pix);
3349  LEPT_FREE(lineptrs);
3350  return 0;
3351 }
3352 
3353 
3354 /*------------------------------------------------------------------------*
3355  * Setting parameters for antialias masking with alpha transforms *
3356  *------------------------------------------------------------------------*/
3379 void
3380 l_setAlphaMaskBorder(l_float32 val1,
3381  l_float32 val2)
3382 {
3383  val1 = L_MAX(0.0, L_MIN(1.0, val1));
3384  val2 = L_MAX(0.0, L_MIN(1.0, val2));
3385  AlphaMaskBorderVals[0] = val1;
3386  AlphaMaskBorderVals[1] = val2;
3387 }
l_ok pixSetPadBitsBand(PIX *pix, l_int32 by, l_int32 bh, l_int32 val)
pixSetPadBitsBand()
Definition: pix2.c:1367
l_ok pixCopyRGBComponent(PIX *pixd, PIX *pixs, l_int32 comp)
pixCopyRGBComponent()
Definition: pix2.c:2610
l_int32 lineEndianByteSwap(l_uint32 *datad, l_uint32 *datas, l_int32 wpl)
lineEndianByteSwap()
Definition: pix2.c:3000
l_ok pixSetRGBPixel(PIX *pix, l_int32 x, l_int32 y, l_int32 rval, l_int32 gval, l_int32 bval)
pixSetRGBPixel()
Definition: pix2.c:368
PIX * pixAddMixedBorder(PIX *pixs, l_int32 left, l_int32 right, l_int32 top, l_int32 bot)
pixAddMixedBorder()
Definition: pix2.c:2135
PIX * pixRemoveColormap(PIX *pixs, l_int32 type)
pixRemoveColormap()
Definition: pixconv.c:322
l_ok pixSetRGBComponent(PIX *pixd, PIX *pixs, l_int32 comp)
pixSetRGBComponent()
Definition: pix2.c:2463
Definition: pix.h:717
l_ok pixCleanupByteProcessing(PIX *pix, l_uint8 **lineptrs)
pixCleanupByteProcessing()
Definition: pix2.c:3338
PIX * pixConvertTo32(PIX *pixs)
pixConvertTo32()
Definition: pixconv.c:3233
#define PIX_CLR
Definition: pix.h:330
PIX * pixRemoveBorderGeneral(PIX *pixs, l_int32 left, l_int32 right, l_int32 top, l_int32 bot)
pixRemoveBorderGeneral()
Definition: pix2.c:1918
l_ok pixSetComponentArbitrary(PIX *pix, l_int32 comp, l_int32 val)
pixSetComponentArbitrary()
Definition: pix2.c:993
void extractRGBAValues(l_uint32 pixel, l_int32 *prval, l_int32 *pgval, l_int32 *pbval, l_int32 *paval)
extractRGBAValues()
Definition: pix2.c:2760
l_ok pixSetInRectArbitrary(PIX *pix, BOX *box, l_uint32 val)
pixSetInRectArbitrary()
Definition: pix2.c:1120
PIXA * pixaCreate(l_int32 n)
pixaCreate()
Definition: pixabasic.c:163
void setPixelLow(l_uint32 *line, l_int32 x, l_int32 depth, l_uint32 val)
setPixelLow()
Definition: pix2.c:600
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:193
l_ok pixGetRasterData(PIX *pixs, l_uint8 **pdata, size_t *pnbytes)
pixGetRasterData()
Definition: pix2.c:3160
PIX * pixConvertTo8(PIX *pixs, l_int32 cmapflag)
pixConvertTo8()
Definition: pixconv.c:3041
void ** pixGetLinePtrs(PIX *pix, l_int32 *psize)
pixGetLinePtrs()
Definition: pix1.c:1810
l_ok pixShiftAndTransferAlpha(PIX *pixd, PIX *pixs, l_float32 shiftx, l_float32 shifty)
pixShiftAndTransferAlpha()
Definition: pix2.c:2225
l_uint8 red
Definition: pix.h:173
BOX * boxClipToRectangle(BOX *box, l_int32 wi, l_int32 hi)
boxClipToRectangle()
Definition: boxfunc1.c:1587
PIX * pixCreate(l_int32 width, l_int32 height, l_int32 depth)
pixCreate()
Definition: pix1.c:302
l_ok pixSetAll(PIX *pix)
pixSetAll()
Definition: pix2.c:741
#define SET_DATA_QBIT(pdata, n, val)
Definition: arrayaccess.h:168
PIX * pixAddMirroredBorder(PIX *pixs, l_int32 left, l_int32 right, l_int32 top, l_int32 bot)
pixAddMirroredBorder()
Definition: pix2.c:2026
l_uint32 * pixGetData(PIX *pix)
pixGetData()
Definition: pix1.c:1624
PIX * pixAddBlackOrWhiteBorder(PIX *pixs, l_int32 left, l_int32 right, l_int32 top, l_int32 bot, l_int32 op)
pixAddBlackOrWhiteBorder()
Definition: pix2.c:1788
#define GET_DATA_BIT(pdata, n)
Definition: arrayaccess.h:123
PIX * pixCreateTemplate(PIX *pixs)
pixCreateTemplate()
Definition: pix1.c:367
l_ok pixClearInRect(PIX *pix, BOX *box)
pixClearInRect()
Definition: pix2.c:1043
l_ok pixSetAllGray(PIX *pix, l_int32 grayval)
pixSetAllGray()
Definition: pix2.c:784
l_ok pixSetOrClearBorder(PIX *pixs, l_int32 left, l_int32 right, l_int32 top, l_int32 bot, l_int32 op)
pixSetOrClearBorder()
Definition: pix2.c:1439
PIX * pixGetRGBComponent(PIX *pixs, l_int32 comp)
pixGetRGBComponent()
Definition: pix2.c:2404
l_uint8 blue
Definition: pix.h:171
PIX * pixAddBorder(PIX *pixs, l_int32 npix, l_uint32 val)
pixAddBorder()
Definition: pix2.c:1748
l_ok pixGetRandomPixel(PIX *pix, l_uint32 *pval, l_int32 *px, l_int32 *py)
pixGetRandomPixel()
Definition: pix2.c:413
#define SET_DATA_DIBIT(pdata, n, val)
Definition: arrayaccess.h:149
l_ok pixSetAllArbitrary(PIX *pix, l_uint32 val)
pixSetAllArbitrary()
Definition: pix2.c:876
l_ok pixSetBorderVal(PIX *pixs, l_int32 left, l_int32 right, l_int32 top, l_int32 bot, l_uint32 val)
pixSetBorderVal()
Definition: pix2.c:1488
#define CLEAR_DATA_BIT(pdata, n)
Definition: arrayaccess.h:131
PIX * pixEndianTwoByteSwapNew(PIX *pixs)
pixEndianTwoByteSwapNew()
Definition: pix2.c:3053
PIX * pixAlphaBlendUniform(PIX *pixs, l_uint32 color)
pixAlphaBlendUniform()
Definition: blend.c:2004
PIX * pixRemoveBorder(PIX *pixs, l_int32 npix)
pixRemoveBorder()
Definition: pix2.c:1897
l_ok pixaAddPix(PIXA *pixa, PIX *pix, l_int32 copyflag)
pixaAddPix()
Definition: pixabasic.c:503
l_uint8 ** pixSetupByteProcessing(PIX *pix, l_int32 *pw, l_int32 *ph)
pixSetupByteProcessing()
Definition: pix2.c:3300
l_ok pixFlipPixel(PIX *pix, l_int32 x, l_int32 y)
pixFlipPixel()
Definition: pix2.c:523
l_ok pixClearPixel(PIX *pix, l_int32 x, l_int32 y)
pixClearPixel()
Definition: pix2.c:463
#define CLEAR_DATA_DIBIT(pdata, n)
Definition: arrayaccess.h:156
l_ok pixClearAll(PIX *pix)
pixClearAll()
Definition: pix2.c:712
#define PIX_SET
Definition: pix.h:331
l_ok pixSetBorderRingVal(PIX *pixs, l_int32 dist, l_uint32 val)
pixSetBorderRingVal()
Definition: pix2.c:1592
l_ok pixSetPixel(PIX *pix, l_int32 x, l_int32 y, l_uint32 val)
pixSetPixel()
Definition: pix2.c:253
PIX * pixaDisplayTiledInRows(PIXA *pixa, l_int32 outdepth, l_int32 maxwidth, l_float32 scalefactor, l_int32 background, l_int32 spacing, l_int32 border)
pixaDisplayTiledInRows()
Definition: pixafunc2.c:836
l_ok pixcmapGetColor(PIXCMAP *cmap, l_int32 index, l_int32 *prval, l_int32 *pgval, l_int32 *pbval)
pixcmapGetColor()
Definition: colormap.c:751
l_int32 extractMinMaxComponent(l_uint32 pixel, l_int32 type)
extractMinMaxComponent()
Definition: pix2.c:2782
l_ok pixEndianByteSwap(PIX *pixs)
pixEndianByteSwap()
Definition: pix2.c:2942
l_ok composeRGBAPixel(l_int32 rval, l_int32 gval, l_int32 bval, l_int32 aval, l_uint32 *ppixel)
composeRGBAPixel()
Definition: pix2.c:2702
#define SET_DATA_BYTE(pdata, n, val)
Definition: arrayaccess.h:198
l_ok pixSetPadBits(PIX *pix, l_int32 val)
pixSetPadBits()
Definition: pix2.c:1307
#define GET_DATA_QBIT(pdata, n)
Definition: arrayaccess.h:164
l_ok pixSetBlackOrWhite(PIX *pixs, l_int32 op)
pixSetBlackOrWhite()
Definition: pix2.c:946
l_ok pixEndianTwoByteSwap(PIX *pixs)
pixEndianTwoByteSwap()
Definition: pix2.c:3106
#define CLEAR_DATA_QBIT(pdata, n)
Definition: arrayaccess.h:175
#define GET_DATA_BYTE(pdata, n)
Definition: arrayaccess.h:188
l_uint8 green
Definition: pix.h:172
Definition: pix.h:169
PIX * pixCreateRGBImage(PIX *pixr, PIX *pixg, PIX *pixb)
pixCreateRGBImage()
Definition: pix2.c:2348
PIX * pixAddContinuedBorder(PIX *pixs, l_int32 left, l_int32 right, l_int32 top, l_int32 bot)
pixAddContinuedBorder()
Definition: pix2.c:2182
PIX * pixCreateNoInit(l_int32 width, l_int32 height, l_int32 depth)
pixCreateNoInit()
Definition: pix1.c:331
PIX * pixClone(PIX *pixs)
pixClone()
Definition: pix1.c:515
void pixDestroy(PIX **ppix)
pixDestroy()
Definition: pix1.c:543
l_ok pixCopyColormap(PIX *pixd, PIX *pixs)
pixCopyColormap()
Definition: pix1.c:745
l_ok pixcmapAddNearestColor(PIXCMAP *cmap, l_int32 rval, l_int32 gval, l_int32 bval, l_int32 *pindex)
pixcmapAddNearestColor()
Definition: colormap.c:472
l_ok pixGetRGBLine(PIX *pixs, l_int32 row, l_uint8 *bufr, l_uint8 *bufg, l_uint8 *bufb)
pixGetRGBLine()
Definition: pix2.c:2816
PIX * pixGetRGBComponentCmap(PIX *pixs, l_int32 comp)
pixGetRGBComponentCmap()
Definition: pix2.c:2525
l_ok pixGetBlackOrWhiteVal(PIX *pixs, l_int32 op, l_uint32 *pval)
pixGetBlackOrWhiteVal()
Definition: pix2.c:656
Definition: pix.h:454
l_ok pixGetPixel(PIX *pix, l_int32 x, l_int32 y, l_uint32 *pval)
pixGetPixel()
Definition: pix2.c:180
PIX * pixEndianByteSwapNew(PIX *pixs)
pixEndianByteSwapNew()
Definition: pix2.c:2879
l_ok pixGetRGBPixel(PIX *pix, l_int32 x, l_int32 y, l_int32 *prval, l_int32 *pgval, l_int32 *pbval)
pixGetRGBPixel()
Definition: pix2.c:318
l_ok pixGetDimensions(const PIX *pix, l_int32 *pw, l_int32 *ph, l_int32 *pd)
pixGetDimensions()
Definition: pix1.c:1065
PIX * pixAddRepeatedBorder(PIX *pixs, l_int32 left, l_int32 right, l_int32 top, l_int32 bot)
pixAddRepeatedBorder()
Definition: pix2.c:2079
l_ok pixSetMirroredBorder(PIX *pixs, l_int32 left, l_int32 right, l_int32 top, l_int32 bot)
pixSetMirroredBorder()
Definition: pix2.c:1643
void l_setAlphaMaskBorder(l_float32 val1, l_float32 val2)
l_setAlphaMaskBorder()
Definition: pix2.c:3380
l_ok pixcmapAddBlackOrWhite(PIXCMAP *cmap, l_int32 color, l_int32 *pindex)
pixcmapAddBlackOrWhite()
Definition: colormap.c:566
#define GET_DATA_TWO_BYTES(pdata, n)
Definition: arrayaccess.h:212
#define GET_DATA_DIBIT(pdata, n)
Definition: arrayaccess.h:145
void * array
Definition: pix.h:157
PIX * pixDisplayLayersRGBA(PIX *pixs, l_uint32 val, l_int32 maxw)
pixDisplayLayersRGBA()
Definition: pix2.c:2276
l_int32 pixcmapGetCount(PIXCMAP *cmap)
pixcmapGetCount()
Definition: colormap.c:635
Definition: pix.h:134
#define PIX_SRC
Definition: pix.h:327
PIX * pixCopy(PIX *pixd, PIX *pixs)
pixCopy()
Definition: pix1.c:628
l_ok pixAlphaIsOpaque(PIX *pix, l_int32 *popaque)
pixAlphaIsOpaque()
Definition: pix2.c:3235
void boxDestroy(BOX **pbox)
boxDestroy()
Definition: boxbasic.c:278
Definition: pix.h:201
PIX * pixRemoveBorderToSize(PIX *pixs, l_int32 wd, l_int32 hd)
pixRemoveBorderToSize()
Definition: pix2.c:1971
l_ok composeRGBPixel(l_int32 rval, l_int32 gval, l_int32 bval, l_uint32 *ppixel)
composeRGBPixel()
Definition: pix2.c:2671
l_ok pixCopySpp(PIX *pixd, const PIX *pixs)
pixCopySpp()
Definition: pix1.c:1188
l_int32 pixSizesEqual(const PIX *pix1, const PIX *pix2)
pixSizesEqual()
Definition: pix1.c:781
l_ok boxGetGeometry(BOX *box, l_int32 *px, l_int32 *py, l_int32 *pw, l_int32 *ph)
boxGetGeometry()
Definition: boxbasic.c:310
Definition: pix.h:480
#define SET_DATA_TWO_BYTES(pdata, n, val)
Definition: arrayaccess.h:222
void pixaDestroy(PIXA **ppixa)
pixaDestroy()
Definition: pixabasic.c:408
PIX * pixCopyBorder(PIX *pixd, PIX *pixs, l_int32 left, l_int32 right, l_int32 top, l_int32 bot)
pixCopyBorder()
Definition: pix2.c:1694
l_ok pixSetInRect(PIX *pix, BOX *box)
pixSetInRect()
Definition: pix2.c:1078
void extractRGBValues(l_uint32 pixel, l_int32 *prval, l_int32 *pgval, l_int32 *pbval)
extractRGBValues()
Definition: pix2.c:2737
l_ok pixBlendInRect(PIX *pixs, BOX *box, l_uint32 val, l_float32 fract)
pixBlendInRect()
Definition: pix2.c:1221
#define SET_DATA_BIT(pdata, n)
Definition: arrayaccess.h:127
PIX * pixAddBorderGeneral(PIX *pixs, l_int32 left, l_int32 right, l_int32 top, l_int32 bot, l_uint32 val)
pixAddBorderGeneral()
Definition: pix2.c:1842