101 #include <config_auto.h>
106 #include "allheaders.h"
109 l_int32 wpld, l_uint32 *datas, l_int32 wpls,
110 l_uint32 *bufs1, l_uint32 *bufs2,
111 l_int32 lowerclip, l_int32 upperclip);
113 l_int32 wpld, l_uint32 *datas, l_int32 d,
114 l_int32 wpls, l_int32 thresh);
115 static void ditherTo2bppLow(l_uint32 *datad, l_int32 w, l_int32 h, l_int32 wpld,
116 l_uint32 *datas, l_int32 wpls, l_uint32 *bufs1,
117 l_uint32 *bufs2, l_int32 *tabval, l_int32 *tab38,
120 l_uint32 *bufs2, l_int32 *tabval,
121 l_int32 *tab38, l_int32 *tab14,
122 l_int32 lastlineflag);
124 l_int32 **ptab14, l_int32 cliptoblack,
125 l_int32 cliptowhite);
127 l_uint32 *datas, l_int32 wpls, l_int32 *tab);
129 l_uint32 *datas, l_int32 wpls, l_int32 *tab);
132 l_int32 outdepth,
PIXCMAP **pcmap);
134 l_float32 minfract, l_int32 maxsize,
137 #ifndef NO_CONSOLE_IO
138 #define DEBUG_UNROLLING 0
178 return (
PIX *)ERROR_PTR(
"pixs not defined", __func__, NULL);
179 if (pixGetDepth(pixs) != 8)
180 return (
PIX *)ERROR_PTR(
"must be 8 bpp for dithering", __func__, NULL);
209 l_int32 w, h, d, wplt, wpld;
210 l_uint32 *datat, *datad;
211 l_uint32 *bufs1, *bufs2;
215 return (
PIX *)ERROR_PTR(
"pixs not defined", __func__, NULL);
218 return (
PIX *)ERROR_PTR(
"must be 8 bpp for dithering", __func__, NULL);
219 if (lowerclip < 0 || lowerclip > 255)
220 return (
PIX *)ERROR_PTR(
"invalid value for lowerclip", __func__, NULL);
221 if (upperclip < 0 || upperclip > 255)
222 return (
PIX *)ERROR_PTR(
"invalid value for upperclip", __func__, NULL);
225 return (
PIX *)ERROR_PTR(
"pixd not made", __func__, NULL);
226 pixCopyResolution(pixd, pixs);
227 pixCopyInputFormat(pixd, pixs);
229 wpld = pixGetWpl(pixd);
234 return (
PIX *)ERROR_PTR(
"pixt not made", __func__, NULL);
237 wplt = pixGetWpl(pixt);
240 bufs1 = (l_uint32 *)LEPT_CALLOC(wplt,
sizeof(l_uint32));
241 bufs2 = (l_uint32 *)LEPT_CALLOC(wplt,
sizeof(l_uint32));
242 if (!bufs1 || !bufs2) {
247 return (
PIX *)ERROR_PTR(
"bufs1, bufs2 not both made", __func__, NULL);
251 lowerclip, upperclip);
281 memcpy(bufs2, datas, 4 * wpls);
282 for (i = 0; i < h - 1; i++) {
283 memcpy(bufs1, bufs2, 4 * wpls);
284 memcpy(bufs2, datas + (i + 1) * wpls, 4 * wpls);
285 lined = datad + i * wpld;
290 memcpy(bufs1, bufs2, 4 * wpls);
291 lined = datad + (h - 1) * wpld;
328 l_int32 lastlineflag)
332 l_uint8 fval1, fval2, rval, bval, dval;
334 if (lastlineflag == 0) {
335 for (j = 0; j < w - 1; j++) {
338 if ((eval = 255 - oval) > upperclip) {
340 fval1 = (3 * eval) / 8;
343 rval = L_MAX(0, rval - fval1);
346 bval = L_MAX(0, bval - fval1);
349 dval = L_MAX(0, dval - fval2);
354 if (oval > lowerclip) {
356 fval1 = (3 * oval) / 8;
359 rval = L_MIN(255, rval + fval1);
362 bval = L_MIN(255, bval + fval1);
365 dval = L_MIN(255, dval + fval2);
374 if ((eval = 255 - oval) > upperclip) {
376 fval1 = (3 * eval) / 8;
378 bval = L_MAX(0, bval - fval1);
383 if (oval > lowerclip) {
385 fval1 = (3 * oval) / 8;
387 bval = L_MIN(255, bval + fval1);
392 for (j = 0; j < w - 1; j++) {
395 if ((eval = 255 - oval) > upperclip) {
397 fval1 = (3 * eval) / 8;
399 rval = L_MAX(0, rval - fval1);
404 if (oval > lowerclip) {
406 fval1 = (3 * oval) / 8;
408 rval = L_MIN(255, rval + fval1);
446 l_int32 d, w, h, wplt, wpld;
447 l_uint32 *datat, *datad;
451 return (
PIX *)ERROR_PTR(
"pixs not defined", __func__, NULL);
453 if (d != 4 && d != 8)
454 return (
PIX *)ERROR_PTR(
"pixs must be 4 or 8 bpp", __func__, NULL);
456 return (
PIX *)ERROR_PTR(
"thresh must be non-negative", __func__, NULL);
457 if (d == 4 && thresh > 16)
458 return (
PIX *)ERROR_PTR(
"4 bpp thresh not in {0-16}", __func__, NULL);
459 if (d == 8 && thresh > 256)
460 return (
PIX *)ERROR_PTR(
"8 bpp thresh not in {0-256}", __func__, NULL);
463 return (
PIX *)ERROR_PTR(
"pixd not made", __func__, NULL);
464 pixCopyResolution(pixd, pixs);
465 pixCopyInputFormat(pixd, pixs);
467 wpld = pixGetWpl(pixd);
473 wplt = pixGetWpl(pixt);
474 if (pixGetColormap(pixs) && d == 4) {
502 l_uint32 *lines, *lined;
504 for (i = 0; i < h; i++) {
505 lines = datas + i * wpls;
506 lined = datad + i * wpld;
507 thresholdToBinaryLineLow(lined, w, lines, d, thresh);
517 thresholdToBinaryLineLow(l_uint32 *lined,
523 l_int32 j, k, gval, scount, dcount;
524 l_uint32 sword, dword;
530 for (j = 0, scount = 0, dcount = 0; j + 31 < w; j += 32) {
532 for (k = 0; k < 4; k++) {
533 sword = lines[scount++];
535 gval = (sword >> 28) & 0xf;
542 dword |= ((gval - thresh) >> 24) & 128;
543 gval = (sword >> 24) & 0xf;
544 dword |= ((gval - thresh) >> 25) & 64;
545 gval = (sword >> 20) & 0xf;
546 dword |= ((gval - thresh) >> 26) & 32;
547 gval = (sword >> 16) & 0xf;
548 dword |= ((gval - thresh) >> 27) & 16;
549 gval = (sword >> 12) & 0xf;
550 dword |= ((gval - thresh) >> 28) & 8;
551 gval = (sword >> 8) & 0xf;
552 dword |= ((gval - thresh) >> 29) & 4;
553 gval = (sword >> 4) & 0xf;
554 dword |= ((gval - thresh) >> 30) & 2;
556 dword |= ((gval - thresh) >> 31) & 1;
558 lined[dcount++] = dword;
565 sword = lines[scount++];
567 gval = (sword >> 28) & 0xf;
569 dword |= (((gval - thresh) >> 31) & 1) << (31 - (j & 31));
571 lined[dcount] = dword;
574 #define CHECK_BIT(a, b, c) if (GET_DATA_BIT(a, b) != c) { \
575 lept_stderr("Error: mismatch at %d/%d(%d), %d vs %d\n", \
576 j, w, d, GET_DATA_BIT(a, b), c); }
577 for (j = 0; j < w; j++) {
579 CHECK_BIT(lined, j, gval < thresh ? 1 : 0);
585 for (j = 0, scount = 0, dcount = 0; j + 31 < w; j += 32) {
587 for (k = 0; k < 8; k++) {
588 sword = lines[scount++];
590 gval = (sword >> 24) & 0xff;
591 dword |= ((gval - thresh) >> 28) & 8;
592 gval = (sword >> 16) & 0xff;
593 dword |= ((gval - thresh) >> 29) & 4;
594 gval = (sword >> 8) & 0xff;
595 dword |= ((gval - thresh) >> 30) & 2;
597 dword |= ((gval - thresh) >> 31) & 1;
599 lined[dcount++] = dword;
606 sword = lines[scount++];
608 gval = (sword >> 24) & 0xff;
610 dword |= (l_uint64)(((gval - thresh) >> 31) & 1)
613 lined[dcount] = dword;
616 for (j = 0; j < w; j++) {
618 CHECK_BIT(lined, j, gval < thresh ? 1 : 0);
624 L_ERROR(
"src depth not 4 or 8 bpp\n", __func__);
650 l_int32 i, j, vals, valg, w, h, d, wpls, wplg, wpld;
651 l_uint32 *datas, *datag, *datad, *lines, *lineg, *lined;
655 return (
PIX *)ERROR_PTR(
"pixs not defined", __func__, NULL);
657 return (
PIX *)ERROR_PTR(
"pixg not defined", __func__, NULL);
659 return (
PIX *)ERROR_PTR(
"pix sizes not equal", __func__, NULL);
662 return (
PIX *)ERROR_PTR(
"pixs must be 8 bpp", __func__, NULL);
665 pixCopyResolution(pixd, pixs);
666 pixCopyInputFormat(pixd, pixs);
668 wpld = pixGetWpl(pixd);
670 wpls = pixGetWpl(pixs);
672 wplg = pixGetWpl(pixg);
673 for (i = 0; i < h; i++) {
674 lines = datas + i * wpls;
675 lineg = datag + i * wplg;
676 lined = datad + i * wpld;
677 for (j = 0; j < w; j++) {
724 if (!pixs || pixGetDepth(pixs) != 8)
725 return (
PIX *)ERROR_PTR(
"pixs undefined or not 8 bpp", __func__, NULL);
767 if (!pixs || pixGetDepth(pixs) != 8)
768 return (
PIX *)ERROR_PTR(
"pixs undefined or not 8 bpp", __func__, NULL);
771 return (
PIX *)ERROR_PTR(
"pix1 not made", __func__, NULL);
772 pixGammaTRC(pix1, pix1, gamma, blackval, whiteval);
806 l_int32 i, j, w, h, d, wplg, wpld;
807 l_uint32 *datag, *datad, *lineg, *lined;
811 return (
PIX *)ERROR_PTR(
"pixs not defined", __func__, NULL);
812 d = pixGetDepth(pixs);
813 if (d != 2 && d != 4 && d != 8)
814 return (
PIX *)ERROR_PTR(
"not 2, 4 or 8 bpp", __func__, NULL);
816 if (!usecmap && pixGetColormap(pixs))
821 if (d == 8 && (val < 0 || val > 255)) {
823 return (
PIX *)ERROR_PTR(
"val out of 8 bpp range", __func__, NULL);
825 if (d == 4 && (val < 0 || val > 15)) {
827 return (
PIX *)ERROR_PTR(
"val out of 4 bpp range", __func__, NULL);
829 if (d == 2 && (val < 0 || val > 3)) {
831 return (
PIX *)ERROR_PTR(
"val out of 2 bpp range", __func__, NULL);
835 pixCopyResolution(pixd, pixg);
836 pixCopyInputFormat(pixd, pixs);
838 wplg = pixGetWpl(pixg);
840 wpld = pixGetWpl(pixd);
841 for (i = 0; i < h; i++) {
842 lineg = datag + i * wplg;
843 lined = datad + i * wpld;
844 for (j = 0; j < w; j++) {
897 l_int32 i, j, w, h, d, wplg, wpld, val;
898 l_uint32 *datag, *datad, *lineg, *lined;
902 return (
PIX *)ERROR_PTR(
"pixs not defined", __func__, NULL);
903 d = pixGetDepth(pixs);
904 if (d != 2 && d != 4 && d != 8)
905 return (
PIX *)ERROR_PTR(
"not 2, 4 or 8 bpp", __func__, NULL);
906 if (lower < 0 || lower > upper)
907 return (
PIX *)ERROR_PTR(
"lower < 0 or lower > upper!", __func__, NULL);
909 if (!usecmap && pixGetColormap(pixs))
914 if (d == 8 && upper > 255) {
916 return (
PIX *)ERROR_PTR(
"d == 8 and upper > 255", __func__, NULL);
918 if (d == 4 && upper > 15) {
920 return (
PIX *)ERROR_PTR(
"d == 4 and upper > 15", __func__, NULL);
922 if (d == 2 && upper > 3) {
924 return (
PIX *)ERROR_PTR(
"d == 2 and upper > 3", __func__, NULL);
928 pixCopyResolution(pixd, pixg);
929 pixCopyInputFormat(pixd, pixs);
931 wplg = pixGetWpl(pixg);
933 wpld = pixGetWpl(pixd);
934 for (i = 0; i < h; i++) {
935 lineg = datag + i * wplg;
936 lined = datad + i * wpld;
937 for (j = 0; j < w; j++) {
945 if (val >= lower && val <= upper)
948 if (val < lower || val > upper)
1006 return (
PIX *)ERROR_PTR(
"pixs not defined", __func__, NULL);
1007 if (pixGetDepth(pixs) != 8)
1008 return (
PIX *)ERROR_PTR(
"must be 8 bpp for dithering", __func__, NULL);
1039 l_int32 w, h, d, wplt, wpld;
1040 l_int32 *tabval, *tab38, *tab14;
1041 l_uint32 *datat, *datad;
1042 l_uint32 *bufs1, *bufs2;
1047 return (
PIX *)ERROR_PTR(
"pixs not defined", __func__, NULL);
1050 return (
PIX *)ERROR_PTR(
"must be 8 bpp for dithering", __func__, NULL);
1051 if (lowerclip < 0 || lowerclip > 255)
1052 return (
PIX *)ERROR_PTR(
"invalid value for lowerclip", __func__, NULL);
1053 if (upperclip < 0 || upperclip > 255)
1054 return (
PIX *)ERROR_PTR(
"invalid value for upperclip", __func__, NULL);
1056 if ((pixd =
pixCreate(w, h, 2)) == NULL)
1057 return (
PIX *)ERROR_PTR(
"pixd not made", __func__, NULL);
1058 pixCopyResolution(pixd, pixs);
1059 pixCopyInputFormat(pixd, pixs);
1061 wpld = pixGetWpl(pixd);
1066 wplt = pixGetWpl(pixt);
1069 bufs1 = (l_uint32 *)LEPT_CALLOC(wplt,
sizeof(l_uint32));
1070 bufs2 = (l_uint32 *)LEPT_CALLOC(wplt,
sizeof(l_uint32));
1071 if (!bufs1 || !bufs2) {
1076 return (
PIX *)ERROR_PTR(
"bufs1, bufs2 not both made", __func__, NULL);
1083 tabval, tab38, tab14);
1131 memcpy(bufs2, datas, 4 * wpls);
1132 for (i = 0; i < h - 1; i++) {
1133 memcpy(bufs1, bufs2, 4 * wpls);
1134 memcpy(bufs2, datas + (i + 1) * wpls, 4 * wpls);
1135 lined = datad + i * wpld;
1140 memcpy(bufs1, bufs2, 4 * wpls);
1141 lined = datad + (h - 1) * wpld;
1180 l_int32 lastlineflag)
1183 l_int32 oval, tab38val, tab14val;
1184 l_uint8 rval, bval, dval;
1186 if (lastlineflag == 0) {
1187 for (j = 0; j < w - 1; j++) {
1193 tab38val = tab38[oval];
1194 tab14val = tab14[oval];
1196 rval = L_MAX(0, rval + tab38val);
1197 bval = L_MAX(0, bval + tab38val);
1198 dval = L_MAX(0, dval + tab14val);
1200 rval = L_MIN(255, rval + tab38val);
1201 bval = L_MIN(255, bval + tab38val);
1202 dval = L_MIN(255, dval + tab14val);
1213 tab38val = tab38[oval];
1215 bval = L_MAX(0, bval + tab38val);
1217 bval = L_MIN(255, bval + tab38val);
1220 for (j = 0; j < w - 1; j++) {
1224 tab38val = tab38[oval];
1226 rval = L_MAX(0, rval + tab38val);
1228 rval = L_MIN(255, rval + tab38val);
1254 l_int32 cliptoblack,
1255 l_int32 cliptowhite)
1258 l_int32 *tabval, *tab38, *tab14;
1261 tabval = (l_int32 *)LEPT_CALLOC(256,
sizeof(l_int32));
1262 tab38 = (l_int32 *)LEPT_CALLOC(256,
sizeof(l_int32));
1263 tab14 = (l_int32 *)LEPT_CALLOC(256,
sizeof(l_int32));
1268 for (i = 0; i < 256; i++) {
1269 if (i <= cliptoblack) {
1273 }
else if (i < 43) {
1275 tab38[i] = (3 * i + 4) / 8;
1276 tab14[i] = (i + 2) / 4;
1277 }
else if (i < 85) {
1279 tab38[i] = (3 * (i - 85) - 4) / 8;
1280 tab14[i] = ((i - 85) - 2) / 4;
1281 }
else if (i < 128) {
1283 tab38[i] = (3 * (i - 85) + 4) / 8;
1284 tab14[i] = ((i - 85) + 2) / 4;
1285 }
else if (i < 170) {
1287 tab38[i] = (3 * (i - 170) - 4) / 8;
1288 tab14[i] = ((i - 170) - 2) / 4;
1289 }
else if (i < 213) {
1291 tab38[i] = (3 * (i - 170) + 4) / 8;
1292 tab14[i] = ((i - 170) + 2) / 4;
1293 }
else if (i < 255 - cliptowhite) {
1295 tab38[i] = (3 * (i - 255) - 4) / 8;
1296 tab14[i] = ((i - 255) - 2) / 4;
1361 l_int32 w, h, d, wplt, wpld;
1362 l_uint32 *datat, *datad;
1367 return (
PIX *)ERROR_PTR(
"pixs not defined", __func__, NULL);
1370 return (
PIX *)ERROR_PTR(
"pixs not 8 bpp", __func__, NULL);
1371 if (nlevels < 2 || nlevels > 4)
1372 return (
PIX *)ERROR_PTR(
"nlevels not in {2, 3, 4}", __func__, NULL);
1374 if ((pixd =
pixCreate(w, h, 2)) == NULL)
1375 return (
PIX *)ERROR_PTR(
"pixd not made", __func__, NULL);
1376 pixCopyResolution(pixd, pixs);
1377 pixCopyInputFormat(pixd, pixs);
1379 wpld = pixGetWpl(pixd);
1389 wplt = pixGetWpl(pixt);
1425 l_uint8 sval1, sval2, sval3, sval4, dval;
1427 l_uint32 *lines, *lined;
1429 for (i = 0; i < h; i++) {
1430 lines = datas + i * wpls;
1431 lined = datad + i * wpld;
1432 for (j = 0; j < wpls; j++) {
1438 dval = (tab[sval1] << 6) | (tab[sval2] << 4) |
1439 (tab[sval3] << 2) | tab[sval4];
1501 l_int32 w, h, d, wplt, wpld;
1502 l_uint32 *datat, *datad;
1507 return (
PIX *)ERROR_PTR(
"pixs not defined", __func__, NULL);
1510 return (
PIX *)ERROR_PTR(
"pixs not 8 bpp", __func__, NULL);
1511 if (nlevels < 2 || nlevels > 16)
1512 return (
PIX *)ERROR_PTR(
"nlevels not in [2,...,16]", __func__, NULL);
1514 if ((pixd =
pixCreate(w, h, 4)) == NULL)
1515 return (
PIX *)ERROR_PTR(
"pixd not made", __func__, NULL);
1516 pixCopyResolution(pixd, pixs);
1517 pixCopyInputFormat(pixd, pixs);
1519 wpld = pixGetWpl(pixd);
1529 wplt = pixGetWpl(pixt);
1565 l_uint8 sval1, sval2, sval3, sval4;
1568 l_uint32 *lines, *lined;
1570 for (i = 0; i < h; i++) {
1571 lines = datas + i * wpls;
1572 lined = datad + i * wpld;
1573 for (j = 0; j < wpls; j++) {
1579 dval = (tab[sval1] << 12) | (tab[sval2] << 8) |
1580 (tab[sval3] << 4) | tab[sval4];
1616 l_int32 i, j, w, h, wpld, val, newval;
1617 l_uint32 *datad, *lined;
1622 return (
PIX *)ERROR_PTR(
"pixs not defined", __func__, NULL);
1623 if (pixGetDepth(pixs) != 8)
1624 return (
PIX *)ERROR_PTR(
"pixs not 8 bpp", __func__, NULL);
1625 if (nlevels < 2 || nlevels > 256)
1626 return (
PIX *)ERROR_PTR(
"nlevels not in [2,...,256]", __func__, NULL);
1629 if (pixGetColormap(pixs))
1645 pixCopyResolution(pixd, pixs);
1646 pixCopyInputFormat(pixd, pixs);
1648 wpld = pixGetWpl(pixd);
1649 for (i = 0; i < h; i++) {
1650 lined = datad + i * wpld;
1651 for (j = 0; j < w; j++) {
1711 const char *edgevals,
1713 l_int32 use_average,
1718 l_int32 w, h, d, i, j, n, wplt, wpld, val, newval;
1719 l_uint32 *datat, *datad, *linet, *lined;
1725 return (
PIX *)ERROR_PTR(
"pixs not defined", __func__, NULL);
1728 return (
PIX *)ERROR_PTR(
"pixs not 8 bpp", __func__, NULL);
1730 return (
PIX *)ERROR_PTR(
"edgevals not defined", __func__, NULL);
1731 if (outdepth != 0 && outdepth != 2 && outdepth != 4 && outdepth != 8)
1732 return (
PIX *)ERROR_PTR(
"invalid outdepth", __func__, NULL);
1739 return (
PIX *)ERROR_PTR(
"more than 256 levels", __func__, NULL);
1741 if (outdepth == 0) {
1748 }
else if (n + 1 > (1 << outdepth)) {
1749 L_WARNING(
"outdepth too small; setting to 8 bpp\n", __func__);
1763 if ((pixd =
pixCreate(w, h, outdepth)) == NULL) {
1766 return (
PIX *)ERROR_PTR(
"pixd not made", __func__, NULL);
1768 pixCopyResolution(pixd, pixs);
1769 pixCopyInputFormat(pixd, pixs);
1772 wpld = pixGetWpl(pixd);
1777 wplt = pixGetWpl(pixt);
1779 if (outdepth == 2) {
1781 }
else if (outdepth == 4) {
1784 for (i = 0; i < h; i++) {
1785 lined = datad + i * wpld;
1786 linet = datat + i * wplt;
1787 for (j = 0; j < w; j++) {
1821 l_int32 i, j, thresh;
1823 tab = (l_int32 *)LEPT_CALLOC(256,
sizeof(l_int32));
1824 for (i = 0; i < 256; i++) {
1825 for (j = 0; j < nlevels; j++) {
1826 thresh = 255 * (2 * j + 1) / (2 * nlevels - 2);
1871 l_int32 i, j, thresh, maxval, quantval;
1873 tab = (l_int32 *)LEPT_CALLOC(256,
sizeof(l_int32));
1874 maxval = (1 << depth) - 1;
1876 nlevels = 1 << depth;
1877 for (i = 0; i < 256; i++) {
1878 for (j = 0; j < nlevels; j++) {
1879 thresh = 255 * (2 * j + 1) / (2 * nlevels - 2);
1881 quantval = maxval * j / (nlevels - 1);
1925 l_int32 i, j, n, jstart, ave, val;
1930 return ERROR_INT(
"&tab not defined", __func__, 1);
1933 return ERROR_INT(
"&cmap not defined", __func__, 1);
1936 return ERROR_INT(
"na not defined", __func__, 1);
1938 if (n + 1 > (1 << outdepth))
1939 return ERROR_INT(
"more bins than cmap levels", __func__, 1);
1942 return ERROR_INT(
"cmap not made", __func__, 1);
1943 tab = (l_int32 *)LEPT_CALLOC(256,
sizeof(l_int32));
1949 for (i = 0; i < n; i++) {
1951 ave = (jstart + val) / 2;
1953 for (j = jstart; j < val; j++)
1959 ave = (jstart + 255) / 2;
1961 for (j = jstart; j < 256; j++)
1995 l_int32 i, j, index, w, h, d, nbins, wpl, factor, val;
1996 l_int32 *bincount, *binave, *binstart;
1997 l_uint32 *line, *data;
2000 return ERROR_INT(
"&cmap not defined", __func__, 1);
2003 return ERROR_INT(
"pixs not defined", __func__, 1);
2006 return ERROR_INT(
"pixs not 8 bpp", __func__, 1);
2008 return ERROR_INT(
"tab not defined", __func__, 1);
2009 nbins = tab[255] + 1;
2010 if (nbins > (1 << outdepth))
2011 return ERROR_INT(
"more bins than cmap levels", __func__, 1);
2014 if ((bincount = (l_int32 *)LEPT_CALLOC(nbins,
sizeof(l_int32))) == NULL)
2015 return ERROR_INT(
"calloc fail for bincount", __func__, 1);
2016 if ((binave = (l_int32 *)LEPT_CALLOC(nbins,
sizeof(l_int32))) == NULL) {
2017 LEPT_FREE(bincount);
2018 return ERROR_INT(
"calloc fail for binave", __func__, 1);
2020 factor = (l_int32)(sqrt((l_float64)(w * h) / 30000.) + 0.5);
2021 factor = L_MAX(1, factor);
2023 wpl = pixGetWpl(pixs);
2024 for (i = 0; i < h; i += factor) {
2025 line = data + i * wpl;
2026 for (j = 0; j < w; j += factor) {
2028 bincount[tab[val]]++;
2029 binave[tab[val]] += val;
2034 binstart = (l_int32 *)LEPT_CALLOC(nbins,
sizeof(l_int32));
2035 for (i = 1, index = 1; i < 256; i++) {
2036 if (tab[i] < index)
continue;
2037 if (tab[i] == index)
2038 binstart[index++] = i;
2044 for (i = 0; i < nbins; i++) {
2046 val = binave[i] / bincount[i];
2049 val = (binstart[i] + binstart[i + 1]) / 2;
2051 val = (binstart[i] + 255) / 2;
2056 LEPT_FREE(bincount);
2058 LEPT_FREE(binstart);
2100 l_int32 i, j, w, h, d, wpls, wpld;
2101 l_int32 rref, gref, bref, rval, gval, bval;
2102 l_int32 rmin, gmin, bmin, rmax, gmax, bmax;
2104 l_uint32 *datas, *datad, *lines, *lined;
2108 return (
PIX *)ERROR_PTR(
"pixs not defined", __func__, NULL);
2111 return (
PIX *)ERROR_PTR(
"not 32 bpp", __func__, NULL);
2112 if (delm < 0 || delp < 0)
2113 return (
PIX *)ERROR_PTR(
"delm and delp must be >= 0", __func__, NULL);
2114 if (fractm < 0.0 || fractm > 1.0 || fractp < 0.0 || fractp > 1.0)
2115 return (
PIX *)ERROR_PTR(
"fractm and/or fractp invalid", __func__, NULL);
2118 if (fractm == 0.0 && fractp == 0.0) {
2125 }
else if (delm == 0 && delp == 0) {
2126 rmin = (l_int32)((1.0 - fractm) * rref);
2127 gmin = (l_int32)((1.0 - fractm) * gref);
2128 bmin = (l_int32)((1.0 - fractm) * bref);
2129 rmax = rref + (l_int32)(fractp * (255 - rref));
2130 gmax = gref + (l_int32)(fractp * (255 - gref));
2131 bmax = bref + (l_int32)(fractp * (255 - bref));
2133 L_ERROR(
"bad input: either (delm, delp) or (fractm, fractp) "
2134 "must be 0\n", __func__);
2139 pixCopyResolution(pixd, pixs);
2140 pixCopyInputFormat(pixd, pixs);
2142 wpls = pixGetWpl(pixs);
2144 wpld = pixGetWpl(pixd);
2145 for (i = 0; i < h; i++) {
2146 lines = datas + i * wpls;
2147 lined = datad + i * wpld;
2148 for (j = 0; j < w; j++) {
2150 rval = (pixel >> L_RED_SHIFT) & 0xff;
2151 if (rval < rmin || rval > rmax)
2153 gval = (pixel >> L_GREEN_SHIFT) & 0xff;
2154 if (gval < gmin || gval > gmax)
2156 bval = (pixel >> L_BLUE_SHIFT) & 0xff;
2157 if (bval < bmin || bval > bmax)
2194 l_int32 i, j, w, h, d, wpls, wpld;
2195 l_int32 rref1, gref1, bref1, rref2, gref2, bref2, rval, gval, bval;
2196 l_uint32 pixel, dist1, dist2;
2197 l_uint32 *datas, *datad, *lines, *lined;
2201 return (
PIX *)ERROR_PTR(
"pixs not defined", __func__, NULL);
2204 return (
PIX *)ERROR_PTR(
"not 32 bpp", __func__, NULL);
2206 return (
PIX *)ERROR_PTR(
"invalid distflag", __func__, NULL);
2211 pixCopyResolution(pixd, pixs);
2212 pixCopyInputFormat(pixd, pixs);
2214 wpls = pixGetWpl(pixs);
2216 wpld = pixGetWpl(pixd);
2217 for (i = 0; i < h; i++) {
2218 lines = datas + i * wpls;
2219 lined = datad + i * wpld;
2220 for (j = 0; j < w; j++) {
2224 dist1 = L_ABS(rref1 - rval);
2225 dist2 = L_ABS(rref2 - rval);
2226 dist1 += L_ABS(gref1 - gval);
2227 dist2 += L_ABS(gref2 - gval);
2228 dist1 += L_ABS(bref1 - bval);
2229 dist2 += L_ABS(bref2 - bval);
2231 dist1 = (rref1 - rval) * (rref1 - rval);
2232 dist2 = (rref2 - rval) * (rref2 - rval);
2233 dist1 += (gref1 - gval) * (gref1 - gval);
2234 dist2 += (gref2 - gval) * (gref2 - gval);
2235 dist1 += (bref1 - bval) * (bref1 - bval);
2236 dist2 += (bref2 - bval) * (bref2 - bval);
2307 l_int32 w, h, wd, hd, wm, hm, wpls, wplm, wpld;
2308 l_int32 nc, nestim, i, j, vals, vald;
2310 l_uint32 *datas, *datam, *datad, *lines, *linem, *lined;
2315 if (!pixs || pixGetDepth(pixs) != 8)
2316 return (
PIX *)ERROR_PTR(
"pixs undefined or not 8 bpp", __func__, NULL);
2317 if (minfract < 0.01) {
2318 L_WARNING(
"minfract < 0.01; setting to 0.05\n", __func__);
2322 L_WARNING(
"maxsize < 2; setting to 10\n", __func__);
2325 if ((pixd && !pixm) || (!pixd && pixm))
2326 return (
PIX *)ERROR_PTR(
"(pixd,pixm) not defined together",
2330 if (pixGetDepth(pixm) != 1)
2331 return (
PIX *)ERROR_PTR(
"pixm not 1 bpp", __func__, NULL);
2332 if ((cmap = pixGetColormap(pixd)) == NULL)
2333 return (
PIX *)ERROR_PTR(
"pixd not cmapped", __func__, NULL);
2335 if (w != wd || h != hd)
2336 return (
PIX *)ERROR_PTR(
"pixs, pixd sizes differ", __func__, NULL);
2338 nestim = nc + (l_int32)(1.5 * 255 / maxsize);
2341 L_ERROR(
"Estimate %d colors!\n", __func__, nestim);
2342 return (
PIX *)ERROR_PTR(
"probably too many colors", __func__, NULL);
2345 if (w != wm || h != hm) {
2346 L_WARNING(
"mask and dest sizes not equal\n", __func__);
2359 pixCopyResolution(pixd, pixs);
2360 pixCopyInputFormat(pixd, pixs);
2368 L_ERROR(
"ran out of colors in cmap!\n", __func__);
2374 wpls = pixGetWpl(pixs);
2375 wpld = pixGetWpl(pixd);
2377 for (i = 0; i < h; i++) {
2378 lines = datas + i * wpls;
2379 lined = datad + i * wpld;
2380 for (j = 0; j < w; j++) {
2391 wplm = pixGetWpl(pixmr);
2392 for (i = 0; i < h; i++) {
2393 lines = datas + i * wpls;
2394 linem = datam + i * wplm;
2395 lined = datad + i * wpld;
2396 for (j = 0; j < w; j++) {
2437 l_int32 mincount, index, sum, wtsum, span, istart, i, val, ret;
2438 l_int32 *iahisto, *lut;
2442 return ERROR_INT(
"&lut not defined", __func__, 1);
2445 return ERROR_INT(
"na not defined", __func__, 1);
2447 return ERROR_INT(
"cmap not defined", __func__, 1);
2450 mincount = (l_int32)(minfract * total);
2452 lut = (l_int32 *)LEPT_CALLOC(256,
sizeof(l_int32));
2469 for (i = 0; i < 256; i++) {
2472 wtsum += i * iahisto[i];
2473 span = i - istart + 1;
2474 if (sum < mincount && span < maxsize)
2483 val = (l_int32)((l_float32)wtsum / (l_float32)sum + 0.5);
2490 if (istart < 256 && sum > 0) {
2491 span = 256 - istart;
2492 val = (l_int32)((l_float32)wtsum / (l_float32)sum + 0.5);
2524 l_int32 i, j, index, w, h, d, depth, wpls, wpld;
2525 l_int32 hascolor, vals, vald;
2527 l_uint32 *datas, *datad, *lines, *lined;
2532 return (
PIX *)ERROR_PTR(
"pixs not defined", __func__, NULL);
2533 if (pixGetColormap(pixs) != NULL) {
2534 L_WARNING(
"pixs already has a colormap; returning a copy\n", __func__);
2539 return (
PIX *)ERROR_PTR(
"pixs not 8 bpp", __func__, NULL);
2541 return (
PIX *)ERROR_PTR(
"cmap not defined", __func__, NULL);
2542 if (mindepth != 2 && mindepth != 4 && mindepth != 8)
2543 return (
PIX *)ERROR_PTR(
"invalid mindepth", __func__, NULL);
2548 L_WARNING(
"Converting colormap colors to gray\n", __func__);
2555 tab = (l_int32 *)LEPT_CALLOC(256,
sizeof(l_int32));
2556 for (i = 0; i < 256; i++) {
2562 depth = L_MAX(depth, mindepth);
2565 pixCopyResolution(pixd, pixs);
2566 pixCopyInputFormat(pixd, pixs);
2569 wpls = pixGetWpl(pixs);
2570 wpld = pixGetWpl(pixd);
2571 for (i = 0; i < h; i++) {
2572 lines = datas + i * wpls;
2573 lined = datad + i * wpld;
2574 for (j = 0; j < w; j++) {
2579 else if (depth == 4)
2611 pixDitherToBinaryLUT(
PIX *pixs,
2615 l_int32 w, h, d, wplt, wpld;
2616 l_int32 *tabval, *tab38, *tab14;
2617 l_uint32 *datat, *datad;
2618 l_uint32 *bufs1, *bufs2;
2622 return (
PIX *)ERROR_PTR(
"pixs not defined", __func__, NULL);
2625 return (
PIX *)ERROR_PTR(
"must be 8 bpp for dithering", __func__, NULL);
2631 if ((pixd =
pixCreate(w, h, 1)) == NULL)
2632 return (
PIX *)ERROR_PTR(
"pixd not made", __func__, NULL);
2633 pixCopyResolution(pixd, pixs);
2634 pixCopyInputFormat(pixd, pixs);
2636 wpld = pixGetWpl(pixd);
2641 wplt = pixGetWpl(pixt);
2644 bufs1 = (l_uint32 *)LEPT_CALLOC(wplt,
sizeof(l_uint32));
2645 bufs2 = (l_uint32 *)LEPT_CALLOC(wplt,
sizeof(l_uint32));
2646 if (!bufs1 || !bufs2) {
2651 return (
PIX *)ERROR_PTR(
"bufs1, bufs2 not both made", __func__, NULL);
2655 make8To1DitherTables(&tabval, &tab38, &tab14, lowerclip, upperclip);
2657 ditherToBinaryLUTLow(datad, w, h, wpld, datat, wplt, bufs1, bufs2,
2658 tabval, tab38, tab14);
2683 ditherToBinaryLUTLow(l_uint32 *datad,
2699 memcpy(bufs2, datas, 4 * wpls);
2700 for (i = 0; i < h - 1; i++) {
2701 memcpy(bufs1, bufs2, 4 * wpls);
2702 memcpy(bufs2, datas + (i + 1) * wpls, 4 * wpls);
2703 lined = datad + i * wpld;
2704 ditherToBinaryLineLUTLow(lined, w, bufs1, bufs2,
2705 tabval, tab38, tab14, 0);
2709 memcpy(bufs1, bufs2, 4 * wpls);
2710 lined = datad + (h - 1) * wpld;
2711 ditherToBinaryLineLUTLow(lined, w, bufs1, bufs2, tabval, tab38, tab14, 1);
2729 ditherToBinaryLineLUTLow(l_uint32 *lined,
2736 l_int32 lastlineflag)
2739 l_int32 oval, tab38val, tab14val;
2740 l_uint8 rval, bval, dval;
2742 if (lastlineflag == 0) {
2743 for (j = 0; j < w - 1; j++) {
2750 tab38val = tab38[oval];
2753 tab14val = tab14[oval];
2755 rval = L_MAX(0, rval + tab38val);
2756 bval = L_MAX(0, bval + tab38val);
2757 dval = L_MAX(0, dval + tab14val);
2759 rval = L_MIN(255, rval + tab38val);
2760 bval = L_MIN(255, bval + tab38val);
2761 dval = L_MIN(255, dval + tab14val);
2773 tab38val = tab38[oval];
2775 bval = L_MAX(0, bval + tab38val);
2777 }
else if (tab38val > 0 ) {
2778 bval = L_MIN(255, bval + tab38val);
2782 for (j = 0; j < w - 1; j++) {
2787 tab38val = tab38[oval];
2791 rval = L_MAX(0, rval + tab38val);
2793 rval = L_MIN(255, rval + tab38val);
2818 make8To1DitherTables(l_int32 **ptabval,
2825 l_int32 *tabval, *tab38, *tab14;
2827 if (ptabval) *ptabval = NULL;
2828 if (ptab38) *ptab38 = NULL;
2829 if (ptab14) *ptab14 = NULL;
2830 if (!ptabval || !ptab38 || !ptab14)
2831 return ERROR_INT(
"table ptrs not all defined", __func__, 1);
2834 tabval = (l_int32 *)LEPT_CALLOC(256,
sizeof(l_int32));
2835 tab38 = (l_int32 *)LEPT_CALLOC(256,
sizeof(l_int32));
2836 tab14 = (l_int32 *)LEPT_CALLOC(256,
sizeof(l_int32));
2837 if (!tabval || !tab38 || !tab14)
2838 return ERROR_INT(
"calloc failure to make small table", __func__, 1);
2843 for (i = 0; i < 256; i++) {
2844 if (i <= lowerclip) {
2848 }
else if (i < 128) {
2850 tab38[i] = (3 * i + 4) / 8;
2851 tab14[i] = (i + 2) / 4;
2852 }
else if (i < 255 - upperclip) {
2854 tab38[i] = (3 * (i - 255) + 4) / 8;
2855 tab14[i] = ((i - 255) + 2) / 4;
PIX * pixBackgroundNormSimple(PIX *pixs, PIX *pixim, PIX *pixg)
pixBackgroundNormSimple()
#define GET_DATA_QBIT(pdata, n)
#define SET_DATA_BIT(pdata, n)
#define SET_DATA_DIBIT(pdata, n, val)
#define SET_DATA_TWO_BYTES(pdata, n, val)
#define GET_DATA_BYTE(pdata, n)
#define GET_DATA_DIBIT(pdata, n)
#define SET_DATA_BYTE(pdata, n, val)
#define GET_DATA_BIT(pdata, n)
#define SET_DATA_QBIT(pdata, n, val)
void pixcmapDestroy(PIXCMAP **pcmap)
pixcmapDestroy()
l_ok pixcmapHasColor(PIXCMAP *cmap, l_int32 *pcolor)
pixcmapHasColor()
l_int32 pixcmapGetCount(const PIXCMAP *cmap)
pixcmapGetCount()
l_ok pixcmapSetBlackAndWhite(PIXCMAP *cmap, l_int32 setblack, l_int32 setwhite)
pixcmapSetBlackAndWhite()
PIXCMAP * pixcmapCreate(l_int32 depth)
pixcmapCreate()
PIXCMAP * pixcmapColorToGray(PIXCMAP *cmaps, l_float32 rwt, l_float32 gwt, l_float32 bwt)
pixcmapColorToGray()
l_ok pixcmapGetMinDepth(PIXCMAP *cmap, l_int32 *pmindepth)
pixcmapGetMinDepth()
PIXCMAP * pixcmapCreateLinear(l_int32 d, l_int32 nlevels)
pixcmapCreateLinear()
PIXCMAP * pixcmapCopy(const PIXCMAP *cmaps)
pixcmapCopy()
l_ok pixcmapAddColor(PIXCMAP *cmap, l_int32 rval, l_int32 gval, l_int32 bval)
pixcmapAddColor()
l_ok pixcmapGetNearestGrayIndex(PIXCMAP *cmap, l_int32 val, l_int32 *pindex)
pixcmapGetNearestGrayIndex()
PIX * pixGammaTRC(PIX *pixd, PIX *pixs, l_float32 gamma, l_int32 minval, l_int32 maxval)
pixGammaTRC()
PIX * pixGenerateMaskByBand32(PIX *pixs, l_uint32 refval, l_int32 delm, l_int32 delp, l_float32 fractm, l_float32 fractp)
pixGenerateMaskByBand32()
static void thresholdToBinaryLow(l_uint32 *datad, l_int32 w, l_int32 h, l_int32 wpld, l_uint32 *datas, l_int32 d, l_int32 wpls, l_int32 thresh)
thresholdToBinaryLow()
void ditherToBinaryLineLow(l_uint32 *lined, l_int32 w, l_uint32 *bufs1, l_uint32 *bufs2, l_int32 lowerclip, l_int32 upperclip, l_int32 lastlineflag)
ditherToBinaryLineLow()
PIX * pixThresholdTo2bpp(PIX *pixs, l_int32 nlevels, l_int32 cmapflag)
pixThresholdTo2bpp()
static l_int32 make8To2DitherTables(l_int32 **ptabval, l_int32 **ptab38, l_int32 **ptab14, l_int32 cliptoblack, l_int32 cliptowhite)
make8To2DitherTables()
PIX * pixThresholdTo4bpp(PIX *pixs, l_int32 nlevels, l_int32 cmapflag)
pixThresholdTo4bpp()
static void thresholdTo4bppLow(l_uint32 *datad, l_int32 h, l_int32 wpld, l_uint32 *datas, l_int32 wpls, l_int32 *tab)
thresholdTo4bppLow()
static l_int32 makeGrayQuantColormapArb(PIX *pixs, l_int32 *tab, l_int32 outdepth, PIXCMAP **pcmap)
makeGrayQuantColormapArb()
PIX * pixGrayQuantFromCmap(PIX *pixs, PIXCMAP *cmap, l_int32 mindepth)
pixGrayQuantFromCmap()
static void ditherTo2bppLow(l_uint32 *datad, l_int32 w, l_int32 h, l_int32 wpld, l_uint32 *datas, l_int32 wpls, l_uint32 *bufs1, l_uint32 *bufs2, l_int32 *tabval, l_int32 *tab38, l_int32 *tab14)
ditherTo2bppLow()
PIX * pixThresholdOn8bpp(PIX *pixs, l_int32 nlevels, l_int32 cmapflag)
pixThresholdOn8bpp()
PIX * pixDitherTo2bpp(PIX *pixs, l_int32 cmapflag)
pixDitherTo2bpp()
PIX * pixGenerateMaskByValue(PIX *pixs, l_int32 val, l_int32 usecmap)
pixGenerateMaskByValue()
l_int32 * makeGrayQuantIndexTable(l_int32 nlevels)
makeGrayQuantIndexTable()
PIX * pixAdaptThresholdToBinary(PIX *pixs, PIX *pixm, l_float32 gamma)
pixAdaptThresholdToBinary()
PIX * pixGenerateMaskByBand(PIX *pixs, l_int32 lower, l_int32 upper, l_int32 inband, l_int32 usecmap)
pixGenerateMaskByBand()
PIX * pixGenerateMaskByDiscr32(PIX *pixs, l_uint32 refval1, l_uint32 refval2, l_int32 distflag)
pixGenerateMaskByDiscr32()
static void ditherToBinaryLow(l_uint32 *datad, l_int32 w, l_int32 h, l_int32 wpld, l_uint32 *datas, l_int32 wpls, l_uint32 *bufs1, l_uint32 *bufs2, l_int32 lowerclip, l_int32 upperclip)
ditherToBinaryLow()
static l_int32 * makeGrayQuantTargetTable(l_int32 nlevels, l_int32 depth)
makeGrayQuantTargetTable()
PIX * pixThresholdGrayArb(PIX *pixs, const char *edgevals, l_int32 outdepth, l_int32 use_average, l_int32 setblack, l_int32 setwhite)
pixThresholdGrayArb()
PIX * pixVarThresholdToBinary(PIX *pixs, PIX *pixg)
pixVarThresholdToBinary()
PIX * pixDitherToBinarySpec(PIX *pixs, l_int32 lowerclip, l_int32 upperclip)
pixDitherToBinarySpec()
PIX * pixDitherTo2bppSpec(PIX *pixs, l_int32 lowerclip, l_int32 upperclip, l_int32 cmapflag)
pixDitherTo2bppSpec()
PIX * pixDitherToBinary(PIX *pixs)
pixDitherToBinary()
static l_int32 numaFillCmapFromHisto(NUMA *na, PIXCMAP *cmap, l_float32 minfract, l_int32 maxsize, l_int32 **plut)
numaFillCmapFromHisto()
static void thresholdTo2bppLow(l_uint32 *datad, l_int32 h, l_int32 wpld, l_uint32 *datas, l_int32 wpls, l_int32 *tab)
thresholdTo2bppLow()
l_ok makeGrayQuantTableArb(NUMA *na, l_int32 outdepth, l_int32 **ptab, PIXCMAP **pcmap)
makeGrayQuantTableArb()
static void ditherTo2bppLineLow(l_uint32 *lined, l_int32 w, l_uint32 *bufs1, l_uint32 *bufs2, l_int32 *tabval, l_int32 *tab38, l_int32 *tab14, l_int32 lastlineflag)
ditherTo2bppLineLow()
PIX * pixGrayQuantFromHisto(PIX *pixd, PIX *pixs, PIX *pixm, l_float32 minfract, l_int32 maxsize)
pixGrayQuantFromHisto()
PIX * pixThresholdToBinary(PIX *pixs, l_int32 thresh)
pixThresholdToBinary()
PIX * pixAdaptThresholdToBinaryGen(PIX *pixs, PIX *pixm, l_float32 gamma, l_int32 blackval, l_int32 whiteval, l_int32 thresh)
pixAdaptThresholdToBinaryGen()
NUMA * parseStringForNumbers(const char *str, const char *seps)
parseStringForNumbers()
void numaDestroy(NUMA **pna)
numaDestroy()
l_int32 numaGetCount(NUMA *na)
numaGetCount()
l_ok numaGetIValue(NUMA *na, l_int32 index, l_int32 *pival)
numaGetIValue()
l_int32 * numaGetIArray(NUMA *na)
numaGetIArray()
NUMA * numaSort(NUMA *naout, NUMA *nain, l_int32 sortorder)
numaSort()
l_ok numaGetSum(NUMA *na, l_float32 *psum)
numaGetSum()
l_uint32 * pixGetData(PIX *pix)
pixGetData()
l_ok pixSetColormap(PIX *pix, PIXCMAP *colormap)
pixSetColormap()
void pixDestroy(PIX **ppix)
pixDestroy()
l_ok pixGetDimensions(const PIX *pix, l_int32 *pw, l_int32 *ph, l_int32 *pd)
pixGetDimensions()
l_int32 pixSizesEqual(const PIX *pix1, const PIX *pix2)
pixSizesEqual()
PIX * pixCopy(PIX *pixd, const PIX *pixs)
pixCopy()
PIX * pixCreateTemplate(const PIX *pixs)
pixCreateTemplate()
PIX * pixCreate(l_int32 width, l_int32 height, l_int32 depth)
pixCreate()
PIX * pixClone(PIX *pixs)
pixClone()
void extractRGBValues(l_uint32 pixel, l_int32 *prval, l_int32 *pgval, l_int32 *pbval)
extractRGBValues()
NUMA * pixGetGrayHistogramMasked(PIX *pixs, PIX *pixm, l_int32 x, l_int32 y, l_int32 factor)
pixGetGrayHistogramMasked()
@ REMOVE_CMAP_TO_GRAYSCALE
PIX * pixRemoveColormap(PIX *pixs, l_int32 type)
pixRemoveColormap()
l_ok pixRasterop(PIX *pixd, l_int32 dx, l_int32 dy, l_int32 dw, l_int32 dh, l_int32 op, PIX *pixs, l_int32 sx, l_int32 sy)
pixRasterop()
void lept_stderr(const char *fmt,...)
lept_stderr()