Leptonica 1.85.0
Image processing and image analysis suite
Loading...
Searching...
No Matches
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
136#ifdef HAVE_CONFIG_H
137#include <config_auto.h>
138#endif /* HAVE_CONFIG_H */
139
140#include <string.h>
141#include "allheaders.h"
142#include "pix_internal.h"
143
144static const l_uint32 rmask32[] = {0x0,
145 0x00000001, 0x00000003, 0x00000007, 0x0000000f,
146 0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff,
147 0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff,
148 0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff,
149 0x0001ffff, 0x0003ffff, 0x0007ffff, 0x000fffff,
150 0x001fffff, 0x003fffff, 0x007fffff, 0x00ffffff,
151 0x01ffffff, 0x03ffffff, 0x07ffffff, 0x0fffffff,
152 0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff};
153
154 /* This is a global that determines the default 8 bpp alpha mask values
155 * for rings at distance 1 and 2 from the border. Declare extern
156 * to use. To change the values, use l_setAlphaMaskBorder(). */
157LEPT_DLL l_float32 AlphaMaskBorderVals[2] = {0.0, 0.5};
158
159
160#ifndef NO_CONSOLE_IO
161#define DEBUG_SERIALIZE 0
162#endif /* ~NO_CONSOLE_IO */
163
164
165/*-------------------------------------------------------------*
166 * Pixel poking *
167 *-------------------------------------------------------------*/
191l_ok
193 l_int32 x,
194 l_int32 y,
195 l_uint32 *pval)
196{
197l_int32 w, h, d, wpl, val;
198l_uint32 *line, *data;
199
200 if (!pval)
201 return ERROR_INT("&val not defined", __func__, 1);
202 *pval = 0;
203 if (!pix)
204 return ERROR_INT("pix not defined", __func__, 1);
205
206 pixGetDimensions(pix, &w, &h, &d);
207 if (x < 0 || x >= w || y < 0 || y >= h)
208 return 2;
209
210 wpl = pixGetWpl(pix);
211 data = pixGetData(pix);
212 line = data + y * wpl;
213 switch (d)
214 {
215 case 1:
216 val = GET_DATA_BIT(line, x);
217 break;
218 case 2:
219 val = GET_DATA_DIBIT(line, x);
220 break;
221 case 4:
222 val = GET_DATA_QBIT(line, x);
223 break;
224 case 8:
225 val = GET_DATA_BYTE(line, x);
226 break;
227 case 16:
228 val = GET_DATA_TWO_BYTES(line, x);
229 break;
230 case 32:
231 val = line[x];
232 break;
233 default:
234 return ERROR_INT("depth must be in {1,2,4,8,16,32} bpp", __func__, 1);
235 }
236
237 *pval = val;
238 return 0;
239}
240
241
262l_ok
264 l_int32 x,
265 l_int32 y,
266 l_uint32 val)
267{
268l_int32 w, h, d, wpl;
269l_uint32 *line, *data;
270
271 if (!pix)
272 return ERROR_INT("pix not defined", __func__, 1);
273 pixGetDimensions(pix, &w, &h, &d);
274 if (x < 0 || x >= w || y < 0 || y >= h)
275 return 2;
276
277 data = pixGetData(pix);
278 wpl = pixGetWpl(pix);
279 line = data + y * wpl;
280 switch (d)
281 {
282 case 1:
283 if (val)
284 SET_DATA_BIT(line, x);
285 else
286 CLEAR_DATA_BIT(line, x);
287 break;
288 case 2:
289 SET_DATA_DIBIT(line, x, val);
290 break;
291 case 4:
292 SET_DATA_QBIT(line, x, val);
293 break;
294 case 8:
295 SET_DATA_BYTE(line, x, val);
296 break;
297 case 16:
298 SET_DATA_TWO_BYTES(line, x, val);
299 break;
300 case 32:
301 line[x] = val;
302 break;
303 default:
304 return ERROR_INT("depth must be in {1,2,4,8,16,32} bpp", __func__, 1);
305 }
306
307 return 0;
308}
309
310
327l_ok
329 l_int32 x,
330 l_int32 y,
331 l_int32 *prval,
332 l_int32 *pgval,
333 l_int32 *pbval)
334{
335l_int32 w, h, d, wpl;
336l_uint32 *data, *ppixel;
337
338 if (prval) *prval = 0;
339 if (pgval) *pgval = 0;
340 if (pbval) *pbval = 0;
341 if (!prval && !pgval && !pbval)
342 return ERROR_INT("no output requested", __func__, 1);
343 if (!pix)
344 return ERROR_INT("pix not defined", __func__, 1);
345 pixGetDimensions(pix, &w, &h, &d);
346 if (d != 32)
347 return ERROR_INT("pix not 32 bpp", __func__, 1);
348 if (x < 0 || x >= w || y < 0 || y >= h)
349 return 2;
350
351 wpl = pixGetWpl(pix);
352 data = pixGetData(pix);
353 ppixel = data + y * wpl + x;
354 if (prval) *prval = GET_DATA_BYTE(ppixel, COLOR_RED);
355 if (pgval) *pgval = GET_DATA_BYTE(ppixel, COLOR_GREEN);
356 if (pbval) *pbval = GET_DATA_BYTE(ppixel, COLOR_BLUE);
357 return 0;
358}
359
360
377l_ok
379 l_int32 x,
380 l_int32 y,
381 l_int32 rval,
382 l_int32 gval,
383 l_int32 bval)
384{
385l_int32 w, h, d, wpl;
386l_uint32 pixel;
387l_uint32 *data, *line;
388
389 if (!pix)
390 return ERROR_INT("pix not defined", __func__, 1);
391 pixGetDimensions(pix, &w, &h, &d);
392 if (d != 32)
393 return ERROR_INT("pix not 32 bpp", __func__, 1);
394 if (x < 0 || x >= w || y < 0 || y >= h)
395 return 2;
396
397 wpl = pixGetWpl(pix);
398 data = pixGetData(pix);
399 line = data + y * wpl;
400 composeRGBPixel(rval, gval, bval, &pixel);
401 *(line + x) = pixel;
402 return 0;
403}
404
405
433l_ok
435 l_int32 x,
436 l_int32 y,
437 l_int32 rval,
438 l_int32 gval,
439 l_int32 bval)
440{
441l_int32 w, h, d, index;
442PIXCMAP *cmap;
443
444 if (!pix)
445 return ERROR_INT("pix not defined", __func__, 1);
446 if ((cmap = pixGetColormap(pix)) == NULL)
447 return ERROR_INT("pix is not colormapped", __func__, 1);
448 pixGetDimensions(pix, &w, &h, &d);
449 if (d != 2 && d != 4 && d != 8)
450 return ERROR_INT("pix depth not 2, 4 or 8", __func__, 1);
451 if (x < 0 || x >= w || y < 0 || y >= h)
452 return 2;
453
454 if (d == 8) { /* always add */
455 pixcmapAddNearestColor(cmap, rval, gval, bval, &index);
456 } else { /* d < 8 */
457 if (pixcmapAddNewColor(cmap, rval, gval, bval, &index) == 2)
458 return ERROR_INT("colormap is full", __func__, 2);
459 }
460 pixSetPixel(pix, x, y, index);
461 return 0;
462}
463
464
479l_ok
481 l_uint32 *pval,
482 l_int32 *px,
483 l_int32 *py)
484{
485l_int32 w, h, x, y, rval, gval, bval;
486l_uint32 val;
487PIXCMAP *cmap;
488
489 if (pval) *pval = 0;
490 if (px) *px = 0;
491 if (py) *py = 0;
492 if (!pval && !px && !py)
493 return ERROR_INT("no output requested", __func__, 1);
494 if (!pix)
495 return ERROR_INT("pix not defined", __func__, 1);
496
497 pixGetDimensions(pix, &w, &h, NULL);
498 x = rand() % w;
499 y = rand() % h;
500 if (px) *px = x;
501 if (py) *py = y;
502 if (pval) {
503 pixGetPixel(pix, x, y, &val);
504 if ((cmap = pixGetColormap(pix)) != NULL) {
505 pixcmapGetColor(cmap, val, &rval, &gval, &bval);
506 composeRGBPixel(rval, gval, bval, pval);
507 } else {
508 *pval = val;
509 }
510 }
511
512 return 0;
513}
514
515
529l_ok
531 l_int32 x,
532 l_int32 y)
533{
534l_int32 w, h, d, wpl;
535l_uint32 *line, *data;
536
537 if (!pix)
538 return ERROR_INT("pix not defined", __func__, 1);
539 if (pixGetColormap(pix))
540 L_WARNING("cmapped: setting to 0 may not be intended\n", __func__);
541 pixGetDimensions(pix, &w, &h, &d);
542 if (x < 0 || x >= w || y < 0 || y >= h)
543 return 2;
544
545 wpl = pixGetWpl(pix);
546 data = pixGetData(pix);
547 line = data + y * wpl;
548 switch (d)
549 {
550 case 1:
551 CLEAR_DATA_BIT(line, x);
552 break;
553 case 2:
554 CLEAR_DATA_DIBIT(line, x);
555 break;
556 case 4:
557 CLEAR_DATA_QBIT(line, x);
558 break;
559 case 8:
560 SET_DATA_BYTE(line, x, 0);
561 break;
562 case 16:
563 SET_DATA_TWO_BYTES(line, x, 0);
564 break;
565 case 32:
566 line[x] = 0;
567 break;
568 default:
569 return ERROR_INT("depth must be in {1,2,4,8,16,32} bpp", __func__, 1);
570 }
571
572 return 0;
573}
574
575
589l_ok
591 l_int32 x,
592 l_int32 y)
593{
594l_int32 w, h, d, wpl;
595l_uint32 val;
596l_uint32 *line, *data;
597
598 if (!pix)
599 return ERROR_INT("pix not defined", __func__, 1);
600 if (pixGetColormap(pix))
601 L_WARNING("cmapped: setting to 0 may not be intended\n", __func__);
602 pixGetDimensions(pix, &w, &h, &d);
603 if (x < 0 || x >= w || y < 0 || y >= h)
604 return 2;
605
606 data = pixGetData(pix);
607 wpl = pixGetWpl(pix);
608 line = data + y * wpl;
609 switch (d)
610 {
611 case 1:
612 val = GET_DATA_BIT(line, x);
613 if (val)
614 CLEAR_DATA_BIT(line, x);
615 else
616 SET_DATA_BIT(line, x);
617 break;
618 case 2:
619 val = GET_DATA_DIBIT(line, x);
620 val ^= 0x3;
621 SET_DATA_DIBIT(line, x, val);
622 break;
623 case 4:
624 val = GET_DATA_QBIT(line, x);
625 val ^= 0xf;
626 SET_DATA_QBIT(line, x, val);
627 break;
628 case 8:
629 val = GET_DATA_BYTE(line, x);
630 val ^= 0xff;
631 SET_DATA_BYTE(line, x, val);
632 break;
633 case 16:
634 val = GET_DATA_TWO_BYTES(line, x);
635 val ^= 0xffff;
636 SET_DATA_TWO_BYTES(line, x, val);
637 break;
638 case 32:
639 val = line[x] ^ 0xffffffff;
640 line[x] = val;
641 break;
642 default:
643 return ERROR_INT("depth must be in {1,2,4,8,16,32} bpp", __func__, 1);
644 }
645
646 return 0;
647}
648
649
664void
665setPixelLow(l_uint32 *line,
666 l_int32 x,
667 l_int32 depth,
668 l_uint32 val)
669{
670 switch (depth)
671 {
672 case 1:
673 if (val)
674 SET_DATA_BIT(line, x);
675 else
676 CLEAR_DATA_BIT(line, x);
677 break;
678 case 2:
679 SET_DATA_DIBIT(line, x, val);
680 break;
681 case 4:
682 SET_DATA_QBIT(line, x, val);
683 break;
684 case 8:
685 SET_DATA_BYTE(line, x, val);
686 break;
687 case 16:
688 SET_DATA_TWO_BYTES(line, x, val);
689 break;
690 case 32:
691 line[x] = val;
692 break;
693 default:
694 lept_stderr("illegal depth in setPixelLow()\n");
695 }
696}
697
698
699/*-------------------------------------------------------------*
700 * Find black or white value *
701 *-------------------------------------------------------------*/
718l_ok
720 l_int32 op,
721 l_uint32 *pval)
722{
723l_int32 d, index;
724PIXCMAP *cmap;
725
726 if (!pval)
727 return ERROR_INT("&val not defined", __func__, 1);
728 *pval = 0;
729 if (!pixs)
730 return ERROR_INT("pixs not defined", __func__, 1);
731 if (op != L_GET_BLACK_VAL && op != L_GET_WHITE_VAL)
732 return ERROR_INT("invalid op", __func__, 1);
733
734 cmap = pixGetColormap(pixs);
735 d = pixGetDepth(pixs);
736 if (!cmap) {
737 if ((d == 1 && op == L_GET_WHITE_VAL) ||
738 (d > 1 && op == L_GET_BLACK_VAL)) { /* min val */
739 *pval = 0;
740 } else { /* max val */
741 *pval = (d == 32) ? 0xffffff00 : (1 << d) - 1;
742 }
743 } else { /* handle colormap */
744 if (op == L_GET_BLACK_VAL)
745 pixcmapAddBlackOrWhite(cmap, 0, &index);
746 else /* L_GET_WHITE_VAL */
747 pixcmapAddBlackOrWhite(cmap, 1, &index);
748 *pval = index;
749 }
750
751 return 0;
752}
753
754
755/*-------------------------------------------------------------*
756 * Full image clear/set/set-to-arbitrary-value/invert *
757 *-------------------------------------------------------------*/
772l_ok
774{
775 if (!pix)
776 return ERROR_INT("pix not defined", __func__, 1);
777
778 memset(pix->data, 0, 4LL * pix->wpl * pix->h);
779 return 0;
780}
781
782
798l_ok
800{
801l_int32 n;
802PIXCMAP *cmap;
803
804 if (!pix)
805 return ERROR_INT("pix not defined", __func__, 1);
806 if ((cmap = pixGetColormap(pix)) != NULL) {
807 n = pixcmapGetCount(cmap);
808 if (n < cmap->nalloc) /* cmap is not full */
809 return ERROR_INT("cmap entry does not exist", __func__, 1);
810 }
811
812 memset(pix->data, 0xff, 4LL * pix->wpl * pix->h);
813 return 0;
814}
815
816
838l_ok
840 l_int32 grayval)
841{
842l_int32 d, spp, index;
843l_uint32 val32;
844PIX *alpha;
845PIXCMAP *cmap;
846
847 if (!pix)
848 return ERROR_INT("pix not defined", __func__, 1);
849 if (grayval < 0) {
850 L_WARNING("grayval < 0; setting to 0\n", __func__);
851 grayval = 0;
852 } else if (grayval > 255) {
853 L_WARNING("grayval > 255; setting to 255\n", __func__);
854 grayval = 255;
855 }
856
857 /* Handle the colormap case */
858 cmap = pixGetColormap(pix);
859 if (cmap) {
860 pixcmapAddNearestColor(cmap, grayval, grayval, grayval, &index);
861 pixSetAllArbitrary(pix, index);
862 return 0;
863 }
864
865 /* Non-cmapped */
866 d = pixGetDepth(pix);
867 spp = pixGetSpp(pix);
868 if (d == 1) {
869 if (grayval < 128) /* black */
870 pixSetAll(pix);
871 else
872 pixClearAll(pix); /* white */
873 } else if (d < 8) {
874 grayval >>= 8 - d;
875 pixSetAllArbitrary(pix, grayval);
876 } else if (d == 8) {
877 pixSetAllArbitrary(pix, grayval);
878 } else if (d == 16) {
879 grayval |= (grayval << 8);
880 pixSetAllArbitrary(pix, grayval);
881 } else if (d == 32 && spp == 3) {
882 composeRGBPixel(grayval, grayval, grayval, &val32);
883 pixSetAllArbitrary(pix, val32);
884 } else if (d == 32 && spp == 4) {
886 composeRGBPixel(grayval, grayval, grayval, &val32);
887 pixSetAllArbitrary(pix, val32);
889 pixDestroy(&alpha);
890 } else {
891 L_ERROR("invalid depth: %d\n", __func__, d);
892 return 1;
893 }
894
895 return 0;
896}
897
898
928l_ok
930 l_uint32 val)
931{
932l_int32 n, i, j, w, h, d, wpl, npix;
933l_uint32 maxval, wordval;
934l_uint32 *data, *line;
935PIXCMAP *cmap;
936
937 if (!pix)
938 return ERROR_INT("pix not defined", __func__, 1);
939
940 /* If colormapped, make sure that val is less than the size
941 * of the cmap array. */
942 if ((cmap = pixGetColormap(pix)) != NULL) {
943 n = pixcmapGetCount(cmap);
944 if (val >= n) {
945 L_WARNING("index not in colormap; using last color\n", __func__);
946 val = n - 1;
947 }
948 }
949
950 /* Make sure val isn't too large for the pixel depth.
951 * If it is too large, set the pixel color to white. */
952 pixGetDimensions(pix, &w, &h, &d);
953 if (d < 32) {
954 maxval = (1 << d) - 1;
955 if (val > maxval) {
956 L_WARNING("val = %d too large for depth; using maxval = %d\n",
957 __func__, val, maxval);
958 val = maxval;
959 }
960 }
961
962 /* Set up word to tile with */
963 wordval = 0;
964 npix = 32 / d; /* number of pixels per 32 bit word */
965 for (j = 0; j < npix; j++)
966 wordval |= (val << (j * d));
967 wpl = pixGetWpl(pix);
968 data = pixGetData(pix);
969 for (i = 0; i < h; i++) {
970 line = data + i * wpl;
971 for (j = 0; j < wpl; j++) {
972 *(line + j) = wordval;
973 }
974 }
975 return 0;
976}
977
978
996l_ok
998 l_int32 op)
999{
1000l_int32 d, index;
1001PIXCMAP *cmap;
1002
1003 if (!pixs)
1004 return ERROR_INT("pix not defined", __func__, 1);
1005 if (op != L_SET_BLACK && op != L_SET_WHITE)
1006 return ERROR_INT("invalid op", __func__, 1);
1007
1008 cmap = pixGetColormap(pixs);
1009 d = pixGetDepth(pixs);
1010 if (!cmap) {
1011 if ((d == 1 && op == L_SET_BLACK) || (d > 1 && op == L_SET_WHITE))
1012 pixSetAll(pixs);
1013 else
1014 pixClearAll(pixs);
1015 } else { /* handle colormap */
1016 if (op == L_SET_BLACK)
1017 pixcmapAddBlackOrWhite(cmap, 0, &index);
1018 else /* L_SET_WHITE */
1019 pixcmapAddBlackOrWhite(cmap, 1, &index);
1020 pixSetAllArbitrary(pixs, index);
1021 }
1022
1023 return 0;
1024}
1025
1026
1041l_ok
1043 l_int32 comp,
1044 l_int32 val)
1045{
1046l_int32 i, nwords;
1047l_uint32 mask1, mask2;
1048l_uint32 *data;
1049
1050 if (!pix || pixGetDepth(pix) != 32)
1051 return ERROR_INT("pix not defined or not 32 bpp", __func__, 1);
1052 if (comp != COLOR_RED && comp != COLOR_GREEN && comp != COLOR_BLUE &&
1053 comp != L_ALPHA_CHANNEL)
1054 return ERROR_INT("invalid component", __func__, 1);
1055 if (val < 0 || val > 255)
1056 return ERROR_INT("val not in [0 ... 255]", __func__, 1);
1057
1058 mask1 = ~(255 << (8 * (3 - comp)));
1059 mask2 = val << (8 * (3 - comp));
1060 nwords = pixGetHeight(pix) * pixGetWpl(pix);
1061 data = pixGetData(pix);
1062 for (i = 0; i < nwords; i++) {
1063 data[i] &= mask1; /* clear out the component */
1064 data[i] |= mask2; /* insert the new component value */
1065 }
1066
1067 return 0;
1068}
1069
1070
1071/*-------------------------------------------------------------*
1072 * Rectangular region clear/set/set-to-arbitrary-value *
1073 *-------------------------------------------------------------*/
1089l_ok
1091 BOX *box)
1092{
1093l_int32 x, y, w, h;
1094
1095 if (!pix)
1096 return ERROR_INT("pix not defined", __func__, 1);
1097 if (!box)
1098 return ERROR_INT("box not defined", __func__, 1);
1099
1100 boxGetGeometry(box, &x, &y, &w, &h);
1101 pixRasterop(pix, x, y, w, h, PIX_CLR, NULL, 0, 0);
1102 return 0;
1103}
1104
1105
1122l_ok
1124 BOX *box)
1125{
1126l_int32 n, x, y, w, h;
1127PIXCMAP *cmap;
1128
1129 if (!pix)
1130 return ERROR_INT("pix not defined", __func__, 1);
1131 if (!box)
1132 return ERROR_INT("box not defined", __func__, 1);
1133 if ((cmap = pixGetColormap(pix)) != NULL) {
1134 n = pixcmapGetCount(cmap);
1135 if (n < cmap->nalloc) /* cmap is not full */
1136 return ERROR_INT("cmap entry does not exist", __func__, 1);
1137 }
1138
1139 boxGetGeometry(box, &x, &y, &w, &h);
1140 pixRasterop(pix, x, y, w, h, PIX_SET, NULL, 0, 0);
1141 return 0;
1142}
1143
1144
1162l_ok
1164 BOX *box,
1165 l_uint32 val)
1166{
1167l_int32 n, x, y, xstart, xend, ystart, yend, bw, bh, w, h, d, wpl;
1168l_uint32 maxval;
1169l_uint32 *data, *line;
1170BOX *boxc;
1171PIXCMAP *cmap;
1172
1173 if (!pix)
1174 return ERROR_INT("pix not defined", __func__, 1);
1175 if (!box)
1176 return ERROR_INT("box not defined", __func__, 1);
1177 pixGetDimensions(pix, &w, &h, &d);
1178 if (d != 1 && d != 2 && d != 4 && d !=8 && d != 16 && d != 32)
1179 return ERROR_INT("depth must be in {1,2,4,8,16,32} bpp", __func__, 1);
1180 if ((cmap = pixGetColormap(pix)) != NULL) {
1181 n = pixcmapGetCount(cmap);
1182 if (val >= n) {
1183 L_WARNING("index not in colormap; using last color\n", __func__);
1184 val = n - 1;
1185 }
1186 }
1187
1188 maxval = (d == 32) ? 0xffffff00 : (1 << d) - 1;
1189 if (val > maxval) val = maxval;
1190
1191 /* Handle the simple cases: the min and max values */
1192 if (val == 0) {
1193 pixClearInRect(pix, box);
1194 return 0;
1195 }
1196 if (d == 1 ||
1197 (d == 2 && val == 3) ||
1198 (d == 4 && val == 0xf) ||
1199 (d == 8 && val == 0xff) ||
1200 (d == 16 && val == 0xffff) ||
1201 (d == 32 && ((val ^ 0xffffff00) >> 8 == 0))) {
1202 pixSetInRect(pix, box);
1203 return 0;
1204 }
1205
1206 /* Find the overlap of box with the input pix */
1207 if ((boxc = boxClipToRectangle(box, w, h)) == NULL)
1208 return ERROR_INT("no overlap of box with image", __func__, 1);
1209 boxGetGeometry(boxc, &xstart, &ystart, &bw, &bh);
1210 xend = xstart + bw - 1;
1211 yend = ystart + bh - 1;
1212 boxDestroy(&boxc);
1213
1214 wpl = pixGetWpl(pix);
1215 data = pixGetData(pix);
1216 for (y = ystart; y <= yend; y++) {
1217 line = data + y * wpl;
1218 for (x = xstart; x <= xend; x++) {
1219 switch(d)
1220 {
1221 case 2:
1222 SET_DATA_DIBIT(line, x, val);
1223 break;
1224 case 4:
1225 SET_DATA_QBIT(line, x, val);
1226 break;
1227 case 8:
1228 SET_DATA_BYTE(line, x, val);
1229 break;
1230 case 16:
1231 SET_DATA_TWO_BYTES(line, x, val);
1232 break;
1233 case 32:
1234 line[x] = val;
1235 break;
1236 default:
1237 return ERROR_INT("depth not 2|4|8|16|32 bpp", __func__, 1);
1238 }
1239 }
1240 }
1241
1242 return 0;
1243}
1244
1245
1262l_ok
1264 BOX *box,
1265 l_uint32 val,
1266 l_float32 fract)
1267{
1268l_int32 i, j, bx, by, bw, bh, w, h, wpls;
1269l_int32 prval, pgval, pbval, rval, gval, bval;
1270l_uint32 val32;
1271l_uint32 *datas, *lines;
1272
1273 if (!pixs || pixGetDepth(pixs) != 32)
1274 return ERROR_INT("pixs not defined or not 32 bpp", __func__, 1);
1275
1276 extractRGBValues(val, &rval, &gval, &bval);
1277 pixGetDimensions(pixs, &w, &h, NULL);
1278 datas = pixGetData(pixs);
1279 wpls = pixGetWpl(pixs);
1280 if (!box) {
1281 for (i = 0; i < h; i++) { /* scan over box */
1282 lines = datas + i * wpls;
1283 for (j = 0; j < w; j++) {
1284 val32 = *(lines + j);
1285 extractRGBValues(val32, &prval, &pgval, &pbval);
1286 prval = (l_int32)((1. - fract) * prval + fract * rval);
1287 pgval = (l_int32)((1. - fract) * pgval + fract * gval);
1288 pbval = (l_int32)((1. - fract) * pbval + fract * bval);
1289 composeRGBPixel(prval, pgval, pbval, &val32);
1290 *(lines + j) = val32;
1291 }
1292 }
1293 return 0;
1294 }
1295
1296 boxGetGeometry(box, &bx, &by, &bw, &bh);
1297 for (i = 0; i < bh; i++) { /* scan over box */
1298 if (by + i < 0 || by + i >= h) continue;
1299 lines = datas + (by + i) * wpls;
1300 for (j = 0; j < bw; j++) {
1301 if (bx + j < 0 || bx + j >= w) continue;
1302 val32 = *(lines + bx + j);
1303 extractRGBValues(val32, &prval, &pgval, &pbval);
1304 prval = (l_int32)((1. - fract) * prval + fract * rval);
1305 pgval = (l_int32)((1. - fract) * pgval + fract * gval);
1306 pbval = (l_int32)((1. - fract) * pbval + fract * bval);
1307 composeRGBPixel(prval, pgval, pbval, &val32);
1308 *(lines + bx + j) = val32;
1309 }
1310 }
1311 return 0;
1312}
1313
1314
1315/*-------------------------------------------------------------*
1316 * Set pad bits *
1317 *-------------------------------------------------------------*/
1349l_ok
1351 l_int32 val)
1352{
1353l_int32 i, w, h, d, wpl, endbits, fullwords;
1354l_uint32 mask;
1355l_uint32 *data, *pword;
1356
1357 if (!pix)
1358 return ERROR_INT("pix not defined", __func__, 1);
1359
1360 pixGetDimensions(pix, &w, &h, &d);
1361 if (d == 32) /* no padding exists for 32 bpp */
1362 return 0;
1363 if (d == 24) { /* pixels not aligned with 32-bit words */
1364 L_INFO("pix is 24 bpp\n", __func__);
1365 return 1;
1366 }
1367
1368 data = pixGetData(pix);
1369 wpl = pixGetWpl(pix);
1370 endbits = 32 - (((l_int64)w * d) % 32);
1371 if (endbits == 32) /* no partial word */
1372 return 0;
1373 fullwords = (1LL * w * d) / 32;
1374 mask = rmask32[endbits];
1375 if (val == 0)
1376 mask = ~mask;
1377
1378 for (i = 0; i < h; i++) {
1379 pword = data + i * wpl + fullwords;
1380 if (val == 0) /* clear */
1381 *pword = *pword & mask;
1382 else /* set */
1383 *pword = *pword | mask;
1384 }
1385
1386 return 0;
1387}
1388
1389
1412l_ok
1414 l_int32 by,
1415 l_int32 bh,
1416 l_int32 val)
1417{
1418l_int32 i, w, h, d, wpl, endbits, fullwords;
1419l_uint32 mask;
1420l_uint32 *data, *pword;
1421
1422 if (!pix)
1423 return ERROR_INT("pix not defined", __func__, 1);
1424
1425 pixGetDimensions(pix, &w, &h, &d);
1426 if (d == 32) /* no padding exists for 32 bpp */
1427 return 0;
1428 if (d == 24) { /* pixels not aligned with 32-bit words */
1429 L_INFO("pix is 24 bpp\n", __func__);
1430 return 1;
1431 }
1432
1433 if (by < 0)
1434 by = 0;
1435 if (by >= h)
1436 return ERROR_INT("start y not in image", __func__, 1);
1437 if (by + bh > h)
1438 bh = h - by;
1439
1440 data = pixGetData(pix);
1441 wpl = pixGetWpl(pix);
1442 endbits = 32 - (((l_int64)w * d) % 32);
1443 if (endbits == 32) /* no partial word */
1444 return 0;
1445 fullwords = (l_int64)w * d / 32;
1446
1447 mask = rmask32[endbits];
1448 if (val == 0)
1449 mask = ~mask;
1450
1451 for (i = by; i < by + bh; i++) {
1452 pword = data + i * wpl + fullwords;
1453 if (val == 0) /* clear */
1454 *pword = *pword & mask;
1455 else /* set */
1456 *pword = *pword | mask;
1457 }
1458
1459 return 0;
1460}
1461
1462
1463/*-------------------------------------------------------------*
1464 * Set border pixels *
1465 *-------------------------------------------------------------*/
1486l_ok
1488 l_int32 left,
1489 l_int32 right,
1490 l_int32 top,
1491 l_int32 bot,
1492 l_int32 op)
1493{
1494l_int32 w, h;
1495
1496 if (!pixs)
1497 return ERROR_INT("pixs not defined", __func__, 1);
1498 if (op != PIX_SET && op != PIX_CLR)
1499 return ERROR_INT("op must be PIX_SET or PIX_CLR", __func__, 1);
1500
1501 pixGetDimensions(pixs, &w, &h, NULL);
1502 pixRasterop(pixs, 0, 0, left, h, op, NULL, 0, 0);
1503 pixRasterop(pixs, w - right, 0, right, h, op, NULL, 0, 0);
1504 pixRasterop(pixs, 0, 0, w, top, op, NULL, 0, 0);
1505 pixRasterop(pixs, 0, h - bot, w, bot, op, NULL, 0, 0);
1506
1507 return 0;
1508}
1509
1510
1533l_ok
1535 l_int32 left,
1536 l_int32 right,
1537 l_int32 top,
1538 l_int32 bot,
1539 l_uint32 val)
1540{
1541l_int32 w, h, d, wpls, i, j, bstart, rstart;
1542l_uint32 *datas, *lines;
1543
1544 if (!pixs)
1545 return ERROR_INT("pixs not defined", __func__, 1);
1546 pixGetDimensions(pixs, &w, &h, &d);
1547 if (d != 8 && d != 16 && d != 32)
1548 return ERROR_INT("depth must be 8, 16 or 32 bpp", __func__, 1);
1549
1550 datas = pixGetData(pixs);
1551 wpls = pixGetWpl(pixs);
1552 if (d == 8) {
1553 val &= 0xff;
1554 for (i = 0; i < top; i++) {
1555 lines = datas + i * wpls;
1556 for (j = 0; j < w; j++)
1557 SET_DATA_BYTE(lines, j, val);
1558 }
1559 rstart = w - right;
1560 bstart = h - bot;
1561 for (i = top; i < bstart; i++) {
1562 lines = datas + i * wpls;
1563 for (j = 0; j < left; j++)
1564 SET_DATA_BYTE(lines, j, val);
1565 for (j = rstart; j < w; j++)
1566 SET_DATA_BYTE(lines, j, val);
1567 }
1568 for (i = bstart; i < h; i++) {
1569 lines = datas + i * wpls;
1570 for (j = 0; j < w; j++)
1571 SET_DATA_BYTE(lines, j, val);
1572 }
1573 } else if (d == 16) {
1574 val &= 0xffff;
1575 for (i = 0; i < top; i++) {
1576 lines = datas + i * wpls;
1577 for (j = 0; j < w; j++)
1578 SET_DATA_TWO_BYTES(lines, j, val);
1579 }
1580 rstart = w - right;
1581 bstart = h - bot;
1582 for (i = top; i < bstart; i++) {
1583 lines = datas + i * wpls;
1584 for (j = 0; j < left; j++)
1585 SET_DATA_TWO_BYTES(lines, j, val);
1586 for (j = rstart; j < w; j++)
1587 SET_DATA_TWO_BYTES(lines, j, val);
1588 }
1589 for (i = bstart; i < h; i++) {
1590 lines = datas + i * wpls;
1591 for (j = 0; j < w; j++)
1592 SET_DATA_TWO_BYTES(lines, j, val);
1593 }
1594 } else { /* d == 32 */
1595 for (i = 0; i < top; i++) {
1596 lines = datas + i * wpls;
1597 for (j = 0; j < w; j++)
1598 *(lines + j) = val;
1599 }
1600 rstart = w - right;
1601 bstart = h - bot;
1602 for (i = top; i < bstart; i++) {
1603 lines = datas + i * wpls;
1604 for (j = 0; j < left; j++)
1605 *(lines + j) = val;
1606 for (j = rstart; j < w; j++)
1607 *(lines + j) = val;
1608 }
1609 for (i = bstart; i < h; i++) {
1610 lines = datas + i * wpls;
1611 for (j = 0; j < w; j++)
1612 *(lines + j) = val;
1613 }
1614 }
1615
1616 return 0;
1617}
1618
1619
1635l_ok
1637 l_int32 dist,
1638 l_uint32 val)
1639{
1640l_int32 w, h, d, i, j, xend, yend;
1641
1642 if (!pixs)
1643 return ERROR_INT("pixs not defined", __func__, 1);
1644 if (dist < 1)
1645 return ERROR_INT("dist must be > 0", __func__, 1);
1646 pixGetDimensions(pixs, &w, &h, &d);
1647 if (w < 2 * dist + 1 || h < 2 * dist + 1)
1648 return ERROR_INT("ring doesn't exist", __func__, 1);
1649 if (d < 32 && (val >= (1 << d)))
1650 return ERROR_INT("invalid pixel value", __func__, 1);
1651
1652 xend = w - dist;
1653 yend = h - dist;
1654 for (j = dist - 1; j <= xend; j++)
1655 pixSetPixel(pixs, j, dist - 1, val);
1656 for (j = dist - 1; j <= xend; j++)
1657 pixSetPixel(pixs, j, yend, val);
1658 for (i = dist - 1; i <= yend; i++)
1659 pixSetPixel(pixs, dist - 1, i, val);
1660 for (i = dist - 1; i <= yend; i++)
1661 pixSetPixel(pixs, xend, i, val);
1662
1663 return 0;
1664}
1665
1666
1684l_ok
1686 l_int32 left,
1687 l_int32 right,
1688 l_int32 top,
1689 l_int32 bot)
1690{
1691l_int32 i, j, w, h;
1692
1693 if (!pixs)
1694 return ERROR_INT("pixs not defined", __func__, 1);
1695
1696 pixGetDimensions(pixs, &w, &h, NULL);
1697 for (j = 0; j < left; j++)
1698 pixRasterop(pixs, left - 1 - j, top, 1, h - top - bot, PIX_SRC,
1699 pixs, left + j, top);
1700 for (j = 0; j < right; j++)
1701 pixRasterop(pixs, w - right + j, top, 1, h - top - bot, PIX_SRC,
1702 pixs, w - right - 1 - j, top);
1703 for (i = 0; i < top; i++)
1704 pixRasterop(pixs, 0, top - 1 - i, w, 1, PIX_SRC,
1705 pixs, 0, top + i);
1706 for (i = 0; i < bot; i++)
1707 pixRasterop(pixs, 0, h - bot + i, w, 1, PIX_SRC,
1708 pixs, 0, h - bot - 1 - i);
1709
1710 return 0;
1711}
1712
1713
1733PIX *
1735 PIX *pixs,
1736 l_int32 left,
1737 l_int32 right,
1738 l_int32 top,
1739 l_int32 bot)
1740{
1741l_int32 w, h;
1742
1743 if (!pixs)
1744 return (PIX *)ERROR_PTR("pixs not defined", __func__, pixd);
1745
1746 if (pixd) {
1747 if (pixd == pixs) {
1748 L_WARNING("same: nothing to do\n", __func__);
1749 return pixd;
1750 } else if (!pixSizesEqual(pixs, pixd)) {
1751 return (PIX *)ERROR_PTR("pixs and pixd sizes differ",
1752 __func__, pixd);
1753 }
1754 } else {
1755 if ((pixd = pixCreateTemplate(pixs)) == NULL)
1756 return (PIX *)ERROR_PTR("pixd not made", __func__, pixd);
1757 }
1758
1759 pixGetDimensions(pixs, &w, &h, NULL);
1760 pixRasterop(pixd, 0, 0, left, h, PIX_SRC, pixs, 0, 0);
1761 pixRasterop(pixd, w - right, 0, right, h, PIX_SRC, pixs, w - right, 0);
1762 pixRasterop(pixd, 0, 0, w, top, PIX_SRC, pixs, 0, 0);
1763 pixRasterop(pixd, 0, h - bot, w, bot, PIX_SRC, pixs, 0, h - bot);
1764 return pixd;
1765}
1766
1767
1768
1769/*-------------------------------------------------------------*
1770 * Add and remove border *
1771 *-------------------------------------------------------------*/
1785PIX *
1787 l_int32 npix,
1788 l_uint32 val)
1789{
1790 if (!pixs)
1791 return (PIX *)ERROR_PTR("pixs not defined", __func__, NULL);
1792 if (npix == 0)
1793 return pixClone(pixs);
1794 return pixAddBorderGeneral(pixs, npix, npix, npix, npix, val);
1795}
1796
1797
1823PIX *
1825 l_int32 left,
1826 l_int32 right,
1827 l_int32 top,
1828 l_int32 bot,
1829 l_int32 op)
1830{
1831l_uint32 val;
1832
1833 if (!pixs)
1834 return (PIX *)ERROR_PTR("pixs not defined", __func__, NULL);
1835 if (op != L_GET_BLACK_VAL && op != L_GET_WHITE_VAL)
1836 return (PIX *)ERROR_PTR("invalid op", __func__, NULL);
1837
1838 pixGetBlackOrWhiteVal(pixs, op, &val);
1839 return pixAddBorderGeneral(pixs, left, right, top, bot, val);
1840}
1841
1842
1875PIX *
1877 l_int32 left,
1878 l_int32 right,
1879 l_int32 top,
1880 l_int32 bot,
1881 l_uint32 val)
1882{
1883l_int32 ws, hs, wd, hd, d, op;
1884l_uint32 maxval;
1885PIX *pixd;
1886
1887 if (!pixs)
1888 return (PIX *)ERROR_PTR("pixs not defined", __func__, NULL);
1889 if (left < 0 || right < 0 || top < 0 || bot < 0)
1890 return (PIX *)ERROR_PTR("negative border added!", __func__, NULL);
1891
1892 pixGetDimensions(pixs, &ws, &hs, &d);
1893 wd = ws + left + right;
1894 hd = hs + top + bot;
1895 if ((pixd = pixCreate(wd, hd, d)) == NULL)
1896 return (PIX *)ERROR_PTR("pixd not made", __func__, NULL);
1897 pixCopyResolution(pixd, pixs);
1898 pixCopyColormap(pixd, pixs);
1899
1900 /* Set the new border pixels */
1901 maxval = (d == 32) ? 0xffffff00 : (1 << d) - 1;
1902 op = UNDEF;
1903 if (val == 0)
1904 op = PIX_CLR;
1905 else if (val >= maxval)
1906 op = PIX_SET;
1907 if (op == UNDEF) {
1908 pixSetAllArbitrary(pixd, val);
1909 } else { /* just set or clear the border pixels */
1910 pixRasterop(pixd, 0, 0, left, hd, op, NULL, 0, 0);
1911 pixRasterop(pixd, wd - right, 0, right, hd, op, NULL, 0, 0);
1912 pixRasterop(pixd, 0, 0, wd, top, op, NULL, 0, 0);
1913 pixRasterop(pixd, 0, hd - bot, wd, bot, op, NULL, 0, 0);
1914 }
1915
1916 /* Copy pixs into the interior */
1917 pixRasterop(pixd, left, top, ws, hs, PIX_SRC, pixs, 0, 0);
1918 return pixd;
1919}
1920
1921
1944PIX *
1946 l_int32 nblack1,
1947 l_int32 nwhite1,
1948 l_int32 nblack2,
1949 l_int32 nwhite2,
1950 l_int32 nblack3,
1951 l_int32 nwhite3)
1952{
1953l_int32 i, color;
1954l_int32 w[6];
1955PIX *pix1, *pixd;
1956
1957 if (!pixs)
1958 return (PIX *)ERROR_PTR("pixs not defined", __func__, NULL);
1959
1960 w[0] = nblack1;
1961 w[1] = nwhite1;
1962 w[2] = nblack2;
1963 w[3] = nwhite2;
1964 w[4] = nblack3;
1965 w[5] = nwhite3;
1966 pixd = pixClone(pixs);
1967 for (i = 0; i < 6; i++) {
1968 if (w[i] > 500)
1969 L_WARNING("w = %d > 500; skipping\n", __func__, w[i]);
1970 if (w[i] > 0 && w[i] <= 500) {
1971 color = (i % 2 == 0) ? L_GET_BLACK_VAL : L_GET_WHITE_VAL;
1972 pix1 = pixAddBlackOrWhiteBorder(pixd, w[i], w[i], w[i], w[i],
1973 color);
1974 pixDestroy(&pixd);
1975 pixd = pix1;
1976 }
1977 }
1978
1979 return pixd;
1980}
1981
1982
1990PIX *
1992 l_int32 npix)
1993{
1994 if (!pixs)
1995 return (PIX *)ERROR_PTR("pixs not defined", __func__, NULL);
1996 if (npix == 0)
1997 return pixClone(pixs);
1998 return pixRemoveBorderGeneral(pixs, npix, npix, npix, npix);
1999}
2000
2001
2009PIX *
2011 l_int32 left,
2012 l_int32 right,
2013 l_int32 top,
2014 l_int32 bot)
2015{
2016l_int32 ws, hs, wd, hd, d;
2017PIX *pixd;
2018
2019 if (!pixs)
2020 return (PIX *)ERROR_PTR("pixs not defined", __func__, NULL);
2021 if (left < 0 || right < 0 || top < 0 || bot < 0)
2022 return (PIX *)ERROR_PTR("negative border removed!", __func__, NULL);
2023
2024 pixGetDimensions(pixs, &ws, &hs, &d);
2025 wd = ws - left - right;
2026 hd = hs - top - bot;
2027 if (wd <= 0)
2028 return (PIX *)ERROR_PTR("width must be > 0", __func__, NULL);
2029 if (hd <= 0)
2030 return (PIX *)ERROR_PTR("height must be > 0", __func__, NULL);
2031 if ((pixd = pixCreate(wd, hd, d)) == NULL)
2032 return (PIX *)ERROR_PTR("pixd not made", __func__, NULL);
2033 pixCopyResolution(pixd, pixs);
2034 pixCopySpp(pixd, pixs);
2035 pixCopyColormap(pixd, pixs);
2036
2037 pixRasterop(pixd, 0, 0, wd, hd, PIX_SRC, pixs, left, top);
2038 if (pixGetDepth(pixs) == 32 && pixGetSpp(pixs) == 4)
2039 pixShiftAndTransferAlpha(pixd, pixs, -left, -top);
2040 return pixd;
2041}
2042
2043
2060PIX *
2062 l_int32 wd,
2063 l_int32 hd)
2064{
2065l_int32 w, h, top, bot, left, right, delta;
2066
2067 if (!pixs)
2068 return (PIX *)ERROR_PTR("pixs not defined", __func__, NULL);
2069
2070 pixGetDimensions(pixs, &w, &h, NULL);
2071 if ((wd <= 0 || wd >= w) && (hd <= 0 || hd >= h))
2072 return pixClone(pixs);
2073
2074 left = right = (w - wd) / 2;
2075 delta = w - 2 * left - wd;
2076 right += delta;
2077 top = bot = (h - hd) / 2;
2078 delta = h - hd - 2 * top;
2079 bot += delta;
2080 if (wd <= 0 || wd > w)
2081 left = right = 0;
2082 else if (hd <= 0 || hd > h)
2083 top = bot = 0;
2084
2085 return pixRemoveBorderGeneral(pixs, left, right, top, bot);
2086}
2087
2088
2113PIX *
2115 l_int32 left,
2116 l_int32 right,
2117 l_int32 top,
2118 l_int32 bot)
2119{
2120l_int32 i, j, w, h;
2121PIX *pixd;
2122
2123 if (!pixs)
2124 return (PIX *)ERROR_PTR("pixs not defined", __func__, NULL);
2125 pixGetDimensions(pixs, &w, &h, NULL);
2126 if (left > w || right > w || top > h || bot > h)
2127 return (PIX *)ERROR_PTR("border too large", __func__, NULL);
2128
2129 /* Set pixels on left, right, top and bottom, in that order */
2130 pixd = pixAddBorderGeneral(pixs, left, right, top, bot, 0);
2131 for (j = 0; j < left; j++)
2132 pixRasterop(pixd, left - 1 - j, top, 1, h, PIX_SRC,
2133 pixd, left + j, top);
2134 for (j = 0; j < right; j++)
2135 pixRasterop(pixd, left + w + j, top, 1, h, PIX_SRC,
2136 pixd, left + w - 1 - j, top);
2137 for (i = 0; i < top; i++)
2138 pixRasterop(pixd, 0, top - 1 - i, left + w + right, 1, PIX_SRC,
2139 pixd, 0, top + i);
2140 for (i = 0; i < bot; i++)
2141 pixRasterop(pixd, 0, top + h + i, left + w + right, 1, PIX_SRC,
2142 pixd, 0, top + h - 1 - i);
2143
2144 return pixd;
2145}
2146
2147
2164PIX *
2166 l_int32 left,
2167 l_int32 right,
2168 l_int32 top,
2169 l_int32 bot)
2170{
2171l_int32 w, h;
2172PIX *pixd;
2173
2174 if (!pixs)
2175 return (PIX *)ERROR_PTR("pixs not defined", __func__, NULL);
2176 pixGetDimensions(pixs, &w, &h, NULL);
2177 if (left > w || right > w || top > h || bot > h)
2178 return (PIX *)ERROR_PTR("border too large", __func__, NULL);
2179
2180 pixd = pixAddBorderGeneral(pixs, left, right, top, bot, 0);
2181
2182 /* Set pixels on left, right, top and bottom, in that order */
2183 pixRasterop(pixd, 0, top, left, h, PIX_SRC, pixd, w, top);
2184 pixRasterop(pixd, left + w, top, right, h, PIX_SRC, pixd, left, top);
2185 pixRasterop(pixd, 0, 0, left + w + right, top, PIX_SRC, pixd, 0, h);
2186 pixRasterop(pixd, 0, top + h, left + w + right, bot, PIX_SRC, pixd, 0, top);
2187
2188 return pixd;
2189}
2190
2191
2218PIX *
2220 l_int32 left,
2221 l_int32 right,
2222 l_int32 top,
2223 l_int32 bot)
2224{
2225l_int32 j, w, h;
2226PIX *pixd;
2227
2228 if (!pixs)
2229 return (PIX *)ERROR_PTR("pixs not defined", __func__, NULL);
2230 pixGetDimensions(pixs, &w, &h, NULL);
2231 if (left > w || right > w || top > h || bot > h)
2232 return (PIX *)ERROR_PTR("border too large", __func__, NULL);
2233
2234 /* Set mirrored pixels on left and right;
2235 * then set repeated pixels on top and bottom. */
2236 pixd = pixAddBorderGeneral(pixs, left, right, top, bot, 0);
2237 for (j = 0; j < left; j++)
2238 pixRasterop(pixd, left - 1 - j, top, 1, h, PIX_SRC,
2239 pixd, left + j, top);
2240 for (j = 0; j < right; j++)
2241 pixRasterop(pixd, left + w + j, top, 1, h, PIX_SRC,
2242 pixd, left + w - 1 - j, top);
2243 pixRasterop(pixd, 0, 0, left + w + right, top, PIX_SRC, pixd, 0, h);
2244 pixRasterop(pixd, 0, top + h, left + w + right, bot, PIX_SRC, pixd, 0, top);
2245
2246 return pixd;
2247}
2248
2249
2263PIX *
2265 l_int32 left,
2266 l_int32 right,
2267 l_int32 top,
2268 l_int32 bot)
2269{
2270l_int32 i, j, w, h;
2271PIX *pixd;
2272
2273 if (!pixs)
2274 return (PIX *)ERROR_PTR("pixs not defined", __func__, NULL);
2275
2276 pixd = pixAddBorderGeneral(pixs, left, right, top, bot, 0);
2277 pixGetDimensions(pixs, &w, &h, NULL);
2278 for (j = 0; j < left; j++)
2279 pixRasterop(pixd, j, top, 1, h, PIX_SRC, pixd, left, top);
2280 for (j = 0; j < right; j++)
2281 pixRasterop(pixd, left + w + j, top, 1, h,
2282 PIX_SRC, pixd, left + w - 1, top);
2283 for (i = 0; i < top; i++)
2284 pixRasterop(pixd, 0, i, left + w + right, 1, PIX_SRC, pixd, 0, top);
2285 for (i = 0; i < bot; i++)
2286 pixRasterop(pixd, 0, top + h + i, left + w + right, 1,
2287 PIX_SRC, pixd, 0, top + h - 1);
2288
2289 return pixd;
2290}
2291
2292
2293/*-------------------------------------------------------------------*
2294 * Helper functions using alpha *
2295 *-------------------------------------------------------------------*/
2304l_ok
2306 PIX *pixs,
2307 l_float32 shiftx,
2308 l_float32 shifty)
2309{
2310l_int32 w, h;
2311PIX *pix1, *pix2;
2312
2313 if (!pixs || !pixd)
2314 return ERROR_INT("pixs and pixd not both defined", __func__, 1);
2315 if (pixGetDepth(pixs) != 32 || pixGetSpp(pixs) != 4)
2316 return ERROR_INT("pixs not 32 bpp and 4 spp", __func__, 1);
2317 if (pixGetDepth(pixd) != 32)
2318 return ERROR_INT("pixd not 32 bpp", __func__, 1);
2319
2320 if (shiftx == 0 && shifty == 0) {
2322 return 0;
2323 }
2324
2325 pix1 = pixGetRGBComponent(pixs, L_ALPHA_CHANNEL);
2326 pixGetDimensions(pixd, &w, &h, NULL);
2327 pix2 = pixCreate(w, h, 8);
2328 pixRasterop(pix2, 0, 0, w, h, PIX_SRC, pix1, -shiftx, -shifty);
2330 pixDestroy(&pix1);
2331 pixDestroy(&pix2);
2332 return 0;
2333}
2334
2335
2353PIX *
2355 l_uint32 val,
2356 l_int32 maxw)
2357{
2358l_int32 w, width;
2359l_float32 scalefact;
2360PIX *pix1, *pix2, *pixd;
2361PIXA *pixa;
2362PIXCMAP *cmap;
2363
2364 if (!pixs)
2365 return (PIX *)ERROR_PTR("pixs not defined", __func__, NULL);
2366 cmap = pixGetColormap(pixs);
2367 if (!cmap && !(pixGetDepth(pixs) == 32 && pixGetSpp(pixs) == 4))
2368 return (PIX *)ERROR_PTR("pixs not cmap and not 32 bpp rgba",
2369 __func__, NULL);
2370 if ((w = pixGetWidth(pixs)) == 0)
2371 return (PIX *)ERROR_PTR("pixs width 0 !!", __func__, NULL);
2372
2373 if (cmap)
2374 pix1 = pixRemoveColormap(pixs, REMOVE_CMAP_WITH_ALPHA);
2375 else
2376 pix1 = pixCopy(NULL, pixs);
2377
2378 /* Scale if necessary so the output width is not larger than maxw */
2379 scalefact = (maxw == 0) ? 1.0f : L_MIN(1.0f, (l_float32)(maxw) / w);
2380 width = (l_int32)(scalefact * w);
2381
2382 pixa = pixaCreate(3);
2383 pixSetSpp(pix1, 3);
2384 pixaAddPix(pixa, pix1, L_INSERT); /* show the rgb values */
2385 pix1 = pixGetRGBComponent(pixs, L_ALPHA_CHANNEL);
2386 pix2 = pixConvertTo32(pix1);
2387 pixaAddPix(pixa, pix2, L_INSERT); /* show the alpha channel */
2388 pixDestroy(&pix1);
2389 pix1 = pixAlphaBlendUniform(pixs, (val & 0xffffff00));
2390 pixaAddPix(pixa, pix1, L_INSERT); /* with %val color bg showing */
2391 pixd = pixaDisplayTiledInRows(pixa, 32, width, scalefact, 0, 25, 2);
2392 pixaDestroy(&pixa);
2393 return pixd;
2394}
2395
2396
2397/*-------------------------------------------------------------*
2398 * Color sample setting and extraction *
2399 *-------------------------------------------------------------*/
2423PIX *
2425 PIX *pixg,
2426 PIX *pixb)
2427{
2428l_int32 wr, wg, wb, hr, hg, hb, dr, dg, db;
2429PIX *pixd;
2430
2431 if (!pixr)
2432 return (PIX *)ERROR_PTR("pixr not defined", __func__, NULL);
2433 if (!pixg)
2434 return (PIX *)ERROR_PTR("pixg not defined", __func__, NULL);
2435 if (!pixb)
2436 return (PIX *)ERROR_PTR("pixb not defined", __func__, NULL);
2437 pixGetDimensions(pixr, &wr, &hr, &dr);
2438 pixGetDimensions(pixg, &wg, &hg, &dg);
2439 pixGetDimensions(pixb, &wb, &hb, &db);
2440 if (dr != 8 || dg != 8 || db != 8)
2441 return (PIX *)ERROR_PTR("input pix not all 8 bpp", __func__, NULL);
2442 if (wr != wg || wr != wb)
2443 return (PIX *)ERROR_PTR("widths not the same", __func__, NULL);
2444 if (hr != hg || hr != hb)
2445 return (PIX *)ERROR_PTR("heights not the same", __func__, NULL);
2446
2447 if ((pixd = pixCreate(wr, hr, 32)) == NULL)
2448 return (PIX *)ERROR_PTR("pixd not made", __func__, NULL);
2449 pixCopyResolution(pixd, pixr);
2450 pixSetRGBComponent(pixd, pixr, COLOR_RED);
2451 pixSetRGBComponent(pixd, pixg, COLOR_GREEN);
2452 pixSetRGBComponent(pixd, pixb, COLOR_BLUE);
2453
2454 return pixd;
2455}
2456
2457
2477PIX *
2479 l_int32 comp)
2480{
2481l_int32 i, j, w, h, wpls, wpld, val;
2482l_uint32 *lines, *lined;
2483l_uint32 *datas, *datad;
2484PIX *pixd;
2485
2486 if (!pixs)
2487 return (PIX *)ERROR_PTR("pixs not defined", __func__, NULL);
2488 if (pixGetColormap(pixs))
2489 return pixGetRGBComponentCmap(pixs, comp);
2490 if (pixGetDepth(pixs) != 32)
2491 return (PIX *)ERROR_PTR("pixs not 32 bpp", __func__, NULL);
2492 if (comp != COLOR_RED && comp != COLOR_GREEN &&
2493 comp != COLOR_BLUE && comp != L_ALPHA_CHANNEL)
2494 return (PIX *)ERROR_PTR("invalid comp", __func__, NULL);
2495
2496 pixGetDimensions(pixs, &w, &h, NULL);
2497 if ((pixd = pixCreate(w, h, 8)) == NULL)
2498 return (PIX *)ERROR_PTR("pixd not made", __func__, NULL);
2499 pixCopyResolution(pixd, pixs);
2500 wpls = pixGetWpl(pixs);
2501 wpld = pixGetWpl(pixd);
2502 datas = pixGetData(pixs);
2503 datad = pixGetData(pixd);
2504 for (i = 0; i < h; i++) {
2505 lines = datas + i * wpls;
2506 lined = datad + i * wpld;
2507 for (j = 0; j < w; j++) {
2508 val = GET_DATA_BYTE(lines + j, comp);
2509 SET_DATA_BYTE(lined, j, val);
2510 }
2511 }
2512
2513 return pixd;
2514}
2515
2516
2534l_ok
2536 PIX *pixs,
2537 l_int32 comp)
2538{
2539l_uint8 srcbyte;
2540l_int32 i, j, w, h, ws, hs, wd, hd;
2541l_int32 wpls, wpld;
2542l_uint32 *lines, *lined;
2543l_uint32 *datas, *datad;
2544
2545 if (!pixd)
2546 return ERROR_INT("pixd not defined", __func__, 1);
2547 if (!pixs)
2548 return ERROR_INT("pixs not defined", __func__, 1);
2549 if (pixGetDepth(pixd) != 32)
2550 return ERROR_INT("pixd not 32 bpp", __func__, 1);
2551 if (pixGetDepth(pixs) != 8)
2552 return ERROR_INT("pixs not 8 bpp", __func__, 1);
2553 if (comp != COLOR_RED && comp != COLOR_GREEN &&
2554 comp != COLOR_BLUE && comp != L_ALPHA_CHANNEL)
2555 return ERROR_INT("invalid comp", __func__, 1);
2556 pixGetDimensions(pixs, &ws, &hs, NULL);
2557 pixGetDimensions(pixd, &wd, &hd, NULL);
2558 if (ws != wd || hs != hd)
2559 L_WARNING("images sizes not equal\n", __func__);
2560 w = L_MIN(ws, wd);
2561 h = L_MIN(hs, hd);
2562 if (comp == L_ALPHA_CHANNEL)
2563 pixSetSpp(pixd, 4);
2564 datas = pixGetData(pixs);
2565 datad = pixGetData(pixd);
2566 wpls = pixGetWpl(pixs);
2567 wpld = pixGetWpl(pixd);
2568 for (i = 0; i < h; i++) {
2569 lines = datas + i * wpls;
2570 lined = datad + i * wpld;
2571 for (j = 0; j < w; j++) {
2572 srcbyte = GET_DATA_BYTE(lines, j);
2573 SET_DATA_BYTE(lined + j, comp, srcbyte);
2574 }
2575 }
2576
2577 return 0;
2578}
2579
2580
2594PIX *
2596 l_int32 comp)
2597{
2598l_int32 i, j, w, h, val, index, valid;
2599l_int32 wplc, wpld;
2600l_uint32 *linec, *lined;
2601l_uint32 *datac, *datad;
2602PIX *pixc, *pixd;
2603PIXCMAP *cmap;
2604RGBA_QUAD *cta;
2605
2606 if (!pixs)
2607 return (PIX *)ERROR_PTR("pixs not defined", __func__, NULL);
2608 if ((cmap = pixGetColormap(pixs)) == NULL)
2609 return (PIX *)ERROR_PTR("pixs not cmapped", __func__, NULL);
2610 if (comp == L_ALPHA_CHANNEL)
2611 return (PIX *)ERROR_PTR("alpha in cmaps not supported", __func__, NULL);
2612 if (comp != COLOR_RED && comp != COLOR_GREEN && comp != COLOR_BLUE)
2613 return (PIX *)ERROR_PTR("invalid comp", __func__, NULL);
2614
2615 /* If not 8 bpp, make a cmapped 8 bpp pix */
2616 if (pixGetDepth(pixs) == 8)
2617 pixc = pixClone(pixs);
2618 else
2619 pixc = pixConvertTo8(pixs, TRUE);
2620 pixcmapIsValid(cmap, pixc, &valid);
2621 if (!valid) {
2622 pixDestroy(&pixc);
2623 return (PIX *)ERROR_PTR("invalid colormap", __func__, NULL);
2624 }
2625
2626 pixGetDimensions(pixs, &w, &h, NULL);
2627 if ((pixd = pixCreate(w, h, 8)) == NULL) {
2628 pixDestroy(&pixc);
2629 return (PIX *)ERROR_PTR("pixd not made", __func__, NULL);
2630 }
2631 pixCopyResolution(pixd, pixs);
2632 wplc = pixGetWpl(pixc);
2633 wpld = pixGetWpl(pixd);
2634 datac = pixGetData(pixc);
2635 datad = pixGetData(pixd);
2636 cta = (RGBA_QUAD *)cmap->array;
2637
2638 for (i = 0; i < h; i++) {
2639 linec = datac + i * wplc;
2640 lined = datad + i * wpld;
2641 if (comp == COLOR_RED) {
2642 for (j = 0; j < w; j++) {
2643 index = GET_DATA_BYTE(linec, j);
2644 val = cta[index].red;
2645 SET_DATA_BYTE(lined, j, val);
2646 }
2647 } else if (comp == COLOR_GREEN) {
2648 for (j = 0; j < w; j++) {
2649 index = GET_DATA_BYTE(linec, j);
2650 val = cta[index].green;
2651 SET_DATA_BYTE(lined, j, val);
2652 }
2653 } else if (comp == COLOR_BLUE) {
2654 for (j = 0; j < w; j++) {
2655 index = GET_DATA_BYTE(linec, j);
2656 val = cta[index].blue;
2657 SET_DATA_BYTE(lined, j, val);
2658 }
2659 }
2660 }
2661
2662 pixDestroy(&pixc);
2663 return pixd;
2664}
2665
2666
2682l_ok
2684 PIX *pixs,
2685 l_int32 comp)
2686{
2687l_int32 i, j, w, h, ws, hs, wd, hd, val;
2688l_int32 wpls, wpld;
2689l_uint32 *lines, *lined;
2690l_uint32 *datas, *datad;
2691
2692 if (!pixd && pixGetDepth(pixd) != 32)
2693 return ERROR_INT("pixd not defined or not 32 bpp", __func__, 1);
2694 if (!pixs && pixGetDepth(pixs) != 32)
2695 return ERROR_INT("pixs not defined or not 32 bpp", __func__, 1);
2696 if (comp != COLOR_RED && comp != COLOR_GREEN &&
2697 comp != COLOR_BLUE && comp != L_ALPHA_CHANNEL)
2698 return ERROR_INT("invalid component", __func__, 1);
2699 pixGetDimensions(pixs, &ws, &hs, NULL);
2700 pixGetDimensions(pixd, &wd, &hd, NULL);
2701 if (ws != wd || hs != hd)
2702 L_WARNING("images sizes not equal\n", __func__);
2703 w = L_MIN(ws, wd);
2704 h = L_MIN(hs, hd);
2705 if (comp == L_ALPHA_CHANNEL)
2706 pixSetSpp(pixd, 4);
2707 wpls = pixGetWpl(pixs);
2708 wpld = pixGetWpl(pixd);
2709 datas = pixGetData(pixs);
2710 datad = pixGetData(pixd);
2711 for (i = 0; i < h; i++) {
2712 lines = datas + i * wpls;
2713 lined = datad + i * wpld;
2714 for (j = 0; j < w; j++) {
2715 val = GET_DATA_BYTE(lines + j, comp);
2716 SET_DATA_BYTE(lined + j, comp, val);
2717 }
2718 }
2719 return 0;
2720}
2721
2722
2741l_ok
2742composeRGBPixel(l_int32 rval,
2743 l_int32 gval,
2744 l_int32 bval,
2745 l_uint32 *ppixel)
2746{
2747 if (!ppixel)
2748 return ERROR_INT("&pixel not defined", __func__, 1);
2749
2750 *ppixel = ((l_uint32)rval << L_RED_SHIFT) |
2751 ((l_uint32)gval << L_GREEN_SHIFT) |
2752 ((l_uint32)bval << L_BLUE_SHIFT);
2753 return 0;
2754}
2755
2756
2771l_ok
2772composeRGBAPixel(l_int32 rval,
2773 l_int32 gval,
2774 l_int32 bval,
2775 l_int32 aval,
2776 l_uint32 *ppixel)
2777{
2778 if (!ppixel)
2779 return ERROR_INT("&pixel not defined", __func__, 1);
2780
2781 *ppixel = ((l_uint32)rval << L_RED_SHIFT) |
2782 ((l_uint32)gval << L_GREEN_SHIFT) |
2783 ((l_uint32)bval << L_BLUE_SHIFT) |
2784 aval;
2785 return 0;
2786}
2787
2788
2806void
2807extractRGBValues(l_uint32 pixel,
2808 l_int32 *prval,
2809 l_int32 *pgval,
2810 l_int32 *pbval)
2811{
2812 if (prval) *prval = (pixel >> L_RED_SHIFT) & 0xff;
2813 if (pgval) *pgval = (pixel >> L_GREEN_SHIFT) & 0xff;
2814 if (pbval) *pbval = (pixel >> L_BLUE_SHIFT) & 0xff;
2815}
2816
2817
2828void
2829extractRGBAValues(l_uint32 pixel,
2830 l_int32 *prval,
2831 l_int32 *pgval,
2832 l_int32 *pbval,
2833 l_int32 *paval)
2834{
2835 if (prval) *prval = (pixel >> L_RED_SHIFT) & 0xff;
2836 if (pgval) *pgval = (pixel >> L_GREEN_SHIFT) & 0xff;
2837 if (pbval) *pbval = (pixel >> L_BLUE_SHIFT) & 0xff;
2838 if (paval) *paval = (pixel >> L_ALPHA_SHIFT) & 0xff;
2839}
2840
2841
2849l_int32
2851 l_int32 type)
2852{
2853l_int32 rval, gval, bval, val;
2854
2855 extractRGBValues(pixel, &rval, &gval, &bval);
2856 if (type == L_CHOOSE_MIN) {
2857 val = L_MIN(rval, gval);
2858 val = L_MIN(val, bval);
2859 } else { /* type == L_CHOOSE_MAX */
2860 val = L_MAX(rval, gval);
2861 val = L_MAX(val, bval);
2862 }
2863 return val;
2864}
2865
2866
2883l_ok
2885 l_int32 row,
2886 l_uint8 *bufr,
2887 l_uint8 *bufg,
2888 l_uint8 *bufb)
2889{
2890l_uint32 *lines;
2891l_int32 j, w, h;
2892l_int32 wpls;
2893
2894 if (!pixs)
2895 return ERROR_INT("pixs not defined", __func__, 1);
2896 if (pixGetDepth(pixs) != 32)
2897 return ERROR_INT("pixs not 32 bpp", __func__, 1);
2898 if (!bufr || !bufg || !bufb)
2899 return ERROR_INT("buffer not defined", __func__, 1);
2900
2901 pixGetDimensions(pixs, &w, &h, NULL);
2902 if (row < 0 || row >= h)
2903 return ERROR_INT("row out of bounds", __func__, 1);
2904 wpls = pixGetWpl(pixs);
2905 lines = pixGetData(pixs) + row * wpls;
2906
2907 for (j = 0; j < w; j++) {
2908 bufr[j] = GET_DATA_BYTE(lines + j, COLOR_RED);
2909 bufg[j] = GET_DATA_BYTE(lines + j, COLOR_GREEN);
2910 bufb[j] = GET_DATA_BYTE(lines + j, COLOR_BLUE);
2911 }
2912
2913 return 0;
2914}
2915
2916
2917/*-------------------------------------------------------------*
2918 * Raster line pixel setter *
2919 *-------------------------------------------------------------*/
2936l_ok
2937setLineDataVal(l_uint32 *line,
2938 l_int32 j,
2939 l_int32 d,
2940 l_uint32 val)
2941{
2942 if (!line)
2943 return ERROR_INT("line not defined", __func__, 1);
2944 if (j < 0)
2945 return ERROR_INT("j must be >= 0", __func__, 1);
2946 if (d != 1 && d != 2 && d != 4 && d != 8 && d != 16 && d != 32)
2947 return ERROR_INT("invalid d", __func__, 1);
2948
2949 if (d == 1)
2950 SET_DATA_BIT_VAL(line, j, val);
2951 else if (d == 2)
2952 SET_DATA_DIBIT(line, j, val);
2953 else if (d == 4)
2954 SET_DATA_QBIT(line, j, val);
2955 else if (d == 8)
2956 SET_DATA_BYTE(line, j, val);
2957 else if (d == 16)
2958 SET_DATA_TWO_BYTES(line, j, val);
2959 else /* d == 32 */
2960 *(line + j) = val;
2961 return 0;
2962}
2963
2964
2965/*-------------------------------------------------------------*
2966 * Pixel endian conversion *
2967 *-------------------------------------------------------------*/
2992PIX *
2994{
2995l_uint32 *datas, *datad;
2996l_int32 i, j, h, wpl;
2997l_uint32 word;
2998PIX *pixd;
2999
3000#ifdef L_BIG_ENDIAN
3001
3002 return pixClone(pixs);
3003
3004#else /* L_LITTLE_ENDIAN */
3005
3006 if (!pixs)
3007 return (PIX *)ERROR_PTR("pixs not defined", __func__, NULL);
3008
3009 datas = pixGetData(pixs);
3010 wpl = pixGetWpl(pixs);
3011 h = pixGetHeight(pixs);
3012 if ((pixd = pixCreateTemplate(pixs)) == NULL)
3013 return (PIX *)ERROR_PTR("pixd not made", __func__, NULL);
3014 datad = pixGetData(pixd);
3015 for (i = 0; i < h; i++) {
3016 for (j = 0; j < wpl; j++, datas++, datad++) {
3017 word = *datas;
3018 *datad = (word >> 24) |
3019 ((word >> 8) & 0x0000ff00) |
3020 ((word << 8) & 0x00ff0000) |
3021 (word << 24);
3022 }
3023 }
3024
3025 return pixd;
3026
3027#endif /* L_BIG_ENDIAN */
3028
3029}
3030
3031
3054l_ok
3056{
3057l_uint32 *data;
3058l_int32 i, j, h, wpl;
3059l_uint32 word;
3060
3061#ifdef L_BIG_ENDIAN
3062
3063 return 0;
3064
3065#else /* L_LITTLE_ENDIAN */
3066
3067 if (!pixs)
3068 return ERROR_INT("pixs not defined", __func__, 1);
3069
3070 data = pixGetData(pixs);
3071 wpl = pixGetWpl(pixs);
3072 h = pixGetHeight(pixs);
3073 for (i = 0; i < h; i++) {
3074 for (j = 0; j < wpl; j++, data++) {
3075 word = *data;
3076 *data = (word >> 24) |
3077 ((word >> 8) & 0x0000ff00) |
3078 ((word << 8) & 0x00ff0000) |
3079 (word << 24);
3080 }
3081 }
3082
3083 return 0;
3084
3085#endif /* L_BIG_ENDIAN */
3086
3087}
3088
3089
3110l_int32
3111lineEndianByteSwap(l_uint32 *datad,
3112 l_uint32 *datas,
3113 l_int32 wpl)
3114{
3115l_int32 j;
3116l_uint32 word;
3117
3118 if (!datad || !datas)
3119 return ERROR_INT("datad and datas not both defined", __func__, 1);
3120
3121#ifdef L_BIG_ENDIAN
3122
3123 memcpy(datad, datas, 4 * wpl);
3124 return 0;
3125
3126#else /* L_LITTLE_ENDIAN */
3127
3128 for (j = 0; j < wpl; j++, datas++, datad++) {
3129 word = *datas;
3130 *datad = (word >> 24) |
3131 ((word >> 8) & 0x0000ff00) |
3132 ((word << 8) & 0x00ff0000) |
3133 (word << 24);
3134 }
3135 return 0;
3136
3137#endif /* L_BIG_ENDIAN */
3138
3139}
3140
3141
3161PIX *
3163{
3164l_uint32 *datas, *datad;
3165l_int32 i, j, h, wpl;
3166l_uint32 word;
3167PIX *pixd;
3168
3169#ifdef L_BIG_ENDIAN
3170
3171 return pixClone(pixs);
3172
3173#else /* L_LITTLE_ENDIAN */
3174
3175 if (!pixs)
3176 return (PIX *)ERROR_PTR("pixs not defined", __func__, NULL);
3177
3178 datas = pixGetData(pixs);
3179 wpl = pixGetWpl(pixs);
3180 h = pixGetHeight(pixs);
3181 if ((pixd = pixCreateTemplate(pixs)) == NULL)
3182 return (PIX *)ERROR_PTR("pixd not made", __func__, NULL);
3183 datad = pixGetData(pixd);
3184 for (i = 0; i < h; i++) {
3185 for (j = 0; j < wpl; j++, datas++, datad++) {
3186 word = *datas;
3187 *datad = (word << 16) | (word >> 16);
3188 }
3189 }
3190
3191 return pixd;
3192
3193#endif /* L_BIG_ENDIAN */
3194
3195}
3196
3197
3213l_ok
3215{
3216l_uint32 *data;
3217l_int32 i, j, h, wpl;
3218l_uint32 word;
3219
3220#ifdef L_BIG_ENDIAN
3221
3222 return 0;
3223
3224#else /* L_LITTLE_ENDIAN */
3225
3226 if (!pixs)
3227 return ERROR_INT("pixs not defined", __func__, 1);
3228
3229 data = pixGetData(pixs);
3230 wpl = pixGetWpl(pixs);
3231 h = pixGetHeight(pixs);
3232 for (i = 0; i < h; i++) {
3233 for (j = 0; j < wpl; j++, data++) {
3234 word = *data;
3235 *data = (word << 16) | (word >> 16);
3236 }
3237 }
3238
3239 return 0;
3240
3241#endif /* L_BIG_ENDIAN */
3242
3243}
3244
3245
3246/*-------------------------------------------------------------*
3247 * Extract raster data as binary string *
3248 *-------------------------------------------------------------*/
3265l_ok
3267 l_uint8 **pdata,
3268 size_t *pnbytes)
3269{
3270l_int32 w, h, d, wpl, i, j, rval, gval, bval;
3271l_int32 databpl; /* bytes for each raster line in returned data */
3272l_uint8 *line, *data; /* packed data in returned array */
3273l_uint32 *rline, *rdata; /* data in pix raster */
3274
3275 if (pdata) *pdata = NULL;
3276 if (pnbytes) *pnbytes = 0;
3277 if (!pdata || !pnbytes)
3278 return ERROR_INT("&data and &nbytes not both defined", __func__, 1);
3279 if (!pixs)
3280 return ERROR_INT("pixs not defined", __func__, 1);
3281 pixGetDimensions(pixs, &w, &h, &d);
3282 if (d != 1 && d != 2 && d != 4 && d != 8 && d != 16 && d != 32)
3283 return ERROR_INT("depth not in {1,2,4,8,16,32}", __func__, 1);
3284
3285 pixSetPadBits(pixs, 0);
3286 rdata = pixGetData(pixs);
3287 wpl = pixGetWpl(pixs);
3288 if (d == 1)
3289 databpl = (w + 7) / 8;
3290 else if (d == 2)
3291 databpl = (w + 3) / 4;
3292 else if (d == 4)
3293 databpl = (w + 1) / 2;
3294 else if (d == 8 || d == 16)
3295 databpl = w * (d / 8);
3296 else /* d == 32 bpp rgb */
3297 databpl = 3 * w;
3298 if ((data = (l_uint8 *)LEPT_CALLOC((size_t)databpl * h, sizeof(l_uint8)))
3299 == NULL)
3300 return ERROR_INT("data not allocated", __func__, 1);
3301 *pdata = data;
3302 *pnbytes = (size_t)databpl * h;
3303
3304 for (i = 0; i < h; i++) {
3305 rline = rdata + i * wpl;
3306 line = data + i * databpl;
3307 if (d <= 8) {
3308 for (j = 0; j < databpl; j++)
3309 line[j] = GET_DATA_BYTE(rline, j);
3310 } else if (d == 16) {
3311 for (j = 0; j < w; j++)
3312 line[2 * j] = GET_DATA_TWO_BYTES(rline, j);
3313 } else { /* d == 32 bpp rgb */
3314 for (j = 0; j < w; j++) {
3315 extractRGBValues(rline[j], &rval, &gval, &bval);
3316 *(line + 3 * j) = rval;
3317 *(line + 3 * j + 1) = gval;
3318 *(line + 3 * j + 2) = bval;
3319 }
3320 }
3321 }
3322
3323 return 0;
3324}
3325
3326
3327/*-------------------------------------------------------------*
3328 * Infer resolution from image size *
3329 *-------------------------------------------------------------*/
3347l_ok
3349 l_float32 longside,
3350 l_int32 *pres)
3351{
3352l_int32 w, h, maxdim, res;
3353
3354 if (!pres)
3355 return ERROR_INT("&res not defined", __func__, 1);
3356 *pres = 300;
3357 if (!pix)
3358 return ERROR_INT("pix not defined", __func__, 1);
3359 if (longside <= 0.0)
3360 return ERROR_INT("longside not > 0", __func__, 1);
3361
3362 pixGetDimensions(pix, &w, &h, NULL);
3363 maxdim = L_MAX(w, h);
3364 res = (l_int32)(maxdim / longside + 0.5);
3365 res = L_MAX(res, 1); /* don't let it be 0 */
3366 if (res < 10)
3367 L_WARNING("low inferred resolution: %d ppi\n", __func__, res);
3368 if (res > 10000)
3369 L_WARNING("high inferred resolution: %d ppi\n", __func__, res);
3370 *pres = res;
3371 return 0;
3372}
3373
3374
3375/*-------------------------------------------------------------*
3376 * Test alpha component opaqueness *
3377 *-------------------------------------------------------------*/
3391l_ok
3393 l_int32 *popaque)
3394{
3395l_int32 w, h, wpl, i, j, alpha;
3396l_uint32 *data, *line;
3397
3398 if (!popaque)
3399 return ERROR_INT("&opaque not defined", __func__, 1);
3400 *popaque = FALSE;
3401 if (!pix)
3402 return ERROR_INT("&pix not defined", __func__, 1);
3403 if (pixGetDepth(pix) != 32)
3404 return ERROR_INT("&pix not 32 bpp", __func__, 1);
3405 if (pixGetSpp(pix) != 4)
3406 return ERROR_INT("&pix not 4 spp", __func__, 1);
3407
3408 data = pixGetData(pix);
3409 wpl = pixGetWpl(pix);
3410 pixGetDimensions(pix, &w, &h, NULL);
3411 for (i = 0; i < h; i++) {
3412 line = data + i * wpl;
3413 for (j = 0; j < w; j++) {
3414 alpha = GET_DATA_BYTE(line + j, L_ALPHA_CHANNEL);
3415 if (alpha ^ 0xff) /* not opaque */
3416 return 0;
3417 }
3418 }
3419
3420 *popaque = TRUE;
3421 return 0;
3422}
3423
3424
3425/*-------------------------------------------------------------*
3426 * Setup helpers for 8 bpp byte processing *
3427 *-------------------------------------------------------------*/
3454l_uint8 **
3456 l_int32 *pw,
3457 l_int32 *ph)
3458{
3459l_int32 w, h;
3460
3461 if (pw) *pw = 0;
3462 if (ph) *ph = 0;
3463 if (!pix || pixGetDepth(pix) != 8)
3464 return (l_uint8 **)ERROR_PTR("pix not defined or not 8 bpp",
3465 __func__, NULL);
3466 pixGetDimensions(pix, &w, &h, NULL);
3467 if (pw) *pw = w;
3468 if (ph) *ph = h;
3469 if (pixGetColormap(pix))
3470 return (l_uint8 **)ERROR_PTR("pix has colormap", __func__, NULL);
3471
3472 pixEndianByteSwap(pix);
3473 return (l_uint8 **)pixGetLinePtrs(pix, NULL);
3474}
3475
3476
3490l_ok
3492 l_uint8 **lineptrs)
3493{
3494 if (!pix)
3495 return ERROR_INT("pix not defined", __func__, 1);
3496 if (!lineptrs)
3497 return ERROR_INT("lineptrs not defined", __func__, 1);
3498
3499 pixEndianByteSwap(pix);
3500 LEPT_FREE(lineptrs);
3501 return 0;
3502}
3503
3504
3505/*------------------------------------------------------------------------*
3506 * Setting parameters for antialias masking with alpha transforms *
3507 *------------------------------------------------------------------------*/
3530void
3532 l_float32 val2)
3533{
3534 val1 = L_MAX(0.0f, L_MIN(1.0f, val1));
3535 val2 = L_MAX(0.0f, L_MIN(1.0f, val2));
3536 AlphaMaskBorderVals[0] = val1;
3537 AlphaMaskBorderVals[1] = val2;
3538}
#define GET_DATA_QBIT(pdata, n)
#define GET_DATA_TWO_BYTES(pdata, n)
#define CLEAR_DATA_QBIT(pdata, n)
#define CLEAR_DATA_DIBIT(pdata, n)
#define SET_DATA_BIT(pdata, n)
#define SET_DATA_DIBIT(pdata, n, val)
#define SET_DATA_TWO_BYTES(pdata, n, val)
#define SET_DATA_BIT_VAL(pdata, n, val)
#define GET_DATA_BYTE(pdata, n)
#define GET_DATA_DIBIT(pdata, n)
#define SET_DATA_BYTE(pdata, n, val)
#define CLEAR_DATA_BIT(pdata, n)
#define GET_DATA_BIT(pdata, n)
#define SET_DATA_QBIT(pdata, n, val)
l_ok pixSetInRectArbitrary(PIX *pix, BOX *box, l_uint32 val)
pixSetInRectArbitrary()
Definition pix2.c:1163
l_ok pixSetBorderRingVal(PIX *pixs, l_int32 dist, l_uint32 val)
pixSetBorderRingVal()
Definition pix2.c:1636
PIX * pixAddMultipleBlackWhiteBorders(PIX *pixs, l_int32 nblack1, l_int32 nwhite1, l_int32 nblack2, l_int32 nwhite2, l_int32 nblack3, l_int32 nwhite3)
pixAddMultipleBlackWhiteBorders()
Definition pix2.c:1945
l_ok pixAlphaIsOpaque(PIX *pix, l_int32 *popaque)
pixAlphaIsOpaque()
Definition pix2.c:3392
PIX * pixAddContinuedBorder(PIX *pixs, l_int32 left, l_int32 right, l_int32 top, l_int32 bot)
pixAddContinuedBorder()
Definition pix2.c:2264
l_int32 lineEndianByteSwap(l_uint32 *datad, l_uint32 *datas, l_int32 wpl)
lineEndianByteSwap()
Definition pix2.c:3111
PIX * pixDisplayLayersRGBA(PIX *pixs, l_uint32 val, l_int32 maxw)
pixDisplayLayersRGBA()
Definition pix2.c:2354
l_uint8 ** pixSetupByteProcessing(PIX *pix, l_int32 *pw, l_int32 *ph)
pixSetupByteProcessing()
Definition pix2.c:3455
l_ok pixSetPixel(PIX *pix, l_int32 x, l_int32 y, l_uint32 val)
pixSetPixel()
Definition pix2.c:263
PIX * pixAddRepeatedBorder(PIX *pixs, l_int32 left, l_int32 right, l_int32 top, l_int32 bot)
pixAddRepeatedBorder()
Definition pix2.c:2165
l_int32 extractMinMaxComponent(l_uint32 pixel, l_int32 type)
extractMinMaxComponent()
Definition pix2.c:2850
l_ok pixClearAll(PIX *pix)
pixClearAll()
Definition pix2.c:773
l_ok pixShiftAndTransferAlpha(PIX *pixd, PIX *pixs, l_float32 shiftx, l_float32 shifty)
pixShiftAndTransferAlpha()
Definition pix2.c:2305
l_ok pixGetPixel(PIX *pix, l_int32 x, l_int32 y, l_uint32 *pval)
pixGetPixel()
Definition pix2.c:192
l_ok pixClearInRect(PIX *pix, BOX *box)
pixClearInRect()
Definition pix2.c:1090
PIX * pixRemoveBorder(PIX *pixs, l_int32 npix)
pixRemoveBorder()
Definition pix2.c:1991
l_ok pixGetRGBLine(PIX *pixs, l_int32 row, l_uint8 *bufr, l_uint8 *bufg, l_uint8 *bufb)
pixGetRGBLine()
Definition pix2.c:2884
l_ok pixClearPixel(PIX *pix, l_int32 x, l_int32 y)
pixClearPixel()
Definition pix2.c:530
l_ok pixInferResolution(PIX *pix, l_float32 longside, l_int32 *pres)
pixInferResolution()
Definition pix2.c:3348
PIX * pixEndianByteSwapNew(PIX *pixs)
pixEndianByteSwapNew()
Definition pix2.c:2993
PIX * pixAddBlackOrWhiteBorder(PIX *pixs, l_int32 left, l_int32 right, l_int32 top, l_int32 bot, l_int32 op)
pixAddBlackOrWhiteBorder()
Definition pix2.c:1824
void extractRGBAValues(l_uint32 pixel, l_int32 *prval, l_int32 *pgval, l_int32 *pbval, l_int32 *paval)
extractRGBAValues()
Definition pix2.c:2829
l_ok pixEndianTwoByteSwap(PIX *pixs)
pixEndianTwoByteSwap()
Definition pix2.c:3214
PIX * pixCopyBorder(PIX *pixd, PIX *pixs, l_int32 left, l_int32 right, l_int32 top, l_int32 bot)
pixCopyBorder()
Definition pix2.c:1734
l_ok pixSetAllGray(PIX *pix, l_int32 grayval)
pixSetAllGray()
Definition pix2.c:839
l_ok pixSetBorderVal(PIX *pixs, l_int32 left, l_int32 right, l_int32 top, l_int32 bot, l_uint32 val)
pixSetBorderVal()
Definition pix2.c:1534
l_ok pixCopyRGBComponent(PIX *pixd, PIX *pixs, l_int32 comp)
pixCopyRGBComponent()
Definition pix2.c:2683
l_ok pixSetInRect(PIX *pix, BOX *box)
pixSetInRect()
Definition pix2.c:1123
void setPixelLow(l_uint32 *line, l_int32 x, l_int32 depth, l_uint32 val)
setPixelLow()
Definition pix2.c:665
void l_setAlphaMaskBorder(l_float32 val1, l_float32 val2)
l_setAlphaMaskBorder()
Definition pix2.c:3531
PIX * pixAddMixedBorder(PIX *pixs, l_int32 left, l_int32 right, l_int32 top, l_int32 bot)
pixAddMixedBorder()
Definition pix2.c:2219
l_ok pixGetRandomPixel(PIX *pix, l_uint32 *pval, l_int32 *px, l_int32 *py)
pixGetRandomPixel()
Definition pix2.c:480
l_ok pixGetBlackOrWhiteVal(PIX *pixs, l_int32 op, l_uint32 *pval)
pixGetBlackOrWhiteVal()
Definition pix2.c:719
PIX * pixRemoveBorderGeneral(PIX *pixs, l_int32 left, l_int32 right, l_int32 top, l_int32 bot)
pixRemoveBorderGeneral()
Definition pix2.c:2010
l_ok pixSetAll(PIX *pix)
pixSetAll()
Definition pix2.c:799
l_ok pixSetPadBits(PIX *pix, l_int32 val)
pixSetPadBits()
Definition pix2.c:1350
l_ok pixSetOrClearBorder(PIX *pixs, l_int32 left, l_int32 right, l_int32 top, l_int32 bot, l_int32 op)
pixSetOrClearBorder()
Definition pix2.c:1487
PIX * pixGetRGBComponentCmap(PIX *pixs, l_int32 comp)
pixGetRGBComponentCmap()
Definition pix2.c:2595
l_ok pixSetCmapPixel(PIX *pix, l_int32 x, l_int32 y, l_int32 rval, l_int32 gval, l_int32 bval)
pixSetCmapPixel()
Definition pix2.c:434
l_ok composeRGBAPixel(l_int32 rval, l_int32 gval, l_int32 bval, l_int32 aval, l_uint32 *ppixel)
composeRGBAPixel()
Definition pix2.c:2772
l_ok pixFlipPixel(PIX *pix, l_int32 x, l_int32 y)
pixFlipPixel()
Definition pix2.c:590
PIX * pixAddMirroredBorder(PIX *pixs, l_int32 left, l_int32 right, l_int32 top, l_int32 bot)
pixAddMirroredBorder()
Definition pix2.c:2114
l_ok pixBlendInRect(PIX *pixs, BOX *box, l_uint32 val, l_float32 fract)
pixBlendInRect()
Definition pix2.c:1263
l_ok composeRGBPixel(l_int32 rval, l_int32 gval, l_int32 bval, l_uint32 *ppixel)
composeRGBPixel()
Definition pix2.c:2742
l_ok pixCleanupByteProcessing(PIX *pix, l_uint8 **lineptrs)
pixCleanupByteProcessing()
Definition pix2.c:3491
void extractRGBValues(l_uint32 pixel, l_int32 *prval, l_int32 *pgval, l_int32 *pbval)
extractRGBValues()
Definition pix2.c:2807
l_ok setLineDataVal(l_uint32 *line, l_int32 j, l_int32 d, l_uint32 val)
setLineDataVal()
Definition pix2.c:2937
PIX * pixEndianTwoByteSwapNew(PIX *pixs)
pixEndianTwoByteSwapNew()
Definition pix2.c:3162
l_ok pixGetRGBPixel(PIX *pix, l_int32 x, l_int32 y, l_int32 *prval, l_int32 *pgval, l_int32 *pbval)
pixGetRGBPixel()
Definition pix2.c:328
l_ok pixSetMirroredBorder(PIX *pixs, l_int32 left, l_int32 right, l_int32 top, l_int32 bot)
pixSetMirroredBorder()
Definition pix2.c:1685
l_ok pixSetPadBitsBand(PIX *pix, l_int32 by, l_int32 bh, l_int32 val)
pixSetPadBitsBand()
Definition pix2.c:1413
PIX * pixAddBorder(PIX *pixs, l_int32 npix, l_uint32 val)
pixAddBorder()
Definition pix2.c:1786
l_ok pixEndianByteSwap(PIX *pixs)
pixEndianByteSwap()
Definition pix2.c:3055
l_ok pixSetBlackOrWhite(PIX *pixs, l_int32 op)
pixSetBlackOrWhite()
Definition pix2.c:997
PIX * pixGetRGBComponent(PIX *pixs, l_int32 comp)
pixGetRGBComponent()
Definition pix2.c:2478
PIX * pixAddBorderGeneral(PIX *pixs, l_int32 left, l_int32 right, l_int32 top, l_int32 bot, l_uint32 val)
pixAddBorderGeneral()
Definition pix2.c:1876
l_ok pixSetRGBComponent(PIX *pixd, PIX *pixs, l_int32 comp)
pixSetRGBComponent()
Definition pix2.c:2535
l_ok pixSetRGBPixel(PIX *pix, l_int32 x, l_int32 y, l_int32 rval, l_int32 gval, l_int32 bval)
pixSetRGBPixel()
Definition pix2.c:378
l_ok pixSetComponentArbitrary(PIX *pix, l_int32 comp, l_int32 val)
pixSetComponentArbitrary()
Definition pix2.c:1042
PIX * pixRemoveBorderToSize(PIX *pixs, l_int32 wd, l_int32 hd)
pixRemoveBorderToSize()
Definition pix2.c:2061
l_ok pixSetAllArbitrary(PIX *pix, l_uint32 val)
pixSetAllArbitrary()
Definition pix2.c:929
l_ok pixGetRasterData(PIX *pixs, l_uint8 **pdata, size_t *pnbytes)
pixGetRasterData()
Definition pix2.c:3266
PIX * pixCreateRGBImage(PIX *pixr, PIX *pixg, PIX *pixb)
pixCreateRGBImage()
Definition pix2.c:2424
@ COLOR_BLUE
Definition pix.h:330
@ COLOR_RED
Definition pix.h:328
@ L_ALPHA_CHANNEL
Definition pix.h:331
@ COLOR_GREEN
Definition pix.h:329
@ REMOVE_CMAP_WITH_ALPHA
Definition pix.h:383
@ L_INSERT
Definition pix.h:504
@ L_SET_WHITE
Definition pix.h:699
@ L_SET_BLACK
Definition pix.h:700
#define PIX_SRC
Definition pix.h:444
#define PIX_CLR
Definition pix.h:447
#define PIX_SET
Definition pix.h:448
@ L_GET_BLACK_VAL
Definition pix.h:709
@ L_GET_WHITE_VAL
Definition pix.h:708
l_uint32 * data
l_uint32 wpl
l_uint32 h
l_uint8 green
l_uint8 blue
l_uint8 red