From 64063c86071bbfc2de0fe032e372e1321c4b34e5 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Sun, 5 Jul 2009 15:51:10 +0100 Subject: [PATCH] New colour canonification based on tree --- pctb/convert.c | 2 ++ pctb/convert.h | 1 + pctb/pages.c | 8 +++----- pctb/structure.c | 44 ++++++++++++++++++++++++++++++++++++-------- pctb/structure.h | 43 +++++++++++++++++++------------------------ 5 files changed, 61 insertions(+), 37 deletions(-) diff --git a/pctb/convert.c b/pctb/convert.c index 9531da0..ec91f82 100644 --- a/pctb/convert.c +++ b/pctb/convert.c @@ -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(); diff --git a/pctb/convert.h b/pctb/convert.h index b85d98d..6601b77 100644 --- a/pctb/convert.h +++ b/pctb/convert.h @@ -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); diff --git a/pctb/pages.c b/pctb/pages.c index 433ea36..c504c95 100644 --- a/pctb/pages.c +++ b/pctb/pages.c @@ -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)); diff --git a/pctb/structure.c b/pctb/structure.c index cb79f99..f0de5fa 100644 --- a/pctb/structure.c +++ b/pctb/structure.c @@ -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)); diff --git a/pctb/structure.h b/pctb/structure.h index beadfed..ec7b4bf 100644 --- a/pctb/structure.h +++ b/pctb/structure.h @@ -33,15 +33,23 @@ #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) -- 2.30.2