chiark / gitweb /
Use fixed point arithmetic in find_aa_density
authorIan Jackson <ian@liberator.relativity.greenend.org.uk>
Sun, 19 Jul 2009 15:11:21 +0000 (16:11 +0100)
committerIan Jackson <ian@liberator.relativity.greenend.org.uk>
Sun, 19 Jul 2009 15:11:21 +0000 (16:11 +0100)
pctb/structure.c
pctb/x.gdb

index 21bb1697e19e68c10788980546fc80ba58b7bded..e86f2c51d5bd92b067b62fb5c3ebda85141b61ef 100644 (file)
@@ -558,7 +558,18 @@ void read_screenshots(void) {
   progress_log("read %d screenshots.",npages);
 }
 
   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)) >> FIXPT_SHIFT;
+}
+#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) {
 static Rgb aa_background, aa_foreground;
 
 static void find_aa_density_prep(Rgb bg, Rgb fg, int fg_extra) {
@@ -567,46 +578,52 @@ static void find_aa_density_prep(Rgb bg, Rgb fg, int fg_extra) {
 
   aa_background= bg;
   aa_foreground= fg;
 
   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++) {
 
   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);
 
   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);
 
   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;
   }
 
     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;
+  Fixpt alpha_max= alpha_mean + thresh;
 
   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);
 
   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(alpha_min); MI(i);MFP(alpha[i]);MFP(alpha_max) );
 
   MUST( 0 <= alpha_mean && alpha_mean <= aa_alpha_mean_max,
        MP(p);
        MRGB(here);MRGB(aa_background);MRGB(aa_foreground);
 
   MUST( 0 <= alpha_mean && alpha_mean <= aa_alpha_mean_max,
        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(alpha_mean); MFP(alpha[0]);MFP(alpha[1]);MFP(alpha[2]); );
 
   return alpha_mean;
 }
 
   return alpha_mean;
 }
@@ -738,9 +755,9 @@ static void adjust_colours_cell(CanonImage *ci, const RgbImage *ri,
   find_aa_density_prep(background, foreground, fg_extra);
 
   FOR_P_RECT(p,cell) {
   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;
     assert(here_int <= AAMAXVAL);
     if (!(here_int==0 || here_int==AAMAXVAL)) monochrome=0;
     ci->d[p.y * ci->w + p.x]= '0' + here_int;
@@ -927,8 +944,8 @@ void find_islandname(void) {
       
       for (p.y=islandnamer.tl.y; p.y<=islandnamer.br.y; p.y++) {
        pattern <<= 1;
       
       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 {
           runs[nruns]++;
           pattern |= 1u;
        } else {
index 614122f711278c57ef9601b2eb8c2796b242d12a..371162ba3712803b0d072b6a8ffa3f91b7ddd3c8 100644 (file)
@@ -1,4 +1,5 @@
 file ypp-commodities
 file ypp-commodities
-set args -Drect 2>u --edit-charset --raw-tsv --same >raw.tsv 
+set args -Drect 2>u --edit-charset --raw-tsv --same >raw.tsv
+break structure.c:596 if here!=aa_background
 break mustfail2
 run
 break mustfail2
 run