1 /* readyuv.c - read an Abekas A66 style image file. Steve Simon, 2003 */
18 static int lsbtab[] = { 6, 4, 2, 0};
21 looksize(char *file, vlong size, int *pixels, int *lines, int *bits)
28 * This may not always work, there could be an alias between file
29 * sizes of different standards stored in 8bits and 10 bits.
31 if ((bp = Bopen(file, OREAD)) == nil)
33 while((s = Brdstr(bp, '\n', 1)) != nil){
34 if (tokenize(s, a, nelem(a)) < 3)
47 if ((l*p*20)/8 == size){
64 x >>= (Shift+2); // +2 as we assume all input images are 10 bit
74 Breadyuv(Biobuf *bp, int colourspace)
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;
85 if ((d = dirfstat(Bfildes(bp))) != nil){
90 fprint(2, "cannot stat input, assuming pixelsx576x10bit\n");
91 sz = Pixels * R601pal * 2L + (Pixels * R601pal / 2L);
94 if (looksize("/lib/video.specs", sz, &pixels, &lines, &bits) == -1){
95 werrstr("file size not listed in /lib/video.specs");
100 if (colourspace != CYCbCr) {
101 werrstr("ReadYUV: unknown colour space %d", colourspace);
105 if ((a = calloc(sizeof(Rawimage), 1)) == nil)
106 sysfatal("no memory");
108 if ((array = calloc(sizeof(Rawimage * ), 2)) == nil)
109 sysfatal("no memory");
115 a->chanlen = pixels * lines;
116 a->r = Rect(0, 0, pixels, lines);
118 if ((frm = malloc(pixels*2*lines*sizeof(ushort))) == nil)
121 for (c = 0; c < 3; c++)
122 if ((a->chans[c] = malloc(pixels*lines)) == nil)
125 if ((buf = malloc(pixels*2)) == nil)
128 for (l = 0; l < lines; l++) {
129 if (Bread(bp, buf, pixels *2) == -1)
133 for (w = 0; w < pixels *2; w++)
134 frm[base + w] = ((ushort)buf[w]) << 2;
139 for (l = 0; l < lines; l++) {
140 if (Bread(bp, buf, pixels / 2) == -1)
144 base = l * pixels * 2;
145 for (w = 0; w < pixels * 2; w++)
146 frm[base + w] |= (buf[w / 4] >> lsbtab[w % 4]) & 3;
150 end = frm + pixels * lines * 2;
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));
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));
169 * Fixme: fixed colourspace conversion at present
174 y1 = (int)*mux++ << Shift;
176 y2 = (int)*mux++ << Shift;
178 *r++ = clip(y1 + F1*cr);
179 *g++ = clip(y1 - F2*cb - F3*cr);
180 *b++ = clip((y1 + F4*cb));
182 *r++ = clip(y2 + F1*cr);
183 *g++ = clip(y2 - F2*cb - F3*cr);
184 *b++ = clip((y2 + F4*cb));
191 for (c = 0; c < 3; c++)
203 readyuv(int fd, int colorspace)
208 if (Binit(&b, fd, OREAD) < 0)
210 a = Breadyuv(&b, colorspace);