1 | /*
|
---|
2 |
|
---|
3 | gbmvid.c - YUV12C M-Motion Video Frame Buffer format
|
---|
4 |
|
---|
5 | Reads and writes 24 bit RGB.
|
---|
6 |
|
---|
7 | */
|
---|
8 |
|
---|
9 | /*...sincludes:0:*/
|
---|
10 | #include <stdio.h>
|
---|
11 | #include <ctype.h>
|
---|
12 | #include <stddef.h>
|
---|
13 | #include <stdlib.h>
|
---|
14 | #include <string.h>
|
---|
15 | #include "gbm.h"
|
---|
16 | #include "gbmhelp.h"
|
---|
17 |
|
---|
18 | /*...vgbm\46\h:0:*/
|
---|
19 | /*...vgbmhelp\46\h:0:*/
|
---|
20 | /*...e*/
|
---|
21 |
|
---|
22 | /*...suseful:0:*/
|
---|
23 | #define low_byte(w) ((byte) ( (w)&0x00ff) )
|
---|
24 | #define high_byte(w) ((byte) (((unsigned)(w)&0xff00)>>8))
|
---|
25 | #define make_word(a,b) (((word)a) + (((word)b) << 8))
|
---|
26 | /*...e*/
|
---|
27 |
|
---|
28 | static GBMFT vid_gbmft =
|
---|
29 | {
|
---|
30 | "YUV12C",
|
---|
31 | "YUV12C M-Motion Video Frame Buffer",
|
---|
32 | "VID",
|
---|
33 | GBM_FT_R24|GBM_FT_W24,
|
---|
34 | };
|
---|
35 |
|
---|
36 | #define GBM_ERR_VID_BAD_W ((GBM_ERR) 1000)
|
---|
37 |
|
---|
38 | /*...svid_qft:0:*/
|
---|
39 | GBM_ERR vid_qft(GBMFT *gbmft)
|
---|
40 | {
|
---|
41 | *gbmft = vid_gbmft;
|
---|
42 | return GBM_ERR_OK;
|
---|
43 | }
|
---|
44 | /*...e*/
|
---|
45 | /*...svid_rhdr:0:*/
|
---|
46 | GBM_ERR vid_rhdr(const char *fn, int fd, GBM *gbm, const char *opt)
|
---|
47 | {
|
---|
48 | int w, h;
|
---|
49 | byte buf[16];
|
---|
50 |
|
---|
51 | fn=fn; opt=opt; /* Suppress 'unref arg' compiler warnings */
|
---|
52 |
|
---|
53 | if ( gbm_file_read(fd, buf, 16) != 16 )
|
---|
54 | return GBM_ERR_READ;
|
---|
55 |
|
---|
56 | if ( memcmp(buf, "YUV12C", 6) )
|
---|
57 | return GBM_ERR_BAD_MAGIC;
|
---|
58 |
|
---|
59 | w = make_word(buf[12], buf[13]);
|
---|
60 | h = make_word(buf[14], buf[15]);
|
---|
61 |
|
---|
62 | if ( w & 3 )
|
---|
63 | return GBM_ERR_VID_BAD_W;
|
---|
64 |
|
---|
65 | if ( w <= 0 || h <= 0 )
|
---|
66 | return GBM_ERR_BAD_SIZE;
|
---|
67 |
|
---|
68 | gbm->w = w;
|
---|
69 | gbm->h = h;
|
---|
70 | gbm->bpp = 24;
|
---|
71 |
|
---|
72 | return GBM_ERR_OK;
|
---|
73 | }
|
---|
74 | /*...e*/
|
---|
75 | /*...svid_rpal:0:*/
|
---|
76 | GBM_ERR vid_rpal(int fd, GBM *gbm, GBMRGB *gbmrgb)
|
---|
77 | {
|
---|
78 | fd=fd; gbm=gbm; gbmrgb=gbmrgb; /* Suppress 'unref arg' compiler warnings */
|
---|
79 |
|
---|
80 | return GBM_ERR_OK;
|
---|
81 | }
|
---|
82 | /*...e*/
|
---|
83 | /*...svid_rdata:0:*/
|
---|
84 | /*...sdata tables:0:*/
|
---|
85 | static short tab1[] =
|
---|
86 | {
|
---|
87 | 0,2,5,8,11,14,17,20,
|
---|
88 | 22,25,28,31,34,37,40,42,
|
---|
89 | 45,48,51,54,57,60,62,65,
|
---|
90 | 68,71,74,77,80,82,85,88,
|
---|
91 | 91,94,97,100,102,105,108,111,
|
---|
92 | 114,117,120,122,125,128,131,134,
|
---|
93 | 137,140,142,145,148,151,154,157,
|
---|
94 | 160,163,165,168,171,174,177,180,
|
---|
95 | -183,-180,-177,-174,-171,-168,-165,-163,
|
---|
96 | -160,-157,-154,-151,-148,-145,-142,-140,
|
---|
97 | -137,-134,-131,-128,-125,-122,-120,-117,
|
---|
98 | -114,-111,-108,-105,-102,-100,-97,-94,
|
---|
99 | -91,-88,-85,-82,-80,-77,-74,-71,
|
---|
100 | -68,-65,-62,-60,-57,-54,-51,-48,
|
---|
101 | -45,-42,-40,-37,-34,-31,-28,-25,
|
---|
102 | -22,-20,-17,-14,-11,-8,-5,-2,
|
---|
103 | };
|
---|
104 |
|
---|
105 | static short tab2[] =
|
---|
106 | {
|
---|
107 | 0,0,-1,-1,-2,-2,-3,-3,
|
---|
108 | -4,-4,-5,-5,-6,-7,-7,-8,
|
---|
109 | -8,-9,-9,-10,-10,-11,-11,-12,
|
---|
110 | -13,-13,-14,-14,-15,-15,-16,-16,
|
---|
111 | -17,-17,-18,-19,-19,-20,-20,-21,
|
---|
112 | -21,-22,-22,-23,-23,-24,-24,-25,
|
---|
113 | -26,-26,-27,-27,-28,-28,-29,-29,
|
---|
114 | -30,-30,-31,-32,-32,-33,-33,-34,
|
---|
115 | 34,34,33,33,32,32,31,30,
|
---|
116 | 30,29,29,28,28,27,27,26,
|
---|
117 | 26,25,24,24,23,23,22,22,
|
---|
118 | 21,21,20,20,19,19,18,17,
|
---|
119 | 17,16,16,15,15,14,14,13,
|
---|
120 | 13,12,11,11,10,10,9,9,
|
---|
121 | 8,8,7,7,6,5,5,4,
|
---|
122 | 4,3,3,2,2,1,1,0,
|
---|
123 | };
|
---|
124 |
|
---|
125 | static short tab3[] =
|
---|
126 | {
|
---|
127 | 0,-1,-2,-3,-4,-5,-6,-8,
|
---|
128 | -9,-10,-11,-12,-13,-14,-16,-17,
|
---|
129 | -18,-19,-20,-21,-23,-24,-25,-26,
|
---|
130 | -27,-28,-29,-31,-32,-33,-34,-35,
|
---|
131 | -36,-37,-39,-40,-41,-42,-43,-44,
|
---|
132 | -46,-47,-48,-49,-50,-51,-52,-54,
|
---|
133 | -55,-56,-57,-58,-59,-60,-62,-63,
|
---|
134 | -64,-65,-66,-67,-69,-70,-71,-72,
|
---|
135 | 73,72,71,70,69,67,66,65,
|
---|
136 | 64,63,62,60,59,58,57,56,
|
---|
137 | 55,54,52,51,50,49,48,47,
|
---|
138 | 46,44,43,42,41,40,39,37,
|
---|
139 | 36,35,34,33,32,31,29,28,
|
---|
140 | 27,26,25,24,23,21,20,19,
|
---|
141 | 18,17,16,14,13,12,11,10,
|
---|
142 | 9,8,6,5,4,3,2,1,
|
---|
143 | };
|
---|
144 |
|
---|
145 | static short tab4[] =
|
---|
146 | {
|
---|
147 | 0,2,4,6,9,11,13,15,
|
---|
148 | 18,20,22,24,27,29,31,33,
|
---|
149 | 36,38,40,42,45,47,49,51,
|
---|
150 | 54,56,58,60,63,65,67,69,
|
---|
151 | 72,74,76,78,81,83,85,87,
|
---|
152 | 90,92,94,96,99,101,103,105,
|
---|
153 | 108,110,112,115,117,119,121,124,
|
---|
154 | 126,128,130,133,135,137,139,142,
|
---|
155 | -144,-142,-139,-137,-135,-133,-130,-128,
|
---|
156 | -126,-124,-121,-119,-117,-115,-112,-110,
|
---|
157 | -108,-105,-103,-101,-99,-96,-94,-92,
|
---|
158 | -90,-87,-85,-83,-81,-78,-76,-74,
|
---|
159 | -72,-69,-67,-65,-63,-60,-58,-56,
|
---|
160 | -54,-51,-49,-47,-45,-42,-40,-38,
|
---|
161 | -36,-33,-31,-29,-27,-24,-22,-20,
|
---|
162 | -18,-15,-13,-11,-9,-6,-4,-2,
|
---|
163 | };
|
---|
164 |
|
---|
165 | #ifdef NEVER
|
---|
166 | static void make_tables(void)
|
---|
167 | {
|
---|
168 | int i;
|
---|
169 | signed char j;
|
---|
170 |
|
---|
171 | for ( i = 0, j = 0; i < 0x80; i++, j += 2 )
|
---|
172 | {
|
---|
173 | #ifdef NEVER
|
---|
174 | /* Version 1 */
|
---|
175 | tab1[i] = (short) ( 1.7874 * j);
|
---|
176 | tab2[i] = (short) (-0.3396 * j);
|
---|
177 | tab3[i] = (short) (-0.7188 * j);
|
---|
178 | tab4[i] = (short) ( 1.4094 * j);
|
---|
179 | #endif
|
---|
180 | /* Version 2, 80% Saturation */
|
---|
181 | tab1[i] = (short) ( 1.4299 * j);
|
---|
182 | tab2[i] = (short) (-0.2717 * j);
|
---|
183 | tab3[i] = (short) (-0.5751 * j);
|
---|
184 | tab4[i] = (short) ( 1.1275 * j);
|
---|
185 | }
|
---|
186 | }
|
---|
187 | #endif
|
---|
188 | /*...e*/
|
---|
189 | /*...sdecode_sites:0:*/
|
---|
190 | /*
|
---|
191 |
|
---|
192 | Supplied wordwise:
|
---|
193 |
|
---|
194 | Which pixel: 00000000 11111111 2222 2222 33333333
|
---|
195 | What comp: uuvvyyyyyyyguuvv yyyyyyyguuvvyyyy yyygu_v_yyyyyyyg
|
---|
196 | Bit posn: 76767654321 5454 7654321 32327654 321 1 1 7654321
|
---|
197 |
|
---|
198 | Supplied bytewise:
|
---|
199 |
|
---|
200 | Which pixel: 0000 0000 2222 11111111 33333333 2222
|
---|
201 | What comp: yyyguuvv uuvvyyyy uuvvyyyy yyyyyyyg yyyyyyyg yyygu_v_
|
---|
202 | Bit posn: 321 5454 76767654 32327654 7654321 7654321 321 1 1
|
---|
203 |
|
---|
204 | Desired:
|
---|
205 |
|
---|
206 | Which pixel: 00000000 11111111 22222222 33333333
|
---|
207 | What comp: yyyyyyy_ yyyyyyy_ yyyyyyy_ yyyyyyy_ uuuuuuu_ vvvvvvv_
|
---|
208 |
|
---|
209 | */
|
---|
210 |
|
---|
211 | static void decode_sites(byte *src, byte *dest, int n_sites)
|
---|
212 | {
|
---|
213 | for ( ; n_sites--; src += 6 )
|
---|
214 | {
|
---|
215 | *dest++ = (byte) ( ((byte) (src[0] & 0xe0)>>4) |
|
---|
216 | ((byte) (src[1] & 0x0f)<<4) );
|
---|
217 | *dest++ = (byte) (byte) (src[3] & 0xfe) ;
|
---|
218 | *dest++ = (byte) ( ((byte) (src[2] & 0x0f)<<4) |
|
---|
219 | ((byte) (src[5] & 0xe0)>>4) );
|
---|
220 | *dest++ = (byte) (byte) (src[4] & 0xfe) ;
|
---|
221 | *dest++ = (byte) ( ((byte) (src[0] & 0x0c)<<2) |
|
---|
222 | (byte) (src[1] & 0xc0) |
|
---|
223 | ((byte) (src[2] & 0xc0)>>4) |
|
---|
224 | ((byte) (src[5] & 0x08)>>2) );
|
---|
225 | *dest++ = (byte) ( ((byte) (src[0] & 0x03)<<4) |
|
---|
226 | ((byte) (src[1] & 0x30)<<2) |
|
---|
227 | ((byte) (src[2] & 0x30)>>2) |
|
---|
228 | (byte) (src[5] & 0x02) );
|
---|
229 | }
|
---|
230 | }
|
---|
231 | /*...e*/
|
---|
232 | /*...sconvert_sites:0:*/
|
---|
233 | /*...sVersion1:0:*/
|
---|
234 | /*
|
---|
235 |
|
---|
236 | Site has Y1 Y2 Y3 Y4 U V.
|
---|
237 |
|
---|
238 | Input is of the form Y1 Y2 Y3 Y4 U V
|
---|
239 |
|
---|
240 | R = ( V * 179 / 127 ) + Y
|
---|
241 |
|
---|
242 | B = ( U * 227 / 127 ) + Y
|
---|
243 |
|
---|
244 | 170 * Y - 51 * R - 19 * B
|
---|
245 | G = -------------------------
|
---|
246 | 100
|
---|
247 |
|
---|
248 | Rewrite to give better optimisation ...
|
---|
249 |
|
---|
250 | R = Y + 1.4094 * V
|
---|
251 |
|
---|
252 | B = Y + 1.7874 * U
|
---|
253 |
|
---|
254 | G = Y - 0.7188 * V - 0.3396 * U
|
---|
255 |
|
---|
256 | */
|
---|
257 | /*...e*/
|
---|
258 | /*...sVersion2\44\ 80\37\ saturation \40\as recommended\41\:0:*/
|
---|
259 | /*
|
---|
260 |
|
---|
261 | Site has Y1 Y2 Y3 Y4 U V.
|
---|
262 |
|
---|
263 | Input is of the form Y1 Y2 Y3 Y4 U V
|
---|
264 |
|
---|
265 | R = 0.8 * ( V * 179 / 127 ) + Y
|
---|
266 |
|
---|
267 | B = 0.8 * ( U * 227 / 127 ) + Y
|
---|
268 |
|
---|
269 | 170 * Y - 51 * R - 19 * B
|
---|
270 | G = -------------------------
|
---|
271 | 100
|
---|
272 |
|
---|
273 | Rewrite to give better optimisation ...
|
---|
274 |
|
---|
275 | R = Y + 1.1275 * V
|
---|
276 |
|
---|
277 | B = Y + 1.4299 * U
|
---|
278 |
|
---|
279 | G = Y - 0.5751 * V - 0.2717 * U
|
---|
280 |
|
---|
281 | */
|
---|
282 | /*...e*/
|
---|
283 |
|
---|
284 | static void convert_sites(byte *src, byte *dest, int n_sites)
|
---|
285 | {
|
---|
286 | for ( ; n_sites--; src += 6 )
|
---|
287 | {
|
---|
288 | byte u = (src[4] >> 1);
|
---|
289 | byte v = (src[5] >> 1);
|
---|
290 | short tu = tab1[u];
|
---|
291 | short ts = tab2[u] + tab3[v];
|
---|
292 | short tv = tab4[v];
|
---|
293 | int p;
|
---|
294 |
|
---|
295 | for ( p = 0; p < 4; p++ )
|
---|
296 | {
|
---|
297 | short b = (short) ((unsigned short) src[p]) + tu;
|
---|
298 | short g = (short) ((unsigned short) src[p]) + ts;
|
---|
299 | short r = (short) ((unsigned short) src[p]) + tv;
|
---|
300 |
|
---|
301 | if ( b < 0 ) b = 0; else if ( b > 0xff ) b = 0xff;
|
---|
302 | if ( g < 0 ) g = 0; else if ( g > 0xff ) g = 0xff;
|
---|
303 | if ( r < 0 ) r = 0; else if ( r > 0xff ) r = 0xff;
|
---|
304 |
|
---|
305 | *dest++ = (byte) b;
|
---|
306 | *dest++ = (byte) g;
|
---|
307 | *dest++ = (byte) r;
|
---|
308 | }
|
---|
309 | }
|
---|
310 | }
|
---|
311 | /*...e*/
|
---|
312 |
|
---|
313 | GBM_ERR vid_rdata(int fd, GBM *gbm, byte *data)
|
---|
314 | {
|
---|
315 | int stride = ((gbm->w * 3 + 3) & ~3);
|
---|
316 | int n_sites = gbm->w / 4;
|
---|
317 | byte *ibuffer, *sbuffer, *p;
|
---|
318 | int i;
|
---|
319 |
|
---|
320 | if ( (ibuffer = malloc((size_t) (n_sites * 6))) == NULL )
|
---|
321 | return GBM_ERR_MEM;
|
---|
322 |
|
---|
323 | if ( (sbuffer = malloc((size_t) (n_sites * 6))) == NULL )
|
---|
324 | {
|
---|
325 | free(ibuffer);
|
---|
326 | return GBM_ERR_MEM;
|
---|
327 | }
|
---|
328 |
|
---|
329 | gbm_file_lseek(fd, 16L, SEEK_SET);
|
---|
330 |
|
---|
331 | p = data + ((gbm->h - 1) * stride);
|
---|
332 | for ( i = gbm->h - 1; i >= 0; i-- )
|
---|
333 | {
|
---|
334 | if ( gbm_file_read(fd, (char *) ibuffer, n_sites * 6) != n_sites * 6 )
|
---|
335 | {
|
---|
336 | free(sbuffer);
|
---|
337 | free(ibuffer);
|
---|
338 | return GBM_ERR_READ;
|
---|
339 | }
|
---|
340 | decode_sites(ibuffer, sbuffer, n_sites);
|
---|
341 | convert_sites(sbuffer, p, n_sites);
|
---|
342 | p -= stride;
|
---|
343 | }
|
---|
344 | free(sbuffer);
|
---|
345 | free(ibuffer);
|
---|
346 | return GBM_ERR_OK;
|
---|
347 | }
|
---|
348 | /*...e*/
|
---|
349 | /*...svid_w:0:*/
|
---|
350 | /*...sconvert_to_yuv:0:*/
|
---|
351 | /*...sVersion1:0:*/
|
---|
352 | /*
|
---|
353 |
|
---|
354 | Y = 51 * R + 100 * G + 19 * B
|
---|
355 | -------------------------
|
---|
356 | 170
|
---|
357 |
|
---|
358 | U = ( B - Y ) * 127 / 227
|
---|
359 |
|
---|
360 | V = ( R - Y ) * 127 / 179
|
---|
361 |
|
---|
362 | */
|
---|
363 | /*...e*/
|
---|
364 | /*...sVersion2\44\ 80\37\ saturation \40\as recommended\41\:0:*/
|
---|
365 | /*
|
---|
366 |
|
---|
367 | Y = 51 * R + 100 * G + 19 * B
|
---|
368 | -------------------------
|
---|
369 | 170
|
---|
370 |
|
---|
371 | U = (1 / 0.8) * ( B - Y ) * 127 / 227
|
---|
372 |
|
---|
373 | V = (1 / 0.8) * ( R - Y ) * 127 / 179
|
---|
374 |
|
---|
375 | */
|
---|
376 | /*...e*/
|
---|
377 |
|
---|
378 | static void convert_to_yuv(const byte *src, byte *dest, int n_sites)
|
---|
379 | {
|
---|
380 | while ( n_sites-- )
|
---|
381 | {
|
---|
382 | short u = 0, v = 0;
|
---|
383 | int i;
|
---|
384 |
|
---|
385 | for ( i = 0; i < 4; i++ )
|
---|
386 | {
|
---|
387 | byte b = *src++;
|
---|
388 | byte g = *src++;
|
---|
389 | byte r = *src++;
|
---|
390 | short y = ( 51 * r + 100 * g + 19 * b ) / 170;
|
---|
391 |
|
---|
392 | u += ( (b - y) * (127 * 5) / (227 * 4) );
|
---|
393 | v += ( (r - y) * (127 * 5) / (179 * 4) );
|
---|
394 |
|
---|
395 | if ( y < 0 ) y = 0; else if ( y > 0xff ) y = 0xff;
|
---|
396 |
|
---|
397 | *dest++ = (byte) (y & 0xfe);
|
---|
398 | }
|
---|
399 |
|
---|
400 | u >>= 2; v >>= 2;
|
---|
401 |
|
---|
402 | if ( u < -0x80 ) u = -0x80; else if ( u > 0x7f ) u = 0x7f;
|
---|
403 | if ( v < -0x80 ) v = -0x80; else if ( v > 0x7f ) v = 0x7f;
|
---|
404 |
|
---|
405 | *dest++ = (byte) (u & 0xfe);
|
---|
406 | *dest++ = (byte) (v & 0xfe);
|
---|
407 | }
|
---|
408 | }
|
---|
409 | /*...e*/
|
---|
410 | /*...sencode_sites:0:*/
|
---|
411 | /*
|
---|
412 |
|
---|
413 | Supplied:
|
---|
414 |
|
---|
415 | Which pixel: 00000000 11111111 22222222 33333333
|
---|
416 | What comp: yyyyyyy_ yyyyyyy_ yyyyyyy_ yyyyyyy_ uuuuuuu_ vvvvvvv_
|
---|
417 |
|
---|
418 | Desired bytewise:
|
---|
419 |
|
---|
420 | Which pixel: 0000 0000 2222 11111111 33333333 2222
|
---|
421 | What comp: yyyguuvv uuvvyyyy uuvvyyyy yyyyyyyg yyyyyyyg yyygu_v_
|
---|
422 | Bit posn: 321 5454 76767654 32327654 7654321 7654321 321 1 1
|
---|
423 |
|
---|
424 | */
|
---|
425 |
|
---|
426 | static void encode_sites(const byte *src, byte *dest, int n_sites)
|
---|
427 | {
|
---|
428 | for ( ; n_sites--; src += 6 )
|
---|
429 | {
|
---|
430 | *dest++ = (byte) ( ((byte) (src[0] & 0x0e)<<4) |
|
---|
431 | ((byte) (src[4] & 0x30)>>2) |
|
---|
432 | ((byte) (src[5] & 0x30)>>4) );
|
---|
433 | *dest++ = (byte) ( (byte) (src[4] & 0xc0) |
|
---|
434 | ((byte) (src[5] & 0xc0)>>2) |
|
---|
435 | ((byte) (src[0] & 0xf0)>>4) );
|
---|
436 | *dest++ = (byte) ( ((byte) (src[4] & 0x0c)<<4) |
|
---|
437 | ((byte) (src[5] & 0x0c)<<2) |
|
---|
438 | ((byte) (src[2] & 0xf0)>>4) );
|
---|
439 | *dest++ = (byte) (byte) (src[1] & 0xfe) ;
|
---|
440 | *dest++ = (byte) (byte) (src[3] & 0xfe) ;
|
---|
441 | *dest++ = (byte) ( ((byte) (src[2] & 0x0e)<<4) |
|
---|
442 | ((byte) (src[4] & 0x02)<<2) |
|
---|
443 | (byte) (src[5] & 0x02) );
|
---|
444 | }
|
---|
445 | }
|
---|
446 | /*...e*/
|
---|
447 |
|
---|
448 | GBM_ERR vid_w(const char *fn, int fd, const GBM *gbm, const GBMRGB *gbmrgb, const byte *data, const char *opt)
|
---|
449 | {
|
---|
450 | byte buf[16];
|
---|
451 | int xpos = 0, ypos = 0;
|
---|
452 | int stride = ((gbm->w * 3 + 3) & ~3);
|
---|
453 | int n_sites = gbm->w / 4;
|
---|
454 | byte *obuffer, *sbuffer;
|
---|
455 | const byte *p;
|
---|
456 | int i;
|
---|
457 | const char *s;
|
---|
458 |
|
---|
459 | fn=fn; gbmrgb=gbmrgb; /* Suppress 'unref arg' compiler warnings */
|
---|
460 |
|
---|
461 | if ( (s = gbm_find_word_prefix(opt, "xpos=")) != NULL )
|
---|
462 | sscanf(s + 5, "%d", &xpos);
|
---|
463 |
|
---|
464 | if ( (s = gbm_find_word_prefix(opt, "ypos=")) != NULL )
|
---|
465 | sscanf(s + 5, "%d", &ypos);
|
---|
466 |
|
---|
467 | memcpy(buf, "YUV12C", 6);
|
---|
468 | buf[ 6] = 0;
|
---|
469 | buf[ 7] = 0;
|
---|
470 | buf[ 8] = low_byte(xpos);
|
---|
471 | buf[ 9] = high_byte(xpos);
|
---|
472 | buf[10] = low_byte(ypos);
|
---|
473 | buf[11] = high_byte(ypos);
|
---|
474 | buf[12] = low_byte(gbm->w & ~3);
|
---|
475 | buf[13] = high_byte(gbm->w & ~3);
|
---|
476 | buf[14] = low_byte(gbm->h);
|
---|
477 | buf[15] = high_byte(gbm->h);
|
---|
478 |
|
---|
479 | if ( gbm_file_write(fd, buf, 16) != 16 )
|
---|
480 | return GBM_ERR_WRITE;
|
---|
481 |
|
---|
482 | if ( (obuffer = malloc((size_t) (n_sites * 6))) == NULL )
|
---|
483 | return GBM_ERR_MEM;
|
---|
484 |
|
---|
485 | if ( (sbuffer = malloc((size_t) (n_sites * 6))) == NULL )
|
---|
486 | {
|
---|
487 | free(obuffer);
|
---|
488 | return GBM_ERR_MEM;
|
---|
489 | }
|
---|
490 |
|
---|
491 | p = data + ((gbm->h - 1) * stride);
|
---|
492 | for ( i = gbm->h - 1; i >= 0; i-- )
|
---|
493 | {
|
---|
494 | convert_to_yuv(p, sbuffer, n_sites);
|
---|
495 | encode_sites(sbuffer, obuffer, n_sites);
|
---|
496 | if ( gbm_file_write(fd, (char *) obuffer, n_sites * 6) != n_sites * 6 )
|
---|
497 | {
|
---|
498 | free(sbuffer);
|
---|
499 | free(obuffer);
|
---|
500 | return GBM_ERR_WRITE;
|
---|
501 | }
|
---|
502 | p -= stride;
|
---|
503 | }
|
---|
504 | free(sbuffer);
|
---|
505 | free(obuffer);
|
---|
506 |
|
---|
507 | return GBM_ERR_OK;
|
---|
508 | }
|
---|
509 | /*...e*/
|
---|
510 | /*...svid_err:0:*/
|
---|
511 | const char *vid_err(GBM_ERR rc)
|
---|
512 | {
|
---|
513 | switch ( (int) rc )
|
---|
514 | {
|
---|
515 | case GBM_ERR_VID_BAD_W:
|
---|
516 | return "width not a multiple of 4 pixels";
|
---|
517 | }
|
---|
518 | return NULL;
|
---|
519 | }
|
---|
520 | /*...e*/
|
---|