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