2 * huffyuv codec for libavcodec
4 * Copyright (c) 2002-2003 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
26 * huffyuv codec for libavcodec.
34 #define INT64_MAX 9223372036854775807LL
39 typedef enum Predictor{
45 typedef struct HYuvContext{
46 AVCodecContext *avctx;
54 int yuy2; //use yuy2 instead of 422P
55 int bgr32; //use bgr32 instead of bgr24
60 uint8_t __align8 temp[3][2500];
61 uint64_t stats[3][256];
63 uint32_t bits[3][256];
66 uint8_t __align8 bitstream_buffer[1024*1024*3]; //FIXME dynamic alloc or some other solution
70 static const unsigned char classic_shift_luma[] = {
71 34,36,35,69,135,232,9,16,10,24,11,23,12,16,13,10,14,8,15,8,
72 16,8,17,20,16,10,207,206,205,236,11,8,10,21,9,23,8,8,199,70,
76 static const unsigned char classic_shift_chroma[] = {
77 66,36,37,38,39,40,41,75,76,77,110,239,144,81,82,83,84,85,118,183,
78 56,57,88,89,56,89,154,57,58,57,26,141,57,56,58,57,58,57,184,119,
79 214,245,116,83,82,49,80,79,78,77,44,75,41,40,39,38,37,36,34, 0
82 static const unsigned char classic_add_luma[256] = {
83 3, 9, 5, 12, 10, 35, 32, 29, 27, 50, 48, 45, 44, 41, 39, 37,
84 73, 70, 68, 65, 64, 61, 58, 56, 53, 50, 49, 46, 44, 41, 38, 36,
85 68, 65, 63, 61, 58, 55, 53, 51, 48, 46, 45, 43, 41, 39, 38, 36,
86 35, 33, 32, 30, 29, 27, 26, 25, 48, 47, 46, 44, 43, 41, 40, 39,
87 37, 36, 35, 34, 32, 31, 30, 28, 27, 26, 24, 23, 22, 20, 19, 37,
88 35, 34, 33, 31, 30, 29, 27, 26, 24, 23, 21, 20, 18, 17, 15, 29,
89 27, 26, 24, 22, 21, 19, 17, 16, 14, 26, 25, 23, 21, 19, 18, 16,
90 15, 27, 25, 23, 21, 19, 17, 16, 14, 26, 25, 23, 21, 18, 17, 14,
91 12, 17, 19, 13, 4, 9, 2, 11, 1, 7, 8, 0, 16, 3, 14, 6,
92 12, 10, 5, 15, 18, 11, 10, 13, 15, 16, 19, 20, 22, 24, 27, 15,
93 18, 20, 22, 24, 26, 14, 17, 20, 22, 24, 27, 15, 18, 20, 23, 25,
94 28, 16, 19, 22, 25, 28, 32, 36, 21, 25, 29, 33, 38, 42, 45, 49,
95 28, 31, 34, 37, 40, 42, 44, 47, 49, 50, 52, 54, 56, 57, 59, 60,
96 62, 64, 66, 67, 69, 35, 37, 39, 40, 42, 43, 45, 47, 48, 51, 52,
97 54, 55, 57, 59, 60, 62, 63, 66, 67, 69, 71, 72, 38, 40, 42, 43,
98 46, 47, 49, 51, 26, 28, 30, 31, 33, 34, 18, 19, 11, 13, 7, 8,
101 static const unsigned char classic_add_chroma[256] = {
102 3, 1, 2, 2, 2, 2, 3, 3, 7, 5, 7, 5, 8, 6, 11, 9,
103 7, 13, 11, 10, 9, 8, 7, 5, 9, 7, 6, 4, 7, 5, 8, 7,
104 11, 8, 13, 11, 19, 15, 22, 23, 20, 33, 32, 28, 27, 29, 51, 77,
105 43, 45, 76, 81, 46, 82, 75, 55, 56,144, 58, 80, 60, 74,147, 63,
106 143, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
107 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 27, 30, 21, 22,
108 17, 14, 5, 6,100, 54, 47, 50, 51, 53,106,107,108,109,110,111,
109 112,113,114,115, 4,117,118, 92, 94,121,122, 3,124,103, 2, 1,
110 0,129,130,131,120,119,126,125,136,137,138,139,140,141,142,134,
111 135,132,133,104, 64,101, 62, 57,102, 95, 93, 59, 61, 28, 97, 96,
112 52, 49, 48, 29, 32, 25, 24, 46, 23, 98, 45, 44, 43, 20, 42, 41,
113 19, 18, 99, 40, 15, 39, 38, 16, 13, 12, 11, 37, 10, 9, 8, 36,
114 7,128,127,105,123,116, 35, 34, 33,145, 31, 79, 42,146, 78, 26,
115 83, 48, 49, 50, 44, 47, 26, 31, 30, 18, 17, 19, 21, 24, 25, 13,
116 14, 16, 17, 18, 20, 21, 12, 14, 15, 9, 10, 6, 9, 6, 5, 8,
117 6, 12, 8, 10, 7, 9, 6, 4, 6, 2, 2, 3, 3, 3, 3, 2,
120 static inline int add_left_prediction(uint8_t *dst, uint8_t *src, int w, int acc){
123 for(i=0; i<w-1; i++){
139 static inline void add_median_prediction(uint8_t *dst, uint8_t *src1, uint8_t *diff, int w, int *left, int *left_top){
147 l= mid_pred(l, src1[i], (l + src1[i] - lt)&0xFF) + diff[i];
157 static inline void sub_median_prediction(uint8_t *dst, uint8_t *src1, uint8_t *src2, int w, int *left, int *left_top){
165 const int pred= mid_pred(l, src1[i], (l + src1[i] - lt)&0xFF);
175 static inline void add_left_prediction_bgr32(uint8_t *dst, uint8_t *src, int w, int *red, int *green, int *blue){
197 static inline int sub_left_prediction(HYuvContext *s, uint8_t *dst, uint8_t *src, int w, int left){
201 const int temp= src[i];
208 const int temp= src[i];
212 s->dsp.diff_bytes(dst+16, src+16, src+15, w-16);
217 static void read_len_table(uint8_t *dst, GetBitContext *gb){
221 repeat= get_bits(gb, 3);
222 val = get_bits(gb, 5);
224 repeat= get_bits(gb, 8);
225 //printf("%d %d\n", val, repeat);
231 static int generate_bits_table(uint32_t *dst, uint8_t *len_table){
235 for(len=32; len>0; len--){
236 for(index=0; index<256; index++){
237 if(len_table[index]==len)
241 fprintf(stderr, "Error generating huffman table\n");
249 static void generate_len_table(uint8_t *dst, uint64_t *stats, int size){
250 uint64_t counts[2*size];
254 for(offset=1; ; offset<<=1){
255 for(i=0; i<size; i++){
256 counts[i]= stats[i] + offset - 1;
259 for(next=size; next<size*2; next++){
263 min1=min2= INT64_MAX;
266 for(i=0; i<next; i++){
267 if(min2 > counts[i]){
268 if(min1 > counts[i]){
280 if(min2==INT64_MAX) break;
282 counts[next]= min1 + min2;
284 counts[min2_i]= INT64_MAX;
290 for(i=0; i<size; i++){
294 for(len=0; up[index] != -1; len++)
305 static int read_huffman_tables(HYuvContext *s, uint8_t *src, int length){
309 init_get_bits(&gb, src, length*8);
312 read_len_table(s->len[i], &gb);
314 if(generate_bits_table(s->bits[i], s->len[i])<0){
318 for(j=0; j<256; j++){
319 printf("%6X, %2d, %3d\n", s->bits[i][j], s->len[i][j], j);
322 init_vlc(&s->vlc[i], VLC_BITS, 256, s->len[i], 1, 1, s->bits[i], 4, 4);
328 static int read_old_huffman_tables(HYuvContext *s){
333 init_get_bits(&gb, classic_shift_luma, sizeof(classic_shift_luma)*8);
334 read_len_table(s->len[0], &gb);
335 init_get_bits(&gb, classic_shift_chroma, sizeof(classic_shift_chroma)*8);
336 read_len_table(s->len[1], &gb);
338 for(i=0; i<256; i++) s->bits[0][i] = classic_add_luma [i];
339 for(i=0; i<256; i++) s->bits[1][i] = classic_add_chroma[i];
341 if(s->bitstream_bpp >= 24){
342 memcpy(s->bits[1], s->bits[0], 256*sizeof(uint32_t));
343 memcpy(s->len[1] , s->len [0], 256*sizeof(uint8_t));
345 memcpy(s->bits[2], s->bits[1], 256*sizeof(uint32_t));
346 memcpy(s->len[2] , s->len [1], 256*sizeof(uint8_t));
349 init_vlc(&s->vlc[i], VLC_BITS, 256, s->len[i], 1, 1, s->bits[i], 4, 4);
353 fprintf(stderr, "v1 huffyuv is not supported \n");
358 static int decode_init(AVCodecContext *avctx)
360 HYuvContext *s = avctx->priv_data;
364 s->flags= avctx->flags;
366 dsputil_init(&s->dsp, avctx);
368 width= s->width= avctx->width;
369 height= s->height= avctx->height;
370 avctx->coded_frame= &s->picture;
373 assert(width && height);
374 //if(avctx->extradata)
375 // printf("extradata:%X, extradata_size:%d\n", *(uint32_t*)avctx->extradata, avctx->extradata_size);
376 if(avctx->extradata_size){
377 if((avctx->bits_per_sample&7) && avctx->bits_per_sample != 12)
378 s->version=1; // do such files exist at all?
387 method= ((uint8_t*)avctx->extradata)[0];
388 s->decorrelate= method&64 ? 1 : 0;
389 s->predictor= method&63;
390 s->bitstream_bpp= ((uint8_t*)avctx->extradata)[1];
391 if(s->bitstream_bpp==0)
392 s->bitstream_bpp= avctx->bits_per_sample&~7;
394 if(read_huffman_tables(s, ((uint8_t*)avctx->extradata)+4, avctx->extradata_size) < 0)
397 switch(avctx->bits_per_sample&7){
408 s->decorrelate= avctx->bits_per_sample >= 24;
411 s->predictor= MEDIAN;
415 s->predictor= LEFT; //OLD
419 s->bitstream_bpp= avctx->bits_per_sample & ~7;
421 if(read_old_huffman_tables(s) < 0)
425 s->interlaced= height > 288;
427 switch(s->bitstream_bpp){
429 avctx->pix_fmt = PIX_FMT_YUV420P;
433 avctx->pix_fmt = PIX_FMT_YUV422;
435 avctx->pix_fmt = PIX_FMT_YUV422P;
441 avctx->pix_fmt = PIX_FMT_RGBA32;
443 avctx->pix_fmt = PIX_FMT_BGR24;
450 // printf("pred:%d bpp:%d hbpp:%d il:%d\n", s->predictor, s->bitstream_bpp, avctx->bits_per_sample, s->interlaced);
455 static void store_table(HYuvContext *s, uint8_t *len){
457 int index= s->avctx->extradata_size;
464 for(; i<256 && len[i]==val; i++);
469 ((uint8_t*)s->avctx->extradata)[index++]= val;
470 ((uint8_t*)s->avctx->extradata)[index++]= repeat;
472 ((uint8_t*)s->avctx->extradata)[index++]= val | (repeat<<5);
476 s->avctx->extradata_size= index;
479 static int encode_init(AVCodecContext *avctx)
481 HYuvContext *s = avctx->priv_data;
482 int i, j, width, height;
485 s->flags= avctx->flags;
487 dsputil_init(&s->dsp, avctx);
489 width= s->width= avctx->width;
490 height= s->height= avctx->height;
492 assert(width && height);
494 avctx->extradata= av_mallocz(1024*10);
495 avctx->stats_out= av_mallocz(1024*10);
498 avctx->coded_frame= &s->picture;
500 switch(avctx->pix_fmt){
501 case PIX_FMT_YUV420P:
502 if(avctx->strict_std_compliance>=0){
503 fprintf(stderr, "YV12-huffyuv is experimental, there WILL be no compatbility! (use (v)strict=-1)\n");
506 s->bitstream_bpp= 12;
508 case PIX_FMT_YUV422P:
509 s->bitstream_bpp= 16;
512 fprintf(stderr, "format not supported\n");
515 avctx->bits_per_sample= s->bitstream_bpp;
516 s->decorrelate= s->bitstream_bpp >= 24;
517 s->predictor= avctx->prediction_method;
519 ((uint8_t*)avctx->extradata)[0]= s->predictor;
520 ((uint8_t*)avctx->extradata)[1]= s->bitstream_bpp;
521 ((uint8_t*)avctx->extradata)[2]=
522 ((uint8_t*)avctx->extradata)[3]= 0;
523 s->avctx->extradata_size= 4;
526 char *p= avctx->stats_in;
536 for(j=0; j<256; j++){
537 s->stats[i][j]+= strtol(p, &next, 0);
538 if(next==p) return -1;
542 if(p[0]==0 || p[1]==0 || p[2]==0) break;
546 for(j=0; j<256; j++){
547 int d= FFMIN(j, 256-j);
549 s->stats[i][j]= 100000000/(d+1);
554 generate_len_table(s->len[i], s->stats[i], 256);
556 if(generate_bits_table(s->bits[i], s->len[i])<0){
560 store_table(s, s->len[i]);
567 s->interlaced= height > 288;
569 // printf("pred:%d bpp:%d hbpp:%d il:%d\n", s->predictor, s->bitstream_bpp, avctx->bits_per_sample, s->interlaced);
576 static void decode_422_bitstream(HYuvContext *s, int count){
581 for(i=0; i<count; i++){
582 s->temp[0][2*i ]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3);
583 s->temp[1][ i ]= get_vlc2(&s->gb, s->vlc[1].table, VLC_BITS, 3);
584 s->temp[0][2*i+1]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3);
585 s->temp[2][ i ]= get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3);
589 static void decode_gray_bitstream(HYuvContext *s, int count){
594 for(i=0; i<count; i++){
595 s->temp[0][2*i ]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3);
596 s->temp[0][2*i+1]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3);
600 static void encode_422_bitstream(HYuvContext *s, int count){
604 if(s->flags&CODEC_FLAG_PASS1){
605 for(i=0; i<count; i++){
606 s->stats[0][ s->temp[0][2*i ] ]++;
607 s->stats[1][ s->temp[1][ i ] ]++;
608 s->stats[0][ s->temp[0][2*i+1] ]++;
609 s->stats[2][ s->temp[2][ i ] ]++;
612 for(i=0; i<count; i++){
613 put_bits(&s->pb, s->len[0][ s->temp[0][2*i ] ], s->bits[0][ s->temp[0][2*i ] ]);
614 put_bits(&s->pb, s->len[1][ s->temp[1][ i ] ], s->bits[1][ s->temp[1][ 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 put_bits(&s->pb, s->len[2][ s->temp[2][ i ] ], s->bits[2][ s->temp[2][ i ] ]);
621 static void encode_gray_bitstream(HYuvContext *s, int count){
625 if(s->flags&CODEC_FLAG_PASS1){
626 for(i=0; i<count; i++){
627 s->stats[0][ s->temp[0][2*i ] ]++;
628 s->stats[0][ s->temp[0][2*i+1] ]++;
631 for(i=0; i<count; i++){
632 put_bits(&s->pb, s->len[0][ s->temp[0][2*i ] ], s->bits[0][ s->temp[0][2*i ] ]);
633 put_bits(&s->pb, s->len[0][ s->temp[0][2*i+1] ], s->bits[0][ s->temp[0][2*i+1] ]);
638 static void decode_bgr_bitstream(HYuvContext *s, int count){
642 if(s->bitstream_bpp==24){
643 for(i=0; i<count; i++){
644 s->temp[0][4*i+1]= get_vlc2(&s->gb, s->vlc[1].table, VLC_BITS, 3);
645 s->temp[0][4*i ]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3) + s->temp[0][4*i+1];
646 s->temp[0][4*i+2]= get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3) + s->temp[0][4*i+1];
649 for(i=0; i<count; i++){
650 s->temp[0][4*i+1]= get_vlc2(&s->gb, s->vlc[1].table, VLC_BITS, 3);
651 s->temp[0][4*i ]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3) + s->temp[0][4*i+1];
652 s->temp[0][4*i+2]= get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3) + s->temp[0][4*i+1];
653 get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3); //?!
657 if(s->bitstream_bpp==24){
658 for(i=0; i<count; i++){
659 s->temp[0][4*i ]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3);
660 s->temp[0][4*i+1]= get_vlc2(&s->gb, s->vlc[1].table, VLC_BITS, 3);
661 s->temp[0][4*i+2]= get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3);
664 for(i=0; i<count; i++){
665 s->temp[0][4*i ]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3);
666 s->temp[0][4*i+1]= get_vlc2(&s->gb, s->vlc[1].table, VLC_BITS, 3);
667 s->temp[0][4*i+2]= get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3);
668 get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3); //?!
674 static void draw_slice(HYuvContext *s, int y){
678 if(s->avctx->draw_horiz_band==NULL)
681 h= y - s->last_slice_end;
684 if(s->bitstream_bpp==12){
690 offset[0] = s->picture.linesize[0]*y;
691 offset[1] = s->picture.linesize[1]*cy;
692 offset[2] = s->picture.linesize[2]*cy;
696 s->avctx->draw_horiz_band(s->avctx, &s->picture, offset, y, 3, h);
698 s->last_slice_end= y + h;
701 static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8_t *buf, int buf_size){
702 HYuvContext *s = avctx->priv_data;
703 const int width= s->width;
704 const int width2= s->width>>1;
705 const int height= s->height;
706 int fake_ystride, fake_ustride, fake_vstride;
707 AVFrame * const p= &s->picture;
709 AVFrame *picture = data;
713 /* no supplementary picture */
717 s->dsp.bswap_buf((uint32_t*)s->bitstream_buffer, (uint32_t*)buf, buf_size/4);
719 init_get_bits(&s->gb, s->bitstream_buffer, buf_size*8);
722 avctx->release_buffer(avctx, p);
725 if(avctx->get_buffer(avctx, p) < 0){
726 fprintf(stderr, "get_buffer() failed\n");
730 fake_ystride= s->interlaced ? p->linesize[0]*2 : p->linesize[0];
731 fake_ustride= s->interlaced ? p->linesize[1]*2 : p->linesize[1];
732 fake_vstride= s->interlaced ? p->linesize[2]*2 : p->linesize[2];
734 s->last_slice_end= 0;
736 if(s->bitstream_bpp<24){
738 int lefty, leftu, leftv;
739 int lefttopy, lefttopu, lefttopv;
742 p->data[0][3]= get_bits(&s->gb, 8);
743 p->data[0][2]= get_bits(&s->gb, 8);
744 p->data[0][1]= get_bits(&s->gb, 8);
745 p->data[0][0]= get_bits(&s->gb, 8);
747 fprintf(stderr, "YUY2 output isnt implemenetd yet\n");
751 leftv= p->data[2][0]= get_bits(&s->gb, 8);
752 lefty= p->data[0][1]= get_bits(&s->gb, 8);
753 leftu= p->data[1][0]= get_bits(&s->gb, 8);
754 p->data[0][0]= get_bits(&s->gb, 8);
756 switch(s->predictor){
759 decode_422_bitstream(s, width-2);
760 lefty= add_left_prediction(p->data[0] + 2, s->temp[0], width-2, lefty);
761 if(!(s->flags&CODEC_FLAG_GRAY)){
762 leftu= add_left_prediction(p->data[1] + 1, s->temp[1], width2-1, leftu);
763 leftv= add_left_prediction(p->data[2] + 1, s->temp[2], width2-1, leftv);
766 for(cy=y=1; y<s->height; y++,cy++){
767 uint8_t *ydst, *udst, *vdst;
769 if(s->bitstream_bpp==12){
770 decode_gray_bitstream(s, width);
772 ydst= p->data[0] + p->linesize[0]*y;
774 lefty= add_left_prediction(ydst, s->temp[0], width, lefty);
775 if(s->predictor == PLANE){
777 s->dsp.add_bytes(ydst, ydst - fake_ystride, width);
780 if(y>=s->height) break;
785 ydst= p->data[0] + p->linesize[0]*y;
786 udst= p->data[1] + p->linesize[1]*cy;
787 vdst= p->data[2] + p->linesize[2]*cy;
789 decode_422_bitstream(s, width);
790 lefty= add_left_prediction(ydst, s->temp[0], width, lefty);
791 if(!(s->flags&CODEC_FLAG_GRAY)){
792 leftu= add_left_prediction(udst, s->temp[1], width2, leftu);
793 leftv= add_left_prediction(vdst, s->temp[2], width2, leftv);
795 if(s->predictor == PLANE){
796 if(cy>s->interlaced){
797 s->dsp.add_bytes(ydst, ydst - fake_ystride, width);
798 if(!(s->flags&CODEC_FLAG_GRAY)){
799 s->dsp.add_bytes(udst, udst - fake_ustride, width2);
800 s->dsp.add_bytes(vdst, vdst - fake_vstride, width2);
805 draw_slice(s, height);
809 /* first line except first 2 pixels is left predicted */
810 decode_422_bitstream(s, width-2);
811 lefty= add_left_prediction(p->data[0] + 2, s->temp[0], width-2, lefty);
812 if(!(s->flags&CODEC_FLAG_GRAY)){
813 leftu= add_left_prediction(p->data[1] + 1, s->temp[1], width2-1, leftu);
814 leftv= add_left_prediction(p->data[2] + 1, s->temp[2], width2-1, leftv);
819 /* second line is left predicted for interlaced case */
821 decode_422_bitstream(s, width);
822 lefty= add_left_prediction(p->data[0] + p->linesize[0], s->temp[0], width, lefty);
823 if(!(s->flags&CODEC_FLAG_GRAY)){
824 leftu= add_left_prediction(p->data[1] + p->linesize[2], s->temp[1], width2, leftu);
825 leftv= add_left_prediction(p->data[2] + p->linesize[1], s->temp[2], width2, leftv);
830 /* next 4 pixels are left predicted too */
831 decode_422_bitstream(s, 4);
832 lefty= add_left_prediction(p->data[0] + fake_ystride, s->temp[0], 4, lefty);
833 if(!(s->flags&CODEC_FLAG_GRAY)){
834 leftu= add_left_prediction(p->data[1] + fake_ustride, s->temp[1], 2, leftu);
835 leftv= add_left_prediction(p->data[2] + fake_vstride, s->temp[2], 2, leftv);
838 /* next line except the first 4 pixels is median predicted */
839 lefttopy= p->data[0][3];
840 decode_422_bitstream(s, width-4);
841 add_median_prediction(p->data[0] + fake_ystride+4, p->data[0]+4, s->temp[0], width-4, &lefty, &lefttopy);
842 if(!(s->flags&CODEC_FLAG_GRAY)){
843 lefttopu= p->data[1][1];
844 lefttopv= p->data[2][1];
845 add_median_prediction(p->data[1] + fake_ustride+2, p->data[1]+2, s->temp[1], width2-2, &leftu, &lefttopu);
846 add_median_prediction(p->data[2] + fake_vstride+2, p->data[2]+2, s->temp[2], width2-2, &leftv, &lefttopv);
850 for(; y<height; y++,cy++){
851 uint8_t *ydst, *udst, *vdst;
853 if(s->bitstream_bpp==12){
855 decode_gray_bitstream(s, width);
856 ydst= p->data[0] + p->linesize[0]*y;
857 add_median_prediction(ydst, ydst - fake_ystride, s->temp[0], width, &lefty, &lefttopy);
864 decode_422_bitstream(s, width);
866 ydst= p->data[0] + p->linesize[0]*y;
867 udst= p->data[1] + p->linesize[1]*cy;
868 vdst= p->data[2] + p->linesize[2]*cy;
870 add_median_prediction(ydst, ydst - fake_ystride, s->temp[0], width, &lefty, &lefttopy);
871 if(!(s->flags&CODEC_FLAG_GRAY)){
872 add_median_prediction(udst, udst - fake_ustride, s->temp[1], width2, &leftu, &lefttopu);
873 add_median_prediction(vdst, vdst - fake_vstride, s->temp[2], width2, &leftv, &lefttopv);
877 draw_slice(s, height);
883 int leftr, leftg, leftb;
884 const int last_line= (height-1)*p->linesize[0];
886 if(s->bitstream_bpp==32){
887 p->data[0][last_line+3]= get_bits(&s->gb, 8);
888 leftr= p->data[0][last_line+2]= get_bits(&s->gb, 8);
889 leftg= p->data[0][last_line+1]= get_bits(&s->gb, 8);
890 leftb= p->data[0][last_line+0]= get_bits(&s->gb, 8);
892 leftr= p->data[0][last_line+2]= get_bits(&s->gb, 8);
893 leftg= p->data[0][last_line+1]= get_bits(&s->gb, 8);
894 leftb= p->data[0][last_line+0]= get_bits(&s->gb, 8);
895 skip_bits(&s->gb, 8);
899 switch(s->predictor){
902 decode_bgr_bitstream(s, width-1);
903 add_left_prediction_bgr32(p->data[0] + last_line+4, s->temp[0], width-1, &leftr, &leftg, &leftb);
905 for(y=s->height-2; y>=0; y--){ //yes its stored upside down
906 decode_bgr_bitstream(s, width);
908 add_left_prediction_bgr32(p->data[0] + p->linesize[0]*y, s->temp[0], width, &leftr, &leftg, &leftb);
909 if(s->predictor == PLANE){
910 if((y&s->interlaced)==0){
911 s->dsp.add_bytes(p->data[0] + p->linesize[0]*y,
912 p->data[0] + p->linesize[0]*y + fake_ystride, fake_ystride);
916 draw_slice(s, height); // just 1 large slice as this isnt possible in reverse order
919 fprintf(stderr, "prediction type not supported!\n");
923 fprintf(stderr, "BGR24 output isnt implemenetd yet\n");
930 *data_size = sizeof(AVFrame);
932 return (get_bits_count(&s->gb)+31)/32*4;
935 static int decode_end(AVCodecContext *avctx)
937 HYuvContext *s = avctx->priv_data;
941 free_vlc(&s->vlc[i]);
944 avcodec_default_free_buffers(avctx);
949 static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){
950 HYuvContext *s = avctx->priv_data;
951 AVFrame *pict = data;
952 const int width= s->width;
953 const int width2= s->width>>1;
954 const int height= s->height;
955 const int fake_ystride= s->interlaced ? pict->linesize[0]*2 : pict->linesize[0];
956 const int fake_ustride= s->interlaced ? pict->linesize[1]*2 : pict->linesize[1];
957 const int fake_vstride= s->interlaced ? pict->linesize[2]*2 : pict->linesize[2];
958 AVFrame * const p= &s->picture;
961 init_put_bits(&s->pb, buf, buf_size);
964 p->pict_type= FF_I_TYPE;
967 if(avctx->pix_fmt == PIX_FMT_YUV422P || avctx->pix_fmt == PIX_FMT_YUV420P){
968 int lefty, leftu, leftv, y, cy;
970 put_bits(&s->pb, 8, leftv= p->data[2][0]);
971 put_bits(&s->pb, 8, lefty= p->data[0][1]);
972 put_bits(&s->pb, 8, leftu= p->data[1][0]);
973 put_bits(&s->pb, 8, p->data[0][0]);
975 lefty= sub_left_prediction(s, s->temp[0], p->data[0]+2, width-2 , lefty);
976 leftu= sub_left_prediction(s, s->temp[1], p->data[1]+1, width2-1, leftu);
977 leftv= sub_left_prediction(s, s->temp[2], p->data[2]+1, width2-1, leftv);
979 encode_422_bitstream(s, width-2);
981 if(s->predictor==MEDIAN){
982 int lefttopy, lefttopu, lefttopv;
985 lefty= sub_left_prediction(s, s->temp[0], p->data[0]+p->linesize[0], width , lefty);
986 leftu= sub_left_prediction(s, s->temp[1], p->data[1]+p->linesize[1], width2, leftu);
987 leftv= sub_left_prediction(s, s->temp[2], p->data[2]+p->linesize[2], width2, leftv);
989 encode_422_bitstream(s, width);
993 lefty= sub_left_prediction(s, s->temp[0], p->data[0]+fake_ystride, 4, lefty);
994 leftu= sub_left_prediction(s, s->temp[1], p->data[1]+fake_ystride, 2, leftu);
995 leftv= sub_left_prediction(s, s->temp[2], p->data[2]+fake_ystride, 2, leftv);
997 encode_422_bitstream(s, 4);
999 lefttopy= p->data[0][3];
1000 lefttopu= p->data[1][1];
1001 lefttopv= p->data[2][1];
1002 sub_median_prediction(s->temp[0], p->data[0]+4, p->data[0] + fake_ystride+4, width-4 , &lefty, &lefttopy);
1003 sub_median_prediction(s->temp[1], p->data[1]+2, p->data[1] + fake_ustride+2, width2-2, &leftu, &lefttopu);
1004 sub_median_prediction(s->temp[2], p->data[2]+2, p->data[2] + fake_vstride+2, width2-2, &leftv, &lefttopv);
1005 encode_422_bitstream(s, width-4);
1008 for(; y<height; y++,cy++){
1009 uint8_t *ydst, *udst, *vdst;
1011 if(s->bitstream_bpp==12){
1013 ydst= p->data[0] + p->linesize[0]*y;
1014 sub_median_prediction(s->temp[0], ydst - fake_ystride, ydst, width , &lefty, &lefttopy);
1015 encode_gray_bitstream(s, width);
1018 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 sub_median_prediction(s->temp[0], ydst - fake_ystride, ydst, width , &lefty, &lefttopy);
1025 sub_median_prediction(s->temp[1], udst - fake_ustride, udst, width2, &leftu, &lefttopu);
1026 sub_median_prediction(s->temp[2], vdst - fake_vstride, vdst, width2, &leftv, &lefttopv);
1028 encode_422_bitstream(s, width);
1031 for(cy=y=1; y<height; y++,cy++){
1032 uint8_t *ydst, *udst, *vdst;
1034 /* encode a luma only line & y++ */
1035 if(s->bitstream_bpp==12){
1036 ydst= p->data[0] + p->linesize[0]*y;
1038 if(s->predictor == PLANE && s->interlaced < y){
1039 s->dsp.diff_bytes(s->temp[1], ydst, ydst - fake_ystride, width);
1041 lefty= sub_left_prediction(s, s->temp[0], s->temp[1], width , lefty);
1043 lefty= sub_left_prediction(s, s->temp[0], ydst, width , lefty);
1045 encode_gray_bitstream(s, width);
1047 if(y>=height) break;
1050 ydst= p->data[0] + p->linesize[0]*y;
1051 udst= p->data[1] + p->linesize[1]*cy;
1052 vdst= p->data[2] + p->linesize[2]*cy;
1054 if(s->predictor == PLANE && s->interlaced < cy){
1055 s->dsp.diff_bytes(s->temp[1], ydst, ydst - fake_ystride, width);
1056 s->dsp.diff_bytes(s->temp[2], udst, udst - fake_ustride, width2);
1057 s->dsp.diff_bytes(s->temp[3], vdst, vdst - fake_vstride, width2);
1059 lefty= sub_left_prediction(s, s->temp[0], s->temp[1], width , lefty);
1060 leftu= sub_left_prediction(s, s->temp[1], s->temp[2], width2, leftu);
1061 leftv= sub_left_prediction(s, s->temp[2], s->temp[3], width2, leftv);
1063 lefty= sub_left_prediction(s, s->temp[0], ydst, width , lefty);
1064 leftu= sub_left_prediction(s, s->temp[1], udst, width2, leftu);
1065 leftv= sub_left_prediction(s, s->temp[2], vdst, width2, leftv);
1068 encode_422_bitstream(s, width);
1072 fprintf(stderr, "Format not supported!\n");
1076 size= (get_bit_count(&s->pb)+31)/32;
1078 if((s->flags&CODEC_FLAG_PASS1) && (s->picture_number&31)==0){
1080 char *p= avctx->stats_out;
1082 for(j=0; j<256; j++){
1083 sprintf(p, "%llu ", s->stats[i][j]);
1091 flush_put_bits(&s->pb);
1092 s->dsp.bswap_buf((uint32_t*)buf, (uint32_t*)buf, size);
1095 s->picture_number++;
1100 static int encode_end(AVCodecContext *avctx)
1102 // HYuvContext *s = avctx->priv_data;
1104 av_freep(&avctx->extradata);
1105 av_freep(&avctx->stats_out);
1110 static const AVOption huffyuv_options[] =
1112 AVOPTION_CODEC_INT("prediction_method", "prediction_method", prediction_method, 0, 2, 0),
1116 AVCodec huffyuv_decoder = {
1120 sizeof(HYuvContext),
1125 CODEC_CAP_DR1 | CODEC_CAP_DRAW_HORIZ_BAND,
1129 #ifdef CONFIG_ENCODERS
1131 AVCodec huffyuv_encoder = {
1135 sizeof(HYuvContext),
1139 .options = huffyuv_options,
1142 #endif //CONFIG_ENCODERS