Blame


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"
8 28994509 2004-04-21 devnull
9 28994509 2004-04-21 devnull /*
10 28994509 2004-04-21 devnull * ITU/CCIR Rec601 states:
11 28994509 2004-04-21 devnull *
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
15 28994509 2004-04-21 devnull *
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
24 28994509 2004-04-21 devnull */
25 28994509 2004-04-21 devnull
26 28994509 2004-04-21 devnull enum {
27 28994509 2004-04-21 devnull PAL = 576, NTSC = 486 };
28 28994509 2004-04-21 devnull
29 28994509 2004-04-21 devnull
30 28994509 2004-04-21 devnull static int lsbtab[] = { 6, 4, 2, 0};
31 28994509 2004-04-21 devnull
32 fa325e9b 2020-01-10 cross static int
33 28994509 2004-04-21 devnull clip(int x)
34 28994509 2004-04-21 devnull {
35 28994509 2004-04-21 devnull x >>= 18;
36 28994509 2004-04-21 devnull
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;
42 28994509 2004-04-21 devnull }
43 28994509 2004-04-21 devnull
44 28994509 2004-04-21 devnull
45 28994509 2004-04-21 devnull Rawimage**
46 28994509 2004-04-21 devnull Breadyuv(Biobuf *bp, int colourspace)
47 28994509 2004-04-21 devnull {
48 28994509 2004-04-21 devnull Dir * d;
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;
54 28994509 2004-04-21 devnull
55 28994509 2004-04-21 devnull frm = 0;
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;
60 28994509 2004-04-21 devnull }
61 28994509 2004-04-21 devnull
62 28994509 2004-04-21 devnull if ((a = calloc(sizeof(Rawimage), 1)) == nil)
63 28994509 2004-04-21 devnull sysfatal("no memory");
64 28994509 2004-04-21 devnull
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;
69 28994509 2004-04-21 devnull
70 28994509 2004-04-21 devnull if ((d = dirfstat(Bfildes(bp))) != nil) {
71 28994509 2004-04-21 devnull sz = d->length;
72 28994509 2004-04-21 devnull free(d);
73 28994509 2004-04-21 devnull } else {
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);
76 28994509 2004-04-21 devnull }
77 28994509 2004-04-21 devnull
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;
82 28994509 2004-04-21 devnull break;
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;
86 28994509 2004-04-21 devnull break;
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;
90 28994509 2004-04-21 devnull break;
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;
94 28994509 2004-04-21 devnull break;
95 28994509 2004-04-21 devnull default:
96 28994509 2004-04-21 devnull e = "unknown file size";
97 28994509 2004-04-21 devnull goto Error;
98 28994509 2004-04-21 devnull }
99 28994509 2004-04-21 devnull
100 cbeb0b26 2006-04-01 devnull /* print("bits=%d pixels=%d lines=%d\n", bits, 720, lines); */
101 cbeb0b26 2006-04-01 devnull /* */
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);
106 28994509 2004-04-21 devnull
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;
110 28994509 2004-04-21 devnull
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;
114 28994509 2004-04-21 devnull
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;
119 28994509 2004-04-21 devnull
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;
123 28994509 2004-04-21 devnull }
124 28994509 2004-04-21 devnull
125 28994509 2004-04-21 devnull
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;
130 28994509 2004-04-21 devnull
131 28994509 2004-04-21 devnull
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];
135 28994509 2004-04-21 devnull }
136 28994509 2004-04-21 devnull
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];
142 28994509 2004-04-21 devnull
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;
148 28994509 2004-04-21 devnull
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);
152 28994509 2004-04-21 devnull
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);
156 28994509 2004-04-21 devnull }
157 28994509 2004-04-21 devnull free(frm);
158 28994509 2004-04-21 devnull return array;
159 28994509 2004-04-21 devnull
160 28994509 2004-04-21 devnull Error:
161 28994509 2004-04-21 devnull
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);
166 28994509 2004-04-21 devnull
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;
174 28994509 2004-04-21 devnull }
175 28994509 2004-04-21 devnull
176 28994509 2004-04-21 devnull
177 28994509 2004-04-21 devnull Rawimage**
178 28994509 2004-04-21 devnull readyuv(int fd, int colorspace)
179 28994509 2004-04-21 devnull {
180 28994509 2004-04-21 devnull Rawimage * *a;
181 28994509 2004-04-21 devnull Biobuf b;
182 28994509 2004-04-21 devnull
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;
188 28994509 2004-04-21 devnull }