Subversion Repositories planix.SVN

Rev

Details | Last modification | View Log | RSS feed

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