chiark / gitweb /
New colour canonification based on tree
authorIan Jackson <ian@liberator.relativity.greenend.org.uk>
Sun, 5 Jul 2009 14:51:10 +0000 (15:51 +0100)
committerIan Jackson <ian@liberator.relativity.greenend.org.uk>
Sun, 5 Jul 2009 14:51:10 +0000 (15:51 +0100)
pctb/convert.c
pctb/convert.h
pctb/pages.c
pctb/structure.c
pctb/structure.h

index 9531da0..ec91f82 100644 (file)
@@ -271,6 +271,8 @@ int main(int argc, char **argv) {
 
   /* Actually do the work */
             
+  canon_colour_prepare();
+  
   if (o_mode & mf_findwindow) {
     screenshot_startup();
     find_yppclient_window();
index b85d98d..6601b77 100644 (file)
@@ -72,6 +72,7 @@ static inline Rgb ri_rgb(const RgbImage *ri, int x, int y) {
 void find_structure(CanonImage *im, int *max_relevant_y_r);
 Rect find_sunshine_widget(void);
 
+void canon_colour_prepare(void);
 void find_islandname(RgbImage *ri);
 void check_correct_commodities(void);
 void read_screenshots(void);
index 433ea36..c504c95 100644 (file)
@@ -523,11 +523,9 @@ static CanonImage *convert_page(Snapshot *sn) {
 
   unsigned char *pixel= sn->data;
   CANONICALISE_IMAGE(im, sn->w, sn->h, {
-    rgb=
-      (pixel[0] << 16) |
-      (pixel[1] <<  8) |
-      (pixel[2]      );
-    pixel += 3;
+    r= *pixel++;
+    g= *pixel++;
+    b= *pixel++;
   });
     
   sysassert(!ferror(screenshot_file));
index cb79f99..f0de5fa 100644 (file)
@@ -51,7 +51,12 @@ char *archipelago, *island;
 #define OTHERCOORD_x y
 #define OTHERCOORD_y x
 
-const CanonColourInfo canoncolourinfos[]= {
+typedef struct {
+  Rgb rgb; /* on screen */
+  char c; /* canonical */
+} CanonColourInfo;
+
+const CanonColourInfo canoncolourinfo_table[]= {
   { 0x475A5E, '*' }, /* edge */
   { 0x2C5F7A, '*' }, /* edge just under box heading shadow */
   { 0xC5C7AE, '*' }, /* blank area of partial commodities list */
@@ -89,6 +94,31 @@ const CanonColourInfo canoncolourinfos[]= {
   { 0,0 }
 };
 
+CanonColourInfoReds canoncolourinfo_tree;
+
+void canon_colour_prepare(void) {
+  const CanonColourInfo *cci;
+  for (cci=canoncolourinfo_table; cci->c; cci++) {
+    unsigned char r= cci->rgb >> 16;
+    unsigned char g= cci->rgb >>  8;
+    unsigned char b= cci->rgb;
+
+    CanonColourInfoGreens *greens= canoncolourinfo_tree.red2[r];
+    if (!greens) {
+      greens= canoncolourinfo_tree.red2[r]= mmalloc(sizeof(*greens));
+      FILLZERO(*greens);
+    }
+
+    CanonColourInfoBlues *blues= greens->green2[g];
+    if (!blues) {
+      blues= greens->green2[g]= mmalloc(sizeof(*blues));
+      memset(blues, '?', sizeof(blues));
+    }
+
+    blues->blue2[b]= cci->c;
+  }
+}
+
 
 static void mustfail1(const char *file, int line, const char *what) {
   fprintf(stderr,
@@ -390,15 +420,13 @@ static void file_read_image_ppm(FILE *f) {
     fatal("PNM screenshot(s) file must be 8bpp 1 byte-per-sample RGB raw");
 
   CANONICALISE_IMAGE(im, inpam.width, inpam.height, {
-    int r= fread(&rgb_buf,1,3,f);
+    int rr= fread(&rgb_buf,1,3,f);
     sysassert(!ferror(f));
-    if (r!=3) fatal("PNM screenshot(s) file ends unexpectedly");
-
-    rgb=
-       ((unsigned long)rgb_buf[0]<<16) |
-       ((unsigned long)rgb_buf[1]<<8) |
-                      (rgb_buf[2]);
+    if (rr!=3) fatal("PNM screenshot(s) file ends unexpectedly");
 
+    r= rgb_buf[0];
+    g= rgb_buf[1];
+    b= rgb_buf[2];
   });
 
   sysassert(!ferror(screenshot_file));
index beadfed..ec7b4bf 100644 (file)
 #include "convert.h"
 
 
-typedef struct {
-  Rgb rgb; /* on screen */
-  char c; /* canonical */
-} CanonColourInfo;
-
-extern const CanonColourInfo canoncolourinfos[];
+typedef struct { char blue2[256]; } CanonColourInfoBlues;
+typedef struct { CanonColourInfoBlues *green2[256]; } CanonColourInfoGreens;
+typedef struct { CanonColourInfoGreens *red2[256]; } CanonColourInfoReds;
+extern CanonColourInfoReds canoncolourinfo_tree;
 
 CanonImage *alloc_canon_image(int w, int h);
 
+static inline char canon_lookup_colour(unsigned char r,
+                                      unsigned char g,
+                                      unsigned char b) {
+  CanonColourInfoGreens *greens= canoncolourinfo_tree.red2[r];
+  if (!greens) return '?';
+  CanonColourInfoBlues *blues= greens->green2[g];
+  if (!blues) return '?';
+  return blues->blue2[b];
+}
+
 #define CANONICALISE_IMAGE(im,w,h, COMPUTE_RGB) do{            \
     /* compute_rgb should be a number of statements, or                \
      * a block, which assigns to                               \
@@ -56,25 +64,12 @@ CanonImage *alloc_canon_image(int w, int h);
     (im)->rgb= alloc_rgb_image((w), (h));                      \
                                                                \
     int x,y;                                                   \
-    unsigned long last_rgb= ~0UL;                              \
-    int last_c= -1;                                            \
     for (y=0; y<(h); y++) {                                    \
       for (x=0; x<(w); x++) {                                  \
-        const CanonColourInfo *cci;                            \
-        unsigned long rgb;                                     \
+        unsigned char r,g,b;                                   \
        COMPUTE_RGB;                                            \
         CANONIMG_ALSO_STORERGB((im)->rgb);                     \
-       if (rgb == last_rgb) {                                  \
-         (im)->d[y*(w) + x]= last_c;                           \
-       } else {                                                \
-         for (cci=canoncolourinfos; cci->c; cci++) {           \
-           if (cci->rgb == rgb) {                              \
-             last_rgb= rgb;                                    \
-             (im)->d[y*(w) + x]= last_c= cci->c;               \
-             break;                                            \
-           }                                                   \
-         }                                                     \
-       }                                                       \
+       (im)->d[y*(w) + x]= canon_lookup_colour(r,g,b);         \
       }                                                                \
       if (DEBUGP(rect)) {                                      \
        fprintf(debug, "%4d ",y);                               \
@@ -89,9 +84,9 @@ CanonImage *alloc_canon_image(int w, int h);
 #define CANONIMG_ALSO_STORERGB(ri)             \
   do{                                          \
     unsigned char *rip= RI_PIXEL((ri),x,y);    \
-    rip[0]= rgb >> 16;                         \
-    rip[1]= rgb >> 8;                          \
-    rip[2]= rgb;                               \
+    rip[0]= r;                                 \
+    rip[1]= g;                                 \
+    rip[2]= b;                                 \
   }while(0)