! * \brief pixOctreeQuantizePixels() * * \param[in] pixs 32 bpp * \param[in] cqcaa octree in array format * \param[in] ditherflag 1 for dithering, 0 for no dithering * \return pixd or NULL on error * * * Notes: * (1) This routine doesn't need to use the CTEs (colormap * table entries) because the color indices are embedded * in the octree. Thus
| 971 | * </pre> |
| 972 | */ |
| 973 | static PIX * |
| 974 | pixOctreeQuantizePixels(PIX *pixs, |
| 975 | CQCELL ***cqcaa, |
| 976 | l_int32 ditherflag) |
| 977 | { |
| 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; |
| 983 | l_int32 rc, gc, bc; |
| 984 | l_int32 *buf1r, *buf1g, *buf1b, *buf2r, *buf2g, *buf2b; |
| 985 | l_uint32 *rtab, *gtab, *btab; |
| 986 | l_uint32 *datas, *datad, *lines, *lined; |
| 987 | PIX *pixd; |
| 988 | |
| 989 | PROCNAME("pixOctreeQuantizePixels"); |
| 990 | |
| 991 | if (!pixs) |
| 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); |
| 995 | if (!cqcaa) |
| 996 | return (PIX *)ERROR_PTR("cqcaa not defined", procName, NULL); |
| 997 | |
| 998 | /* Make output 8 bpp palette image */ |
| 999 | pixGetDimensions(pixs, &w, &h, NULL); |
| 1000 | datas = pixGetData(pixs); |
| 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); |
| 1006 | datad = pixGetData(pixd); |
| 1007 | wpld = pixGetWpl(pixd); |
| 1008 | |
| 1009 | /* Make the canonical index tables */ |
| 1010 | rtab = gtab = btab = NULL; |
| 1011 | makeRGBToIndexTables(&rtab, >ab, &btab, CQ_NLEVELS); |
| 1012 | |
| 1013 | /* Traverse tree from root, looking for lowest cube |
| 1014 | * that is a leaf, and set dest pix to its |
| 1015 | * colortable index value. The results are far |
| 1016 | * better when dithering to get a more accurate |
| 1017 | * average color. */ |
| 1018 | if (ditherflag == 0) { /* no dithering */ |
| 1019 | for (i = 0; i < h; i++) { |
| 1020 | lines = datas + i * wpls; |
| 1021 | lined = datad + i * wpld; |
| 1022 | for (j = 0; j < w; j++) { |
| 1023 | extractRGBValues(lines[j], &rval, &gval, &bval); |
| 1024 | octindex = rtab[rval] | gtab[gval] | btab[bval]; |
| 1025 | octreeFindColorCell(octindex, cqcaa, &index, &rc, &gc, &bc); |
| 1026 | SET_DATA_BYTE(lined, j, index); |
| 1027 | } |
| 1028 | } |
| 1029 | } else { /* Dither */ |
| 1030 | success = TRUE; |
no test coverage detected