Leptonica  1.73
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_int32
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 1;
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 
250 l_int32
252  l_int32 x,
253  l_int32 y,
254  l_uint32 val)
255 {
256 l_int32 w, h, d, wpl;
257 l_uint32 *line, *data;
258 
259  PROCNAME("pixSetPixel");
260 
261  if (!pix)
262  return ERROR_INT("pix not defined", procName, 1);
263  pixGetDimensions(pix, &w, &h, &d);
264  if (x < 0 || x >= w)
265  return ERROR_INT("x out of bounds", procName, 1);
266  if (y < 0 || y >= h)
267  return ERROR_INT("y out of bounds", procName, 1);
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 
313 l_int32
315  l_int32 x,
316  l_int32 y,
317  l_int32 *prval,
318  l_int32 *pgval,
319  l_int32 *pbval)
320 {
321 l_int32 w, h, d, wpl;
322 l_uint32 *data, *ppixel;
323 
324  PROCNAME("pixGetRGBPixel");
325 
326  if (prval) *prval = 0;
327  if (pgval) *pgval = 0;
328  if (pbval) *pbval = 0;
329  if (!prval && !pgval && !pbval)
330  return ERROR_INT("no output requested", procName, 1);
331  if (!pix)
332  return ERROR_INT("pix not defined", procName, 1);
333  pixGetDimensions(pix, &w, &h, &d);
334  if (d != 32)
335  return ERROR_INT("pix not 32 bpp", procName, 1);
336  if (x < 0 || x >= w)
337  return ERROR_INT("x out of bounds", procName, 1);
338  if (y < 0 || y >= h)
339  return ERROR_INT("y out of bounds", procName, 1);
340 
341  wpl = pixGetWpl(pix);
342  data = pixGetData(pix);
343  ppixel = data + y * wpl + x;
344  if (prval) *prval = GET_DATA_BYTE(ppixel, COLOR_RED);
345  if (pgval) *pgval = GET_DATA_BYTE(ppixel, COLOR_GREEN);
346  if (pbval) *pbval = GET_DATA_BYTE(ppixel, COLOR_BLUE);
347  return 0;
348 }
349 
350 
361 l_int32
363  l_int32 x,
364  l_int32 y,
365  l_int32 rval,
366  l_int32 gval,
367  l_int32 bval)
368 {
369 l_int32 w, h, d, wpl;
370 l_uint32 pixel;
371 l_uint32 *data, *line;
372 
373  PROCNAME("pixSetRGBPixel");
374 
375  if (!pix)
376  return ERROR_INT("pix not defined", procName, 1);
377  pixGetDimensions(pix, &w, &h, &d);
378  if (d != 32)
379  return ERROR_INT("pix not 32 bpp", procName, 1);
380  if (x < 0 || x >= w)
381  return ERROR_INT("x out of bounds", procName, 1);
382  if (y < 0 || y >= h)
383  return ERROR_INT("y out of bounds", procName, 1);
384 
385  wpl = pixGetWpl(pix);
386  data = pixGetData(pix);
387  line = data + y * wpl;
388  composeRGBPixel(rval, gval, bval, &pixel);
389  *(line + x) = pixel;
390  return 0;
391 }
392 
393 
408 l_int32
410  l_uint32 *pval,
411  l_int32 *px,
412  l_int32 *py)
413 {
414 l_int32 w, h, x, y, rval, gval, bval;
415 l_uint32 val;
416 PIXCMAP *cmap;
417 
418  PROCNAME("pixGetRandomPixel");
419 
420  if (pval) *pval = 0;
421  if (px) *px = 0;
422  if (py) *py = 0;
423  if (!pval && !px && !py)
424  return ERROR_INT("no output requested", procName, 1);
425  if (!pix)
426  return ERROR_INT("pix not defined", procName, 1);
427 
428  pixGetDimensions(pix, &w, &h, NULL);
429  x = rand() % w;
430  y = rand() % h;
431  if (px) *px = x;
432  if (py) *py = y;
433  if (pval) {
434  pixGetPixel(pix, x, y, &val);
435  if ((cmap = pixGetColormap(pix)) != NULL) {
436  pixcmapGetColor(cmap, val, &rval, &gval, &bval);
437  composeRGBPixel(rval, gval, bval, pval);
438  } else {
439  *pval = val;
440  }
441  }
442 
443  return 0;
444 }
445 
446 
454 l_int32
456  l_int32 x,
457  l_int32 y)
458 {
459 l_int32 w, h, d, wpl;
460 l_uint32 *line, *data;
461 
462  PROCNAME("pixClearPixel");
463 
464  if (!pix)
465  return ERROR_INT("pix not defined", procName, 1);
466  pixGetDimensions(pix, &w, &h, &d);
467  if (x < 0 || x >= w)
468  return ERROR_INT("x out of bounds", procName, 1);
469  if (y < 0 || y >= h)
470  return ERROR_INT("y out of bounds", procName, 1);
471 
472  wpl = pixGetWpl(pix);
473  data = pixGetData(pix);
474  line = data + y * wpl;
475  switch (d)
476  {
477  case 1:
478  CLEAR_DATA_BIT(line, x);
479  break;
480  case 2:
481  CLEAR_DATA_DIBIT(line, x);
482  break;
483  case 4:
484  CLEAR_DATA_QBIT(line, x);
485  break;
486  case 8:
487  SET_DATA_BYTE(line, x, 0);
488  break;
489  case 16:
490  SET_DATA_TWO_BYTES(line, x, 0);
491  break;
492  case 32:
493  line[x] = 0;
494  break;
495  default:
496  return ERROR_INT("depth must be in {1,2,4,8,16,32} bpp", procName, 1);
497  }
498 
499  return 0;
500 }
501 
502 
510 l_int32
512  l_int32 x,
513  l_int32 y)
514 {
515 l_int32 w, h, d, wpl;
516 l_uint32 val;
517 l_uint32 *line, *data;
518 
519  PROCNAME("pixFlipPixel");
520 
521  if (!pix)
522  return ERROR_INT("pix not defined", procName, 1);
523  pixGetDimensions(pix, &w, &h, &d);
524  if (x < 0 || x >= w)
525  return ERROR_INT("x out of bounds", procName, 1);
526  if (y < 0 || y >= h)
527  return ERROR_INT("y out of bounds", procName, 1);
528 
529  data = pixGetData(pix);
530  wpl = pixGetWpl(pix);
531  line = data + y * wpl;
532  switch (d)
533  {
534  case 1:
535  val = GET_DATA_BIT(line, x);
536  if (val)
537  CLEAR_DATA_BIT(line, x);
538  else
539  SET_DATA_BIT(line, x);
540  break;
541  case 2:
542  val = GET_DATA_DIBIT(line, x);
543  val ^= 0x3;
544  SET_DATA_DIBIT(line, x, val);
545  break;
546  case 4:
547  val = GET_DATA_QBIT(line, x);
548  val ^= 0xf;
549  SET_DATA_QBIT(line, x, val);
550  break;
551  case 8:
552  val = GET_DATA_BYTE(line, x);
553  val ^= 0xff;
554  SET_DATA_BYTE(line, x, val);
555  break;
556  case 16:
557  val = GET_DATA_TWO_BYTES(line, x);
558  val ^= 0xffff;
559  SET_DATA_TWO_BYTES(line, x, val);
560  break;
561  case 32:
562  val = line[x] ^ 0xffffffff;
563  line[x] = val;
564  break;
565  default:
566  return ERROR_INT("depth must be in {1,2,4,8,16,32} bpp", procName, 1);
567  }
568 
569  return 0;
570 }
571 
572 
587 void
588 setPixelLow(l_uint32 *line,
589  l_int32 x,
590  l_int32 depth,
591  l_uint32 val)
592 {
593  switch (depth)
594  {
595  case 1:
596  if (val)
597  SET_DATA_BIT(line, x);
598  else
599  CLEAR_DATA_BIT(line, x);
600  break;
601  case 2:
602  SET_DATA_DIBIT(line, x, val);
603  break;
604  case 4:
605  SET_DATA_QBIT(line, x, val);
606  break;
607  case 8:
608  SET_DATA_BYTE(line, x, val);
609  break;
610  case 16:
611  SET_DATA_TWO_BYTES(line, x, val);
612  break;
613  case 32:
614  line[x] = val;
615  break;
616  default:
617  fprintf(stderr, "illegal depth in setPixelLow()\n");
618  }
619 
620  return;
621 }
622 
623 
624 /*-------------------------------------------------------------*
625  * Find black or white value *
626  *-------------------------------------------------------------*/
643 l_int32
645  l_int32 op,
646  l_uint32 *pval)
647 {
648 l_int32 d, val;
649 PIXCMAP *cmap;
650 
651  PROCNAME("pixGetBlackOrWhiteVal");
652 
653  if (!pval)
654  return ERROR_INT("&val not defined", procName, 1);
655  *pval = 0;
656  if (!pixs)
657  return ERROR_INT("pixs not defined", procName, 1);
658  if (op != L_GET_BLACK_VAL && op != L_GET_WHITE_VAL)
659  return ERROR_INT("invalid op", procName, 1);
660 
661  cmap = pixGetColormap(pixs);
662  d = pixGetDepth(pixs);
663  if (!cmap) {
664  if ((d == 1 && op == L_GET_WHITE_VAL) ||
665  (d > 1 && op == L_GET_BLACK_VAL)) { /* min val */
666  val = 0;
667  } else { /* max val */
668  val = (d == 32) ? 0xffffff00 : (1 << d) - 1;
669  }
670  } else { /* handle colormap */
671  if (op == L_GET_BLACK_VAL)
672  pixcmapAddBlackOrWhite(cmap, 0, &val);
673  else /* L_GET_WHITE_VAL */
674  pixcmapAddBlackOrWhite(cmap, 1, &val);
675  }
676  *pval = val;
677 
678  return 0;
679 }
680 
681 
682 /*-------------------------------------------------------------*
683  * Full image clear/set/set-to-arbitrary-value/invert *
684  *-------------------------------------------------------------*/
699 l_int32
701 {
702  PROCNAME("pixClearAll");
703 
704  if (!pix)
705  return ERROR_INT("pix not defined", procName, 1);
706 
707  pixRasterop(pix, 0, 0, pixGetWidth(pix), pixGetHeight(pix),
708  PIX_CLR, NULL, 0, 0);
709  return 0;
710 }
711 
712 
728 l_int32
730 {
731 l_int32 n;
732 PIXCMAP *cmap;
733 
734  PROCNAME("pixSetAll");
735 
736  if (!pix)
737  return ERROR_INT("pix not defined", procName, 1);
738  if ((cmap = pixGetColormap(pix)) != NULL) {
739  n = pixcmapGetCount(cmap);
740  if (n < cmap->nalloc) /* cmap is not full */
741  return ERROR_INT("cmap entry does not exist", procName, 1);
742  }
743 
744  pixRasterop(pix, 0, 0, pixGetWidth(pix), pixGetHeight(pix),
745  PIX_SET, NULL, 0, 0);
746  return 0;
747 }
748 
749 
771 l_int32
773  l_int32 grayval)
774 {
775 l_int32 d, spp, index;
776 l_uint32 val32;
777 PIX *alpha;
778 PIXCMAP *cmap;
779 
780  PROCNAME("pixSetAllGray");
781 
782  if (!pix)
783  return ERROR_INT("pix not defined", procName, 1);
784  if (grayval < 0) {
785  L_WARNING("grayval < 0; setting to 0\n", procName);
786  grayval = 0;
787  } else if (grayval > 255) {
788  L_WARNING("grayval > 255; setting to 255\n", procName);
789  grayval = 255;
790  }
791 
792  /* Handle the colormap case */
793  cmap = pixGetColormap(pix);
794  if (cmap) {
795  pixcmapAddNearestColor(cmap, grayval, grayval, grayval, &index);
796  pixSetAllArbitrary(pix, index);
797  return 0;
798  }
799 
800  /* Non-cmapped */
801  d = pixGetDepth(pix);
802  spp = pixGetSpp(pix);
803  if (d == 1) {
804  if (grayval < 128) /* black */
805  pixSetAll(pix);
806  else
807  pixClearAll(pix); /* white */
808  } else if (d < 8) {
809  grayval >>= 8 - d;
810  pixSetAllArbitrary(pix, grayval);
811  } else if (d == 8) {
812  pixSetAllArbitrary(pix, grayval);
813  } else if (d == 16) {
814  grayval |= (grayval << 8);
815  pixSetAllArbitrary(pix, grayval);
816  } else if (d == 32 && spp == 3) {
817  composeRGBPixel(grayval, grayval, grayval, &val32);
818  pixSetAllArbitrary(pix, val32);
819  } else if (d == 32 && spp == 4) {
820  alpha = pixGetRGBComponent(pix, L_ALPHA_CHANNEL);
821  composeRGBPixel(grayval, grayval, grayval, &val32);
822  pixSetAllArbitrary(pix, val32);
823  pixSetRGBComponent(pix, alpha, L_ALPHA_CHANNEL);
824  pixDestroy(&alpha);
825  } else {
826  L_ERROR("invalid depth: %d\n", procName, d);
827  return 1;
828  }
829 
830  return 0;
831 }
832 
833 
863 l_int32
865  l_uint32 val)
866 {
867 l_int32 n, i, j, w, h, d, wpl, npix;
868 l_uint32 maxval, wordval;
869 l_uint32 *data, *line;
870 PIXCMAP *cmap;
871 
872  PROCNAME("pixSetAllArbitrary");
873 
874  if (!pix)
875  return ERROR_INT("pix not defined", procName, 1);
876 
877  /* If colormapped, make sure that val is less than the size
878  * of the cmap array. */
879  if ((cmap = pixGetColormap(pix)) != NULL) {
880  n = pixcmapGetCount(cmap);
881  if (val >= n) {
882  L_WARNING("index not in colormap; using last color\n", procName);
883  val = n - 1;
884  }
885  }
886 
887  /* Make sure val isn't too large for the pixel depth.
888  * If it is too large, set the pixel color to white. */
889  pixGetDimensions(pix, &w, &h, &d);
890  if (d < 32) {
891  maxval = (1 << d) - 1;
892  if (val > maxval) {
893  L_WARNING("val = %d too large for depth; using maxval = %d\n",
894  procName, val, maxval);
895  val = maxval;
896  }
897  }
898 
899  /* Set up word to tile with */
900  wordval = 0;
901  npix = 32 / d; /* number of pixels per 32 bit word */
902  for (j = 0; j < npix; j++)
903  wordval |= (val << (j * d));
904  wpl = pixGetWpl(pix);
905  data = pixGetData(pix);
906  for (i = 0; i < h; i++) {
907  line = data + i * wpl;
908  for (j = 0; j < wpl; j++) {
909  *(line + j) = wordval;
910  }
911  }
912  return 0;
913 }
914 
915 
933 l_int32
935  l_int32 op)
936 {
937 l_int32 d, index;
938 PIXCMAP *cmap;
939 
940  PROCNAME("pixSetBlackOrWhite");
941 
942  if (!pixs)
943  return ERROR_INT("pix not defined", procName, 1);
944  if (op != L_SET_BLACK && op != L_SET_WHITE)
945  return ERROR_INT("invalid op", procName, 1);
946 
947  cmap = pixGetColormap(pixs);
948  d = pixGetDepth(pixs);
949  if (!cmap) {
950  if ((d == 1 && op == L_SET_BLACK) || (d > 1 && op == L_SET_WHITE))
951  pixSetAll(pixs);
952  else
953  pixClearAll(pixs);
954  } else { /* handle colormap */
955  if (op == L_SET_BLACK)
956  pixcmapAddBlackOrWhite(cmap, 0, &index);
957  else /* L_SET_WHITE */
958  pixcmapAddBlackOrWhite(cmap, 1, &index);
959  pixSetAllArbitrary(pixs, index);
960  }
961 
962  return 0;
963 }
964 
965 
980 l_int32
982  l_int32 comp,
983  l_int32 val)
984 {
985 l_int32 i, nwords;
986 l_uint32 mask1, mask2;
987 l_uint32 *data;
988 
989  PROCNAME("pixSetComponentArbitrary");
990 
991  if (!pix || pixGetDepth(pix) != 32)
992  return ERROR_INT("pix not defined or not 32 bpp", procName, 1);
993  if (comp != COLOR_RED && comp != COLOR_GREEN && comp != COLOR_BLUE &&
994  comp != L_ALPHA_CHANNEL)
995  return ERROR_INT("invalid component", procName, 1);
996  if (val < 0 || val > 255)
997  return ERROR_INT("val not in [0 ... 255]", procName, 1);
998 
999  mask1 = ~(255 << (8 * (3 - comp)));
1000  mask2 = val << (8 * (3 - comp));
1001  nwords = pixGetHeight(pix) * pixGetWpl(pix);
1002  data = pixGetData(pix);
1003  for (i = 0; i < nwords; i++) {
1004  data[i] &= mask1; /* clear out the component */
1005  data[i] |= mask2; /* insert the new component value */
1006  }
1007 
1008  return 0;
1009 }
1010 
1011 
1012 /*-------------------------------------------------------------*
1013  * Rectangular region clear/set/set-to-arbitrary-value *
1014  *-------------------------------------------------------------*/
1030 l_int32
1032  BOX *box)
1033 {
1034 l_int32 x, y, w, h;
1035 
1036  PROCNAME("pixClearInRect");
1037 
1038  if (!pix)
1039  return ERROR_INT("pix not defined", procName, 1);
1040  if (!box)
1041  return ERROR_INT("box not defined", procName, 1);
1042 
1043  boxGetGeometry(box, &x, &y, &w, &h);
1044  pixRasterop(pix, x, y, w, h, PIX_CLR, NULL, 0, 0);
1045  return 0;
1046 }
1047 
1048 
1065 l_int32
1067  BOX *box)
1068 {
1069 l_int32 n, x, y, w, h;
1070 PIXCMAP *cmap;
1071 
1072  PROCNAME("pixSetInRect");
1073 
1074  if (!pix)
1075  return ERROR_INT("pix not defined", procName, 1);
1076  if (!box)
1077  return ERROR_INT("box not defined", procName, 1);
1078  if ((cmap = pixGetColormap(pix)) != NULL) {
1079  n = pixcmapGetCount(cmap);
1080  if (n < cmap->nalloc) /* cmap is not full */
1081  return ERROR_INT("cmap entry does not exist", procName, 1);
1082  }
1083 
1084  boxGetGeometry(box, &x, &y, &w, &h);
1085  pixRasterop(pix, x, y, w, h, PIX_SET, NULL, 0, 0);
1086  return 0;
1087 }
1088 
1089 
1107 l_int32
1109  BOX *box,
1110  l_uint32 val)
1111 {
1112 l_int32 n, x, y, xstart, xend, ystart, yend, bw, bh, w, h, d, wpl, maxval;
1113 l_uint32 *data, *line;
1114 BOX *boxc;
1115 PIXCMAP *cmap;
1116 
1117  PROCNAME("pixSetInRectArbitrary");
1118 
1119  if (!pix)
1120  return ERROR_INT("pix not defined", procName, 1);
1121  if (!box)
1122  return ERROR_INT("box not defined", procName, 1);
1123  pixGetDimensions(pix, &w, &h, &d);
1124  if (d != 1 && d != 2 && d != 4 && d !=8 && d != 16 && d != 32)
1125  return ERROR_INT("depth must be in {1,2,4,8,16,32} bpp", procName, 1);
1126  if ((cmap = pixGetColormap(pix)) != NULL) {
1127  n = pixcmapGetCount(cmap);
1128  if (val >= n) {
1129  L_WARNING("index not in colormap; using last color\n", procName);
1130  val = n - 1;
1131  }
1132  }
1133 
1134  maxval = (d == 32) ? 0xffffff00 : (1 << d) - 1;
1135  if (val > maxval) val = maxval;
1136 
1137  /* Handle the simple cases: the min and max values */
1138  if (val == 0) {
1139  pixClearInRect(pix, box);
1140  return 0;
1141  }
1142  if (d == 1 ||
1143  (d == 2 && val == 3) ||
1144  (d == 4 && val == 0xf) ||
1145  (d == 8 && val == 0xff) ||
1146  (d == 16 && val == 0xffff) ||
1147  (d == 32 && ((val ^ 0xffffff00) >> 8 == 0))) {
1148  pixSetInRect(pix, box);
1149  return 0;
1150  }
1151 
1152  /* Find the overlap of box with the input pix */
1153  if ((boxc = boxClipToRectangle(box, w, h)) == NULL)
1154  return ERROR_INT("no overlap of box with image", procName, 1);
1155  boxGetGeometry(boxc, &xstart, &ystart, &bw, &bh);
1156  xend = xstart + bw - 1;
1157  yend = ystart + bh - 1;
1158  boxDestroy(&boxc);
1159 
1160  wpl = pixGetWpl(pix);
1161  data = pixGetData(pix);
1162  for (y = ystart; y <= yend; y++) {
1163  line = data + y * wpl;
1164  for (x = xstart; x <= xend; x++) {
1165  switch(d)
1166  {
1167  case 2:
1168  SET_DATA_DIBIT(line, x, val);
1169  break;
1170  case 4:
1171  SET_DATA_QBIT(line, x, val);
1172  break;
1173  case 8:
1174  SET_DATA_BYTE(line, x, val);
1175  break;
1176  case 16:
1177  SET_DATA_TWO_BYTES(line, x, val);
1178  break;
1179  case 32:
1180  line[x] = val;
1181  break;
1182  default:
1183  return ERROR_INT("depth not 2|4|8|16|32 bpp", procName, 1);
1184  }
1185  }
1186  }
1187 
1188  return 0;
1189 }
1190 
1191 
1208 l_int32
1210  BOX *box,
1211  l_uint32 val,
1212  l_float32 fract)
1213 {
1214 l_int32 i, j, bx, by, bw, bh, w, h, wpls;
1215 l_int32 prval, pgval, pbval, rval, gval, bval;
1216 l_uint32 val32;
1217 l_uint32 *datas, *lines;
1218 
1219  PROCNAME("pixBlendInRect");
1220 
1221  if (!pixs || pixGetDepth(pixs) != 32)
1222  return ERROR_INT("pixs not defined or not 32 bpp", procName, 1);
1223 
1224  extractRGBValues(val, &rval, &gval, &bval);
1225  pixGetDimensions(pixs, &w, &h, NULL);
1226  datas = pixGetData(pixs);
1227  wpls = pixGetWpl(pixs);
1228  if (!box) {
1229  for (i = 0; i < h; i++) { /* scan over box */
1230  lines = datas + i * wpls;
1231  for (j = 0; j < w; j++) {
1232  val32 = *(lines + j);
1233  extractRGBValues(val32, &prval, &pgval, &pbval);
1234  prval = (l_int32)((1. - fract) * prval + fract * rval);
1235  pgval = (l_int32)((1. - fract) * pgval + fract * gval);
1236  pbval = (l_int32)((1. - fract) * pbval + fract * bval);
1237  composeRGBPixel(prval, pgval, pbval, &val32);
1238  *(lines + j) = val32;
1239  }
1240  }
1241  return 0;
1242  }
1243 
1244  boxGetGeometry(box, &bx, &by, &bw, &bh);
1245  for (i = 0; i < bh; i++) { /* scan over box */
1246  if (by + i < 0 || by + i >= h) continue;
1247  lines = datas + (by + i) * wpls;
1248  for (j = 0; j < bw; j++) {
1249  if (bx + j < 0 || bx + j >= w) continue;
1250  val32 = *(lines + bx + j);
1251  extractRGBValues(val32, &prval, &pgval, &pbval);
1252  prval = (l_int32)((1. - fract) * prval + fract * rval);
1253  pgval = (l_int32)((1. - fract) * pgval + fract * gval);
1254  pbval = (l_int32)((1. - fract) * pbval + fract * bval);
1255  composeRGBPixel(prval, pgval, pbval, &val32);
1256  *(lines + bx + j) = val32;
1257  }
1258  }
1259  return 0;
1260 }
1261 
1262 
1263 /*-------------------------------------------------------------*
1264  * Set pad bits *
1265  *-------------------------------------------------------------*/
1294 l_int32
1296  l_int32 val)
1297 {
1298 l_int32 i, w, h, d, wpl, endbits, fullwords;
1299 l_uint32 mask;
1300 l_uint32 *data, *pword;
1301 
1302  PROCNAME("pixSetPadBits");
1303 
1304  if (!pix)
1305  return ERROR_INT("pix not defined", procName, 1);
1306 
1307  pixGetDimensions(pix, &w, &h, &d);
1308  if (d == 32) /* no padding exists for 32 bpp */
1309  return 0;
1310 
1311  data = pixGetData(pix);
1312  wpl = pixGetWpl(pix);
1313  endbits = 32 - (((l_int64)w * d) % 32);
1314  if (endbits == 32) /* no partial word */
1315  return 0;
1316  fullwords = (1LL * w * d) / 32;
1317  mask = rmask32[endbits];
1318  if (val == 0)
1319  mask = ~mask;
1320 
1321  for (i = 0; i < h; i++) {
1322  pword = data + i * wpl + fullwords;
1323  if (val == 0) /* clear */
1324  *pword = *pword & mask;
1325  else /* set */
1326  *pword = *pword | mask;
1327  }
1328 
1329  return 0;
1330 }
1331 
1332 
1354 l_int32
1356  l_int32 by,
1357  l_int32 bh,
1358  l_int32 val)
1359 {
1360 l_int32 i, w, h, d, wpl, endbits, fullwords;
1361 l_uint32 mask;
1362 l_uint32 *data, *pword;
1363 
1364  PROCNAME("pixSetPadBitsBand");
1365 
1366  if (!pix)
1367  return ERROR_INT("pix not defined", procName, 1);
1368 
1369  pixGetDimensions(pix, &w, &h, &d);
1370  if (d == 32) /* no padding exists for 32 bpp */
1371  return 0;
1372 
1373  if (by < 0)
1374  by = 0;
1375  if (by >= h)
1376  return ERROR_INT("start y not in image", procName, 1);
1377  if (by + bh > h)
1378  bh = h - by;
1379 
1380  data = pixGetData(pix);
1381  wpl = pixGetWpl(pix);
1382  endbits = 32 - (((l_int64)w * d) % 32);
1383  if (endbits == 32) /* no partial word */
1384  return 0;
1385  fullwords = (l_int64)w * d / 32;
1386 
1387  mask = rmask32[endbits];
1388  if (val == 0)
1389  mask = ~mask;
1390 
1391  for (i = by; i < by + bh; i++) {
1392  pword = data + i * wpl + fullwords;
1393  if (val == 0) /* clear */
1394  *pword = *pword & mask;
1395  else /* set */
1396  *pword = *pword | mask;
1397  }
1398 
1399  return 0;
1400 }
1401 
1402 
1403 /*-------------------------------------------------------------*
1404  * Set border pixels *
1405  *-------------------------------------------------------------*/
1426 l_int32
1428  l_int32 left,
1429  l_int32 right,
1430  l_int32 top,
1431  l_int32 bot,
1432  l_int32 op)
1433 {
1434 l_int32 w, h;
1435 
1436  PROCNAME("pixSetOrClearBorder");
1437 
1438  if (!pixs)
1439  return ERROR_INT("pixs not defined", procName, 1);
1440  if (op != PIX_SET && op != PIX_CLR)
1441  return ERROR_INT("op must be PIX_SET or PIX_CLR", procName, 1);
1442 
1443  pixGetDimensions(pixs, &w, &h, NULL);
1444  pixRasterop(pixs, 0, 0, left, h, op, NULL, 0, 0);
1445  pixRasterop(pixs, w - right, 0, right, h, op, NULL, 0, 0);
1446  pixRasterop(pixs, 0, 0, w, top, op, NULL, 0, 0);
1447  pixRasterop(pixs, 0, h - bot, w, bot, op, NULL, 0, 0);
1448 
1449  return 0;
1450 }
1451 
1452 
1475 l_int32
1477  l_int32 left,
1478  l_int32 right,
1479  l_int32 top,
1480  l_int32 bot,
1481  l_uint32 val)
1482 {
1483 l_int32 w, h, d, wpls, i, j, bstart, rstart;
1484 l_uint32 *datas, *lines;
1485 
1486  PROCNAME("pixSetBorderVal");
1487 
1488  if (!pixs)
1489  return ERROR_INT("pixs not defined", procName, 1);
1490  pixGetDimensions(pixs, &w, &h, &d);
1491  if (d != 8 && d != 16 && d != 32)
1492  return ERROR_INT("depth must be 8, 16 or 32 bpp", procName, 1);
1493 
1494  datas = pixGetData(pixs);
1495  wpls = pixGetWpl(pixs);
1496  if (d == 8) {
1497  val &= 0xff;
1498  for (i = 0; i < top; i++) {
1499  lines = datas + i * wpls;
1500  for (j = 0; j < w; j++)
1501  SET_DATA_BYTE(lines, j, val);
1502  }
1503  rstart = w - right;
1504  bstart = h - bot;
1505  for (i = top; i < bstart; i++) {
1506  lines = datas + i * wpls;
1507  for (j = 0; j < left; j++)
1508  SET_DATA_BYTE(lines, j, val);
1509  for (j = rstart; j < w; j++)
1510  SET_DATA_BYTE(lines, j, val);
1511  }
1512  for (i = bstart; i < h; i++) {
1513  lines = datas + i * wpls;
1514  for (j = 0; j < w; j++)
1515  SET_DATA_BYTE(lines, j, val);
1516  }
1517  } else if (d == 16) {
1518  val &= 0xffff;
1519  for (i = 0; i < top; i++) {
1520  lines = datas + i * wpls;
1521  for (j = 0; j < w; j++)
1522  SET_DATA_TWO_BYTES(lines, j, val);
1523  }
1524  rstart = w - right;
1525  bstart = h - bot;
1526  for (i = top; i < bstart; i++) {
1527  lines = datas + i * wpls;
1528  for (j = 0; j < left; j++)
1529  SET_DATA_TWO_BYTES(lines, j, val);
1530  for (j = rstart; j < w; j++)
1531  SET_DATA_TWO_BYTES(lines, j, val);
1532  }
1533  for (i = bstart; i < h; i++) {
1534  lines = datas + i * wpls;
1535  for (j = 0; j < w; j++)
1536  SET_DATA_TWO_BYTES(lines, j, val);
1537  }
1538  } else { /* d == 32 */
1539  for (i = 0; i < top; i++) {
1540  lines = datas + i * wpls;
1541  for (j = 0; j < w; j++)
1542  *(lines + j) = val;
1543  }
1544  rstart = w - right;
1545  bstart = h - bot;
1546  for (i = top; i < bstart; i++) {
1547  lines = datas + i * wpls;
1548  for (j = 0; j < left; j++)
1549  *(lines + j) = val;
1550  for (j = rstart; j < w; j++)
1551  *(lines + j) = val;
1552  }
1553  for (i = bstart; i < h; i++) {
1554  lines = datas + i * wpls;
1555  for (j = 0; j < w; j++)
1556  *(lines + j) = val;
1557  }
1558  }
1559 
1560  return 0;
1561 }
1562 
1563 
1579 l_int32
1581  l_int32 dist,
1582  l_uint32 val)
1583 {
1584 l_int32 w, h, d, i, j, xend, yend;
1585 
1586  PROCNAME("pixSetBorderRingVal");
1587 
1588  if (!pixs)
1589  return ERROR_INT("pixs not defined", procName, 1);
1590  if (dist < 1)
1591  return ERROR_INT("dist must be > 0", procName, 1);
1592  pixGetDimensions(pixs, &w, &h, &d);
1593  if (w < 2 * dist + 1 || h < 2 * dist + 1)
1594  return ERROR_INT("ring doesn't exist", procName, 1);
1595  if (d < 32 && (val >= (1 << d)))
1596  return ERROR_INT("invalid pixel value", procName, 1);
1597 
1598  xend = w - dist;
1599  yend = h - dist;
1600  for (j = dist - 1; j <= xend; j++)
1601  pixSetPixel(pixs, j, dist - 1, val);
1602  for (j = dist - 1; j <= xend; j++)
1603  pixSetPixel(pixs, j, yend, val);
1604  for (i = dist - 1; i <= yend; i++)
1605  pixSetPixel(pixs, dist - 1, i, val);
1606  for (i = dist - 1; i <= yend; i++)
1607  pixSetPixel(pixs, xend, i, val);
1608 
1609  return 0;
1610 }
1611 
1612 
1630 l_int32
1632  l_int32 left,
1633  l_int32 right,
1634  l_int32 top,
1635  l_int32 bot)
1636 {
1637 l_int32 i, j, w, h;
1638 
1639  PROCNAME("pixSetMirroredBorder");
1640 
1641  if (!pixs)
1642  return ERROR_INT("pixs not defined", procName, 1);
1643 
1644  pixGetDimensions(pixs, &w, &h, NULL);
1645  for (j = 0; j < left; j++)
1646  pixRasterop(pixs, left - 1 - j, top, 1, h - top - bot, PIX_SRC,
1647  pixs, left + j, top);
1648  for (j = 0; j < right; j++)
1649  pixRasterop(pixs, w - right + j, top, 1, h - top - bot, PIX_SRC,
1650  pixs, w - right - 1 - j, top);
1651  for (i = 0; i < top; i++)
1652  pixRasterop(pixs, 0, top - 1 - i, w, 1, PIX_SRC,
1653  pixs, 0, top + i);
1654  for (i = 0; i < bot; i++)
1655  pixRasterop(pixs, 0, h - bot + i, w, 1, PIX_SRC,
1656  pixs, 0, h - bot - 1 - i);
1657 
1658  return 0;
1659 }
1660 
1661 
1681 PIX *
1683  PIX *pixs,
1684  l_int32 left,
1685  l_int32 right,
1686  l_int32 top,
1687  l_int32 bot)
1688 {
1689 l_int32 w, h;
1690 
1691  PROCNAME("pixCopyBorder");
1692 
1693  if (!pixs)
1694  return (PIX *)ERROR_PTR("pixs not defined", procName, pixd);
1695 
1696  if (pixd) {
1697  if (pixd == pixs) {
1698  L_WARNING("same: nothing to do\n", procName);
1699  return pixd;
1700  } else if (!pixSizesEqual(pixs, pixd)) {
1701  return (PIX *)ERROR_PTR("pixs and pixd sizes differ",
1702  procName, pixd);
1703  }
1704  } else {
1705  if ((pixd = pixCreateTemplate(pixs)) == NULL)
1706  return (PIX *)ERROR_PTR("pixd not made", procName, pixd);
1707  }
1708 
1709  pixGetDimensions(pixs, &w, &h, NULL);
1710  pixRasterop(pixd, 0, 0, left, h, PIX_SRC, pixs, 0, 0);
1711  pixRasterop(pixd, w - right, 0, right, h, PIX_SRC, pixs, w - right, 0);
1712  pixRasterop(pixd, 0, 0, w, top, PIX_SRC, pixs, 0, 0);
1713  pixRasterop(pixd, 0, h - bot, w, bot, PIX_SRC, pixs, 0, h - bot);
1714  return pixd;
1715 }
1716 
1717 
1718 
1719 /*-------------------------------------------------------------*
1720  * Add and remove border *
1721  *-------------------------------------------------------------*/
1735 PIX *
1737  l_int32 npix,
1738  l_uint32 val)
1739 {
1740  PROCNAME("pixAddBorder");
1741 
1742  if (!pixs)
1743  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
1744  if (npix == 0)
1745  return pixClone(pixs);
1746  return pixAddBorderGeneral(pixs, npix, npix, npix, npix, val);
1747 }
1748 
1749 
1775 PIX *
1777  l_int32 left,
1778  l_int32 right,
1779  l_int32 top,
1780  l_int32 bot,
1781  l_int32 op)
1782 {
1783 l_uint32 val;
1784 
1785  PROCNAME("pixAddBlackOrWhiteBorder");
1786 
1787  if (!pixs)
1788  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
1789  if (op != L_GET_BLACK_VAL && op != L_GET_WHITE_VAL)
1790  return (PIX *)ERROR_PTR("invalid op", procName, NULL);
1791 
1792  pixGetBlackOrWhiteVal(pixs, op, &val);
1793  return pixAddBorderGeneral(pixs, left, right, top, bot, val);
1794 }
1795 
1796 
1829 PIX *
1831  l_int32 left,
1832  l_int32 right,
1833  l_int32 top,
1834  l_int32 bot,
1835  l_uint32 val)
1836 {
1837 l_int32 ws, hs, wd, hd, d, maxval, op;
1838 PIX *pixd;
1839 
1840  PROCNAME("pixAddBorderGeneral");
1841 
1842  if (!pixs)
1843  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
1844  if (left < 0 || right < 0 || top < 0 || bot < 0)
1845  return (PIX *)ERROR_PTR("negative border added!", procName, NULL);
1846 
1847  pixGetDimensions(pixs, &ws, &hs, &d);
1848  wd = ws + left + right;
1849  hd = hs + top + bot;
1850  if ((pixd = pixCreateNoInit(wd, hd, d)) == NULL)
1851  return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
1852  pixCopyResolution(pixd, pixs);
1853  pixCopyColormap(pixd, pixs);
1854 
1855  /* Set the new border pixels */
1856  maxval = (d == 32) ? 0xffffff00 : (1 << d) - 1;
1857  op = UNDEF;
1858  if (val == 0)
1859  op = PIX_CLR;
1860  else if (val >= maxval)
1861  op = PIX_SET;
1862  if (op == UNDEF) {
1863  pixSetAllArbitrary(pixd, val);
1864  } else { /* just set or clear the border pixels */
1865  pixRasterop(pixd, 0, 0, left, hd, op, NULL, 0, 0);
1866  pixRasterop(pixd, wd - right, 0, right, hd, op, NULL, 0, 0);
1867  pixRasterop(pixd, 0, 0, wd, top, op, NULL, 0, 0);
1868  pixRasterop(pixd, 0, hd - bot, wd, bot, op, NULL, 0, 0);
1869  }
1870 
1871  /* Copy pixs into the interior */
1872  pixRasterop(pixd, left, top, ws, hs, PIX_SRC, pixs, 0, 0);
1873  return pixd;
1874 }
1875 
1876 
1884 PIX *
1886  l_int32 npix)
1887 {
1888  PROCNAME("pixRemoveBorder");
1889 
1890  if (!pixs)
1891  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
1892  if (npix == 0)
1893  return pixClone(pixs);
1894  return pixRemoveBorderGeneral(pixs, npix, npix, npix, npix);
1895 }
1896 
1897 
1905 PIX *
1907  l_int32 left,
1908  l_int32 right,
1909  l_int32 top,
1910  l_int32 bot)
1911 {
1912 l_int32 ws, hs, wd, hd, d;
1913 PIX *pixd;
1914 
1915  PROCNAME("pixRemoveBorderGeneral");
1916 
1917  if (!pixs)
1918  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
1919  if (left < 0 || right < 0 || top < 0 || bot < 0)
1920  return (PIX *)ERROR_PTR("negative border removed!", procName, NULL);
1921 
1922  pixGetDimensions(pixs, &ws, &hs, &d);
1923  wd = ws - left - right;
1924  hd = hs - top - bot;
1925  if (wd <= 0)
1926  return (PIX *)ERROR_PTR("width must be > 0", procName, NULL);
1927  if (hd <= 0)
1928  return (PIX *)ERROR_PTR("height must be > 0", procName, NULL);
1929  if ((pixd = pixCreateNoInit(wd, hd, d)) == NULL)
1930  return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
1931  pixCopyResolution(pixd, pixs);
1932  pixCopySpp(pixd, pixs);
1933  pixCopyColormap(pixd, pixs);
1934 
1935  pixRasterop(pixd, 0, 0, wd, hd, PIX_SRC, pixs, left, top);
1936  if (pixGetDepth(pixs) == 32 && pixGetSpp(pixs) == 4)
1937  pixShiftAndTransferAlpha(pixd, pixs, -left, -top);
1938  return pixd;
1939 }
1940 
1941 
1958 PIX *
1960  l_int32 wd,
1961  l_int32 hd)
1962 {
1963 l_int32 w, h, top, bot, left, right, delta;
1964 
1965  PROCNAME("pixRemoveBorderToSize");
1966 
1967  if (!pixs)
1968  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
1969 
1970  pixGetDimensions(pixs, &w, &h, NULL);
1971  if ((wd <= 0 || wd >= w) && (hd <= 0 || hd >= h))
1972  return pixClone(pixs);
1973 
1974  left = right = (w - wd) / 2;
1975  delta = w - 2 * left - wd;
1976  right += delta;
1977  top = bot = (h - hd) / 2;
1978  delta = h - hd - 2 * top;
1979  bot += delta;
1980  if (wd <= 0 || wd > w)
1981  left = right = 0;
1982  else if (hd <= 0 || hd > h)
1983  top = bot = 0;
1984 
1985  return pixRemoveBorderGeneral(pixs, left, right, top, bot);
1986 }
1987 
1988 
2013 PIX *
2015  l_int32 left,
2016  l_int32 right,
2017  l_int32 top,
2018  l_int32 bot)
2019 {
2020 l_int32 i, j, w, h;
2021 PIX *pixd;
2022 
2023  PROCNAME("pixAddMirroredBorder");
2024 
2025  if (!pixs)
2026  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
2027  pixGetDimensions(pixs, &w, &h, NULL);
2028  if (left > w || right > w || top > h || bot > h)
2029  return (PIX *)ERROR_PTR("border too large", procName, NULL);
2030 
2031  /* Set pixels on left, right, top and bottom, in that order */
2032  pixd = pixAddBorderGeneral(pixs, left, right, top, bot, 0);
2033  for (j = 0; j < left; j++)
2034  pixRasterop(pixd, left - 1 - j, top, 1, h, PIX_SRC,
2035  pixd, left + j, top);
2036  for (j = 0; j < right; j++)
2037  pixRasterop(pixd, left + w + j, top, 1, h, PIX_SRC,
2038  pixd, left + w - 1 - j, top);
2039  for (i = 0; i < top; i++)
2040  pixRasterop(pixd, 0, top - 1 - i, left + w + right, 1, PIX_SRC,
2041  pixd, 0, top + i);
2042  for (i = 0; i < bot; i++)
2043  pixRasterop(pixd, 0, top + h + i, left + w + right, 1, PIX_SRC,
2044  pixd, 0, top + h - 1 - i);
2045 
2046  return pixd;
2047 }
2048 
2049 
2066 PIX *
2068  l_int32 left,
2069  l_int32 right,
2070  l_int32 top,
2071  l_int32 bot)
2072 {
2073 l_int32 w, h;
2074 PIX *pixd;
2075 
2076  PROCNAME("pixAddRepeatedBorder");
2077 
2078  if (!pixs)
2079  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
2080  pixGetDimensions(pixs, &w, &h, NULL);
2081  if (left > w || right > w || top > h || bot > h)
2082  return (PIX *)ERROR_PTR("border too large", procName, NULL);
2083 
2084  pixd = pixAddBorderGeneral(pixs, left, right, top, bot, 0);
2085 
2086  /* Set pixels on left, right, top and bottom, in that order */
2087  pixRasterop(pixd, 0, top, left, h, PIX_SRC, pixd, w, top);
2088  pixRasterop(pixd, left + w, top, right, h, PIX_SRC, pixd, left, top);
2089  pixRasterop(pixd, 0, 0, left + w + right, top, PIX_SRC, pixd, 0, h);
2090  pixRasterop(pixd, 0, top + h, left + w + right, bot, PIX_SRC, pixd, 0, top);
2091 
2092  return pixd;
2093 }
2094 
2095 
2122 PIX *
2124  l_int32 left,
2125  l_int32 right,
2126  l_int32 top,
2127  l_int32 bot)
2128 {
2129 l_int32 j, w, h;
2130 PIX *pixd;
2131 
2132  PROCNAME("pixAddMixedBorder");
2133 
2134  if (!pixs)
2135  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
2136  pixGetDimensions(pixs, &w, &h, NULL);
2137  if (left > w || right > w || top > h || bot > h)
2138  return (PIX *)ERROR_PTR("border too large", procName, NULL);
2139 
2140  /* Set mirrored pixels on left and right;
2141  * then set repeated pixels on top and bottom. */
2142  pixd = pixAddBorderGeneral(pixs, left, right, top, bot, 0);
2143  for (j = 0; j < left; j++)
2144  pixRasterop(pixd, left - 1 - j, top, 1, h, PIX_SRC,
2145  pixd, left + j, top);
2146  for (j = 0; j < right; j++)
2147  pixRasterop(pixd, left + w + j, top, 1, h, PIX_SRC,
2148  pixd, left + w - 1 - j, top);
2149  pixRasterop(pixd, 0, 0, left + w + right, top, PIX_SRC, pixd, 0, h);
2150  pixRasterop(pixd, 0, top + h, left + w + right, bot, PIX_SRC, pixd, 0, top);
2151 
2152  return pixd;
2153 }
2154 
2155 
2169 PIX *
2171  l_int32 left,
2172  l_int32 right,
2173  l_int32 top,
2174  l_int32 bot)
2175 {
2176 l_int32 i, j, w, h;
2177 PIX *pixd;
2178 
2179  PROCNAME("pixAddContinuedBorder");
2180 
2181  if (!pixs)
2182  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
2183 
2184  pixd = pixAddBorderGeneral(pixs, left, right, top, bot, 0);
2185  pixGetDimensions(pixs, &w, &h, NULL);
2186  for (j = 0; j < left; j++)
2187  pixRasterop(pixd, j, top, 1, h, PIX_SRC, pixd, left, top);
2188  for (j = 0; j < right; j++)
2189  pixRasterop(pixd, left + w + j, top, 1, h,
2190  PIX_SRC, pixd, left + w - 1, top);
2191  for (i = 0; i < top; i++)
2192  pixRasterop(pixd, 0, i, left + w + right, 1, PIX_SRC, pixd, 0, top);
2193  for (i = 0; i < bot; i++)
2194  pixRasterop(pixd, 0, top + h + i, left + w + right, 1,
2195  PIX_SRC, pixd, 0, top + h - 1);
2196 
2197  return pixd;
2198 }
2199 
2200 
2201 /*-------------------------------------------------------------------*
2202  * Helper functions using alpha *
2203  *-------------------------------------------------------------------*/
2212 l_int32
2214  PIX *pixs,
2215  l_float32 shiftx,
2216  l_float32 shifty)
2217 {
2218 l_int32 w, h;
2219 PIX *pix1, *pix2;
2220 
2221  PROCNAME("pixShiftAndTransferAlpha");
2222 
2223  if (!pixs || !pixd)
2224  return ERROR_INT("pixs and pixd not both defined", procName, 1);
2225  if (pixGetDepth(pixs) != 32 || pixGetSpp(pixs) != 4)
2226  return ERROR_INT("pixs not 32 bpp and 4 spp", procName, 1);
2227  if (pixGetDepth(pixd) != 32)
2228  return ERROR_INT("pixd not 32 bpp", procName, 1);
2229 
2230  if (shiftx == 0 && shifty == 0) {
2231  pixCopyRGBComponent(pixd, pixs, L_ALPHA_CHANNEL);
2232  return 0;
2233  }
2234 
2235  pix1 = pixGetRGBComponent(pixs, L_ALPHA_CHANNEL);
2236  pixGetDimensions(pixd, &w, &h, NULL);
2237  pix2 = pixCreate(w, h, 8);
2238  pixRasterop(pix2, 0, 0, w, h, PIX_SRC, pix1, -shiftx, -shifty);
2239  pixSetRGBComponent(pixd, pix2, L_ALPHA_CHANNEL);
2240  pixDestroy(&pix1);
2241  pixDestroy(&pix2);
2242  return 0;
2243 }
2244 
2245 
2263 PIX *
2265  l_uint32 val,
2266  l_int32 maxw)
2267 {
2268 l_int32 w, width;
2269 l_float32 scalefact;
2270 PIX *pix1, *pix2, *pixd;
2271 PIXA *pixa;
2272 PIXCMAP *cmap;
2273 
2274  PROCNAME("pixDisplayLayersRGBA");
2275 
2276  if (!pixs)
2277  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
2278  cmap = pixGetColormap(pixs);
2279  if (!cmap && !(pixGetDepth(pixs) == 32 && pixGetSpp(pixs) == 4))
2280  return (PIX *)ERROR_PTR("pixs not cmap and not 32 bpp rgba",
2281  procName, NULL);
2282  if ((w = pixGetWidth(pixs)) == 0)
2283  return (PIX *)ERROR_PTR("pixs width 0 !!", procName, NULL);
2284 
2285  if (cmap)
2287  else
2288  pix1 = pixCopy(NULL, pixs);
2289 
2290  /* Scale if necessary so the output width is not larger than maxw */
2291  scalefact = (maxw == 0) ? 1.0 : L_MIN(1.0, (l_float32)(maxw) / w);
2292  width = (l_int32)(scalefact * w);
2293 
2294  pixa = pixaCreate(3);
2295  pixSetSpp(pix1, 3);
2296  pixaAddPix(pixa, pix1, L_INSERT); /* show the rgb values */
2297  pix1 = pixGetRGBComponent(pixs, L_ALPHA_CHANNEL);
2298  pix2 = pixConvertTo32(pix1);
2299  pixaAddPix(pixa, pix2, L_INSERT); /* show the alpha channel */
2300  pixDestroy(&pix1);
2301  pix1 = pixAlphaBlendUniform(pixs, (val & 0xffffff00));
2302  pixaAddPix(pixa, pix1, L_INSERT); /* with %val color bg showing */
2303  pixd = pixaDisplayTiledInRows(pixa, 32, width, scalefact, 0, 25, 2);
2304  pixaDestroy(&pixa);
2305  return pixd;
2306 }
2307 
2308 
2309 /*-------------------------------------------------------------*
2310  * Color sample setting and extraction *
2311  *-------------------------------------------------------------*/
2335 PIX *
2337  PIX *pixg,
2338  PIX *pixb)
2339 {
2340 l_int32 wr, wg, wb, hr, hg, hb, dr, dg, db;
2341 PIX *pixd;
2342 
2343  PROCNAME("pixCreateRGBImage");
2344 
2345  if (!pixr)
2346  return (PIX *)ERROR_PTR("pixr not defined", procName, NULL);
2347  if (!pixg)
2348  return (PIX *)ERROR_PTR("pixg not defined", procName, NULL);
2349  if (!pixb)
2350  return (PIX *)ERROR_PTR("pixb not defined", procName, NULL);
2351  pixGetDimensions(pixr, &wr, &hr, &dr);
2352  pixGetDimensions(pixg, &wg, &hg, &dg);
2353  pixGetDimensions(pixb, &wb, &hb, &db);
2354  if (dr != 8 || dg != 8 || db != 8)
2355  return (PIX *)ERROR_PTR("input pix not all 8 bpp", procName, NULL);
2356  if (wr != wg || wr != wb)
2357  return (PIX *)ERROR_PTR("widths not the same", procName, NULL);
2358  if (hr != hg || hr != hb)
2359  return (PIX *)ERROR_PTR("heights not the same", procName, NULL);
2360 
2361  if ((pixd = pixCreate(wr, hr, 32)) == NULL)
2362  return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
2363  pixCopyResolution(pixd, pixr);
2364  pixSetRGBComponent(pixd, pixr, COLOR_RED);
2365  pixSetRGBComponent(pixd, pixg, COLOR_GREEN);
2366  pixSetRGBComponent(pixd, pixb, COLOR_BLUE);
2367 
2368  return pixd;
2369 }
2370 
2371 
2391 PIX *
2393  l_int32 comp)
2394 {
2395 l_int32 i, j, w, h, wpls, wpld, val;
2396 l_uint32 *lines, *lined;
2397 l_uint32 *datas, *datad;
2398 PIX *pixd;
2399 
2400  PROCNAME("pixGetRGBComponent");
2401 
2402  if (!pixs)
2403  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
2404  if (pixGetColormap(pixs))
2405  return pixGetRGBComponentCmap(pixs, comp);
2406  if (pixGetDepth(pixs) != 32)
2407  return (PIX *)ERROR_PTR("pixs not 32 bpp", procName, NULL);
2408  if (comp != COLOR_RED && comp != COLOR_GREEN &&
2409  comp != COLOR_BLUE && comp != L_ALPHA_CHANNEL)
2410  return (PIX *)ERROR_PTR("invalid comp", procName, NULL);
2411 
2412  pixGetDimensions(pixs, &w, &h, NULL);
2413  if ((pixd = pixCreate(w, h, 8)) == NULL)
2414  return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
2415  pixCopyResolution(pixd, pixs);
2416  wpls = pixGetWpl(pixs);
2417  wpld = pixGetWpl(pixd);
2418  datas = pixGetData(pixs);
2419  datad = pixGetData(pixd);
2420  for (i = 0; i < h; i++) {
2421  lines = datas + i * wpls;
2422  lined = datad + i * wpld;
2423  for (j = 0; j < w; j++) {
2424  val = GET_DATA_BYTE(lines + j, comp);
2425  SET_DATA_BYTE(lined, j, val);
2426  }
2427  }
2428 
2429  return pixd;
2430 }
2431 
2432 
2450 l_int32
2452  PIX *pixs,
2453  l_int32 comp)
2454 {
2455 l_uint8 srcbyte;
2456 l_int32 i, j, w, h, ws, hs, wd, hd;
2457 l_int32 wpls, wpld;
2458 l_uint32 *lines, *lined;
2459 l_uint32 *datas, *datad;
2460 
2461  PROCNAME("pixSetRGBComponent");
2462 
2463  if (!pixd)
2464  return ERROR_INT("pixd not defined", procName, 1);
2465  if (!pixs)
2466  return ERROR_INT("pixs not defined", procName, 1);
2467  if (pixGetDepth(pixd) != 32)
2468  return ERROR_INT("pixd not 32 bpp", procName, 1);
2469  if (pixGetDepth(pixs) != 8)
2470  return ERROR_INT("pixs not 8 bpp", procName, 1);
2471  if (comp != COLOR_RED && comp != COLOR_GREEN &&
2472  comp != COLOR_BLUE && comp != L_ALPHA_CHANNEL)
2473  return ERROR_INT("invalid comp", procName, 1);
2474  pixGetDimensions(pixs, &ws, &hs, NULL);
2475  pixGetDimensions(pixd, &wd, &hd, NULL);
2476  if (ws != wd || hs != hd)
2477  L_WARNING("images sizes not equal\n", procName);
2478  w = L_MIN(ws, wd);
2479  h = L_MIN(hs, hd);
2480  if (comp == L_ALPHA_CHANNEL)
2481  pixSetSpp(pixd, 4);
2482  datas = pixGetData(pixs);
2483  datad = pixGetData(pixd);
2484  wpls = pixGetWpl(pixs);
2485  wpld = pixGetWpl(pixd);
2486  for (i = 0; i < h; i++) {
2487  lines = datas + i * wpls;
2488  lined = datad + i * wpld;
2489  for (j = 0; j < w; j++) {
2490  srcbyte = GET_DATA_BYTE(lines, j);
2491  SET_DATA_BYTE(lined + j, comp, srcbyte);
2492  }
2493  }
2494 
2495  return 0;
2496 }
2497 
2498 
2512 PIX *
2514  l_int32 comp)
2515 {
2516 l_int32 i, j, w, h, val, index;
2517 l_int32 wplc, wpld;
2518 l_uint32 *linec, *lined;
2519 l_uint32 *datac, *datad;
2520 PIX *pixc, *pixd;
2521 PIXCMAP *cmap;
2522 RGBA_QUAD *cta;
2523 
2524  PROCNAME("pixGetRGBComponentCmap");
2525 
2526  if (!pixs)
2527  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
2528  if ((cmap = pixGetColormap(pixs)) == NULL)
2529  return (PIX *)ERROR_PTR("pixs not cmapped", procName, NULL);
2530  if (comp == L_ALPHA_CHANNEL)
2531  return (PIX *)ERROR_PTR("alpha in cmaps not supported", procName, NULL);
2532  if (comp != COLOR_RED && comp != COLOR_GREEN && comp != COLOR_BLUE)
2533  return (PIX *)ERROR_PTR("invalid comp", procName, NULL);
2534 
2535  /* If not 8 bpp, make a cmapped 8 bpp pix */
2536  if (pixGetDepth(pixs) == 8)
2537  pixc = pixClone(pixs);
2538  else
2539  pixc = pixConvertTo8(pixs, TRUE);
2540 
2541  pixGetDimensions(pixs, &w, &h, NULL);
2542  if ((pixd = pixCreateNoInit(w, h, 8)) == NULL) {
2543  pixDestroy(&pixc);
2544  return (PIX *)ERROR_PTR("pixd not made", procName, NULL);
2545  }
2546  pixCopyResolution(pixd, pixs);
2547  wplc = pixGetWpl(pixc);
2548  wpld = pixGetWpl(pixd);
2549  datac = pixGetData(pixc);
2550  datad = pixGetData(pixd);
2551  cta = (RGBA_QUAD *)cmap->array;
2552 
2553  for (i = 0; i < h; i++) {
2554  linec = datac + i * wplc;
2555  lined = datad + i * wpld;
2556  if (comp == COLOR_RED) {
2557  for (j = 0; j < w; j++) {
2558  index = GET_DATA_BYTE(linec, j);
2559  val = cta[index].red;
2560  SET_DATA_BYTE(lined, j, val);
2561  }
2562  } else if (comp == COLOR_GREEN) {
2563  for (j = 0; j < w; j++) {
2564  index = GET_DATA_BYTE(linec, j);
2565  val = cta[index].green;
2566  SET_DATA_BYTE(lined, j, val);
2567  }
2568  } else if (comp == COLOR_BLUE) {
2569  for (j = 0; j < w; j++) {
2570  index = GET_DATA_BYTE(linec, j);
2571  val = cta[index].blue;
2572  SET_DATA_BYTE(lined, j, val);
2573  }
2574  }
2575  }
2576 
2577  pixDestroy(&pixc);
2578  return pixd;
2579 }
2580 
2581 
2597 l_int32
2599  PIX *pixs,
2600  l_int32 comp)
2601 {
2602 l_int32 i, j, w, h, ws, hs, wd, hd, val;
2603 l_int32 wpls, wpld;
2604 l_uint32 *lines, *lined;
2605 l_uint32 *datas, *datad;
2606 
2607  PROCNAME("pixCopyRGBComponent");
2608 
2609  if (!pixd && pixGetDepth(pixd) != 32)
2610  return ERROR_INT("pixd not defined or not 32 bpp", procName, 1);
2611  if (!pixs && pixGetDepth(pixs) != 32)
2612  return ERROR_INT("pixs not defined or not 32 bpp", procName, 1);
2613  if (comp != COLOR_RED && comp != COLOR_GREEN &&
2614  comp != COLOR_BLUE && comp != L_ALPHA_CHANNEL)
2615  return ERROR_INT("invalid component", procName, 1);
2616  pixGetDimensions(pixs, &ws, &hs, NULL);
2617  pixGetDimensions(pixd, &wd, &hd, NULL);
2618  if (ws != wd || hs != hd)
2619  L_WARNING("images sizes not equal\n", procName);
2620  w = L_MIN(ws, wd);
2621  h = L_MIN(hs, hd);
2622  if (comp == L_ALPHA_CHANNEL)
2623  pixSetSpp(pixd, 4);
2624  wpls = pixGetWpl(pixs);
2625  wpld = pixGetWpl(pixd);
2626  datas = pixGetData(pixs);
2627  datad = pixGetData(pixd);
2628  for (i = 0; i < h; i++) {
2629  lines = datas + i * wpls;
2630  lined = datad + i * wpld;
2631  for (j = 0; j < w; j++) {
2632  val = GET_DATA_BYTE(lines + j, comp);
2633  SET_DATA_BYTE(lined + j, comp, val);
2634  }
2635  }
2636  return 0;
2637 }
2638 
2639 
2658 l_int32
2659 composeRGBPixel(l_int32 rval,
2660  l_int32 gval,
2661  l_int32 bval,
2662  l_uint32 *ppixel)
2663 {
2664  PROCNAME("composeRGBPixel");
2665 
2666  if (!ppixel)
2667  return ERROR_INT("&pixel not defined", procName, 1);
2668 
2669  *ppixel = (rval << L_RED_SHIFT) | (gval << L_GREEN_SHIFT) |
2670  (bval << L_BLUE_SHIFT);
2671  return 0;
2672 }
2673 
2674 
2689 l_int32
2690 composeRGBAPixel(l_int32 rval,
2691  l_int32 gval,
2692  l_int32 bval,
2693  l_int32 aval,
2694  l_uint32 *ppixel)
2695 {
2696  PROCNAME("composeRGBAPixel");
2697 
2698  if (!ppixel)
2699  return ERROR_INT("&pixel not defined", procName, 1);
2700 
2701  *ppixel = (rval << L_RED_SHIFT) | (gval << L_GREEN_SHIFT) |
2702  (bval << L_BLUE_SHIFT) | aval;
2703  return 0;
2704 }
2705 
2706 
2724 void
2725 extractRGBValues(l_uint32 pixel,
2726  l_int32 *prval,
2727  l_int32 *pgval,
2728  l_int32 *pbval)
2729 {
2730  if (prval) *prval = (pixel >> L_RED_SHIFT) & 0xff;
2731  if (pgval) *pgval = (pixel >> L_GREEN_SHIFT) & 0xff;
2732  if (pbval) *pbval = (pixel >> L_BLUE_SHIFT) & 0xff;
2733  return;
2734 }
2735 
2736 
2747 void
2748 extractRGBAValues(l_uint32 pixel,
2749  l_int32 *prval,
2750  l_int32 *pgval,
2751  l_int32 *pbval,
2752  l_int32 *paval)
2753 {
2754  if (prval) *prval = (pixel >> L_RED_SHIFT) & 0xff;
2755  if (pgval) *pgval = (pixel >> L_GREEN_SHIFT) & 0xff;
2756  if (pbval) *pbval = (pixel >> L_BLUE_SHIFT) & 0xff;
2757  if (paval) *paval = (pixel >> L_ALPHA_SHIFT) & 0xff;
2758  return;
2759 }
2760 
2761 
2769 l_int32
2770 extractMinMaxComponent(l_uint32 pixel,
2771  l_int32 type)
2772 {
2773 l_int32 rval, gval, bval, val;
2774 
2775  extractRGBValues(pixel, &rval, &gval, &bval);
2776  if (type == L_CHOOSE_MIN) {
2777  val = L_MIN(rval, gval);
2778  val = L_MIN(val, bval);
2779  } else { /* type == L_CHOOSE_MAX */
2780  val = L_MAX(rval, gval);
2781  val = L_MAX(val, bval);
2782  }
2783  return val;
2784 }
2785 
2786 
2803 l_int32
2805  l_int32 row,
2806  l_uint8 *bufr,
2807  l_uint8 *bufg,
2808  l_uint8 *bufb)
2809 {
2810 l_uint32 *lines;
2811 l_int32 j, w, h;
2812 l_int32 wpls;
2813 
2814  PROCNAME("pixGetRGBLine");
2815 
2816  if (!pixs)
2817  return ERROR_INT("pixs not defined", procName, 1);
2818  if (pixGetDepth(pixs) != 32)
2819  return ERROR_INT("pixs not 32 bpp", procName, 1);
2820  if (!bufr || !bufg || !bufb)
2821  return ERROR_INT("buffer not defined", procName, 1);
2822 
2823  pixGetDimensions(pixs, &w, &h, NULL);
2824  if (row < 0 || row >= h)
2825  return ERROR_INT("row out of bounds", procName, 1);
2826  wpls = pixGetWpl(pixs);
2827  lines = pixGetData(pixs) + row * wpls;
2828 
2829  for (j = 0; j < w; j++) {
2830  bufr[j] = GET_DATA_BYTE(lines + j, COLOR_RED);
2831  bufg[j] = GET_DATA_BYTE(lines + j, COLOR_GREEN);
2832  bufb[j] = GET_DATA_BYTE(lines + j, COLOR_BLUE);
2833  }
2834 
2835  return 0;
2836 }
2837 
2838 
2839 /*-------------------------------------------------------------*
2840  * Pixel endian conversion *
2841  *-------------------------------------------------------------*/
2866 PIX *
2868 {
2869 l_uint32 *datas, *datad;
2870 l_int32 i, j, h, wpl;
2871 l_uint32 word;
2872 PIX *pixd;
2873 
2874  PROCNAME("pixEndianByteSwapNew");
2875 
2876 #ifdef L_BIG_ENDIAN
2877 
2878  return pixClone(pixs);
2879 
2880 #else /* L_LITTLE_ENDIAN */
2881 
2882  if (!pixs)
2883  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
2884 
2885  datas = pixGetData(pixs);
2886  wpl = pixGetWpl(pixs);
2887  h = pixGetHeight(pixs);
2888  pixd = pixCreateTemplate(pixs);
2889  datad = pixGetData(pixd);
2890  for (i = 0; i < h; i++) {
2891  for (j = 0; j < wpl; j++, datas++, datad++) {
2892  word = *datas;
2893  *datad = (word >> 24) |
2894  ((word >> 8) & 0x0000ff00) |
2895  ((word << 8) & 0x00ff0000) |
2896  (word << 24);
2897  }
2898  }
2899 
2900  return pixd;
2901 
2902 #endif /* L_BIG_ENDIAN */
2903 
2904 }
2905 
2906 
2929 l_int32
2931 {
2932 l_uint32 *data;
2933 l_int32 i, j, h, wpl;
2934 l_uint32 word;
2935 
2936  PROCNAME("pixEndianByteSwap");
2937 
2938 #ifdef L_BIG_ENDIAN
2939 
2940  return 0;
2941 
2942 #else /* L_LITTLE_ENDIAN */
2943 
2944  if (!pixs)
2945  return ERROR_INT("pixs not defined", procName, 1);
2946 
2947  data = pixGetData(pixs);
2948  wpl = pixGetWpl(pixs);
2949  h = pixGetHeight(pixs);
2950  for (i = 0; i < h; i++) {
2951  for (j = 0; j < wpl; j++, data++) {
2952  word = *data;
2953  *data = (word >> 24) |
2954  ((word >> 8) & 0x0000ff00) |
2955  ((word << 8) & 0x00ff0000) |
2956  (word << 24);
2957  }
2958  }
2959 
2960  return 0;
2961 
2962 #endif /* L_BIG_ENDIAN */
2963 
2964 }
2965 
2966 
2985 l_int32
2986 lineEndianByteSwap(l_uint32 *datad,
2987  l_uint32 *datas,
2988  l_int32 wpl)
2989 {
2990 l_int32 j;
2991 l_uint32 word;
2992 
2993  PROCNAME("lineEndianByteSwap");
2994 
2995  if (!datad || !datas)
2996  return ERROR_INT("datad and datas not both defined", procName, 1);
2997 
2998 #ifdef L_BIG_ENDIAN
2999 
3000  memcpy((char *)datad, (char *)datas, 4 * wpl);
3001  return 0;
3002 
3003 #else /* L_LITTLE_ENDIAN */
3004 
3005  for (j = 0; j < wpl; j++, datas++, datad++) {
3006  word = *datas;
3007  *datad = (word >> 24) |
3008  ((word >> 8) & 0x0000ff00) |
3009  ((word << 8) & 0x00ff0000) |
3010  (word << 24);
3011  }
3012  return 0;
3013 
3014 #endif /* L_BIG_ENDIAN */
3015 
3016 }
3017 
3018 
3038 PIX *
3040 {
3041 l_uint32 *datas, *datad;
3042 l_int32 i, j, h, wpl;
3043 l_uint32 word;
3044 PIX *pixd;
3045 
3046  PROCNAME("pixEndianTwoByteSwapNew");
3047 
3048 #ifdef L_BIG_ENDIAN
3049 
3050  return pixClone(pixs);
3051 
3052 #else /* L_LITTLE_ENDIAN */
3053 
3054  if (!pixs)
3055  return (PIX *)ERROR_PTR("pixs not defined", procName, NULL);
3056 
3057  datas = pixGetData(pixs);
3058  wpl = pixGetWpl(pixs);
3059  h = pixGetHeight(pixs);
3060  pixd = pixCreateTemplate(pixs);
3061  datad = pixGetData(pixd);
3062  for (i = 0; i < h; i++) {
3063  for (j = 0; j < wpl; j++, datas++, datad++) {
3064  word = *datas;
3065  *datad = (word << 16) | (word >> 16);
3066  }
3067  }
3068 
3069  return pixd;
3070 
3071 #endif /* L_BIG_ENDIAN */
3072 
3073 }
3074 
3075 
3091 l_int32
3093 {
3094 l_uint32 *data;
3095 l_int32 i, j, h, wpl;
3096 l_uint32 word;
3097 
3098  PROCNAME("pixEndianTwoByteSwap");
3099 
3100 #ifdef L_BIG_ENDIAN
3101 
3102  return 0;
3103 
3104 #else /* L_LITTLE_ENDIAN */
3105 
3106  if (!pixs)
3107  return ERROR_INT("pixs not defined", procName, 1);
3108 
3109  data = pixGetData(pixs);
3110  wpl = pixGetWpl(pixs);
3111  h = pixGetHeight(pixs);
3112  for (i = 0; i < h; i++) {
3113  for (j = 0; j < wpl; j++, data++) {
3114  word = *data;
3115  *data = (word << 16) | (word >> 16);
3116  }
3117  }
3118 
3119  return 0;
3120 
3121 #endif /* L_BIG_ENDIAN */
3122 
3123 }
3124 
3125 
3126 /*-------------------------------------------------------------*
3127  * Extract raster data as binary string *
3128  *-------------------------------------------------------------*/
3145 l_int32
3147  l_uint8 **pdata,
3148  size_t *pnbytes)
3149 {
3150 l_int32 w, h, d, wpl, i, j, rval, gval, bval;
3151 l_int32 databpl; /* bytes for each raster line in returned data */
3152 l_uint8 *line, *data; /* packed data in returned array */
3153 l_uint32 *rline, *rdata; /* data in pix raster */
3154 
3155  PROCNAME("pixGetRasterData");
3156 
3157  if (pdata) *pdata = NULL;
3158  if (pnbytes) *pnbytes = 0;
3159  if (!pdata || !pnbytes)
3160  return ERROR_INT("&data and &nbytes not both defined", procName, 1);
3161  if (!pixs)
3162  return ERROR_INT("pixs not defined", procName, 1);
3163  pixGetDimensions(pixs, &w, &h, &d);
3164  if (d != 1 && d != 2 && d != 4 && d != 8 && d != 16 && d != 32)
3165  return ERROR_INT("depth not in {1,2,4,8,16,32}", procName, 1);
3166  rdata = pixGetData(pixs);
3167  wpl = pixGetWpl(pixs);
3168  if (d == 1)
3169  databpl = (w + 7) / 8;
3170  else if (d == 2)
3171  databpl = (w + 3) / 4;
3172  else if (d == 4)
3173  databpl = (w + 1) / 2;
3174  else if (d == 8 || d == 16)
3175  databpl = w * (d / 8);
3176  else /* d == 32 bpp rgb */
3177  databpl = 3 * w;
3178  if ((data = (l_uint8 *)LEPT_CALLOC(databpl * h, sizeof(l_uint8))) == NULL)
3179  return ERROR_INT("data not allocated", procName, 1);
3180  *pdata = data;
3181  *pnbytes = databpl * h;
3182 
3183  for (i = 0; i < h; i++) {
3184  rline = rdata + i * wpl;
3185  line = data + i * databpl;
3186  if (d <= 8) {
3187  for (j = 0; j < databpl; j++)
3188  line[j] = GET_DATA_BYTE(rline, j);
3189  } else if (d == 16) {
3190  for (j = 0; j < w; j++)
3191  line[2 * j] = GET_DATA_TWO_BYTES(rline, j);
3192  } else { /* d == 32 bpp rgb */
3193  for (j = 0; j < w; j++) {
3194  extractRGBValues(rline[j], &rval, &gval, &bval);
3195  *(line + 3 * j) = rval;
3196  *(line + 3 * j + 1) = gval;
3197  *(line + 3 * j + 2) = bval;
3198  }
3199  }
3200  }
3201 
3202  return 0;
3203 }
3204 
3205 
3206 /*-------------------------------------------------------------*
3207  * Test alpha component opaqueness *
3208  *-------------------------------------------------------------*/
3219 l_int32
3221  l_int32 *popaque)
3222 {
3223 l_int32 w, h, wpl, i, j, alpha;
3224 l_uint32 *data, *line;
3225 
3226  PROCNAME("pixAlphaIsOpaque");
3227 
3228  if (!popaque)
3229  return ERROR_INT("&opaque not defined", procName, 1);
3230  *popaque = FALSE;
3231  if (!pix)
3232  return ERROR_INT("&pix not defined", procName, 1);
3233  if (pixGetDepth(pix) != 32)
3234  return ERROR_INT("&pix not 32 bpp", procName, 1);
3235  if (pixGetSpp(pix) != 4)
3236  return ERROR_INT("&pix not 4 spp", procName, 1);
3237 
3238  data = pixGetData(pix);
3239  wpl = pixGetWpl(pix);
3240  pixGetDimensions(pix, &w, &h, NULL);
3241  for (i = 0; i < h; i++) {
3242  line = data + i * wpl;
3243  for (j = 0; j < w; j++) {
3244  alpha = GET_DATA_BYTE(line + j, L_ALPHA_CHANNEL);
3245  if (alpha ^ 0xff) /* not opaque */
3246  return 0;
3247  }
3248  }
3249 
3250  *popaque = TRUE;
3251  return 0;
3252 }
3253 
3254 
3255 /*-------------------------------------------------------------*
3256  * Setup helpers for 8 bpp byte processing *
3257  *-------------------------------------------------------------*/
3284 l_uint8 **
3286  l_int32 *pw,
3287  l_int32 *ph)
3288 {
3289 l_int32 w, h;
3290 
3291  PROCNAME("pixSetupByteProcessing");
3292 
3293  if (pw) *pw = 0;
3294  if (ph) *ph = 0;
3295  if (!pix || pixGetDepth(pix) != 8)
3296  return (l_uint8 **)ERROR_PTR("pix not defined or not 8 bpp",
3297  procName, NULL);
3298  pixGetDimensions(pix, &w, &h, NULL);
3299  if (pw) *pw = w;
3300  if (ph) *ph = h;
3301  if (pixGetColormap(pix))
3302  return (l_uint8 **)ERROR_PTR("pix has colormap", procName, NULL);
3303 
3304  pixEndianByteSwap(pix);
3305  return (l_uint8 **)pixGetLinePtrs(pix, NULL);
3306 }
3307 
3308 
3322 l_int32
3324  l_uint8 **lineptrs)
3325 {
3326  PROCNAME("pixCleanupByteProcessing");
3327 
3328  if (!pix)
3329  return ERROR_INT("pix not defined", procName, 1);
3330  if (!lineptrs)
3331  return ERROR_INT("lineptrs not defined", procName, 1);
3332 
3333  pixEndianByteSwap(pix);
3334  LEPT_FREE(lineptrs);
3335  return 0;
3336 }
3337 
3338 
3339 /*------------------------------------------------------------------------*
3340  * Setting parameters for antialias masking with alpha transforms *
3341  *------------------------------------------------------------------------*/
3364 void
3365 l_setAlphaMaskBorder(l_float32 val1,
3366  l_float32 val2)
3367 {
3368  val1 = L_MAX(0.0, L_MIN(1.0, val1));
3369  val2 = L_MAX(0.0, L_MIN(1.0, val2));
3370  AlphaMaskBorderVals[0] = val1;
3371  AlphaMaskBorderVals[1] = val2;
3372 }
l_int32 lineEndianByteSwap(l_uint32 *datad, l_uint32 *datas, l_int32 wpl)
lineEndianByteSwap()
Definition: pix2.c:2986
l_int32 pixCopyColormap(PIX *pixd, PIX *pixs)
pixCopyColormap()
Definition: pix1.c:735
PIX * pixAddMixedBorder(PIX *pixs, l_int32 left, l_int32 right, l_int32 top, l_int32 bot)
pixAddMixedBorder()
Definition: pix2.c:2123
l_int32 pixSetPadBitsBand(PIX *pix, l_int32 by, l_int32 bh, l_int32 val)
pixSetPadBitsBand()
Definition: pix2.c:1355
PIX * pixRemoveColormap(PIX *pixs, l_int32 type)
pixRemoveColormap()
Definition: pixconv.c:322
l_int32 pixEndianByteSwap(PIX *pixs)
pixEndianByteSwap()
Definition: pix2.c:2930
PIX * pixConvertTo32(PIX *pixs)
pixConvertTo32()
Definition: pixconv.c:3233
l_int32 pixClearInRect(PIX *pix, BOX *box)
pixClearInRect()
Definition: pix2.c:1031
#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:1906
l_int32 pixSetComponentArbitrary(PIX *pix, l_int32 comp, l_int32 val)
pixSetComponentArbitrary()
Definition: pix2.c:981
l_int32 pixEndianTwoByteSwap(PIX *pixs)
pixEndianTwoByteSwap()
Definition: pix2.c:3092
void extractRGBAValues(l_uint32 pixel, l_int32 *prval, l_int32 *pgval, l_int32 *pbval, l_int32 *paval)
extractRGBAValues()
Definition: pix2.c:2748
l_int32 pixShiftAndTransferAlpha(PIX *pixd, PIX *pixs, l_float32 shiftx, l_float32 shifty)
pixShiftAndTransferAlpha()
Definition: pix2.c:2213
l_int32 pixGetPixel(PIX *pix, l_int32 x, l_int32 y, l_uint32 *pval)
pixGetPixel()
Definition: pix2.c:180
PIXA * pixaCreate(l_int32 n)
pixaCreate()
Definition: pixabasic.c:161
l_int32 pixSetRGBComponent(PIX *pixd, PIX *pixs, l_int32 comp)
pixSetRGBComponent()
Definition: pix2.c:2451
l_int32 pixSetAllArbitrary(PIX *pix, l_uint32 val)
pixSetAllArbitrary()
Definition: pix2.c:864
void setPixelLow(l_uint32 *line, l_int32 x, l_int32 depth, l_uint32 val)
setPixelLow()
Definition: pix2.c:588
PIX * pixConvertTo8(PIX *pixs, l_int32 cmapflag)
pixConvertTo8()
Definition: pixconv.c:3041
void ** pixGetLinePtrs(PIX *pix, l_int32 *psize)
pixGetLinePtrs()
Definition: pix1.c:1772
l_int32 pixGetRGBPixel(PIX *pix, l_int32 x, l_int32 y, l_int32 *prval, l_int32 *pgval, l_int32 *pbval)
pixGetRGBPixel()
Definition: pix2.c:314
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_int32 pixSetOrClearBorder(PIX *pixs, l_int32 left, l_int32 right, l_int32 top, l_int32 bot, l_int32 op)
pixSetOrClearBorder()
Definition: pix2.c:1427
l_int32 pixAlphaIsOpaque(PIX *pix, l_int32 *popaque)
pixAlphaIsOpaque()
Definition: pix2.c:3220
#define SET_DATA_QBIT(pdata, n, val)
Definition: arrayaccess.h:162
l_int32 composeRGBAPixel(l_int32 rval, l_int32 gval, l_int32 bval, l_int32 aval, l_uint32 *ppixel)
composeRGBAPixel()
Definition: pix2.c:2690
PIX * pixAddMirroredBorder(PIX *pixs, l_int32 left, l_int32 right, l_int32 top, l_int32 bot)
pixAddMirroredBorder()
Definition: pix2.c:2014
l_uint32 * pixGetData(PIX *pix)
pixGetData()
Definition: pix1.c:1602
PIX * pixAddBlackOrWhiteBorder(PIX *pixs, l_int32 left, l_int32 right, l_int32 top, l_int32 bot, l_int32 op)
pixAddBlackOrWhiteBorder()
Definition: pix2.c:1776
l_int32 pixcmapGetColor(PIXCMAP *cmap, l_int32 index, l_int32 *prval, l_int32 *pgval, l_int32 *pbval)
pixcmapGetColor()
Definition: colormap.c:709
l_int32 pixClearPixel(PIX *pix, l_int32 x, l_int32 y)
pixClearPixel()
Definition: pix2.c:455
l_int32 pixcmapAddBlackOrWhite(PIXCMAP *cmap, l_int32 color, l_int32 *pindex)
pixcmapAddBlackOrWhite()
Definition: colormap.c:524
#define GET_DATA_BIT(pdata, n)
Definition: arrayaccess.h:117
PIX * pixCreateTemplate(PIX *pixs)
pixCreateTemplate()
Definition: pix1.c:367
PIX * pixGetRGBComponent(PIX *pixs, l_int32 comp)
pixGetRGBComponent()
Definition: pix2.c:2392
l_uint8 blue
Definition: pix.h:171
PIX * pixAddBorder(PIX *pixs, l_int32 npix, l_uint32 val)
pixAddBorder()
Definition: pix2.c:1736
l_int32 pixSetBorderVal(PIX *pixs, l_int32 left, l_int32 right, l_int32 top, l_int32 bot, l_uint32 val)
pixSetBorderVal()
Definition: pix2.c:1476
#define SET_DATA_DIBIT(pdata, n, val)
Definition: arrayaccess.h:143
l_int32 pixGetBlackOrWhiteVal(PIX *pixs, l_int32 op, l_uint32 *pval)
pixGetBlackOrWhiteVal()
Definition: pix2.c:644
l_int32 pixGetRasterData(PIX *pixs, l_uint8 **pdata, size_t *pnbytes)
pixGetRasterData()
Definition: pix2.c:3146
#define CLEAR_DATA_BIT(pdata, n)
Definition: arrayaccess.h:125
l_int32 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
PIX * pixEndianTwoByteSwapNew(PIX *pixs)
pixEndianTwoByteSwapNew()
Definition: pix2.c:3039
PIX * pixAlphaBlendUniform(PIX *pixs, l_uint32 color)
pixAlphaBlendUniform()
Definition: blend.c:2004
l_int32 pixFlipPixel(PIX *pix, l_int32 x, l_int32 y)
pixFlipPixel()
Definition: pix2.c:511
PIX * pixRemoveBorder(PIX *pixs, l_int32 npix)
pixRemoveBorder()
Definition: pix2.c:1885
l_int32 pixCopySpp(PIX *pixd, PIX *pixs)
pixCopySpp()
Definition: pix1.c:1172
static const l_int32 L_INSERT
Definition: pix.h:710
l_uint8 ** pixSetupByteProcessing(PIX *pix, l_int32 *pw, l_int32 *ph)
pixSetupByteProcessing()
Definition: pix2.c:3285
l_int32 pixGetRandomPixel(PIX *pix, l_uint32 *pval, l_int32 *px, l_int32 *py)
pixGetRandomPixel()
Definition: pix2.c:409
#define CLEAR_DATA_DIBIT(pdata, n)
Definition: arrayaccess.h:150
l_int32 pixaAddPix(PIXA *pixa, PIX *pix, l_int32 copyflag)
pixaAddPix()
Definition: pixabasic.c:493
#define PIX_SET
Definition: pix.h:331
l_int32 pixSetPadBits(PIX *pix, l_int32 val)
pixSetPadBits()
Definition: pix2.c:1295
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:821
l_int32 pixClearAll(PIX *pix)
pixClearAll()
Definition: pix2.c:700
l_int32 extractMinMaxComponent(l_uint32 pixel, l_int32 type)
extractMinMaxComponent()
Definition: pix2.c:2770
#define SET_DATA_BYTE(pdata, n, val)
Definition: arrayaccess.h:192
l_int32 boxGetGeometry(BOX *box, l_int32 *px, l_int32 *py, l_int32 *pw, l_int32 *ph)
boxGetGeometry()
Definition: boxbasic.c:309
#define GET_DATA_QBIT(pdata, n)
Definition: arrayaccess.h:158
l_int32 pixSizesEqual(PIX *pix1, PIX *pix2)
pixSizesEqual()
Definition: pix1.c:768
#define CLEAR_DATA_QBIT(pdata, n)
Definition: arrayaccess.h:169
#define GET_DATA_BYTE(pdata, n)
Definition: arrayaccess.h:182
l_uint8 green
Definition: pix.h:172
Definition: pix.h:169
PIX * pixCreateRGBImage(PIX *pixr, PIX *pixg, PIX *pixb)
pixCreateRGBImage()
Definition: pix2.c:2336
PIX * pixAddContinuedBorder(PIX *pixs, l_int32 left, l_int32 right, l_int32 top, l_int32 bot)
pixAddContinuedBorder()
Definition: pix2.c:2170
PIX * pixCreateNoInit(l_int32 width, l_int32 height, l_int32 depth)
pixCreateNoInit()
Definition: pix1.c:331
PIX * pixClone(PIX *pixs)
pixClone()
Definition: pix1.c:517
void pixDestroy(PIX **ppix)
pixDestroy()
Definition: pix1.c:545
PIX * pixGetRGBComponentCmap(PIX *pixs, l_int32 comp)
pixGetRGBComponentCmap()
Definition: pix2.c:2513
l_int32 pixcmapAddNearestColor(PIXCMAP *cmap, l_int32 rval, l_int32 gval, l_int32 bval, l_int32 *pindex)
pixcmapAddNearestColor()
Definition: colormap.c:430
l_int32 pixCopyRGBComponent(PIX *pixd, PIX *pixs, l_int32 comp)
pixCopyRGBComponent()
Definition: pix2.c:2598
Definition: pix.h:454
PIX * pixEndianByteSwapNew(PIX *pixs)
pixEndianByteSwapNew()
Definition: pix2.c:2867
PIX * pixAddRepeatedBorder(PIX *pixs, l_int32 left, l_int32 right, l_int32 top, l_int32 bot)
pixAddRepeatedBorder()
Definition: pix2.c:2067
l_int32 pixGetRGBLine(PIX *pixs, l_int32 row, l_uint8 *bufr, l_uint8 *bufg, l_uint8 *bufb)
pixGetRGBLine()
Definition: pix2.c:2804
l_int32 pixSetBlackOrWhite(PIX *pixs, l_int32 op)
pixSetBlackOrWhite()
Definition: pix2.c:934
l_int32 pixSetInRect(PIX *pix, BOX *box)
pixSetInRect()
Definition: pix2.c:1066
void l_setAlphaMaskBorder(l_float32 val1, l_float32 val2)
l_setAlphaMaskBorder()
Definition: pix2.c:3365
l_int32 pixSetPixel(PIX *pix, l_int32 x, l_int32 y, l_uint32 val)
pixSetPixel()
Definition: pix2.c:251
l_int32 pixSetBorderRingVal(PIX *pixs, l_int32 dist, l_uint32 val)
pixSetBorderRingVal()
Definition: pix2.c:1580
#define GET_DATA_TWO_BYTES(pdata, n)
Definition: arrayaccess.h:206
#define GET_DATA_DIBIT(pdata, n)
Definition: arrayaccess.h:139
void * array
Definition: pix.h:157
l_int32 pixSetMirroredBorder(PIX *pixs, l_int32 left, l_int32 right, l_int32 top, l_int32 bot)
pixSetMirroredBorder()
Definition: pix2.c:1631
l_int32 composeRGBPixel(l_int32 rval, l_int32 gval, l_int32 bval, l_uint32 *ppixel)
composeRGBPixel()
Definition: pix2.c:2659
PIX * pixDisplayLayersRGBA(PIX *pixs, l_uint32 val, l_int32 maxw)
pixDisplayLayersRGBA()
Definition: pix2.c:2264
l_int32 pixcmapGetCount(PIXCMAP *cmap)
pixcmapGetCount()
Definition: colormap.c:593
Definition: pix.h:134
#define PIX_SRC
Definition: pix.h:327
PIX * pixCopy(PIX *pixd, PIX *pixs)
pixCopy()
Definition: pix1.c:630
l_int32 pixCleanupByteProcessing(PIX *pix, l_uint8 **lineptrs)
pixCleanupByteProcessing()
Definition: pix2.c:3323
void boxDestroy(BOX **pbox)
boxDestroy()
Definition: boxbasic.c:277
Definition: pix.h:201
l_int32 pixSetAll(PIX *pix)
pixSetAll()
Definition: pix2.c:729
l_int32 pixGetDimensions(PIX *pix, l_int32 *pw, l_int32 *ph, l_int32 *pd)
pixGetDimensions()
Definition: pix1.c:1052
l_int32 pixSetRGBPixel(PIX *pix, l_int32 x, l_int32 y, l_int32 rval, l_int32 gval, l_int32 bval)
pixSetRGBPixel()
Definition: pix2.c:362
PIX * pixRemoveBorderToSize(PIX *pixs, l_int32 wd, l_int32 hd)
pixRemoveBorderToSize()
Definition: pix2.c:1959
l_int32 pixSetInRectArbitrary(PIX *pix, BOX *box, l_uint32 val)
pixSetInRectArbitrary()
Definition: pix2.c:1108
l_int32 pixSetAllGray(PIX *pix, l_int32 grayval)
pixSetAllGray()
Definition: pix2.c:772
Definition: pix.h:480
#define SET_DATA_TWO_BYTES(pdata, n, val)
Definition: arrayaccess.h:216
void pixaDestroy(PIXA **ppixa)
pixaDestroy()
Definition: pixabasic.c:398
PIX * pixCopyBorder(PIX *pixd, PIX *pixs, l_int32 left, l_int32 right, l_int32 top, l_int32 bot)
pixCopyBorder()
Definition: pix2.c:1682
void extractRGBValues(l_uint32 pixel, l_int32 *prval, l_int32 *pgval, l_int32 *pbval)
extractRGBValues()
Definition: pix2.c:2725
#define SET_DATA_BIT(pdata, n)
Definition: arrayaccess.h:121
PIX * pixAddBorderGeneral(PIX *pixs, l_int32 left, l_int32 right, l_int32 top, l_int32 bot, l_uint32 val)
pixAddBorderGeneral()
Definition: pix2.c:1830
l_int32 pixBlendInRect(PIX *pixs, BOX *box, l_uint32 val, l_float32 fract)
pixBlendInRect()
Definition: pix2.c:1209