comparison libmpcodecs/vd_huffyuv.c @ 5235:3e04fd1074d3

added HuffYUV support, courtesy of Roberto Togni <rtogni@bresciaonline.it>
author melanson
date Thu, 21 Mar 2002 01:21:49 +0000
parents
children 9e80ac615570
comparison
equal deleted inserted replaced
5234:781a155f76cf 5235:3e04fd1074d3
1 /*
2 *
3 * HuffYUV Decoder for Mplayer
4 * (c) 2002 Roberto Togni
5 *
6 * Fourcc: HFYU
7 *
8 * Original Win32 codec copyright:
9 *
10 *** Huffyuv v2.1.1, by Ben Rudiak-Gould.
11 *** http://www.math.berkeley.edu/~benrg/huffyuv.html
12 ***
13 *** This file is copyright 2000 Ben Rudiak-Gould, and distributed under
14 *** the terms of the GNU General Public License, v2 or later. See
15 *** http://www.gnu.org/copyleft/gpl.html.
16 *
17 */
18
19 #include <stdio.h>
20 #include <stdlib.h>
21
22 #include "config.h"
23 #include "mp_msg.h"
24
25 #include "vd_internal.h"
26
27
28 static vd_info_t info = {
29 "HuffYUV Video decoder",
30 "huffyuv",
31 VFM_HUFFYUV,
32 "Roberto Togni",
33 "Roberto Togni",
34 "native codec, original win32 by Ben Rudiak-Gould http://www.math.berkeley.edu/~benrg/huffyuv.html"
35 };
36
37 LIBVD_EXTERN(huffyuv)
38
39
40 /*
41 * Bitmap types
42 */
43 #define BMPTYPE_YUV -1
44 #define BMPTYPE_RGB -2
45 #define BMPTYPE_RGBA -3
46
47 /*
48 * Compression methods
49 */
50 #define METHOD_LEFT 0
51 #define METHOD_GRAD 1
52 #define METHOD_MEDIAN 2
53 #define DECORR_FLAG 64
54 #define METHOD_LEFT_DECORR (METHOD_LEFT | DECORR_FLAG)
55 #define METHOD_GRAD_DECORR (METHOD_GRAD | DECORR_FLAG)
56 #define METHOD_OLD -2
57
58 #define FOURCC_HFYU mmioFOURCC('H','F','Y','U')
59
60 #define HUFFTABLE_CLASSIC_YUV ((unsigned char*) -1)
61 #define HUFFTABLE_CLASSIC_RGB ((unsigned char*) -2)
62 #define HUFFTABLE_CLASSIC_YUV_CHROMA ((unsigned char*) -3)
63
64
65 /*
66 * Huffman table
67 */
68 typedef struct {
69 unsigned char* table_pointers[32];
70 unsigned char table_data[129*25];
71 } DecodeTable;
72
73
74 /*
75 * Decoder context
76 */
77 typedef struct {
78 // Real image depth
79 int bitcount;
80 // Prediction method
81 int method;
82 // Bitmap color type
83 int bitmaptype;
84 // Huffman tables
85 unsigned char decode1_shift[256];
86 unsigned char decode2_shift[256];
87 unsigned char decode3_shift[256];
88 DecodeTable decode1, decode2, decode3;
89 // Above line buffers
90 unsigned char *abovebuf1, *abovebuf2;
91 } huffyuv_context_t;
92
93
94 /*
95 * Classic Huffman tables
96 */
97 unsigned char classic_shift_luma[] = {
98 34,36,35,69,135,232,9,16,10,24,11,23,12,16,13,10,14,8,15,8,
99 16,8,17,20,16,10,207,206,205,236,11,8,10,21,9,23,8,8,199,70,
100 69,68, 0
101 };
102
103 unsigned char classic_shift_chroma[] = {
104 66,36,37,38,39,40,41,75,76,77,110,239,144,81,82,83,84,85,118,183,
105 56,57,88,89,56,89,154,57,58,57,26,141,57,56,58,57,58,57,184,119,
106 214,245,116,83,82,49,80,79,78,77,44,75,41,40,39,38,37,36,34, 0
107 };
108
109 unsigned char classic_add_luma[256] = {
110 3, 9, 5, 12, 10, 35, 32, 29, 27, 50, 48, 45, 44, 41, 39, 37,
111 73, 70, 68, 65, 64, 61, 58, 56, 53, 50, 49, 46, 44, 41, 38, 36,
112 68, 65, 63, 61, 58, 55, 53, 51, 48, 46, 45, 43, 41, 39, 38, 36,
113 35, 33, 32, 30, 29, 27, 26, 25, 48, 47, 46, 44, 43, 41, 40, 39,
114 37, 36, 35, 34, 32, 31, 30, 28, 27, 26, 24, 23, 22, 20, 19, 37,
115 35, 34, 33, 31, 30, 29, 27, 26, 24, 23, 21, 20, 18, 17, 15, 29,
116 27, 26, 24, 22, 21, 19, 17, 16, 14, 26, 25, 23, 21, 19, 18, 16,
117 15, 27, 25, 23, 21, 19, 17, 16, 14, 26, 25, 23, 21, 18, 17, 14,
118 12, 17, 19, 13, 4, 9, 2, 11, 1, 7, 8, 0, 16, 3, 14, 6,
119 12, 10, 5, 15, 18, 11, 10, 13, 15, 16, 19, 20, 22, 24, 27, 15,
120 18, 20, 22, 24, 26, 14, 17, 20, 22, 24, 27, 15, 18, 20, 23, 25,
121 28, 16, 19, 22, 25, 28, 32, 36, 21, 25, 29, 33, 38, 42, 45, 49,
122 28, 31, 34, 37, 40, 42, 44, 47, 49, 50, 52, 54, 56, 57, 59, 60,
123 62, 64, 66, 67, 69, 35, 37, 39, 40, 42, 43, 45, 47, 48, 51, 52,
124 54, 55, 57, 59, 60, 62, 63, 66, 67, 69, 71, 72, 38, 40, 42, 43,
125 46, 47, 49, 51, 26, 28, 30, 31, 33, 34, 18, 19, 11, 13, 7, 8,
126 };
127
128 unsigned char classic_add_chroma[256] = {
129 3, 1, 2, 2, 2, 2, 3, 3, 7, 5, 7, 5, 8, 6, 11, 9,
130 7, 13, 11, 10, 9, 8, 7, 5, 9, 7, 6, 4, 7, 5, 8, 7,
131 11, 8, 13, 11, 19, 15, 22, 23, 20, 33, 32, 28, 27, 29, 51, 77,
132 43, 45, 76, 81, 46, 82, 75, 55, 56,144, 58, 80, 60, 74,147, 63,
133 143, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
134 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 27, 30, 21, 22,
135 17, 14, 5, 6,100, 54, 47, 50, 51, 53,106,107,108,109,110,111,
136 112,113,114,115, 4,117,118, 92, 94,121,122, 3,124,103, 2, 1,
137 0,129,130,131,120,119,126,125,136,137,138,139,140,141,142,134,
138 135,132,133,104, 64,101, 62, 57,102, 95, 93, 59, 61, 28, 97, 96,
139 52, 49, 48, 29, 32, 25, 24, 46, 23, 98, 45, 44, 43, 20, 42, 41,
140 19, 18, 99, 40, 15, 39, 38, 16, 13, 12, 11, 37, 10, 9, 8, 36,
141 7,128,127,105,123,116, 35, 34, 33,145, 31, 79, 42,146, 78, 26,
142 83, 48, 49, 50, 44, 47, 26, 31, 30, 18, 17, 19, 21, 24, 25, 13,
143 14, 16, 17, 18, 20, 21, 12, 14, 15, 9, 10, 6, 9, 6, 5, 8,
144 6, 12, 8, 10, 7, 9, 6, 4, 6, 2, 2, 3, 3, 3, 3, 2,
145 };
146
147
148 /*
149 * Internal function prototypes
150 */
151 unsigned char* InitializeDecodeTable(unsigned char* hufftable,
152 unsigned char* shift, DecodeTable* decode_table);
153 unsigned char* InitializeShiftAddTables(unsigned char* hufftable,
154 unsigned char* shift, unsigned* add_shifted);
155 unsigned char* DecompressHuffmanTable(unsigned char* hufftable,
156 unsigned char* dst);
157 unsigned char huff_decompress(unsigned int* in, unsigned int *pos,
158 DecodeTable *decode_table, unsigned char *decode_shift);
159
160
161
162
163 // to set/get/query special features/parameters
164 static int control(sh_video_t *sh,int cmd,void* arg,...){
165 return CONTROL_UNKNOWN;
166 }
167
168
169 /*
170 *
171 * Init HuffYUV decoder
172 *
173 */
174 static int init(sh_video_t *sh)
175 {
176 int vo_ret; // Video output init ret value
177 huffyuv_context_t *hc; // Decoder context
178 unsigned char *hufftable; // Compressed huffman tables
179 BITMAPINFOHEADER *bih = sh->bih;
180
181 if ((hc = malloc(sizeof(huffyuv_context_t))) == NULL) {
182 mp_msg(MSGT_DECVIDEO, MSGL_ERR, "Can't allocate memory for HuffYUV decoder context\n");
183 return 0;
184 }
185
186 sh->context = (void *)hc;
187
188 mp_msg(MSGT_DECVIDEO, MSGL_V, "[HuffYUV] Allocating above line buffer\n");
189 if ((hc->abovebuf1 = malloc(sizeof(char) * 4 * bih->biWidth)) == NULL) {
190 mp_msg(MSGT_DECVIDEO, MSGL_ERR, "Can't allocate memory for HuffYUV above buffer 1\n");
191 return 0;
192 }
193
194 if ((hc->abovebuf2 = malloc(sizeof(char) * 4 * bih->biWidth)) == NULL) {
195 mp_msg(MSGT_DECVIDEO, MSGL_ERR, "Can't allocate memory for HuffYUV above buffer 2\n");
196 return 0;
197 }
198
199 if (bih->biCompression != FOURCC_HFYU) {
200 mp_msg(MSGT_DECVIDEO, MSGL_WARN, "[HuffYUV] BITMAPHEADER fourcc != HFYU\n");
201 return 0;
202 }
203
204 /* Get bitcount */
205 hc->bitcount = 0;
206 if (bih->biSize > sizeof(BITMAPINFOHEADER)+1)
207 hc->bitcount = *((char*)bih + sizeof(BITMAPINFOHEADER) + 1);
208 if (hc->bitcount == 0)
209 hc->bitcount = bih->biBitCount;
210
211 /* Get bitmap type */
212 switch (hc->bitcount & ~7) {
213 case 16:
214 hc->bitmaptype = BMPTYPE_YUV; // -1
215 mp_msg(MSGT_DECVIDEO, MSGL_V, "[HuffYUV] Image type is YUV\n");
216 break;
217 case 24:
218 hc->bitmaptype = BMPTYPE_RGB; // -2
219 mp_msg(MSGT_DECVIDEO, MSGL_V, "[HuffYUV] Image type is RGB\n");
220 break;
221 case 32:
222 hc->bitmaptype = BMPTYPE_RGBA; //-3
223 mp_msg(MSGT_DECVIDEO, MSGL_V, "[HuffYUV] Image type is RGBA\n");
224 break;
225 default:
226 hc->bitmaptype = 0; // ERR
227 mp_msg(MSGT_DECVIDEO, MSGL_WARN, "[HuffYUV] Image type is unknown\n");
228 }
229
230 /* Get method */
231 switch (bih->biBitCount & 7) {
232 case 0:
233 if (bih->biSize > sizeof(BITMAPINFOHEADER)) {
234 hc->method = *((unsigned char*)bih + sizeof(BITMAPINFOHEADER));
235 mp_msg(MSGT_DECVIDEO, MSGL_V, "[HuffYUV] Method stored in extra data\n");
236 } else
237 hc->method = METHOD_OLD; // Is it really needed?
238 break;
239 case 1:
240 hc->method = METHOD_LEFT;
241 break;
242 case 2:
243 hc->method = METHOD_LEFT_DECORR;
244 break;
245 case 3:
246 if (hc->bitmaptype == BMPTYPE_YUV) {
247 hc->method = METHOD_GRAD;
248 } else {
249 hc->method = METHOD_GRAD_DECORR;
250 }
251 break;
252 case 4:
253 hc->method = METHOD_MEDIAN;
254 break;
255 default:
256 mp_msg(MSGT_DECVIDEO, MSGL_V, "[HuffYUV] Method: fallback to METHOD_OLD\n");
257 hc->method = METHOD_OLD;
258 }
259
260 /* Print method info */
261 switch (hc->method) {
262 case METHOD_LEFT:
263 mp_msg(MSGT_DECVIDEO, MSGL_V, "[HuffYUV] Method: Predict Left\n");
264 break;
265 case METHOD_GRAD:
266 mp_msg(MSGT_DECVIDEO, MSGL_V, "[HuffYUV] Method: Predict Gradient\n");
267 break;
268 case METHOD_MEDIAN:
269 mp_msg(MSGT_DECVIDEO, MSGL_V, "[HuffYUV] Method: Predict Median\n");
270 break;
271 case METHOD_LEFT_DECORR:
272 mp_msg(MSGT_DECVIDEO, MSGL_V, "[HuffYUV] Method: Predict Left with decorrelation\n");
273 break;
274 case METHOD_GRAD_DECORR:
275 mp_msg(MSGT_DECVIDEO, MSGL_V, "[HuffYUV] Method: Predict Gradient with decorrelation\n");
276 break;
277 case METHOD_OLD:
278 mp_msg(MSGT_DECVIDEO, MSGL_V, "[HuffYUV] Method Old\n");
279 break;
280 default:
281 mp_msg(MSGT_DECVIDEO, MSGL_WARN, "[HuffYUV] Method unknown\n");
282 }
283
284 /* Get compressed Huffman tables */
285 if (bih->biSize == sizeof(BITMAPINFOHEADER) /*&& !(bih->biBitCount&7)*/) {
286 hufftable = (hc->bitmaptype == BMPTYPE_YUV) ? HUFFTABLE_CLASSIC_YUV : HUFFTABLE_CLASSIC_RGB;
287 mp_msg(MSGT_DECVIDEO, MSGL_V, "[HuffYUV] Using classic static Huffman tables\n");
288 } else {
289 hufftable = (unsigned char*)bih + sizeof(BITMAPINFOHEADER) + ((bih->biBitCount&7) ? 0 : 4);
290 mp_msg(MSGT_DECVIDEO, MSGL_V, "[HuffYUV] Using Huffman tables stored in file\n");
291 }
292
293 /* Initialize decoder Huffman tables */
294 hufftable = InitializeDecodeTable(hufftable, hc->decode1_shift, &(hc->decode1));
295 hufftable = InitializeDecodeTable(hufftable, hc->decode2_shift, &(hc->decode2));
296 InitializeDecodeTable(hufftable, hc->decode3_shift, &(hc->decode3));
297
298 /*
299 * Initialize video output device
300 */
301 switch (hc->bitmaptype) {
302 case BMPTYPE_YUV:
303 vo_ret = mpcodecs_config_vo(sh,sh->disp_w,sh->disp_h,IMGFMT_YUY2);
304 break;
305 case BMPTYPE_RGB:
306 vo_ret = mpcodecs_config_vo(sh,sh->disp_w,sh->disp_h,IMGFMT_BGR24);
307 break;
308 case BMPTYPE_RGBA:
309 mp_msg(MSGT_DECVIDEO, MSGL_ERR, "[HuffYUV] RGBA not supported yet.\n");
310 return 0;
311 default:
312 mp_msg(MSGT_DECVIDEO, MSGL_ERR, "[HuffYUV] BUG! Unknown bitmaptype in vo config.\n");
313 return 0;
314 }
315
316 return vo_ret;
317 }
318
319
320
321
322 /*
323 *
324 * Uninit HuffYUV decoder
325 *
326 */
327 static void uninit(sh_video_t *sh)
328 {
329 if (sh->context) {
330 if (((huffyuv_context_t*)&sh->context)->abovebuf1)
331 free(((huffyuv_context_t*)sh->context)->abovebuf1);
332 if (((huffyuv_context_t*)&sh->context)->abovebuf2)
333 free(((huffyuv_context_t*)sh->context)->abovebuf2);
334 free(sh->context);
335 }
336 }
337
338
339
340 #define HUFF_DECOMPRESS_YUYV() \
341 { \
342 y1 = huff_decompress((unsigned int *)encoded, &pos, &(hc->decode1), hc->decode1_shift); \
343 u = huff_decompress((unsigned int *)encoded, &pos, &(hc->decode2), hc->decode2_shift); \
344 y2 = huff_decompress((unsigned int *)encoded, &pos, &(hc->decode1), hc->decode1_shift); \
345 v = huff_decompress((unsigned int *)encoded, &pos, &(hc->decode3), hc->decode3_shift); \
346 }
347
348
349
350 #define HUFF_DECOMPRESS_RGB_DECORR() \
351 { \
352 g = huff_decompress((unsigned int *)encoded, &pos, &(hc->decode2), hc->decode2_shift); \
353 b = huff_decompress((unsigned int *)encoded, &pos, &(hc->decode1), hc->decode1_shift); \
354 r = huff_decompress((unsigned int *)encoded, &pos, &(hc->decode3), hc->decode3_shift); \
355 }
356
357
358
359 #define HUFF_DECOMPRESS_RGB() \
360 { \
361 b = huff_decompress((unsigned int *)encoded, &pos, &(hc->decode1), hc->decode1_shift); \
362 g = huff_decompress((unsigned int *)encoded, &pos, &(hc->decode2), hc->decode2_shift); \
363 r = huff_decompress((unsigned int *)encoded, &pos, &(hc->decode3), hc->decode3_shift); \
364 }
365
366
367
368 #define MEDIAN(left, above, aboveleft) \
369 { \
370 if ((mi = (above)) > (left)) { \
371 mx = mi; \
372 mi = (left); \
373 } else \
374 mx = (left); \
375 tmp = (above) + (left) - (aboveleft); \
376 if (tmp < mi) \
377 med = mi; \
378 else if (tmp > mx) \
379 med = mx; \
380 else \
381 med = tmp; \
382 }
383
384
385
386 #define YUV_STORE1ST_ABOVEBUF() \
387 { \
388 abovebuf[0] = outptr[0] = encoded[0]; \
389 abovebuf[1] = left_u = outptr[1] = encoded[1]; \
390 abovebuf[2] = left_y = outptr[2] = encoded[2]; \
391 abovebuf[3] = left_v = outptr[3] = encoded[3]; \
392 pixel_ptr = 4; \
393 }
394
395
396
397 #define YUV_STORE1ST() \
398 { \
399 outptr[0] = encoded[0]; \
400 left_u = outptr[1] = encoded[1]; \
401 left_y = outptr[2] = encoded[2]; \
402 left_v = outptr[3] = encoded[3]; \
403 pixel_ptr = 4; \
404 }
405
406
407
408 #define RGB_STORE1ST() \
409 { \
410 pixel_ptr = (height-1)*mpi->stride[0]; \
411 left_b = outptr[pixel_ptr++] = encoded[1]; \
412 left_g = outptr[pixel_ptr++] = encoded[2]; \
413 left_r = outptr[pixel_ptr++] = encoded[3]; \
414 pixel_ptr += bgr32; \
415 }
416
417
418
419 #define RGB_STORE1ST_ABOVEBUF() \
420 { \
421 pixel_ptr = (height-1)*mpi->stride[0]; \
422 abovebuf[0] = left_b = outptr[pixel_ptr++] = encoded[1]; \
423 abovebuf[1] = left_g = outptr[pixel_ptr++] = encoded[2]; \
424 abovebuf[2] = left_r = outptr[pixel_ptr++] = encoded[3]; \
425 pixel_ptr += bgr32; \
426 }
427
428
429
430
431 #define YUV_PREDLEFT() \
432 { \
433 outptr[pixel_ptr++] = left_y += y1; \
434 outptr[pixel_ptr++] = left_u += u; \
435 outptr[pixel_ptr++] = left_y += y2; \
436 outptr[pixel_ptr++] = left_v += v; \
437 }
438
439
440
441 #define YUV_PREDLEFT_BUF(buf, offs) \
442 { \
443 (buf)[(offs)] = outptr[pixel_ptr++] = left_y += y1; \
444 (buf)[(offs)+1] = outptr[pixel_ptr++] = left_u += u; \
445 (buf)[(offs)+2] = outptr[pixel_ptr++] = left_y += y2; \
446 (buf)[(offs)+3] = outptr[pixel_ptr++] = left_v += v; \
447 }
448
449
450
451 #define YUV_PREDMED() \
452 { \
453 MEDIAN (left_y, abovebuf[col], abovebuf[col-2]); \
454 curbuf[col] = outptr[pixel_ptr++] = left_y = med + y1; \
455 MEDIAN (left_u, abovebuf[col+1], abovebuf[col+1-4]); \
456 curbuf[col+1] = outptr[pixel_ptr++] = left_u = med + u; \
457 MEDIAN (left_y, abovebuf[col+2], abovebuf[col+2-2]); \
458 curbuf[col+2] = outptr[pixel_ptr++] = left_y = med + y2; \
459 MEDIAN (left_v, abovebuf[col+3], abovebuf[col+3-4]); \
460 curbuf[col+3] = outptr[pixel_ptr++] = left_v = med + v; \
461 }
462
463
464
465 #define RGB_PREDLEFT_DECORR() \
466 { \
467 outptr[pixel_ptr++] = left_b += b + g; \
468 outptr[pixel_ptr++] = left_g += g; \
469 outptr[pixel_ptr++] = left_r += r + g; \
470 pixel_ptr += bgr32; \
471 }
472
473
474
475 #define RGB_PREDLEFT() \
476 { \
477 outptr[pixel_ptr++] = left_b += b; \
478 outptr[pixel_ptr++] = left_g += g; \
479 outptr[pixel_ptr++] = left_r += r; \
480 pixel_ptr += bgr32; \
481 }
482
483
484
485
486 /*
487 *
488 * Decode a HuffYUV frame
489 *
490 */
491 static mp_image_t* decode(sh_video_t *sh,void* data,int len,int flags)
492 {
493 mp_image_t* mpi;
494 int pixel_ptr;
495 unsigned char y1, y2, u, v, r, g, b, a;
496 unsigned char left_y, left_u, left_v, left_r, left_g, left_b;
497 unsigned char tmp, mi, mx, med;
498 unsigned char *swap;
499 int row, col;
500 unsigned int pos = 32;
501 unsigned char *encoded = (unsigned char *)data;
502 huffyuv_context_t *hc = (huffyuv_context_t *) sh->context; // Decoder context
503 unsigned char *abovebuf = hc->abovebuf1;
504 unsigned char *curbuf = hc->abovebuf2;
505 unsigned char *outptr;
506 int width = sh->disp_w; // Real image width
507 int height = sh->disp_h; // Real image height
508 int bgr32;
509
510 // skipped frame
511 if(len <= 0)
512 return NULL;
513
514 /* Do not accept stride for rgb, it gives me wrong output :-( */
515 if (hc->bitmaptype == BMPTYPE_YUV)
516 mpi=mpcodecs_get_image(sh, MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE, sh->disp_w, sh->disp_h);
517 else
518 mpi=mpcodecs_get_image(sh, MP_IMGTYPE_TEMP, 0, sh->disp_w, sh->disp_h);
519
520 if (!mpi) {
521 mp_msg(MSGT_DECVIDEO, MSGL_ERR, "Can't allocate mpi image for huffyuv codec.\n");
522 return NULL;
523 }
524
525 outptr = mpi->planes[0]; // Output image pointer
526
527 if (hc->bitmaptype == BMPTYPE_YUV) {
528 width >>= 1; // Each cycle stores two pixels
529 if (hc->method == METHOD_GRAD) {
530 /*
531 * YUV predict gradient
532 */
533 /* Store 1st pixel */
534 YUV_STORE1ST_ABOVEBUF();
535 // Decompress 1st row (always stored with left prediction)
536 for (col = 1*4; col < width*4; col += 4) {
537 HUFF_DECOMPRESS_YUYV();
538 YUV_PREDLEFT_BUF(abovebuf, col);
539 }
540 curbuf[width*4-1] = curbuf[width*4-2] = curbuf[width*4-3] = 0;
541 for (row = 1; row < height; row++) {
542 pixel_ptr = row * mpi->stride[0];
543 HUFF_DECOMPRESS_YUYV();
544 curbuf[0] = outptr[pixel_ptr++] = left_y += y1 + abovebuf[0] - curbuf[width*4-2];
545 curbuf[1] = outptr[pixel_ptr++] = left_u += u + abovebuf[1] - curbuf[width*4+1-4];
546 curbuf[2] = outptr[pixel_ptr++] = left_y += y2 + abovebuf[2] - abovebuf[0];
547 curbuf[3] = outptr[pixel_ptr++] = left_v += v + abovebuf[3] - curbuf[width*4+3-4];
548 for (col = 1*4; col < width*4; col += 4) {
549 HUFF_DECOMPRESS_YUYV();
550 curbuf[col] = outptr[pixel_ptr++] = left_y += y1 + abovebuf[col]-abovebuf[col-2];
551 curbuf[col+1] = outptr[pixel_ptr++] = left_u += u + abovebuf[col+1]-abovebuf[col+1-4];
552 curbuf[col+2] = outptr[pixel_ptr++] = left_y += y2 + abovebuf[col+2]-abovebuf[col+2-2];
553 curbuf[col+3] = outptr[pixel_ptr++] = left_v += v + abovebuf[col+3]-abovebuf[col+3-4];
554 }
555 swap = abovebuf;
556 abovebuf = curbuf;
557 curbuf = swap;
558 }
559 } else if (hc->method == METHOD_MEDIAN) {
560 /*
561 * YUV predict median
562 */
563 /* Store 1st pixel */
564 YUV_STORE1ST_ABOVEBUF();
565 // Decompress 1st row (always stored with left prediction)
566 for (col = 1*4; col < width*4; col += 4) {
567 HUFF_DECOMPRESS_YUYV();
568 YUV_PREDLEFT_BUF (abovebuf, col);
569 }
570 // Decompress 1st two pixels of 2nd row
571 pixel_ptr = mpi->stride[0];
572 HUFF_DECOMPRESS_YUYV();
573 YUV_PREDLEFT_BUF (curbuf, 0);
574 HUFF_DECOMPRESS_YUYV();
575 YUV_PREDLEFT_BUF (curbuf, 4);
576 // Complete 2nd row
577 for (col = 2*4; col < width*4; col += 4) {
578 HUFF_DECOMPRESS_YUYV();
579 YUV_PREDMED();
580 }
581 swap = abovebuf;
582 abovebuf = curbuf;
583 curbuf = swap;
584 for (row = 2; row < height; row++) {
585 pixel_ptr = row * mpi->stride[0];
586 HUFF_DECOMPRESS_YUYV();
587 MEDIAN (left_y, abovebuf[0], curbuf[width*4-2]);
588 curbuf[0] = outptr[pixel_ptr++] = left_y = med + y1;
589 MEDIAN (left_u, abovebuf[1], curbuf[width*4+1-4]);
590 curbuf[1] = outptr[pixel_ptr++] = left_u = med + u;
591 MEDIAN (left_y, abovebuf[2], abovebuf[0]);
592 curbuf[2] = outptr[pixel_ptr++] = left_y = med + y2;
593 MEDIAN (left_v, abovebuf[3], curbuf[width*4+3-4]);
594 curbuf[3] = outptr[pixel_ptr++] = left_v = med + v;
595 for (col = 1*4; col < width*4; col += 4) {
596 HUFF_DECOMPRESS_YUYV();
597 YUV_PREDMED();
598 }
599 swap = abovebuf;
600 abovebuf = curbuf;
601 curbuf = swap;
602 }
603 } else {
604 /*
605 * YUV predict left and predict old
606 */
607 /* Store 1st pixel */
608 YUV_STORE1ST();
609 // Decompress 1st row (always stored with left prediction)
610 for (col = 1*4; col < width*4; col += 4) {
611 HUFF_DECOMPRESS_YUYV();
612 YUV_PREDLEFT();
613 }
614 for (row = 1; row < height; row++) {
615 pixel_ptr = row * mpi->stride[0];
616 for (col = 0; col < width*4; col += 4) {
617 HUFF_DECOMPRESS_YUYV();
618 YUV_PREDLEFT();
619 }
620 }
621 }
622 } else {
623 bgr32 = (mpi->bpp) >> 5; // 1 if bpp = 32, 0 if bpp = 24
624 if (hc->method == METHOD_LEFT_DECORR) {
625 /*
626 * RGB predict left with decorrelation
627 */
628 /* Store 1st pixel */
629 RGB_STORE1ST();
630 // Decompress 1st row
631 for (col = 1; col < width; col ++) {
632 HUFF_DECOMPRESS_RGB_DECORR();
633 RGB_PREDLEFT_DECORR();
634 }
635 for (row = 1; row < height; row++) {
636 pixel_ptr = (height - row - 1) * mpi->stride[0];
637 for (col = 0; col < width; col++) {
638 HUFF_DECOMPRESS_RGB_DECORR();
639 RGB_PREDLEFT_DECORR();
640 }
641 }
642 } else if (hc->method == METHOD_GRAD_DECORR) {
643 /*
644 * RGB predict gradient with decorrelation
645 */
646 /* Store 1st pixel */
647 RGB_STORE1ST_ABOVEBUF();
648 // Decompress 1st row (always stored with left prediction)
649 for (col = 1*3; col < width*3; col += 3) {
650 HUFF_DECOMPRESS_RGB_DECORR();
651 abovebuf[col] = outptr[pixel_ptr++] = left_b += b + g;
652 abovebuf[col+1] = outptr[pixel_ptr++] = left_g += g;
653 abovebuf[col+2] = outptr[pixel_ptr++] = left_r += r + g;
654 pixel_ptr += bgr32;
655 }
656 curbuf[width*3-1] = curbuf[width*3-2] = curbuf[width*3-3] = 0;
657 for (row = 1; row < height; row++) {
658 pixel_ptr = (height - row - 1) * mpi->stride[0];
659 HUFF_DECOMPRESS_RGB_DECORR();
660 curbuf[0] = outptr[pixel_ptr++] = left_b += b + g + abovebuf[0] - curbuf[width*3-3];
661 curbuf[1] = outptr[pixel_ptr++] = left_g += g + abovebuf[1] - curbuf[width*3+1-3];
662 curbuf[2] = outptr[pixel_ptr++] = left_r += r + g + abovebuf[2] - curbuf[width*3+2-3];
663 pixel_ptr += bgr32;
664 for (col = 1*3; col < width*3; col += 3) {
665 HUFF_DECOMPRESS_RGB_DECORR();
666 curbuf[col] = outptr[pixel_ptr++] = left_b += b + g + abovebuf[col]-abovebuf[col-3];
667 curbuf[col+1] = outptr[pixel_ptr++] = left_g += g + abovebuf[col+1]-abovebuf[col+1-3];
668 curbuf[col+2] = outptr[pixel_ptr++] = left_r += r + g + abovebuf[col+2]-abovebuf[col+2-3];
669 pixel_ptr += bgr32;
670 }
671 swap = abovebuf;
672 abovebuf = curbuf;
673 curbuf = swap;
674 }
675 } else {
676 /*
677 * RGB predict left (no decorrelation) and predict old
678 */
679 /* Store 1st pixel */
680 RGB_STORE1ST();
681 // Decompress 1st row
682 for (col = 1; col < width; col++) {
683 HUFF_DECOMPRESS_RGB();
684 RGB_PREDLEFT();
685 }
686 for (row = 1; row < height; row++) {
687 pixel_ptr = (height - row - 1) * mpi->stride[0];
688 for (col = 0; col < width; col++) {
689 HUFF_DECOMPRESS_RGB();
690 RGB_PREDLEFT();
691 }
692 }
693 }
694 }
695
696 return mpi;
697 }
698
699
700
701 unsigned char* InitializeDecodeTable(unsigned char* hufftable,
702 unsigned char* shift, DecodeTable* decode_table)
703 {
704 unsigned int add_shifted[256];
705 char code_lengths[256];
706 char code_firstbits[256];
707 char table_lengths[32];
708 int all_zero_code=-1;
709 int i, j, k;
710 int firstbit, length, val;
711 unsigned char* p;
712 unsigned char * table;
713
714 /* Initialize shift[] and add_shifted[] */
715 hufftable = InitializeShiftAddTables(hufftable, shift, add_shifted);
716
717 memset(table_lengths, -1, 32);
718
719 /* Fill code_firstbits[], code_legths[] and table_lengths[] */
720 for (i = 0; i < 256; ++i) {
721 if (add_shifted[i]) {
722 for (firstbit = 31; firstbit >= 0; firstbit--) {
723 if (add_shifted[i] & (1 << firstbit)) {
724 code_firstbits[i] = firstbit;
725 length = shift[i] - (32 - firstbit);
726 code_lengths[i] = length;
727 table_lengths[firstbit] = max(table_lengths[firstbit], length);
728 break;
729 }
730 }
731 } else {
732 all_zero_code = i;
733 }
734 }
735
736 p = decode_table->table_data;
737 *p++ = 31;
738 *p++ = all_zero_code;
739 for (j = 0; j < 32; ++j) {
740 if (table_lengths[j] == -1) {
741 decode_table->table_pointers[j] = decode_table->table_data;
742 } else {
743 decode_table->table_pointers[j] = p;
744 *p++ = j - table_lengths[j];
745 p += 1 << table_lengths[j];
746 }
747 }
748
749 for (k=0; k<256; ++k) {
750 if (add_shifted[k]) {
751 firstbit = code_firstbits[k];
752 val = add_shifted[k] - (1 << firstbit);
753 table = decode_table->table_pointers[firstbit];
754 memset(&table[1 + (val >> table[0])], k,
755 1 << (table_lengths[firstbit] - code_lengths[k]));
756 }
757 }
758
759 return hufftable;
760 }
761
762
763
764 unsigned char* InitializeShiftAddTables(unsigned char* hufftable,
765 unsigned char* shift, unsigned* add_shifted)
766 {
767 int i, j;
768 unsigned int bits; // must be 32bit unsigned
769 int min_already_processed;
770 int max_not_processed;
771 int bit;
772
773 // special-case the old tables, since they don't fit the new rules
774 if (hufftable == HUFFTABLE_CLASSIC_YUV || hufftable == HUFFTABLE_CLASSIC_RGB) {
775 DecompressHuffmanTable(classic_shift_luma, shift);
776 for (i = 0; i < 256; ++i)
777 add_shifted[i] = classic_add_luma[i] << (32 - shift[i]);
778 return (hufftable == HUFFTABLE_CLASSIC_YUV) ? HUFFTABLE_CLASSIC_YUV_CHROMA : hufftable;
779 } else if (hufftable == HUFFTABLE_CLASSIC_YUV_CHROMA) {
780 DecompressHuffmanTable(classic_shift_chroma, shift);
781 for (i = 0; i < 256; ++i)
782 add_shifted[i] = classic_add_chroma[i] << (32 - shift[i]);
783 return hufftable;
784 }
785
786 hufftable = DecompressHuffmanTable(hufftable, shift);
787
788 // derive the actual bit patterns from the code lengths
789 min_already_processed = 32;
790 bits = 0;
791 do {
792 max_not_processed = 0;
793 for (i = 0; i < 256; ++i) {
794 if (shift[i] < min_already_processed && shift[i] > max_not_processed)
795 max_not_processed = shift[i];
796 }
797 bit = 1 << (32 - max_not_processed);
798 // assert (!(bits & (bit - 1)));
799 for (j = 0; j < 256; ++j) {
800 if (shift[j] == max_not_processed) {
801 add_shifted[j] = bits;
802 bits += bit;
803 }
804 }
805 min_already_processed = max_not_processed;
806 } while (bits & 0xFFFFFFFF);
807
808 return hufftable;
809 }
810
811
812
813 unsigned char* DecompressHuffmanTable(unsigned char* hufftable,
814 unsigned char* dst)
815 {
816 int val;
817 int repeat;
818 int i = 0;
819
820 do {
821 val = *hufftable & 31;
822 repeat = *hufftable++ >> 5;
823 if (!repeat)
824 repeat = *hufftable++;
825 while (repeat--)
826 dst[i++] = val;
827 } while (i < 256);
828
829 return hufftable;
830 }
831
832
833 unsigned char huff_decompress(unsigned int* in, unsigned int *pos, DecodeTable *decode_table,
834 unsigned char *decode_shift)
835 {
836 unsigned int word = *pos >> 5;
837 unsigned int bit = *pos & 31;
838 unsigned int val = in[word];
839 unsigned char outbyte;
840 unsigned char *tableptr;
841 int i;
842
843 if (bit)
844 val = (val << bit) | (in[word + 1] >> (32 - bit));
845 // figure out the appropriate lookup table based on the number of leading zeros
846 i = 31;
847 val |= 1;
848 while ((val & (1 << i--)) == 0);
849 val &= ~(1 << (i+1));
850 tableptr = decode_table->table_pointers[i+1];
851 val >>= *tableptr;
852
853 outbyte = tableptr[val+1];
854 *pos += decode_shift[outbyte];
855
856 return outbyte;
857 }