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