(non)interlaced huffyuv patch by (Loren Merritt <lorenm at u dot washington dot edu>)
[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
48cb67c6 284 if(len >= 32) break;
11f18faf
MN
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
ee598f7b
LM
412 if(((uint8_t*)avctx->extradata)[2] & 0x20)
413 s->interlaced= ((uint8_t*)avctx->extradata)[2] & 0x10 ? 1 : 0;
414 else
415 s->interlaced= height > 288;
11f18faf 416
11f18faf
MN
417 switch(s->bitstream_bpp){
418 case 12:
419 avctx->pix_fmt = PIX_FMT_YUV420P;
11f18faf
MN
420 break;
421 case 16:
422 if(s->yuy2){
423 avctx->pix_fmt = PIX_FMT_YUV422;
11f18faf
MN
424 }else{
425 avctx->pix_fmt = PIX_FMT_YUV422P;
11f18faf
MN
426 }
427 break;
428 case 24:
429 case 32:
430 if(s->bgr32){
0b2612b1 431 avctx->pix_fmt = PIX_FMT_RGBA32;
11f18faf
MN
432 }else{
433 avctx->pix_fmt = PIX_FMT_BGR24;
11f18faf
MN
434 }
435 break;
436 default:
437 assert(0);
11f18faf
MN
438 }
439
07140e39
MN
440// av_log(NULL, AV_LOG_DEBUG, "pred:%d bpp:%d hbpp:%d il:%d\n", s->predictor, s->bitstream_bpp, avctx->bits_per_sample, s->interlaced);
441
11f18faf
MN
442 return 0;
443}
444
445static void store_table(HYuvContext *s, uint8_t *len){
446 int i;
447 int index= s->avctx->extradata_size;
448
449 for(i=0; i<256;){
11f18faf 450 int val= len[i];
a003ee9a 451 int repeat=0;
11f18faf 452
a003ee9a
MN
453 for(; i<256 && len[i]==val && repeat<255; i++)
454 repeat++;
11f18faf 455
a003ee9a 456 assert(val < 32 && val >0 && repeat<256 && repeat>0);
11f18faf
MN
457 if(repeat>7){
458 ((uint8_t*)s->avctx->extradata)[index++]= val;
459 ((uint8_t*)s->avctx->extradata)[index++]= repeat;
460 }else{
461 ((uint8_t*)s->avctx->extradata)[index++]= val | (repeat<<5);
462 }
463 }
464
465 s->avctx->extradata_size= index;
466}
467
468static int encode_init(AVCodecContext *avctx)
469{
470 HYuvContext *s = avctx->priv_data;
471 int i, j, width, height;
472
473 s->avctx= avctx;
474 s->flags= avctx->flags;
475
1d98dca3 476 dsputil_init(&s->dsp, avctx);
11f18faf
MN
477
478 width= s->width= avctx->width;
479 height= s->height= avctx->height;
480
481 assert(width && height);
482
8c812d73
MN
483 avctx->extradata= av_mallocz(1024*30);
484 avctx->stats_out= av_mallocz(1024*30);
11f18faf
MN
485 s->version=2;
486
492cd3a9 487 avctx->coded_frame= &s->picture;
1e491e29 488
11f18faf 489 switch(avctx->pix_fmt){
152ba68c 490 case PIX_FMT_YUV420P:
152ba68c
MN
491 s->bitstream_bpp= 12;
492 break;
11f18faf
MN
493 case PIX_FMT_YUV422P:
494 s->bitstream_bpp= 16;
495 break;
496 default:
9b879566 497 av_log(avctx, AV_LOG_ERROR, "format not supported\n");
11f18faf
MN
498 return -1;
499 }
500 avctx->bits_per_sample= s->bitstream_bpp;
501 s->decorrelate= s->bitstream_bpp >= 24;
502 s->predictor= avctx->prediction_method;
ee598f7b 503 s->interlaced= avctx->flags&CODEC_FLAG_INTERLACED_ME ? 1 : 0;
11f18faf
MN
504
505 ((uint8_t*)avctx->extradata)[0]= s->predictor;
506 ((uint8_t*)avctx->extradata)[1]= s->bitstream_bpp;
ee598f7b 507 ((uint8_t*)avctx->extradata)[2]= 0x20 | (s->interlaced ? 0x10 : 0);
11f18faf
MN
508 ((uint8_t*)avctx->extradata)[3]= 0;
509 s->avctx->extradata_size= 4;
510
511 if(avctx->stats_in){
512 char *p= avctx->stats_in;
513
514 for(i=0; i<3; i++)
515 for(j=0; j<256; j++)
516 s->stats[i][j]= 1;
517
518 for(;;){
519 for(i=0; i<3; i++){
520 char *next;
521
522 for(j=0; j<256; j++){
523 s->stats[i][j]+= strtol(p, &next, 0);
524 if(next==p) return -1;
525 p=next;
526 }
527 }
528 if(p[0]==0 || p[1]==0 || p[2]==0) break;
529 }
530 }else{
531 for(i=0; i<3; i++)
532 for(j=0; j<256; j++){
533 int d= FFMIN(j, 256-j);
534
535 s->stats[i][j]= 100000000/(d+1);
536 }
537 }
538
539 for(i=0; i<3; i++){
540 generate_len_table(s->len[i], s->stats[i], 256);
541
542 if(generate_bits_table(s->bits[i], s->len[i])<0){
543 return -1;
544 }
545
546 store_table(s, s->len[i]);
547 }
548
549 for(i=0; i<3; i++)
550 for(j=0; j<256; j++)
551 s->stats[i][j]= 0;
552
11f18faf 553// printf("pred:%d bpp:%d hbpp:%d il:%d\n", s->predictor, s->bitstream_bpp, avctx->bits_per_sample, s->interlaced);
5fd74135 554
11f18faf 555 s->picture_number=0;
5fd74135 556
11f18faf
MN
557 return 0;
558}
559
560static void decode_422_bitstream(HYuvContext *s, int count){
561 int i;
5fd74135 562
11f18faf
MN
563 count/=2;
564
565 for(i=0; i<count; i++){
566 s->temp[0][2*i ]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3);
567 s->temp[1][ i ]= get_vlc2(&s->gb, s->vlc[1].table, VLC_BITS, 3);
568 s->temp[0][2*i+1]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3);
569 s->temp[2][ i ]= get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3);
570 }
571}
572
152ba68c
MN
573static void decode_gray_bitstream(HYuvContext *s, int count){
574 int i;
575
576 count/=2;
577
578 for(i=0; i<count; i++){
579 s->temp[0][2*i ]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3);
580 s->temp[0][2*i+1]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3);
581 }
582}
583
11f18faf
MN
584static void encode_422_bitstream(HYuvContext *s, int count){
585 int i;
586
587 count/=2;
588 if(s->flags&CODEC_FLAG_PASS1){
589 for(i=0; i<count; i++){
590 s->stats[0][ s->temp[0][2*i ] ]++;
591 s->stats[1][ s->temp[1][ i ] ]++;
592 s->stats[0][ s->temp[0][2*i+1] ]++;
593 s->stats[2][ s->temp[2][ i ] ]++;
594 }
595 }else{
596 for(i=0; i<count; i++){
597 put_bits(&s->pb, s->len[0][ s->temp[0][2*i ] ], s->bits[0][ s->temp[0][2*i ] ]);
598 put_bits(&s->pb, s->len[1][ s->temp[1][ i ] ], s->bits[1][ s->temp[1][ i ] ]);
599 put_bits(&s->pb, s->len[0][ s->temp[0][2*i+1] ], s->bits[0][ s->temp[0][2*i+1] ]);
600 put_bits(&s->pb, s->len[2][ s->temp[2][ i ] ], s->bits[2][ s->temp[2][ i ] ]);
601 }
602 }
603}
604
152ba68c
MN
605static void encode_gray_bitstream(HYuvContext *s, int count){
606 int i;
607
608 count/=2;
609 if(s->flags&CODEC_FLAG_PASS1){
610 for(i=0; i<count; i++){
611 s->stats[0][ s->temp[0][2*i ] ]++;
612 s->stats[0][ s->temp[0][2*i+1] ]++;
613 }
614 }else{
615 for(i=0; i<count; i++){
616 put_bits(&s->pb, s->len[0][ s->temp[0][2*i ] ], s->bits[0][ s->temp[0][2*i ] ]);
617 put_bits(&s->pb, s->len[0][ s->temp[0][2*i+1] ], s->bits[0][ s->temp[0][2*i+1] ]);
618 }
619 }
620}
621
11f18faf
MN
622static void decode_bgr_bitstream(HYuvContext *s, int count){
623 int i;
5fd74135 624
11f18faf
MN
625 if(s->decorrelate){
626 if(s->bitstream_bpp==24){
627 for(i=0; i<count; i++){
0722ccdb
MN
628 s->temp[0][4*i+G]= get_vlc2(&s->gb, s->vlc[1].table, VLC_BITS, 3);
629 s->temp[0][4*i+B]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3) + s->temp[0][4*i+G];
630 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
631 }
632 }else{
633 for(i=0; i<count; i++){
3ad7dd8c
MN
634 s->temp[0][4*i+G]= get_vlc2(&s->gb, s->vlc[1].table, VLC_BITS, 3);
635 s->temp[0][4*i+B]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3) + s->temp[0][4*i+G];
636 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
637 get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3); //?!
638 }
639 }
640 }else{
641 if(s->bitstream_bpp==24){
642 for(i=0; i<count; i++){
0722ccdb
MN
643 s->temp[0][4*i+B]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3);
644 s->temp[0][4*i+G]= get_vlc2(&s->gb, s->vlc[1].table, VLC_BITS, 3);
645 s->temp[0][4*i+R]= get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3);
11f18faf
MN
646 }
647 }else{
648 for(i=0; i<count; i++){
3ad7dd8c
MN
649 s->temp[0][4*i+B]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3);
650 s->temp[0][4*i+G]= get_vlc2(&s->gb, s->vlc[1].table, VLC_BITS, 3);
651 s->temp[0][4*i+R]= get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3);
11f18faf
MN
652 get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3); //?!
653 }
654 }
655 }
656}
657
7c5ab7b8
MN
658static void draw_slice(HYuvContext *s, int y){
659 int h, cy;
7a06ff14 660 int offset[4];
7c5ab7b8
MN
661
662 if(s->avctx->draw_horiz_band==NULL)
663 return;
664
665 h= y - s->last_slice_end;
666 y -= h;
667
668 if(s->bitstream_bpp==12){
669 cy= y>>1;
670 }else{
671 cy= y;
672 }
7a06ff14
MN
673
674 offset[0] = s->picture.linesize[0]*y;
675 offset[1] = s->picture.linesize[1]*cy;
676 offset[2] = s->picture.linesize[2]*cy;
677 offset[3] = 0;
7c5ab7b8
MN
678 emms_c();
679
3bb07d61 680 s->avctx->draw_horiz_band(s->avctx, &s->picture, offset, y, 3, h);
7c5ab7b8
MN
681
682 s->last_slice_end= y + h;
683}
684
11f18faf
MN
685static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8_t *buf, int buf_size){
686 HYuvContext *s = avctx->priv_data;
687 const int width= s->width;
688 const int width2= s->width>>1;
689 const int height= s->height;
22f3e8be 690 int fake_ystride, fake_ustride, fake_vstride;
492cd3a9 691 AVFrame * const p= &s->picture;
11f18faf 692
492cd3a9 693 AVFrame *picture = data;
11f18faf 694
11f18faf
MN
695 /* no supplementary picture */
696 if (buf_size == 0)
697 return 0;
698
3d2e8cce 699 s->dsp.bswap_buf((uint32_t*)s->bitstream_buffer, (uint32_t*)buf, buf_size/4);
11f18faf 700
68f593b4 701 init_get_bits(&s->gb, s->bitstream_buffer, buf_size*8);
22f3e8be 702
e20c4069
MN
703 if(p->data[0])
704 avctx->release_buffer(avctx, p);
705
1e491e29
MN
706 p->reference= 0;
707 if(avctx->get_buffer(avctx, p) < 0){
9b879566 708 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
1e491e29 709 return -1;
22f3e8be 710 }
1e491e29
MN
711
712 fake_ystride= s->interlaced ? p->linesize[0]*2 : p->linesize[0];
713 fake_ustride= s->interlaced ? p->linesize[1]*2 : p->linesize[1];
714 fake_vstride= s->interlaced ? p->linesize[2]*2 : p->linesize[2];
7c5ab7b8
MN
715
716 s->last_slice_end= 0;
22f3e8be 717
11f18faf 718 if(s->bitstream_bpp<24){
152ba68c 719 int y, cy;
11f18faf
MN
720 int lefty, leftu, leftv;
721 int lefttopy, lefttopu, lefttopv;
722
723 if(s->yuy2){
1e491e29
MN
724 p->data[0][3]= get_bits(&s->gb, 8);
725 p->data[0][2]= get_bits(&s->gb, 8);
726 p->data[0][1]= get_bits(&s->gb, 8);
727 p->data[0][0]= get_bits(&s->gb, 8);
11f18faf 728
9b879566 729 av_log(avctx, AV_LOG_ERROR, "YUY2 output isnt implemenetd yet\n");
11f18faf
MN
730 return -1;
731 }else{
732
1e491e29
MN
733 leftv= p->data[2][0]= get_bits(&s->gb, 8);
734 lefty= p->data[0][1]= get_bits(&s->gb, 8);
735 leftu= p->data[1][0]= get_bits(&s->gb, 8);
736 p->data[0][0]= get_bits(&s->gb, 8);
11f18faf
MN
737
738 switch(s->predictor){
739 case LEFT:
740 case PLANE:
741 decode_422_bitstream(s, width-2);
1e491e29 742 lefty= add_left_prediction(p->data[0] + 2, s->temp[0], width-2, lefty);
11f18faf 743 if(!(s->flags&CODEC_FLAG_GRAY)){
1e491e29
MN
744 leftu= add_left_prediction(p->data[1] + 1, s->temp[1], width2-1, leftu);
745 leftv= add_left_prediction(p->data[2] + 1, s->temp[2], width2-1, leftv);
11f18faf
MN
746 }
747
152ba68c 748 for(cy=y=1; y<s->height; y++,cy++){
11f18faf 749 uint8_t *ydst, *udst, *vdst;
152ba68c
MN
750
751 if(s->bitstream_bpp==12){
752 decode_gray_bitstream(s, width);
753
1e491e29 754 ydst= p->data[0] + p->linesize[0]*y;
152ba68c
MN
755
756 lefty= add_left_prediction(ydst, s->temp[0], width, lefty);
757 if(s->predictor == PLANE){
758 if(y>s->interlaced)
759 s->dsp.add_bytes(ydst, ydst - fake_ystride, width);
760 }
761 y++;
762 if(y>=s->height) break;
763 }
11f18faf 764
7c5ab7b8
MN
765 draw_slice(s, y);
766
1e491e29
MN
767 ydst= p->data[0] + p->linesize[0]*y;
768 udst= p->data[1] + p->linesize[1]*cy;
769 vdst= p->data[2] + p->linesize[2]*cy;
152ba68c
MN
770
771 decode_422_bitstream(s, width);
11f18faf
MN
772 lefty= add_left_prediction(ydst, s->temp[0], width, lefty);
773 if(!(s->flags&CODEC_FLAG_GRAY)){
774 leftu= add_left_prediction(udst, s->temp[1], width2, leftu);
775 leftv= add_left_prediction(vdst, s->temp[2], width2, leftv);
776 }
777 if(s->predictor == PLANE){
152ba68c 778 if(cy>s->interlaced){
11f18faf
MN
779 s->dsp.add_bytes(ydst, ydst - fake_ystride, width);
780 if(!(s->flags&CODEC_FLAG_GRAY)){
781 s->dsp.add_bytes(udst, udst - fake_ustride, width2);
782 s->dsp.add_bytes(vdst, vdst - fake_vstride, width2);
783 }
784 }
785 }
786 }
7c5ab7b8
MN
787 draw_slice(s, height);
788
11f18faf
MN
789 break;
790 case MEDIAN:
791 /* first line except first 2 pixels is left predicted */
792 decode_422_bitstream(s, width-2);
1e491e29 793 lefty= add_left_prediction(p->data[0] + 2, s->temp[0], width-2, lefty);
11f18faf 794 if(!(s->flags&CODEC_FLAG_GRAY)){
1e491e29
MN
795 leftu= add_left_prediction(p->data[1] + 1, s->temp[1], width2-1, leftu);
796 leftv= add_left_prediction(p->data[2] + 1, s->temp[2], width2-1, leftv);
11f18faf
MN
797 }
798
152ba68c 799 cy=y=1;
11f18faf
MN
800
801 /* second line is left predicted for interlaced case */
802 if(s->interlaced){
803 decode_422_bitstream(s, width);
1e491e29 804 lefty= add_left_prediction(p->data[0] + p->linesize[0], s->temp[0], width, lefty);
11f18faf 805 if(!(s->flags&CODEC_FLAG_GRAY)){
1e491e29
MN
806 leftu= add_left_prediction(p->data[1] + p->linesize[2], s->temp[1], width2, leftu);
807 leftv= add_left_prediction(p->data[2] + p->linesize[1], s->temp[2], width2, leftv);
11f18faf 808 }
152ba68c 809 y++; cy++;
11f18faf
MN
810 }
811
812 /* next 4 pixels are left predicted too */
813 decode_422_bitstream(s, 4);
1e491e29 814 lefty= add_left_prediction(p->data[0] + fake_ystride, s->temp[0], 4, lefty);
11f18faf 815 if(!(s->flags&CODEC_FLAG_GRAY)){
1e491e29
MN
816 leftu= add_left_prediction(p->data[1] + fake_ustride, s->temp[1], 2, leftu);
817 leftv= add_left_prediction(p->data[2] + fake_vstride, s->temp[2], 2, leftv);
11f18faf
MN
818 }
819
820 /* next line except the first 4 pixels is median predicted */
1e491e29 821 lefttopy= p->data[0][3];
11f18faf 822 decode_422_bitstream(s, width-4);
1e491e29 823 add_median_prediction(p->data[0] + fake_ystride+4, p->data[0]+4, s->temp[0], width-4, &lefty, &lefttopy);
11f18faf 824 if(!(s->flags&CODEC_FLAG_GRAY)){
1e491e29
MN
825 lefttopu= p->data[1][1];
826 lefttopv= p->data[2][1];
827 add_median_prediction(p->data[1] + fake_ustride+2, p->data[1]+2, s->temp[1], width2-2, &leftu, &lefttopu);
828 add_median_prediction(p->data[2] + fake_vstride+2, p->data[2]+2, s->temp[2], width2-2, &leftv, &lefttopv);
11f18faf 829 }
152ba68c
MN
830 y++; cy++;
831
832 for(; y<height; y++,cy++){
11f18faf 833 uint8_t *ydst, *udst, *vdst;
152ba68c
MN
834
835 if(s->bitstream_bpp==12){
836 while(2*cy > y){
837 decode_gray_bitstream(s, width);
1e491e29 838 ydst= p->data[0] + p->linesize[0]*y;
152ba68c
MN
839 add_median_prediction(ydst, ydst - fake_ystride, s->temp[0], width, &lefty, &lefttopy);
840 y++;
841 }
842 if(y>=height) break;
843 }
7c5ab7b8 844 draw_slice(s, y);
152ba68c 845
11f18faf 846 decode_422_bitstream(s, width);
152ba68c 847
1e491e29
MN
848 ydst= p->data[0] + p->linesize[0]*y;
849 udst= p->data[1] + p->linesize[1]*cy;
850 vdst= p->data[2] + p->linesize[2]*cy;
11f18faf
MN
851
852 add_median_prediction(ydst, ydst - fake_ystride, s->temp[0], width, &lefty, &lefttopy);
853 if(!(s->flags&CODEC_FLAG_GRAY)){
854 add_median_prediction(udst, udst - fake_ustride, s->temp[1], width2, &leftu, &lefttopu);
855 add_median_prediction(vdst, vdst - fake_vstride, s->temp[2], width2, &leftv, &lefttopv);
856 }
857 }
7c5ab7b8
MN
858
859 draw_slice(s, height);
11f18faf
MN
860 break;
861 }
862 }
863 }else{
864 int y;
865 int leftr, leftg, leftb;
1e491e29 866 const int last_line= (height-1)*p->linesize[0];
11f18faf
MN
867
868 if(s->bitstream_bpp==32){
0722ccdb
MN
869 skip_bits(&s->gb, 8);
870 leftr= p->data[0][last_line+R]= get_bits(&s->gb, 8);
871 leftg= p->data[0][last_line+G]= get_bits(&s->gb, 8);
872 leftb= p->data[0][last_line+B]= get_bits(&s->gb, 8);
11f18faf 873 }else{
0722ccdb
MN
874 leftr= p->data[0][last_line+R]= get_bits(&s->gb, 8);
875 leftg= p->data[0][last_line+G]= get_bits(&s->gb, 8);
876 leftb= p->data[0][last_line+B]= get_bits(&s->gb, 8);
11f18faf
MN
877 skip_bits(&s->gb, 8);
878 }
879
880 if(s->bgr32){
881 switch(s->predictor){
882 case LEFT:
883 case PLANE:
884 decode_bgr_bitstream(s, width-1);
1e491e29 885 add_left_prediction_bgr32(p->data[0] + last_line+4, s->temp[0], width-1, &leftr, &leftg, &leftb);
11f18faf
MN
886
887 for(y=s->height-2; y>=0; y--){ //yes its stored upside down
888 decode_bgr_bitstream(s, width);
889
1e491e29 890 add_left_prediction_bgr32(p->data[0] + p->linesize[0]*y, s->temp[0], width, &leftr, &leftg, &leftb);
11f18faf 891 if(s->predictor == PLANE){
0722ccdb 892 if((y&s->interlaced)==0 && y<s->height-2){
1e491e29
MN
893 s->dsp.add_bytes(p->data[0] + p->linesize[0]*y,
894 p->data[0] + p->linesize[0]*y + fake_ystride, fake_ystride);
11f18faf
MN
895 }
896 }
897 }
7c5ab7b8 898 draw_slice(s, height); // just 1 large slice as this isnt possible in reverse order
11f18faf
MN
899 break;
900 default:
9b879566 901 av_log(avctx, AV_LOG_ERROR, "prediction type not supported!\n");
11f18faf
MN
902 }
903 }else{
904
9b879566 905 av_log(avctx, AV_LOG_ERROR, "BGR24 output isnt implemenetd yet\n");
11f18faf
MN
906 return -1;
907 }
908 }
909 emms_c();
910
1e491e29 911 *picture= *p;
492cd3a9 912 *data_size = sizeof(AVFrame);
11f18faf 913
8c031d1c 914 return (get_bits_count(&s->gb)+31)/32*4;
11f18faf
MN
915}
916
917static int decode_end(AVCodecContext *avctx)
918{
919 HYuvContext *s = avctx->priv_data;
920 int i;
921
922 for(i=0; i<3; i++){
11f18faf
MN
923 free_vlc(&s->vlc[i]);
924 }
1e491e29 925
11f18faf
MN
926 return 0;
927}
928
929static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){
930 HYuvContext *s = avctx->priv_data;
492cd3a9 931 AVFrame *pict = data;
11f18faf
MN
932 const int width= s->width;
933 const int width2= s->width>>1;
934 const int height= s->height;
935 const int fake_ystride= s->interlaced ? pict->linesize[0]*2 : pict->linesize[0];
936 const int fake_ustride= s->interlaced ? pict->linesize[1]*2 : pict->linesize[1];
937 const int fake_vstride= s->interlaced ? pict->linesize[2]*2 : pict->linesize[2];
492cd3a9 938 AVFrame * const p= &s->picture;
11f18faf
MN
939 int i, size;
940
ed7debda 941 init_put_bits(&s->pb, buf, buf_size);
11f18faf 942
1e491e29 943 *p = *pict;
aaa1e4cd
MN
944 p->pict_type= FF_I_TYPE;
945 p->key_frame= 1;
11f18faf 946
152ba68c
MN
947 if(avctx->pix_fmt == PIX_FMT_YUV422P || avctx->pix_fmt == PIX_FMT_YUV420P){
948 int lefty, leftu, leftv, y, cy;
11f18faf 949
1e491e29
MN
950 put_bits(&s->pb, 8, leftv= p->data[2][0]);
951 put_bits(&s->pb, 8, lefty= p->data[0][1]);
952 put_bits(&s->pb, 8, leftu= p->data[1][0]);
953 put_bits(&s->pb, 8, p->data[0][0]);
11f18faf 954
1e491e29
MN
955 lefty= sub_left_prediction(s, s->temp[0], p->data[0]+2, width-2 , lefty);
956 leftu= sub_left_prediction(s, s->temp[1], p->data[1]+1, width2-1, leftu);
957 leftv= sub_left_prediction(s, s->temp[2], p->data[2]+1, width2-1, leftv);
11f18faf
MN
958
959 encode_422_bitstream(s, width-2);
960
961 if(s->predictor==MEDIAN){
962 int lefttopy, lefttopu, lefttopv;
152ba68c 963 cy=y=1;
11f18faf 964 if(s->interlaced){
1e491e29
MN
965 lefty= sub_left_prediction(s, s->temp[0], p->data[0]+p->linesize[0], width , lefty);
966 leftu= sub_left_prediction(s, s->temp[1], p->data[1]+p->linesize[1], width2, leftu);
967 leftv= sub_left_prediction(s, s->temp[2], p->data[2]+p->linesize[2], width2, leftv);
11f18faf
MN
968
969 encode_422_bitstream(s, width);
152ba68c 970 y++; cy++;
11f18faf
MN
971 }
972
1e491e29 973 lefty= sub_left_prediction(s, s->temp[0], p->data[0]+fake_ystride, 4, lefty);
07140e39
MN
974 leftu= sub_left_prediction(s, s->temp[1], p->data[1]+fake_ustride, 2, leftu);
975 leftv= sub_left_prediction(s, s->temp[2], p->data[2]+fake_vstride, 2, leftv);
11f18faf
MN
976
977 encode_422_bitstream(s, 4);
152ba68c 978
1e491e29
MN
979 lefttopy= p->data[0][3];
980 lefttopu= p->data[1][1];
981 lefttopv= p->data[2][1];
84705403
MN
982 s->dsp.sub_hfyu_median_prediction(s->temp[0], p->data[0]+4, p->data[0] + fake_ystride+4, width-4 , &lefty, &lefttopy);
983 s->dsp.sub_hfyu_median_prediction(s->temp[1], p->data[1]+2, p->data[1] + fake_ustride+2, width2-2, &leftu, &lefttopu);
984 s->dsp.sub_hfyu_median_prediction(s->temp[2], p->data[2]+2, p->data[2] + fake_vstride+2, width2-2, &leftv, &lefttopv);
11f18faf 985 encode_422_bitstream(s, width-4);
152ba68c 986 y++; cy++;
11f18faf 987
152ba68c 988 for(; y<height; y++,cy++){
11f18faf
MN
989 uint8_t *ydst, *udst, *vdst;
990
152ba68c
MN
991 if(s->bitstream_bpp==12){
992 while(2*cy > y){
1e491e29 993 ydst= p->data[0] + p->linesize[0]*y;
84705403 994 s->dsp.sub_hfyu_median_prediction(s->temp[0], ydst - fake_ystride, ydst, width , &lefty, &lefttopy);
152ba68c
MN
995 encode_gray_bitstream(s, width);
996 y++;
997 }
998 if(y>=height) break;
999 }
1e491e29
MN
1000 ydst= p->data[0] + p->linesize[0]*y;
1001 udst= p->data[1] + p->linesize[1]*cy;
1002 vdst= p->data[2] + p->linesize[2]*cy;
11f18faf 1003
84705403
MN
1004 s->dsp.sub_hfyu_median_prediction(s->temp[0], ydst - fake_ystride, ydst, width , &lefty, &lefttopy);
1005 s->dsp.sub_hfyu_median_prediction(s->temp[1], udst - fake_ustride, udst, width2, &leftu, &lefttopu);
1006 s->dsp.sub_hfyu_median_prediction(s->temp[2], vdst - fake_vstride, vdst, width2, &leftv, &lefttopv);
11f18faf
MN
1007
1008 encode_422_bitstream(s, width);
1009 }
1010 }else{
152ba68c 1011 for(cy=y=1; y<height; y++,cy++){
11f18faf 1012 uint8_t *ydst, *udst, *vdst;
152ba68c
MN
1013
1014 /* encode a luma only line & y++ */
1015 if(s->bitstream_bpp==12){
1e491e29 1016 ydst= p->data[0] + p->linesize[0]*y;
152ba68c
MN
1017
1018 if(s->predictor == PLANE && s->interlaced < y){
7c5ab7b8 1019 s->dsp.diff_bytes(s->temp[1], ydst, ydst - fake_ystride, width);
152ba68c 1020
7c5ab7b8 1021 lefty= sub_left_prediction(s, s->temp[0], s->temp[1], width , lefty);
152ba68c 1022 }else{
7c5ab7b8 1023 lefty= sub_left_prediction(s, s->temp[0], ydst, width , lefty);
152ba68c
MN
1024 }
1025 encode_gray_bitstream(s, width);
1026 y++;
1027 if(y>=height) break;
1028 }
1029
1e491e29
MN
1030 ydst= p->data[0] + p->linesize[0]*y;
1031 udst= p->data[1] + p->linesize[1]*cy;
1032 vdst= p->data[2] + p->linesize[2]*cy;
11f18faf 1033
152ba68c 1034 if(s->predictor == PLANE && s->interlaced < cy){
7c5ab7b8
MN
1035 s->dsp.diff_bytes(s->temp[1], ydst, ydst - fake_ystride, width);
1036 s->dsp.diff_bytes(s->temp[2], udst, udst - fake_ustride, width2);
8c812d73 1037 s->dsp.diff_bytes(s->temp[2] + 1250, vdst, vdst - fake_vstride, width2);
11f18faf 1038
7c5ab7b8
MN
1039 lefty= sub_left_prediction(s, s->temp[0], s->temp[1], width , lefty);
1040 leftu= sub_left_prediction(s, s->temp[1], s->temp[2], width2, leftu);
8c812d73 1041 leftv= sub_left_prediction(s, s->temp[2], s->temp[2] + 1250, width2, leftv);
11f18faf 1042 }else{
7c5ab7b8
MN
1043 lefty= sub_left_prediction(s, s->temp[0], ydst, width , lefty);
1044 leftu= sub_left_prediction(s, s->temp[1], udst, width2, leftu);
1045 leftv= sub_left_prediction(s, s->temp[2], vdst, width2, leftv);
11f18faf
MN
1046 }
1047
1048 encode_422_bitstream(s, width);
1049 }
1050 }
1051 }else{
9b879566 1052 av_log(avctx, AV_LOG_ERROR, "Format not supported!\n");
11f18faf
MN
1053 }
1054 emms_c();
1055
fe455f33 1056 size= (put_bits_count(&s->pb)+31)/32;
11f18faf
MN
1057
1058 if((s->flags&CODEC_FLAG_PASS1) && (s->picture_number&31)==0){
1059 int j;
1060 char *p= avctx->stats_out;
1061 for(i=0; i<3; i++){
1062 for(j=0; j<256; j++){
4cfbf61b 1063 sprintf(p, "%llu ", s->stats[i][j]);
11f18faf
MN
1064 p+= strlen(p);
1065 s->stats[i][j]= 0;
1066 }
1067 sprintf(p, "\n");
1068 p++;
1069 }
1070 }else{
152ba68c 1071 flush_put_bits(&s->pb);
3d2e8cce 1072 s->dsp.bswap_buf((uint32_t*)buf, (uint32_t*)buf, size);
11f18faf
MN
1073 }
1074
11f18faf 1075 s->picture_number++;
1e491e29 1076
11f18faf
MN
1077 return size*4;
1078}
1079
1080static int encode_end(AVCodecContext *avctx)
1081{
1082// HYuvContext *s = avctx->priv_data;
1083
1084 av_freep(&avctx->extradata);
1085 av_freep(&avctx->stats_out);
1086
1087 return 0;
1088}
1089
5d4ce457
ZK
1090static const AVOption huffyuv_options[] =
1091{
1092 AVOPTION_CODEC_INT("prediction_method", "prediction_method", prediction_method, 0, 2, 0),
1093 AVOPTION_END()
1094};
1095
11f18faf
MN
1096AVCodec huffyuv_decoder = {
1097 "huffyuv",
1098 CODEC_TYPE_VIDEO,
1099 CODEC_ID_HUFFYUV,
1100 sizeof(HYuvContext),
1101 decode_init,
1102 NULL,
1103 decode_end,
1104 decode_frame,
7c5ab7b8 1105 CODEC_CAP_DR1 | CODEC_CAP_DRAW_HORIZ_BAND,
11f18faf
MN
1106 NULL
1107};
1108
5fd74135
MN
1109#ifdef CONFIG_ENCODERS
1110
11f18faf
MN
1111AVCodec huffyuv_encoder = {
1112 "huffyuv",
1113 CODEC_TYPE_VIDEO,
1114 CODEC_ID_HUFFYUV,
1115 sizeof(HYuvContext),
1116 encode_init,
1117 encode_frame,
1118 encode_end,
5d4ce457 1119 .options = huffyuv_options,
11f18faf 1120};
5fd74135 1121
aea22133 1122#endif //CONFIG_ENCODERS