+#define FOR_COMMODITY_CELL(ROW_START, CELL, ROW_END) do{ \
+ Rect rowr, cell; \
+ int tryrect, colno; \
+ \
+ for (tryrect= +cim->h; tryrect >= -cim->h; tryrect--) { \
+ find_commodity(tryrect, &rowr); \
+ if (rowr.tl.x < 0) \
+ continue; \
+ debug_rect("commod",tryrect, rowr); \
+ \
+ ROW_START; \
+ \
+ for (colno=0; colno<columns; colno++) { \
+ compute_table_location(rowr,colno,&cell); \
+ \
+ CELL; \
+ } \
+ \
+ ROW_END; \
+ } \
+ }while(0);
+
+static void adjust_colours_cell(CanonImage *ci, const RgbImage *ri,
+ int colno, Rect cell) {
+ Rgb background;
+ unsigned char chanbg[3];
+ long bg_count=0, light_count=0, dark_count=0;
+ int i;
+ Point p;
+
+ background= ri_rgb(ri, cell.br.x, cell.br.y);
+ for (i=0; i<3; i++)
+ chanbg[i]= background >> (i*8);
+
+ FOR_P_RECT(p,cell) {
+ Rgb herergb= ri_rgb(ri, p.x, p.y);
+ if (herergb==background) {
+ bg_count+=3;
+ } else {
+ for (i=0; i<3; i++) {
+ unsigned char here= herergb >> (i*8);
+ if (here == chanbg[i]) bg_count++;
+ else if (here < chanbg[i]) dark_count += (chanbg[i] - here)/4 + 1;
+ else if (here > chanbg[i]) light_count += (here - chanbg[i])/4 + 1;
+ }
+ }
+ }
+ long total_count= RECT_W(cell) * RECT_H(cell) * 3;
+
+ MUST( bg_count > total_count / 2,
+ MR(cell);MIL(total_count);MIL(bg_count);
+ MIL(light_count);MIL(dark_count) );
+
+ if (bg_count == total_count)
+ return;
+
+ Rgb foreground;
+ double fg_extra;
+
+ if (light_count/16 > dark_count) {
+ foreground= 0xffffffU;
+ fg_extra= +1;
+ } else if (dark_count/16 > light_count) {
+ foreground= 0;
+ fg_extra= -1;
+ } else {
+ MUST( !"tell light from dark",
+ MR(cell);MIL(total_count);MIL(bg_count);
+ MIL(light_count);MIL(dark_count);MRGB(background); );
+ }
+
+ debugf("TABLEENTRY col=%d %d,%d..%d,%d bg=%ld light=%ld dark=%ld\n",
+ colno, cell.tl.x,cell.tl.y, cell.br.x,cell.br.y,
+ bg_count, light_count, dark_count);
+
+ int monochrome= 1;
+
+ find_aa_density_prep(background, foreground, fg_extra);
+
+ FOR_P_RECT(p,cell) {
+ Fixpt alpha= find_aa_density(ri,p);
+
+ int here_int= alpha >> (FIXPT_SHIFT - AADEPTH);
+ assert(here_int <= AAMAXVAL);
+ if (!(here_int==0 || here_int==AAMAXVAL)) monochrome=0;
+ ci->d[p.y * ci->w + p.x]= '0' + here_int;
+ }
+
+ debug_rect("cell0M", colno, cell);
+
+ require_rectangle_r(cell, "0123456789", __LINE__);
+}
+
+void adjust_colours(CanonImage *ci, const RgbImage *ri) {
+ if (!(o_mode & mf_analyse))
+ return;
+
+ cim= ci;
+
+ FOR_COMMODITY_CELL({},({
+ adjust_colours_cell(ci,ri,colno,cell);
+ }),{});
+}
+