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.
35 #ifdef WORDS_BIGENDIAN
45 typedef enum Predictor{
51 typedef struct HYuvContext{
52 AVCodecContext *avctx;
60 int yuy2; //use yuy2 instead of 422P
61 int bgr32; //use bgr32 instead of bgr24
67 uint8_t __align8 temp[3][2560];
68 uint64_t stats[3][256];
70 uint32_t bits[3][256];
73 uint8_t __align8 bitstream_buffer[1024*1024*3]; //FIXME dynamic alloc or some other solution
77 static const unsigned char classic_shift_luma[] = {
78 34,36,35,69,135,232,9,16,10,24,11,23,12,16,13,10,14,8,15,8,
79 16,8,17,20,16,10,207,206,205,236,11,8,10,21,9,23,8,8,199,70,
83 static const unsigned char classic_shift_chroma[] = {
84 66,36,37,38,39,40,41,75,76,77,110,239,144,81,82,83,84,85,118,183,
85 56,57,88,89,56,89,154,57,58,57,26,141,57,56,58,57,58,57,184,119,
86 214,245,116,83,82,49,80,79,78,77,44,75,41,40,39,38,37,36,34, 0
89 static const unsigned char classic_add_luma[256] = {
90 3, 9, 5, 12, 10, 35, 32, 29, 27, 50, 48, 45, 44, 41, 39, 37,
91 73, 70, 68, 65, 64, 61, 58, 56, 53, 50, 49, 46, 44, 41, 38, 36,
92 68, 65, 63, 61, 58, 55, 53, 51, 48, 46, 45, 43, 41, 39, 38, 36,
93 35, 33, 32, 30, 29, 27, 26, 25, 48, 47, 46, 44, 43, 41, 40, 39,
94 37, 36, 35, 34, 32, 31, 30, 28, 27, 26, 24, 23, 22, 20, 19, 37,
95 35, 34, 33, 31, 30, 29, 27, 26, 24, 23, 21, 20, 18, 17, 15, 29,
96 27, 26, 24, 22, 21, 19, 17, 16, 14, 26, 25, 23, 21, 19, 18, 16,
97 15, 27, 25, 23, 21, 19, 17, 16, 14, 26, 25, 23, 21, 18, 17, 14,
98 12, 17, 19, 13, 4, 9, 2, 11, 1, 7, 8, 0, 16, 3, 14, 6,
99 12, 10, 5, 15, 18, 11, 10, 13, 15, 16, 19, 20, 22, 24, 27, 15,
100 18, 20, 22, 24, 26, 14, 17, 20, 22, 24, 27, 15, 18, 20, 23, 25,
101 28, 16, 19, 22, 25, 28, 32, 36, 21, 25, 29, 33, 38, 42, 45, 49,
102 28, 31, 34, 37, 40, 42, 44, 47, 49, 50, 52, 54, 56, 57, 59, 60,
103 62, 64, 66, 67, 69, 35, 37, 39, 40, 42, 43, 45, 47, 48, 51, 52,
104 54, 55, 57, 59, 60, 62, 63, 66, 67, 69, 71, 72, 38, 40, 42, 43,
105 46, 47, 49, 51, 26, 28, 30, 31, 33, 34, 18, 19, 11, 13, 7, 8,
108 static const unsigned char classic_add_chroma[256] = {
109 3, 1, 2, 2, 2, 2, 3, 3, 7, 5, 7, 5, 8, 6, 11, 9,
110 7, 13, 11, 10, 9, 8, 7, 5, 9, 7, 6, 4, 7, 5, 8, 7,
111 11, 8, 13, 11, 19, 15, 22, 23, 20, 33, 32, 28, 27, 29, 51, 77,
112 43, 45, 76, 81, 46, 82, 75, 55, 56,144, 58, 80, 60, 74,147, 63,
113 143, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
114 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 27, 30, 21, 22,
115 17, 14, 5, 6,100, 54, 47, 50, 51, 53,106,107,108,109,110,111,
116 112,113,114,115, 4,117,118, 92, 94,121,122, 3,124,103, 2, 1,
117 0,129,130,131,120,119,126,125,136,137,138,139,140,141,142,134,
118 135,132,133,104, 64,101, 62, 57,102, 95, 93, 59, 61, 28, 97, 96,
119 52, 49, 48, 29, 32, 25, 24, 46, 23, 98, 45, 44, 43, 20, 42, 41,
120 19, 18, 99, 40, 15, 39, 38, 16, 13, 12, 11, 37, 10, 9, 8, 36,
121 7,128,127,105,123,116, 35, 34, 33,145, 31, 79, 42,146, 78, 26,
122 83, 48, 49, 50, 44, 47, 26, 31, 30, 18, 17, 19, 21, 24, 25, 13,
123 14, 16, 17, 18, 20, 21, 12, 14, 15, 9, 10, 6, 9, 6, 5, 8,
124 6, 12, 8, 10, 7, 9, 6, 4, 6, 2, 2, 3, 3, 3, 3, 2,
127 static inline int add_left_prediction(uint8_t *dst, uint8_t *src, int w, int acc){
130 for(i=0; i<w-1; i++){
146 static inline void add_median_prediction(uint8_t *dst, uint8_t *src1, uint8_t *diff, int w, int *left, int *left_top){
154 l= mid_pred(l, src1[i], (l + src1[i] - lt)&0xFF) + diff[i];
163 static inline void add_left_prediction_bgr32(uint8_t *dst, uint8_t *src, int w, int *red, int *green, int *blue){
185 static inline int sub_left_prediction(HYuvContext *s, uint8_t *dst, uint8_t *src, int w, int left){
189 const int temp= src[i];
196 const int temp= src[i];
200 s->dsp.diff_bytes(dst+16, src+16, src+15, w-16);
205 static void read_len_table(uint8_t *dst, GetBitContext *gb){
209 repeat= get_bits(gb, 3);
210 val = get_bits(gb, 5);
212 repeat= get_bits(gb, 8);
213 //printf("%d %d\n", val, repeat);
219 static int generate_bits_table(uint32_t *dst, uint8_t *len_table){
223 for(len=32; len>0; len--){
224 for(index=0; index<256; index++){
225 if(len_table[index]==len)
229 av_log(NULL, AV_LOG_ERROR, "Error generating huffman table\n");
237 static void generate_len_table(uint8_t *dst, uint64_t *stats, int size){
238 uint64_t counts[2*size];
242 for(offset=1; ; offset<<=1){
243 for(i=0; i<size; i++){
244 counts[i]= stats[i] + offset - 1;
247 for(next=size; next<size*2; next++){
251 min1=min2= INT64_MAX;
254 for(i=0; i<next; i++){
255 if(min2 > counts[i]){
256 if(min1 > counts[i]){
268 if(min2==INT64_MAX) break;
270 counts[next]= min1 + min2;
272 counts[min2_i]= INT64_MAX;
278 for(i=0; i<size; i++){
282 for(len=0; up[index] != -1; len++)
293 static int read_huffman_tables(HYuvContext *s, uint8_t *src, int length){
297 init_get_bits(&gb, src, length*8);
300 read_len_table(s->len[i], &gb);
302 if(generate_bits_table(s->bits[i], s->len[i])<0){
306 for(j=0; j<256; j++){
307 printf("%6X, %2d, %3d\n", s->bits[i][j], s->len[i][j], j);
310 free_vlc(&s->vlc[i]);
311 init_vlc(&s->vlc[i], VLC_BITS, 256, s->len[i], 1, 1, s->bits[i], 4, 4, 0);
314 return (get_bits_count(&gb)+7)/8;
317 static int read_old_huffman_tables(HYuvContext *s){
322 init_get_bits(&gb, classic_shift_luma, sizeof(classic_shift_luma)*8);
323 read_len_table(s->len[0], &gb);
324 init_get_bits(&gb, classic_shift_chroma, sizeof(classic_shift_chroma)*8);
325 read_len_table(s->len[1], &gb);
327 for(i=0; i<256; i++) s->bits[0][i] = classic_add_luma [i];
328 for(i=0; i<256; i++) s->bits[1][i] = classic_add_chroma[i];
330 if(s->bitstream_bpp >= 24){
331 memcpy(s->bits[1], s->bits[0], 256*sizeof(uint32_t));
332 memcpy(s->len[1] , s->len [0], 256*sizeof(uint8_t));
334 memcpy(s->bits[2], s->bits[1], 256*sizeof(uint32_t));
335 memcpy(s->len[2] , s->len [1], 256*sizeof(uint8_t));
338 free_vlc(&s->vlc[i]);
339 init_vlc(&s->vlc[i], VLC_BITS, 256, s->len[i], 1, 1, s->bits[i], 4, 4, 0);
344 fprintf(stderr, "v1 huffyuv is not supported \n");
349 static int decode_init(AVCodecContext *avctx)
351 HYuvContext *s = avctx->priv_data;
355 s->flags= avctx->flags;
357 dsputil_init(&s->dsp, avctx);
358 memset(s->vlc, 0, 3*sizeof(VLC));
360 width= s->width= avctx->width;
361 height= s->height= avctx->height;
362 avctx->coded_frame= &s->picture;
365 assert(width && height);
366 //if(avctx->extradata)
367 // printf("extradata:%X, extradata_size:%d\n", *(uint32_t*)avctx->extradata, avctx->extradata_size);
368 if(avctx->extradata_size){
369 if((avctx->bits_per_sample&7) && avctx->bits_per_sample != 12)
370 s->version=1; // do such files exist at all?
379 method= ((uint8_t*)avctx->extradata)[0];
380 s->decorrelate= method&64 ? 1 : 0;
381 s->predictor= method&63;
382 s->bitstream_bpp= ((uint8_t*)avctx->extradata)[1];
383 if(s->bitstream_bpp==0)
384 s->bitstream_bpp= avctx->bits_per_sample&~7;
385 s->context= ((uint8_t*)avctx->extradata)[2] & 0x40 ? 1 : 0;
387 if(read_huffman_tables(s, ((uint8_t*)avctx->extradata)+4, avctx->extradata_size) < 0)
390 switch(avctx->bits_per_sample&7){
401 s->decorrelate= avctx->bits_per_sample >= 24;
404 s->predictor= MEDIAN;
408 s->predictor= LEFT; //OLD
412 s->bitstream_bpp= avctx->bits_per_sample & ~7;
415 if(read_old_huffman_tables(s) < 0)
419 if(((uint8_t*)avctx->extradata)[2] & 0x20)
420 s->interlaced= ((uint8_t*)avctx->extradata)[2] & 0x10 ? 1 : 0;
422 s->interlaced= height > 288;
424 switch(s->bitstream_bpp){
426 avctx->pix_fmt = PIX_FMT_YUV420P;
430 avctx->pix_fmt = PIX_FMT_YUV422;
432 avctx->pix_fmt = PIX_FMT_YUV422P;
438 avctx->pix_fmt = PIX_FMT_RGBA32;
440 avctx->pix_fmt = PIX_FMT_BGR24;
447 // 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);
452 static int store_table(HYuvContext *s, uint8_t *len, uint8_t *buf){
460 for(; i<256 && len[i]==val && repeat<255; i++)
463 assert(val < 32 && val >0 && repeat<256 && repeat>0);
466 buf[index++]= repeat;
468 buf[index++]= val | (repeat<<5);
475 static int encode_init(AVCodecContext *avctx)
477 HYuvContext *s = avctx->priv_data;
478 int i, j, width, height;
481 s->flags= avctx->flags;
483 dsputil_init(&s->dsp, avctx);
485 width= s->width= avctx->width;
486 height= s->height= avctx->height;
488 assert(width && height);
490 avctx->extradata= av_mallocz(1024*30);
491 avctx->stats_out= av_mallocz(1024*30);
494 avctx->coded_frame= &s->picture;
496 switch(avctx->pix_fmt){
497 case PIX_FMT_YUV420P:
498 s->bitstream_bpp= 12;
500 case PIX_FMT_YUV422P:
501 s->bitstream_bpp= 16;
504 av_log(avctx, AV_LOG_ERROR, "format not supported\n");
507 avctx->bits_per_sample= s->bitstream_bpp;
508 s->decorrelate= s->bitstream_bpp >= 24;
509 s->predictor= avctx->prediction_method;
510 s->interlaced= avctx->flags&CODEC_FLAG_INTERLACED_ME ? 1 : 0;
511 if(avctx->context_model==1){
512 s->context= avctx->context_model;
513 if(s->flags & (CODEC_FLAG_PASS1|CODEC_FLAG_PASS2)){
514 av_log(avctx, AV_LOG_ERROR, "context=1 is not compatible with 2 pass huffyuv encoding\n");
519 if(avctx->codec->id==CODEC_ID_HUFFYUV){
520 if(avctx->pix_fmt==PIX_FMT_YUV420P){
521 av_log(avctx, AV_LOG_ERROR, "Error: YV12 is not supported by huffyuv; use vcodec=ffvhuff or format=422p\n");
524 if(avctx->context_model){
525 av_log(avctx, AV_LOG_ERROR, "Error: per-frame huffman tables are not supported by huffyuv; use vcodec=ffvhuff\n");
528 if(s->interlaced != ( height > 288 ))
529 av_log(avctx, AV_LOG_INFO, "using huffyuv 2.2.0 or newer interlacing flag\n");
530 }else if(avctx->strict_std_compliance>=0){
531 av_log(avctx, AV_LOG_ERROR, "This codec is under development; files encoded with it may not be decodeable with future versions!!! Set vstrict=-1 to use it anyway.\n");
535 ((uint8_t*)avctx->extradata)[0]= s->predictor;
536 ((uint8_t*)avctx->extradata)[1]= s->bitstream_bpp;
537 ((uint8_t*)avctx->extradata)[2]= 0x20 | (s->interlaced ? 0x10 : 0);
539 ((uint8_t*)avctx->extradata)[2]|= 0x40;
540 ((uint8_t*)avctx->extradata)[3]= 0;
541 s->avctx->extradata_size= 4;
544 char *p= avctx->stats_in;
554 for(j=0; j<256; j++){
555 s->stats[i][j]+= strtol(p, &next, 0);
556 if(next==p) return -1;
560 if(p[0]==0 || p[1]==0 || p[2]==0) break;
564 for(j=0; j<256; j++){
565 int d= FFMIN(j, 256-j);
567 s->stats[i][j]= 100000000/(d+1);
572 generate_len_table(s->len[i], s->stats[i], 256);
574 if(generate_bits_table(s->bits[i], s->len[i])<0){
578 s->avctx->extradata_size+=
579 store_table(s, s->len[i], &((uint8_t*)s->avctx->extradata)[s->avctx->extradata_size]);
584 int pels = width*height / (i?40:10);
585 for(j=0; j<256; j++){
586 int d= FFMIN(j, 256-j);
587 s->stats[i][j]= pels/(d+1);
596 // printf("pred:%d bpp:%d hbpp:%d il:%d\n", s->predictor, s->bitstream_bpp, avctx->bits_per_sample, s->interlaced);
603 static void decode_422_bitstream(HYuvContext *s, int count){
608 for(i=0; i<count; i++){
609 s->temp[0][2*i ]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3);
610 s->temp[1][ i ]= get_vlc2(&s->gb, s->vlc[1].table, VLC_BITS, 3);
611 s->temp[0][2*i+1]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3);
612 s->temp[2][ i ]= get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3);
616 static void decode_gray_bitstream(HYuvContext *s, int count){
621 for(i=0; i<count; i++){
622 s->temp[0][2*i ]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3);
623 s->temp[0][2*i+1]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3);
627 static void encode_422_bitstream(HYuvContext *s, int count){
631 if(s->flags&CODEC_FLAG_PASS1){
632 for(i=0; i<count; i++){
633 s->stats[0][ s->temp[0][2*i ] ]++;
634 s->stats[1][ s->temp[1][ i ] ]++;
635 s->stats[0][ s->temp[0][2*i+1] ]++;
636 s->stats[2][ s->temp[2][ i ] ]++;
638 }else if(s->context){
639 for(i=0; i<count; i++){
640 s->stats[0][ s->temp[0][2*i ] ]++;
641 put_bits(&s->pb, s->len[0][ s->temp[0][2*i ] ], s->bits[0][ s->temp[0][2*i ] ]);
642 s->stats[1][ s->temp[1][ i ] ]++;
643 put_bits(&s->pb, s->len[1][ s->temp[1][ i ] ], s->bits[1][ s->temp[1][ i ] ]);
644 s->stats[0][ s->temp[0][2*i+1] ]++;
645 put_bits(&s->pb, s->len[0][ s->temp[0][2*i+1] ], s->bits[0][ s->temp[0][2*i+1] ]);
646 s->stats[2][ s->temp[2][ i ] ]++;
647 put_bits(&s->pb, s->len[2][ s->temp[2][ i ] ], s->bits[2][ s->temp[2][ i ] ]);
650 for(i=0; i<count; i++){
651 put_bits(&s->pb, s->len[0][ s->temp[0][2*i ] ], s->bits[0][ s->temp[0][2*i ] ]);
652 put_bits(&s->pb, s->len[1][ s->temp[1][ i ] ], s->bits[1][ s->temp[1][ i ] ]);
653 put_bits(&s->pb, s->len[0][ s->temp[0][2*i+1] ], s->bits[0][ s->temp[0][2*i+1] ]);
654 put_bits(&s->pb, s->len[2][ s->temp[2][ i ] ], s->bits[2][ s->temp[2][ i ] ]);
659 static void encode_gray_bitstream(HYuvContext *s, int count){
663 if(s->flags&CODEC_FLAG_PASS1){
664 for(i=0; i<count; i++){
665 s->stats[0][ s->temp[0][2*i ] ]++;
666 s->stats[0][ s->temp[0][2*i+1] ]++;
668 }else if(s->context){
669 for(i=0; i<count; i++){
670 s->stats[0][ s->temp[0][2*i ] ]++;
671 put_bits(&s->pb, s->len[0][ s->temp[0][2*i ] ], s->bits[0][ s->temp[0][2*i ] ]);
672 s->stats[0][ s->temp[0][2*i+1] ]++;
673 put_bits(&s->pb, s->len[0][ s->temp[0][2*i+1] ], s->bits[0][ s->temp[0][2*i+1] ]);
676 for(i=0; i<count; i++){
677 put_bits(&s->pb, s->len[0][ s->temp[0][2*i ] ], s->bits[0][ s->temp[0][2*i ] ]);
678 put_bits(&s->pb, s->len[0][ s->temp[0][2*i+1] ], s->bits[0][ s->temp[0][2*i+1] ]);
683 static void decode_bgr_bitstream(HYuvContext *s, int count){
687 if(s->bitstream_bpp==24){
688 for(i=0; i<count; i++){
689 s->temp[0][4*i+G]= get_vlc2(&s->gb, s->vlc[1].table, VLC_BITS, 3);
690 s->temp[0][4*i+B]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3) + s->temp[0][4*i+G];
691 s->temp[0][4*i+R]= get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3) + s->temp[0][4*i+G];
694 for(i=0; i<count; i++){
695 s->temp[0][4*i+G]= get_vlc2(&s->gb, s->vlc[1].table, VLC_BITS, 3);
696 s->temp[0][4*i+B]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3) + s->temp[0][4*i+G];
697 s->temp[0][4*i+R]= get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3) + s->temp[0][4*i+G];
698 get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3); //?!
702 if(s->bitstream_bpp==24){
703 for(i=0; i<count; i++){
704 s->temp[0][4*i+B]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3);
705 s->temp[0][4*i+G]= get_vlc2(&s->gb, s->vlc[1].table, VLC_BITS, 3);
706 s->temp[0][4*i+R]= get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3);
709 for(i=0; i<count; i++){
710 s->temp[0][4*i+B]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3);
711 s->temp[0][4*i+G]= get_vlc2(&s->gb, s->vlc[1].table, VLC_BITS, 3);
712 s->temp[0][4*i+R]= get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3);
713 get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3); //?!
719 static void draw_slice(HYuvContext *s, int y){
723 if(s->avctx->draw_horiz_band==NULL)
726 h= y - s->last_slice_end;
729 if(s->bitstream_bpp==12){
735 offset[0] = s->picture.linesize[0]*y;
736 offset[1] = s->picture.linesize[1]*cy;
737 offset[2] = s->picture.linesize[2]*cy;
741 s->avctx->draw_horiz_band(s->avctx, &s->picture, offset, y, 3, h);
743 s->last_slice_end= y + h;
746 static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8_t *buf, int buf_size){
747 HYuvContext *s = avctx->priv_data;
748 const int width= s->width;
749 const int width2= s->width>>1;
750 const int height= s->height;
751 int fake_ystride, fake_ustride, fake_vstride;
752 AVFrame * const p= &s->picture;
755 AVFrame *picture = data;
757 /* no supplementary picture */
761 s->dsp.bswap_buf((uint32_t*)s->bitstream_buffer, (uint32_t*)buf, buf_size/4);
764 avctx->release_buffer(avctx, p);
767 if(avctx->get_buffer(avctx, p) < 0){
768 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
773 table_size = read_huffman_tables(s, s->bitstream_buffer, buf_size);
778 init_get_bits(&s->gb, s->bitstream_buffer+table_size, (buf_size-table_size)*8);
780 fake_ystride= s->interlaced ? p->linesize[0]*2 : p->linesize[0];
781 fake_ustride= s->interlaced ? p->linesize[1]*2 : p->linesize[1];
782 fake_vstride= s->interlaced ? p->linesize[2]*2 : p->linesize[2];
784 s->last_slice_end= 0;
786 if(s->bitstream_bpp<24){
788 int lefty, leftu, leftv;
789 int lefttopy, lefttopu, lefttopv;
792 p->data[0][3]= get_bits(&s->gb, 8);
793 p->data[0][2]= get_bits(&s->gb, 8);
794 p->data[0][1]= get_bits(&s->gb, 8);
795 p->data[0][0]= get_bits(&s->gb, 8);
797 av_log(avctx, AV_LOG_ERROR, "YUY2 output isnt implemenetd yet\n");
801 leftv= p->data[2][0]= get_bits(&s->gb, 8);
802 lefty= p->data[0][1]= get_bits(&s->gb, 8);
803 leftu= p->data[1][0]= get_bits(&s->gb, 8);
804 p->data[0][0]= get_bits(&s->gb, 8);
806 switch(s->predictor){
809 decode_422_bitstream(s, width-2);
810 lefty= add_left_prediction(p->data[0] + 2, s->temp[0], width-2, lefty);
811 if(!(s->flags&CODEC_FLAG_GRAY)){
812 leftu= add_left_prediction(p->data[1] + 1, s->temp[1], width2-1, leftu);
813 leftv= add_left_prediction(p->data[2] + 1, s->temp[2], width2-1, leftv);
816 for(cy=y=1; y<s->height; y++,cy++){
817 uint8_t *ydst, *udst, *vdst;
819 if(s->bitstream_bpp==12){
820 decode_gray_bitstream(s, width);
822 ydst= p->data[0] + p->linesize[0]*y;
824 lefty= add_left_prediction(ydst, s->temp[0], width, lefty);
825 if(s->predictor == PLANE){
827 s->dsp.add_bytes(ydst, ydst - fake_ystride, width);
830 if(y>=s->height) break;
835 ydst= p->data[0] + p->linesize[0]*y;
836 udst= p->data[1] + p->linesize[1]*cy;
837 vdst= p->data[2] + p->linesize[2]*cy;
839 decode_422_bitstream(s, width);
840 lefty= add_left_prediction(ydst, s->temp[0], width, lefty);
841 if(!(s->flags&CODEC_FLAG_GRAY)){
842 leftu= add_left_prediction(udst, s->temp[1], width2, leftu);
843 leftv= add_left_prediction(vdst, s->temp[2], width2, leftv);
845 if(s->predictor == PLANE){
846 if(cy>s->interlaced){
847 s->dsp.add_bytes(ydst, ydst - fake_ystride, width);
848 if(!(s->flags&CODEC_FLAG_GRAY)){
849 s->dsp.add_bytes(udst, udst - fake_ustride, width2);
850 s->dsp.add_bytes(vdst, vdst - fake_vstride, width2);
855 draw_slice(s, height);
859 /* first line except first 2 pixels is left predicted */
860 decode_422_bitstream(s, width-2);
861 lefty= add_left_prediction(p->data[0] + 2, s->temp[0], width-2, lefty);
862 if(!(s->flags&CODEC_FLAG_GRAY)){
863 leftu= add_left_prediction(p->data[1] + 1, s->temp[1], width2-1, leftu);
864 leftv= add_left_prediction(p->data[2] + 1, s->temp[2], width2-1, leftv);
869 /* second line is left predicted for interlaced case */
871 decode_422_bitstream(s, width);
872 lefty= add_left_prediction(p->data[0] + p->linesize[0], s->temp[0], width, lefty);
873 if(!(s->flags&CODEC_FLAG_GRAY)){
874 leftu= add_left_prediction(p->data[1] + p->linesize[2], s->temp[1], width2, leftu);
875 leftv= add_left_prediction(p->data[2] + p->linesize[1], s->temp[2], width2, leftv);
880 /* next 4 pixels are left predicted too */
881 decode_422_bitstream(s, 4);
882 lefty= add_left_prediction(p->data[0] + fake_ystride, s->temp[0], 4, lefty);
883 if(!(s->flags&CODEC_FLAG_GRAY)){
884 leftu= add_left_prediction(p->data[1] + fake_ustride, s->temp[1], 2, leftu);
885 leftv= add_left_prediction(p->data[2] + fake_vstride, s->temp[2], 2, leftv);
888 /* next line except the first 4 pixels is median predicted */
889 lefttopy= p->data[0][3];
890 decode_422_bitstream(s, width-4);
891 add_median_prediction(p->data[0] + fake_ystride+4, p->data[0]+4, s->temp[0], width-4, &lefty, &lefttopy);
892 if(!(s->flags&CODEC_FLAG_GRAY)){
893 lefttopu= p->data[1][1];
894 lefttopv= p->data[2][1];
895 add_median_prediction(p->data[1] + fake_ustride+2, p->data[1]+2, s->temp[1], width2-2, &leftu, &lefttopu);
896 add_median_prediction(p->data[2] + fake_vstride+2, p->data[2]+2, s->temp[2], width2-2, &leftv, &lefttopv);
900 for(; y<height; y++,cy++){
901 uint8_t *ydst, *udst, *vdst;
903 if(s->bitstream_bpp==12){
905 decode_gray_bitstream(s, width);
906 ydst= p->data[0] + p->linesize[0]*y;
907 add_median_prediction(ydst, ydst - fake_ystride, s->temp[0], width, &lefty, &lefttopy);
914 decode_422_bitstream(s, width);
916 ydst= p->data[0] + p->linesize[0]*y;
917 udst= p->data[1] + p->linesize[1]*cy;
918 vdst= p->data[2] + p->linesize[2]*cy;
920 add_median_prediction(ydst, ydst - fake_ystride, s->temp[0], width, &lefty, &lefttopy);
921 if(!(s->flags&CODEC_FLAG_GRAY)){
922 add_median_prediction(udst, udst - fake_ustride, s->temp[1], width2, &leftu, &lefttopu);
923 add_median_prediction(vdst, vdst - fake_vstride, s->temp[2], width2, &leftv, &lefttopv);
927 draw_slice(s, height);
933 int leftr, leftg, leftb;
934 const int last_line= (height-1)*p->linesize[0];
936 if(s->bitstream_bpp==32){
937 skip_bits(&s->gb, 8);
938 leftr= p->data[0][last_line+R]= get_bits(&s->gb, 8);
939 leftg= p->data[0][last_line+G]= get_bits(&s->gb, 8);
940 leftb= p->data[0][last_line+B]= get_bits(&s->gb, 8);
942 leftr= p->data[0][last_line+R]= get_bits(&s->gb, 8);
943 leftg= p->data[0][last_line+G]= get_bits(&s->gb, 8);
944 leftb= p->data[0][last_line+B]= get_bits(&s->gb, 8);
945 skip_bits(&s->gb, 8);
949 switch(s->predictor){
952 decode_bgr_bitstream(s, width-1);
953 add_left_prediction_bgr32(p->data[0] + last_line+4, s->temp[0], width-1, &leftr, &leftg, &leftb);
955 for(y=s->height-2; y>=0; y--){ //yes its stored upside down
956 decode_bgr_bitstream(s, width);
958 add_left_prediction_bgr32(p->data[0] + p->linesize[0]*y, s->temp[0], width, &leftr, &leftg, &leftb);
959 if(s->predictor == PLANE){
960 if((y&s->interlaced)==0 && y<s->height-1-s->interlaced){
961 s->dsp.add_bytes(p->data[0] + p->linesize[0]*y,
962 p->data[0] + p->linesize[0]*y + fake_ystride, fake_ystride);
966 draw_slice(s, height); // just 1 large slice as this isnt possible in reverse order
969 av_log(avctx, AV_LOG_ERROR, "prediction type not supported!\n");
973 av_log(avctx, AV_LOG_ERROR, "BGR24 output isnt implemenetd yet\n");
980 *data_size = sizeof(AVFrame);
982 return (get_bits_count(&s->gb)+31)/32*4;
985 static int decode_end(AVCodecContext *avctx)
987 HYuvContext *s = avctx->priv_data;
991 free_vlc(&s->vlc[i]);
997 static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){
998 HYuvContext *s = avctx->priv_data;
999 AVFrame *pict = data;
1000 const int width= s->width;
1001 const int width2= s->width>>1;
1002 const int height= s->height;
1003 const int fake_ystride= s->interlaced ? pict->linesize[0]*2 : pict->linesize[0];
1004 const int fake_ustride= s->interlaced ? pict->linesize[1]*2 : pict->linesize[1];
1005 const int fake_vstride= s->interlaced ? pict->linesize[2]*2 : pict->linesize[2];
1006 AVFrame * const p= &s->picture;
1010 p->pict_type= FF_I_TYPE;
1015 generate_len_table(s->len[i], s->stats[i], 256);
1016 if(generate_bits_table(s->bits[i], s->len[i])<0)
1018 size+= store_table(s, s->len[i], &buf[size]);
1022 for(j=0; j<256; j++)
1023 s->stats[i][j] >>= 1;
1026 init_put_bits(&s->pb, buf+size, buf_size-size);
1028 if(avctx->pix_fmt == PIX_FMT_YUV422P || avctx->pix_fmt == PIX_FMT_YUV420P){
1029 int lefty, leftu, leftv, y, cy;
1031 put_bits(&s->pb, 8, leftv= p->data[2][0]);
1032 put_bits(&s->pb, 8, lefty= p->data[0][1]);
1033 put_bits(&s->pb, 8, leftu= p->data[1][0]);
1034 put_bits(&s->pb, 8, p->data[0][0]);
1036 lefty= sub_left_prediction(s, s->temp[0], p->data[0]+2, width-2 , lefty);
1037 leftu= sub_left_prediction(s, s->temp[1], p->data[1]+1, width2-1, leftu);
1038 leftv= sub_left_prediction(s, s->temp[2], p->data[2]+1, width2-1, leftv);
1040 encode_422_bitstream(s, width-2);
1042 if(s->predictor==MEDIAN){
1043 int lefttopy, lefttopu, lefttopv;
1046 lefty= sub_left_prediction(s, s->temp[0], p->data[0]+p->linesize[0], width , lefty);
1047 leftu= sub_left_prediction(s, s->temp[1], p->data[1]+p->linesize[1], width2, leftu);
1048 leftv= sub_left_prediction(s, s->temp[2], p->data[2]+p->linesize[2], width2, leftv);
1050 encode_422_bitstream(s, width);
1054 lefty= sub_left_prediction(s, s->temp[0], p->data[0]+fake_ystride, 4, lefty);
1055 leftu= sub_left_prediction(s, s->temp[1], p->data[1]+fake_ustride, 2, leftu);
1056 leftv= sub_left_prediction(s, s->temp[2], p->data[2]+fake_vstride, 2, leftv);
1058 encode_422_bitstream(s, 4);
1060 lefttopy= p->data[0][3];
1061 lefttopu= p->data[1][1];
1062 lefttopv= p->data[2][1];
1063 s->dsp.sub_hfyu_median_prediction(s->temp[0], p->data[0]+4, p->data[0] + fake_ystride+4, width-4 , &lefty, &lefttopy);
1064 s->dsp.sub_hfyu_median_prediction(s->temp[1], p->data[1]+2, p->data[1] + fake_ustride+2, width2-2, &leftu, &lefttopu);
1065 s->dsp.sub_hfyu_median_prediction(s->temp[2], p->data[2]+2, p->data[2] + fake_vstride+2, width2-2, &leftv, &lefttopv);
1066 encode_422_bitstream(s, width-4);
1069 for(; y<height; y++,cy++){
1070 uint8_t *ydst, *udst, *vdst;
1072 if(s->bitstream_bpp==12){
1074 ydst= p->data[0] + p->linesize[0]*y;
1075 s->dsp.sub_hfyu_median_prediction(s->temp[0], ydst - fake_ystride, ydst, width , &lefty, &lefttopy);
1076 encode_gray_bitstream(s, width);
1079 if(y>=height) break;
1081 ydst= p->data[0] + p->linesize[0]*y;
1082 udst= p->data[1] + p->linesize[1]*cy;
1083 vdst= p->data[2] + p->linesize[2]*cy;
1085 s->dsp.sub_hfyu_median_prediction(s->temp[0], ydst - fake_ystride, ydst, width , &lefty, &lefttopy);
1086 s->dsp.sub_hfyu_median_prediction(s->temp[1], udst - fake_ustride, udst, width2, &leftu, &lefttopu);
1087 s->dsp.sub_hfyu_median_prediction(s->temp[2], vdst - fake_vstride, vdst, width2, &leftv, &lefttopv);
1089 encode_422_bitstream(s, width);
1092 for(cy=y=1; y<height; y++,cy++){
1093 uint8_t *ydst, *udst, *vdst;
1095 /* encode a luma only line & y++ */
1096 if(s->bitstream_bpp==12){
1097 ydst= p->data[0] + p->linesize[0]*y;
1099 if(s->predictor == PLANE && s->interlaced < y){
1100 s->dsp.diff_bytes(s->temp[1], ydst, ydst - fake_ystride, width);
1102 lefty= sub_left_prediction(s, s->temp[0], s->temp[1], width , lefty);
1104 lefty= sub_left_prediction(s, s->temp[0], ydst, width , lefty);
1106 encode_gray_bitstream(s, width);
1108 if(y>=height) break;
1111 ydst= p->data[0] + p->linesize[0]*y;
1112 udst= p->data[1] + p->linesize[1]*cy;
1113 vdst= p->data[2] + p->linesize[2]*cy;
1115 if(s->predictor == PLANE && s->interlaced < cy){
1116 s->dsp.diff_bytes(s->temp[1], ydst, ydst - fake_ystride, width);
1117 s->dsp.diff_bytes(s->temp[2], udst, udst - fake_ustride, width2);
1118 s->dsp.diff_bytes(s->temp[2] + 1250, vdst, vdst - fake_vstride, width2);
1120 lefty= sub_left_prediction(s, s->temp[0], s->temp[1], width , lefty);
1121 leftu= sub_left_prediction(s, s->temp[1], s->temp[2], width2, leftu);
1122 leftv= sub_left_prediction(s, s->temp[2], s->temp[2] + 1250, width2, leftv);
1124 lefty= sub_left_prediction(s, s->temp[0], ydst, width , lefty);
1125 leftu= sub_left_prediction(s, s->temp[1], udst, width2, leftu);
1126 leftv= sub_left_prediction(s, s->temp[2], vdst, width2, leftv);
1129 encode_422_bitstream(s, width);
1133 av_log(avctx, AV_LOG_ERROR, "Format not supported!\n");
1137 size+= (put_bits_count(&s->pb)+31)/8;
1140 if((s->flags&CODEC_FLAG_PASS1) && (s->picture_number&31)==0){
1142 char *p= avctx->stats_out;
1144 for(j=0; j<256; j++){
1145 sprintf(p, "%llu ", s->stats[i][j]);
1153 flush_put_bits(&s->pb);
1154 s->dsp.bswap_buf((uint32_t*)buf, (uint32_t*)buf, size);
1155 avctx->stats_out[0] = '\0';
1158 s->picture_number++;
1163 static int encode_end(AVCodecContext *avctx)
1165 // HYuvContext *s = avctx->priv_data;
1167 av_freep(&avctx->extradata);
1168 av_freep(&avctx->stats_out);
1173 static const AVOption huffyuv_options[] =
1175 AVOPTION_CODEC_INT("prediction_method", "prediction_method", prediction_method, 0, 2, 0),
1179 static const AVOption ffvhuff_options[] =
1181 AVOPTION_CODEC_INT("prediction_method", "prediction_method", prediction_method, 0, 2, 0),
1182 AVOPTION_CODEC_INT("context_model", "context_model", context_model, 0, 2, 0),
1187 AVCodec huffyuv_decoder = {
1191 sizeof(HYuvContext),
1196 CODEC_CAP_DR1 | CODEC_CAP_DRAW_HORIZ_BAND,
1200 AVCodec ffvhuff_decoder = {
1204 sizeof(HYuvContext),
1209 CODEC_CAP_DR1 | CODEC_CAP_DRAW_HORIZ_BAND,
1213 #ifdef CONFIG_ENCODERS
1215 AVCodec huffyuv_encoder = {
1219 sizeof(HYuvContext),
1223 .options = huffyuv_options,
1226 AVCodec ffvhuff_encoder = {
1230 sizeof(HYuvContext),
1234 .options = ffvhuff_options,
1237 #endif //CONFIG_ENCODERS