+#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) {
+ int i;
+ unsigned char fg_chan[3];
+
+ aa_background= bg;
+ aa_foreground= fg;
+ aa_alpha_mean_max= fg_extra ? int2fixpt(1)-1 : int2fixpt(1);
+
+ for (i=0; i<3; 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 Fixpt find_aa_density(const RgbImage *ri, Point p) {
+ Rgb here= ri_rgb(ri, p.x, p.y);
+
+ 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);
+
+ Fixpt alpha_chan= fixpt_mul(int2fixpt(here_chan) - aa_bg_chan[i],
+ aa_scale_chan[i]);
+ alpha[i]= alpha_chan;
+ alpha_total += alpha_chan;
+ }
+
+ Fixpt one_third= dbl2fixpt(1/3.0);
+ Fixpt alpha_mean= fixpt_mul(alpha_total, one_third);
+
+ 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);
+ MFP(aa_alpha_mean_max);MFP(thresh);MFP(alpha_mean);
+ MFP(alpha_min);MI(i);MFP(alpha[i]);MFP(alpha_max) );
+
+ MUST( -thresh <= alpha_mean && alpha_mean <= aa_alpha_mean_max + thresh,
+ MP(p);
+ MRGB(here);MRGB(aa_background);MRGB(aa_foreground);
+ 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;
+}
+