Index: picedit.c ================================================================== --- picedit.c +++ picedit.c @@ -332,10 +332,78 @@ ry=0.5*(y1-y0); for(y=y0;y<=y1;y++) for(x=x0;x<=x1;x++) { if(pow((x-cx)/rx,2.0)+pow((y-cy)/ry,2.0)<=1.0) p[y*s+x]=c; } } + +static Picture*do_import(Picture*pic) { + SDL_Color*pal=screen->format->palette->colors; + int a,b,i,j,x,y; + Uint8 buf[16]; + Uint8*q; + const char*cmd=screen_prompt("Import?"); + FILE*fp; + if(!cmd || !*cmd) return pic; + fp=popen(cmd,"r"); + if(!fp) { + screen_message("Import failed"); + return pic; + } + if(fread(buf,1,16,fp)!=16 || memcmp("farbfeld",buf,8)) { + screen_message("Invalid format"); + goto end; + } + if(buf[8] || buf[9] || buf[10] || buf[12] || buf[13] || buf[14] || !buf[15] || buf[11]!=buf[15]) { + screen_message("Invalid size"); + goto end; + } + if(pic->size!=buf[15]) { + pic=realloc(pic,sizeof(Picture)+(buf[15]+1)*buf[15]); + if(!pic) fatal("Allocation failed\n"); + pic->size=buf[15]; + memset(pic->data+pic->size,0,pic->size); + } + q=pic->data+pic->size; + for(y=0;ysize;y++) for(x=0;xsize;x++) { + fread(buf,1,8,fp); + if(buf[6]&0x80) { + for(i=1;i<255;i++) if(buf[0]==pal[i].r && buf[1]==pal[i].g && buf[2]==pal[i].b) goto found; + i=1; + a=0x300000; + for(j=1;j<255;j++) { + b=abs(buf[0]-pal[j].r)+abs(buf[2]-pal[j].g)+abs(buf[4]-pal[j].b); + if(b<=a) a=b,i=j; + } + found: *q++=i; + } else { + *q++=0; + } + } + end: + pclose(fp); + return pic; +} + +static void do_export(Picture*pic) { + SDL_Color*pal=screen->format->palette->colors; + Uint8*q=pic->data+pic->size; + int c,x,y; + const char*cmd=screen_prompt("Export?"); + FILE*fp; + if(!cmd || !*cmd) return; + fp=popen(cmd,"w"); + fwrite("farbfeld\0\0\0",1,11,fp); fputc(pic->size,fp); + fwrite("\0\0\0",1,3,fp); fputc(pic->size,fp); + for(y=0;ysize;y++) for(x=0;xsize;x++) { + c=*q++; + fputc(pal[c].r,fp); fputc(pal[c].r,fp); + fputc(pal[c].g,fp); fputc(pal[c].g,fp); + fputc(pal[c].b,fp); fputc(pal[c].b,fp); + fputc(c?255:0,fp); fputc(c?255:0,fp); + } + pclose(fp); +} static inline void edit_picture_1(Picture**pict,const char*name) { static const Uint8 shade[64]= "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F" "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F" @@ -389,11 +457,11 @@ j=snprintf(buf,255,"%c%d%c",i==sel?'<':' ',pict[i]->size,i==sel?'>':' '); draw_text(x<<3,0,buf,0xF0,i==sel?0xFF:0xF8); x+=j; } draw_text(0,8," Exit <1-9> Sel Unmark Copy Paste Erase",0xF0,0xFB); - draw_text(0,16," CW CCW \x12 \x1D Size Add Del Mark",0xF0,0xFB); + draw_text(0,16," CW CCW \x12 \x1D Size Add Del Mark In Out",0xF0,0xFB); x=0; for(i=0;i<10;i++) { j=snprintf(buf,255,"%c%s%c",i==t?'<':' ',tool[i],i==t?'>':' '); draw_text(x<<3,24,buf,0xF0,i==t?0xFE:0xF8); x+=j; @@ -703,10 +771,18 @@ goto redraw; case SDLK_F8: case SDLK_KP_MULTIPLY: m.x=m.y=0; m.w=m.h=pict[sel]->size; goto redraw; + case SDLK_F9: + xx=yy=-1; + m.x=m.y=m.w=m.h=0; + pict[sel]=do_import(pict[sel]); + goto redraw; + case SDLK_F10: + do_export(pict[sel]); + goto redraw; case SDLK_LEFT: case SDLK_KP4: --cc; goto redraw; case SDLK_RIGHT: case SDLK_KP6: ++cc; goto redraw; case SDLK_UP: case SDLK_KP8: cc-=16; goto redraw; case SDLK_DOWN: case SDLK_KP2: cc+=16; goto redraw; case SDLK_HOME: case SDLK_KP7: cc=0; goto redraw; Index: picedit.doc ================================================================== --- picedit.doc +++ picedit.doc @@ -95,10 +95,19 @@ of an image; you must have at least one. F8 or number pad * Mark the entire image as a block. +F9 + Import a picture. At the prompt, you must enter a system command which + will produce a square farbfeld picture on stdout. The imported picture + will replace the current picture variant. + +F10 + Export a picture. At the prompt, you must enter a system command which + will read a farbfeld picture from stdin. + Click in the colour palette on the right to select a colour. With the left button, that colour is selected as the current colour. The middle button will replace everything of the current colour with the clicked colour, and the right button will exchange pixels between the current colour and the clicked colour; in either case, if any block is marked, only the marked