URI:
       tbmp.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       tbmp.c (4221B)
       ---
            1 #include <u.h>
            2 #include <libc.h>
            3 #include <bio.h>
            4 #include <draw.h>
            5 #include <event.h>
            6 #include "imagefile.h"
            7 
            8 int                cflag = 0;
            9 int                dflag = 0;
           10 int                eflag = 0;
           11 int                nineflag = 0;
           12 int                threeflag = 0;
           13 int                output = 0;
           14 ulong                outchan = CMAP8;
           15 int                defaultcolor = 1;
           16 Image                *image;
           17 
           18 enum{
           19         Border        = 2,
           20         Edge        = 5
           21 };
           22 
           23 char        *show(int, char*);
           24 
           25 Rawimage** readbmp(int fd, int colorspace);
           26 
           27 void
           28 eresized(int new)
           29 {
           30         Rectangle r;
           31 
           32         if(new && getwindow(display, Refnone) < 0){
           33                 fprint(2, "bmp: can't reattach to window\n");
           34                 exits("resize");
           35         }
           36         if(image == nil)
           37                 return;
           38         r = rectaddpt(image->r, subpt(screen->r.min, image->r.min));
           39         if(!new && !winsize)
           40                 drawresizewindow(r);
           41         flushimage(display, 1);
           42 }
           43 
           44 void
           45 usage(void)
           46 {
           47         fprint(2, "usage: bmp -39cdektv -W winsize [file.bmp ...]\n");
           48         exits("usage");
           49 }
           50 
           51 void
           52 main(int argc, char *argv[])
           53 {
           54         int fd, i;
           55         char *err;
           56 
           57         ARGBEGIN{
           58         case 'W':
           59                 winsize = EARGF(usage());
           60                 break;
           61         case '3':                /* produce encoded, compressed, three-color bitmap file; no display by default */
           62                 threeflag++;
           63                 /* fall through */
           64         case 't':                /* produce encoded, compressed, true-color bitmap file; no display by default */
           65                 cflag++;
           66                 dflag++;
           67                 output++;
           68                 defaultcolor = 0;
           69                 outchan = RGB24;
           70                 break;
           71         case 'c':                /* produce encoded, compressed, bitmap file; no display by default */
           72                 cflag++;
           73                 dflag++;
           74                 output++;
           75                 if(defaultcolor)
           76                         outchan = CMAP8;
           77                 break;
           78         case 'd':                /* suppress display of image */
           79                 dflag++;
           80                 break;
           81         case 'e':                /* disable floyd-steinberg error diffusion */
           82                 eflag++;
           83                 break;
           84         case 'k':                /* force black and white */
           85                 defaultcolor = 0;
           86                 outchan = GREY8;
           87                 break;
           88         case 'v':                /* force RGBV */
           89                 defaultcolor = 0;
           90                 outchan = CMAP8;
           91                 break;
           92         case '9':                /* produce plan 9, uncompressed, bitmap file; no display by default */
           93                 nineflag++;
           94                 dflag++;
           95                 output++;
           96                 if(defaultcolor)
           97                         outchan = CMAP8;
           98                 break;
           99         default:
          100                 usage();
          101         }ARGEND;
          102 
          103         err = nil;
          104         if(argc == 0)
          105                 err = show(0, "<stdin>");
          106         else{
          107                 for(i=0; i<argc; i++){
          108                         fd = open(argv[i], OREAD);
          109                         if(fd < 0){
          110                                 fprint(2, "bmp: can't open %s: %r\n", argv[i]);
          111                                 err = "open";
          112                         }else{
          113                                 err = show(fd, argv[i]);
          114                                 close(fd);
          115                         }
          116                         if((nineflag || cflag) && argc>1 && err==nil){
          117                                 fprint(2, "bmp: exiting after one file\n");
          118                                 break;
          119                         }
          120                 }
          121         }
          122         exits(err);
          123 }
          124 
          125 int
          126 init(void)
          127 {
          128         static int inited;
          129 
          130         if(inited == 0){
          131                 if(initdraw(0, 0, 0) < 0){
          132                         fprint(2, "bmp: initdraw failed: %r");
          133                         return -1;
          134                 }
          135                 einit(Ekeyboard|Emouse);
          136                 inited++;
          137         }
          138         return 1;
          139 }
          140 
          141 char*
          142 show(int fd, char *name)
          143 {
          144         Rawimage **array, *r, *c;
          145         Image *i;
          146         int j, ch;
          147         char buf[32];
          148 
          149         array = readbmp(fd, CRGB);
          150         if(array == nil || array[0]==nil){
          151                 fprint(2, "bmp: decode %s failed: %r\n", name);
          152                 return "decode";
          153         }
          154         if(!dflag){
          155                 if(init() < 0)
          156                         return "initdraw";
          157                 if(defaultcolor && screen->depth>8)
          158                         outchan = RGB24;
          159         }
          160         r = array[0];
          161         if(outchan == CMAP8)
          162                 c = torgbv(r, !eflag);
          163         else{
          164                 if(outchan==GREY8 || (r->chandesc==CY && threeflag==0))
          165                         c = totruecolor(r, CY);
          166                 else
          167                         c = totruecolor(r, CRGB24);
          168         }
          169         if(c == nil){
          170                 fprint(2, "bmp: converting %s to local format failed: %r\n", name);
          171                 return "torgbv";
          172         }
          173         if(!dflag){
          174                 if(r->chandesc == CY)
          175                         i = allocimage(display, c->r, GREY8, 0, 0);
          176                 else
          177                         i = allocimage(display, c->r, outchan, 0, 0);
          178                 if(i == nil){
          179                         fprint(2, "bmp: allocimage %s failed: %r\n", name);
          180                         return "allocimage";
          181                 }
          182                 if(loadimage(i, i->r, c->chans[0], c->chanlen) < 0){
          183                         fprint(2, "bmp: loadimage %s failed: %r\n", name);
          184                         return "loadimage";
          185                 }
          186                 image = i;
          187                 eresized(0);
          188                 if((ch=ekbd())=='q' || ch==0x7F || ch==0x04)
          189                         exits(nil);
          190                 draw(screen, screen->clipr, display->white, nil, ZP);
          191                 image = nil;
          192                 freeimage(i);
          193         }
          194         if(nineflag){
          195                 chantostr(buf, outchan);
          196                 print("%11s %11d %11d %11d %11d ", buf,
          197                         c->r.min.x, c->r.min.y, c->r.max.x, c->r.max.y);
          198                 if(write(1, c->chans[0], c->chanlen) != c->chanlen){
          199                         fprint(2, "bmp: %s: write error %r\n", name);
          200                         return "write";
          201                 }
          202         }else if(cflag){
          203                 if(writerawimage(1, c) < 0){
          204                         fprint(2, "bmp: %s: write error: %r\n", name);
          205                         return "write";
          206                 }
          207         }
          208         for(j=0; j<r->nchans; j++)
          209                 free(r->chans[j]);
          210         free(r);
          211         free(array);
          212         if(c){
          213                 free(c->chans[0]);
          214                 free(c);
          215         }
          216         return nil;
          217 }