r125: This commit was manufactured by cvs2svn to create tag 'r1_1_7-last'.
[cinelerra_cv/mob.git] / hvirtual / quicktime / libavcodec / huffyuv.c
blob0eb701037d275c091ccab374e4ea6759eb4c71f4
1 /*
2 * huffyuv codec for libavcodec
4 * Copyright (c) 2002 Michael Niedermayer <michaelni@gmx.at>
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.
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.
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
20 * see http://www.pcisys.net/~melanson/codecs/huffyuv.txt for a description of
21 * the algorithm used
24 #include "common.h"
25 #include "avcodec.h"
26 #include "dsputil.h"
28 #ifndef INT64_MAX
29 #define INT64_MAX 9223372036854775807LL
30 #endif
32 #define VLC_BITS 11
34 typedef enum Predictor{
35 LEFT= 0,
36 PLANE,
37 MEDIAN,
38 } Predictor;
40 typedef struct HYuvContext{
41 AVCodecContext *avctx;
42 Predictor predictor;
43 GetBitContext gb;
44 PutBitContext pb;
45 int interlaced;
46 int decorrelate;
47 int bitstream_bpp;
48 int version;
49 int yuy2; //use yuy2 instead of 422P
50 int bgr32; //use bgr32 instead of bgr24
51 int width, height;
52 int flags;
53 int picture_number;
54 int last_slice_end;
55 uint8_t __align8 temp[3][2500];
56 uint64_t stats[3][256];
57 uint8_t len[3][256];
58 uint32_t bits[3][256];
59 VLC vlc[3];
60 AVFrame picture;
61 uint8_t __align8 bitstream_buffer[1024*1024*3]; //FIXME dynamic alloc or some other solution
62 DSPContext dsp;
63 }HYuvContext;
65 static inline void bswap_buf(uint32_t *dst, uint32_t *src, int w){
66 int i;
68 for(i=0; i+8<=w; i+=8){
69 dst[i+0]= bswap_32(src[i+0]);
70 dst[i+1]= bswap_32(src[i+1]);
71 dst[i+2]= bswap_32(src[i+2]);
72 dst[i+3]= bswap_32(src[i+3]);
73 dst[i+4]= bswap_32(src[i+4]);
74 dst[i+5]= bswap_32(src[i+5]);
75 dst[i+6]= bswap_32(src[i+6]);
76 dst[i+7]= bswap_32(src[i+7]);
78 for(;i<w; i++){
79 dst[i+0]= bswap_32(src[i+0]);
83 static inline int add_left_prediction(uint8_t *dst, uint8_t *src, int w, int acc){
84 int i;
86 for(i=0; i<w-1; i++){
87 acc+= src[i];
88 dst[i]= acc;
89 i++;
90 acc+= src[i];
91 dst[i]= acc;
94 for(; i<w; i++){
95 acc+= src[i];
96 dst[i]= acc;
99 return acc;
102 static inline void add_median_prediction(uint8_t *dst, uint8_t *src1, uint8_t *diff, int w, int *left, int *left_top){
103 int i;
104 uint8_t l, lt;
106 l= *left;
107 lt= *left_top;
109 for(i=0; i<w; i++){
110 l= mid_pred(l, src1[i], (l + src1[i] - lt)&0xFF) + diff[i];
111 lt= src1[i];
112 dst[i]= l;
115 *left= l;
116 *left_top= lt;
118 //FIXME optimize
119 static inline void sub_median_prediction(uint8_t *dst, uint8_t *src1, uint8_t *src2, int w, int *left, int *left_top){
120 int i;
121 uint8_t l, lt;
123 l= *left;
124 lt= *left_top;
126 for(i=0; i<w; i++){
127 const int pred= mid_pred(l, src1[i], (l + src1[i] - lt)&0xFF);
128 lt= src1[i];
129 l= src2[i];
130 dst[i]= l - pred;
133 *left= l;
134 *left_top= lt;
138 static inline void add_left_prediction_bgr32(uint8_t *dst, uint8_t *src, int w, int *red, int *green, int *blue){
139 int i;
140 int r,g,b;
141 r= *red;
142 g= *green;
143 b= *blue;
145 for(i=0; i<w; i++){
146 b+= src[4*i+0];
147 g+= src[4*i+1];
148 r+= src[4*i+2];
150 dst[4*i+0]= b;
151 dst[4*i+1]= g;
152 dst[4*i+2]= r;
155 *red= r;
156 *green= g;
157 *blue= b;
160 static inline int sub_left_prediction(HYuvContext *s, uint8_t *dst, uint8_t *src, int w, int left){
161 int i;
162 if(w<32){
163 for(i=0; i<w; i++){
164 const int temp= src[i];
165 dst[i]= temp - left;
166 left= temp;
168 return left;
169 }else{
170 for(i=0; i<16; i++){
171 const int temp= src[i];
172 dst[i]= temp - left;
173 left= temp;
175 s->dsp.diff_bytes(dst+16, src+16, src+15, w-16);
176 return src[w-1];
180 static void read_len_table(uint8_t *dst, GetBitContext *gb){
181 int i, val, repeat;
183 for(i=0; i<256;){
184 repeat= get_bits(gb, 3);
185 val = get_bits(gb, 5);
186 if(repeat==0)
187 repeat= get_bits(gb, 8);
188 //printf("%d %d\n", val, repeat);
189 while (repeat--)
190 dst[i++] = val;
194 static int generate_bits_table(uint32_t *dst, uint8_t *len_table){
195 int len, index;
196 uint32_t bits=0;
198 for(len=32; len>0; len--){
199 int bit= 1<<(32-len);
200 for(index=0; index<256; index++){
201 if(len_table[index]==len){
202 if(bits & (bit-1)){
203 fprintf(stderr, "Error generating huffman table\n");
204 return -1;
206 dst[index]= bits>>(32-len);
207 bits+= bit;
211 return 0;
214 static void generate_len_table(uint8_t *dst, uint64_t *stats, int size){
215 uint64_t counts[2*size];
216 int up[2*size];
217 int offset, i, next;
219 for(offset=1; ; offset<<=1){
220 for(i=0; i<size; i++){
221 counts[i]= stats[i] + offset - 1;
224 for(next=size; next<size*2; next++){
225 uint64_t min1, min2;
226 int min1_i, min2_i;
228 min1=min2= INT64_MAX;
229 min1_i= min2_i=-1;
231 for(i=0; i<next; i++){
232 if(min2 > counts[i]){
233 if(min1 > counts[i]){
234 min2= min1;
235 min2_i= min1_i;
236 min1= counts[i];
237 min1_i= i;
238 }else{
239 min2= counts[i];
240 min2_i= i;
245 if(min2==INT64_MAX) break;
247 counts[next]= min1 + min2;
248 counts[min1_i]=
249 counts[min2_i]= INT64_MAX;
250 up[min1_i]=
251 up[min2_i]= next;
252 up[next]= -1;
255 for(i=0; i<size; i++){
256 int len;
257 int index=i;
259 for(len=0; up[index] != -1; len++)
260 index= up[index];
262 if(len > 32) break;
264 dst[i]= len;
266 if(i==size) break;
270 static int read_huffman_tables(HYuvContext *s, uint8_t *src, int length){
271 GetBitContext gb;
272 int i;
274 init_get_bits(&gb, src, length);
276 for(i=0; i<3; i++){
277 read_len_table(s->len[i], &gb);
279 if(generate_bits_table(s->bits[i], s->len[i])<0){
280 return -1;
282 #if 0
283 for(j=0; j<256; j++){
284 printf("%6X, %2d, %3d\n", s->bits[i][j], s->len[i][j], j);
286 #endif
287 init_vlc(&s->vlc[i], VLC_BITS, 256, s->len[i], 1, 1, s->bits[i], 4, 4);
290 return 0;
293 static int read_old_huffman_tables(HYuvContext *s){
294 #if 0
295 GetBitContext gb;
296 int i;
298 init_get_bits(&gb, classic_shift_luma, sizeof(classic_shift_luma));
299 read_len_table(s->len[0], &gb);
300 init_get_bits(&gb, classic_shift_chroma, sizeof(classic_shift_chroma));
301 read_len_table(s->len[1], &gb);
303 for(i=0; i<256; i++) s->bits[0][i] = classic_add_luma [i];
304 for(i=0; i<256; i++) s->bits[1][i] = classic_add_chroma[i];
306 if(s->bitstream_bpp >= 24){
307 memcpy(s->bits[1], s->bits[0], 256*sizeof(uint32_t));
308 memcpy(s->len[1] , s->len [0], 256*sizeof(uint8_t));
310 memcpy(s->bits[2], s->bits[1], 256*sizeof(uint32_t));
311 memcpy(s->len[2] , s->len [1], 256*sizeof(uint8_t));
313 for(i=0; i<3; i++)
314 init_vlc(&s->vlc[i], VLC_BITS, 256, s->len[i], 1, 1, s->bits[i], 4, 4);
316 return 0;
317 #else
318 fprintf(stderr, "v1 huffyuv is not supported \n");
319 return -1;
320 #endif
323 static int decode_init(AVCodecContext *avctx)
325 HYuvContext *s = avctx->priv_data;
326 int width, height;
328 s->avctx= avctx;
329 s->flags= avctx->flags;
331 dsputil_init(&s->dsp, avctx->dsp_mask);
333 width= s->width= avctx->width;
334 height= s->height= avctx->height;
335 avctx->coded_frame= &s->picture;
337 s->bgr32=1;
338 assert(width && height);
339 //if(avctx->extradata)
340 // printf("extradata:%X, extradata_size:%d\n", *(uint32_t*)avctx->extradata, avctx->extradata_size);
341 if(avctx->extradata_size){
342 if((avctx->bits_per_sample&7) && avctx->bits_per_sample != 12)
343 s->version=1; // do such files exist at all?
344 else
345 s->version=2;
346 }else
347 s->version=0;
349 if(s->version==2){
350 int method;
352 method= ((uint8_t*)avctx->extradata)[0];
353 s->decorrelate= method&64 ? 1 : 0;
354 s->predictor= method&63;
355 s->bitstream_bpp= ((uint8_t*)avctx->extradata)[1];
356 if(s->bitstream_bpp==0)
357 s->bitstream_bpp= avctx->bits_per_sample&~7;
359 if(read_huffman_tables(s, ((uint8_t*)avctx->extradata)+4, avctx->extradata_size) < 0)
360 return -1;
361 }else{
362 switch(avctx->bits_per_sample&7){
363 case 1:
364 s->predictor= LEFT;
365 s->decorrelate= 0;
366 break;
367 case 2:
368 s->predictor= LEFT;
369 s->decorrelate= 1;
370 break;
371 case 3:
372 s->predictor= PLANE;
373 s->decorrelate= avctx->bits_per_sample >= 24;
374 break;
375 case 4:
376 s->predictor= MEDIAN;
377 s->decorrelate= 0;
378 break;
379 default:
380 s->predictor= LEFT; //OLD
381 s->decorrelate= 0;
382 break;
384 s->bitstream_bpp= avctx->bits_per_sample & ~7;
386 if(read_old_huffman_tables(s) < 0)
387 return -1;
390 s->interlaced= height > 288;
392 switch(s->bitstream_bpp){
393 case 12:
394 avctx->pix_fmt = PIX_FMT_YUV420P;
395 break;
396 case 16:
397 if(s->yuy2){
398 avctx->pix_fmt = PIX_FMT_YUV422;
399 }else{
400 avctx->pix_fmt = PIX_FMT_YUV422P;
402 break;
403 case 24:
404 case 32:
405 if(s->bgr32){
406 avctx->pix_fmt = PIX_FMT_BGRA32;
407 }else{
408 avctx->pix_fmt = PIX_FMT_BGR24;
410 break;
411 default:
412 assert(0);
415 // printf("pred:%d bpp:%d hbpp:%d il:%d\n", s->predictor, s->bitstream_bpp, avctx->bits_per_sample, s->interlaced);
417 return 0;
420 static void store_table(HYuvContext *s, uint8_t *len){
421 int i;
422 int index= s->avctx->extradata_size;
424 for(i=0; i<256;){
425 int cur=i;
426 int val= len[i];
427 int repeat;
429 for(; i<256 && len[i]==val; i++);
431 repeat= i - cur;
433 if(repeat>7){
434 ((uint8_t*)s->avctx->extradata)[index++]= val;
435 ((uint8_t*)s->avctx->extradata)[index++]= repeat;
436 }else{
437 ((uint8_t*)s->avctx->extradata)[index++]= val | (repeat<<5);
441 s->avctx->extradata_size= index;
444 static int encode_init(AVCodecContext *avctx)
446 HYuvContext *s = avctx->priv_data;
447 int i, j, width, height;
449 s->avctx= avctx;
450 s->flags= avctx->flags;
452 dsputil_init(&s->dsp, avctx->dsp_mask);
454 width= s->width= avctx->width;
455 height= s->height= avctx->height;
457 assert(width && height);
459 avctx->extradata= av_mallocz(1024*10);
460 avctx->stats_out= av_mallocz(1024*10);
461 s->version=2;
463 avctx->coded_frame= &s->picture;
464 s->picture.pict_type= FF_I_TYPE;
465 s->picture.key_frame= 1;
467 switch(avctx->pix_fmt){
468 case PIX_FMT_YUV420P:
469 if(avctx->strict_std_compliance>=0){
470 fprintf(stderr, "YV12-huffyuv is experimental, there WILL be no compatbility! (use (v)strict=-1)\n");
471 return -1;
473 s->bitstream_bpp= 12;
474 break;
475 case PIX_FMT_YUV422P:
476 s->bitstream_bpp= 16;
477 break;
478 default:
479 fprintf(stderr, "format not supported\n");
480 return -1;
482 avctx->bits_per_sample= s->bitstream_bpp;
483 s->decorrelate= s->bitstream_bpp >= 24;
484 s->predictor= avctx->prediction_method;
486 ((uint8_t*)avctx->extradata)[0]= s->predictor;
487 ((uint8_t*)avctx->extradata)[1]= s->bitstream_bpp;
488 ((uint8_t*)avctx->extradata)[2]=
489 ((uint8_t*)avctx->extradata)[3]= 0;
490 s->avctx->extradata_size= 4;
492 if(avctx->stats_in){
493 char *p= avctx->stats_in;
495 for(i=0; i<3; i++)
496 for(j=0; j<256; j++)
497 s->stats[i][j]= 1;
499 for(;;){
500 for(i=0; i<3; i++){
501 char *next;
503 for(j=0; j<256; j++){
504 s->stats[i][j]+= strtol(p, &next, 0);
505 if(next==p) return -1;
506 p=next;
509 if(p[0]==0 || p[1]==0 || p[2]==0) break;
511 }else{
512 for(i=0; i<3; i++)
513 for(j=0; j<256; j++){
514 int d= FFMIN(j, 256-j);
516 s->stats[i][j]= 100000000/(d+1);
520 for(i=0; i<3; i++){
521 generate_len_table(s->len[i], s->stats[i], 256);
523 if(generate_bits_table(s->bits[i], s->len[i])<0){
524 return -1;
527 store_table(s, s->len[i]);
530 for(i=0; i<3; i++)
531 for(j=0; j<256; j++)
532 s->stats[i][j]= 0;
534 s->interlaced= height > 288;
536 // printf("pred:%d bpp:%d hbpp:%d il:%d\n", s->predictor, s->bitstream_bpp, avctx->bits_per_sample, s->interlaced);
538 s->picture_number=0;
540 return 0;
543 static void decode_422_bitstream(HYuvContext *s, int count){
544 int i;
546 count/=2;
548 for(i=0; i<count; i++){
549 s->temp[0][2*i ]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3);
550 s->temp[1][ i ]= get_vlc2(&s->gb, s->vlc[1].table, VLC_BITS, 3);
551 s->temp[0][2*i+1]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3);
552 s->temp[2][ i ]= get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3);
556 static void decode_gray_bitstream(HYuvContext *s, int count){
557 int i;
559 count/=2;
561 for(i=0; i<count; i++){
562 s->temp[0][2*i ]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3);
563 s->temp[0][2*i+1]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3);
567 static void encode_422_bitstream(HYuvContext *s, int count){
568 int i;
570 count/=2;
571 if(s->flags&CODEC_FLAG_PASS1){
572 for(i=0; i<count; i++){
573 s->stats[0][ s->temp[0][2*i ] ]++;
574 s->stats[1][ s->temp[1][ i ] ]++;
575 s->stats[0][ s->temp[0][2*i+1] ]++;
576 s->stats[2][ s->temp[2][ i ] ]++;
578 }else{
579 for(i=0; i<count; i++){
580 put_bits(&s->pb, s->len[0][ s->temp[0][2*i ] ], s->bits[0][ s->temp[0][2*i ] ]);
581 put_bits(&s->pb, s->len[1][ s->temp[1][ i ] ], s->bits[1][ s->temp[1][ i ] ]);
582 put_bits(&s->pb, s->len[0][ s->temp[0][2*i+1] ], s->bits[0][ s->temp[0][2*i+1] ]);
583 put_bits(&s->pb, s->len[2][ s->temp[2][ i ] ], s->bits[2][ s->temp[2][ i ] ]);
588 static void encode_gray_bitstream(HYuvContext *s, int count){
589 int i;
591 count/=2;
592 if(s->flags&CODEC_FLAG_PASS1){
593 for(i=0; i<count; i++){
594 s->stats[0][ s->temp[0][2*i ] ]++;
595 s->stats[0][ s->temp[0][2*i+1] ]++;
597 }else{
598 for(i=0; i<count; i++){
599 put_bits(&s->pb, s->len[0][ s->temp[0][2*i ] ], s->bits[0][ s->temp[0][2*i ] ]);
600 put_bits(&s->pb, s->len[0][ s->temp[0][2*i+1] ], s->bits[0][ s->temp[0][2*i+1] ]);
605 static void decode_bgr_bitstream(HYuvContext *s, int count){
606 int i;
608 if(s->decorrelate){
609 if(s->bitstream_bpp==24){
610 for(i=0; i<count; i++){
611 s->temp[0][4*i+1]= get_vlc2(&s->gb, s->vlc[1].table, VLC_BITS, 3);
612 s->temp[0][4*i ]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3) + s->temp[0][4*i+1];
613 s->temp[0][4*i+2]= get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3) + s->temp[0][4*i+1];
615 }else{
616 for(i=0; i<count; i++){
617 s->temp[0][4*i+1]= get_vlc2(&s->gb, s->vlc[1].table, VLC_BITS, 3);
618 s->temp[0][4*i ]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3) + s->temp[0][4*i+1];
619 s->temp[0][4*i+2]= get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3) + s->temp[0][4*i+1];
620 get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3); //?!
623 }else{
624 if(s->bitstream_bpp==24){
625 for(i=0; i<count; i++){
626 s->temp[0][4*i ]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3);
627 s->temp[0][4*i+1]= get_vlc2(&s->gb, s->vlc[1].table, VLC_BITS, 3);
628 s->temp[0][4*i+2]= get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3);
630 }else{
631 for(i=0; i<count; i++){
632 s->temp[0][4*i ]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3);
633 s->temp[0][4*i+1]= get_vlc2(&s->gb, s->vlc[1].table, VLC_BITS, 3);
634 s->temp[0][4*i+2]= get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3);
635 get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3); //?!
641 static void draw_slice(HYuvContext *s, int y){
642 int h, cy;
643 UINT8 *src_ptr[3];
645 if(s->avctx->draw_horiz_band==NULL)
646 return;
648 h= y - s->last_slice_end;
649 y -= h;
651 if(s->bitstream_bpp==12){
652 cy= y>>1;
653 }else{
654 cy= y;
657 src_ptr[0] = s->picture.data[0] + s->picture.linesize[0]*y;
658 src_ptr[1] = s->picture.data[1] + s->picture.linesize[1]*cy;
659 src_ptr[2] = s->picture.data[2] + s->picture.linesize[2]*cy;
660 emms_c();
662 s->avctx->draw_horiz_band(s->avctx, src_ptr, s->picture.linesize[0], y, s->width, h);
664 s->last_slice_end= y + h;
667 static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8_t *buf, int buf_size){
668 HYuvContext *s = avctx->priv_data;
669 const int width= s->width;
670 const int width2= s->width>>1;
671 const int height= s->height;
672 int fake_ystride, fake_ustride, fake_vstride;
673 AVFrame * const p= &s->picture;
675 AVFrame *picture = data;
677 *data_size = 0;
679 /* no supplementary picture */
680 if (buf_size == 0)
681 return 0;
683 bswap_buf((uint32_t*)s->bitstream_buffer, (uint32_t*)buf, buf_size/4);
685 init_get_bits(&s->gb, s->bitstream_buffer, buf_size);
687 p->reference= 0;
688 if(avctx->get_buffer(avctx, p) < 0){
689 fprintf(stderr, "get_buffer() failed\n");
690 return -1;
693 fake_ystride= s->interlaced ? p->linesize[0]*2 : p->linesize[0];
694 fake_ustride= s->interlaced ? p->linesize[1]*2 : p->linesize[1];
695 fake_vstride= s->interlaced ? p->linesize[2]*2 : p->linesize[2];
697 s->last_slice_end= 0;
699 if(s->bitstream_bpp<24){
700 int y, cy;
701 int lefty, leftu, leftv;
702 int lefttopy, lefttopu, lefttopv;
704 if(s->yuy2){
705 p->data[0][3]= get_bits(&s->gb, 8);
706 p->data[0][2]= get_bits(&s->gb, 8);
707 p->data[0][1]= get_bits(&s->gb, 8);
708 p->data[0][0]= get_bits(&s->gb, 8);
710 fprintf(stderr, "YUY2 output isnt implemenetd yet\n");
711 return -1;
712 }else{
714 leftv= p->data[2][0]= get_bits(&s->gb, 8);
715 lefty= p->data[0][1]= get_bits(&s->gb, 8);
716 leftu= p->data[1][0]= get_bits(&s->gb, 8);
717 p->data[0][0]= get_bits(&s->gb, 8);
719 switch(s->predictor){
720 case LEFT:
721 case PLANE:
722 decode_422_bitstream(s, width-2);
723 lefty= add_left_prediction(p->data[0] + 2, s->temp[0], width-2, lefty);
724 if(!(s->flags&CODEC_FLAG_GRAY)){
725 leftu= add_left_prediction(p->data[1] + 1, s->temp[1], width2-1, leftu);
726 leftv= add_left_prediction(p->data[2] + 1, s->temp[2], width2-1, leftv);
729 for(cy=y=1; y<s->height; y++,cy++){
730 uint8_t *ydst, *udst, *vdst;
732 if(s->bitstream_bpp==12){
733 decode_gray_bitstream(s, width);
735 ydst= p->data[0] + p->linesize[0]*y;
737 lefty= add_left_prediction(ydst, s->temp[0], width, lefty);
738 if(s->predictor == PLANE){
739 if(y>s->interlaced)
740 s->dsp.add_bytes(ydst, ydst - fake_ystride, width);
742 y++;
743 if(y>=s->height) break;
746 draw_slice(s, y);
748 ydst= p->data[0] + p->linesize[0]*y;
749 udst= p->data[1] + p->linesize[1]*cy;
750 vdst= p->data[2] + p->linesize[2]*cy;
752 decode_422_bitstream(s, width);
753 lefty= add_left_prediction(ydst, s->temp[0], width, lefty);
754 if(!(s->flags&CODEC_FLAG_GRAY)){
755 leftu= add_left_prediction(udst, s->temp[1], width2, leftu);
756 leftv= add_left_prediction(vdst, s->temp[2], width2, leftv);
758 if(s->predictor == PLANE){
759 if(cy>s->interlaced){
760 s->dsp.add_bytes(ydst, ydst - fake_ystride, width);
761 if(!(s->flags&CODEC_FLAG_GRAY)){
762 s->dsp.add_bytes(udst, udst - fake_ustride, width2);
763 s->dsp.add_bytes(vdst, vdst - fake_vstride, width2);
768 draw_slice(s, height);
770 break;
771 case MEDIAN:
772 /* first line except first 2 pixels is left predicted */
773 decode_422_bitstream(s, width-2);
774 lefty= add_left_prediction(p->data[0] + 2, s->temp[0], width-2, lefty);
775 if(!(s->flags&CODEC_FLAG_GRAY)){
776 leftu= add_left_prediction(p->data[1] + 1, s->temp[1], width2-1, leftu);
777 leftv= add_left_prediction(p->data[2] + 1, s->temp[2], width2-1, leftv);
780 cy=y=1;
782 /* second line is left predicted for interlaced case */
783 if(s->interlaced){
784 decode_422_bitstream(s, width);
785 lefty= add_left_prediction(p->data[0] + p->linesize[0], s->temp[0], width, lefty);
786 if(!(s->flags&CODEC_FLAG_GRAY)){
787 leftu= add_left_prediction(p->data[1] + p->linesize[2], s->temp[1], width2, leftu);
788 leftv= add_left_prediction(p->data[2] + p->linesize[1], s->temp[2], width2, leftv);
790 y++; cy++;
793 /* next 4 pixels are left predicted too */
794 decode_422_bitstream(s, 4);
795 lefty= add_left_prediction(p->data[0] + fake_ystride, s->temp[0], 4, lefty);
796 if(!(s->flags&CODEC_FLAG_GRAY)){
797 leftu= add_left_prediction(p->data[1] + fake_ustride, s->temp[1], 2, leftu);
798 leftv= add_left_prediction(p->data[2] + fake_vstride, s->temp[2], 2, leftv);
801 /* next line except the first 4 pixels is median predicted */
802 lefttopy= p->data[0][3];
803 decode_422_bitstream(s, width-4);
804 add_median_prediction(p->data[0] + fake_ystride+4, p->data[0]+4, s->temp[0], width-4, &lefty, &lefttopy);
805 if(!(s->flags&CODEC_FLAG_GRAY)){
806 lefttopu= p->data[1][1];
807 lefttopv= p->data[2][1];
808 add_median_prediction(p->data[1] + fake_ustride+2, p->data[1]+2, s->temp[1], width2-2, &leftu, &lefttopu);
809 add_median_prediction(p->data[2] + fake_vstride+2, p->data[2]+2, s->temp[2], width2-2, &leftv, &lefttopv);
811 y++; cy++;
813 for(; y<height; y++,cy++){
814 uint8_t *ydst, *udst, *vdst;
816 if(s->bitstream_bpp==12){
817 while(2*cy > y){
818 decode_gray_bitstream(s, width);
819 ydst= p->data[0] + p->linesize[0]*y;
820 add_median_prediction(ydst, ydst - fake_ystride, s->temp[0], width, &lefty, &lefttopy);
821 y++;
823 if(y>=height) break;
825 draw_slice(s, y);
827 decode_422_bitstream(s, width);
829 ydst= p->data[0] + p->linesize[0]*y;
830 udst= p->data[1] + p->linesize[1]*cy;
831 vdst= p->data[2] + p->linesize[2]*cy;
833 add_median_prediction(ydst, ydst - fake_ystride, s->temp[0], width, &lefty, &lefttopy);
834 if(!(s->flags&CODEC_FLAG_GRAY)){
835 add_median_prediction(udst, udst - fake_ustride, s->temp[1], width2, &leftu, &lefttopu);
836 add_median_prediction(vdst, vdst - fake_vstride, s->temp[2], width2, &leftv, &lefttopv);
840 draw_slice(s, height);
841 break;
844 }else{
845 int y;
846 int leftr, leftg, leftb;
847 const int last_line= (height-1)*p->linesize[0];
849 if(s->bitstream_bpp==32){
850 p->data[0][last_line+3]= get_bits(&s->gb, 8);
851 leftr= p->data[0][last_line+2]= get_bits(&s->gb, 8);
852 leftg= p->data[0][last_line+1]= get_bits(&s->gb, 8);
853 leftb= p->data[0][last_line+0]= get_bits(&s->gb, 8);
854 }else{
855 leftr= p->data[0][last_line+2]= get_bits(&s->gb, 8);
856 leftg= p->data[0][last_line+1]= get_bits(&s->gb, 8);
857 leftb= p->data[0][last_line+0]= get_bits(&s->gb, 8);
858 skip_bits(&s->gb, 8);
861 if(s->bgr32){
862 switch(s->predictor){
863 case LEFT:
864 case PLANE:
865 decode_bgr_bitstream(s, width-1);
866 add_left_prediction_bgr32(p->data[0] + last_line+4, s->temp[0], width-1, &leftr, &leftg, &leftb);
868 for(y=s->height-2; y>=0; y--){ //yes its stored upside down
869 decode_bgr_bitstream(s, width);
871 add_left_prediction_bgr32(p->data[0] + p->linesize[0]*y, s->temp[0], width, &leftr, &leftg, &leftb);
872 if(s->predictor == PLANE){
873 if((y&s->interlaced)==0){
874 s->dsp.add_bytes(p->data[0] + p->linesize[0]*y,
875 p->data[0] + p->linesize[0]*y + fake_ystride, fake_ystride);
879 draw_slice(s, height); // just 1 large slice as this isnt possible in reverse order
880 break;
881 default:
882 fprintf(stderr, "prediction type not supported!\n");
884 }else{
886 fprintf(stderr, "BGR24 output isnt implemenetd yet\n");
887 return -1;
890 emms_c();
892 *picture= *p;
894 avctx->release_buffer(avctx, p);
896 *data_size = sizeof(AVFrame);
898 return (get_bits_count(&s->gb)+7)>>3;
901 static int decode_end(AVCodecContext *avctx)
903 HYuvContext *s = avctx->priv_data;
904 int i;
906 for(i=0; i<3; i++){
907 free_vlc(&s->vlc[i]);
910 if(avctx->get_buffer == avcodec_default_get_buffer){
911 for(i=0; i<4; i++){
912 av_freep(&s->picture.base[i]);
913 s->picture.data[i]= NULL;
915 av_freep(&s->picture.opaque);
918 return 0;
921 static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){
922 HYuvContext *s = avctx->priv_data;
923 AVFrame *pict = data;
924 const int width= s->width;
925 const int width2= s->width>>1;
926 const int height= s->height;
927 const int fake_ystride= s->interlaced ? pict->linesize[0]*2 : pict->linesize[0];
928 const int fake_ustride= s->interlaced ? pict->linesize[1]*2 : pict->linesize[1];
929 const int fake_vstride= s->interlaced ? pict->linesize[2]*2 : pict->linesize[2];
930 AVFrame * const p= &s->picture;
931 int i, size;
933 init_put_bits(&s->pb, buf, buf_size, NULL, NULL);
935 *p = *pict;
937 if(avctx->pix_fmt == PIX_FMT_YUV422P || avctx->pix_fmt == PIX_FMT_YUV420P){
938 int lefty, leftu, leftv, y, cy;
940 put_bits(&s->pb, 8, leftv= p->data[2][0]);
941 put_bits(&s->pb, 8, lefty= p->data[0][1]);
942 put_bits(&s->pb, 8, leftu= p->data[1][0]);
943 put_bits(&s->pb, 8, p->data[0][0]);
945 lefty= sub_left_prediction(s, s->temp[0], p->data[0]+2, width-2 , lefty);
946 leftu= sub_left_prediction(s, s->temp[1], p->data[1]+1, width2-1, leftu);
947 leftv= sub_left_prediction(s, s->temp[2], p->data[2]+1, width2-1, leftv);
949 encode_422_bitstream(s, width-2);
951 if(s->predictor==MEDIAN){
952 int lefttopy, lefttopu, lefttopv;
953 cy=y=1;
954 if(s->interlaced){
955 lefty= sub_left_prediction(s, s->temp[0], p->data[0]+p->linesize[0], width , lefty);
956 leftu= sub_left_prediction(s, s->temp[1], p->data[1]+p->linesize[1], width2, leftu);
957 leftv= sub_left_prediction(s, s->temp[2], p->data[2]+p->linesize[2], width2, leftv);
959 encode_422_bitstream(s, width);
960 y++; cy++;
963 lefty= sub_left_prediction(s, s->temp[0], p->data[0]+fake_ystride, 4, lefty);
964 leftu= sub_left_prediction(s, s->temp[1], p->data[1]+fake_ystride, 2, leftu);
965 leftv= sub_left_prediction(s, s->temp[2], p->data[2]+fake_ystride, 2, leftv);
967 encode_422_bitstream(s, 4);
969 lefttopy= p->data[0][3];
970 lefttopu= p->data[1][1];
971 lefttopv= p->data[2][1];
972 sub_median_prediction(s->temp[0], p->data[0]+4, p->data[0] + fake_ystride+4, width-4 , &lefty, &lefttopy);
973 sub_median_prediction(s->temp[1], p->data[1]+2, p->data[1] + fake_ustride+2, width2-2, &leftu, &lefttopu);
974 sub_median_prediction(s->temp[2], p->data[2]+2, p->data[2] + fake_vstride+2, width2-2, &leftv, &lefttopv);
975 encode_422_bitstream(s, width-4);
976 y++; cy++;
978 for(; y<height; y++,cy++){
979 uint8_t *ydst, *udst, *vdst;
981 if(s->bitstream_bpp==12){
982 while(2*cy > y){
983 ydst= p->data[0] + p->linesize[0]*y;
984 sub_median_prediction(s->temp[0], ydst - fake_ystride, ydst, width , &lefty, &lefttopy);
985 encode_gray_bitstream(s, width);
986 y++;
988 if(y>=height) break;
990 ydst= p->data[0] + p->linesize[0]*y;
991 udst= p->data[1] + p->linesize[1]*cy;
992 vdst= p->data[2] + p->linesize[2]*cy;
994 sub_median_prediction(s->temp[0], ydst - fake_ystride, ydst, width , &lefty, &lefttopy);
995 sub_median_prediction(s->temp[1], udst - fake_ustride, udst, width2, &leftu, &lefttopu);
996 sub_median_prediction(s->temp[2], vdst - fake_vstride, vdst, width2, &leftv, &lefttopv);
998 encode_422_bitstream(s, width);
1000 }else{
1001 for(cy=y=1; y<height; y++,cy++){
1002 uint8_t *ydst, *udst, *vdst;
1004 /* encode a luma only line & y++ */
1005 if(s->bitstream_bpp==12){
1006 ydst= p->data[0] + p->linesize[0]*y;
1008 if(s->predictor == PLANE && s->interlaced < y){
1009 s->dsp.diff_bytes(s->temp[1], ydst, ydst - fake_ystride, width);
1011 lefty= sub_left_prediction(s, s->temp[0], s->temp[1], width , lefty);
1012 }else{
1013 lefty= sub_left_prediction(s, s->temp[0], ydst, width , lefty);
1015 encode_gray_bitstream(s, width);
1016 y++;
1017 if(y>=height) break;
1020 ydst= p->data[0] + p->linesize[0]*y;
1021 udst= p->data[1] + p->linesize[1]*cy;
1022 vdst= p->data[2] + p->linesize[2]*cy;
1024 if(s->predictor == PLANE && s->interlaced < cy){
1025 s->dsp.diff_bytes(s->temp[1], ydst, ydst - fake_ystride, width);
1026 s->dsp.diff_bytes(s->temp[2], udst, udst - fake_ustride, width2);
1027 s->dsp.diff_bytes(s->temp[3], vdst, vdst - fake_vstride, width2);
1029 lefty= sub_left_prediction(s, s->temp[0], s->temp[1], width , lefty);
1030 leftu= sub_left_prediction(s, s->temp[1], s->temp[2], width2, leftu);
1031 leftv= sub_left_prediction(s, s->temp[2], s->temp[3], width2, leftv);
1032 }else{
1033 lefty= sub_left_prediction(s, s->temp[0], ydst, width , lefty);
1034 leftu= sub_left_prediction(s, s->temp[1], udst, width2, leftu);
1035 leftv= sub_left_prediction(s, s->temp[2], vdst, width2, leftv);
1038 encode_422_bitstream(s, width);
1041 }else{
1042 fprintf(stderr, "Format not supported!\n");
1044 emms_c();
1046 size= (get_bit_count(&s->pb)+31)/32;
1048 if((s->flags&CODEC_FLAG_PASS1) && (s->picture_number&31)==0){
1049 int j;
1050 char *p= avctx->stats_out;
1051 for(i=0; i<3; i++){
1052 for(j=0; j<256; j++){
1053 sprintf(p, "%Ld ", s->stats[i][j]);
1054 p+= strlen(p);
1055 s->stats[i][j]= 0;
1057 sprintf(p, "\n");
1058 p++;
1060 }else{
1061 flush_put_bits(&s->pb);
1062 bswap_buf((uint32_t*)buf, (uint32_t*)buf, size);
1065 s->picture_number++;
1067 return size*4;
1070 static int encode_end(AVCodecContext *avctx)
1072 // HYuvContext *s = avctx->priv_data;
1074 av_freep(&avctx->extradata);
1075 av_freep(&avctx->stats_out);
1077 return 0;
1080 AVCodec huffyuv_decoder = {
1081 "huffyuv",
1082 CODEC_TYPE_VIDEO,
1083 CODEC_ID_HUFFYUV,
1084 sizeof(HYuvContext),
1085 decode_init,
1086 NULL,
1087 decode_end,
1088 decode_frame,
1089 CODEC_CAP_DR1 | CODEC_CAP_DRAW_HORIZ_BAND,
1090 NULL
1093 AVCodec huffyuv_encoder = {
1094 "huffyuv",
1095 CODEC_TYPE_VIDEO,
1096 CODEC_ID_HUFFYUV,
1097 sizeof(HYuvContext),
1098 encode_init,
1099 encode_frame,
1100 encode_end,