progress_log("read %d screenshots.",npages);
}
-static double aa_bg_chan[3], aa_scale_chan[3], aa_alpha_mean_max;
+#define FIXPT_SHIFT 15
+
+typedef long Fixpt;
+static inline Fixpt int2fixpt(int x) { return x<<FIXPT_SHIFT; }
+static inline Fixpt dbl2fixpt(double x) { return x * int2fixpt(1); }
+static inline double fixpt2dbl(Fixpt x) { return x / (1.0*int2fixpt(1)); }
+static inline Fixpt fixpt_mul(Fixpt a, Fixpt b) {
+ return (a*b + dbl2fixpt(0.5)) / int2fixpt(1);
+}
+#define MFP(v) fprintf(stderr," %s=%lx=%f", #v,(v),fixpt2dbl((v)))
+
+static Fixpt aa_bg_chan[3], aa_scale_chan[3], aa_alpha_mean_max;
static Rgb aa_background, aa_foreground;
static void find_aa_density_prep(Rgb bg, Rgb fg, int fg_extra) {
aa_background= bg;
aa_foreground= fg;
- aa_alpha_mean_max= fg_extra ? 0.999 : 1.0;
+ aa_alpha_mean_max= fg_extra ? int2fixpt(1)-1 : int2fixpt(1);
for (i=0; i<3; i++) {
- aa_bg_chan[i]= (aa_background >> (i*8)) & 0xff;
- fg_chan[i]= aa_foreground >> (i*8);
- aa_scale_chan[i]= 1.0 / (fg_chan[i] + fg_extra - aa_bg_chan[i]);
+ aa_bg_chan[i]= int2fixpt( (aa_background >> (i*8)) & 0xff );
+ fg_chan[i]= aa_foreground >> (i*8);
+
+ aa_scale_chan[i]= 1.0 / (int2fixpt(fg_chan[i]) + fg_extra - aa_bg_chan[i])
+ * dbl2fixpt(1) * dbl2fixpt(1);
}
}
-static inline double find_aa_density(const RgbImage *ri, Point p) {
+static inline Fixpt find_aa_density(const RgbImage *ri, Point p) {
Rgb here= ri_rgb(ri, p.x, p.y);
- double alpha[3], alpha_total=0;
+ if (here==aa_background) return 0;
+
+ Fixpt alpha[3], alpha_total=0;
int i;
for (i=0; i<3; i++) {
unsigned char here_chan= here >> (i*8);
- double alpha_chan= (here_chan - aa_bg_chan[i]) * aa_scale_chan[i];
+ Fixpt alpha_chan= fixpt_mul(int2fixpt(here_chan) - aa_bg_chan[i],
+ aa_scale_chan[i]);
alpha[i]= alpha_chan;
alpha_total += alpha_chan;
}
- double alpha_mean= round(alpha_total * (1e5/3.0)) * 1e-5;
+ Fixpt one_third= dbl2fixpt(1/3.0);
+ Fixpt alpha_mean= fixpt_mul(alpha_total, one_third);
- double thresh= 1.5/AAMAXVAL;
- double alpha_min= alpha_mean - thresh;
- double alpha_max= alpha_mean + thresh;
+ Fixpt thresh= dbl2fixpt(1.5/AAMAXVAL);
+ Fixpt alpha_min= alpha_mean - thresh*2;
+ Fixpt alpha_max= alpha_mean + thresh*2;
for (i=0; i<3; i++)
MUST( alpha_min <= alpha[i] && alpha[i] <= alpha_max,
MP(p);
MRGB(here);MRGB(aa_background);MRGB(aa_foreground);
- MF(aa_alpha_mean_max);
- MF(alpha_min); MI(i);MF(alpha[i]);MF(alpha_max) );
+ MFP(aa_alpha_mean_max);MFP(thresh);MFP(alpha_mean);
+ MFP(alpha_min);MI(i);MFP(alpha[i]);MFP(alpha_max) );
- MUST( 0 <= alpha_mean && alpha_mean <= aa_alpha_mean_max,
+ MUST( -thresh <= alpha_mean && alpha_mean <= aa_alpha_mean_max + thresh,
MP(p);
MRGB(here);MRGB(aa_background);MRGB(aa_foreground);
- MF(aa_alpha_mean_max);
- MF(alpha_mean); MF(alpha[0]);MF(alpha[1]);MF(alpha[2]); );
+ MFP(aa_alpha_mean_max);MFP(thresh);
+ MFP(alpha_mean); MFP(alpha[0]);MFP(alpha[1]);MFP(alpha[2]); );
+
+ if (alpha_mean < 0) alpha_mean= 0;
+ if (alpha_mean > aa_alpha_mean_max) alpha_mean= aa_alpha_mean_max;
return alpha_mean;
}
find_aa_density_prep(background, foreground, fg_extra);
FOR_P_RECT(p,cell) {
- double alpha= find_aa_density(ri,p);
+ Fixpt alpha= find_aa_density(ri,p);
- int here_int= floor((AAMAXVAL+1)*alpha);
+ 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;
for (p.y=islandnamer.tl.y; p.y<=islandnamer.br.y; p.y++) {
pattern <<= 1;
- double alpha= find_aa_density(ri,p);
- if (alpha >= 0.49) {
+ Fixpt alpha= find_aa_density(ri,p);
+ if (alpha >= dbl2fixpt(0.49)) {
runs[nruns]++;
pattern |= 1u;
} else {