source: trunk/JPGPROC/source/gbmsrc/gbmvid.c@ 2

Last change on this file since 2 was 2, checked in by stevenhl, 8 years ago

Import sources from cwmm-full.zip dated 2005-03-21

File size: 11.3 KB
Line 
1/*
2
3gbmvid.c - YUV12C M-Motion Video Frame Buffer format
4
5Reads 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
28static 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:*/
39GBM_ERR vid_qft(GBMFT *gbmft)
40 {
41 *gbmft = vid_gbmft;
42 return GBM_ERR_OK;
43 }
44/*...e*/
45/*...svid_rhdr:0:*/
46GBM_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:*/
76GBM_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:*/
85static 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
105static 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
125static 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
145static 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
166static 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
192Supplied wordwise:
193
194Which pixel: 00000000 11111111 2222 2222 33333333
195What comp: uuvvyyyyyyyguuvv yyyyyyyguuvvyyyy yyygu_v_yyyyyyyg
196Bit posn: 76767654321 5454 7654321 32327654 321 1 1 7654321
197
198Supplied bytewise:
199
200Which pixel: 0000 0000 2222 11111111 33333333 2222
201What comp: yyyguuvv uuvvyyyy uuvvyyyy yyyyyyyg yyyyyyyg yyygu_v_
202Bit posn: 321 5454 76767654 32327654 7654321 7654321 321 1 1
203
204Desired:
205
206Which pixel: 00000000 11111111 22222222 33333333
207What comp: yyyyyyy_ yyyyyyy_ yyyyyyy_ yyyyyyy_ uuuuuuu_ vvvvvvv_
208
209*/
210
211static 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
236Site has Y1 Y2 Y3 Y4 U V.
237
238Input is of the form Y1 Y2 Y3 Y4 U V
239
240R = ( V * 179 / 127 ) + Y
241
242B = ( U * 227 / 127 ) + Y
243
244 170 * Y - 51 * R - 19 * B
245G = -------------------------
246 100
247
248Rewrite to give better optimisation ...
249
250R = Y + 1.4094 * V
251
252B = Y + 1.7874 * U
253
254G = Y - 0.7188 * V - 0.3396 * U
255
256*/
257/*...e*/
258/*...sVersion2\44\ 80\37\ saturation \40\as recommended\41\:0:*/
259/*
260
261Site has Y1 Y2 Y3 Y4 U V.
262
263Input is of the form Y1 Y2 Y3 Y4 U V
264
265R = 0.8 * ( V * 179 / 127 ) + Y
266
267B = 0.8 * ( U * 227 / 127 ) + Y
268
269 170 * Y - 51 * R - 19 * B
270G = -------------------------
271 100
272
273Rewrite to give better optimisation ...
274
275R = Y + 1.1275 * V
276
277B = Y + 1.4299 * U
278
279G = Y - 0.5751 * V - 0.2717 * U
280
281*/
282/*...e*/
283
284static 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
313GBM_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
354Y = 51 * R + 100 * G + 19 * B
355 -------------------------
356 170
357
358U = ( B - Y ) * 127 / 227
359
360V = ( R - Y ) * 127 / 179
361
362*/
363/*...e*/
364/*...sVersion2\44\ 80\37\ saturation \40\as recommended\41\:0:*/
365/*
366
367Y = 51 * R + 100 * G + 19 * B
368 -------------------------
369 170
370
371U = (1 / 0.8) * ( B - Y ) * 127 / 227
372
373V = (1 / 0.8) * ( R - Y ) * 127 / 179
374
375*/
376/*...e*/
377
378static 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
413Supplied:
414
415Which pixel: 00000000 11111111 22222222 33333333
416What comp: yyyyyyy_ yyyyyyy_ yyyyyyy_ yyyyyyy_ uuuuuuu_ vvvvvvv_
417
418Desired bytewise:
419
420Which pixel: 0000 0000 2222 11111111 33333333 2222
421What comp: yyyguuvv uuvvyyyy uuvvyyyy yyyyyyyg yyyyyyyg yyygu_v_
422Bit posn: 321 5454 76767654 32327654 7654321 7654321 321 1 1
423
424*/
425
426static 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
448GBM_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:*/
511const 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*/
Note: See TracBrowser for help on using the repository browser.