1 28994509 2004-04-21 devnull /* readyuv.c - read an Abekas A66 style image file. Steve Simon, 2003 */
2 28994509 2004-04-21 devnull #include <u.h>
3 28994509 2004-04-21 devnull #include <libc.h>
4 28994509 2004-04-21 devnull #include <bio.h>
5 28994509 2004-04-21 devnull #include <draw.h>
6 28994509 2004-04-21 devnull #include <ctype.h>
7 28994509 2004-04-21 devnull #include "imagefile.h"
10 28994509 2004-04-21 devnull * ITU/CCIR Rec601 states:
12 28994509 2004-04-21 devnull * R = y + 1.402 * Cr
13 28994509 2004-04-21 devnull * B = Y + 1.77305 * Cb
14 28994509 2004-04-21 devnull * G = Y - 0.72414 * Cr - 0.34414 * Cb
16 28994509 2004-04-21 devnull * using 8 bit traffic
17 28994509 2004-04-21 devnull * Y = 16 + 219 * Y
18 28994509 2004-04-21 devnull * Cr = 128 + 224 * Cr
19 28994509 2004-04-21 devnull * Cb = 128 + 224 * Cb
20 28994509 2004-04-21 devnull * or, if 10bit is used
21 28994509 2004-04-21 devnull * Y = 64 + 876 * Y
22 28994509 2004-04-21 devnull * Cr = 512 + 896 * Cr
23 28994509 2004-04-21 devnull * Cb = 512 + 896 * Cb
27 28994509 2004-04-21 devnull PAL = 576, NTSC = 486 };
30 28994509 2004-04-21 devnull static int lsbtab[] = { 6, 4, 2, 0};
33 28994509 2004-04-21 devnull clip(int x)
35 28994509 2004-04-21 devnull x >>= 18;
37 28994509 2004-04-21 devnull if (x > 255)
38 28994509 2004-04-21 devnull return 0xff;
39 28994509 2004-04-21 devnull if (x <= 0)
40 28994509 2004-04-21 devnull return 0;
41 28994509 2004-04-21 devnull return x;
45 28994509 2004-04-21 devnull Rawimage**
46 28994509 2004-04-21 devnull Breadyuv(Biobuf *bp, int colourspace)
49 28994509 2004-04-21 devnull Rawimage * a, **array;
50 28994509 2004-04-21 devnull char *e, ebuf[128];
51 28994509 2004-04-21 devnull ushort * mux, *end, *frm;
52 28994509 2004-04-21 devnull uchar buf[720 * 2], *r, *g, *b;
53 28994509 2004-04-21 devnull int y1, y2, cb, cr, sz, c, l, w, base, bits, lines;
56 28994509 2004-04-21 devnull if (colourspace != CYCbCr) {
57 28994509 2004-04-21 devnull errstr(ebuf, sizeof ebuf); /* throw it away */
58 28994509 2004-04-21 devnull werrstr("ReadYUV: unknown colour space %d", colourspace);
59 28994509 2004-04-21 devnull return nil;
62 28994509 2004-04-21 devnull if ((a = calloc(sizeof(Rawimage), 1)) == nil)
63 28994509 2004-04-21 devnull sysfatal("no memory");
65 28994509 2004-04-21 devnull if ((array = calloc(sizeof(Rawimage * ), 2)) == nil)
66 28994509 2004-04-21 devnull sysfatal("no memory");
67 28994509 2004-04-21 devnull array[0] = a;
68 28994509 2004-04-21 devnull array[1] = nil;
70 28994509 2004-04-21 devnull if ((d = dirfstat(Bfildes(bp))) != nil) {
71 28994509 2004-04-21 devnull sz = d->length;
74 28994509 2004-04-21 devnull fprint(2, "cannot stat input, assuming 720x576x10bit\n");
75 28994509 2004-04-21 devnull sz = 720 * PAL * 2L + (720 * PAL / 2L);
78 28994509 2004-04-21 devnull switch (sz) {
79 cbeb0b26 2006-04-01 devnull case 720 * PAL * 2: /* 625 x 8bit */
80 28994509 2004-04-21 devnull bits = 8;
81 28994509 2004-04-21 devnull lines = PAL;
83 cbeb0b26 2006-04-01 devnull case 720 * NTSC * 2: /* 525 x 8bit */
84 28994509 2004-04-21 devnull bits = 8;
85 28994509 2004-04-21 devnull lines = NTSC;
87 cbeb0b26 2006-04-01 devnull case 720 * PAL * 2 + (720 * PAL / 2) : /* 625 x 10bit */
88 28994509 2004-04-21 devnull bits = 10;
89 28994509 2004-04-21 devnull lines = PAL;
91 cbeb0b26 2006-04-01 devnull case 720 * NTSC * 2 + (720 * NTSC / 2) : /* 525 x 10bit */
92 28994509 2004-04-21 devnull bits = 10;
93 28994509 2004-04-21 devnull lines = NTSC;
96 28994509 2004-04-21 devnull e = "unknown file size";
97 28994509 2004-04-21 devnull goto Error;
100 cbeb0b26 2006-04-01 devnull /* print("bits=%d pixels=%d lines=%d\n", bits, 720, lines); */
102 28994509 2004-04-21 devnull a->nchans = 3;
103 28994509 2004-04-21 devnull a->chandesc = CRGB;
104 28994509 2004-04-21 devnull a->chanlen = 720 * lines;
105 28994509 2004-04-21 devnull a->r = Rect(0, 0, 720, lines);
107 28994509 2004-04-21 devnull e = "no memory";
108 28994509 2004-04-21 devnull if ((frm = malloc(720 * 2 * lines * sizeof(ushort))) == nil)
109 28994509 2004-04-21 devnull goto Error;
111 28994509 2004-04-21 devnull for (c = 0; c < 3; c++)
112 28994509 2004-04-21 devnull if ((a->chans[c] = malloc(720 * lines)) == nil)
113 28994509 2004-04-21 devnull goto Error;
115 28994509 2004-04-21 devnull e = "read file";
116 28994509 2004-04-21 devnull for (l = 0; l < lines; l++) {
117 28994509 2004-04-21 devnull if (Bread(bp, buf, 720 * 2) == -1)
118 28994509 2004-04-21 devnull goto Error;
120 28994509 2004-04-21 devnull base = l * 720 * 2;
121 28994509 2004-04-21 devnull for (w = 0; w < 720 * 2; w++)
122 28994509 2004-04-21 devnull frm[base + w] = ((ushort)buf[w]) << 2;
126 28994509 2004-04-21 devnull if (bits == 10)
127 28994509 2004-04-21 devnull for (l = 0; l < lines; l++) {
128 28994509 2004-04-21 devnull if (Bread(bp, buf, 720 / 2) == -1)
129 28994509 2004-04-21 devnull goto Error;
132 28994509 2004-04-21 devnull base = l * 720 * 2;
133 28994509 2004-04-21 devnull for (w = 0; w < 720 * 2; w++)
134 28994509 2004-04-21 devnull frm[base + w] |= buf[w / 4] >> lsbtab[w % 4];
137 28994509 2004-04-21 devnull mux = frm;
138 28994509 2004-04-21 devnull end = frm + 720 * lines * 2;
139 28994509 2004-04-21 devnull r = a->chans[0];
140 28994509 2004-04-21 devnull g = a->chans[1];
141 28994509 2004-04-21 devnull b = a->chans[2];
143 28994509 2004-04-21 devnull while (mux < end) {
144 28994509 2004-04-21 devnull cb = *mux++ - 512;
145 28994509 2004-04-21 devnull y1 = (*mux++ - 64) * 76310;
146 28994509 2004-04-21 devnull cr = *mux++ - 512;
147 28994509 2004-04-21 devnull y2 = (*mux++ - 64) * 76310;
149 28994509 2004-04-21 devnull *r++ = clip((104635 * cr) + y1);
150 28994509 2004-04-21 devnull *g++ = clip((-25690 * cb + -53294 * cr) + y1);
151 28994509 2004-04-21 devnull *b++ = clip((132278 * cb) + y1);
153 28994509 2004-04-21 devnull *r++ = clip((104635 * cr) + y2);
154 28994509 2004-04-21 devnull *g++ = clip((-25690 * cb + -53294 * cr) + y2);
155 28994509 2004-04-21 devnull *b++ = clip((132278 * cb) + y2);
157 28994509 2004-04-21 devnull free(frm);
158 28994509 2004-04-21 devnull return array;
162 28994509 2004-04-21 devnull errstr(ebuf, sizeof ebuf);
163 28994509 2004-04-21 devnull if (ebuf[0] == 0)
164 28994509 2004-04-21 devnull strcpy(ebuf, e);
165 28994509 2004-04-21 devnull errstr(ebuf, sizeof ebuf);
167 28994509 2004-04-21 devnull for (c = 0; c < 3; c++)
168 28994509 2004-04-21 devnull free(a->chans[c]);
169 28994509 2004-04-21 devnull free(a->cmap);
170 28994509 2004-04-21 devnull free(array[0]);
171 28994509 2004-04-21 devnull free(array);
172 28994509 2004-04-21 devnull free(frm);
173 28994509 2004-04-21 devnull return nil;
177 28994509 2004-04-21 devnull Rawimage**
178 28994509 2004-04-21 devnull readyuv(int fd, int colorspace)
180 28994509 2004-04-21 devnull Rawimage * *a;
181 28994509 2004-04-21 devnull Biobuf b;
183 28994509 2004-04-21 devnull if (Binit(&b, fd, OREAD) < 0)
184 28994509 2004-04-21 devnull return nil;
185 28994509 2004-04-21 devnull a = Breadyuv(&b, colorspace);
186 28994509 2004-04-21 devnull Bterm(&b);
187 28994509 2004-04-21 devnull return a;