118 #include "allheaders.h" 169 static const l_int32 CQ_NLEVELS = 5;
170 static const l_int32 CQ_RESERVED_COLORS = 64;
172 static const l_int32 EXTRA_RESERVED_COLORS = 25;
173 static const l_int32 TREE_GEN_WIDTH = 350;
174 static const l_int32 MIN_DITHER_SIZE = 250;
194 l_int32 rcum, gcum, bcum;
195 l_int32 rval, gval, bval;
227 static const l_int32 FIXED_DIF_CAP = 0;
228 static const l_int32 POP_DIF_CAP = 40;
233 l_int32 *pindex, l_int32 *prval,
234 l_int32 *pgval, l_int32 *pbval);
238 l_int32 reservedcolors,
247 l_int32 *prval, l_int32 *pgval, l_int32 *pbval);
249 l_int32 *pbindex, l_int32 *psindex);
254 l_uint32 *gtab, l_uint32 *btab,
255 l_int32 *carray, l_int32 difcap);
259 l_int32 mindepth, l_int32 *cmaptab,
260 l_uint32 *rtab, l_uint32 *gtab,
263 #ifndef NO_CONSOLE_IO 264 #define DEBUG_COLORQUANT 0 265 #define DEBUG_OCTINDEX 0 266 #define DEBUG_OCTCUBE_CMAP 0 268 #define DEBUG_FEW_COLORS 0 269 #define PRINT_OCTCUBE_STATS 0 539 PROCNAME(
"pixOctreeColorQuant");
542 return (
PIX *)ERROR_PTR(
"pixs not defined", procName, NULL);
543 if (pixGetDepth(pixs) != 32)
544 return (
PIX *)ERROR_PTR(
"pixs not 32 bpp", procName, NULL);
545 if (colors < 128 || colors > 240)
546 return (
PIX *)ERROR_PTR(
"colors must be in [128, 240]", procName, NULL);
604 l_float32 validthresh,
605 l_float32 colorthresh)
607 l_int32 w, h, minside, factor, index, rval, gval, bval;
608 l_float32 scalefactor;
610 l_float32 colorfract;
615 PROCNAME(
"pixOctreeColorQuantGeneral");
618 return (
PIX *)ERROR_PTR(
"pixs not defined", procName, NULL);
619 if (pixGetDepth(pixs) != 32)
620 return (
PIX *)ERROR_PTR(
"pixs not 32 bpp", procName, NULL);
621 if (colors < 128 || colors > 240)
622 return (
PIX *)ERROR_PTR(
"colors must be in [128, 240]", procName, NULL);
631 if (validthresh > 0.0 && colorthresh > 0.0) {
632 minside = L_MIN(w, h);
633 factor = L_MAX(1, minside / 400);
635 if (pixfract * colorfract < validthresh * colorthresh) {
636 L_INFO(
"\n Pixel fraction neither white nor black = %6.3f" 637 "\n Color fraction of those pixels = %6.3f" 638 "\n Quantizing to 8 bpp gray\n",
639 procName, pixfract, colorfract);
643 L_INFO(
"\n Process in color by default\n", procName);
647 if (w > TREE_GEN_WIDTH) {
648 scalefactor = (l_float32)TREE_GEN_WIDTH / (l_float32)w;
655 if (w < MIN_DITHER_SIZE && h < MIN_DITHER_SIZE)
656 colors = L_MIN(colors, 220);
662 return (
PIX *)ERROR_PTR(
"tree not made", procName, NULL);
665 L_INFO(
" Colors requested = %d\n", procName, colors);
666 L_INFO(
" Actual colors = %d\n", procName, cmap->
n);
670 if (w < MIN_DITHER_SIZE && h < MIN_DITHER_SIZE && ditherflag == 1) {
671 L_INFO(
"Small image: dithering turned off\n", procName);
681 return (
PIX *)ERROR_PTR(
"pixd not made", procName, NULL);
686 pixCopyResolution(pixd, pixs);
687 pixCopyInputFormat(pixd, pixs);
692 if (rval < 5 && gval < 5 && bval < 5)
698 if (rval > 251 && gval > 251 && bval > 251)
726 l_int32 reservedcolors,
729 l_int32 rval, gval, bval, cindex;
730 l_int32 level, ncells, octindex;
737 l_float32 thresholdFactor[] = {0.01f, 0.01f, 1.0f, 1.0f, 1.0f, 1.0f};
739 l_uint32 *datas, *lines;
740 l_uint32 *rtab, *gtab, *btab;
748 PROCNAME(
"octreeGenerateAndPrune");
751 return (
CQCELL ***)ERROR_PTR(
"pixs not defined", procName, NULL);
752 if (pixGetDepth(pixs) != 32)
753 return (
CQCELL ***)ERROR_PTR(
"pixs must be 32 bpp", procName, NULL);
754 if (colors < 128 || colors > 256)
755 return (
CQCELL ***)ERROR_PTR(
"colors not in [128,256]", procName, NULL);
757 return (
CQCELL ***)ERROR_PTR(
"&cmap not defined", procName, NULL);
760 return (
CQCELL ***)ERROR_PTR(
"cqcaa not made", procName, NULL);
763 rtab = gtab = btab = NULL;
772 ncolor = colors - reservedcolors - EXTRA_RESERVED_COLORS;
775 wpls = pixGetWpl(pixs);
778 ncells = 1 << (3 * CQ_NLEVELS);
779 cqca = cqcaa[CQ_NLEVELS];
780 for (i = 0; i < h; i++) {
781 lines = datas + i * wpls;
782 for (j = 0; j < w; j++) {
784 octindex = rtab[rval] | gtab[gval] | btab[bval];
785 cqc = cqca[octindex];
795 for (level = CQ_NLEVELS - 1; level >= 2; level--) {
796 thresh = thresholdFactor[level];
798 cqcasub = cqcaa[level + 1];
799 ncells = 1 << (3 * level);
800 for (i = 0; i < ncells; i++) {
802 for (j = 0; j < 8; j++) {
804 cqcsub = cqcasub[isub];
805 if (cqcsub->bleaf == 1) {
809 if (cqcsub->n >= thresh * ppc) {
812 cqcsub->index = cmap->
n;
822 L_ERROR(
"assigning pixels to wrong color\n", procName);
824 cqcsub->index = cindex;
835 else if (ncolor + reservedcolors > 0)
836 ppc = npix / (ncolor + reservedcolors);
841 #if DEBUG_OCTCUBE_CMAP 842 fprintf(stderr,
"Exceeds threshold: colors used = %d, colors remaining = %d\n",
843 cmap->
n, ncolor + reservedcolors);
844 fprintf(stderr,
" cell with %d pixels, npix = %d, ppc = %d\n",
845 cqcsub->n, npix, ppc);
846 fprintf(stderr,
" index = %d, level = %d, subindex = %d\n",
848 fprintf(stderr,
" rv = %d, gv = %d, bv = %d\n", rv, gv, bv);
853 if (cqc->nleaves > 0 || level == 2) {
855 if (cqc->nleaves < 8) {
857 for (j = 0; j < 8; j++) {
859 cqcsub = cqcasub[isub];
860 if (cqcsub->bleaf == 0)
864 cqc->index = cmap->
n;
873 L_WARNING(
"possibly assigned pixels to wrong color\n",
889 else if (ncolor + reservedcolors > 0)
890 ppc = npix / (ncolor + reservedcolors);
895 #if DEBUG_OCTCUBE_CMAP 896 fprintf(stderr,
"By remainder: colors used = %d, colors remaining = %d\n",
897 cmap->
n, ncolor + reservedcolors);
898 fprintf(stderr,
" cell with %d pixels, npix = %d, ppc = %d\n",
900 fprintf(stderr,
" index = %d, level = %d\n", i, level);
901 fprintf(stderr,
" rv = %d, gv = %d, bv = %d\n", rv, gv, bv);
906 for (j = 0; j < 8; j++) {
908 cqcsub = cqcasub[isub];
915 #if PRINT_OCTCUBE_STATS 917 l_int32 tc[] = {0, 0, 0, 0, 0, 0, 0};
918 l_int32 rc[] = {0, 0, 0, 0, 0, 0, 0};
919 l_int32 nt, nr, ival;
923 for (i = 0; i < nt; i++) {
927 for (i = 0; i < nr; i++) {
931 fprintf(stderr,
" Threshold cells formed: %d\n", nt);
932 for (i = 1; i < CQ_NLEVELS + 1; i++)
933 fprintf(stderr,
" level %d: %d\n", i, tc[i]);
934 fprintf(stderr,
"\n Residual cells formed: %d\n", nr);
935 for (i = 0; i < CQ_NLEVELS ; i++)
936 fprintf(stderr,
" level %d: %d\n", i, rc[i]);
978 l_uint8 *bufu8r, *bufu8g, *bufu8b;
979 l_int32 rval, gval, bval;
980 l_int32 octindex, index;
981 l_int32 val1, val2, val3, dif;
982 l_int32 w, h, wpls, wpld, i, j, success;
984 l_int32 *buf1r, *buf1g, *buf1b, *buf2r, *buf2g, *buf2b;
985 l_uint32 *rtab, *gtab, *btab;
986 l_uint32 *datas, *datad, *lines, *lined;
989 PROCNAME(
"pixOctreeQuantizePixels");
992 return (
PIX *)ERROR_PTR(
"pixs not defined", procName, NULL);
993 if (pixGetDepth(pixs) != 32)
994 return (
PIX *)ERROR_PTR(
"pixs must be 32 bpp", procName, NULL);
996 return (
PIX *)ERROR_PTR(
"cqcaa not defined", procName, NULL);
1001 wpls = pixGetWpl(pixs);
1002 if ((pixd =
pixCreate(w, h, 8)) == NULL)
1003 return (
PIX *)ERROR_PTR(
"pixd not made", procName, NULL);
1004 pixCopyResolution(pixd, pixs);
1005 pixCopyInputFormat(pixd, pixs);
1007 wpld = pixGetWpl(pixd);
1010 rtab = gtab = btab = NULL;
1018 if (ditherflag == 0) {
1019 for (i = 0; i < h; i++) {
1020 lines = datas + i * wpls;
1021 lined = datad + i * wpld;
1022 for (j = 0; j < w; j++) {
1024 octindex = rtab[rval] | gtab[gval] | btab[bval];
1031 bufu8r = bufu8g = bufu8b = NULL;
1032 buf1r = buf1g = buf1b = buf2r = buf2g = buf2b = NULL;
1033 bufu8r = (l_uint8 *)LEPT_CALLOC(w,
sizeof(l_uint8));
1034 bufu8g = (l_uint8 *)LEPT_CALLOC(w,
sizeof(l_uint8));
1035 bufu8b = (l_uint8 *)LEPT_CALLOC(w,
sizeof(l_uint8));
1036 buf1r = (l_int32 *)LEPT_CALLOC(w,
sizeof(l_int32));
1037 buf1g = (l_int32 *)LEPT_CALLOC(w,
sizeof(l_int32));
1038 buf1b = (l_int32 *)LEPT_CALLOC(w,
sizeof(l_int32));
1039 buf2r = (l_int32 *)LEPT_CALLOC(w,
sizeof(l_int32));
1040 buf2g = (l_int32 *)LEPT_CALLOC(w,
sizeof(l_int32));
1041 buf2b = (l_int32 *)LEPT_CALLOC(w,
sizeof(l_int32));
1042 if (!bufu8r || !bufu8g || !bufu8b || !buf1r || !buf1g ||
1043 !buf1b || !buf2r || !buf2g || !buf2b) {
1044 L_ERROR(
"buffer not made\n", procName);
1046 goto buffer_cleanup;
1051 for (j = 0; j < w; j++) {
1052 buf2r[j] = 64 * bufu8r[j];
1053 buf2g[j] = 64 * bufu8g[j];
1054 buf2b[j] = 64 * bufu8b[j];
1057 for (i = 0; i < h - 1; i++) {
1059 memcpy(buf1r, buf2r, 4 * w);
1060 memcpy(buf1g, buf2g, 4 * w);
1061 memcpy(buf1b, buf2b, 4 * w);
1063 for (j = 0; j < w; j++) {
1064 buf2r[j] = 64 * bufu8r[j];
1065 buf2g[j] = 64 * bufu8g[j];
1066 buf2b[j] = 64 * bufu8b[j];
1070 lined = datad + i * wpld;
1071 for (j = 0; j < w - 1; j++) {
1072 rval = buf1r[j] / 64;
1073 gval = buf1g[j] / 64;
1074 bval = buf1b[j] / 64;
1075 octindex = rtab[rval] | gtab[gval] | btab[bval];
1079 dif = buf1r[j] / 8 - 8 * rc;
1081 val1 = buf1r[j + 1] + 3 * dif;
1082 val2 = buf2r[j] + 3 * dif;
1083 val3 = buf2r[j + 1] + 2 * dif;
1085 buf1r[j + 1] = L_MIN(16383, val1);
1086 buf2r[j] = L_MIN(16383, val2);
1087 buf2r[j + 1] = L_MIN(16383, val3);
1089 buf1r[j + 1] = L_MAX(0, val1);
1090 buf2r[j] = L_MAX(0, val2);
1091 buf2r[j + 1] = L_MAX(0, val3);
1095 dif = buf1g[j] / 8 - 8 * gc;
1097 val1 = buf1g[j + 1] + 3 * dif;
1098 val2 = buf2g[j] + 3 * dif;
1099 val3 = buf2g[j + 1] + 2 * dif;
1101 buf1g[j + 1] = L_MIN(16383, val1);
1102 buf2g[j] = L_MIN(16383, val2);
1103 buf2g[j + 1] = L_MIN(16383, val3);
1105 buf1g[j + 1] = L_MAX(0, val1);
1106 buf2g[j] = L_MAX(0, val2);
1107 buf2g[j + 1] = L_MAX(0, val3);
1111 dif = buf1b[j] / 8 - 8 * bc;
1113 val1 = buf1b[j + 1] + 3 * dif;
1114 val2 = buf2b[j] + 3 * dif;
1115 val3 = buf2b[j + 1] + 2 * dif;
1117 buf1b[j + 1] = L_MIN(16383, val1);
1118 buf2b[j] = L_MIN(16383, val2);
1119 buf2b[j + 1] = L_MIN(16383, val3);
1121 buf1b[j + 1] = L_MAX(0, val1);
1122 buf2b[j] = L_MAX(0, val2);
1123 buf2b[j + 1] = L_MAX(0, val3);
1129 rval = buf1r[w - 1] / 64;
1130 gval = buf1g[w - 1] / 64;
1131 bval = buf1b[w - 1] / 64;
1132 octindex = rtab[rval] | gtab[gval] | btab[bval];
1138 lined = datad + (h - 1) * wpld;
1139 for (j = 0; j < w; j++) {
1140 rval = buf2r[j] / 64;
1141 gval = buf2g[j] / 64;
1142 bval = buf2b[j] / 64;
1143 octindex = rtab[rval] | gtab[gval] | btab[bval];
1198 l_int32 baseindex, subindex;
1202 for (level = 2; level < CQ_NLEVELS; level++) {
1204 cqc = cqcaa[level][baseindex];
1205 cqcsub = cqcaa[level + 1][subindex];
1206 if (cqcsub->bleaf == 0) {
1207 *pindex = cqc->index;
1212 }
else if (level == CQ_NLEVELS - 1) {
1213 *pindex = cqcsub->index;
1214 *prval = cqcsub->rc;
1215 *pgval = cqcsub->gc;
1216 *pbval = cqcsub->bc;
1223 for (level = 2; level < CQ_NLEVELS; level++) {
1226 cqc = cqcaa[level][baseindex];
1227 cqcsub = cqcaa[level + 1][subindex];
1228 if (cqcsub->bleaf == 0) {
1230 *pindex = cqc->index;
1235 }
else if (level == CQ_NLEVELS - 1) {
1237 *pindex = cqcsub->index;
1262 l_int32 level, ncells, i;
1266 PROCNAME(
"cqcellTreeCreate");
1269 if ((cqcaa = (
CQCELL ***)LEPT_CALLOC(CQ_NLEVELS + 1,
sizeof(
CQCELL **)))
1271 return (
CQCELL ***)ERROR_PTR(
"cqcaa not made", procName, NULL);
1272 for (level = 0; level <= CQ_NLEVELS; level++) {
1273 ncells = 1 << (3 * level);
1274 if ((cqca = (
CQCELL **)LEPT_CALLOC(ncells,
sizeof(
CQCELL *))) == NULL) {
1276 return (
CQCELL ***)ERROR_PTR(
"cqca not made", procName, NULL);
1278 cqcaa[level] = cqca;
1279 for (i = 0; i < ncells; i++) {
1280 if ((cqca[i] = (
CQCELL *)LEPT_CALLOC(1,
sizeof(
CQCELL))) == NULL) {
1282 return (
CQCELL ***)ERROR_PTR(
"cqc not made", procName, NULL);
1299 l_int32 level, ncells, i;
1303 PROCNAME(
"cqcellTreeDestroy");
1305 if (pcqcaa == NULL) {
1306 L_WARNING(
"ptr address is NULL\n", procName);
1310 if ((cqcaa = *pcqcaa) == NULL)
1313 for (level = 0; level <= CQ_NLEVELS; level++) {
1314 cqca = cqcaa[level];
1315 ncells = 1 << (3 * level);
1316 for (i = 0; i < ncells; i++)
1367 l_uint32 *rtab, *gtab, *btab;
1369 PROCNAME(
"makeRGBToIndexTables");
1371 if (cqlevels < 1 || cqlevels > 6)
1372 return ERROR_INT(
"cqlevels must be in {1,...6}", procName, 1);
1374 if (!prtab || !pgtab || !pbtab)
1375 return ERROR_INT(
"not all &tabs defined", procName, 1);
1376 rtab = (l_uint32 *)LEPT_CALLOC(256,
sizeof(l_uint32));
1377 gtab = (l_uint32 *)LEPT_CALLOC(256,
sizeof(l_uint32));
1378 btab = (l_uint32 *)LEPT_CALLOC(256,
sizeof(l_uint32));
1379 if (!rtab || !gtab || !btab)
1380 return ERROR_INT(
"calloc fail for tab", procName, 1);
1388 for (i = 0; i < 256; i++) {
1389 rtab[i] = (i >> 5) & 0x0004;
1390 gtab[i] = (i >> 6) & 0x0002;
1395 for (i = 0; i < 256; i++) {
1396 rtab[i] = ((i >> 2) & 0x0020) | ((i >> 4) & 0x0004);
1397 gtab[i] = ((i >> 3) & 0x0010) | ((i >> 5) & 0x0002);
1398 btab[i] = ((i >> 4) & 0x0008) | ((i >> 6) & 0x0001);
1402 for (i = 0; i < 256; i++) {
1403 rtab[i] = ((i << 1) & 0x0100) | ((i >> 1) & 0x0020) |
1404 ((i >> 3) & 0x0004);
1405 gtab[i] = (i & 0x0080) | ((i >> 2) & 0x0010) |
1406 ((i >> 4) & 0x0002);
1407 btab[i] = ((i >> 1) & 0x0040) | ((i >> 3) & 0x0008) |
1408 ((i >> 5) & 0x0001);
1412 for (i = 0; i < 256; i++) {
1413 rtab[i] = ((i << 4) & 0x0800) | ((i << 2) & 0x0100) |
1414 (i & 0x0020) | ((i >> 2) & 0x0004);
1415 gtab[i] = ((i << 3) & 0x0400) | ((i << 1) & 0x0080) |
1416 ((i >> 1) & 0x0010) | ((i >> 3) & 0x0002);
1417 btab[i] = ((i << 2) & 0x0200) | (i & 0x0040) |
1418 ((i >> 2) & 0x0008) | ((i >> 4) & 0x0001);
1422 for (i = 0; i < 256; i++) {
1423 rtab[i] = ((i << 7) & 0x4000) | ((i << 5) & 0x0800) |
1424 ((i << 3) & 0x0100) | ((i << 1) & 0x0020) |
1425 ((i >> 1) & 0x0004);
1426 gtab[i] = ((i << 6) & 0x2000) | ((i << 4) & 0x0400) |
1427 ((i << 2) & 0x0080) | (i & 0x0010) |
1428 ((i >> 2) & 0x0002);
1429 btab[i] = ((i << 5) & 0x1000) | ((i << 3) & 0x0200) |
1430 ((i << 1) & 0x0040) | ((i >> 1) & 0x0008) |
1431 ((i >> 3) & 0x0001);
1435 for (i = 0; i < 256; i++) {
1436 rtab[i] = ((i << 10) & 0x20000) | ((i << 8) & 0x4000) |
1437 ((i << 6) & 0x0800) | ((i << 4) & 0x0100) |
1438 ((i << 2) & 0x0020) | (i & 0x0004);
1439 gtab[i] = ((i << 9) & 0x10000) | ((i << 7) & 0x2000) |
1440 ((i << 5) & 0x0400) | ((i << 3) & 0x0080) |
1441 ((i << 1) & 0x0010) | ((i >> 1) & 0x0002);
1442 btab[i] = ((i << 8) & 0x8000) | ((i << 6) & 0x1000) |
1443 ((i << 4) & 0x0200) | ((i << 2) & 0x0040) |
1444 (i & 0x0008) | ((i >> 2) & 0x0001);
1448 ERROR_INT(
"cqlevels not in [1...6]", procName, 1);
1478 *pindex = rtab[rval] | gtab[gval] | btab[bval];
1526 rgbindex = cubeindex << (3 * (7 - level));
1527 rgbindex |= (0x7 << (3 * (6 - level)));
1530 *prval = ((rgbindex >> 13) & 0x80) |
1531 ((rgbindex >> 11) & 0x40) |
1532 ((rgbindex >> 9) & 0x20) |
1533 ((rgbindex >> 7) & 0x10) |
1534 ((rgbindex >> 5) & 0x08) |
1535 ((rgbindex >> 3) & 0x04) |
1536 ((rgbindex >> 1) & 0x02);
1537 *pgval = ((rgbindex >> 12) & 0x80) |
1538 ((rgbindex >> 10) & 0x40) |
1539 ((rgbindex >> 8) & 0x20) |
1540 ((rgbindex >> 6) & 0x10) |
1541 ((rgbindex >> 4) & 0x08) |
1542 ((rgbindex >> 2) & 0x04) |
1544 *pbval = ((rgbindex >> 11) & 0x80) |
1545 ((rgbindex >> 9) & 0x40) |
1546 ((rgbindex >> 7) & 0x20) |
1547 ((rgbindex >> 5) & 0x10) |
1548 ((rgbindex >> 3) & 0x08) |
1549 ((rgbindex >> 1) & 0x04) |
1550 ((rgbindex << 1) & 0x02);
1598 PROCNAME(
"getOctcubeIndex");
1600 if (level < 0 || level > CQ_NLEVELS - 1)
1601 return ERROR_INT(
"level must be in e.g., [0 ... 5]", procName, 1);
1603 return ERROR_INT(
"&bindex not defined", procName, 1);
1605 return ERROR_INT(
"&sindex not defined", procName, 1);
1607 *pbindex = rgbindex >> (3 * (CQ_NLEVELS - level));
1608 *psindex = rgbindex >> (3 * (CQ_NLEVELS - 1 - level));
1630 PROCNAME(
"octcubeGetCount");
1633 return ERROR_INT(
"&size not defined", procName, 1);
1634 if (level < 1 || level > 6)
1635 return ERROR_INT(
"invalid level", procName, 1);
1637 *psize = 1 << (3 * level);
1705 l_int32 w, h, wpls, wpld, i, j, depth, size, ncolors, index;
1706 l_int32 rval, gval, bval;
1707 l_int32 *rarray, *garray, *barray, *narray, *iarray;
1708 l_uint32 octindex, octindex2;
1709 l_uint32 *rtab, *gtab, *btab, *rtab2, *gtab2, *btab2;
1710 l_uint32 *lines, *lined, *datas, *datad;
1716 PROCNAME(
"pixOctreeQuantByPopulation");
1719 return (
PIX *)ERROR_PTR(
"pixs not defined", procName, NULL);
1720 if (pixGetDepth(pixs) != 32)
1721 return (
PIX *)ERROR_PTR(
"pixs not 32 bpp", procName, NULL);
1722 if (level == 0) level = 4;
1723 if (level < 3 || level > 4)
1724 return (
PIX *)ERROR_PTR(
"level not in {3,4}", procName, NULL);
1728 if (w < MIN_DITHER_SIZE && h < MIN_DITHER_SIZE && ditherflag == 1) {
1729 L_INFO(
"Small image: dithering turned off\n", procName);
1734 return (
PIX *)ERROR_PTR(
"size not returned", procName, NULL);
1735 rtab = gtab = btab = NULL;
1739 narray = (l_int32 *)LEPT_CALLOC(size,
sizeof(l_int32));
1740 rarray = (l_int32 *)LEPT_CALLOC(size,
sizeof(l_int32));
1741 garray = (l_int32 *)LEPT_CALLOC(size,
sizeof(l_int32));
1742 barray = (l_int32 *)LEPT_CALLOC(size,
sizeof(l_int32));
1743 if (!narray || !rarray || !garray || !barray)
1748 wpls = pixGetWpl(pixs);
1749 for (i = 0; i < h; i++) {
1750 lines = datas + i * wpls;
1751 for (j = 0; j < w; j++) {
1753 octindex = rtab[rval] | gtab[gval] | btab[bval];
1755 rarray[octindex] += rval;
1756 garray[octindex] += gval;
1757 barray[octindex] += bval;
1762 for (i = 0, ncolors = 0; i < size; i++) {
1768 else if (ncolors <= 16)
1774 wpld = pixGetWpl(pixd);
1775 pixCopyResolution(pixd, pixs);
1776 pixCopyInputFormat(pixd, pixs);
1781 for (i = 0; i < size; i++) {
1782 if (narray[i] > 0) {
1783 rarray[i] /= narray[i];
1784 garray[i] /= narray[i];
1785 barray[i] /= narray[i];
1791 if (ncolors <= 256) {
1792 for (i = 0, index = 0; i < size; i++) {
1793 if (narray[i] > 0) {
1795 narray[i] = index + 1;
1801 for (i = 0; i < h; i++) {
1802 lines = datas + i * wpls;
1803 lined = datad + i * wpld;
1804 for (j = 0; j < w; j++) {
1806 octindex = rtab[rval] | gtab[gval] | btab[bval];
1819 L_WARNING(
"shouldn't get here\n", procName);
1828 for (i = 0; i < size; i++) {
1829 if (narray[i] > 0) {
1831 opop->npix = (l_float32)narray[i];
1833 opop->rval = rarray[i];
1834 opop->gval = garray[i];
1835 opop->bval = barray[i];
1842 iarray = (l_int32 *)LEPT_CALLOC(size,
sizeof(l_int32));
1843 for (i = 0; i < 192; i++) {
1847 iarray[opop->index] = i + 1;
1850 fprintf(stderr,
"i = %d, n = %6.0f, (r,g,b) = (%d %d %d)\n",
1851 i, opop->npix, opop->rval, opop->gval, opop->bval);
1858 rtab2 = gtab2 = btab2 = NULL;
1860 for (i = 0; i < 64; i++) {
1871 for (i = 192; i < size; i++) {
1877 octindex2 = rtab2[rval] | gtab2[gval] | btab2[bval];
1878 narray[octindex2] += (l_int32)opop->npix;
1879 rarray[octindex2] += (l_int32)opop->npix * rval;
1880 garray[octindex2] += (l_int32)opop->npix * gval;
1881 barray[octindex2] += (l_int32)opop->npix * bval;
1882 iarray[opop->index] = 192 + octindex2 + 1;
1893 for (i = 0; i < size; i++) {
1894 if (iarray[i] == 0) {
1896 octindex2 = rtab2[rval] | gtab2[gval] | btab2[bval];
1897 iarray[i] = 192 + octindex2 + 1;
1907 for (i = 0; i < 64; i++) {
1908 if (narray[i] > 0) {
1909 rarray[i] /= narray[i];
1910 garray[i] /= narray[i];
1911 barray[i] /= narray[i];
1920 if (ditherflag == 0) {
1921 for (i = 0; i < h; i++) {
1922 lines = datas + i * wpls;
1923 lined = datad + i * wpld;
1924 for (j = 0; j < w; j++) {
1926 octindex = rtab[rval] | gtab[gval] | btab[bval];
1932 iarray, POP_DIF_CAP);
1936 for (i = 0; i < size / 16; i++) {
1938 for (j = 0; j < 16; j++)
1939 fprintf(stderr,
"%d ", iarray[16 * i + j]);
1940 fprintf(stderr,
"\n");
2000 l_uint8 *bufu8r, *bufu8g, *bufu8b;
2001 l_int32 i, j, w, h, wpld, octindex, cmapindex, success;
2002 l_int32 rval, gval, bval, rc, gc, bc;
2003 l_int32 dif, val1, val2, val3;
2004 l_int32 *buf1r, *buf1g, *buf1b, *buf2r, *buf2g, *buf2b;
2005 l_uint32 *datad, *lined;
2008 PROCNAME(
"pixDitherOctindexWithCmap");
2010 if (!pixs || pixGetDepth(pixs) != 32)
2011 return ERROR_INT(
"pixs undefined or not 32 bpp", procName, 1);
2012 if (!pixd || pixGetDepth(pixd) != 8)
2013 return ERROR_INT(
"pixd undefined or not 8 bpp", procName, 1);
2014 if ((cmap = pixGetColormap(pixd)) == NULL)
2015 return ERROR_INT(
"pixd not cmapped", procName, 1);
2016 if (!rtab || !gtab || !btab || !indexmap)
2017 return ERROR_INT(
"not all 4 tables defined", procName, 1);
2019 if (pixGetWidth(pixd) != w || pixGetHeight(pixd) != h)
2020 return ERROR_INT(
"pixs and pixd not same size", procName, 1);
2023 bufu8r = bufu8g = bufu8b = NULL;
2024 buf1r = buf1g = buf1b = buf2r = buf2g = buf2b = NULL;
2025 bufu8r = (l_uint8 *)LEPT_CALLOC(w,
sizeof(l_uint8));
2026 bufu8g = (l_uint8 *)LEPT_CALLOC(w,
sizeof(l_uint8));
2027 bufu8b = (l_uint8 *)LEPT_CALLOC(w,
sizeof(l_uint8));
2028 buf1r = (l_int32 *)LEPT_CALLOC(w,
sizeof(l_int32));
2029 buf1g = (l_int32 *)LEPT_CALLOC(w,
sizeof(l_int32));
2030 buf1b = (l_int32 *)LEPT_CALLOC(w,
sizeof(l_int32));
2031 buf2r = (l_int32 *)LEPT_CALLOC(w,
sizeof(l_int32));
2032 buf2g = (l_int32 *)LEPT_CALLOC(w,
sizeof(l_int32));
2033 buf2b = (l_int32 *)LEPT_CALLOC(w,
sizeof(l_int32));
2034 if (!bufu8r || !bufu8g || !bufu8b || !buf1r || !buf1g ||
2035 !buf1b || !buf2r || !buf2g || !buf2b) {
2036 L_ERROR(
"buffer not made\n", procName);
2038 goto buffer_cleanup;
2043 for (j = 0; j < w; j++) {
2044 buf2r[j] = 64 * bufu8r[j];
2045 buf2g[j] = 64 * bufu8g[j];
2046 buf2b[j] = 64 * bufu8b[j];
2050 wpld = pixGetWpl(pixd);
2051 for (i = 0; i < h - 1; i++) {
2053 memcpy(buf1r, buf2r, 4 * w);
2054 memcpy(buf1g, buf2g, 4 * w);
2055 memcpy(buf1b, buf2b, 4 * w);
2057 for (j = 0; j < w; j++) {
2058 buf2r[j] = 64 * bufu8r[j];
2059 buf2g[j] = 64 * bufu8g[j];
2060 buf2b[j] = 64 * bufu8b[j];
2064 lined = datad + i * wpld;
2065 for (j = 0; j < w - 1; j++) {
2066 rval = buf1r[j] / 64;
2067 gval = buf1g[j] / 64;
2068 bval = buf1b[j] / 64;
2069 octindex = rtab[rval] | gtab[gval] | btab[bval];
2070 cmapindex = indexmap[octindex] - 1;
2074 dif = buf1r[j] / 8 - 8 * rc;
2076 if (dif > difcap) dif = difcap;
2077 if (dif < -difcap) dif = -difcap;
2080 val1 = buf1r[j + 1] + 3 * dif;
2081 val2 = buf2r[j] + 3 * dif;
2082 val3 = buf2r[j + 1] + 2 * dif;
2084 buf1r[j + 1] = L_MIN(16383, val1);
2085 buf2r[j] = L_MIN(16383, val2);
2086 buf2r[j + 1] = L_MIN(16383, val3);
2088 buf1r[j + 1] = L_MAX(0, val1);
2089 buf2r[j] = L_MAX(0, val2);
2090 buf2r[j + 1] = L_MAX(0, val3);
2094 dif = buf1g[j] / 8 - 8 * gc;
2096 if (dif > difcap) dif = difcap;
2097 if (dif < -difcap) dif = -difcap;
2100 val1 = buf1g[j + 1] + 3 * dif;
2101 val2 = buf2g[j] + 3 * dif;
2102 val3 = buf2g[j + 1] + 2 * dif;
2104 buf1g[j + 1] = L_MIN(16383, val1);
2105 buf2g[j] = L_MIN(16383, val2);
2106 buf2g[j + 1] = L_MIN(16383, val3);
2108 buf1g[j + 1] = L_MAX(0, val1);
2109 buf2g[j] = L_MAX(0, val2);
2110 buf2g[j + 1] = L_MAX(0, val3);
2114 dif = buf1b[j] / 8 - 8 * bc;
2116 if (dif > difcap) dif = difcap;
2117 if (dif < -difcap) dif = -difcap;
2120 val1 = buf1b[j + 1] + 3 * dif;
2121 val2 = buf2b[j] + 3 * dif;
2122 val3 = buf2b[j + 1] + 2 * dif;
2124 buf1b[j + 1] = L_MIN(16383, val1);
2125 buf2b[j] = L_MIN(16383, val2);
2126 buf2b[j + 1] = L_MIN(16383, val3);
2128 buf1b[j + 1] = L_MAX(0, val1);
2129 buf2b[j] = L_MAX(0, val2);
2130 buf2b[j + 1] = L_MAX(0, val3);
2136 rval = buf1r[w - 1] / 64;
2137 gval = buf1g[w - 1] / 64;
2138 bval = buf1b[w - 1] / 64;
2139 octindex = rtab[rval] | gtab[gval] | btab[bval];
2140 cmapindex = indexmap[octindex] - 1;
2145 lined = datad + (h - 1) * wpld;
2146 for (j = 0; j < w; j++) {
2147 rval = buf2r[j] / 64;
2148 gval = buf2g[j] / 64;
2149 bval = buf2b[j] / 64;
2150 octindex = rtab[rval] | gtab[gval] | btab[bval];
2151 cmapindex = indexmap[octindex] - 1;
2166 return (success) ? 0 : 1;
2267 l_int32 w, h, minside, bpp, wpls, wpld, i, j, actualcolors;
2268 l_int32 rval, gval, bval, nbase, nextra, maxlevel, ncubes, val;
2269 l_int32 *lut1, *lut2;
2271 l_uint32 *lines, *lined, *datas, *datad, *pspixel;
2272 l_uint32 *rtab, *gtab, *btab;
2279 PROCNAME(
"pixOctreeQuantNumColors");
2282 return (
PIX *)ERROR_PTR(
"pixs not defined", procName, NULL);
2283 if (pixGetDepth(pixs) != 32)
2284 return (
PIX *)ERROR_PTR(
"pixs not 32 bpp", procName, NULL);
2288 wpls = pixGetWpl(pixs);
2289 minside = L_MIN(w, h);
2290 if (subsample <= 0) {
2291 subsample = L_MAX(1, minside / 200);
2294 if (maxcolors >= 8 && maxcolors <= 16) {
2300 nextra = maxcolors - nbase;
2301 }
else if (maxcolors < 64) {
2307 nextra = maxcolors - nbase;
2308 }
else if (maxcolors >= 64 && maxcolors <= 256) {
2314 nextra = maxcolors - nbase;
2316 return (
PIX *)ERROR_PTR(
"maxcolors not in {8...256}", procName, NULL);
2319 pixCopyResolution(pixd, pixs);
2320 pixCopyInputFormat(pixd, pixs);
2329 if ((oqca = (
OQCELL **)LEPT_CALLOC(nbase,
sizeof(
OQCELL *))) == NULL) {
2331 return (
PIX *)ERROR_PTR(
"oqca not made", procName, NULL);
2333 for (i = 0; i < nbase; i++) {
2338 rtab = gtab = btab = NULL;
2344 wpld = pixGetWpl(pixd);
2345 for (i = 0; i < h; i++) {
2346 lines = datas + i * wpls;
2347 lined = datad + i * wpld;
2348 for (j = 0; j < w; j++) {
2349 pspixel = lines + j;
2352 rtab, gtab, btab, &index);
2359 oqca[index]->n += 1.0;
2360 oqca[index]->rcum += rval;
2361 oqca[index]->gcum += gval;
2362 oqca[index]->bcum += bval;
2370 for (i = 0; i < nbase; i++) {
2373 oqc->rval = (l_int32)(oqc->rcum / oqc->n);
2374 oqc->gval = (l_int32)(oqc->gcum / oqc->n);
2375 oqc->bval = (l_int32)(oqc->bcum / oqc->n);
2378 &oqc->gval, &oqc->bval);
2383 for (i = 0; i < nbase; i++)
2398 if ((oqca = (
OQCELL **)LEPT_CALLOC(ncubes,
sizeof(
OQCELL *))) == NULL) {
2400 return (
PIX *)ERROR_PTR(
"oqca not made", procName, NULL);
2402 for (i = 0; i < ncubes; i++) {
2409 rtab = gtab = btab = NULL;
2414 for (i = 0; i < h; i += subsample) {
2415 lines = datas + i * wpls;
2416 for (j = 0; j < w; j += subsample) {
2417 pspixel = lines + j;
2420 oqca[index]->n += 1.0;
2421 oqca[index]->octindex = index;
2422 oqca[index]->rcum += rval;
2423 oqca[index]->gcum += gval;
2424 oqca[index]->bcum += bval;
2430 for (i = 0; i < ncubes; i++)
2435 oqca = (
OQCELL **)LEPT_CALLOC(maxcolors,
sizeof(
OQCELL *));
2436 for (i = 0; i < nbase; i++) {
2442 for (i = 0; i < nextra; i++) {
2448 oqca[nbase + i] = oqc;
2456 lut1 = (l_int32 *)LEPT_CALLOC(ncubes,
sizeof(l_int32));
2457 for (i = 0; i < nextra; i++)
2458 lut1[oqca[nbase + i]->octindex] = nbase + i;
2459 for (index = 0; index < ncubes; index++) {
2460 if (lut1[index] == 0)
2461 lut1[index] = index >> 3;
2468 wpld = pixGetWpl(pixd);
2469 for (i = 0; i < h; i++) {
2470 lines = datas + i * wpls;
2471 lined = datad + i * wpld;
2472 for (j = 0; j < w; j++) {
2473 pspixel = lines + j;
2489 return (
PIX *)ERROR_PTR(
"bpp not 4 or 8!", procName, NULL);
2492 oqca[val]->n += 1.0;
2493 oqca[val]->rcum += rval;
2494 oqca[val]->gcum += gval;
2495 oqca[val]->bcum += bval;
2502 lut2 = (l_int32 *)LEPT_CALLOC(ncubes,
sizeof(l_int32));
2505 for (i = 0, index = 0; i < maxcolors; i++) {
2510 oqc->rval = (l_int32)(oqc->rcum / oqc->n);
2511 oqc->gval = (l_int32)(oqc->gcum / oqc->n);
2512 oqc->bval = (l_int32)(oqc->bcum / oqc->n);
2522 if (actualcolors < maxcolors) {
2523 for (i = 0; i < h; i++) {
2524 lined = datad + i * wpld;
2525 for (j = 0; j < w; j++) {
2541 for (i = 0; i < maxcolors; i++)
2592 l_int32 w, h, wpls, wpld, i, j, size, octlevels;
2593 l_int32 rval, gval, bval, del, val, midval;
2594 l_int32 *carray, *rarray, *garray, *barray;
2597 l_uint32 *rtab, *gtab, *btab;
2598 l_uint32 *lines, *lined, *datas, *datad;
2602 PROCNAME(
"pixOctcubeQuantMixedWithGray");
2605 return (
PIX *)ERROR_PTR(
"pixs not defined", procName, NULL);
2606 if (pixGetDepth(pixs) != 32)
2607 return (
PIX *)ERROR_PTR(
"pixs not 32 bpp", procName, NULL);
2609 return (
PIX *)ERROR_PTR(
"invalid graylevels", procName, NULL);
2614 return (
PIX *)ERROR_PTR(
"max 8 gray levels", procName, NULL);
2615 }
else if (depth == 8) {
2618 if (graylevels > 192)
2619 return (
PIX *)ERROR_PTR(
"max 192 gray levels", procName, NULL);
2621 return (
PIX *)ERROR_PTR(
"output depth not 4 or 8 bpp", procName, NULL);
2627 rtab = gtab = btab = NULL;
2631 carray = (l_int32 *)LEPT_CALLOC(size,
sizeof(l_int32));
2632 rarray = (l_int32 *)LEPT_CALLOC(size,
sizeof(l_int32));
2633 garray = (l_int32 *)LEPT_CALLOC(size,
sizeof(l_int32));
2634 barray = (l_int32 *)LEPT_CALLOC(size,
sizeof(l_int32));
2638 if (!rtab || !gtab || !btab ||
2639 !carray || !rarray || !garray || !barray || !tabval) {
2640 L_ERROR(
"calloc fail for an array\n", procName);
2646 if ((pixd =
pixCreate(w, h, depth)) == NULL) {
2647 L_ERROR(
"pixd not made\n", procName);
2650 pixCopyResolution(pixd, pixs);
2651 pixCopyInputFormat(pixd, pixs);
2653 for (j = 0; j < size; j++)
2655 for (j = 0; j < graylevels; j++) {
2656 val = (255 * j) / (graylevels - 1);
2660 wpld = pixGetWpl(pixd);
2666 wpls = pixGetWpl(pixs);
2667 for (i = 0; i < h; i++) {
2668 lines = datas + i * wpls;
2669 lined = datad + i * wpld;
2670 for (j = 0; j < w; j++) {
2676 }
else if (rval > bval) {
2687 }
else if (gval > bval) {
2696 octindex = rtab[rval] | gtab[gval] | btab[bval];
2698 rarray[octindex] += rval;
2699 garray[octindex] += gval;
2700 barray[octindex] += bval;
2706 val = size + tabval[midval];
2716 for (i = 0; i < size; i++) {
2717 if (carray[i] > 0) {
2718 rarray[i] /= carray[i];
2719 garray[i] /= carray[i];
2720 barray[i] /= carray[i];
2810 l_int32 rval, gval, bval;
2811 l_int32 w, h, wpls, wpld, i, j, cindex;
2812 l_uint32 *rtab, *gtab, *btab;
2814 l_uint32 *datas, *datad, *lines, *lined;
2818 PROCNAME(
"pixFixedOctcubeQuant256");
2821 return (
PIX *)ERROR_PTR(
"pixs not defined", procName, NULL);
2822 if (pixGetDepth(pixs) != 32)
2823 return (
PIX *)ERROR_PTR(
"pixs not 32 bpp", procName, NULL);
2827 if (w < MIN_DITHER_SIZE && h < MIN_DITHER_SIZE && ditherflag == 1) {
2828 L_INFO(
"Small image: dithering turned off\n", procName);
2841 for (cindex = 0; cindex < 256; cindex++) {
2842 rval = (cindex & 0xe0) | 0x10;
2843 gval = ((cindex << 3) & 0xe0) | 0x10;
2844 bval = ((cindex << 6) & 0xc0) | 0x20;
2850 wpls = pixGetWpl(pixs);
2851 if ((pixd =
pixCreate(w, h, 8)) == NULL) {
2853 return (
PIX *)ERROR_PTR(
"pixd not made", procName, NULL);
2856 pixCopyResolution(pixd, pixs);
2857 pixCopyInputFormat(pixd, pixs);
2859 wpld = pixGetWpl(pixd);
2862 if (ditherflag == 0) {
2863 for (i = 0; i < h; i++) {
2864 lines = datas + i * wpls;
2865 lined = datad + i * wpld;
2866 for (j = 0; j < w; j++) {
2868 index = (rval & 0xe0) | ((gval >> 3) & 0x1c) | (bval >> 6);
2880 rtab = (l_uint32 *)LEPT_CALLOC(256,
sizeof(l_uint32));
2881 gtab = (l_uint32 *)LEPT_CALLOC(256,
sizeof(l_uint32));
2882 btab = (l_uint32 *)LEPT_CALLOC(256,
sizeof(l_uint32));
2883 itab = (l_int32 *)LEPT_CALLOC(256,
sizeof(l_int32));
2884 if (!rtab || !gtab || !btab || !itab) {
2886 return (
PIX *)ERROR_PTR(
"calloc fail for table", procName, NULL);
2888 for (i = 0; i < 256; i++) {
2890 gtab[i] = (i >> 3) & 0x1c;
2943 l_int32 w, h, wpls, wpld, i, j, depth, size, ncolors, index;
2944 l_int32 rval, gval, bval;
2945 l_int32 *carray, *rarray, *garray, *barray;
2947 l_uint32 *rtab, *gtab, *btab;
2948 l_uint32 *lines, *lined, *datas, *datad, *pspixel;
2952 PROCNAME(
"pixFewColorsOctcubeQuant1");
2955 return (
PIX *)ERROR_PTR(
"pixs not defined", procName, NULL);
2956 if (pixGetDepth(pixs) != 32)
2957 return (
PIX *)ERROR_PTR(
"pixs not 32 bpp", procName, NULL);
2958 if (level < 1 || level > 6)
2959 return (
PIX *)ERROR_PTR(
"invalid level", procName, NULL);
2964 return (
PIX *)ERROR_PTR(
"size not returned", procName, NULL);
2965 rtab = gtab = btab = NULL;
2968 carray = (l_int32 *)LEPT_CALLOC(size,
sizeof(l_int32));
2969 rarray = (l_int32 *)LEPT_CALLOC(size,
sizeof(l_int32));
2970 garray = (l_int32 *)LEPT_CALLOC(size,
sizeof(l_int32));
2971 barray = (l_int32 *)LEPT_CALLOC(size,
sizeof(l_int32));
2972 if (!carray || !rarray || !garray || !barray) {
2973 L_ERROR(
"calloc fail for an array\n", procName);
2980 wpls = pixGetWpl(pixs);
2981 for (i = 0; i < h; i++) {
2982 lines = datas + i * wpls;
2983 for (j = 0; j < w; j++) {
2984 pspixel = lines + j;
2986 octindex = rtab[rval] | gtab[gval] | btab[bval];
2988 rarray[octindex] += rval;
2989 garray[octindex] += gval;
2990 barray[octindex] += bval;
2995 for (i = 0, ncolors = 0; i < size; i++) {
2999 if (ncolors > 256) {
3000 L_WARNING(
"%d colors found; more than 256\n", procName, ncolors);
3005 else if (ncolors <= 16)
3013 for (i = 0, index = 0; i < size; i++) {
3014 if (carray[i] > 0) {
3015 rarray[i] /= carray[i];
3016 garray[i] /= carray[i];
3017 barray[i] /= carray[i];
3019 carray[i] = index + 1;
3026 pixCopyResolution(pixd, pixs);
3027 pixCopyInputFormat(pixd, pixs);
3029 wpld = pixGetWpl(pixd);
3030 for (i = 0; i < h; i++) {
3031 lines = datas + i * wpls;
3032 lined = datad + i * wpld;
3033 for (j = 0; j < w; j++) {
3034 pspixel = lines + j;
3036 octindex = rtab[rval] | gtab[gval] | btab[bval];
3049 L_WARNING(
"shouldn't get here\n", procName);
3116 l_int32 w, h, wpls, wpld, i, j, nerrors;
3117 l_int32 ncubes, depth, cindex, oval;
3118 l_int32 rval, gval, bval;
3121 l_uint32 *rtab, *gtab, *btab;
3122 l_uint32 *lines, *lined, *datas, *datad, *ppixel;
3123 l_uint32 *colorarray;
3127 PROCNAME(
"pixFewColorsOctcubeQuant2");
3130 return (
PIX *)ERROR_PTR(
"pixs not defined", procName, NULL);
3131 if (pixGetDepth(pixs) != 32)
3132 return (
PIX *)ERROR_PTR(
"pixs not 32 bpp", procName, NULL);
3133 if (level < 3 || level > 6)
3134 return (
PIX *)ERROR_PTR(
"level not in {4, 5, 6}", procName, NULL);
3136 return (
PIX *)ERROR_PTR(
"ncolors > 256", procName, NULL);
3144 rtab = gtab = btab = NULL;
3149 octarray = (l_int32 *)LEPT_CALLOC(ncubes,
sizeof(l_int32));
3154 colorarray = (l_uint32 *)LEPT_CALLOC(ncolors + 1,
sizeof(l_uint32));
3155 if (!octarray || !colorarray) {
3156 L_ERROR(
"octarray or colorarray not made\n", procName);
3157 goto cleanup_arrays;
3163 wpls = pixGetWpl(pixs);
3166 else if (ncolors <= 16)
3171 if ((pixd =
pixCreate(w, h, depth)) == NULL) {
3172 L_ERROR(
"pixd not made\n", procName);
3173 goto cleanup_arrays;
3175 pixCopyResolution(pixd, pixs);
3176 pixCopyInputFormat(pixd, pixs);
3178 wpld = pixGetWpl(pixd);
3190 for (i = 0; i < h; i++) {
3191 lines = datas + i * wpls;
3192 lined = datad + i * wpld;
3193 for (j = 0; j < w; j++) {
3196 octindex = rtab[rval] | gtab[gval] | btab[bval];
3197 oval = octarray[octindex];
3199 octarray[octindex] = cindex;
3200 colorarray[cindex] = *ppixel;
3205 if (colorarray[oval] != *ppixel)
3211 *pnerrors = nerrors;
3213 #if DEBUG_FEW_COLORS 3214 fprintf(stderr,
"ncubes = %d, ncolors = %d\n", ncubes, ncolors);
3215 for (i = 0; i < ncolors; i++)
3216 fprintf(stderr,
"color[%d] = %x\n", i, colorarray[i + 1]);
3221 for (i = 0; i < ncolors; i++) {
3222 ppixel = colorarray + i + 1;
3229 LEPT_FREE(octarray);
3230 LEPT_FREE(colorarray);
3302 l_int32 lightthresh,
3307 l_int32 i, j, w, h, wplc, wplm, wpld, ncolors, index;
3308 l_int32 rval, gval, bval, val, minval, maxval;
3310 l_uint32 *datac, *datam, *datad, *linec, *linem, *lined;
3311 PIX *pixc, *pixm, *pixg, *pixd;
3314 PROCNAME(
"pixFewColorsOctcubeQuantMixed");
3316 if (!pixs || pixGetDepth(pixs) != 32)
3317 return (
PIX *)ERROR_PTR(
"pixs undefined or not 32 bpp", procName, NULL);
3318 if (level <= 0) level = 3;
3320 return (
PIX *)ERROR_PTR(
"invalid level", procName, NULL);
3321 if (darkthresh <= 0) darkthresh = 20;
3322 if (lightthresh <= 0) lightthresh = 244;
3323 if (diffthresh <= 0) diffthresh = 20;
3324 if (minfract <= 0.0) minfract = 0.05;
3325 if (maxspan <= 2) maxspan = 15;
3329 return (
PIX *)ERROR_PTR(
"too many colors", procName, NULL);
3333 cmap = pixGetColormap(pixc);
3336 lut = (l_int32 *)LEPT_CALLOC(256,
sizeof(l_int32));
3337 for (i = 0; i < 256; i++)
3339 for (i = 0, index = 0; i < ncolors; i++) {
3341 minval = L_MIN(rval, gval);
3342 minval = L_MIN(minval, bval);
3343 if (minval > lightthresh)
3345 maxval = L_MAX(rval, gval);
3346 maxval = L_MAX(maxval, bval);
3347 if (maxval < darkthresh)
3351 if (maxval - minval >= diffthresh) {
3368 wplc = pixGetWpl(pixc);
3369 wplm = pixGetWpl(pixm);
3370 wpld = pixGetWpl(pixd);
3371 for (i = 0; i < h; i++) {
3372 linec = datac + i * wplc;
3373 linem = datam + i * wplm;
3374 lined = datad + i * wpld;
3375 for (j = 0; j < w; j++) {
3420 l_int32 w, h, wpls, wpld, i, j;
3421 l_int32 rval, gval, bval;
3423 l_uint32 *rtab, *gtab, *btab;
3424 l_uint32 *lines, *lined, *datas, *datad;
3427 PROCNAME(
"pixFixedOctcubeQuantGenRGB");
3430 return (
PIX *)ERROR_PTR(
"pixs not defined", procName, NULL);
3431 if (pixGetDepth(pixs) != 32)
3432 return (
PIX *)ERROR_PTR(
"pixs not 32 bpp", procName, NULL);
3433 if (level < 1 || level > 6)
3434 return (
PIX *)ERROR_PTR(
"level not in {1,...6}", procName, NULL);
3437 return (
PIX *)ERROR_PTR(
"tables not made", procName, NULL);
3441 pixCopyResolution(pixd, pixs);
3442 pixCopyInputFormat(pixd, pixs);
3444 wpld = pixGetWpl(pixd);
3446 wpls = pixGetWpl(pixs);
3447 for (i = 0; i < h; i++) {
3448 lines = datas + i * wpls;
3449 lined = datad + i * wpld;
3450 for (j = 0; j < w; j++) {
3452 octindex = rtab[rval] | gtab[gval] | btab[bval];
3498 PROCNAME(
"pixQuantFromCmap");
3501 return (
PIX *)ERROR_PTR(
"pixs not defined", procName, NULL);
3502 if (mindepth != 2 && mindepth != 4 && mindepth != 8)
3503 return (
PIX *)ERROR_PTR(
"invalid mindepth", procName, NULL);
3504 d = pixGetDepth(pixs);
3511 return (
PIX *)ERROR_PTR(
"d not 8 or 32 bpp", procName, NULL);
3586 l_uint32 *rtab, *gtab, *btab;
3589 PROCNAME(
"pixOctcubeQuantFromCmap");
3592 return (
PIX *)ERROR_PTR(
"pixs not defined", procName, NULL);
3593 if (pixGetDepth(pixs) != 32)
3594 return (
PIX *)ERROR_PTR(
"pixs not 32 bpp", procName, NULL);
3596 return (
PIX *)ERROR_PTR(
"cmap not defined", procName, NULL);
3597 if (mindepth != 2 && mindepth != 4 && mindepth != 8)
3598 return (
PIX *)ERROR_PTR(
"invalid mindepth", procName, NULL);
3599 if (level < 1 || level > 6)
3600 return (
PIX *)ERROR_PTR(
"level not in {1...6}", procName, NULL);
3602 return (
PIX *)ERROR_PTR(
"invalid metric", procName, NULL);
3605 rtab = gtab = btab = NULL;
3610 cmaptab, rtab, gtab, btab);
3653 l_int32 i, j, w, h, depth, wpls, wpld;
3654 l_int32 rval, gval, bval, index;
3656 l_uint32 *lines, *lined, *datas, *datad;
3660 PROCNAME(
"pixOctcubeQuantFromCmapLUT");
3663 return (
PIX *)ERROR_PTR(
"pixs not defined", procName, NULL);
3664 if (pixGetDepth(pixs) != 32)
3665 return (
PIX *)ERROR_PTR(
"pixs not 32 bpp", procName, NULL);
3667 return (
PIX *)ERROR_PTR(
"cmap not defined", procName, NULL);
3668 if (mindepth != 2 && mindepth != 4 && mindepth != 8)
3669 return (
PIX *)ERROR_PTR(
"invalid mindepth", procName, NULL);
3670 if (!rtab || !gtab || !btab || !cmaptab)
3671 return (
PIX *)ERROR_PTR(
"tables not all defined", procName, NULL);
3675 depth = L_MAX(depth, mindepth);
3677 if ((pixd =
pixCreate(w, h, depth)) == NULL)
3678 return (
PIX *)ERROR_PTR(
"pixd not made", procName, NULL);
3681 pixCopyResolution(pixd, pixs);
3682 pixCopyInputFormat(pixd, pixs);
3687 wpls = pixGetWpl(pixs);
3688 wpld = pixGetWpl(pixd);
3689 for (i = 0; i < h; i++) {
3690 lines = datas + i * wpls;
3691 lined = datad + i * wpld;
3692 for (j = 0; j < w; j++) {
3698 index = cmaptab[octindex];
3701 else if (depth == 4)
3733 l_int32 size, i, j, w, h, wpl, ncolors, val;
3734 l_int32 rval, gval, bval;
3736 l_uint32 *rtab, *gtab, *btab;
3737 l_uint32 *data, *line;
3741 PROCNAME(
"pixOctcubeHistogram");
3743 if (pncolors) *pncolors = 0;
3745 return (
NUMA *)ERROR_PTR(
"pixs not defined", procName, NULL);
3746 if (pixGetDepth(pixs) != 32)
3747 return (
NUMA *)ERROR_PTR(
"pixs not 32 bpp", procName, NULL);
3750 wpl = pixGetWpl(pixs);
3754 return (
NUMA *)ERROR_PTR(
"size not returned", procName, NULL);
3755 rtab = gtab = btab = NULL;
3759 L_ERROR(
"na not made\n", procName);
3760 goto cleanup_arrays;
3765 for (i = 0; i < h; i++) {
3766 line = data + i * wpl;
3767 for (j = 0; j < w; j++) {
3769 octindex = rtab[rval] | gtab[gval] | btab[bval];
3771 if ((level == 1 && octindex > 7) ||
3772 (level == 2 && octindex > 63) ||
3773 (level == 3 && octindex > 511) ||
3774 (level == 4 && octindex > 4097) ||
3775 (level == 5 && octindex > 32783) ||
3776 (level == 6 && octindex > 262271)) {
3777 fprintf(stderr,
"level = %d, octindex = %d, index error!\n",
3782 array[octindex] += 1.0;
3787 for (i = 0, ncolors = 0; i < size; i++) {
3792 *pncolors = ncolors;
3856 l_int32 i, k, size, ncolors, mindist, dist, mincolor, index;
3857 l_int32 rval, gval, bval;
3858 l_int32 *rmap, *gmap, *bmap, *tab;
3860 PROCNAME(
"pixcmapToOctcubeLUT");
3863 return (l_int32 *)ERROR_PTR(
"cmap not defined", procName, NULL);
3864 if (level < 1 || level > 6)
3865 return (l_int32 *)ERROR_PTR(
"level not in {1...6}", procName, NULL);
3867 return (l_int32 *)ERROR_PTR(
"invalid metric", procName, NULL);
3870 return (l_int32 *)ERROR_PTR(
"size not returned", procName, NULL);
3871 if ((tab = (l_int32 *)LEPT_CALLOC(size,
sizeof(l_int32))) == NULL)
3872 return (l_int32 *)ERROR_PTR(
"tab not allocated", procName, NULL);
3878 for (i = 0; i < size; i++) {
3882 for (k = 0; k < ncolors; k++) {
3884 dist = L_ABS(rval - rmap[k]) + L_ABS(gval - gmap[k]) +
3885 L_ABS(bval - bmap[k]);
3887 dist = (rval - rmap[k]) * (rval - rmap[k]) +
3888 (gval - gmap[k]) * (gval - gmap[k]) +
3889 (bval - bmap[k]) * (bval - bmap[k]);
3891 if (dist < mindist) {
3904 if (rval < 7 && gval < 7 && bval < 7) {
3909 if (rval > 248 && gval > 248 && bval > 248) {
3910 tab[(1 << (3 * level)) - 1] = index;
3940 l_int32 i, j, w, h, d, nc, wpls, val, newval, index, zerofound;
3941 l_int32 rval, gval, bval;
3942 l_uint32 *datas, *lines;
3943 l_int32 *histo, *map1, *map2;
3946 PROCNAME(
"pixRemoveUnusedColors");
3949 return ERROR_INT(
"pixs not defined", procName, 1);
3950 if ((cmap = pixGetColormap(pixs)) == NULL)
3953 d = pixGetDepth(pixs);
3954 if (d != 2 && d != 4 && d != 8)
3955 return ERROR_INT(
"d not in {2, 4, 8}", procName, 1);
3959 if ((histo = (l_int32 *)LEPT_CALLOC(nc,
sizeof(l_int32))) == NULL)
3960 return ERROR_INT(
"histo not made", procName, 1);
3962 wpls = pixGetWpl(pixs);
3964 for (i = 0; i < h; i++) {
3965 lines = datas + i * wpls;
3966 for (j = 0; j < w; j++) {
3980 return ERROR_INT(
"switch ran off end!", procName, 1);
3983 L_WARNING(
"cmap index out of bounds!\n", procName);
3992 for (i = 0; i < nc; i++) {
3993 if (histo[i] == 0) {
4004 map1 = (l_int32 *)LEPT_CALLOC(nc,
sizeof(l_int32));
4005 map2 = (l_int32 *)LEPT_CALLOC(nc,
sizeof(l_int32));
4007 for (i = 0; i < nc; i++) {
4008 if (histo[i] != 0) {
4017 for (i = 0; i < index; i++) {
4024 for (i = 0; i < h; i++) {
4025 lines = datas + i * wpls;
4026 for (j = 0; j < w; j++) {
4048 return ERROR_INT(
"switch ran off end!", procName, 1);
4090 l_int32 i, j, w, h, d, wpl, ncolors, size, octindex;
4091 l_int32 rval, gval, bval;
4093 l_uint32 *data, *line, *rtab, *gtab, *btab;
4095 PROCNAME(
"pixNumberOccupiedOctcubes");
4098 return ERROR_INT(
"&ncolors not defined", procName, 1);
4101 return ERROR_INT(
"pix not defined", procName, 1);
4104 return ERROR_INT(
"pix not 32 bpp", procName, 1);
4105 if (level < 1 || level > 6)
4106 return ERROR_INT(
"invalid level", procName, 1);
4107 if ((mincount < 0 && minfract < 0) || (mincount >= 0.0 && minfract >= 0.0))
4108 return ERROR_INT(
"invalid mincount/minfract", procName, 1);
4109 if (mincount == 0 || minfract == 0.0)
4111 else if (minfract > 0.0)
4112 mincount = L_MIN(1, (l_int32)(minfract * w * h));
4115 return ERROR_INT(
"size not returned", procName, 1);
4116 rtab = gtab = btab = NULL;
4118 if ((carray = (l_int32 *)LEPT_CALLOC(size,
sizeof(l_int32))) == NULL) {
4119 L_ERROR(
"carray not made\n", procName);
4120 goto cleanup_arrays;
4125 wpl = pixGetWpl(pix);
4126 for (i = 0; i < h; i++) {
4127 line = data + i * wpl;
4128 for (j = 0; j < w; j++) {
4130 octindex = rtab[rval] | gtab[gval] | btab[bval];
4136 for (i = 0, ncolors = 0; i < size; i++) {
4137 if (carray[i] >= mincount)
4140 *pncolors = ncolors;
PIX * pixOctreeColorQuant(PIX *pixs, l_int32 colors, l_int32 ditherflag)
pixOctreeColorQuant()
l_int32 pixcmapGetNearestIndex(PIXCMAP *cmap, l_int32 rval, l_int32 gval, l_int32 bval, l_int32 *pindex)
pixcmapGetNearestIndex()
PIX * pixFewColorsOctcubeQuantMixed(PIX *pixs, l_int32 level, l_int32 darkthresh, l_int32 lightthresh, l_int32 diffthresh, l_float32 minfract, l_int32 maxspan)
pixFewColorsOctcubeQuantMixed()
l_int32 numaSetCount(NUMA *na, l_int32 newcount)
numaSetCount()
l_int32 makeRGBToIndexTables(l_uint32 **prtab, l_uint32 **pgtab, l_uint32 **pbtab, l_int32 cqlevels)
makeRGBToIndexTables()
l_int32 numaAddNumber(NUMA *na, l_float32 val)
numaAddNumber()
static PIX * pixOctcubeQuantFromCmapLUT(PIX *pixs, PIXCMAP *cmap, l_int32 mindepth, l_int32 *cmaptab, l_uint32 *rtab, l_uint32 *gtab, l_uint32 *btab)
pixOctcubeQuantFromCmapLUT()
l_int32 * pixcmapToOctcubeLUT(PIXCMAP *cmap, l_int32 level, l_int32 metric)
pixcmapToOctcubeLUT()
NUMA * pixOctcubeHistogram(PIX *pixs, l_int32 level, l_int32 *pncolors)
pixOctcubeHistogram()
PIX * pixGrayQuantFromHisto(PIX *pixd, PIX *pixs, PIX *pixm, l_float32 minfract, l_int32 maxsize)
pixGrayQuantFromHisto()
void setPixelLow(l_uint32 *line, l_int32 x, l_int32 depth, l_uint32 val)
setPixelLow()
static PIX * pixOctreeQuantizePixels(PIX *pixs, CQCELL ***cqcaa, l_int32 ditherflag)
pixOctreeQuantizePixels()
PIX * pixConvertTo8(PIX *pixs, l_int32 cmapflag)
pixConvertTo8()
PIX * pixFixedOctcubeQuant256(PIX *pixs, l_int32 ditherflag)
pixFixedOctcubeQuant256()
static void cqcellTreeDestroy(CQCELL ****pcqcaa)
cqcellTreeDestroy()
static l_int32 octcubeGetCount(l_int32 level, l_int32 *psize)
octcubeGetCount()
PIX * pixCreate(l_int32 width, l_int32 height, l_int32 depth)
pixCreate()
#define SET_DATA_QBIT(pdata, n, val)
void pixcmapDestroy(PIXCMAP **pcmap)
pixcmapDestroy()
NUMA * numaCreate(l_int32 n)
numaCreate()
l_int32 * makeGrayQuantIndexTable(l_int32 nlevels)
makeGrayQuantIndexTable()
l_uint32 * pixGetData(PIX *pix)
pixGetData()
l_int32 pixcmapGetColor(PIXCMAP *cmap, l_int32 index, l_int32 *prval, l_int32 *pgval, l_int32 *pbval)
pixcmapGetColor()
l_int32 pixcmapToArrays(PIXCMAP *cmap, l_int32 **prmap, l_int32 **pgmap, l_int32 **pbmap, l_int32 **pamap)
pixcmapToArrays()
void lheapDestroy(L_HEAP **plh, l_int32 freeflag)
lheapDestroy()
PIX * pixScaleBySampling(PIX *pixs, l_float32 scalex, l_float32 scaley)
pixScaleBySampling()
PIX * pixFewColorsOctcubeQuant2(PIX *pixs, l_int32 level, NUMA *na, l_int32 ncolors, l_int32 *pnerrors)
pixFewColorsOctcubeQuant2()
l_int32 pixNumberOccupiedOctcubes(PIX *pix, l_int32 level, l_int32 mincount, l_float32 minfract, l_int32 *pncolors)
pixNumberOccupiedOctcubes()
static l_int32 pixDitherOctindexWithCmap(PIX *pixs, PIX *pixd, l_uint32 *rtab, l_uint32 *gtab, l_uint32 *btab, l_int32 *carray, l_int32 difcap)
pixDitherOctindexWithCmap()
#define SET_DATA_DIBIT(pdata, n, val)
PIXCMAP * pixcmapCreate(l_int32 depth)
pixcmapCreate()
static CQCELL *** cqcellTreeCreate(void)
cqcellTreeCreate()
PIX * pixOctcubeQuantFromCmap(PIX *pixs, PIXCMAP *cmap, l_int32 mindepth, l_int32 level, l_int32 metric)
pixOctcubeQuantFromCmap()
l_int32 pixcmapAddColor(PIXCMAP *cmap, l_int32 rval, l_int32 gval, l_int32 bval)
pixcmapAddColor()
l_int32 numaGetCount(NUMA *na)
numaGetCount()
l_int32 lheapAdd(L_HEAP *lh, void *item)
lheapAdd()
l_int32 pixRemoveUnusedColors(PIX *pixs)
pixRemoveUnusedColors()
void getOctcubeIndexFromRGB(l_int32 rval, l_int32 gval, l_int32 bval, l_uint32 *rtab, l_uint32 *gtab, l_uint32 *btab, l_uint32 *pindex)
getOctcubeIndexFromRGB()
#define SET_DATA_BYTE(pdata, n, val)
l_int32 pixSetColormap(PIX *pix, PIXCMAP *colormap)
pixSetColormap()
#define GET_DATA_QBIT(pdata, n)
L_HEAP * lheapCreate(l_int32 nalloc, l_int32 direction)
lheapCreate()
#define GET_DATA_BYTE(pdata, n)
l_int32 pixColorFraction(PIX *pixs, l_int32 darkthresh, l_int32 lightthresh, l_int32 diffthresh, l_int32 factor, l_float32 *ppixfract, l_float32 *pcolorfract)
pixColorFraction()
void * lheapRemove(L_HEAP *lh)
lheapRemove()
l_int32 pixcmapGetRankIntensity(PIXCMAP *cmap, l_float32 rankval, l_int32 *pindex)
pixcmapGetRankIntensity()
PIX * pixClone(PIX *pixs)
pixClone()
void pixDestroy(PIX **ppix)
pixDestroy()
l_int32 pixcmapGetMinDepth(PIXCMAP *cmap, l_int32 *pmindepth)
pixcmapGetMinDepth()
PIX * pixFewColorsOctcubeQuant1(PIX *pixs, l_int32 level)
pixFewColorsOctcubeQuant1()
PIX * pixGrayQuantFromCmap(PIX *pixs, PIXCMAP *cmap, l_int32 mindepth)
pixGrayQuantFromCmap()
void numaDestroy(NUMA **pna)
numaDestroy()
static void getRGBFromOctcube(l_int32 cubeindex, l_int32 level, l_int32 *prval, l_int32 *pgval, l_int32 *pbval)
getRGBFromOctcube()
l_int32 pixGetRGBLine(PIX *pixs, l_int32 row, l_uint8 *bufr, l_uint8 *bufg, l_uint8 *bufb)
pixGetRGBLine()
PIX * pixFixedOctcubeQuantGenRGB(PIX *pixs, l_int32 level)
pixFixedOctcubeQuantGenRGB()
PIX * pixOctreeColorQuantGeneral(PIX *pixs, l_int32 colors, l_int32 ditherflag, l_float32 validthresh, l_float32 colorthresh)
pixOctreeColorQuantGeneral()
PIX * pixOctreeQuantNumColors(PIX *pixs, l_int32 maxcolors, l_int32 subsample)
pixOctreeQuantNumColors()
l_int32 pixcmapResetColor(PIXCMAP *cmap, l_int32 index, l_int32 rval, l_int32 gval, l_int32 bval)
pixcmapResetColor()
l_float32 * numaGetFArray(NUMA *na, l_int32 copyflag)
numaGetFArray()
#define GET_DATA_DIBIT(pdata, n)
static l_int32 octreeFindColorCell(l_int32 octindex, CQCELL ***cqcaa, l_int32 *pindex, l_int32 *prval, l_int32 *pgval, l_int32 *pbval)
octreeFindColorCell()
l_int32 composeRGBPixel(l_int32 rval, l_int32 gval, l_int32 bval, l_uint32 *ppixel)
composeRGBPixel()
l_int32 pixcmapGetCount(PIXCMAP *cmap)
pixcmapGetCount()
static l_int32 getOctcubeIndices(l_int32 rgbindex, l_int32 level, l_int32 *pbindex, l_int32 *psindex)
getOctcubeIndices()
PIX * pixOctreeQuantByPopulation(PIX *pixs, l_int32 level, l_int32 ditherflag)
pixOctreeQuantByPopulation()
l_int32 numaGetIValue(NUMA *na, l_int32 index, l_int32 *pival)
numaGetIValue()
PIX * pixOctcubeQuantMixedWithGray(PIX *pixs, l_int32 depth, l_int32 graylevels, l_int32 delta)
pixOctcubeQuantMixedWithGray()
static CQCELL *** octreeGenerateAndPrune(PIX *pixs, l_int32 colors, l_int32 reservedcolors, PIXCMAP **pcmap)
octreeGenerateAndPrune()
PIXCMAP * pixcmapCopy(PIXCMAP *cmaps)
pixcmapCopy()
l_int32 pixGetDimensions(PIX *pix, l_int32 *pw, l_int32 *ph, l_int32 *pd)
pixGetDimensions()
void extractRGBValues(l_uint32 pixel, l_int32 *prval, l_int32 *pgval, l_int32 *pbval)
extractRGBValues()
PIX * pixQuantFromCmap(PIX *pixs, PIXCMAP *cmap, l_int32 mindepth, l_int32 level, l_int32 metric)
pixQuantFromCmap()
#define SET_DATA_BIT(pdata, n)