Leptonica 1.83.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
135
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 *-------------------------------------------------------------*/
1345l_ok
1347 l_int32 val)
1348{
1349l_int32 i, w, h, d, wpl, endbits, fullwords;
1350l_uint32 mask;
1351l_uint32 *data, *pword;
1352
1353 if (!pix)
1354 return ERROR_INT("pix not defined", __func__, 1);
1355
1356 pixGetDimensions(pix, &w, &h, &d);
1357 if (d == 32) /* no padding exists for 32 bpp */
1358 return 0;
1359
1360 data = pixGetData(pix);
1361 wpl = pixGetWpl(pix);
1362 endbits = 32 - (((l_int64)w * d) % 32);
1363 if (endbits == 32) /* no partial word */
1364 return 0;
1365 fullwords = (1LL * w * d) / 32;
1366 mask = rmask32[endbits];
1367 if (val == 0)
1368 mask = ~mask;
1369
1370 for (i = 0; i < h; i++) {
1371 pword = data + i * wpl + fullwords;
1372 if (val == 0) /* clear */
1373 *pword = *pword & mask;
1374 else /* set */
1375 *pword = *pword | mask;
1376 }
1377
1378 return 0;
1379}
1380
1381
1403l_ok
1405 l_int32 by,
1406 l_int32 bh,
1407 l_int32 val)
1408{
1409l_int32 i, w, h, d, wpl, endbits, fullwords;
1410l_uint32 mask;
1411l_uint32 *data, *pword;
1412
1413 if (!pix)
1414 return ERROR_INT("pix not defined", __func__, 1);
1415
1416 pixGetDimensions(pix, &w, &h, &d);
1417 if (d == 32) /* no padding exists for 32 bpp */
1418 return 0;
1419
1420 if (by < 0)
1421 by = 0;
1422 if (by >= h)
1423 return ERROR_INT("start y not in image", __func__, 1);
1424 if (by + bh > h)
1425 bh = h - by;
1426
1427 data = pixGetData(pix);
1428 wpl = pixGetWpl(pix);
1429 endbits = 32 - (((l_int64)w * d) % 32);
1430 if (endbits == 32) /* no partial word */
1431 return 0;
1432 fullwords = (l_int64)w * d / 32;
1433
1434 mask = rmask32[endbits];
1435 if (val == 0)
1436 mask = ~mask;
1437
1438 for (i = by; i < by + bh; i++) {
1439 pword = data + i * wpl + fullwords;
1440 if (val == 0) /* clear */
1441 *pword = *pword & mask;
1442 else /* set */
1443 *pword = *pword | mask;
1444 }
1445
1446 return 0;
1447}
1448
1449
1450/*-------------------------------------------------------------*
1451 * Set border pixels *
1452 *-------------------------------------------------------------*/
1473l_ok
1475 l_int32 left,
1476 l_int32 right,
1477 l_int32 top,
1478 l_int32 bot,
1479 l_int32 op)
1480{
1481l_int32 w, h;
1482
1483 if (!pixs)
1484 return ERROR_INT("pixs not defined", __func__, 1);
1485 if (op != PIX_SET && op != PIX_CLR)
1486 return ERROR_INT("op must be PIX_SET or PIX_CLR", __func__, 1);
1487
1488 pixGetDimensions(pixs, &w, &h, NULL);
1489 pixRasterop(pixs, 0, 0, left, h, op, NULL, 0, 0);
1490 pixRasterop(pixs, w - right, 0, right, h, op, NULL, 0, 0);
1491 pixRasterop(pixs, 0, 0, w, top, op, NULL, 0, 0);
1492 pixRasterop(pixs, 0, h - bot, w, bot, op, NULL, 0, 0);
1493
1494 return 0;
1495}
1496
1497
1520l_ok
1522 l_int32 left,
1523 l_int32 right,
1524 l_int32 top,
1525 l_int32 bot,
1526 l_uint32 val)
1527{
1528l_int32 w, h, d, wpls, i, j, bstart, rstart;
1529l_uint32 *datas, *lines;
1530
1531 if (!pixs)
1532 return ERROR_INT("pixs not defined", __func__, 1);
1533 pixGetDimensions(pixs, &w, &h, &d);
1534 if (d != 8 && d != 16 && d != 32)
1535 return ERROR_INT("depth must be 8, 16 or 32 bpp", __func__, 1);
1536
1537 datas = pixGetData(pixs);
1538 wpls = pixGetWpl(pixs);
1539 if (d == 8) {
1540 val &= 0xff;
1541 for (i = 0; i < top; i++) {
1542 lines = datas + i * wpls;
1543 for (j = 0; j < w; j++)
1544 SET_DATA_BYTE(lines, j, val);
1545 }
1546 rstart = w - right;
1547 bstart = h - bot;
1548 for (i = top; i < bstart; i++) {
1549 lines = datas + i * wpls;
1550 for (j = 0; j < left; j++)
1551 SET_DATA_BYTE(lines, j, val);
1552 for (j = rstart; j < w; j++)
1553 SET_DATA_BYTE(lines, j, val);
1554 }
1555 for (i = bstart; i < h; i++) {
1556 lines = datas + i * wpls;
1557 for (j = 0; j < w; j++)
1558 SET_DATA_BYTE(lines, j, val);
1559 }
1560 } else if (d == 16) {
1561 val &= 0xffff;
1562 for (i = 0; i < top; i++) {
1563 lines = datas + i * wpls;
1564 for (j = 0; j < w; j++)
1565 SET_DATA_TWO_BYTES(lines, j, val);
1566 }
1567 rstart = w - right;
1568 bstart = h - bot;
1569 for (i = top; i < bstart; i++) {
1570 lines = datas + i * wpls;
1571 for (j = 0; j < left; j++)
1572 SET_DATA_TWO_BYTES(lines, j, val);
1573 for (j = rstart; j < w; j++)
1574 SET_DATA_TWO_BYTES(lines, j, val);
1575 }
1576 for (i = bstart; i < h; i++) {
1577 lines = datas + i * wpls;
1578 for (j = 0; j < w; j++)
1579 SET_DATA_TWO_BYTES(lines, j, val);
1580 }
1581 } else { /* d == 32 */
1582 for (i = 0; i < top; i++) {
1583 lines = datas + i * wpls;
1584 for (j = 0; j < w; j++)
1585 *(lines + j) = val;
1586 }
1587 rstart = w - right;
1588 bstart = h - bot;
1589 for (i = top; i < bstart; i++) {
1590 lines = datas + i * wpls;
1591 for (j = 0; j < left; j++)
1592 *(lines + j) = val;
1593 for (j = rstart; j < w; j++)
1594 *(lines + j) = val;
1595 }
1596 for (i = bstart; i < h; i++) {
1597 lines = datas + i * wpls;
1598 for (j = 0; j < w; j++)
1599 *(lines + j) = val;
1600 }
1601 }
1602
1603 return 0;
1604}
1605
1606
1622l_ok
1624 l_int32 dist,
1625 l_uint32 val)
1626{
1627l_int32 w, h, d, i, j, xend, yend;
1628
1629 if (!pixs)
1630 return ERROR_INT("pixs not defined", __func__, 1);
1631 if (dist < 1)
1632 return ERROR_INT("dist must be > 0", __func__, 1);
1633 pixGetDimensions(pixs, &w, &h, &d);
1634 if (w < 2 * dist + 1 || h < 2 * dist + 1)
1635 return ERROR_INT("ring doesn't exist", __func__, 1);
1636 if (d < 32 && (val >= (1 << d)))
1637 return ERROR_INT("invalid pixel value", __func__, 1);
1638
1639 xend = w - dist;
1640 yend = h - dist;
1641 for (j = dist - 1; j <= xend; j++)
1642 pixSetPixel(pixs, j, dist - 1, val);
1643 for (j = dist - 1; j <= xend; j++)
1644 pixSetPixel(pixs, j, yend, val);
1645 for (i = dist - 1; i <= yend; i++)
1646 pixSetPixel(pixs, dist - 1, i, val);
1647 for (i = dist - 1; i <= yend; i++)
1648 pixSetPixel(pixs, xend, i, val);
1649
1650 return 0;
1651}
1652
1653
1671l_ok
1673 l_int32 left,
1674 l_int32 right,
1675 l_int32 top,
1676 l_int32 bot)
1677{
1678l_int32 i, j, w, h;
1679
1680 if (!pixs)
1681 return ERROR_INT("pixs not defined", __func__, 1);
1682
1683 pixGetDimensions(pixs, &w, &h, NULL);
1684 for (j = 0; j < left; j++)
1685 pixRasterop(pixs, left - 1 - j, top, 1, h - top - bot, PIX_SRC,
1686 pixs, left + j, top);
1687 for (j = 0; j < right; j++)
1688 pixRasterop(pixs, w - right + j, top, 1, h - top - bot, PIX_SRC,
1689 pixs, w - right - 1 - j, top);
1690 for (i = 0; i < top; i++)
1691 pixRasterop(pixs, 0, top - 1 - i, w, 1, PIX_SRC,
1692 pixs, 0, top + i);
1693 for (i = 0; i < bot; i++)
1694 pixRasterop(pixs, 0, h - bot + i, w, 1, PIX_SRC,
1695 pixs, 0, h - bot - 1 - i);
1696
1697 return 0;
1698}
1699
1700
1720PIX *
1722 PIX *pixs,
1723 l_int32 left,
1724 l_int32 right,
1725 l_int32 top,
1726 l_int32 bot)
1727{
1728l_int32 w, h;
1729
1730 if (!pixs)
1731 return (PIX *)ERROR_PTR("pixs not defined", __func__, pixd);
1732
1733 if (pixd) {
1734 if (pixd == pixs) {
1735 L_WARNING("same: nothing to do\n", __func__);
1736 return pixd;
1737 } else if (!pixSizesEqual(pixs, pixd)) {
1738 return (PIX *)ERROR_PTR("pixs and pixd sizes differ",
1739 __func__, pixd);
1740 }
1741 } else {
1742 if ((pixd = pixCreateTemplate(pixs)) == NULL)
1743 return (PIX *)ERROR_PTR("pixd not made", __func__, pixd);
1744 }
1745
1746 pixGetDimensions(pixs, &w, &h, NULL);
1747 pixRasterop(pixd, 0, 0, left, h, PIX_SRC, pixs, 0, 0);
1748 pixRasterop(pixd, w - right, 0, right, h, PIX_SRC, pixs, w - right, 0);
1749 pixRasterop(pixd, 0, 0, w, top, PIX_SRC, pixs, 0, 0);
1750 pixRasterop(pixd, 0, h - bot, w, bot, PIX_SRC, pixs, 0, h - bot);
1751 return pixd;
1752}
1753
1754
1755
1756/*-------------------------------------------------------------*
1757 * Add and remove border *
1758 *-------------------------------------------------------------*/
1772PIX *
1774 l_int32 npix,
1775 l_uint32 val)
1776{
1777 if (!pixs)
1778 return (PIX *)ERROR_PTR("pixs not defined", __func__, NULL);
1779 if (npix == 0)
1780 return pixClone(pixs);
1781 return pixAddBorderGeneral(pixs, npix, npix, npix, npix, val);
1782}
1783
1784
1810PIX *
1812 l_int32 left,
1813 l_int32 right,
1814 l_int32 top,
1815 l_int32 bot,
1816 l_int32 op)
1817{
1818l_uint32 val;
1819
1820 if (!pixs)
1821 return (PIX *)ERROR_PTR("pixs not defined", __func__, NULL);
1822 if (op != L_GET_BLACK_VAL && op != L_GET_WHITE_VAL)
1823 return (PIX *)ERROR_PTR("invalid op", __func__, NULL);
1824
1825 pixGetBlackOrWhiteVal(pixs, op, &val);
1826 return pixAddBorderGeneral(pixs, left, right, top, bot, val);
1827}
1828
1829
1862PIX *
1864 l_int32 left,
1865 l_int32 right,
1866 l_int32 top,
1867 l_int32 bot,
1868 l_uint32 val)
1869{
1870l_int32 ws, hs, wd, hd, d, maxval, op;
1871PIX *pixd;
1872
1873 if (!pixs)
1874 return (PIX *)ERROR_PTR("pixs not defined", __func__, NULL);
1875 if (left < 0 || right < 0 || top < 0 || bot < 0)
1876 return (PIX *)ERROR_PTR("negative border added!", __func__, NULL);
1877
1878 pixGetDimensions(pixs, &ws, &hs, &d);
1879 wd = ws + left + right;
1880 hd = hs + top + bot;
1881 if ((pixd = pixCreate(wd, hd, d)) == NULL)
1882 return (PIX *)ERROR_PTR("pixd not made", __func__, NULL);
1883 pixCopyResolution(pixd, pixs);
1884 pixCopyColormap(pixd, pixs);
1885
1886 /* Set the new border pixels */
1887 maxval = (d == 32) ? 0xffffff00 : (1 << d) - 1;
1888 op = UNDEF;
1889 if (val == 0)
1890 op = PIX_CLR;
1891 else if (val >= maxval)
1892 op = PIX_SET;
1893 if (op == UNDEF) {
1894 pixSetAllArbitrary(pixd, val);
1895 } else { /* just set or clear the border pixels */
1896 pixRasterop(pixd, 0, 0, left, hd, op, NULL, 0, 0);
1897 pixRasterop(pixd, wd - right, 0, right, hd, op, NULL, 0, 0);
1898 pixRasterop(pixd, 0, 0, wd, top, op, NULL, 0, 0);
1899 pixRasterop(pixd, 0, hd - bot, wd, bot, op, NULL, 0, 0);
1900 }
1901
1902 /* Copy pixs into the interior */
1903 pixRasterop(pixd, left, top, ws, hs, PIX_SRC, pixs, 0, 0);
1904 return pixd;
1905}
1906
1907
1930PIX *
1932 l_int32 nblack1,
1933 l_int32 nwhite1,
1934 l_int32 nblack2,
1935 l_int32 nwhite2,
1936 l_int32 nblack3,
1937 l_int32 nwhite3)
1938{
1939l_int32 i, color;
1940l_int32 w[6];
1941PIX *pix1, *pixd;
1942
1943 if (!pixs)
1944 return (PIX *)ERROR_PTR("pixs not defined", __func__, NULL);
1945
1946 w[0] = nblack1;
1947 w[1] = nwhite1;
1948 w[2] = nblack2;
1949 w[3] = nwhite2;
1950 w[4] = nblack3;
1951 w[5] = nwhite3;
1952 pixd = pixClone(pixs);
1953 for (i = 0; i < 6; i++) {
1954 if (w[i] > 500)
1955 L_WARNING("w = %d > 500; skipping\n", __func__, w[i]);
1956 if (w[i] > 0 && w[i] <= 500) {
1957 color = (i % 2 == 0) ? L_GET_BLACK_VAL : L_GET_WHITE_VAL;
1958 pix1 = pixAddBlackOrWhiteBorder(pixd, w[i], w[i], w[i], w[i],
1959 color);
1960 pixDestroy(&pixd);
1961 pixd = pix1;
1962 }
1963 }
1964
1965 return pixd;
1966}
1967
1968
1976PIX *
1978 l_int32 npix)
1979{
1980 if (!pixs)
1981 return (PIX *)ERROR_PTR("pixs not defined", __func__, NULL);
1982 if (npix == 0)
1983 return pixClone(pixs);
1984 return pixRemoveBorderGeneral(pixs, npix, npix, npix, npix);
1985}
1986
1987
1995PIX *
1997 l_int32 left,
1998 l_int32 right,
1999 l_int32 top,
2000 l_int32 bot)
2001{
2002l_int32 ws, hs, wd, hd, d;
2003PIX *pixd;
2004
2005 if (!pixs)
2006 return (PIX *)ERROR_PTR("pixs not defined", __func__, NULL);
2007 if (left < 0 || right < 0 || top < 0 || bot < 0)
2008 return (PIX *)ERROR_PTR("negative border removed!", __func__, NULL);
2009
2010 pixGetDimensions(pixs, &ws, &hs, &d);
2011 wd = ws - left - right;
2012 hd = hs - top - bot;
2013 if (wd <= 0)
2014 return (PIX *)ERROR_PTR("width must be > 0", __func__, NULL);
2015 if (hd <= 0)
2016 return (PIX *)ERROR_PTR("height must be > 0", __func__, NULL);
2017 if ((pixd = pixCreate(wd, hd, d)) == NULL)
2018 return (PIX *)ERROR_PTR("pixd not made", __func__, NULL);
2019 pixCopyResolution(pixd, pixs);
2020 pixCopySpp(pixd, pixs);
2021 pixCopyColormap(pixd, pixs);
2022
2023 pixRasterop(pixd, 0, 0, wd, hd, PIX_SRC, pixs, left, top);
2024 if (pixGetDepth(pixs) == 32 && pixGetSpp(pixs) == 4)
2025 pixShiftAndTransferAlpha(pixd, pixs, -left, -top);
2026 return pixd;
2027}
2028
2029
2046PIX *
2048 l_int32 wd,
2049 l_int32 hd)
2050{
2051l_int32 w, h, top, bot, left, right, delta;
2052
2053 if (!pixs)
2054 return (PIX *)ERROR_PTR("pixs not defined", __func__, NULL);
2055
2056 pixGetDimensions(pixs, &w, &h, NULL);
2057 if ((wd <= 0 || wd >= w) && (hd <= 0 || hd >= h))
2058 return pixClone(pixs);
2059
2060 left = right = (w - wd) / 2;
2061 delta = w - 2 * left - wd;
2062 right += delta;
2063 top = bot = (h - hd) / 2;
2064 delta = h - hd - 2 * top;
2065 bot += delta;
2066 if (wd <= 0 || wd > w)
2067 left = right = 0;
2068 else if (hd <= 0 || hd > h)
2069 top = bot = 0;
2070
2071 return pixRemoveBorderGeneral(pixs, left, right, top, bot);
2072}
2073
2074
2099PIX *
2101 l_int32 left,
2102 l_int32 right,
2103 l_int32 top,
2104 l_int32 bot)
2105{
2106l_int32 i, j, w, h;
2107PIX *pixd;
2108
2109 if (!pixs)
2110 return (PIX *)ERROR_PTR("pixs not defined", __func__, NULL);
2111 pixGetDimensions(pixs, &w, &h, NULL);
2112 if (left > w || right > w || top > h || bot > h)
2113 return (PIX *)ERROR_PTR("border too large", __func__, NULL);
2114
2115 /* Set pixels on left, right, top and bottom, in that order */
2116 pixd = pixAddBorderGeneral(pixs, left, right, top, bot, 0);
2117 for (j = 0; j < left; j++)
2118 pixRasterop(pixd, left - 1 - j, top, 1, h, PIX_SRC,
2119 pixd, left + j, top);
2120 for (j = 0; j < right; j++)
2121 pixRasterop(pixd, left + w + j, top, 1, h, PIX_SRC,
2122 pixd, left + w - 1 - j, top);
2123 for (i = 0; i < top; i++)
2124 pixRasterop(pixd, 0, top - 1 - i, left + w + right, 1, PIX_SRC,
2125 pixd, 0, top + i);
2126 for (i = 0; i < bot; i++)
2127 pixRasterop(pixd, 0, top + h + i, left + w + right, 1, PIX_SRC,
2128 pixd, 0, top + h - 1 - i);
2129
2130 return pixd;
2131}
2132
2133
2150PIX *
2152 l_int32 left,
2153 l_int32 right,
2154 l_int32 top,
2155 l_int32 bot)
2156{
2157l_int32 w, h;
2158PIX *pixd;
2159
2160 if (!pixs)
2161 return (PIX *)ERROR_PTR("pixs not defined", __func__, NULL);
2162 pixGetDimensions(pixs, &w, &h, NULL);
2163 if (left > w || right > w || top > h || bot > h)
2164 return (PIX *)ERROR_PTR("border too large", __func__, NULL);
2165
2166 pixd = pixAddBorderGeneral(pixs, left, right, top, bot, 0);
2167
2168 /* Set pixels on left, right, top and bottom, in that order */
2169 pixRasterop(pixd, 0, top, left, h, PIX_SRC, pixd, w, top);
2170 pixRasterop(pixd, left + w, top, right, h, PIX_SRC, pixd, left, top);
2171 pixRasterop(pixd, 0, 0, left + w + right, top, PIX_SRC, pixd, 0, h);
2172 pixRasterop(pixd, 0, top + h, left + w + right, bot, PIX_SRC, pixd, 0, top);
2173
2174 return pixd;
2175}
2176
2177
2204PIX *
2206 l_int32 left,
2207 l_int32 right,
2208 l_int32 top,
2209 l_int32 bot)
2210{
2211l_int32 j, w, h;
2212PIX *pixd;
2213
2214 if (!pixs)
2215 return (PIX *)ERROR_PTR("pixs not defined", __func__, NULL);
2216 pixGetDimensions(pixs, &w, &h, NULL);
2217 if (left > w || right > w || top > h || bot > h)
2218 return (PIX *)ERROR_PTR("border too large", __func__, NULL);
2219
2220 /* Set mirrored pixels on left and right;
2221 * then set repeated pixels on top and bottom. */
2222 pixd = pixAddBorderGeneral(pixs, left, right, top, bot, 0);
2223 for (j = 0; j < left; j++)
2224 pixRasterop(pixd, left - 1 - j, top, 1, h, PIX_SRC,
2225 pixd, left + j, top);
2226 for (j = 0; j < right; j++)
2227 pixRasterop(pixd, left + w + j, top, 1, h, PIX_SRC,
2228 pixd, left + w - 1 - j, top);
2229 pixRasterop(pixd, 0, 0, left + w + right, top, PIX_SRC, pixd, 0, h);
2230 pixRasterop(pixd, 0, top + h, left + w + right, bot, PIX_SRC, pixd, 0, top);
2231
2232 return pixd;
2233}
2234
2235
2249PIX *
2251 l_int32 left,
2252 l_int32 right,
2253 l_int32 top,
2254 l_int32 bot)
2255{
2256l_int32 i, j, w, h;
2257PIX *pixd;
2258
2259 if (!pixs)
2260 return (PIX *)ERROR_PTR("pixs not defined", __func__, NULL);
2261
2262 pixd = pixAddBorderGeneral(pixs, left, right, top, bot, 0);
2263 pixGetDimensions(pixs, &w, &h, NULL);
2264 for (j = 0; j < left; j++)
2265 pixRasterop(pixd, j, top, 1, h, PIX_SRC, pixd, left, top);
2266 for (j = 0; j < right; j++)
2267 pixRasterop(pixd, left + w + j, top, 1, h,
2268 PIX_SRC, pixd, left + w - 1, top);
2269 for (i = 0; i < top; i++)
2270 pixRasterop(pixd, 0, i, left + w + right, 1, PIX_SRC, pixd, 0, top);
2271 for (i = 0; i < bot; i++)
2272 pixRasterop(pixd, 0, top + h + i, left + w + right, 1,
2273 PIX_SRC, pixd, 0, top + h - 1);
2274
2275 return pixd;
2276}
2277
2278
2279/*-------------------------------------------------------------------*
2280 * Helper functions using alpha *
2281 *-------------------------------------------------------------------*/
2290l_ok
2292 PIX *pixs,
2293 l_float32 shiftx,
2294 l_float32 shifty)
2295{
2296l_int32 w, h;
2297PIX *pix1, *pix2;
2298
2299 if (!pixs || !pixd)
2300 return ERROR_INT("pixs and pixd not both defined", __func__, 1);
2301 if (pixGetDepth(pixs) != 32 || pixGetSpp(pixs) != 4)
2302 return ERROR_INT("pixs not 32 bpp and 4 spp", __func__, 1);
2303 if (pixGetDepth(pixd) != 32)
2304 return ERROR_INT("pixd not 32 bpp", __func__, 1);
2305
2306 if (shiftx == 0 && shifty == 0) {
2308 return 0;
2309 }
2310
2311 pix1 = pixGetRGBComponent(pixs, L_ALPHA_CHANNEL);
2312 pixGetDimensions(pixd, &w, &h, NULL);
2313 pix2 = pixCreate(w, h, 8);
2314 pixRasterop(pix2, 0, 0, w, h, PIX_SRC, pix1, -shiftx, -shifty);
2316 pixDestroy(&pix1);
2317 pixDestroy(&pix2);
2318 return 0;
2319}
2320
2321
2339PIX *
2341 l_uint32 val,
2342 l_int32 maxw)
2343{
2344l_int32 w, width;
2345l_float32 scalefact;
2346PIX *pix1, *pix2, *pixd;
2347PIXA *pixa;
2348PIXCMAP *cmap;
2349
2350 if (!pixs)
2351 return (PIX *)ERROR_PTR("pixs not defined", __func__, NULL);
2352 cmap = pixGetColormap(pixs);
2353 if (!cmap && !(pixGetDepth(pixs) == 32 && pixGetSpp(pixs) == 4))
2354 return (PIX *)ERROR_PTR("pixs not cmap and not 32 bpp rgba",
2355 __func__, NULL);
2356 if ((w = pixGetWidth(pixs)) == 0)
2357 return (PIX *)ERROR_PTR("pixs width 0 !!", __func__, NULL);
2358
2359 if (cmap)
2360 pix1 = pixRemoveColormap(pixs, REMOVE_CMAP_WITH_ALPHA);
2361 else
2362 pix1 = pixCopy(NULL, pixs);
2363
2364 /* Scale if necessary so the output width is not larger than maxw */
2365 scalefact = (maxw == 0) ? 1.0 : L_MIN(1.0, (l_float32)(maxw) / w);
2366 width = (l_int32)(scalefact * w);
2367
2368 pixa = pixaCreate(3);
2369 pixSetSpp(pix1, 3);
2370 pixaAddPix(pixa, pix1, L_INSERT); /* show the rgb values */
2371 pix1 = pixGetRGBComponent(pixs, L_ALPHA_CHANNEL);
2372 pix2 = pixConvertTo32(pix1);
2373 pixaAddPix(pixa, pix2, L_INSERT); /* show the alpha channel */
2374 pixDestroy(&pix1);
2375 pix1 = pixAlphaBlendUniform(pixs, (val & 0xffffff00));
2376 pixaAddPix(pixa, pix1, L_INSERT); /* with %val color bg showing */
2377 pixd = pixaDisplayTiledInRows(pixa, 32, width, scalefact, 0, 25, 2);
2378 pixaDestroy(&pixa);
2379 return pixd;
2380}
2381
2382
2383/*-------------------------------------------------------------*
2384 * Color sample setting and extraction *
2385 *-------------------------------------------------------------*/
2409PIX *
2411 PIX *pixg,
2412 PIX *pixb)
2413{
2414l_int32 wr, wg, wb, hr, hg, hb, dr, dg, db;
2415PIX *pixd;
2416
2417 if (!pixr)
2418 return (PIX *)ERROR_PTR("pixr not defined", __func__, NULL);
2419 if (!pixg)
2420 return (PIX *)ERROR_PTR("pixg not defined", __func__, NULL);
2421 if (!pixb)
2422 return (PIX *)ERROR_PTR("pixb not defined", __func__, NULL);
2423 pixGetDimensions(pixr, &wr, &hr, &dr);
2424 pixGetDimensions(pixg, &wg, &hg, &dg);
2425 pixGetDimensions(pixb, &wb, &hb, &db);
2426 if (dr != 8 || dg != 8 || db != 8)
2427 return (PIX *)ERROR_PTR("input pix not all 8 bpp", __func__, NULL);
2428 if (wr != wg || wr != wb)
2429 return (PIX *)ERROR_PTR("widths not the same", __func__, NULL);
2430 if (hr != hg || hr != hb)
2431 return (PIX *)ERROR_PTR("heights not the same", __func__, NULL);
2432
2433 if ((pixd = pixCreate(wr, hr, 32)) == NULL)
2434 return (PIX *)ERROR_PTR("pixd not made", __func__, NULL);
2435 pixCopyResolution(pixd, pixr);
2436 pixSetRGBComponent(pixd, pixr, COLOR_RED);
2437 pixSetRGBComponent(pixd, pixg, COLOR_GREEN);
2438 pixSetRGBComponent(pixd, pixb, COLOR_BLUE);
2439
2440 return pixd;
2441}
2442
2443
2463PIX *
2465 l_int32 comp)
2466{
2467l_int32 i, j, w, h, wpls, wpld, val;
2468l_uint32 *lines, *lined;
2469l_uint32 *datas, *datad;
2470PIX *pixd;
2471
2472 if (!pixs)
2473 return (PIX *)ERROR_PTR("pixs not defined", __func__, NULL);
2474 if (pixGetColormap(pixs))
2475 return pixGetRGBComponentCmap(pixs, comp);
2476 if (pixGetDepth(pixs) != 32)
2477 return (PIX *)ERROR_PTR("pixs not 32 bpp", __func__, NULL);
2478 if (comp != COLOR_RED && comp != COLOR_GREEN &&
2479 comp != COLOR_BLUE && comp != L_ALPHA_CHANNEL)
2480 return (PIX *)ERROR_PTR("invalid comp", __func__, NULL);
2481
2482 pixGetDimensions(pixs, &w, &h, NULL);
2483 if ((pixd = pixCreate(w, h, 8)) == NULL)
2484 return (PIX *)ERROR_PTR("pixd not made", __func__, NULL);
2485 pixCopyResolution(pixd, pixs);
2486 wpls = pixGetWpl(pixs);
2487 wpld = pixGetWpl(pixd);
2488 datas = pixGetData(pixs);
2489 datad = pixGetData(pixd);
2490 for (i = 0; i < h; i++) {
2491 lines = datas + i * wpls;
2492 lined = datad + i * wpld;
2493 for (j = 0; j < w; j++) {
2494 val = GET_DATA_BYTE(lines + j, comp);
2495 SET_DATA_BYTE(lined, j, val);
2496 }
2497 }
2498
2499 return pixd;
2500}
2501
2502
2520l_ok
2522 PIX *pixs,
2523 l_int32 comp)
2524{
2525l_uint8 srcbyte;
2526l_int32 i, j, w, h, ws, hs, wd, hd;
2527l_int32 wpls, wpld;
2528l_uint32 *lines, *lined;
2529l_uint32 *datas, *datad;
2530
2531 if (!pixd)
2532 return ERROR_INT("pixd not defined", __func__, 1);
2533 if (!pixs)
2534 return ERROR_INT("pixs not defined", __func__, 1);
2535 if (pixGetDepth(pixd) != 32)
2536 return ERROR_INT("pixd not 32 bpp", __func__, 1);
2537 if (pixGetDepth(pixs) != 8)
2538 return ERROR_INT("pixs not 8 bpp", __func__, 1);
2539 if (comp != COLOR_RED && comp != COLOR_GREEN &&
2540 comp != COLOR_BLUE && comp != L_ALPHA_CHANNEL)
2541 return ERROR_INT("invalid comp", __func__, 1);
2542 pixGetDimensions(pixs, &ws, &hs, NULL);
2543 pixGetDimensions(pixd, &wd, &hd, NULL);
2544 if (ws != wd || hs != hd)
2545 L_WARNING("images sizes not equal\n", __func__);
2546 w = L_MIN(ws, wd);
2547 h = L_MIN(hs, hd);
2548 if (comp == L_ALPHA_CHANNEL)
2549 pixSetSpp(pixd, 4);
2550 datas = pixGetData(pixs);
2551 datad = pixGetData(pixd);
2552 wpls = pixGetWpl(pixs);
2553 wpld = pixGetWpl(pixd);
2554 for (i = 0; i < h; i++) {
2555 lines = datas + i * wpls;
2556 lined = datad + i * wpld;
2557 for (j = 0; j < w; j++) {
2558 srcbyte = GET_DATA_BYTE(lines, j);
2559 SET_DATA_BYTE(lined + j, comp, srcbyte);
2560 }
2561 }
2562
2563 return 0;
2564}
2565
2566
2580PIX *
2582 l_int32 comp)
2583{
2584l_int32 i, j, w, h, val, index, valid;
2585l_int32 wplc, wpld;
2586l_uint32 *linec, *lined;
2587l_uint32 *datac, *datad;
2588PIX *pixc, *pixd;
2589PIXCMAP *cmap;
2590RGBA_QUAD *cta;
2591
2592 if (!pixs)
2593 return (PIX *)ERROR_PTR("pixs not defined", __func__, NULL);
2594 if ((cmap = pixGetColormap(pixs)) == NULL)
2595 return (PIX *)ERROR_PTR("pixs not cmapped", __func__, NULL);
2596 if (comp == L_ALPHA_CHANNEL)
2597 return (PIX *)ERROR_PTR("alpha in cmaps not supported", __func__, NULL);
2598 if (comp != COLOR_RED && comp != COLOR_GREEN && comp != COLOR_BLUE)
2599 return (PIX *)ERROR_PTR("invalid comp", __func__, NULL);
2600
2601 /* If not 8 bpp, make a cmapped 8 bpp pix */
2602 if (pixGetDepth(pixs) == 8)
2603 pixc = pixClone(pixs);
2604 else
2605 pixc = pixConvertTo8(pixs, TRUE);
2606 pixcmapIsValid(cmap, pixc, &valid);
2607 if (!valid) {
2608 pixDestroy(&pixc);
2609 return (PIX *)ERROR_PTR("invalid colormap", __func__, NULL);
2610 }
2611
2612 pixGetDimensions(pixs, &w, &h, NULL);
2613 if ((pixd = pixCreate(w, h, 8)) == NULL) {
2614 pixDestroy(&pixc);
2615 return (PIX *)ERROR_PTR("pixd not made", __func__, NULL);
2616 }
2617 pixCopyResolution(pixd, pixs);
2618 wplc = pixGetWpl(pixc);
2619 wpld = pixGetWpl(pixd);
2620 datac = pixGetData(pixc);
2621 datad = pixGetData(pixd);
2622 cta = (RGBA_QUAD *)cmap->array;
2623
2624 for (i = 0; i < h; i++) {
2625 linec = datac + i * wplc;
2626 lined = datad + i * wpld;
2627 if (comp == COLOR_RED) {
2628 for (j = 0; j < w; j++) {
2629 index = GET_DATA_BYTE(linec, j);
2630 val = cta[index].red;
2631 SET_DATA_BYTE(lined, j, val);
2632 }
2633 } else if (comp == COLOR_GREEN) {
2634 for (j = 0; j < w; j++) {
2635 index = GET_DATA_BYTE(linec, j);
2636 val = cta[index].green;
2637 SET_DATA_BYTE(lined, j, val);
2638 }
2639 } else if (comp == COLOR_BLUE) {
2640 for (j = 0; j < w; j++) {
2641 index = GET_DATA_BYTE(linec, j);
2642 val = cta[index].blue;
2643 SET_DATA_BYTE(lined, j, val);
2644 }
2645 }
2646 }
2647
2648 pixDestroy(&pixc);
2649 return pixd;
2650}
2651
2652
2668l_ok
2670 PIX *pixs,
2671 l_int32 comp)
2672{
2673l_int32 i, j, w, h, ws, hs, wd, hd, val;
2674l_int32 wpls, wpld;
2675l_uint32 *lines, *lined;
2676l_uint32 *datas, *datad;
2677
2678 if (!pixd && pixGetDepth(pixd) != 32)
2679 return ERROR_INT("pixd not defined or not 32 bpp", __func__, 1);
2680 if (!pixs && pixGetDepth(pixs) != 32)
2681 return ERROR_INT("pixs not defined or not 32 bpp", __func__, 1);
2682 if (comp != COLOR_RED && comp != COLOR_GREEN &&
2683 comp != COLOR_BLUE && comp != L_ALPHA_CHANNEL)
2684 return ERROR_INT("invalid component", __func__, 1);
2685 pixGetDimensions(pixs, &ws, &hs, NULL);
2686 pixGetDimensions(pixd, &wd, &hd, NULL);
2687 if (ws != wd || hs != hd)
2688 L_WARNING("images sizes not equal\n", __func__);
2689 w = L_MIN(ws, wd);
2690 h = L_MIN(hs, hd);
2691 if (comp == L_ALPHA_CHANNEL)
2692 pixSetSpp(pixd, 4);
2693 wpls = pixGetWpl(pixs);
2694 wpld = pixGetWpl(pixd);
2695 datas = pixGetData(pixs);
2696 datad = pixGetData(pixd);
2697 for (i = 0; i < h; i++) {
2698 lines = datas + i * wpls;
2699 lined = datad + i * wpld;
2700 for (j = 0; j < w; j++) {
2701 val = GET_DATA_BYTE(lines + j, comp);
2702 SET_DATA_BYTE(lined + j, comp, val);
2703 }
2704 }
2705 return 0;
2706}
2707
2708
2727l_ok
2728composeRGBPixel(l_int32 rval,
2729 l_int32 gval,
2730 l_int32 bval,
2731 l_uint32 *ppixel)
2732{
2733 if (!ppixel)
2734 return ERROR_INT("&pixel not defined", __func__, 1);
2735
2736 *ppixel = ((l_uint32)rval << L_RED_SHIFT) |
2737 ((l_uint32)gval << L_GREEN_SHIFT) |
2738 ((l_uint32)bval << L_BLUE_SHIFT);
2739 return 0;
2740}
2741
2742
2757l_ok
2758composeRGBAPixel(l_int32 rval,
2759 l_int32 gval,
2760 l_int32 bval,
2761 l_int32 aval,
2762 l_uint32 *ppixel)
2763{
2764 if (!ppixel)
2765 return ERROR_INT("&pixel not defined", __func__, 1);
2766
2767 *ppixel = ((l_uint32)rval << L_RED_SHIFT) |
2768 ((l_uint32)gval << L_GREEN_SHIFT) |
2769 ((l_uint32)bval << L_BLUE_SHIFT) |
2770 aval;
2771 return 0;
2772}
2773
2774
2792void
2793extractRGBValues(l_uint32 pixel,
2794 l_int32 *prval,
2795 l_int32 *pgval,
2796 l_int32 *pbval)
2797{
2798 if (prval) *prval = (pixel >> L_RED_SHIFT) & 0xff;
2799 if (pgval) *pgval = (pixel >> L_GREEN_SHIFT) & 0xff;
2800 if (pbval) *pbval = (pixel >> L_BLUE_SHIFT) & 0xff;
2801}
2802
2803
2814void
2815extractRGBAValues(l_uint32 pixel,
2816 l_int32 *prval,
2817 l_int32 *pgval,
2818 l_int32 *pbval,
2819 l_int32 *paval)
2820{
2821 if (prval) *prval = (pixel >> L_RED_SHIFT) & 0xff;
2822 if (pgval) *pgval = (pixel >> L_GREEN_SHIFT) & 0xff;
2823 if (pbval) *pbval = (pixel >> L_BLUE_SHIFT) & 0xff;
2824 if (paval) *paval = (pixel >> L_ALPHA_SHIFT) & 0xff;
2825}
2826
2827
2835l_int32
2837 l_int32 type)
2838{
2839l_int32 rval, gval, bval, val;
2840
2841 extractRGBValues(pixel, &rval, &gval, &bval);
2842 if (type == L_CHOOSE_MIN) {
2843 val = L_MIN(rval, gval);
2844 val = L_MIN(val, bval);
2845 } else { /* type == L_CHOOSE_MAX */
2846 val = L_MAX(rval, gval);
2847 val = L_MAX(val, bval);
2848 }
2849 return val;
2850}
2851
2852
2869l_ok
2871 l_int32 row,
2872 l_uint8 *bufr,
2873 l_uint8 *bufg,
2874 l_uint8 *bufb)
2875{
2876l_uint32 *lines;
2877l_int32 j, w, h;
2878l_int32 wpls;
2879
2880 if (!pixs)
2881 return ERROR_INT("pixs not defined", __func__, 1);
2882 if (pixGetDepth(pixs) != 32)
2883 return ERROR_INT("pixs not 32 bpp", __func__, 1);
2884 if (!bufr || !bufg || !bufb)
2885 return ERROR_INT("buffer not defined", __func__, 1);
2886
2887 pixGetDimensions(pixs, &w, &h, NULL);
2888 if (row < 0 || row >= h)
2889 return ERROR_INT("row out of bounds", __func__, 1);
2890 wpls = pixGetWpl(pixs);
2891 lines = pixGetData(pixs) + row * wpls;
2892
2893 for (j = 0; j < w; j++) {
2894 bufr[j] = GET_DATA_BYTE(lines + j, COLOR_RED);
2895 bufg[j] = GET_DATA_BYTE(lines + j, COLOR_GREEN);
2896 bufb[j] = GET_DATA_BYTE(lines + j, COLOR_BLUE);
2897 }
2898
2899 return 0;
2900}
2901
2902
2903/*-------------------------------------------------------------*
2904 * Raster line pixel setter *
2905 *-------------------------------------------------------------*/
2922l_ok
2923setLineDataVal(l_uint32 *line,
2924 l_int32 j,
2925 l_int32 d,
2926 l_uint32 val)
2927{
2928 if (!line)
2929 return ERROR_INT("line not defined", __func__, 1);
2930 if (j < 0)
2931 return ERROR_INT("j must be >= 0", __func__, 1);
2932 if (d != 1 && d != 2 && d != 4 && d != 8 && d != 16 && d != 32)
2933 return ERROR_INT("invalid d", __func__, 1);
2934
2935 if (d == 1)
2936 SET_DATA_BIT_VAL(line, j, val);
2937 else if (d == 2)
2938 SET_DATA_DIBIT(line, j, val);
2939 else if (d == 4)
2940 SET_DATA_QBIT(line, j, val);
2941 else if (d == 8)
2942 SET_DATA_BYTE(line, j, val);
2943 else if (d == 16)
2944 SET_DATA_TWO_BYTES(line, j, val);
2945 else /* d == 32 */
2946 *(line + j) = val;
2947 return 0;
2948}
2949
2950
2951/*-------------------------------------------------------------*
2952 * Pixel endian conversion *
2953 *-------------------------------------------------------------*/
2978PIX *
2980{
2981l_uint32 *datas, *datad;
2982l_int32 i, j, h, wpl;
2983l_uint32 word;
2984PIX *pixd;
2985
2986#ifdef L_BIG_ENDIAN
2987
2988 return pixClone(pixs);
2989
2990#else /* L_LITTLE_ENDIAN */
2991
2992 if (!pixs)
2993 return (PIX *)ERROR_PTR("pixs not defined", __func__, NULL);
2994
2995 datas = pixGetData(pixs);
2996 wpl = pixGetWpl(pixs);
2997 h = pixGetHeight(pixs);
2998 if ((pixd = pixCreateTemplate(pixs)) == NULL)
2999 return (PIX *)ERROR_PTR("pixd not made", __func__, NULL);
3000 datad = pixGetData(pixd);
3001 for (i = 0; i < h; i++) {
3002 for (j = 0; j < wpl; j++, datas++, datad++) {
3003 word = *datas;
3004 *datad = (word >> 24) |
3005 ((word >> 8) & 0x0000ff00) |
3006 ((word << 8) & 0x00ff0000) |
3007 (word << 24);
3008 }
3009 }
3010
3011 return pixd;
3012
3013#endif /* L_BIG_ENDIAN */
3014
3015}
3016
3017
3040l_ok
3042{
3043l_uint32 *data;
3044l_int32 i, j, h, wpl;
3045l_uint32 word;
3046
3047#ifdef L_BIG_ENDIAN
3048
3049 return 0;
3050
3051#else /* L_LITTLE_ENDIAN */
3052
3053 if (!pixs)
3054 return ERROR_INT("pixs not defined", __func__, 1);
3055
3056 data = pixGetData(pixs);
3057 wpl = pixGetWpl(pixs);
3058 h = pixGetHeight(pixs);
3059 for (i = 0; i < h; i++) {
3060 for (j = 0; j < wpl; j++, data++) {
3061 word = *data;
3062 *data = (word >> 24) |
3063 ((word >> 8) & 0x0000ff00) |
3064 ((word << 8) & 0x00ff0000) |
3065 (word << 24);
3066 }
3067 }
3068
3069 return 0;
3070
3071#endif /* L_BIG_ENDIAN */
3072
3073}
3074
3075
3096l_int32
3097lineEndianByteSwap(l_uint32 *datad,
3098 l_uint32 *datas,
3099 l_int32 wpl)
3100{
3101l_int32 j;
3102l_uint32 word;
3103
3104 if (!datad || !datas)
3105 return ERROR_INT("datad and datas not both defined", __func__, 1);
3106
3107#ifdef L_BIG_ENDIAN
3108
3109 memcpy(datad, datas, 4 * wpl);
3110 return 0;
3111
3112#else /* L_LITTLE_ENDIAN */
3113
3114 for (j = 0; j < wpl; j++, datas++, datad++) {
3115 word = *datas;
3116 *datad = (word >> 24) |
3117 ((word >> 8) & 0x0000ff00) |
3118 ((word << 8) & 0x00ff0000) |
3119 (word << 24);
3120 }
3121 return 0;
3122
3123#endif /* L_BIG_ENDIAN */
3124
3125}
3126
3127
3147PIX *
3149{
3150l_uint32 *datas, *datad;
3151l_int32 i, j, h, wpl;
3152l_uint32 word;
3153PIX *pixd;
3154
3155#ifdef L_BIG_ENDIAN
3156
3157 return pixClone(pixs);
3158
3159#else /* L_LITTLE_ENDIAN */
3160
3161 if (!pixs)
3162 return (PIX *)ERROR_PTR("pixs not defined", __func__, NULL);
3163
3164 datas = pixGetData(pixs);
3165 wpl = pixGetWpl(pixs);
3166 h = pixGetHeight(pixs);
3167 if ((pixd = pixCreateTemplate(pixs)) == NULL)
3168 return (PIX *)ERROR_PTR("pixd not made", __func__, NULL);
3169 datad = pixGetData(pixd);
3170 for (i = 0; i < h; i++) {
3171 for (j = 0; j < wpl; j++, datas++, datad++) {
3172 word = *datas;
3173 *datad = (word << 16) | (word >> 16);
3174 }
3175 }
3176
3177 return pixd;
3178
3179#endif /* L_BIG_ENDIAN */
3180
3181}
3182
3183
3199l_ok
3201{
3202l_uint32 *data;
3203l_int32 i, j, h, wpl;
3204l_uint32 word;
3205
3206#ifdef L_BIG_ENDIAN
3207
3208 return 0;
3209
3210#else /* L_LITTLE_ENDIAN */
3211
3212 if (!pixs)
3213 return ERROR_INT("pixs not defined", __func__, 1);
3214
3215 data = pixGetData(pixs);
3216 wpl = pixGetWpl(pixs);
3217 h = pixGetHeight(pixs);
3218 for (i = 0; i < h; i++) {
3219 for (j = 0; j < wpl; j++, data++) {
3220 word = *data;
3221 *data = (word << 16) | (word >> 16);
3222 }
3223 }
3224
3225 return 0;
3226
3227#endif /* L_BIG_ENDIAN */
3228
3229}
3230
3231
3232/*-------------------------------------------------------------*
3233 * Extract raster data as binary string *
3234 *-------------------------------------------------------------*/
3251l_ok
3253 l_uint8 **pdata,
3254 size_t *pnbytes)
3255{
3256l_int32 w, h, d, wpl, i, j, rval, gval, bval;
3257l_int32 databpl; /* bytes for each raster line in returned data */
3258l_uint8 *line, *data; /* packed data in returned array */
3259l_uint32 *rline, *rdata; /* data in pix raster */
3260
3261 if (pdata) *pdata = NULL;
3262 if (pnbytes) *pnbytes = 0;
3263 if (!pdata || !pnbytes)
3264 return ERROR_INT("&data and &nbytes not both defined", __func__, 1);
3265 if (!pixs)
3266 return ERROR_INT("pixs not defined", __func__, 1);
3267 pixGetDimensions(pixs, &w, &h, &d);
3268 if (d != 1 && d != 2 && d != 4 && d != 8 && d != 16 && d != 32)
3269 return ERROR_INT("depth not in {1,2,4,8,16,32}", __func__, 1);
3270
3271 pixSetPadBits(pixs, 0);
3272 rdata = pixGetData(pixs);
3273 wpl = pixGetWpl(pixs);
3274 if (d == 1)
3275 databpl = (w + 7) / 8;
3276 else if (d == 2)
3277 databpl = (w + 3) / 4;
3278 else if (d == 4)
3279 databpl = (w + 1) / 2;
3280 else if (d == 8 || d == 16)
3281 databpl = w * (d / 8);
3282 else /* d == 32 bpp rgb */
3283 databpl = 3 * w;
3284 if ((data = (l_uint8 *)LEPT_CALLOC((size_t)databpl * h, sizeof(l_uint8)))
3285 == NULL)
3286 return ERROR_INT("data not allocated", __func__, 1);
3287 *pdata = data;
3288 *pnbytes = (size_t)databpl * h;
3289
3290 for (i = 0; i < h; i++) {
3291 rline = rdata + i * wpl;
3292 line = data + i * databpl;
3293 if (d <= 8) {
3294 for (j = 0; j < databpl; j++)
3295 line[j] = GET_DATA_BYTE(rline, j);
3296 } else if (d == 16) {
3297 for (j = 0; j < w; j++)
3298 line[2 * j] = GET_DATA_TWO_BYTES(rline, j);
3299 } else { /* d == 32 bpp rgb */
3300 for (j = 0; j < w; j++) {
3301 extractRGBValues(rline[j], &rval, &gval, &bval);
3302 *(line + 3 * j) = rval;
3303 *(line + 3 * j + 1) = gval;
3304 *(line + 3 * j + 2) = bval;
3305 }
3306 }
3307 }
3308
3309 return 0;
3310}
3311
3312
3313/*-------------------------------------------------------------*
3314 * Infer resolution from image size *
3315 *-------------------------------------------------------------*/
3333l_ok
3335 l_float32 longside,
3336 l_int32 *pres)
3337{
3338l_int32 w, h, maxdim, res;
3339
3340 if (!pres)
3341 return ERROR_INT("&res not defined", __func__, 1);
3342 *pres = 300;
3343 if (!pix)
3344 return ERROR_INT("pix not defined", __func__, 1);
3345 if (longside <= 0.0)
3346 return ERROR_INT("longside not > 0", __func__, 1);
3347
3348 pixGetDimensions(pix, &w, &h, NULL);
3349 maxdim = L_MAX(w, h);
3350 res = (l_int32)(maxdim / longside + 0.5);
3351 res = L_MAX(res, 1); /* don't let it be 0 */
3352 if (res < 10)
3353 L_WARNING("low inferred resolution: %d ppi\n", __func__, res);
3354 if (res > 10000)
3355 L_WARNING("high inferred resolution: %d ppi\n", __func__, res);
3356 *pres = res;
3357 return 0;
3358}
3359
3360
3361/*-------------------------------------------------------------*
3362 * Test alpha component opaqueness *
3363 *-------------------------------------------------------------*/
3377l_ok
3379 l_int32 *popaque)
3380{
3381l_int32 w, h, wpl, i, j, alpha;
3382l_uint32 *data, *line;
3383
3384 if (!popaque)
3385 return ERROR_INT("&opaque not defined", __func__, 1);
3386 *popaque = FALSE;
3387 if (!pix)
3388 return ERROR_INT("&pix not defined", __func__, 1);
3389 if (pixGetDepth(pix) != 32)
3390 return ERROR_INT("&pix not 32 bpp", __func__, 1);
3391 if (pixGetSpp(pix) != 4)
3392 return ERROR_INT("&pix not 4 spp", __func__, 1);
3393
3394 data = pixGetData(pix);
3395 wpl = pixGetWpl(pix);
3396 pixGetDimensions(pix, &w, &h, NULL);
3397 for (i = 0; i < h; i++) {
3398 line = data + i * wpl;
3399 for (j = 0; j < w; j++) {
3400 alpha = GET_DATA_BYTE(line + j, L_ALPHA_CHANNEL);
3401 if (alpha ^ 0xff) /* not opaque */
3402 return 0;
3403 }
3404 }
3405
3406 *popaque = TRUE;
3407 return 0;
3408}
3409
3410
3411/*-------------------------------------------------------------*
3412 * Setup helpers for 8 bpp byte processing *
3413 *-------------------------------------------------------------*/
3440l_uint8 **
3442 l_int32 *pw,
3443 l_int32 *ph)
3444{
3445l_int32 w, h;
3446
3447 if (pw) *pw = 0;
3448 if (ph) *ph = 0;
3449 if (!pix || pixGetDepth(pix) != 8)
3450 return (l_uint8 **)ERROR_PTR("pix not defined or not 8 bpp",
3451 __func__, NULL);
3452 pixGetDimensions(pix, &w, &h, NULL);
3453 if (pw) *pw = w;
3454 if (ph) *ph = h;
3455 if (pixGetColormap(pix))
3456 return (l_uint8 **)ERROR_PTR("pix has colormap", __func__, NULL);
3457
3458 pixEndianByteSwap(pix);
3459 return (l_uint8 **)pixGetLinePtrs(pix, NULL);
3460}
3461
3462
3476l_ok
3478 l_uint8 **lineptrs)
3479{
3480 if (!pix)
3481 return ERROR_INT("pix not defined", __func__, 1);
3482 if (!lineptrs)
3483 return ERROR_INT("lineptrs not defined", __func__, 1);
3484
3485 pixEndianByteSwap(pix);
3486 LEPT_FREE(lineptrs);
3487 return 0;
3488}
3489
3490
3491/*------------------------------------------------------------------------*
3492 * Setting parameters for antialias masking with alpha transforms *
3493 *------------------------------------------------------------------------*/
3516void
3518 l_float32 val2)
3519{
3520 val1 = L_MAX(0.0, L_MIN(1.0, val1));
3521 val2 = L_MAX(0.0, L_MIN(1.0, val2));
3522 AlphaMaskBorderVals[0] = val1;
3523 AlphaMaskBorderVals[1] = val2;
3524}
#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:1623
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:1931
l_ok pixAlphaIsOpaque(PIX *pix, l_int32 *popaque)
pixAlphaIsOpaque()
Definition pix2.c:3378
PIX * pixAddContinuedBorder(PIX *pixs, l_int32 left, l_int32 right, l_int32 top, l_int32 bot)
pixAddContinuedBorder()
Definition pix2.c:2250
l_int32 lineEndianByteSwap(l_uint32 *datad, l_uint32 *datas, l_int32 wpl)
lineEndianByteSwap()
Definition pix2.c:3097
PIX * pixDisplayLayersRGBA(PIX *pixs, l_uint32 val, l_int32 maxw)
pixDisplayLayersRGBA()
Definition pix2.c:2340
l_uint8 ** pixSetupByteProcessing(PIX *pix, l_int32 *pw, l_int32 *ph)
pixSetupByteProcessing()
Definition pix2.c:3441
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:2151
l_int32 extractMinMaxComponent(l_uint32 pixel, l_int32 type)
extractMinMaxComponent()
Definition pix2.c:2836
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:2291
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:1977
l_ok pixGetRGBLine(PIX *pixs, l_int32 row, l_uint8 *bufr, l_uint8 *bufg, l_uint8 *bufb)
pixGetRGBLine()
Definition pix2.c:2870
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:3334
PIX * pixEndianByteSwapNew(PIX *pixs)
pixEndianByteSwapNew()
Definition pix2.c:2979
PIX * pixAddBlackOrWhiteBorder(PIX *pixs, l_int32 left, l_int32 right, l_int32 top, l_int32 bot, l_int32 op)
pixAddBlackOrWhiteBorder()
Definition pix2.c:1811
void extractRGBAValues(l_uint32 pixel, l_int32 *prval, l_int32 *pgval, l_int32 *pbval, l_int32 *paval)
extractRGBAValues()
Definition pix2.c:2815
l_ok pixEndianTwoByteSwap(PIX *pixs)
pixEndianTwoByteSwap()
Definition pix2.c:3200
PIX * pixCopyBorder(PIX *pixd, PIX *pixs, l_int32 left, l_int32 right, l_int32 top, l_int32 bot)
pixCopyBorder()
Definition pix2.c:1721
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:1521
l_ok pixCopyRGBComponent(PIX *pixd, PIX *pixs, l_int32 comp)
pixCopyRGBComponent()
Definition pix2.c:2669
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:3517
PIX * pixAddMixedBorder(PIX *pixs, l_int32 left, l_int32 right, l_int32 top, l_int32 bot)
pixAddMixedBorder()
Definition pix2.c:2205
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:1996
l_ok pixSetAll(PIX *pix)
pixSetAll()
Definition pix2.c:799
l_ok pixSetPadBits(PIX *pix, l_int32 val)
pixSetPadBits()
Definition pix2.c:1346
l_ok pixSetOrClearBorder(PIX *pixs, l_int32 left, l_int32 right, l_int32 top, l_int32 bot, l_int32 op)
pixSetOrClearBorder()
Definition pix2.c:1474
PIX * pixGetRGBComponentCmap(PIX *pixs, l_int32 comp)
pixGetRGBComponentCmap()
Definition pix2.c:2581
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:2758
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:2100
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:2728
l_ok pixCleanupByteProcessing(PIX *pix, l_uint8 **lineptrs)
pixCleanupByteProcessing()
Definition pix2.c:3477
void extractRGBValues(l_uint32 pixel, l_int32 *prval, l_int32 *pgval, l_int32 *pbval)
extractRGBValues()
Definition pix2.c:2793
l_ok setLineDataVal(l_uint32 *line, l_int32 j, l_int32 d, l_uint32 val)
setLineDataVal()
Definition pix2.c:2923
PIX * pixEndianTwoByteSwapNew(PIX *pixs)
pixEndianTwoByteSwapNew()
Definition pix2.c:3148
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:1672
l_ok pixSetPadBitsBand(PIX *pix, l_int32 by, l_int32 bh, l_int32 val)
pixSetPadBitsBand()
Definition pix2.c:1404
PIX * pixAddBorder(PIX *pixs, l_int32 npix, l_uint32 val)
pixAddBorder()
Definition pix2.c:1773
l_ok pixEndianByteSwap(PIX *pixs)
pixEndianByteSwap()
Definition pix2.c:3041
l_ok pixSetBlackOrWhite(PIX *pixs, l_int32 op)
pixSetBlackOrWhite()
Definition pix2.c:997
PIX * pixGetRGBComponent(PIX *pixs, l_int32 comp)
pixGetRGBComponent()
Definition pix2.c:2464
PIX * pixAddBorderGeneral(PIX *pixs, l_int32 left, l_int32 right, l_int32 top, l_int32 bot, l_uint32 val)
pixAddBorderGeneral()
Definition pix2.c:1863
l_ok pixSetRGBComponent(PIX *pixd, PIX *pixs, l_int32 comp)
pixSetRGBComponent()
Definition pix2.c:2521
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:2047
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:3252
PIX * pixCreateRGBImage(PIX *pixr, PIX *pixg, PIX *pixb)
pixCreateRGBImage()
Definition pix2.c:2410
@ L_GET_BLACK_VAL
Definition pix.h:709
@ L_GET_WHITE_VAL
Definition pix.h:708
@ 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
struct Pix PIX
Definition pix.h:228
struct Box BOX
Definition pix.h:252
#define PIX_SRC
Definition pix.h:444
#define PIX_CLR
Definition pix.h:447
struct PixColormap PIXCMAP
Definition pix.h:231
struct RGBA_Quad RGBA_QUAD
Definition pix.h:237
#define PIX_SET
Definition pix.h:448
@ 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
struct Pixa PIXA
Definition pix.h:243
l_uint32 * data
l_uint32 wpl
l_uint32 h
l_uint8 green
l_uint8 blue
l_uint8 red