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_tlsv12/sys/src/cmd/jpg/readyuv.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
/* readyuv.c - read an Abekas A66 style image file.   Steve Simon, 2003 */
2
#include <u.h>
3
#include <libc.h>
4
#include <bio.h>
5
#include <draw.h>
6
#include <ctype.h>
7
#include "imagefile.h"
8
 
9
 
10
enum {
11
	Pixels = 720,
12
	R601pal = 576,
13
	R601ntsc = 486,
14
	Shift = 13
15
};
16
 
17
 
18
static int lsbtab[] = { 6, 4, 2, 0};
19
 
20
static int
21
looksize(char *file, vlong size, int *pixels, int *lines, int *bits)
22
{
23
	Biobuf *bp;
24
	uvlong l, p;
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
		if (l*p*2 == size){
42
			*pixels = p;
43
			*lines = l;
44
			*bits = 8;
45
			break;
46
		}
47
		if ((l*p*20)/8 == size){
48
			*pixels = p;
49
			*lines = l;
50
			*bits = 10;
51
			break;
52
		}
53
	}
54
	Bterm(bp);
55
	if (s == nil)
56
		return -1;
57
	return 0;
58
}
59
 
60
 
61
static int 
62
clip(int x)
63
{
64
	x >>= (Shift+2); // +2 as we assume all input images are 10 bit
65
 
66
	if (x > 255)
67
		return 0xff;
68
	if (x <= 0)
69
		return 0;
70
	return x;
71
}
72
 
73
Rawimage**
74
Breadyuv(Biobuf *bp, int colourspace)
75
{
76
	Dir *d;
77
	uvlong sz;
78
	Rawimage *a, **array;
79
	ushort * mux, *end, *frm;
80
	uchar *buf, *r, *g, *b;
81
	int y1, y2, cb, cr, c, l, w, base;
82
	int bits, lines, pixels;
83
	int F1, F2, F3, F4;
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, &bits) == -1){
95
		werrstr("file size not listed in /lib/video.specs");
96
		return nil;
97
	}
98
 
99
	buf = nil;
100
	if (colourspace != CYCbCr) {
101
		werrstr("ReadYUV: unknown colour space %d", colourspace);
102
		return nil;
103
	}
104
 
105
	if ((a = calloc(sizeof(Rawimage), 1)) == nil)
106
		sysfatal("no memory");
107
 
108
	if ((array = calloc(sizeof(Rawimage * ), 2)) == nil)
109
		sysfatal("no memory");
110
	array[0] = a;
111
	array[1] = nil;
112
 
113
	a->nchans = 3;
114
	a->chandesc = CRGB;
115
	a->chanlen = pixels * lines;
116
	a->r = Rect(0, 0, pixels, lines);
117
 
118
	if ((frm = malloc(pixels*2*lines*sizeof(ushort))) == nil)
119
		goto Error;
120
 
121
	for (c = 0; c  < 3; c++)
122
		if ((a->chans[c] = malloc(pixels*lines)) == nil)
123
			goto Error;
124
 
125
	if ((buf = malloc(pixels*2)) == nil)
126
		goto Error;
127
 
128
	for (l = 0; l < lines; l++) {
129
		if (Bread(bp, buf, pixels *2) == -1)
130
			goto Error;
131
 
132
		base = l*pixels*2;
133
		for (w = 0; w < pixels *2; w++)
134
			frm[base + w] = ((ushort)buf[w]) << 2;
135
	}
136
 
137
 
138
	if (bits == 10)
139
		for (l = 0; l < lines; l++) {
140
			if (Bread(bp, buf, pixels / 2) == -1)
141
				goto Error;
142
 
143
 
144
			base = l * pixels * 2;
145
			for (w = 0; w < pixels * 2; w++)
146
				frm[base + w] |= (buf[w / 4] >> lsbtab[w % 4]) & 3;
147
		}
148
 
149
	mux = frm;
150
	end = frm + pixels * lines * 2;
151
	r = a->chans[0];
152
	g = a->chans[1];
153
	b = a->chans[2];
154
 
155
	if(pixels == Pixels && lines != R601pal){	// 625
156
		F1 = floor(1.402 * (1 << Shift));
157
		F2 = floor(0.34414 * (1 << Shift));
158
		F3 = floor(0.71414 * (1 << Shift));
159
		F4 = floor(1.772 * (1 << Shift));
160
	}
161
	else{				// 525
162
		F1 = floor(1.5748 * (1 << Shift));
163
		F2 = floor(0.1874 * (1 << Shift));
164
		F3 = floor(0.4681 * (1 << Shift));
165
		F4 = floor(1.8560 * (1 << Shift));
166
	}
167
 
168
	/*
169
	 * Fixme: fixed colourspace conversion at present
170
	 */
171
	while (mux < end) {
172
 
173
		cb = *mux++ - 512;
174
		y1 = (int)*mux++ << Shift;
175
		cr = *mux++ - 512;
176
		y2 = (int)*mux++ << Shift;
177
 
178
		*r++ = clip(y1 + F1*cr);
179
		*g++ = clip(y1 - F2*cb - F3*cr);
180
		*b++ = clip((y1 + F4*cb));
181
 
182
		*r++ = clip(y2 + F1*cr);
183
		*g++ = clip(y2 - F2*cb - F3*cr);
184
		*b++ = clip((y2 + F4*cb));
185
	}
186
	free(frm);
187
	free(buf);
188
	return array;
189
 
190
Error:
191
	for (c = 0; c < 3; c++)
192
		free(a->chans[c]);
193
	free(a->cmap);
194
	free(array[0]);
195
	free(array);
196
	free(frm);
197
	free(buf);
198
	return nil;
199
}
200
 
201
 
202
Rawimage**
203
readyuv(int fd, int colorspace)
204
{
205
	Rawimage * *a;
206
	Biobuf b;
207
 
208
	if (Binit(&b, fd, OREAD) < 0)
209
		return nil;
210
	a = Breadyuv(&b, colorspace);
211
	Bterm(&b);
212
	return a;
213
}
214
 
215