Leptonica 1.84.1
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, val;
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 val = 0;
740 } else { /* max val */
741 val = (d == 32) ? 0xffffff00 : (1 << d) - 1;
742 }
743 } else { /* handle colormap */
744 if (op == L_GET_BLACK_VAL)
745 pixcmapAddBlackOrWhite(cmap, 0, &val);
746 else /* L_GET_WHITE_VAL */
747 pixcmapAddBlackOrWhite(cmap, 1, &val);
748 }
749 *pval = val;
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, maxval;
1168l_uint32 *data, *line;
1169BOX *boxc;
1170PIXCMAP *cmap;
1171
1172 if (!pix)
1173 return ERROR_INT("pix not defined", __func__, 1);
1174 if (!box)
1175 return ERROR_INT("box not defined", __func__, 1);
1176 pixGetDimensions(pix, &w, &h, &d);
1177 if (d != 1 && d != 2 && d != 4 && d !=8 && d != 16 && d != 32)
1178 return ERROR_INT("depth must be in {1,2,4,8,16,32} bpp", __func__, 1);
1179 if ((cmap = pixGetColormap(pix)) != NULL) {
1180 n = pixcmapGetCount(cmap);
1181 if (val >= n) {
1182 L_WARNING("index not in colormap; using last color\n", __func__);
1183 val = n - 1;
1184 }
1185 }
1186
1187 maxval = (d == 32) ? 0xffffff00 : (1 << d) - 1;
1188 if (val > maxval) val = maxval;
1189
1190 /* Handle the simple cases: the min and max values */
1191 if (val == 0) {
1192 pixClearInRect(pix, box);
1193 return 0;
1194 }
1195 if (d == 1 ||
1196 (d == 2 && val == 3) ||
1197 (d == 4 && val == 0xf) ||
1198 (d == 8 && val == 0xff) ||
1199 (d == 16 && val == 0xffff) ||
1200 (d == 32 && ((val ^ 0xffffff00) >> 8 == 0))) {
1201 pixSetInRect(pix, box);
1202 return 0;
1203 }
1204
1205 /* Find the overlap of box with the input pix */
1206 if ((boxc = boxClipToRectangle(box, w, h)) == NULL)
1207 return ERROR_INT("no overlap of box with image", __func__, 1);
1208 boxGetGeometry(boxc, &xstart, &ystart, &bw, &bh);
1209 xend = xstart + bw - 1;
1210 yend = ystart + bh - 1;
1211 boxDestroy(&boxc);
1212
1213 wpl = pixGetWpl(pix);
1214 data = pixGetData(pix);
1215 for (y = ystart; y <= yend; y++) {
1216 line = data + y * wpl;
1217 for (x = xstart; x <= xend; x++) {
1218 switch(d)
1219 {
1220 case 2:
1221 SET_DATA_DIBIT(line, x, val);
1222 break;
1223 case 4:
1224 SET_DATA_QBIT(line, x, val);
1225 break;
1226 case 8:
1227 SET_DATA_BYTE(line, x, val);
1228 break;
1229 case 16:
1230 SET_DATA_TWO_BYTES(line, x, val);
1231 break;
1232 case 32:
1233 line[x] = val;
1234 break;
1235 default:
1236 return ERROR_INT("depth not 2|4|8|16|32 bpp", __func__, 1);
1237 }
1238 }
1239 }
1240
1241 return 0;
1242}
1243
1244
1261l_ok
1263 BOX *box,
1264 l_uint32 val,
1265 l_float32 fract)
1266{
1267l_int32 i, j, bx, by, bw, bh, w, h, wpls;
1268l_int32 prval, pgval, pbval, rval, gval, bval;
1269l_uint32 val32;
1270l_uint32 *datas, *lines;
1271
1272 if (!pixs || pixGetDepth(pixs) != 32)
1273 return ERROR_INT("pixs not defined or not 32 bpp", __func__, 1);
1274
1275 extractRGBValues(val, &rval, &gval, &bval);
1276 pixGetDimensions(pixs, &w, &h, NULL);
1277 datas = pixGetData(pixs);
1278 wpls = pixGetWpl(pixs);
1279 if (!box) {
1280 for (i = 0; i < h; i++) { /* scan over box */
1281 lines = datas + i * wpls;
1282 for (j = 0; j < w; j++) {
1283 val32 = *(lines + j);
1284 extractRGBValues(val32, &prval, &pgval, &pbval);
1285 prval = (l_int32)((1. - fract) * prval + fract * rval);
1286 pgval = (l_int32)((1. - fract) * pgval + fract * gval);
1287 pbval = (l_int32)((1. - fract) * pbval + fract * bval);
1288 composeRGBPixel(prval, pgval, pbval, &val32);
1289 *(lines + j) = val32;
1290 }
1291 }
1292 return 0;
1293 }
1294
1295 boxGetGeometry(box, &bx, &by, &bw, &bh);
1296 for (i = 0; i < bh; i++) { /* scan over box */
1297 if (by + i < 0 || by + i >= h) continue;
1298 lines = datas + (by + i) * wpls;
1299 for (j = 0; j < bw; j++) {
1300 if (bx + j < 0 || bx + j >= w) continue;
1301 val32 = *(lines + bx + j);
1302 extractRGBValues(val32, &prval, &pgval, &pbval);
1303 prval = (l_int32)((1. - fract) * prval + fract * rval);
1304 pgval = (l_int32)((1. - fract) * pgval + fract * gval);
1305 pbval = (l_int32)((1. - fract) * pbval + fract * bval);
1306 composeRGBPixel(prval, pgval, pbval, &val32);
1307 *(lines + bx + j) = val32;
1308 }
1309 }
1310 return 0;
1311}
1312
1313
1314/*-------------------------------------------------------------*
1315 * Set pad bits *
1316 *-------------------------------------------------------------*/
1348l_ok
1350 l_int32 val)
1351{
1352l_int32 i, w, h, d, wpl, endbits, fullwords;
1353l_uint32 mask;
1354l_uint32 *data, *pword;
1355
1356 if (!pix)
1357 return ERROR_INT("pix not defined", __func__, 1);
1358
1359 pixGetDimensions(pix, &w, &h, &d);
1360 if (d == 32) /* no padding exists for 32 bpp */
1361 return 0;
1362 if (d == 24) { /* pixels not aligned with 32-bit words */
1363 L_INFO("pix is 24 bpp\n", __func__);
1364 return 1;
1365 }
1366
1367 data = pixGetData(pix);
1368 wpl = pixGetWpl(pix);
1369 endbits = 32 - (((l_int64)w * d) % 32);
1370 if (endbits == 32) /* no partial word */
1371 return 0;
1372 fullwords = (1LL * w * d) / 32;
1373 mask = rmask32[endbits];
1374 if (val == 0)
1375 mask = ~mask;
1376
1377 for (i = 0; i < h; i++) {
1378 pword = data + i * wpl + fullwords;
1379 if (val == 0) /* clear */
1380 *pword = *pword & mask;
1381 else /* set */
1382 *pword = *pword | mask;
1383 }
1384
1385 return 0;
1386}
1387
1388
1411l_ok
1413 l_int32 by,
1414 l_int32 bh,
1415 l_int32 val)
1416{
1417l_int32 i, w, h, d, wpl, endbits, fullwords;
1418l_uint32 mask;
1419l_uint32 *data, *pword;
1420
1421 if (!pix)
1422 return ERROR_INT("pix not defined", __func__, 1);
1423
1424 pixGetDimensions(pix, &w, &h, &d);
1425 if (d == 32) /* no padding exists for 32 bpp */
1426 return 0;
1427 if (d == 24) { /* pixels not aligned with 32-bit words */
1428 L_INFO("pix is 24 bpp\n", __func__);
1429 return 1;
1430 }
1431
1432 if (by < 0)
1433 by = 0;
1434 if (by >= h)
1435 return ERROR_INT("start y not in image", __func__, 1);
1436 if (by + bh > h)
1437 bh = h - by;
1438
1439 data = pixGetData(pix);
1440 wpl = pixGetWpl(pix);
1441 endbits = 32 - (((l_int64)w * d) % 32);
1442 if (endbits == 32) /* no partial word */
1443 return 0;
1444 fullwords = (l_int64)w * d / 32;
1445
1446 mask = rmask32[endbits];
1447 if (val == 0)
1448 mask = ~mask;
1449
1450 for (i = by; i < by + bh; i++) {
1451 pword = data + i * wpl + fullwords;
1452 if (val == 0) /* clear */
1453 *pword = *pword & mask;
1454 else /* set */
1455 *pword = *pword | mask;
1456 }
1457
1458 return 0;
1459}
1460
1461
1462/*-------------------------------------------------------------*
1463 * Set border pixels *
1464 *-------------------------------------------------------------*/
1485l_ok
1487 l_int32 left,
1488 l_int32 right,
1489 l_int32 top,
1490 l_int32 bot,
1491 l_int32 op)
1492{
1493l_int32 w, h;
1494
1495 if (!pixs)
1496 return ERROR_INT("pixs not defined", __func__, 1);
1497 if (op != PIX_SET && op != PIX_CLR)
1498 return ERROR_INT("op must be PIX_SET or PIX_CLR", __func__, 1);
1499
1500 pixGetDimensions(pixs, &w, &h, NULL);
1501 pixRasterop(pixs, 0, 0, left, h, op, NULL, 0, 0);
1502 pixRasterop(pixs, w - right, 0, right, h, op, NULL, 0, 0);
1503 pixRasterop(pixs, 0, 0, w, top, op, NULL, 0, 0);
1504 pixRasterop(pixs, 0, h - bot, w, bot, op, NULL, 0, 0);
1505
1506 return 0;
1507}
1508
1509
1532l_ok
1534 l_int32 left,
1535 l_int32 right,
1536 l_int32 top,
1537 l_int32 bot,
1538 l_uint32 val)
1539{
1540l_int32 w, h, d, wpls, i, j, bstart, rstart;
1541l_uint32 *datas, *lines;
1542
1543 if (!pixs)
1544 return ERROR_INT("pixs not defined", __func__, 1);
1545 pixGetDimensions(pixs, &w, &h, &d);
1546 if (d != 8 && d != 16 && d != 32)
1547 return ERROR_INT("depth must be 8, 16 or 32 bpp", __func__, 1);
1548
1549 datas = pixGetData(pixs);
1550 wpls = pixGetWpl(pixs);
1551 if (d == 8) {
1552 val &= 0xff;
1553 for (i = 0; i < top; i++) {
1554 lines = datas + i * wpls;
1555 for (j = 0; j < w; j++)
1556 SET_DATA_BYTE(lines, j, val);
1557 }
1558 rstart = w - right;
1559 bstart = h - bot;
1560 for (i = top; i < bstart; i++) {
1561 lines = datas + i * wpls;
1562 for (j = 0; j < left; j++)
1563 SET_DATA_BYTE(lines, j, val);
1564 for (j = rstart; j < w; j++)
1565 SET_DATA_BYTE(lines, j, val);
1566 }
1567 for (i = bstart; i < h; i++) {
1568 lines = datas + i * wpls;
1569 for (j = 0; j < w; j++)
1570 SET_DATA_BYTE(lines, j, val);
1571 }
1572 } else if (d == 16) {
1573 val &= 0xffff;
1574 for (i = 0; i < top; i++) {
1575 lines = datas + i * wpls;
1576 for (j = 0; j < w; j++)
1577 SET_DATA_TWO_BYTES(lines, j, val);
1578 }
1579 rstart = w - right;
1580 bstart = h - bot;
1581 for (i = top; i < bstart; i++) {
1582 lines = datas + i * wpls;
1583 for (j = 0; j < left; j++)
1584 SET_DATA_TWO_BYTES(lines, j, val);
1585 for (j = rstart; j < w; j++)
1586 SET_DATA_TWO_BYTES(lines, j, val);
1587 }
1588 for (i = bstart; i < h; i++) {
1589 lines = datas + i * wpls;
1590 for (j = 0; j < w; j++)
1591 SET_DATA_TWO_BYTES(lines, j, val);
1592 }
1593 } else { /* d == 32 */
1594 for (i = 0; i < top; i++) {
1595 lines = datas + i * wpls;
1596 for (j = 0; j < w; j++)
1597 *(lines + j) = val;
1598 }
1599 rstart = w - right;
1600 bstart = h - bot;
1601 for (i = top; i < bstart; i++) {
1602 lines = datas + i * wpls;
1603 for (j = 0; j < left; j++)
1604 *(lines + j) = val;
1605 for (j = rstart; j < w; j++)
1606 *(lines + j) = val;
1607 }
1608 for (i = bstart; i < h; i++) {
1609 lines = datas + i * wpls;
1610 for (j = 0; j < w; j++)
1611 *(lines + j) = val;
1612 }
1613 }
1614
1615 return 0;
1616}
1617
1618
1634l_ok
1636 l_int32 dist,
1637 l_uint32 val)
1638{
1639l_int32 w, h, d, i, j, xend, yend;
1640
1641 if (!pixs)
1642 return ERROR_INT("pixs not defined", __func__, 1);
1643 if (dist < 1)
1644 return ERROR_INT("dist must be > 0", __func__, 1);
1645 pixGetDimensions(pixs, &w, &h, &d);
1646 if (w < 2 * dist + 1 || h < 2 * dist + 1)
1647 return ERROR_INT("ring doesn't exist", __func__, 1);
1648 if (d < 32 && (val >= (1 << d)))
1649 return ERROR_INT("invalid pixel value", __func__, 1);
1650
1651 xend = w - dist;
1652 yend = h - dist;
1653 for (j = dist - 1; j <= xend; j++)
1654 pixSetPixel(pixs, j, dist - 1, val);
1655 for (j = dist - 1; j <= xend; j++)
1656 pixSetPixel(pixs, j, yend, val);
1657 for (i = dist - 1; i <= yend; i++)
1658 pixSetPixel(pixs, dist - 1, i, val);
1659 for (i = dist - 1; i <= yend; i++)
1660 pixSetPixel(pixs, xend, i, val);
1661
1662 return 0;
1663}
1664
1665
1683l_ok
1685 l_int32 left,
1686 l_int32 right,
1687 l_int32 top,
1688 l_int32 bot)
1689{
1690l_int32 i, j, w, h;
1691
1692 if (!pixs)
1693 return ERROR_INT("pixs not defined", __func__, 1);
1694
1695 pixGetDimensions(pixs, &w, &h, NULL);
1696 for (j = 0; j < left; j++)
1697 pixRasterop(pixs, left - 1 - j, top, 1, h - top - bot, PIX_SRC,
1698 pixs, left + j, top);
1699 for (j = 0; j < right; j++)
1700 pixRasterop(pixs, w - right + j, top, 1, h - top - bot, PIX_SRC,
1701 pixs, w - right - 1 - j, top);
1702 for (i = 0; i < top; i++)
1703 pixRasterop(pixs, 0, top - 1 - i, w, 1, PIX_SRC,
1704 pixs, 0, top + i);
1705 for (i = 0; i < bot; i++)
1706 pixRasterop(pixs, 0, h - bot + i, w, 1, PIX_SRC,
1707 pixs, 0, h - bot - 1 - i);
1708
1709 return 0;
1710}
1711
1712
1732PIX *
1734 PIX *pixs,
1735 l_int32 left,
1736 l_int32 right,
1737 l_int32 top,
1738 l_int32 bot)
1739{
1740l_int32 w, h;
1741
1742 if (!pixs)
1743 return (PIX *)ERROR_PTR("pixs not defined", __func__, pixd);
1744
1745 if (pixd) {
1746 if (pixd == pixs) {
1747 L_WARNING("same: nothing to do\n", __func__);
1748 return pixd;
1749 } else if (!pixSizesEqual(pixs, pixd)) {
1750 return (PIX *)ERROR_PTR("pixs and pixd sizes differ",
1751 __func__, pixd);
1752 }
1753 } else {
1754 if ((pixd = pixCreateTemplate(pixs)) == NULL)
1755 return (PIX *)ERROR_PTR("pixd not made", __func__, pixd);
1756 }
1757
1758 pixGetDimensions(pixs, &w, &h, NULL);
1759 pixRasterop(pixd, 0, 0, left, h, PIX_SRC, pixs, 0, 0);
1760 pixRasterop(pixd, w - right, 0, right, h, PIX_SRC, pixs, w - right, 0);
1761 pixRasterop(pixd, 0, 0, w, top, PIX_SRC, pixs, 0, 0);
1762 pixRasterop(pixd, 0, h - bot, w, bot, PIX_SRC, pixs, 0, h - bot);
1763 return pixd;
1764}
1765
1766
1767
1768/*-------------------------------------------------------------*
1769 * Add and remove border *
1770 *-------------------------------------------------------------*/
1784PIX *
1786 l_int32 npix,
1787 l_uint32 val)
1788{
1789 if (!pixs)
1790 return (PIX *)ERROR_PTR("pixs not defined", __func__, NULL);
1791 if (npix == 0)
1792 return pixClone(pixs);
1793 return pixAddBorderGeneral(pixs, npix, npix, npix, npix, val);
1794}
1795
1796
1822PIX *
1824 l_int32 left,
1825 l_int32 right,
1826 l_int32 top,
1827 l_int32 bot,
1828 l_int32 op)
1829{
1830l_uint32 val;
1831
1832 if (!pixs)
1833 return (PIX *)ERROR_PTR("pixs not defined", __func__, NULL);
1834 if (op != L_GET_BLACK_VAL && op != L_GET_WHITE_VAL)
1835 return (PIX *)ERROR_PTR("invalid op", __func__, NULL);
1836
1837 pixGetBlackOrWhiteVal(pixs, op, &val);
1838 return pixAddBorderGeneral(pixs, left, right, top, bot, val);
1839}
1840
1841
1874PIX *
1876 l_int32 left,
1877 l_int32 right,
1878 l_int32 top,
1879 l_int32 bot,
1880 l_uint32 val)
1881{
1882l_int32 ws, hs, wd, hd, d, maxval, op;
1883PIX *pixd;
1884
1885 if (!pixs)
1886 return (PIX *)ERROR_PTR("pixs not defined", __func__, NULL);
1887 if (left < 0 || right < 0 || top < 0 || bot < 0)
1888 return (PIX *)ERROR_PTR("negative border added!", __func__, NULL);
1889
1890 pixGetDimensions(pixs, &ws, &hs, &d);
1891 wd = ws + left + right;
1892 hd = hs + top + bot;
1893 if ((pixd = pixCreate(wd, hd, d)) == NULL)
1894 return (PIX *)ERROR_PTR("pixd not made", __func__, NULL);
1895 pixCopyResolution(pixd, pixs);
1896 pixCopyColormap(pixd, pixs);
1897
1898 /* Set the new border pixels */
1899 maxval = (d == 32) ? 0xffffff00 : (1 << d) - 1;
1900 op = UNDEF;
1901 if (val == 0)
1902 op = PIX_CLR;
1903 else if (val >= maxval)
1904 op = PIX_SET;
1905 if (op == UNDEF) {
1906 pixSetAllArbitrary(pixd, val);
1907 } else { /* just set or clear the border pixels */
1908 pixRasterop(pixd, 0, 0, left, hd, op, NULL, 0, 0);
1909 pixRasterop(pixd, wd - right, 0, right, hd, op, NULL, 0, 0);
1910 pixRasterop(pixd, 0, 0, wd, top, op, NULL, 0, 0);
1911 pixRasterop(pixd, 0, hd - bot, wd, bot, op, NULL, 0, 0);
1912 }
1913
1914 /* Copy pixs into the interior */
1915 pixRasterop(pixd, left, top, ws, hs, PIX_SRC, pixs, 0, 0);
1916 return pixd;
1917}
1918
1919
1942PIX *
1944 l_int32 nblack1,
1945 l_int32 nwhite1,
1946 l_int32 nblack2,
1947 l_int32 nwhite2,
1948 l_int32 nblack3,
1949 l_int32 nwhite3)
1950{
1951l_int32 i, color;
1952l_int32 w[6];
1953PIX *pix1, *pixd;
1954
1955 if (!pixs)
1956 return (PIX *)ERROR_PTR("pixs not defined", __func__, NULL);
1957
1958 w[0] = nblack1;
1959 w[1] = nwhite1;
1960 w[2] = nblack2;
1961 w[3] = nwhite2;
1962 w[4] = nblack3;
1963 w[5] = nwhite3;
1964 pixd = pixClone(pixs);
1965 for (i = 0; i < 6; i++) {
1966 if (w[i] > 500)
1967 L_WARNING("w = %d > 500; skipping\n", __func__, w[i]);
1968 if (w[i] > 0 && w[i] <= 500) {
1969 color = (i % 2 == 0) ? L_GET_BLACK_VAL : L_GET_WHITE_VAL;
1970 pix1 = pixAddBlackOrWhiteBorder(pixd, w[i], w[i], w[i], w[i],
1971 color);
1972 pixDestroy(&pixd);
1973 pixd = pix1;
1974 }
1975 }
1976
1977 return pixd;
1978}
1979
1980
1988PIX *
1990 l_int32 npix)
1991{
1992 if (!pixs)
1993 return (PIX *)ERROR_PTR("pixs not defined", __func__, NULL);
1994 if (npix == 0)
1995 return pixClone(pixs);
1996 return pixRemoveBorderGeneral(pixs, npix, npix, npix, npix);
1997}
1998
1999
2007PIX *
2009 l_int32 left,
2010 l_int32 right,
2011 l_int32 top,
2012 l_int32 bot)
2013{
2014l_int32 ws, hs, wd, hd, d;
2015PIX *pixd;
2016
2017 if (!pixs)
2018 return (PIX *)ERROR_PTR("pixs not defined", __func__, NULL);
2019 if (left < 0 || right < 0 || top < 0 || bot < 0)
2020 return (PIX *)ERROR_PTR("negative border removed!", __func__, NULL);
2021
2022 pixGetDimensions(pixs, &ws, &hs, &d);
2023 wd = ws - left - right;
2024 hd = hs - top - bot;
2025 if (wd <= 0)
2026 return (PIX *)ERROR_PTR("width must be > 0", __func__, NULL);
2027 if (hd <= 0)
2028 return (PIX *)ERROR_PTR("height must be > 0", __func__, NULL);
2029 if ((pixd = pixCreate(wd, hd, d)) == NULL)
2030 return (PIX *)ERROR_PTR("pixd not made", __func__, NULL);
2031 pixCopyResolution(pixd, pixs);
2032 pixCopySpp(pixd, pixs);
2033 pixCopyColormap(pixd, pixs);
2034
2035 pixRasterop(pixd, 0, 0, wd, hd, PIX_SRC, pixs, left, top);
2036 if (pixGetDepth(pixs) == 32 && pixGetSpp(pixs) == 4)
2037 pixShiftAndTransferAlpha(pixd, pixs, -left, -top);
2038 return pixd;
2039}
2040
2041
2058PIX *
2060 l_int32 wd,
2061 l_int32 hd)
2062{
2063l_int32 w, h, top, bot, left, right, delta;
2064
2065 if (!pixs)
2066 return (PIX *)ERROR_PTR("pixs not defined", __func__, NULL);
2067
2068 pixGetDimensions(pixs, &w, &h, NULL);
2069 if ((wd <= 0 || wd >= w) && (hd <= 0 || hd >= h))
2070 return pixClone(pixs);
2071
2072 left = right = (w - wd) / 2;
2073 delta = w - 2 * left - wd;
2074 right += delta;
2075 top = bot = (h - hd) / 2;
2076 delta = h - hd - 2 * top;
2077 bot += delta;
2078 if (wd <= 0 || wd > w)
2079 left = right = 0;
2080 else if (hd <= 0 || hd > h)
2081 top = bot = 0;
2082
2083 return pixRemoveBorderGeneral(pixs, left, right, top, bot);
2084}
2085
2086
2111PIX *
2113 l_int32 left,
2114 l_int32 right,
2115 l_int32 top,
2116 l_int32 bot)
2117{
2118l_int32 i, j, w, h;
2119PIX *pixd;
2120
2121 if (!pixs)
2122 return (PIX *)ERROR_PTR("pixs not defined", __func__, NULL);
2123 pixGetDimensions(pixs, &w, &h, NULL);
2124 if (left > w || right > w || top > h || bot > h)
2125 return (PIX *)ERROR_PTR("border too large", __func__, NULL);
2126
2127 /* Set pixels on left, right, top and bottom, in that order */
2128 pixd = pixAddBorderGeneral(pixs, left, right, top, bot, 0);
2129 for (j = 0; j < left; j++)
2130 pixRasterop(pixd, left - 1 - j, top, 1, h, PIX_SRC,
2131 pixd, left + j, top);
2132 for (j = 0; j < right; j++)
2133 pixRasterop(pixd, left + w + j, top, 1, h, PIX_SRC,
2134 pixd, left + w - 1 - j, top);
2135 for (i = 0; i < top; i++)
2136 pixRasterop(pixd, 0, top - 1 - i, left + w + right, 1, PIX_SRC,
2137 pixd, 0, top + i);
2138 for (i = 0; i < bot; i++)
2139 pixRasterop(pixd, 0, top + h + i, left + w + right, 1, PIX_SRC,
2140 pixd, 0, top + h - 1 - i);
2141
2142 return pixd;
2143}
2144
2145
2162PIX *
2164 l_int32 left,
2165 l_int32 right,
2166 l_int32 top,
2167 l_int32 bot)
2168{
2169l_int32 w, h;
2170PIX *pixd;
2171
2172 if (!pixs)
2173 return (PIX *)ERROR_PTR("pixs not defined", __func__, NULL);
2174 pixGetDimensions(pixs, &w, &h, NULL);
2175 if (left > w || right > w || top > h || bot > h)
2176 return (PIX *)ERROR_PTR("border too large", __func__, NULL);
2177
2178 pixd = pixAddBorderGeneral(pixs, left, right, top, bot, 0);
2179
2180 /* Set pixels on left, right, top and bottom, in that order */
2181 pixRasterop(pixd, 0, top, left, h, PIX_SRC, pixd, w, top);
2182 pixRasterop(pixd, left + w, top, right, h, PIX_SRC, pixd, left, top);
2183 pixRasterop(pixd, 0, 0, left + w + right, top, PIX_SRC, pixd, 0, h);
2184 pixRasterop(pixd, 0, top + h, left + w + right, bot, PIX_SRC, pixd, 0, top);
2185
2186 return pixd;
2187}
2188
2189
2216PIX *
2218 l_int32 left,
2219 l_int32 right,
2220 l_int32 top,
2221 l_int32 bot)
2222{
2223l_int32 j, w, h;
2224PIX *pixd;
2225
2226 if (!pixs)
2227 return (PIX *)ERROR_PTR("pixs not defined", __func__, NULL);
2228 pixGetDimensions(pixs, &w, &h, NULL);
2229 if (left > w || right > w || top > h || bot > h)
2230 return (PIX *)ERROR_PTR("border too large", __func__, NULL);
2231
2232 /* Set mirrored pixels on left and right;
2233 * then set repeated pixels on top and bottom. */
2234 pixd = pixAddBorderGeneral(pixs, left, right, top, bot, 0);
2235 for (j = 0; j < left; j++)
2236 pixRasterop(pixd, left - 1 - j, top, 1, h, PIX_SRC,
2237 pixd, left + j, top);
2238 for (j = 0; j < right; j++)
2239 pixRasterop(pixd, left + w + j, top, 1, h, PIX_SRC,
2240 pixd, left + w - 1 - j, top);
2241 pixRasterop(pixd, 0, 0, left + w + right, top, PIX_SRC, pixd, 0, h);
2242 pixRasterop(pixd, 0, top + h, left + w + right, bot, PIX_SRC, pixd, 0, top);
2243
2244 return pixd;
2245}
2246
2247
2261PIX *
2263 l_int32 left,
2264 l_int32 right,
2265 l_int32 top,
2266 l_int32 bot)
2267{
2268l_int32 i, j, w, h;
2269PIX *pixd;
2270
2271 if (!pixs)
2272 return (PIX *)ERROR_PTR("pixs not defined", __func__, NULL);
2273
2274 pixd = pixAddBorderGeneral(pixs, left, right, top, bot, 0);
2275 pixGetDimensions(pixs, &w, &h, NULL);
2276 for (j = 0; j < left; j++)
2277 pixRasterop(pixd, j, top, 1, h, PIX_SRC, pixd, left, top);
2278 for (j = 0; j < right; j++)
2279 pixRasterop(pixd, left + w + j, top, 1, h,
2280 PIX_SRC, pixd, left + w - 1, top);
2281 for (i = 0; i < top; i++)
2282 pixRasterop(pixd, 0, i, left + w + right, 1, PIX_SRC, pixd, 0, top);
2283 for (i = 0; i < bot; i++)
2284 pixRasterop(pixd, 0, top + h + i, left + w + right, 1,
2285 PIX_SRC, pixd, 0, top + h - 1);
2286
2287 return pixd;
2288}
2289
2290
2291/*-------------------------------------------------------------------*
2292 * Helper functions using alpha *
2293 *-------------------------------------------------------------------*/
2302l_ok
2304 PIX *pixs,
2305 l_float32 shiftx,
2306 l_float32 shifty)
2307{
2308l_int32 w, h;
2309PIX *pix1, *pix2;
2310
2311 if (!pixs || !pixd)
2312 return ERROR_INT("pixs and pixd not both defined", __func__, 1);
2313 if (pixGetDepth(pixs) != 32 || pixGetSpp(pixs) != 4)
2314 return ERROR_INT("pixs not 32 bpp and 4 spp", __func__, 1);
2315 if (pixGetDepth(pixd) != 32)
2316 return ERROR_INT("pixd not 32 bpp", __func__, 1);
2317
2318 if (shiftx == 0 && shifty == 0) {
2320 return 0;
2321 }
2322
2323 pix1 = pixGetRGBComponent(pixs, L_ALPHA_CHANNEL);
2324 pixGetDimensions(pixd, &w, &h, NULL);
2325 pix2 = pixCreate(w, h, 8);
2326 pixRasterop(pix2, 0, 0, w, h, PIX_SRC, pix1, -shiftx, -shifty);
2328 pixDestroy(&pix1);
2329 pixDestroy(&pix2);
2330 return 0;
2331}
2332
2333
2351PIX *
2353 l_uint32 val,
2354 l_int32 maxw)
2355{
2356l_int32 w, width;
2357l_float32 scalefact;
2358PIX *pix1, *pix2, *pixd;
2359PIXA *pixa;
2360PIXCMAP *cmap;
2361
2362 if (!pixs)
2363 return (PIX *)ERROR_PTR("pixs not defined", __func__, NULL);
2364 cmap = pixGetColormap(pixs);
2365 if (!cmap && !(pixGetDepth(pixs) == 32 && pixGetSpp(pixs) == 4))
2366 return (PIX *)ERROR_PTR("pixs not cmap and not 32 bpp rgba",
2367 __func__, NULL);
2368 if ((w = pixGetWidth(pixs)) == 0)
2369 return (PIX *)ERROR_PTR("pixs width 0 !!", __func__, NULL);
2370
2371 if (cmap)
2372 pix1 = pixRemoveColormap(pixs, REMOVE_CMAP_WITH_ALPHA);
2373 else
2374 pix1 = pixCopy(NULL, pixs);
2375
2376 /* Scale if necessary so the output width is not larger than maxw */
2377 scalefact = (maxw == 0) ? 1.0f : L_MIN(1.0f, (l_float32)(maxw) / w);
2378 width = (l_int32)(scalefact * w);
2379
2380 pixa = pixaCreate(3);
2381 pixSetSpp(pix1, 3);
2382 pixaAddPix(pixa, pix1, L_INSERT); /* show the rgb values */
2383 pix1 = pixGetRGBComponent(pixs, L_ALPHA_CHANNEL);
2384 pix2 = pixConvertTo32(pix1);
2385 pixaAddPix(pixa, pix2, L_INSERT); /* show the alpha channel */
2386 pixDestroy(&pix1);
2387 pix1 = pixAlphaBlendUniform(pixs, (val & 0xffffff00));
2388 pixaAddPix(pixa, pix1, L_INSERT); /* with %val color bg showing */
2389 pixd = pixaDisplayTiledInRows(pixa, 32, width, scalefact, 0, 25, 2);
2390 pixaDestroy(&pixa);
2391 return pixd;
2392}
2393
2394
2395/*-------------------------------------------------------------*
2396 * Color sample setting and extraction *
2397 *-------------------------------------------------------------*/
2421PIX *
2423 PIX *pixg,
2424 PIX *pixb)
2425{
2426l_int32 wr, wg, wb, hr, hg, hb, dr, dg, db;
2427PIX *pixd;
2428
2429 if (!pixr)
2430 return (PIX *)ERROR_PTR("pixr not defined", __func__, NULL);
2431 if (!pixg)
2432 return (PIX *)ERROR_PTR("pixg not defined", __func__, NULL);
2433 if (!pixb)
2434 return (PIX *)ERROR_PTR("pixb not defined", __func__, NULL);
2435 pixGetDimensions(pixr, &wr, &hr, &dr);
2436 pixGetDimensions(pixg, &wg, &hg, &dg);
2437 pixGetDimensions(pixb, &wb, &hb, &db);
2438 if (dr != 8 || dg != 8 || db != 8)
2439 return (PIX *)ERROR_PTR("input pix not all 8 bpp", __func__, NULL);
2440 if (wr != wg || wr != wb)
2441 return (PIX *)ERROR_PTR("widths not the same", __func__, NULL);
2442 if (hr != hg || hr != hb)
2443 return (PIX *)ERROR_PTR("heights not the same", __func__, NULL);
2444
2445 if ((pixd = pixCreate(wr, hr, 32)) == NULL)
2446 return (PIX *)ERROR_PTR("pixd not made", __func__, NULL);
2447 pixCopyResolution(pixd, pixr);
2448 pixSetRGBComponent(pixd, pixr, COLOR_RED);
2449 pixSetRGBComponent(pixd, pixg, COLOR_GREEN);
2450 pixSetRGBComponent(pixd, pixb, COLOR_BLUE);
2451
2452 return pixd;
2453}
2454
2455
2475PIX *
2477 l_int32 comp)
2478{
2479l_int32 i, j, w, h, wpls, wpld, val;
2480l_uint32 *lines, *lined;
2481l_uint32 *datas, *datad;
2482PIX *pixd;
2483
2484 if (!pixs)
2485 return (PIX *)ERROR_PTR("pixs not defined", __func__, NULL);
2486 if (pixGetColormap(pixs))
2487 return pixGetRGBComponentCmap(pixs, comp);
2488 if (pixGetDepth(pixs) != 32)
2489 return (PIX *)ERROR_PTR("pixs not 32 bpp", __func__, NULL);
2490 if (comp != COLOR_RED && comp != COLOR_GREEN &&
2491 comp != COLOR_BLUE && comp != L_ALPHA_CHANNEL)
2492 return (PIX *)ERROR_PTR("invalid comp", __func__, NULL);
2493
2494 pixGetDimensions(pixs, &w, &h, NULL);
2495 if ((pixd = pixCreate(w, h, 8)) == NULL)
2496 return (PIX *)ERROR_PTR("pixd not made", __func__, NULL);
2497 pixCopyResolution(pixd, pixs);
2498 wpls = pixGetWpl(pixs);
2499 wpld = pixGetWpl(pixd);
2500 datas = pixGetData(pixs);
2501 datad = pixGetData(pixd);
2502 for (i = 0; i < h; i++) {
2503 lines = datas + i * wpls;
2504 lined = datad + i * wpld;
2505 for (j = 0; j < w; j++) {
2506 val = GET_DATA_BYTE(lines + j, comp);
2507 SET_DATA_BYTE(lined, j, val);
2508 }
2509 }
2510
2511 return pixd;
2512}
2513
2514
2532l_ok
2534 PIX *pixs,
2535 l_int32 comp)
2536{
2537l_uint8 srcbyte;
2538l_int32 i, j, w, h, ws, hs, wd, hd;
2539l_int32 wpls, wpld;
2540l_uint32 *lines, *lined;
2541l_uint32 *datas, *datad;
2542
2543 if (!pixd)
2544 return ERROR_INT("pixd not defined", __func__, 1);
2545 if (!pixs)
2546 return ERROR_INT("pixs not defined", __func__, 1);
2547 if (pixGetDepth(pixd) != 32)
2548 return ERROR_INT("pixd not 32 bpp", __func__, 1);
2549 if (pixGetDepth(pixs) != 8)
2550 return ERROR_INT("pixs not 8 bpp", __func__, 1);
2551 if (comp != COLOR_RED && comp != COLOR_GREEN &&
2552 comp != COLOR_BLUE && comp != L_ALPHA_CHANNEL)
2553 return ERROR_INT("invalid comp", __func__, 1);
2554 pixGetDimensions(pixs, &ws, &hs, NULL);
2555 pixGetDimensions(pixd, &wd, &hd, NULL);
2556 if (ws != wd || hs != hd)
2557 L_WARNING("images sizes not equal\n", __func__);
2558 w = L_MIN(ws, wd);
2559 h = L_MIN(hs, hd);
2560 if (comp == L_ALPHA_CHANNEL)
2561 pixSetSpp(pixd, 4);
2562 datas = pixGetData(pixs);
2563 datad = pixGetData(pixd);
2564 wpls = pixGetWpl(pixs);
2565 wpld = pixGetWpl(pixd);
2566 for (i = 0; i < h; i++) {
2567 lines = datas + i * wpls;
2568 lined = datad + i * wpld;
2569 for (j = 0; j < w; j++) {
2570 srcbyte = GET_DATA_BYTE(lines, j);
2571 SET_DATA_BYTE(lined + j, comp, srcbyte);
2572 }
2573 }
2574
2575 return 0;
2576}
2577
2578
2592PIX *
2594 l_int32 comp)
2595{
2596l_int32 i, j, w, h, val, index, valid;
2597l_int32 wplc, wpld;
2598l_uint32 *linec, *lined;
2599l_uint32 *datac, *datad;
2600PIX *pixc, *pixd;
2601PIXCMAP *cmap;
2602RGBA_QUAD *cta;
2603
2604 if (!pixs)
2605 return (PIX *)ERROR_PTR("pixs not defined", __func__, NULL);
2606 if ((cmap = pixGetColormap(pixs)) == NULL)
2607 return (PIX *)ERROR_PTR("pixs not cmapped", __func__, NULL);
2608 if (comp == L_ALPHA_CHANNEL)
2609 return (PIX *)ERROR_PTR("alpha in cmaps not supported", __func__, NULL);
2610 if (comp != COLOR_RED && comp != COLOR_GREEN && comp != COLOR_BLUE)
2611 return (PIX *)ERROR_PTR("invalid comp", __func__, NULL);
2612
2613 /* If not 8 bpp, make a cmapped 8 bpp pix */
2614 if (pixGetDepth(pixs) == 8)
2615 pixc = pixClone(pixs);
2616 else
2617 pixc = pixConvertTo8(pixs, TRUE);
2618 pixcmapIsValid(cmap, pixc, &valid);
2619 if (!valid) {
2620 pixDestroy(&pixc);
2621 return (PIX *)ERROR_PTR("invalid colormap", __func__, NULL);
2622 }
2623
2624 pixGetDimensions(pixs, &w, &h, NULL);
2625 if ((pixd = pixCreate(w, h, 8)) == NULL) {
2626 pixDestroy(&pixc);
2627 return (PIX *)ERROR_PTR("pixd not made", __func__, NULL);
2628 }
2629 pixCopyResolution(pixd, pixs);
2630 wplc = pixGetWpl(pixc);
2631 wpld = pixGetWpl(pixd);
2632 datac = pixGetData(pixc);
2633 datad = pixGetData(pixd);
2634 cta = (RGBA_QUAD *)cmap->array;
2635
2636 for (i = 0; i < h; i++) {
2637 linec = datac + i * wplc;
2638 lined = datad + i * wpld;
2639 if (comp == COLOR_RED) {
2640 for (j = 0; j < w; j++) {
2641 index = GET_DATA_BYTE(linec, j);
2642 val = cta[index].red;
2643 SET_DATA_BYTE(lined, j, val);
2644 }
2645 } else if (comp == COLOR_GREEN) {
2646 for (j = 0; j < w; j++) {
2647 index = GET_DATA_BYTE(linec, j);
2648 val = cta[index].green;
2649 SET_DATA_BYTE(lined, j, val);
2650 }
2651 } else if (comp == COLOR_BLUE) {
2652 for (j = 0; j < w; j++) {
2653 index = GET_DATA_BYTE(linec, j);
2654 val = cta[index].blue;
2655 SET_DATA_BYTE(lined, j, val);
2656 }
2657 }
2658 }
2659
2660 pixDestroy(&pixc);
2661 return pixd;
2662}
2663
2664
2680l_ok
2682 PIX *pixs,
2683 l_int32 comp)
2684{
2685l_int32 i, j, w, h, ws, hs, wd, hd, val;
2686l_int32 wpls, wpld;
2687l_uint32 *lines, *lined;
2688l_uint32 *datas, *datad;
2689
2690 if (!pixd && pixGetDepth(pixd) != 32)
2691 return ERROR_INT("pixd not defined or not 32 bpp", __func__, 1);
2692 if (!pixs && pixGetDepth(pixs) != 32)
2693 return ERROR_INT("pixs not defined or not 32 bpp", __func__, 1);
2694 if (comp != COLOR_RED && comp != COLOR_GREEN &&
2695 comp != COLOR_BLUE && comp != L_ALPHA_CHANNEL)
2696 return ERROR_INT("invalid component", __func__, 1);
2697 pixGetDimensions(pixs, &ws, &hs, NULL);
2698 pixGetDimensions(pixd, &wd, &hd, NULL);
2699 if (ws != wd || hs != hd)
2700 L_WARNING("images sizes not equal\n", __func__);
2701 w = L_MIN(ws, wd);
2702 h = L_MIN(hs, hd);
2703 if (comp == L_ALPHA_CHANNEL)
2704 pixSetSpp(pixd, 4);
2705 wpls = pixGetWpl(pixs);
2706 wpld = pixGetWpl(pixd);
2707 datas = pixGetData(pixs);
2708 datad = pixGetData(pixd);
2709 for (i = 0; i < h; i++) {
2710 lines = datas + i * wpls;
2711 lined = datad + i * wpld;
2712 for (j = 0; j < w; j++) {
2713 val = GET_DATA_BYTE(lines + j, comp);
2714 SET_DATA_BYTE(lined + j, comp, val);
2715 }
2716 }
2717 return 0;
2718}
2719
2720
2739l_ok
2740composeRGBPixel(l_int32 rval,
2741 l_int32 gval,
2742 l_int32 bval,
2743 l_uint32 *ppixel)
2744{
2745 if (!ppixel)
2746 return ERROR_INT("&pixel not defined", __func__, 1);
2747
2748 *ppixel = ((l_uint32)rval << L_RED_SHIFT) |
2749 ((l_uint32)gval << L_GREEN_SHIFT) |
2750 ((l_uint32)bval << L_BLUE_SHIFT);
2751 return 0;
2752}
2753
2754
2769l_ok
2770composeRGBAPixel(l_int32 rval,
2771 l_int32 gval,
2772 l_int32 bval,
2773 l_int32 aval,
2774 l_uint32 *ppixel)
2775{
2776 if (!ppixel)
2777 return ERROR_INT("&pixel not defined", __func__, 1);
2778
2779 *ppixel = ((l_uint32)rval << L_RED_SHIFT) |
2780 ((l_uint32)gval << L_GREEN_SHIFT) |
2781 ((l_uint32)bval << L_BLUE_SHIFT) |
2782 aval;
2783 return 0;
2784}
2785
2786
2804void
2805extractRGBValues(l_uint32 pixel,
2806 l_int32 *prval,
2807 l_int32 *pgval,
2808 l_int32 *pbval)
2809{
2810 if (prval) *prval = (pixel >> L_RED_SHIFT) & 0xff;
2811 if (pgval) *pgval = (pixel >> L_GREEN_SHIFT) & 0xff;
2812 if (pbval) *pbval = (pixel >> L_BLUE_SHIFT) & 0xff;
2813}
2814
2815
2826void
2827extractRGBAValues(l_uint32 pixel,
2828 l_int32 *prval,
2829 l_int32 *pgval,
2830 l_int32 *pbval,
2831 l_int32 *paval)
2832{
2833 if (prval) *prval = (pixel >> L_RED_SHIFT) & 0xff;
2834 if (pgval) *pgval = (pixel >> L_GREEN_SHIFT) & 0xff;
2835 if (pbval) *pbval = (pixel >> L_BLUE_SHIFT) & 0xff;
2836 if (paval) *paval = (pixel >> L_ALPHA_SHIFT) & 0xff;
2837}
2838
2839
2847l_int32
2849 l_int32 type)
2850{
2851l_int32 rval, gval, bval, val;
2852
2853 extractRGBValues(pixel, &rval, &gval, &bval);
2854 if (type == L_CHOOSE_MIN) {
2855 val = L_MIN(rval, gval);
2856 val = L_MIN(val, bval);
2857 } else { /* type == L_CHOOSE_MAX */
2858 val = L_MAX(rval, gval);
2859 val = L_MAX(val, bval);
2860 }
2861 return val;
2862}
2863
2864
2881l_ok
2883 l_int32 row,
2884 l_uint8 *bufr,
2885 l_uint8 *bufg,
2886 l_uint8 *bufb)
2887{
2888l_uint32 *lines;
2889l_int32 j, w, h;
2890l_int32 wpls;
2891
2892 if (!pixs)
2893 return ERROR_INT("pixs not defined", __func__, 1);
2894 if (pixGetDepth(pixs) != 32)
2895 return ERROR_INT("pixs not 32 bpp", __func__, 1);
2896 if (!bufr || !bufg || !bufb)
2897 return ERROR_INT("buffer not defined", __func__, 1);
2898
2899 pixGetDimensions(pixs, &w, &h, NULL);
2900 if (row < 0 || row >= h)
2901 return ERROR_INT("row out of bounds", __func__, 1);
2902 wpls = pixGetWpl(pixs);
2903 lines = pixGetData(pixs) + row * wpls;
2904
2905 for (j = 0; j < w; j++) {
2906 bufr[j] = GET_DATA_BYTE(lines + j, COLOR_RED);
2907 bufg[j] = GET_DATA_BYTE(lines + j, COLOR_GREEN);
2908 bufb[j] = GET_DATA_BYTE(lines + j, COLOR_BLUE);
2909 }
2910
2911 return 0;
2912}
2913
2914
2915/*-------------------------------------------------------------*
2916 * Raster line pixel setter *
2917 *-------------------------------------------------------------*/
2934l_ok
2935setLineDataVal(l_uint32 *line,
2936 l_int32 j,
2937 l_int32 d,
2938 l_uint32 val)
2939{
2940 if (!line)
2941 return ERROR_INT("line not defined", __func__, 1);
2942 if (j < 0)
2943 return ERROR_INT("j must be >= 0", __func__, 1);
2944 if (d != 1 && d != 2 && d != 4 && d != 8 && d != 16 && d != 32)
2945 return ERROR_INT("invalid d", __func__, 1);
2946
2947 if (d == 1)
2948 SET_DATA_BIT_VAL(line, j, val);
2949 else if (d == 2)
2950 SET_DATA_DIBIT(line, j, val);
2951 else if (d == 4)
2952 SET_DATA_QBIT(line, j, val);
2953 else if (d == 8)
2954 SET_DATA_BYTE(line, j, val);
2955 else if (d == 16)
2956 SET_DATA_TWO_BYTES(line, j, val);
2957 else /* d == 32 */
2958 *(line + j) = val;
2959 return 0;
2960}
2961
2962
2963/*-------------------------------------------------------------*
2964 * Pixel endian conversion *
2965 *-------------------------------------------------------------*/
2990PIX *
2992{
2993l_uint32 *datas, *datad;
2994l_int32 i, j, h, wpl;
2995l_uint32 word;
2996PIX *pixd;
2997
2998#ifdef L_BIG_ENDIAN
2999
3000 return pixClone(pixs);
3001
3002#else /* L_LITTLE_ENDIAN */
3003
3004 if (!pixs)
3005 return (PIX *)ERROR_PTR("pixs not defined", __func__, NULL);
3006
3007 datas = pixGetData(pixs);
3008 wpl = pixGetWpl(pixs);
3009 h = pixGetHeight(pixs);
3010 if ((pixd = pixCreateTemplate(pixs)) == NULL)
3011 return (PIX *)ERROR_PTR("pixd not made", __func__, NULL);
3012 datad = pixGetData(pixd);
3013 for (i = 0; i < h; i++) {
3014 for (j = 0; j < wpl; j++, datas++, datad++) {
3015 word = *datas;
3016 *datad = (word >> 24) |
3017 ((word >> 8) & 0x0000ff00) |
3018 ((word << 8) & 0x00ff0000) |
3019 (word << 24);
3020 }
3021 }
3022
3023 return pixd;
3024
3025#endif /* L_BIG_ENDIAN */
3026
3027}
3028
3029
3052l_ok
3054{
3055l_uint32 *data;
3056l_int32 i, j, h, wpl;
3057l_uint32 word;
3058
3059#ifdef L_BIG_ENDIAN
3060
3061 return 0;
3062
3063#else /* L_LITTLE_ENDIAN */
3064
3065 if (!pixs)
3066 return ERROR_INT("pixs not defined", __func__, 1);
3067
3068 data = pixGetData(pixs);
3069 wpl = pixGetWpl(pixs);
3070 h = pixGetHeight(pixs);
3071 for (i = 0; i < h; i++) {
3072 for (j = 0; j < wpl; j++, data++) {
3073 word = *data;
3074 *data = (word >> 24) |
3075 ((word >> 8) & 0x0000ff00) |
3076 ((word << 8) & 0x00ff0000) |
3077 (word << 24);
3078 }
3079 }
3080
3081 return 0;
3082
3083#endif /* L_BIG_ENDIAN */
3084
3085}
3086
3087
3108l_int32
3109lineEndianByteSwap(l_uint32 *datad,
3110 l_uint32 *datas,
3111 l_int32 wpl)
3112{
3113l_int32 j;
3114l_uint32 word;
3115
3116 if (!datad || !datas)
3117 return ERROR_INT("datad and datas not both defined", __func__, 1);
3118
3119#ifdef L_BIG_ENDIAN
3120
3121 memcpy(datad, datas, 4 * wpl);
3122 return 0;
3123
3124#else /* L_LITTLE_ENDIAN */
3125
3126 for (j = 0; j < wpl; j++, datas++, datad++) {
3127 word = *datas;
3128 *datad = (word >> 24) |
3129 ((word >> 8) & 0x0000ff00) |
3130 ((word << 8) & 0x00ff0000) |
3131 (word << 24);
3132 }
3133 return 0;
3134
3135#endif /* L_BIG_ENDIAN */
3136
3137}
3138
3139
3159PIX *
3161{
3162l_uint32 *datas, *datad;
3163l_int32 i, j, h, wpl;
3164l_uint32 word;
3165PIX *pixd;
3166
3167#ifdef L_BIG_ENDIAN
3168
3169 return pixClone(pixs);
3170
3171#else /* L_LITTLE_ENDIAN */
3172
3173 if (!pixs)
3174 return (PIX *)ERROR_PTR("pixs not defined", __func__, NULL);
3175
3176 datas = pixGetData(pixs);
3177 wpl = pixGetWpl(pixs);
3178 h = pixGetHeight(pixs);
3179 if ((pixd = pixCreateTemplate(pixs)) == NULL)
3180 return (PIX *)ERROR_PTR("pixd not made", __func__, NULL);
3181 datad = pixGetData(pixd);
3182 for (i = 0; i < h; i++) {
3183 for (j = 0; j < wpl; j++, datas++, datad++) {
3184 word = *datas;
3185 *datad = (word << 16) | (word >> 16);
3186 }
3187 }
3188
3189 return pixd;
3190
3191#endif /* L_BIG_ENDIAN */
3192
3193}
3194
3195
3211l_ok
3213{
3214l_uint32 *data;
3215l_int32 i, j, h, wpl;
3216l_uint32 word;
3217
3218#ifdef L_BIG_ENDIAN
3219
3220 return 0;
3221
3222#else /* L_LITTLE_ENDIAN */
3223
3224 if (!pixs)
3225 return ERROR_INT("pixs not defined", __func__, 1);
3226
3227 data = pixGetData(pixs);
3228 wpl = pixGetWpl(pixs);
3229 h = pixGetHeight(pixs);
3230 for (i = 0; i < h; i++) {
3231 for (j = 0; j < wpl; j++, data++) {
3232 word = *data;
3233 *data = (word << 16) | (word >> 16);
3234 }
3235 }
3236
3237 return 0;
3238
3239#endif /* L_BIG_ENDIAN */
3240
3241}
3242
3243
3244/*-------------------------------------------------------------*
3245 * Extract raster data as binary string *
3246 *-------------------------------------------------------------*/
3263l_ok
3265 l_uint8 **pdata,
3266 size_t *pnbytes)
3267{
3268l_int32 w, h, d, wpl, i, j, rval, gval, bval;
3269l_int32 databpl; /* bytes for each raster line in returned data */
3270l_uint8 *line, *data; /* packed data in returned array */
3271l_uint32 *rline, *rdata; /* data in pix raster */
3272
3273 if (pdata) *pdata = NULL;
3274 if (pnbytes) *pnbytes = 0;
3275 if (!pdata || !pnbytes)
3276 return ERROR_INT("&data and &nbytes not both defined", __func__, 1);
3277 if (!pixs)
3278 return ERROR_INT("pixs not defined", __func__, 1);
3279 pixGetDimensions(pixs, &w, &h, &d);
3280 if (d != 1 && d != 2 && d != 4 && d != 8 && d != 16 && d != 32)
3281 return ERROR_INT("depth not in {1,2,4,8,16,32}", __func__, 1);
3282
3283 pixSetPadBits(pixs, 0);
3284 rdata = pixGetData(pixs);
3285 wpl = pixGetWpl(pixs);
3286 if (d == 1)
3287 databpl = (w + 7) / 8;
3288 else if (d == 2)
3289 databpl = (w + 3) / 4;
3290 else if (d == 4)
3291 databpl = (w + 1) / 2;
3292 else if (d == 8 || d == 16)
3293 databpl = w * (d / 8);
3294 else /* d == 32 bpp rgb */
3295 databpl = 3 * w;
3296 if ((data = (l_uint8 *)LEPT_CALLOC((size_t)databpl * h, sizeof(l_uint8)))
3297 == NULL)
3298 return ERROR_INT("data not allocated", __func__, 1);
3299 *pdata = data;
3300 *pnbytes = (size_t)databpl * h;
3301
3302 for (i = 0; i < h; i++) {
3303 rline = rdata + i * wpl;
3304 line = data + i * databpl;
3305 if (d <= 8) {
3306 for (j = 0; j < databpl; j++)
3307 line[j] = GET_DATA_BYTE(rline, j);
3308 } else if (d == 16) {
3309 for (j = 0; j < w; j++)
3310 line[2 * j] = GET_DATA_TWO_BYTES(rline, j);
3311 } else { /* d == 32 bpp rgb */
3312 for (j = 0; j < w; j++) {
3313 extractRGBValues(rline[j], &rval, &gval, &bval);
3314 *(line + 3 * j) = rval;
3315 *(line + 3 * j + 1) = gval;
3316 *(line + 3 * j + 2) = bval;
3317 }
3318 }
3319 }
3320
3321 return 0;
3322}
3323
3324
3325/*-------------------------------------------------------------*
3326 * Infer resolution from image size *
3327 *-------------------------------------------------------------*/
3345l_ok
3347 l_float32 longside,
3348 l_int32 *pres)
3349{
3350l_int32 w, h, maxdim, res;
3351
3352 if (!pres)
3353 return ERROR_INT("&res not defined", __func__, 1);
3354 *pres = 300;
3355 if (!pix)
3356 return ERROR_INT("pix not defined", __func__, 1);
3357 if (longside <= 0.0)
3358 return ERROR_INT("longside not > 0", __func__, 1);
3359
3360 pixGetDimensions(pix, &w, &h, NULL);
3361 maxdim = L_MAX(w, h);
3362 res = (l_int32)(maxdim / longside + 0.5);
3363 res = L_MAX(res, 1); /* don't let it be 0 */
3364 if (res < 10)
3365 L_WARNING("low inferred resolution: %d ppi\n", __func__, res);
3366 if (res > 10000)
3367 L_WARNING("high inferred resolution: %d ppi\n", __func__, res);
3368 *pres = res;
3369 return 0;
3370}
3371
3372
3373/*-------------------------------------------------------------*
3374 * Test alpha component opaqueness *
3375 *-------------------------------------------------------------*/
3389l_ok
3391 l_int32 *popaque)
3392{
3393l_int32 w, h, wpl, i, j, alpha;
3394l_uint32 *data, *line;
3395
3396 if (!popaque)
3397 return ERROR_INT("&opaque not defined", __func__, 1);
3398 *popaque = FALSE;
3399 if (!pix)
3400 return ERROR_INT("&pix not defined", __func__, 1);
3401 if (pixGetDepth(pix) != 32)
3402 return ERROR_INT("&pix not 32 bpp", __func__, 1);
3403 if (pixGetSpp(pix) != 4)
3404 return ERROR_INT("&pix not 4 spp", __func__, 1);
3405
3406 data = pixGetData(pix);
3407 wpl = pixGetWpl(pix);
3408 pixGetDimensions(pix, &w, &h, NULL);
3409 for (i = 0; i < h; i++) {
3410 line = data + i * wpl;
3411 for (j = 0; j < w; j++) {
3412 alpha = GET_DATA_BYTE(line + j, L_ALPHA_CHANNEL);
3413 if (alpha ^ 0xff) /* not opaque */
3414 return 0;
3415 }
3416 }
3417
3418 *popaque = TRUE;
3419 return 0;
3420}
3421
3422
3423/*-------------------------------------------------------------*
3424 * Setup helpers for 8 bpp byte processing *
3425 *-------------------------------------------------------------*/
3452l_uint8 **
3454 l_int32 *pw,
3455 l_int32 *ph)
3456{
3457l_int32 w, h;
3458
3459 if (pw) *pw = 0;
3460 if (ph) *ph = 0;
3461 if (!pix || pixGetDepth(pix) != 8)
3462 return (l_uint8 **)ERROR_PTR("pix not defined or not 8 bpp",
3463 __func__, NULL);
3464 pixGetDimensions(pix, &w, &h, NULL);
3465 if (pw) *pw = w;
3466 if (ph) *ph = h;
3467 if (pixGetColormap(pix))
3468 return (l_uint8 **)ERROR_PTR("pix has colormap", __func__, NULL);
3469
3470 pixEndianByteSwap(pix);
3471 return (l_uint8 **)pixGetLinePtrs(pix, NULL);
3472}
3473
3474
3488l_ok
3490 l_uint8 **lineptrs)
3491{
3492 if (!pix)
3493 return ERROR_INT("pix not defined", __func__, 1);
3494 if (!lineptrs)
3495 return ERROR_INT("lineptrs not defined", __func__, 1);
3496
3497 pixEndianByteSwap(pix);
3498 LEPT_FREE(lineptrs);
3499 return 0;
3500}
3501
3502
3503/*------------------------------------------------------------------------*
3504 * Setting parameters for antialias masking with alpha transforms *
3505 *------------------------------------------------------------------------*/
3528void
3530 l_float32 val2)
3531{
3532 val1 = L_MAX(0.0f, L_MIN(1.0f, val1));
3533 val2 = L_MAX(0.0f, L_MIN(1.0f, val2));
3534 AlphaMaskBorderVals[0] = val1;
3535 AlphaMaskBorderVals[1] = val2;
3536}
#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:1635
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:1943
l_ok pixAlphaIsOpaque(PIX *pix, l_int32 *popaque)
pixAlphaIsOpaque()
Definition pix2.c:3390
PIX * pixAddContinuedBorder(PIX *pixs, l_int32 left, l_int32 right, l_int32 top, l_int32 bot)
pixAddContinuedBorder()
Definition pix2.c:2262
l_int32 lineEndianByteSwap(l_uint32 *datad, l_uint32 *datas, l_int32 wpl)
lineEndianByteSwap()
Definition pix2.c:3109
PIX * pixDisplayLayersRGBA(PIX *pixs, l_uint32 val, l_int32 maxw)
pixDisplayLayersRGBA()
Definition pix2.c:2352
l_uint8 ** pixSetupByteProcessing(PIX *pix, l_int32 *pw, l_int32 *ph)
pixSetupByteProcessing()
Definition pix2.c:3453
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:2163
l_int32 extractMinMaxComponent(l_uint32 pixel, l_int32 type)
extractMinMaxComponent()
Definition pix2.c:2848
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:2303
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:1989
l_ok pixGetRGBLine(PIX *pixs, l_int32 row, l_uint8 *bufr, l_uint8 *bufg, l_uint8 *bufb)
pixGetRGBLine()
Definition pix2.c:2882
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:3346
PIX * pixEndianByteSwapNew(PIX *pixs)
pixEndianByteSwapNew()
Definition pix2.c:2991
PIX * pixAddBlackOrWhiteBorder(PIX *pixs, l_int32 left, l_int32 right, l_int32 top, l_int32 bot, l_int32 op)
pixAddBlackOrWhiteBorder()
Definition pix2.c:1823
void extractRGBAValues(l_uint32 pixel, l_int32 *prval, l_int32 *pgval, l_int32 *pbval, l_int32 *paval)
extractRGBAValues()
Definition pix2.c:2827
l_ok pixEndianTwoByteSwap(PIX *pixs)
pixEndianTwoByteSwap()
Definition pix2.c:3212
PIX * pixCopyBorder(PIX *pixd, PIX *pixs, l_int32 left, l_int32 right, l_int32 top, l_int32 bot)
pixCopyBorder()
Definition pix2.c:1733
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:1533
l_ok pixCopyRGBComponent(PIX *pixd, PIX *pixs, l_int32 comp)
pixCopyRGBComponent()
Definition pix2.c:2681
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:3529
PIX * pixAddMixedBorder(PIX *pixs, l_int32 left, l_int32 right, l_int32 top, l_int32 bot)
pixAddMixedBorder()
Definition pix2.c:2217
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:2008
l_ok pixSetAll(PIX *pix)
pixSetAll()
Definition pix2.c:799
l_ok pixSetPadBits(PIX *pix, l_int32 val)
pixSetPadBits()
Definition pix2.c:1349
l_ok pixSetOrClearBorder(PIX *pixs, l_int32 left, l_int32 right, l_int32 top, l_int32 bot, l_int32 op)
pixSetOrClearBorder()
Definition pix2.c:1486
PIX * pixGetRGBComponentCmap(PIX *pixs, l_int32 comp)
pixGetRGBComponentCmap()
Definition pix2.c:2593
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:2770
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:2112
l_ok pixBlendInRect(PIX *pixs, BOX *box, l_uint32 val, l_float32 fract)
pixBlendInRect()
Definition pix2.c:1262
l_ok composeRGBPixel(l_int32 rval, l_int32 gval, l_int32 bval, l_uint32 *ppixel)
composeRGBPixel()
Definition pix2.c:2740
l_ok pixCleanupByteProcessing(PIX *pix, l_uint8 **lineptrs)
pixCleanupByteProcessing()
Definition pix2.c:3489
void extractRGBValues(l_uint32 pixel, l_int32 *prval, l_int32 *pgval, l_int32 *pbval)
extractRGBValues()
Definition pix2.c:2805
l_ok setLineDataVal(l_uint32 *line, l_int32 j, l_int32 d, l_uint32 val)
setLineDataVal()
Definition pix2.c:2935
PIX * pixEndianTwoByteSwapNew(PIX *pixs)
pixEndianTwoByteSwapNew()
Definition pix2.c:3160
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:1684
l_ok pixSetPadBitsBand(PIX *pix, l_int32 by, l_int32 bh, l_int32 val)
pixSetPadBitsBand()
Definition pix2.c:1412
PIX * pixAddBorder(PIX *pixs, l_int32 npix, l_uint32 val)
pixAddBorder()
Definition pix2.c:1785
l_ok pixEndianByteSwap(PIX *pixs)
pixEndianByteSwap()
Definition pix2.c:3053
l_ok pixSetBlackOrWhite(PIX *pixs, l_int32 op)
pixSetBlackOrWhite()
Definition pix2.c:997
PIX * pixGetRGBComponent(PIX *pixs, l_int32 comp)
pixGetRGBComponent()
Definition pix2.c:2476
PIX * pixAddBorderGeneral(PIX *pixs, l_int32 left, l_int32 right, l_int32 top, l_int32 bot, l_uint32 val)
pixAddBorderGeneral()
Definition pix2.c:1875
l_ok pixSetRGBComponent(PIX *pixd, PIX *pixs, l_int32 comp)
pixSetRGBComponent()
Definition pix2.c:2533
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:2059
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:3264
PIX * pixCreateRGBImage(PIX *pixr, PIX *pixg, PIX *pixb)
pixCreateRGBImage()
Definition pix2.c:2422
@ 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