| 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*/
|
|---|