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