Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – planix.SVN – Blame – /os/branches/feature-vt/sys/src/cmd/jpg/readv210.c – Rev 2

Subversion Repositories planix.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
/*
2
 * readV210.c - read single uncompressed Quicktime YUV image.
3
 * http://developer.apple.com/quicktime/icefloe/dispatch019.html#v210
4
 * Steve Simon, 2009
5
 */
6
#include <u.h>
7
#include <libc.h>
8
#include <bio.h>
9
#include <draw.h>
10
#include <ctype.h>
11
#include "imagefile.h"
12
 
13
enum {
14
	Pixels = 720,
15
	R601pal = 576,
16
	R601ntsc = 486,
17
	Shift = 13
18
};
19
 
20
static int
21
looksize(char *file, vlong size, int *pixels, int *lines, int *chunk)
22
{
23
	Biobuf *bp;
24
	uvlong l, p, c;
25
	char *s, *a[12];
26
 
27
	/*
28
	 * This may not always work, there could be an alias between file
29
	 * sizes of different standards stored in 8bits and 10 bits.
30
	 */
31
	if((bp = Bopen(file, OREAD)) == nil)
32
		return -1;
33
	while((s = Brdstr(bp, '\n', 1)) != nil){
34
		if(tokenize(s, a, nelem(a)) < 3)
35
			continue;
36
		if(a[0][0] == '#')
37
			continue;
38
		p = atoll(a[3]);
39
		l = atoll(a[5]);
40
		l += atoll(a[7]);
41
		c = 128 * ceil(p/48);
42
		if(l*c == size){
43
			*pixels = p;
44
			*lines = l;
45
			*chunk = c;
46
			break;
47
		}
48
	}
49
	Bterm(bp);
50
	if(s == nil)
51
		return -1;
52
	return 0;
53
}
54
 
55
static int
56
clip(int x)
57
{
58
	x >>= Shift + 2;	/* +2 as we assume all input images are 10 bit */
59
	if(x > 255)
60
		return 0xff;
61
	if(x <= 0)
62
		return 0;
63
	return x;
64
}
65
 
66
Rawimage**
67
BreadV210(Biobuf *bp, int colourspace)
68
{
69
	Dir *d;
70
	uvlong sz;
71
	Rawimage *a, **array;
72
	ushort *mux, *end, *frm, *wr;
73
	uchar *buf, *r, *g, *b;
74
	uint i, t;
75
	int y1, y2, cb, cr, c, l, rd;
76
	int chunk, lines, pixels;
77
	int F1, F2, F3, F4;
78
 
79
	buf = nil;
80
	if(colourspace != CYCbCr){
81
		werrstr("BreadV210: unknown colour space %d", colourspace);
82
		return nil;
83
	}
84
 
85
	if((d = dirfstat(Bfildes(bp))) != nil){
86
		sz = d->length;
87
		free(d);
88
	}
89
	else {
90
		fprint(2, "cannot stat input, assuming pixelsx576x10bit\n");
91
		sz = Pixels * R601pal * 2L + (pixels * R601pal / 2L);
92
	}
93
 
94
	if(looksize("/lib/video.specs", sz, &pixels, &lines, &chunk) == -1){
95
		werrstr("file spec not in /lib/video.specs\n");
96
		return nil;
97
	}
98
 
99
	if((a = calloc(sizeof(Rawimage), 1)) == nil)
100
		sysfatal("no memory");
101
 
102
	if((array = calloc(sizeof(Rawimage * ), 2)) == nil)
103
		sysfatal("no memory");
104
	array[0] = a;
105
	array[1] = nil;
106
 
107
	a->nchans = 3;
108
	a->chandesc = CRGB;
109
	a->chanlen = pixels * lines;
110
	a->r = Rect(0, 0, pixels, lines);
111
 
112
	if((frm = malloc(pixels*2*lines*sizeof(ushort))) == nil)
113
		goto Error;
114
 
115
	for(c = 0; c  < 3; c++)
116
		if((a->chans[c] = malloc(pixels*lines)) == nil)
117
			goto Error;
118
 
119
	if((buf = malloc(chunk)) == nil)
120
		goto Error;
121
 
122
	for(l = 0; l < lines; l++){
123
		if(Bread(bp, buf, chunk) == -1)
124
			goto Error;
125
 
126
		rd = 0;
127
		wr = &frm[l*pixels*2];
128
		end = &frm[(l+1)*pixels*2];
129
		while(wr < end){
130
			t = 0;
131
			for(i = 0; i < 4; i++)
132
				t += buf[rd+i] << 8*i;
133
			*wr++ = t & 0x3ff;
134
			*wr++ = t>>10 & 0x3ff;
135
			*wr++ = t>>20 & 0x3ff;
136
			rd += 4;
137
		}
138
	}
139
 
140
	mux = frm;
141
	end = frm + pixels * lines * 2;
142
	r = a->chans[0];
143
	g = a->chans[1];
144
	b = a->chans[2];
145
 
146
	if(pixels == Pixels && lines != R601pal){	// 625
147
		F1 = floor(1.402 * (1 << Shift));
148
		F2 = floor(0.34414 * (1 << Shift));
149
		F3 = floor(0.71414 * (1 << Shift));
150
		F4 = floor(1.772 * (1 << Shift));
151
	}
152
	else{						// 525 and HD
153
		F1 = floor(1.5748 * (1 << Shift));
154
		F2 = floor(0.1874 * (1 << Shift));
155
		F3 = floor(0.4681 * (1 << Shift));
156
		F4 = floor(1.8560 * (1 << Shift));
157
	}
158
 
159
	/*
160
	 * Fixme: fixed colourspace conversion at present
161
	 */
162
	while(mux < end){
163
 
164
		cb = *mux++ - 512;
165
		y1 = (int)*mux++ << Shift;
166
		cr = *mux++ - 512;
167
		y2 = (int)*mux++ << Shift;
168
 
169
		*r++ = clip(y1 + F1*cr);
170
		*g++ = clip(y1 - F2*cb - F3*cr);
171
		*b++ = clip((y1 + F4*cb));
172
 
173
		*r++ = clip(y2 + F1*cr);
174
		*g++ = clip(y2 - F2*cb - F3*cr);
175
		*b++ = clip((y2 + F4*cb));
176
	}
177
	free(frm);
178
	free(buf);
179
	return array;
180
 
181
Error:
182
	for(c = 0; c < 3; c++)
183
		free(a->chans[c]);
184
	free(a->cmap);
185
	free(array[0]);
186
	free(array);
187
	free(frm);
188
	free(buf);
189
	return nil;
190
}
191
 
192
Rawimage**
193
readV210(int fd, int colorspace)
194
{
195
	Rawimage * *a;
196
	Biobuf b;
197
 
198
	if(Binit(&b, fd, OREAD) < 0)
199
		return nil;
200
	a = BreadV210(&b, colorspace);
201
	Bterm(&b);
202
	return a;
203
}