big endian fix (untested)
[libav.git] / libavcodec / huffyuv.c
CommitLineData
11f18faf
MN
1/*
2 * huffyuv codec for libavcodec
3 *
aaa1e4cd 4 * Copyright (c) 2002-2003 Michael Niedermayer <michaelni@gmx.at>
11f18faf
MN
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 * see http://www.pcisys.net/~melanson/codecs/huffyuv.txt for a description of
21 * the algorithm used
22 */
983e3246
MN
23
24/**
25 * @file huffyuv.c
26 * huffyuv codec for libavcodec.
27 */
11f18faf
MN
28
29#include "common.h"
30#include "avcodec.h"
31#include "dsputil.h"
32
11f18faf 33#define VLC_BITS 11
1e491e29 34
3ad7dd8c
MN
35#ifdef WORDS_BIGENDIAN
36#define B 3
37#define G 2
38#define R 1
39#else
40#define B 0
41#define G 1
42#define R 2
43#endif
44
11f18faf
MN
45typedef enum Predictor{
46 LEFT= 0,
47 PLANE,
48 MEDIAN,
49} Predictor;
50
51typedef struct HYuvContext{
52 AVCodecContext *avctx;
53 Predictor predictor;
54 GetBitContext gb;
55 PutBitContext pb;
56 int interlaced;
57 int decorrelate;
58 int bitstream_bpp;
59 int version;
60 int yuy2; //use yuy2 instead of 422P
61 int bgr32; //use bgr32 instead of bgr24
62 int width, height;
63 int flags;
64 int picture_number;
7c5ab7b8 65 int last_slice_end;
7674347b 66 uint8_t __align8 temp[3][2560];
11f18faf
MN
67 uint64_t stats[3][256];
68 uint8_t len[3][256];
69 uint32_t bits[3][256];
70 VLC vlc[3];
492cd3a9 71 AVFrame picture;
11f18faf
MN
72 uint8_t __align8 bitstream_buffer[1024*1024*3]; //FIXME dynamic alloc or some other solution
73 DSPContext dsp;
74}HYuvContext;
75
24def10e 76static const unsigned char classic_shift_luma[] = {
676b385c
MN
77 34,36,35,69,135,232,9,16,10,24,11,23,12,16,13,10,14,8,15,8,
78 16,8,17,20,16,10,207,206,205,236,11,8,10,21,9,23,8,8,199,70,
79 69,68, 0
80};
81
24def10e 82static const unsigned char classic_shift_chroma[] = {
676b385c
MN
83 66,36,37,38,39,40,41,75,76,77,110,239,144,81,82,83,84,85,118,183,
84 56,57,88,89,56,89,154,57,58,57,26,141,57,56,58,57,58,57,184,119,
85 214,245,116,83,82,49,80,79,78,77,44,75,41,40,39,38,37,36,34, 0
86};
87
24def10e 88static const unsigned char classic_add_luma[256] = {
676b385c
MN
89 3, 9, 5, 12, 10, 35, 32, 29, 27, 50, 48, 45, 44, 41, 39, 37,
90 73, 70, 68, 65, 64, 61, 58, 56, 53, 50, 49, 46, 44, 41, 38, 36,
91 68, 65, 63, 61, 58, 55, 53, 51, 48, 46, 45, 43, 41, 39, 38, 36,
92 35, 33, 32, 30, 29, 27, 26, 25, 48, 47, 46, 44, 43, 41, 40, 39,
93 37, 36, 35, 34, 32, 31, 30, 28, 27, 26, 24, 23, 22, 20, 19, 37,
94 35, 34, 33, 31, 30, 29, 27, 26, 24, 23, 21, 20, 18, 17, 15, 29,
95 27, 26, 24, 22, 21, 19, 17, 16, 14, 26, 25, 23, 21, 19, 18, 16,
96 15, 27, 25, 23, 21, 19, 17, 16, 14, 26, 25, 23, 21, 18, 17, 14,
97 12, 17, 19, 13, 4, 9, 2, 11, 1, 7, 8, 0, 16, 3, 14, 6,
98 12, 10, 5, 15, 18, 11, 10, 13, 15, 16, 19, 20, 22, 24, 27, 15,
99 18, 20, 22, 24, 26, 14, 17, 20, 22, 24, 27, 15, 18, 20, 23, 25,
100 28, 16, 19, 22, 25, 28, 32, 36, 21, 25, 29, 33, 38, 42, 45, 49,
101 28, 31, 34, 37, 40, 42, 44, 47, 49, 50, 52, 54, 56, 57, 59, 60,
102 62, 64, 66, 67, 69, 35, 37, 39, 40, 42, 43, 45, 47, 48, 51, 52,
103 54, 55, 57, 59, 60, 62, 63, 66, 67, 69, 71, 72, 38, 40, 42, 43,
104 46, 47, 49, 51, 26, 28, 30, 31, 33, 34, 18, 19, 11, 13, 7, 8,
105};
106
24def10e 107static const unsigned char classic_add_chroma[256] = {
676b385c
MN
108 3, 1, 2, 2, 2, 2, 3, 3, 7, 5, 7, 5, 8, 6, 11, 9,
109 7, 13, 11, 10, 9, 8, 7, 5, 9, 7, 6, 4, 7, 5, 8, 7,
110 11, 8, 13, 11, 19, 15, 22, 23, 20, 33, 32, 28, 27, 29, 51, 77,
111 43, 45, 76, 81, 46, 82, 75, 55, 56,144, 58, 80, 60, 74,147, 63,
112 143, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
113 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 27, 30, 21, 22,
114 17, 14, 5, 6,100, 54, 47, 50, 51, 53,106,107,108,109,110,111,
115 112,113,114,115, 4,117,118, 92, 94,121,122, 3,124,103, 2, 1,
116 0,129,130,131,120,119,126,125,136,137,138,139,140,141,142,134,
117 135,132,133,104, 64,101, 62, 57,102, 95, 93, 59, 61, 28, 97, 96,
118 52, 49, 48, 29, 32, 25, 24, 46, 23, 98, 45, 44, 43, 20, 42, 41,
119 19, 18, 99, 40, 15, 39, 38, 16, 13, 12, 11, 37, 10, 9, 8, 36,
120 7,128,127,105,123,116, 35, 34, 33,145, 31, 79, 42,146, 78, 26,
121 83, 48, 49, 50, 44, 47, 26, 31, 30, 18, 17, 19, 21, 24, 25, 13,
122 14, 16, 17, 18, 20, 21, 12, 14, 15, 9, 10, 6, 9, 6, 5, 8,
123 6, 12, 8, 10, 7, 9, 6, 4, 6, 2, 2, 3, 3, 3, 3, 2,
124};
125
11f18faf
MN
126static inline int add_left_prediction(uint8_t *dst, uint8_t *src, int w, int acc){
127 int i;
128
129 for(i=0; i<w-1; i++){
130 acc+= src[i];
131 dst[i]= acc;
132 i++;
133 acc+= src[i];
134 dst[i]= acc;
135 }
136
137 for(; i<w; i++){
138 acc+= src[i];
139 dst[i]= acc;
140 }
141
142 return acc;
143}
144
145static inline void add_median_prediction(uint8_t *dst, uint8_t *src1, uint8_t *diff, int w, int *left, int *left_top){
146 int i;
147 uint8_t l, lt;
148
149 l= *left;
150 lt= *left_top;
151
152 for(i=0; i<w; i++){
153 l= mid_pred(l, src1[i], (l + src1[i] - lt)&0xFF) + diff[i];
154 lt= src1[i];
155 dst[i]= l;
156 }
157
158 *left= l;
159 *left_top= lt;
160}
5fd74135 161
11f18faf
MN
162static inline void add_left_prediction_bgr32(uint8_t *dst, uint8_t *src, int w, int *red, int *green, int *blue){
163 int i;
164 int r,g,b;
165 r= *red;
166 g= *green;
167 b= *blue;
168
169 for(i=0; i<w; i++){
3ad7dd8c
MN
170 b+= src[4*i+B];
171 g+= src[4*i+G];
172 r+= src[4*i+R];
11f18faf 173
3ad7dd8c
MN
174 dst[4*i+B]= b;
175 dst[4*i+G]= g;
176 dst[4*i+R]= r;
11f18faf
MN
177 }
178
179 *red= r;
180 *green= g;
181 *blue= b;
182}
183
7c5ab7b8 184static inline int sub_left_prediction(HYuvContext *s, uint8_t *dst, uint8_t *src, int w, int left){
11f18faf 185 int i;
7c5ab7b8
MN
186 if(w<32){
187 for(i=0; i<w; i++){
188 const int temp= src[i];
189 dst[i]= temp - left;
190 left= temp;
191 }
192 return left;
193 }else{
194 for(i=0; i<16; i++){
195 const int temp= src[i];
196 dst[i]= temp - left;
197 left= temp;
198 }
199 s->dsp.diff_bytes(dst+16, src+16, src+15, w-16);
200 return src[w-1];
11f18faf 201 }
11f18faf 202}
2a250222 203
11f18faf
MN
204static void read_len_table(uint8_t *dst, GetBitContext *gb){
205 int i, val, repeat;
206
207 for(i=0; i<256;){
208 repeat= get_bits(gb, 3);
209 val = get_bits(gb, 5);
210 if(repeat==0)
211 repeat= get_bits(gb, 8);
212//printf("%d %d\n", val, repeat);
213 while (repeat--)
214 dst[i++] = val;
215 }
216}
217
218static int generate_bits_table(uint32_t *dst, uint8_t *len_table){
219 int len, index;
220 uint32_t bits=0;
221
222 for(len=32; len>0; len--){
11f18faf 223 for(index=0; index<256; index++){
14b74d38
MN
224 if(len_table[index]==len)
225 dst[index]= bits++;
11f18faf 226 }
14b74d38 227 if(bits & 1){
9b879566 228 av_log(NULL, AV_LOG_ERROR, "Error generating huffman table\n");
14b74d38
MN
229 return -1;
230 }
231 bits >>= 1;
11f18faf
MN
232 }
233 return 0;
234}
235
236static void generate_len_table(uint8_t *dst, uint64_t *stats, int size){
237 uint64_t counts[2*size];
238 int up[2*size];
239 int offset, i, next;
240
241 for(offset=1; ; offset<<=1){
242 for(i=0; i<size; i++){
243 counts[i]= stats[i] + offset - 1;
244 }
245
246 for(next=size; next<size*2; next++){
247 uint64_t min1, min2;
248 int min1_i, min2_i;
249
250 min1=min2= INT64_MAX;
251 min1_i= min2_i=-1;
252
253 for(i=0; i<next; i++){
254 if(min2 > counts[i]){
255 if(min1 > counts[i]){
256 min2= min1;
257 min2_i= min1_i;
258 min1= counts[i];
259 min1_i= i;
260 }else{
261 min2= counts[i];
262 min2_i= i;
263 }
264 }
265 }
266
267 if(min2==INT64_MAX) break;
268
269 counts[next]= min1 + min2;
270 counts[min1_i]=
0626afe9 271 counts[min2_i]= INT64_MAX;
11f18faf
MN
272 up[min1_i]=
273 up[min2_i]= next;
274 up[next]= -1;
275 }
276
277 for(i=0; i<size; i++){
278 int len;
279 int index=i;
280
281 for(len=0; up[index] != -1; len++)
282 index= up[index];
283
284 if(len > 32) break;
285
286 dst[i]= len;
287 }
288 if(i==size) break;
289 }
290}
291
292static int read_huffman_tables(HYuvContext *s, uint8_t *src, int length){
293 GetBitContext gb;
294 int i;
295
68f593b4 296 init_get_bits(&gb, src, length*8);
11f18faf
MN
297
298 for(i=0; i<3; i++){
299 read_len_table(s->len[i], &gb);
300
301 if(generate_bits_table(s->bits[i], s->len[i])<0){
302 return -1;
303 }
304#if 0
305for(j=0; j<256; j++){
306printf("%6X, %2d, %3d\n", s->bits[i][j], s->len[i][j], j);
307}
308#endif
309 init_vlc(&s->vlc[i], VLC_BITS, 256, s->len[i], 1, 1, s->bits[i], 4, 4);
310 }
311
312 return 0;
313}
314
315static int read_old_huffman_tables(HYuvContext *s){
676b385c 316#if 1
11f18faf
MN
317 GetBitContext gb;
318 int i;
319
68f593b4 320 init_get_bits(&gb, classic_shift_luma, sizeof(classic_shift_luma)*8);
11f18faf 321 read_len_table(s->len[0], &gb);
68f593b4 322 init_get_bits(&gb, classic_shift_chroma, sizeof(classic_shift_chroma)*8);
11f18faf
MN
323 read_len_table(s->len[1], &gb);
324
325 for(i=0; i<256; i++) s->bits[0][i] = classic_add_luma [i];
326 for(i=0; i<256; i++) s->bits[1][i] = classic_add_chroma[i];
327
328 if(s->bitstream_bpp >= 24){
329 memcpy(s->bits[1], s->bits[0], 256*sizeof(uint32_t));
330 memcpy(s->len[1] , s->len [0], 256*sizeof(uint8_t));
331 }
332 memcpy(s->bits[2], s->bits[1], 256*sizeof(uint32_t));
333 memcpy(s->len[2] , s->len [1], 256*sizeof(uint8_t));
334
335 for(i=0; i<3; i++)
336 init_vlc(&s->vlc[i], VLC_BITS, 256, s->len[i], 1, 1, s->bits[i], 4, 4);
337
338 return 0;
339#else
340 fprintf(stderr, "v1 huffyuv is not supported \n");
341 return -1;
342#endif
343}
344
345static int decode_init(AVCodecContext *avctx)
346{
347 HYuvContext *s = avctx->priv_data;
1e491e29 348 int width, height;
11f18faf
MN
349
350 s->avctx= avctx;
351 s->flags= avctx->flags;
352
1d98dca3 353 dsputil_init(&s->dsp, avctx);
11f18faf
MN
354
355 width= s->width= avctx->width;
356 height= s->height= avctx->height;
492cd3a9 357 avctx->coded_frame= &s->picture;
1e491e29 358
11f18faf
MN
359s->bgr32=1;
360 assert(width && height);
361//if(avctx->extradata)
362// printf("extradata:%X, extradata_size:%d\n", *(uint32_t*)avctx->extradata, avctx->extradata_size);
363 if(avctx->extradata_size){
152ba68c 364 if((avctx->bits_per_sample&7) && avctx->bits_per_sample != 12)
11f18faf
MN
365 s->version=1; // do such files exist at all?
366 else
367 s->version=2;
368 }else
369 s->version=0;
370
371 if(s->version==2){
372 int method;
373
374 method= ((uint8_t*)avctx->extradata)[0];
375 s->decorrelate= method&64 ? 1 : 0;
376 s->predictor= method&63;
377 s->bitstream_bpp= ((uint8_t*)avctx->extradata)[1];
378 if(s->bitstream_bpp==0)
379 s->bitstream_bpp= avctx->bits_per_sample&~7;
380
381 if(read_huffman_tables(s, ((uint8_t*)avctx->extradata)+4, avctx->extradata_size) < 0)
382 return -1;
383 }else{
384 switch(avctx->bits_per_sample&7){
385 case 1:
386 s->predictor= LEFT;
387 s->decorrelate= 0;
388 break;
389 case 2:
390 s->predictor= LEFT;
391 s->decorrelate= 1;
392 break;
393 case 3:
394 s->predictor= PLANE;
395 s->decorrelate= avctx->bits_per_sample >= 24;
396 break;
397 case 4:
398 s->predictor= MEDIAN;
399 s->decorrelate= 0;
400 break;
401 default:
402 s->predictor= LEFT; //OLD
403 s->decorrelate= 0;
404 break;
405 }
406 s->bitstream_bpp= avctx->bits_per_sample & ~7;
407
408 if(read_old_huffman_tables(s) < 0)
409 return -1;
410 }
411
412 s->interlaced= height > 288;
413
11f18faf
MN
414 switch(s->bitstream_bpp){
415 case 12:
416 avctx->pix_fmt = PIX_FMT_YUV420P;
11f18faf
MN
417 break;
418 case 16:
419 if(s->yuy2){
420 avctx->pix_fmt = PIX_FMT_YUV422;
11f18faf
MN
421 }else{
422 avctx->pix_fmt = PIX_FMT_YUV422P;
11f18faf
MN
423 }
424 break;
425 case 24:
426 case 32:
427 if(s->bgr32){
0b2612b1 428 avctx->pix_fmt = PIX_FMT_RGBA32;
11f18faf
MN
429 }else{
430 avctx->pix_fmt = PIX_FMT_BGR24;
11f18faf
MN
431 }
432 break;
433 default:
434 assert(0);
11f18faf
MN
435 }
436
437// printf("pred:%d bpp:%d hbpp:%d il:%d\n", s->predictor, s->bitstream_bpp, avctx->bits_per_sample, s->interlaced);
438
439 return 0;
440}
441
442static void store_table(HYuvContext *s, uint8_t *len){
443 int i;
444 int index= s->avctx->extradata_size;
445
446 for(i=0; i<256;){
11f18faf 447 int val= len[i];
a003ee9a 448 int repeat=0;
11f18faf 449
a003ee9a
MN
450 for(; i<256 && len[i]==val && repeat<255; i++)
451 repeat++;
11f18faf 452
a003ee9a 453 assert(val < 32 && val >0 && repeat<256 && repeat>0);
11f18faf
MN
454 if(repeat>7){
455 ((uint8_t*)s->avctx->extradata)[index++]= val;
456 ((uint8_t*)s->avctx->extradata)[index++]= repeat;
457 }else{
458 ((uint8_t*)s->avctx->extradata)[index++]= val | (repeat<<5);
459 }
460 }
461
462 s->avctx->extradata_size= index;
463}
464
465static int encode_init(AVCodecContext *avctx)
466{
467 HYuvContext *s = avctx->priv_data;
468 int i, j, width, height;
469
470 s->avctx= avctx;
471 s->flags= avctx->flags;
472
1d98dca3 473 dsputil_init(&s->dsp, avctx);
11f18faf
MN
474
475 width= s->width= avctx->width;
476 height= s->height= avctx->height;
477
478 assert(width && height);
479
8c812d73
MN
480 avctx->extradata= av_mallocz(1024*30);
481 avctx->stats_out= av_mallocz(1024*30);
11f18faf
MN
482 s->version=2;
483
492cd3a9 484 avctx->coded_frame= &s->picture;
1e491e29 485
11f18faf 486 switch(avctx->pix_fmt){
152ba68c 487 case PIX_FMT_YUV420P:
152ba68c
MN
488 s->bitstream_bpp= 12;
489 break;
11f18faf
MN
490 case PIX_FMT_YUV422P:
491 s->bitstream_bpp= 16;
492 break;
493 default:
9b879566 494 av_log(avctx, AV_LOG_ERROR, "format not supported\n");
11f18faf
MN
495 return -1;
496 }
497 avctx->bits_per_sample= s->bitstream_bpp;
498 s->decorrelate= s->bitstream_bpp >= 24;
499 s->predictor= avctx->prediction_method;
500
501 ((uint8_t*)avctx->extradata)[0]= s->predictor;
502 ((uint8_t*)avctx->extradata)[1]= s->bitstream_bpp;
503 ((uint8_t*)avctx->extradata)[2]=
504 ((uint8_t*)avctx->extradata)[3]= 0;
505 s->avctx->extradata_size= 4;
506
507 if(avctx->stats_in){
508 char *p= avctx->stats_in;
509
510 for(i=0; i<3; i++)
511 for(j=0; j<256; j++)
512 s->stats[i][j]= 1;
513
514 for(;;){
515 for(i=0; i<3; i++){
516 char *next;
517
518 for(j=0; j<256; j++){
519 s->stats[i][j]+= strtol(p, &next, 0);
520 if(next==p) return -1;
521 p=next;
522 }
523 }
524 if(p[0]==0 || p[1]==0 || p[2]==0) break;
525 }
526 }else{
527 for(i=0; i<3; i++)
528 for(j=0; j<256; j++){
529 int d= FFMIN(j, 256-j);
530
531 s->stats[i][j]= 100000000/(d+1);
532 }
533 }
534
535 for(i=0; i<3; i++){
536 generate_len_table(s->len[i], s->stats[i], 256);
537
538 if(generate_bits_table(s->bits[i], s->len[i])<0){
539 return -1;
540 }
541
542 store_table(s, s->len[i]);
543 }
544
545 for(i=0; i<3; i++)
546 for(j=0; j<256; j++)
547 s->stats[i][j]= 0;
548
549 s->interlaced= height > 288;
5fd74135 550
11f18faf 551// printf("pred:%d bpp:%d hbpp:%d il:%d\n", s->predictor, s->bitstream_bpp, avctx->bits_per_sample, s->interlaced);
5fd74135 552
11f18faf 553 s->picture_number=0;
5fd74135 554
11f18faf
MN
555 return 0;
556}
557
558static void decode_422_bitstream(HYuvContext *s, int count){
559 int i;
5fd74135 560
11f18faf
MN
561 count/=2;
562
563 for(i=0; i<count; i++){
564 s->temp[0][2*i ]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3);
565 s->temp[1][ i ]= get_vlc2(&s->gb, s->vlc[1].table, VLC_BITS, 3);
566 s->temp[0][2*i+1]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3);
567 s->temp[2][ i ]= get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3);
568 }
569}
570
152ba68c
MN
571static void decode_gray_bitstream(HYuvContext *s, int count){
572 int i;
573
574 count/=2;
575
576 for(i=0; i<count; i++){
577 s->temp[0][2*i ]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3);
578 s->temp[0][2*i+1]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3);
579 }
580}
581
11f18faf
MN
582static void encode_422_bitstream(HYuvContext *s, int count){
583 int i;
584
585 count/=2;
586 if(s->flags&CODEC_FLAG_PASS1){
587 for(i=0; i<count; i++){
588 s->stats[0][ s->temp[0][2*i ] ]++;
589 s->stats[1][ s->temp[1][ i ] ]++;
590 s->stats[0][ s->temp[0][2*i+1] ]++;
591 s->stats[2][ s->temp[2][ i ] ]++;
592 }
593 }else{
594 for(i=0; i<count; i++){
595 put_bits(&s->pb, s->len[0][ s->temp[0][2*i ] ], s->bits[0][ s->temp[0][2*i ] ]);
596 put_bits(&s->pb, s->len[1][ s->temp[1][ i ] ], s->bits[1][ s->temp[1][ i ] ]);
597 put_bits(&s->pb, s->len[0][ s->temp[0][2*i+1] ], s->bits[0][ s->temp[0][2*i+1] ]);
598 put_bits(&s->pb, s->len[2][ s->temp[2][ i ] ], s->bits[2][ s->temp[2][ i ] ]);
599 }
600 }
601}
602
152ba68c
MN
603static void encode_gray_bitstream(HYuvContext *s, int count){
604 int i;
605
606 count/=2;
607 if(s->flags&CODEC_FLAG_PASS1){
608 for(i=0; i<count; i++){
609 s->stats[0][ s->temp[0][2*i ] ]++;
610 s->stats[0][ s->temp[0][2*i+1] ]++;
611 }
612 }else{
613 for(i=0; i<count; i++){
614 put_bits(&s->pb, s->len[0][ s->temp[0][2*i ] ], s->bits[0][ s->temp[0][2*i ] ]);
615 put_bits(&s->pb, s->len[0][ s->temp[0][2*i+1] ], s->bits[0][ s->temp[0][2*i+1] ]);
616 }
617 }
618}
619
11f18faf
MN
620static void decode_bgr_bitstream(HYuvContext *s, int count){
621 int i;
5fd74135 622
11f18faf
MN
623 if(s->decorrelate){
624 if(s->bitstream_bpp==24){
625 for(i=0; i<count; i++){
626 s->temp[0][4*i+1]= get_vlc2(&s->gb, s->vlc[1].table, VLC_BITS, 3);
627 s->temp[0][4*i ]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3) + s->temp[0][4*i+1];
628 s->temp[0][4*i+2]= get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3) + s->temp[0][4*i+1];
629 }
630 }else{
631 for(i=0; i<count; i++){
3ad7dd8c
MN
632 s->temp[0][4*i+G]= get_vlc2(&s->gb, s->vlc[1].table, VLC_BITS, 3);
633 s->temp[0][4*i+B]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3) + s->temp[0][4*i+G];
634 s->temp[0][4*i+R]= get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3) + s->temp[0][4*i+G];
11f18faf
MN
635 get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3); //?!
636 }
637 }
638 }else{
639 if(s->bitstream_bpp==24){
640 for(i=0; i<count; i++){
641 s->temp[0][4*i ]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3);
642 s->temp[0][4*i+1]= get_vlc2(&s->gb, s->vlc[1].table, VLC_BITS, 3);
643 s->temp[0][4*i+2]= get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3);
644 }
645 }else{
646 for(i=0; i<count; i++){
3ad7dd8c
MN
647 s->temp[0][4*i+B]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3);
648 s->temp[0][4*i+G]= get_vlc2(&s->gb, s->vlc[1].table, VLC_BITS, 3);
649 s->temp[0][4*i+R]= get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3);
11f18faf
MN
650 get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3); //?!
651 }
652 }
653 }
654}
655
7c5ab7b8
MN
656static void draw_slice(HYuvContext *s, int y){
657 int h, cy;
7a06ff14 658 int offset[4];
7c5ab7b8
MN
659
660 if(s->avctx->draw_horiz_band==NULL)
661 return;
662
663 h= y - s->last_slice_end;
664 y -= h;
665
666 if(s->bitstream_bpp==12){
667 cy= y>>1;
668 }else{
669 cy= y;
670 }
7a06ff14
MN
671
672 offset[0] = s->picture.linesize[0]*y;
673 offset[1] = s->picture.linesize[1]*cy;
674 offset[2] = s->picture.linesize[2]*cy;
675 offset[3] = 0;
7c5ab7b8
MN
676 emms_c();
677
3bb07d61 678 s->avctx->draw_horiz_band(s->avctx, &s->picture, offset, y, 3, h);
7c5ab7b8
MN
679
680 s->last_slice_end= y + h;
681}
682
11f18faf
MN
683static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8_t *buf, int buf_size){
684 HYuvContext *s = avctx->priv_data;
685 const int width= s->width;
686 const int width2= s->width>>1;
687 const int height= s->height;
22f3e8be 688 int fake_ystride, fake_ustride, fake_vstride;
492cd3a9 689 AVFrame * const p= &s->picture;
11f18faf 690
492cd3a9 691 AVFrame *picture = data;
11f18faf 692
11f18faf
MN
693 /* no supplementary picture */
694 if (buf_size == 0)
695 return 0;
696
3d2e8cce 697 s->dsp.bswap_buf((uint32_t*)s->bitstream_buffer, (uint32_t*)buf, buf_size/4);
11f18faf 698
68f593b4 699 init_get_bits(&s->gb, s->bitstream_buffer, buf_size*8);
22f3e8be 700
e20c4069
MN
701 if(p->data[0])
702 avctx->release_buffer(avctx, p);
703
1e491e29
MN
704 p->reference= 0;
705 if(avctx->get_buffer(avctx, p) < 0){
9b879566 706 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
1e491e29 707 return -1;
22f3e8be 708 }
1e491e29
MN
709
710 fake_ystride= s->interlaced ? p->linesize[0]*2 : p->linesize[0];
711 fake_ustride= s->interlaced ? p->linesize[1]*2 : p->linesize[1];
712 fake_vstride= s->interlaced ? p->linesize[2]*2 : p->linesize[2];
7c5ab7b8
MN
713
714 s->last_slice_end= 0;
22f3e8be 715
11f18faf 716 if(s->bitstream_bpp<24){
152ba68c 717 int y, cy;
11f18faf
MN
718 int lefty, leftu, leftv;
719 int lefttopy, lefttopu, lefttopv;
720
721 if(s->yuy2){
1e491e29
MN
722 p->data[0][3]= get_bits(&s->gb, 8);
723 p->data[0][2]= get_bits(&s->gb, 8);
724 p->data[0][1]= get_bits(&s->gb, 8);
725 p->data[0][0]= get_bits(&s->gb, 8);
11f18faf 726
9b879566 727 av_log(avctx, AV_LOG_ERROR, "YUY2 output isnt implemenetd yet\n");
11f18faf
MN
728 return -1;
729 }else{
730
1e491e29
MN
731 leftv= p->data[2][0]= get_bits(&s->gb, 8);
732 lefty= p->data[0][1]= get_bits(&s->gb, 8);
733 leftu= p->data[1][0]= get_bits(&s->gb, 8);
734 p->data[0][0]= get_bits(&s->gb, 8);
11f18faf
MN
735
736 switch(s->predictor){
737 case LEFT:
738 case PLANE:
739 decode_422_bitstream(s, width-2);
1e491e29 740 lefty= add_left_prediction(p->data[0] + 2, s->temp[0], width-2, lefty);
11f18faf 741 if(!(s->flags&CODEC_FLAG_GRAY)){
1e491e29
MN
742 leftu= add_left_prediction(p->data[1] + 1, s->temp[1], width2-1, leftu);
743 leftv= add_left_prediction(p->data[2] + 1, s->temp[2], width2-1, leftv);
11f18faf
MN
744 }
745
152ba68c 746 for(cy=y=1; y<s->height; y++,cy++){
11f18faf 747 uint8_t *ydst, *udst, *vdst;
152ba68c
MN
748
749 if(s->bitstream_bpp==12){
750 decode_gray_bitstream(s, width);
751
1e491e29 752 ydst= p->data[0] + p->linesize[0]*y;
152ba68c
MN
753
754 lefty= add_left_prediction(ydst, s->temp[0], width, lefty);
755 if(s->predictor == PLANE){
756 if(y>s->interlaced)
757 s->dsp.add_bytes(ydst, ydst - fake_ystride, width);
758 }
759 y++;
760 if(y>=s->height) break;
761 }
11f18faf 762
7c5ab7b8
MN
763 draw_slice(s, y);
764
1e491e29
MN
765 ydst= p->data[0] + p->linesize[0]*y;
766 udst= p->data[1] + p->linesize[1]*cy;
767 vdst= p->data[2] + p->linesize[2]*cy;
152ba68c
MN
768
769 decode_422_bitstream(s, width);
11f18faf
MN
770 lefty= add_left_prediction(ydst, s->temp[0], width, lefty);
771 if(!(s->flags&CODEC_FLAG_GRAY)){
772 leftu= add_left_prediction(udst, s->temp[1], width2, leftu);
773 leftv= add_left_prediction(vdst, s->temp[2], width2, leftv);
774 }
775 if(s->predictor == PLANE){
152ba68c 776 if(cy>s->interlaced){
11f18faf
MN
777 s->dsp.add_bytes(ydst, ydst - fake_ystride, width);
778 if(!(s->flags&CODEC_FLAG_GRAY)){
779 s->dsp.add_bytes(udst, udst - fake_ustride, width2);
780 s->dsp.add_bytes(vdst, vdst - fake_vstride, width2);
781 }
782 }
783 }
784 }
7c5ab7b8
MN
785 draw_slice(s, height);
786
11f18faf
MN
787 break;
788 case MEDIAN:
789 /* first line except first 2 pixels is left predicted */
790 decode_422_bitstream(s, width-2);
1e491e29 791 lefty= add_left_prediction(p->data[0] + 2, s->temp[0], width-2, lefty);
11f18faf 792 if(!(s->flags&CODEC_FLAG_GRAY)){
1e491e29
MN
793 leftu= add_left_prediction(p->data[1] + 1, s->temp[1], width2-1, leftu);
794 leftv= add_left_prediction(p->data[2] + 1, s->temp[2], width2-1, leftv);
11f18faf
MN
795 }
796
152ba68c 797 cy=y=1;
11f18faf
MN
798
799 /* second line is left predicted for interlaced case */
800 if(s->interlaced){
801 decode_422_bitstream(s, width);
1e491e29 802 lefty= add_left_prediction(p->data[0] + p->linesize[0], s->temp[0], width, lefty);
11f18faf 803 if(!(s->flags&CODEC_FLAG_GRAY)){
1e491e29
MN
804 leftu= add_left_prediction(p->data[1] + p->linesize[2], s->temp[1], width2, leftu);
805 leftv= add_left_prediction(p->data[2] + p->linesize[1], s->temp[2], width2, leftv);
11f18faf 806 }
152ba68c 807 y++; cy++;
11f18faf
MN
808 }
809
810 /* next 4 pixels are left predicted too */
811 decode_422_bitstream(s, 4);
1e491e29 812 lefty= add_left_prediction(p->data[0] + fake_ystride, s->temp[0], 4, lefty);
11f18faf 813 if(!(s->flags&CODEC_FLAG_GRAY)){
1e491e29
MN
814 leftu= add_left_prediction(p->data[1] + fake_ustride, s->temp[1], 2, leftu);
815 leftv= add_left_prediction(p->data[2] + fake_vstride, s->temp[2], 2, leftv);
11f18faf
MN
816 }
817
818 /* next line except the first 4 pixels is median predicted */
1e491e29 819 lefttopy= p->data[0][3];
11f18faf 820 decode_422_bitstream(s, width-4);
1e491e29 821 add_median_prediction(p->data[0] + fake_ystride+4, p->data[0]+4, s->temp[0], width-4, &lefty, &lefttopy);
11f18faf 822 if(!(s->flags&CODEC_FLAG_GRAY)){
1e491e29
MN
823 lefttopu= p->data[1][1];
824 lefttopv= p->data[2][1];
825 add_median_prediction(p->data[1] + fake_ustride+2, p->data[1]+2, s->temp[1], width2-2, &leftu, &lefttopu);
826 add_median_prediction(p->data[2] + fake_vstride+2, p->data[2]+2, s->temp[2], width2-2, &leftv, &lefttopv);
11f18faf 827 }
152ba68c
MN
828 y++; cy++;
829
830 for(; y<height; y++,cy++){
11f18faf 831 uint8_t *ydst, *udst, *vdst;
152ba68c
MN
832
833 if(s->bitstream_bpp==12){
834 while(2*cy > y){
835 decode_gray_bitstream(s, width);
1e491e29 836 ydst= p->data[0] + p->linesize[0]*y;
152ba68c
MN
837 add_median_prediction(ydst, ydst - fake_ystride, s->temp[0], width, &lefty, &lefttopy);
838 y++;
839 }
840 if(y>=height) break;
841 }
7c5ab7b8 842 draw_slice(s, y);
152ba68c 843
11f18faf 844 decode_422_bitstream(s, width);
152ba68c 845
1e491e29
MN
846 ydst= p->data[0] + p->linesize[0]*y;
847 udst= p->data[1] + p->linesize[1]*cy;
848 vdst= p->data[2] + p->linesize[2]*cy;
11f18faf
MN
849
850 add_median_prediction(ydst, ydst - fake_ystride, s->temp[0], width, &lefty, &lefttopy);
851 if(!(s->flags&CODEC_FLAG_GRAY)){
852 add_median_prediction(udst, udst - fake_ustride, s->temp[1], width2, &leftu, &lefttopu);
853 add_median_prediction(vdst, vdst - fake_vstride, s->temp[2], width2, &leftv, &lefttopv);
854 }
855 }
7c5ab7b8
MN
856
857 draw_slice(s, height);
11f18faf
MN
858 break;
859 }
860 }
861 }else{
862 int y;
863 int leftr, leftg, leftb;
1e491e29 864 const int last_line= (height-1)*p->linesize[0];
11f18faf
MN
865
866 if(s->bitstream_bpp==32){
1e491e29
MN
867 p->data[0][last_line+3]= get_bits(&s->gb, 8);
868 leftr= p->data[0][last_line+2]= get_bits(&s->gb, 8);
869 leftg= p->data[0][last_line+1]= get_bits(&s->gb, 8);
870 leftb= p->data[0][last_line+0]= get_bits(&s->gb, 8);
11f18faf 871 }else{
1e491e29
MN
872 leftr= p->data[0][last_line+2]= get_bits(&s->gb, 8);
873 leftg= p->data[0][last_line+1]= get_bits(&s->gb, 8);
874 leftb= p->data[0][last_line+0]= get_bits(&s->gb, 8);
11f18faf
MN
875 skip_bits(&s->gb, 8);
876 }
877
878 if(s->bgr32){
879 switch(s->predictor){
880 case LEFT:
881 case PLANE:
882 decode_bgr_bitstream(s, width-1);
1e491e29 883 add_left_prediction_bgr32(p->data[0] + last_line+4, s->temp[0], width-1, &leftr, &leftg, &leftb);
11f18faf
MN
884
885 for(y=s->height-2; y>=0; y--){ //yes its stored upside down
886 decode_bgr_bitstream(s, width);
887
1e491e29 888 add_left_prediction_bgr32(p->data[0] + p->linesize[0]*y, s->temp[0], width, &leftr, &leftg, &leftb);
11f18faf
MN
889 if(s->predictor == PLANE){
890 if((y&s->interlaced)==0){
1e491e29
MN
891 s->dsp.add_bytes(p->data[0] + p->linesize[0]*y,
892 p->data[0] + p->linesize[0]*y + fake_ystride, fake_ystride);
11f18faf
MN
893 }
894 }
895 }
7c5ab7b8 896 draw_slice(s, height); // just 1 large slice as this isnt possible in reverse order
11f18faf
MN
897 break;
898 default:
9b879566 899 av_log(avctx, AV_LOG_ERROR, "prediction type not supported!\n");
11f18faf
MN
900 }
901 }else{
902
9b879566 903 av_log(avctx, AV_LOG_ERROR, "BGR24 output isnt implemenetd yet\n");
11f18faf
MN
904 return -1;
905 }
906 }
907 emms_c();
908
1e491e29 909 *picture= *p;
492cd3a9 910 *data_size = sizeof(AVFrame);
11f18faf 911
8c031d1c 912 return (get_bits_count(&s->gb)+31)/32*4;
11f18faf
MN
913}
914
915static int decode_end(AVCodecContext *avctx)
916{
917 HYuvContext *s = avctx->priv_data;
918 int i;
919
920 for(i=0; i<3; i++){
11f18faf
MN
921 free_vlc(&s->vlc[i]);
922 }
1e491e29 923
11f18faf
MN
924 return 0;
925}
926
927static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){
928 HYuvContext *s = avctx->priv_data;
492cd3a9 929 AVFrame *pict = data;
11f18faf
MN
930 const int width= s->width;
931 const int width2= s->width>>1;
932 const int height= s->height;
933 const int fake_ystride= s->interlaced ? pict->linesize[0]*2 : pict->linesize[0];
934 const int fake_ustride= s->interlaced ? pict->linesize[1]*2 : pict->linesize[1];
935 const int fake_vstride= s->interlaced ? pict->linesize[2]*2 : pict->linesize[2];
492cd3a9 936 AVFrame * const p= &s->picture;
11f18faf
MN
937 int i, size;
938
ed7debda 939 init_put_bits(&s->pb, buf, buf_size);
11f18faf 940
1e491e29 941 *p = *pict;
aaa1e4cd
MN
942 p->pict_type= FF_I_TYPE;
943 p->key_frame= 1;
11f18faf 944
152ba68c
MN
945 if(avctx->pix_fmt == PIX_FMT_YUV422P || avctx->pix_fmt == PIX_FMT_YUV420P){
946 int lefty, leftu, leftv, y, cy;
11f18faf 947
1e491e29
MN
948 put_bits(&s->pb, 8, leftv= p->data[2][0]);
949 put_bits(&s->pb, 8, lefty= p->data[0][1]);
950 put_bits(&s->pb, 8, leftu= p->data[1][0]);
951 put_bits(&s->pb, 8, p->data[0][0]);
11f18faf 952
1e491e29
MN
953 lefty= sub_left_prediction(s, s->temp[0], p->data[0]+2, width-2 , lefty);
954 leftu= sub_left_prediction(s, s->temp[1], p->data[1]+1, width2-1, leftu);
955 leftv= sub_left_prediction(s, s->temp[2], p->data[2]+1, width2-1, leftv);
11f18faf
MN
956
957 encode_422_bitstream(s, width-2);
958
959 if(s->predictor==MEDIAN){
960 int lefttopy, lefttopu, lefttopv;
152ba68c 961 cy=y=1;
11f18faf 962 if(s->interlaced){
1e491e29
MN
963 lefty= sub_left_prediction(s, s->temp[0], p->data[0]+p->linesize[0], width , lefty);
964 leftu= sub_left_prediction(s, s->temp[1], p->data[1]+p->linesize[1], width2, leftu);
965 leftv= sub_left_prediction(s, s->temp[2], p->data[2]+p->linesize[2], width2, leftv);
11f18faf
MN
966
967 encode_422_bitstream(s, width);
152ba68c 968 y++; cy++;
11f18faf
MN
969 }
970
1e491e29
MN
971 lefty= sub_left_prediction(s, s->temp[0], p->data[0]+fake_ystride, 4, lefty);
972 leftu= sub_left_prediction(s, s->temp[1], p->data[1]+fake_ystride, 2, leftu);
973 leftv= sub_left_prediction(s, s->temp[2], p->data[2]+fake_ystride, 2, leftv);
11f18faf
MN
974
975 encode_422_bitstream(s, 4);
152ba68c 976
1e491e29
MN
977 lefttopy= p->data[0][3];
978 lefttopu= p->data[1][1];
979 lefttopv= p->data[2][1];
84705403
MN
980 s->dsp.sub_hfyu_median_prediction(s->temp[0], p->data[0]+4, p->data[0] + fake_ystride+4, width-4 , &lefty, &lefttopy);
981 s->dsp.sub_hfyu_median_prediction(s->temp[1], p->data[1]+2, p->data[1] + fake_ustride+2, width2-2, &leftu, &lefttopu);
982 s->dsp.sub_hfyu_median_prediction(s->temp[2], p->data[2]+2, p->data[2] + fake_vstride+2, width2-2, &leftv, &lefttopv);
11f18faf 983 encode_422_bitstream(s, width-4);
152ba68c 984 y++; cy++;
11f18faf 985
152ba68c 986 for(; y<height; y++,cy++){
11f18faf
MN
987 uint8_t *ydst, *udst, *vdst;
988
152ba68c
MN
989 if(s->bitstream_bpp==12){
990 while(2*cy > y){
1e491e29 991 ydst= p->data[0] + p->linesize[0]*y;
84705403 992 s->dsp.sub_hfyu_median_prediction(s->temp[0], ydst - fake_ystride, ydst, width , &lefty, &lefttopy);
152ba68c
MN
993 encode_gray_bitstream(s, width);
994 y++;
995 }
996 if(y>=height) break;
997 }
1e491e29
MN
998 ydst= p->data[0] + p->linesize[0]*y;
999 udst= p->data[1] + p->linesize[1]*cy;
1000 vdst= p->data[2] + p->linesize[2]*cy;
11f18faf 1001
84705403
MN
1002 s->dsp.sub_hfyu_median_prediction(s->temp[0], ydst - fake_ystride, ydst, width , &lefty, &lefttopy);
1003 s->dsp.sub_hfyu_median_prediction(s->temp[1], udst - fake_ustride, udst, width2, &leftu, &lefttopu);
1004 s->dsp.sub_hfyu_median_prediction(s->temp[2], vdst - fake_vstride, vdst, width2, &leftv, &lefttopv);
11f18faf
MN
1005
1006 encode_422_bitstream(s, width);
1007 }
1008 }else{
152ba68c 1009 for(cy=y=1; y<height; y++,cy++){
11f18faf 1010 uint8_t *ydst, *udst, *vdst;
152ba68c
MN
1011
1012 /* encode a luma only line & y++ */
1013 if(s->bitstream_bpp==12){
1e491e29 1014 ydst= p->data[0] + p->linesize[0]*y;
152ba68c
MN
1015
1016 if(s->predictor == PLANE && s->interlaced < y){
7c5ab7b8 1017 s->dsp.diff_bytes(s->temp[1], ydst, ydst - fake_ystride, width);
152ba68c 1018
7c5ab7b8 1019 lefty= sub_left_prediction(s, s->temp[0], s->temp[1], width , lefty);
152ba68c 1020 }else{
7c5ab7b8 1021 lefty= sub_left_prediction(s, s->temp[0], ydst, width , lefty);
152ba68c
MN
1022 }
1023 encode_gray_bitstream(s, width);
1024 y++;
1025 if(y>=height) break;
1026 }
1027
1e491e29
MN
1028 ydst= p->data[0] + p->linesize[0]*y;
1029 udst= p->data[1] + p->linesize[1]*cy;
1030 vdst= p->data[2] + p->linesize[2]*cy;
11f18faf 1031
152ba68c 1032 if(s->predictor == PLANE && s->interlaced < cy){
7c5ab7b8
MN
1033 s->dsp.diff_bytes(s->temp[1], ydst, ydst - fake_ystride, width);
1034 s->dsp.diff_bytes(s->temp[2], udst, udst - fake_ustride, width2);
8c812d73 1035 s->dsp.diff_bytes(s->temp[2] + 1250, vdst, vdst - fake_vstride, width2);
11f18faf 1036
7c5ab7b8
MN
1037 lefty= sub_left_prediction(s, s->temp[0], s->temp[1], width , lefty);
1038 leftu= sub_left_prediction(s, s->temp[1], s->temp[2], width2, leftu);
8c812d73 1039 leftv= sub_left_prediction(s, s->temp[2], s->temp[2] + 1250, width2, leftv);
11f18faf 1040 }else{
7c5ab7b8
MN
1041 lefty= sub_left_prediction(s, s->temp[0], ydst, width , lefty);
1042 leftu= sub_left_prediction(s, s->temp[1], udst, width2, leftu);
1043 leftv= sub_left_prediction(s, s->temp[2], vdst, width2, leftv);
11f18faf
MN
1044 }
1045
1046 encode_422_bitstream(s, width);
1047 }
1048 }
1049 }else{
9b879566 1050 av_log(avctx, AV_LOG_ERROR, "Format not supported!\n");
11f18faf
MN
1051 }
1052 emms_c();
1053
fe455f33 1054 size= (put_bits_count(&s->pb)+31)/32;
11f18faf
MN
1055
1056 if((s->flags&CODEC_FLAG_PASS1) && (s->picture_number&31)==0){
1057 int j;
1058 char *p= avctx->stats_out;
1059 for(i=0; i<3; i++){
1060 for(j=0; j<256; j++){
4cfbf61b 1061 sprintf(p, "%llu ", s->stats[i][j]);
11f18faf
MN
1062 p+= strlen(p);
1063 s->stats[i][j]= 0;
1064 }
1065 sprintf(p, "\n");
1066 p++;
1067 }
1068 }else{
152ba68c 1069 flush_put_bits(&s->pb);
3d2e8cce 1070 s->dsp.bswap_buf((uint32_t*)buf, (uint32_t*)buf, size);
11f18faf
MN
1071 }
1072
11f18faf 1073 s->picture_number++;
1e491e29 1074
11f18faf
MN
1075 return size*4;
1076}
1077
1078static int encode_end(AVCodecContext *avctx)
1079{
1080// HYuvContext *s = avctx->priv_data;
1081
1082 av_freep(&avctx->extradata);
1083 av_freep(&avctx->stats_out);
1084
1085 return 0;
1086}
1087
5d4ce457
ZK
1088static const AVOption huffyuv_options[] =
1089{
1090 AVOPTION_CODEC_INT("prediction_method", "prediction_method", prediction_method, 0, 2, 0),
1091 AVOPTION_END()
1092};
1093
11f18faf
MN
1094AVCodec huffyuv_decoder = {
1095 "huffyuv",
1096 CODEC_TYPE_VIDEO,
1097 CODEC_ID_HUFFYUV,
1098 sizeof(HYuvContext),
1099 decode_init,
1100 NULL,
1101 decode_end,
1102 decode_frame,
7c5ab7b8 1103 CODEC_CAP_DR1 | CODEC_CAP_DRAW_HORIZ_BAND,
11f18faf
MN
1104 NULL
1105};
1106
5fd74135
MN
1107#ifdef CONFIG_ENCODERS
1108
11f18faf
MN
1109AVCodec huffyuv_encoder = {
1110 "huffyuv",
1111 CODEC_TYPE_VIDEO,
1112 CODEC_ID_HUFFYUV,
1113 sizeof(HYuvContext),
1114 encode_init,
1115 encode_frame,
1116 encode_end,
5d4ce457 1117 .options = huffyuv_options,
11f18faf 1118};
5fd74135 1119
aea22133 1120#endif //CONFIG_ENCODERS