X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~yarrgweb/git?p=ypp-sc-tools.main.git;a=blobdiff_plain;f=pctb%2Frgbimage.c;h=c4fd11d470c9a06ea39cbf81eb647a4fe26b0698;hp=e49044f419f0f7ef06c530a74f8d46c10a8f0dd0;hb=6d7c97eb148bbc805f506a5d7453daafa6a18898;hpb=74e4e249f2c3e848592984cb193aded6a77a341d diff --git a/pctb/rgbimage.c b/pctb/rgbimage.c index e49044f..c4fd11d 100644 --- a/pctb/rgbimage.c +++ b/pctb/rgbimage.c @@ -48,21 +48,16 @@ #include "convert.h" -#define dbassert(x) \ - ((x) ? (void)0 : \ - fatal("Error in pixmap database.\n" \ - " Requirement not met: %s:%d: %s", __FILE__,__LINE__, #x)) +static int identify1(const RgbImage *base, Rect portion, + char result[MAXIMGIDENT], const char *what, + const char *which) { + char *dbfile_name= masprintf("#%s-pixmap#.txt",which); + if (!dbfile_open(dbfile_name)) + goto not_found; -static int identify(const RgbImage *base, Rect portion, - char result[MAXIMGIDENT]) { - FILE *f; - sysassert( f= fopen("pixmaps.txt","r") ); - struct pam inpam; - -#define FGETSLINE (fgetsline(f,result,MAXIMGIDENT)) +#define FGETSLINE (dbfile_getsline(result,MAXIMGIDENT,__FILE__,__LINE__)) FGETSLINE; -fprintf(stderr,">%s<\n",result); dbassert(!strcmp(result,"# ypp-sc-tools pctb pixmaps v1")); void *row= 0; @@ -70,57 +65,98 @@ fprintf(stderr,">%s<\n",result); for (;;) { FGETSLINE; - if (!result || result[0]=='#') continue; + if (!result[0] || result[0]=='#') continue; if (!strcmp(result,".")) break; - pnm_readpaminit(f, &inpam, sizeof(inpam)); - dbassert(inpam.maxval == 255); - dbassert(inpam.bytes_per_sample == 1); - dbassert(inpam.format == PPM_FORMAT); + char magic[10]; + dbfile_getsline(magic,sizeof(magic),__FILE__,__LINE__); - if (rowa < inpam.width) { - rowa= inpam.width; + dbassert(!strcmp(magic,"P3")); + int w,h,maxval; + dbassert( dbfile_scanf("%d %d %d",&w,&h,&maxval) == 3); + dbassert(w>0); dbassert(h>0); dbassert(maxval==255); + + if (rowa < w) { + rowa= w; row= mrealloc(row, rowa*3); } - int diff= - inpam.width != RECT_W(portion) || - inpam.height != RECT_H(portion); - - int y; - for (y=0; y=0 && c<=255); + int px= portion.tl.x + x, py= portion.tl.y + y; + diff |= px > portion.br.x || py > portion.br.y || + (c != RI_PIXEL(base,px,py)[i]); + } + } + } + if (!diff) { + progress_log("Identified %s image: %s.",what,result); + goto found; } - if (!diff) - return 1; } - return 0; + not_found: + result[0]= 0; + + found: + dbfile_close(); + free(dbfile_name); + return !!result[0]; } - -void identify_rgbimage(const RgbImage *base, Rect portion, - char result[MAXIMGIDENT]) { - int ok= identify(base, portion, result); - if (ok) return; - if (DEBUGP(pixmap)) { - int x,y,i; - fprintf(stderr,"P3\n%d %d\n255\n", RECT_W(portion), RECT_H(portion)); - for (y=portion.tl.y; y<=portion.br.y; y++) { - for (x=portion.tl.x; x<=portion.br.x; x++) { - putc(' ',stderr); - for (i=0; i<3; i++) - fprintf(stderr," %3d", RI_PIXEL(base,x,y)[i]); - } - putc('\n',stderr); +static int identify(const RgbImage *base, Rect portion, + char result[MAXIMGIDENT], const char *what) { + return identify1(base,portion,result,what, "master") || + identify1(base,portion,result,what, "local"); +} + +static void fwrite_ppm(FILE *f, const RgbImage *base, Rect portion) { + int x,y,i; + fprintf(f,"P3\n%d %d\n255\n", RECT_W(portion), RECT_H(portion)); + for (y=portion.tl.y; y<=portion.br.y; y++) { + for (x=portion.tl.x; x<=portion.br.x; x++) { + putc(' ',f); + for (i=0; i<3; i++) + fprintf(f," %3d", RI_PIXEL(base,x,y)[i]); } + putc('\n',f); + } + sysassert(!ferror(f)); + sysassert(!fflush(f)); +} + +void identify_rgbimage(const RgbImage *base, Rect portion, + char result[MAXIMGIDENT], const char *what) { + static int synced; + + if (!synced) { + fetch_with_rsync("pixmap"); + synced++; + } + + for (;;) { + int ok= identify(base, portion, result, what); + if (ok) return; + + if (DEBUGP(pixmap)) + fwrite_ppm(stderr,base,portion); + + FILE *resolver= resolve_start(); + if (!resolver) + fatal("Image recognition failed - unrecognised island.\n" + "See FIXME.FIXME\n"); + + fprintf(resolver, "pixmap\n" "%s\n", what); + fwrite_ppm(resolver, base, portion); + putc('\n',resolver); + + resolve_finish(); } - fatal("Unrecognised pixmap."); } RgbImage *alloc_rgb_image(int w, int h) {