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 typedef enum Predictor{
41 typedef struct HYuvContext{
42 AVCodecContext *avctx;
50 int yuy2; //use yuy2 instead of 422P
51 int bgr32; //use bgr32 instead of bgr24
56 uint8_t __align8 temp[3][2560];
57 uint64_t stats[3][256];
59 uint32_t bits[3][256];
62 uint8_t __align8 bitstream_buffer[1024*1024*3]; //FIXME dynamic alloc or some other solution
66 static const unsigned char classic_shift_luma[] = {
67 34,36,35,69,135,232,9,16,10,24,11,23,12,16,13,10,14,8,15,8,
68 16,8,17,20,16,10,207,206,205,236,11,8,10,21,9,23,8,8,199,70,
72 static const unsigned char classic_shift_chroma[] = {
73 66,36,37,38,39,40,41,75,76,77,110,239,144,81,82,83,84,85,118,183,
74 56,57,88,89,56,89,154,57,58,57,26,141,57,56,58,57,58,57,184,119,
75 214,245,116,83,82,49,80,79,78,77,44,75,41,40,39,38,37,36,34, 0
78 static const unsigned char classic_add_luma[256] = {
79 3, 9, 5, 12, 10, 35, 32, 29, 27, 50, 48, 45, 44, 41, 39, 37,
80 73, 70, 68, 65, 64, 61, 58, 56, 53, 50, 49, 46, 44, 41, 38, 36,
81 68, 65, 63, 61, 58, 55, 53, 51, 48, 46, 45, 43, 41, 39, 38, 36,
82 35, 33, 32, 30, 29, 27, 26, 25, 48, 47, 46, 44, 43, 41, 40, 39,
83 37, 36, 35, 34, 32, 31, 30, 28, 27, 26, 24, 23, 22, 20, 19, 37,
84 35, 34, 33, 31, 30, 29, 27, 26, 24, 23, 21, 20, 18, 17, 15, 29,
85 27, 26, 24, 22, 21, 19, 17, 16, 14, 26, 25, 23, 21, 19, 18, 16,
86 15, 27, 25, 23, 21, 19, 17, 16, 14, 26, 25, 23, 21, 18, 17, 14,
87 12, 17, 19, 13, 4, 9, 2, 11, 1, 7, 8, 0, 16, 3, 14, 6,
88 12, 10, 5, 15, 18, 11, 10, 13, 15, 16, 19, 20, 22, 24, 27, 15,
89 18, 20, 22, 24, 26, 14, 17, 20, 22, 24, 27, 15, 18, 20, 23, 25,
90 28, 16, 19, 22, 25, 28, 32, 36, 21, 25, 29, 33, 38, 42, 45, 49,
91 28, 31, 34, 37, 40, 42, 44, 47, 49, 50, 52, 54, 56, 57, 59, 60,
92 62, 64, 66, 67, 69, 35, 37, 39, 40, 42, 43, 45, 47, 48, 51, 52,
93 54, 55, 57, 59, 60, 62, 63, 66, 67, 69, 71, 72, 38, 40, 42, 43,
94 46, 47, 49, 51, 26, 28, 30, 31, 33, 34, 18, 19, 11, 13, 7, 8,
97 static const unsigned char classic_add_chroma[256] = {
98 3, 1, 2, 2, 2, 2, 3, 3, 7, 5, 7, 5, 8, 6, 11, 9,
99 7, 13, 11, 10, 9, 8, 7, 5, 9, 7, 6, 4, 7, 5, 8, 7,
100 11, 8, 13, 11, 19, 15, 22, 23, 20, 33, 32, 28, 27, 29, 51, 77,
101 43, 45, 76, 81, 46, 82, 75, 55, 56,144, 58, 80, 60, 74,147, 63,
102 143, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
103 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 27, 30, 21, 22,
104 17, 14, 5, 6,100, 54, 47, 50, 51, 53,106,107,108,109,110,111,
105 112,113,114,115, 4,117,118, 92, 94,121,122, 3,124,103, 2, 1,
106 0,129,130,131,120,119,126,125,136,137,138,139,140,141,142,134,
107 135,132,133,104, 64,101, 62, 57,102, 95, 93, 59, 61, 28, 97, 96,
108 52, 49, 48, 29, 32, 25, 24, 46, 23, 98, 45, 44, 43, 20, 42, 41,
109 19, 18, 99, 40, 15, 39, 38, 16, 13, 12, 11, 37, 10, 9, 8, 36,
110 7,128,127,105,123,116, 35, 34, 33,145, 31, 79, 42,146, 78, 26,
111 83, 48, 49, 50, 44, 47, 26, 31, 30, 18, 17, 19, 21, 24, 25, 13,
112 14, 16, 17, 18, 20, 21, 12, 14, 15, 9, 10, 6, 9, 6, 5, 8,
113 6, 12, 8, 10, 7, 9, 6, 4, 6, 2, 2, 3, 3, 3, 3, 2,
116 static inline int add_left_prediction(uint8_t *dst, uint8_t *src, int w, int acc){
119 for(i=0; i<w-1; i++){
135 static inline void add_median_prediction(uint8_t *dst, uint8_t *src1, uint8_t *diff, int w, int *left, int *left_top){
143 l= mid_pred(l, src1[i], (l + src1[i] - lt)&0xFF) + diff[i];
152 static inline void add_left_prediction_bgr32(uint8_t *dst, uint8_t *src, int w, int *red, int *green, int *blue){
174 static inline int sub_left_prediction(HYuvContext *s, uint8_t *dst, uint8_t *src, int w, int left){
178 const int temp= src[i];
185 const int temp= src[i];
189 s->dsp.diff_bytes(dst+16, src+16, src+15, w-16);
194 static void read_len_table(uint8_t *dst, GetBitContext *gb){
198 repeat= get_bits(gb, 3);
199 val = get_bits(gb, 5);
201 repeat= get_bits(gb, 8);
202 //printf("%d %d\n", val, repeat);
208 static int generate_bits_table(uint32_t *dst, uint8_t *len_table){
212 for(len=32; len>0; len--){
213 for(index=0; index<256; index++){
214 if(len_table[index]==len)
218 av_log(NULL, AV_LOG_ERROR, "Error generating huffman table\n");
226 static void generate_len_table(uint8_t *dst, uint64_t *stats, int size){
227 uint64_t counts[2*size];
231 for(offset=1; ; offset<<=1){
232 for(i=0; i<size; i++){
233 counts[i]= stats[i] + offset - 1;
236 for(next=size; next<size*2; next++){
240 min1=min2= INT64_MAX;
243 for(i=0; i<next; i++){
244 if(min2 > counts[i]){
245 if(min1 > counts[i]){
257 if(min2==INT64_MAX) break;
259 counts[next]= min1 + min2;
261 counts[min2_i]= INT64_MAX;
267 for(i=0; i<size; i++){
271 for(len=0; up[index] != -1; len++)
282 static int read_huffman_tables(HYuvContext *s, uint8_t *src, int length){
286 init_get_bits(&gb, src, length*8);
289 read_len_table(s->len[i], &gb);
291 if(generate_bits_table(s->bits[i], s->len[i])<0){
295 for(j=0; j<256; j++){
296 printf("%6X, %2d, %3d\n", s->bits[i][j], s->len[i][j], j);
299 init_vlc(&s->vlc[i], VLC_BITS, 256, s->len[i], 1, 1, s->bits[i], 4, 4);
305 static int read_old_huffman_tables(HYuvContext *s){
310 init_get_bits(&gb, classic_shift_luma, sizeof(classic_shift_luma)*8);
311 read_len_table(s->len[0], &gb);
312 init_get_bits(&gb, classic_shift_chroma, sizeof(classic_shift_chroma)*8);
313 read_len_table(s->len[1], &gb);
315 for(i=0; i<256; i++) s->bits[0][i] = classic_add_luma [i];
316 for(i=0; i<256; i++) s->bits[1][i] = classic_add_chroma[i];
318 if(s->bitstream_bpp >= 24){
319 memcpy(s->bits[1], s->bits[0], 256*sizeof(uint32_t));
320 memcpy(s->len[1] , s->len [0], 256*sizeof(uint8_t));
322 memcpy(s->bits[2], s->bits[1], 256*sizeof(uint32_t));
323 memcpy(s->len[2] , s->len [1], 256*sizeof(uint8_t));
326 init_vlc(&s->vlc[i], VLC_BITS, 256, s->len[i], 1, 1, s->bits[i], 4, 4);
330 fprintf(stderr, "v1 huffyuv is not supported \n");
335 static int decode_init(AVCodecContext *avctx)
337 HYuvContext *s = avctx->priv_data;
341 s->flags= avctx->flags;
343 dsputil_init(&s->dsp, avctx);
345 width= s->width= avctx->width;
346 height= s->height= avctx->height;
347 avctx->coded_frame= &s->picture;
350 assert(width && height);
351 //if(avctx->extradata)
352 // printf("extradata:%X, extradata_size:%d\n", *(uint32_t*)avctx->extradata, avctx->extradata_size);
353 if(avctx->extradata_size){
354 if((avctx->bits_per_sample&7) && avctx->bits_per_sample != 12)
355 s->version=1; // do such files exist at all?
364 method= ((uint8_t*)avctx->extradata)[0];
365 s->decorrelate= method&64 ? 1 : 0;
366 s->predictor= method&63;
367 s->bitstream_bpp= ((uint8_t*)avctx->extradata)[1];
368 if(s->bitstream_bpp==0)
369 s->bitstream_bpp= avctx->bits_per_sample&~7;
371 if(read_huffman_tables(s, ((uint8_t*)avctx->extradata)+4, avctx->extradata_size) < 0)
374 switch(avctx->bits_per_sample&7){
385 s->decorrelate= avctx->bits_per_sample >= 24;
388 s->predictor= MEDIAN;
392 s->predictor= LEFT; //OLD
396 s->bitstream_bpp= avctx->bits_per_sample & ~7;
398 if(read_old_huffman_tables(s) < 0)
402 s->interlaced= height > 288;
404 switch(s->bitstream_bpp){
406 avctx->pix_fmt = PIX_FMT_YUV420P;
410 avctx->pix_fmt = PIX_FMT_YUV422;
412 avctx->pix_fmt = PIX_FMT_YUV422P;
418 avctx->pix_fmt = PIX_FMT_RGBA32;
420 avctx->pix_fmt = PIX_FMT_BGR24;
427 // printf("pred:%d bpp:%d hbpp:%d il:%d\n", s->predictor, s->bitstream_bpp, avctx->bits_per_sample, s->interlaced);
432 static void store_table(HYuvContext *s, uint8_t *len){
434 int index= s->avctx->extradata_size;
440 for(; i<256 && len[i]==val && repeat<255; i++)
443 assert(val < 32 && val >0 && repeat<256 && repeat>0);
445 ((uint8_t*)s->avctx->extradata)[index++]= val;
446 ((uint8_t*)s->avctx->extradata)[index++]= repeat;
448 ((uint8_t*)s->avctx->extradata)[index++]= val | (repeat<<5);
452 s->avctx->extradata_size= index;
455 static int encode_init(AVCodecContext *avctx)
457 HYuvContext *s = avctx->priv_data;
458 int i, j, width, height;
461 s->flags= avctx->flags;
463 dsputil_init(&s->dsp, avctx);
465 width= s->width= avctx->width;
466 height= s->height= avctx->height;
468 assert(width && height);
470 avctx->extradata= av_mallocz(1024*30);
471 avctx->stats_out= av_mallocz(1024*30);
474 avctx->coded_frame= &s->picture;
476 switch(avctx->pix_fmt){
477 case PIX_FMT_YUV420P:
478 s->bitstream_bpp= 12;
480 case PIX_FMT_YUV422P:
481 s->bitstream_bpp= 16;
484 av_log(avctx, AV_LOG_ERROR, "format not supported\n");
487 avctx->bits_per_sample= s->bitstream_bpp;
488 s->decorrelate= s->bitstream_bpp >= 24;
489 s->predictor= avctx->prediction_method;
491 ((uint8_t*)avctx->extradata)[0]= s->predictor;
492 ((uint8_t*)avctx->extradata)[1]= s->bitstream_bpp;
493 ((uint8_t*)avctx->extradata)[2]=
494 ((uint8_t*)avctx->extradata)[3]= 0;
495 s->avctx->extradata_size= 4;
498 char *p= avctx->stats_in;
508 for(j=0; j<256; j++){
509 s->stats[i][j]+= strtol(p, &next, 0);
510 if(next==p) return -1;
514 if(p[0]==0 || p[1]==0 || p[2]==0) break;
518 for(j=0; j<256; j++){
519 int d= FFMIN(j, 256-j);
521 s->stats[i][j]= 100000000/(d+1);
526 generate_len_table(s->len[i], s->stats[i], 256);
528 if(generate_bits_table(s->bits[i], s->len[i])<0){
532 store_table(s, s->len[i]);
539 s->interlaced= height > 288;
541 // printf("pred:%d bpp:%d hbpp:%d il:%d\n", s->predictor, s->bitstream_bpp, avctx->bits_per_sample, s->interlaced);
548 static void decode_422_bitstream(HYuvContext *s, int count){
553 for(i=0; i<count; i++){
554 s->temp[0][2*i ]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3);
555 s->temp[1][ i ]= get_vlc2(&s->gb, s->vlc[1].table, VLC_BITS, 3);
556 s->temp[0][2*i+1]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3);
557 s->temp[2][ i ]= get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3);
561 static void decode_gray_bitstream(HYuvContext *s, int count){
566 for(i=0; i<count; i++){
567 s->temp[0][2*i ]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3);
568 s->temp[0][2*i+1]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3);
572 static void encode_422_bitstream(HYuvContext *s, int count){
576 if(s->flags&CODEC_FLAG_PASS1){
577 for(i=0; i<count; i++){
578 s->stats[0][ s->temp[0][2*i ] ]++;
579 s->stats[1][ s->temp[1][ i ] ]++;
580 s->stats[0][ s->temp[0][2*i+1] ]++;
581 s->stats[2][ s->temp[2][ i ] ]++;
584 for(i=0; i<count; i++){
585 put_bits(&s->pb, s->len[0][ s->temp[0][2*i ] ], s->bits[0][ s->temp[0][2*i ] ]);
586 put_bits(&s->pb, s->len[1][ s->temp[1][ i ] ], s->bits[1][ s->temp[1][ i ] ]);
587 put_bits(&s->pb, s->len[0][ s->temp[0][2*i+1] ], s->bits[0][ s->temp[0][2*i+1] ]);
588 put_bits(&s->pb, s->len[2][ s->temp[2][ i ] ], s->bits[2][ s->temp[2][ i ] ]);
593 static void encode_gray_bitstream(HYuvContext *s, int count){
597 if(s->flags&CODEC_FLAG_PASS1){
598 for(i=0; i<count; i++){
599 s->stats[0][ s->temp[0][2*i ] ]++;
600 s->stats[0][ s->temp[0][2*i+1] ]++;
603 for(i=0; i<count; i++){
604 put_bits(&s->pb, s->len[0][ s->temp[0][2*i ] ], s->bits[0][ s->temp[0][2*i ] ]);
605 put_bits(&s->pb, s->len[0][ s->temp[0][2*i+1] ], s->bits[0][ s->temp[0][2*i+1] ]);
610 static void decode_bgr_bitstream(HYuvContext *s, int count){
614 if(s->bitstream_bpp==24){
615 for(i=0; i<count; i++){
616 s->temp[0][4*i+1]= get_vlc2(&s->gb, s->vlc[1].table, VLC_BITS, 3);
617 s->temp[0][4*i ]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3) + s->temp[0][4*i+1];
618 s->temp[0][4*i+2]= get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3) + s->temp[0][4*i+1];
621 for(i=0; i<count; i++){
622 s->temp[0][4*i+1]= get_vlc2(&s->gb, s->vlc[1].table, VLC_BITS, 3);
623 s->temp[0][4*i ]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3) + s->temp[0][4*i+1];
624 s->temp[0][4*i+2]= get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3) + s->temp[0][4*i+1];
625 get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3); //?!
629 if(s->bitstream_bpp==24){
630 for(i=0; i<count; i++){
631 s->temp[0][4*i ]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3);
632 s->temp[0][4*i+1]= get_vlc2(&s->gb, s->vlc[1].table, VLC_BITS, 3);
633 s->temp[0][4*i+2]= get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3);
636 for(i=0; i<count; i++){
637 s->temp[0][4*i ]= get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3);
638 s->temp[0][4*i+1]= get_vlc2(&s->gb, s->vlc[1].table, VLC_BITS, 3);
639 s->temp[0][4*i+2]= get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3);
640 get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3); //?!
646 static void draw_slice(HYuvContext *s, int y){
650 if(s->avctx->draw_horiz_band==NULL)
653 h= y - s->last_slice_end;
656 if(s->bitstream_bpp==12){
662 offset[0] = s->picture.linesize[0]*y;
663 offset[1] = s->picture.linesize[1]*cy;
664 offset[2] = s->picture.linesize[2]*cy;
668 s->avctx->draw_horiz_band(s->avctx, &s->picture, offset, y, 3, h);
670 s->last_slice_end= y + h;
673 static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8_t *buf, int buf_size){
674 HYuvContext *s = avctx->priv_data;
675 const int width= s->width;
676 const int width2= s->width>>1;
677 const int height= s->height;
678 int fake_ystride, fake_ustride, fake_vstride;
679 AVFrame * const p= &s->picture;
681 AVFrame *picture = data;
683 /* no supplementary picture */
687 s->dsp.bswap_buf((uint32_t*)s->bitstream_buffer, (uint32_t*)buf, buf_size/4);
689 init_get_bits(&s->gb, s->bitstream_buffer, buf_size*8);
692 avctx->release_buffer(avctx, p);
695 if(avctx->get_buffer(avctx, p) < 0){
696 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
700 fake_ystride= s->interlaced ? p->linesize[0]*2 : p->linesize[0];
701 fake_ustride= s->interlaced ? p->linesize[1]*2 : p->linesize[1];
702 fake_vstride= s->interlaced ? p->linesize[2]*2 : p->linesize[2];
704 s->last_slice_end= 0;
706 if(s->bitstream_bpp<24){
708 int lefty, leftu, leftv;
709 int lefttopy, lefttopu, lefttopv;
712 p->data[0][3]= get_bits(&s->gb, 8);
713 p->data[0][2]= get_bits(&s->gb, 8);
714 p->data[0][1]= get_bits(&s->gb, 8);
715 p->data[0][0]= get_bits(&s->gb, 8);
717 av_log(avctx, AV_LOG_ERROR, "YUY2 output isnt implemenetd yet\n");
721 leftv= p->data[2][0]= get_bits(&s->gb, 8);
722 lefty= p->data[0][1]= get_bits(&s->gb, 8);
723 leftu= p->data[1][0]= get_bits(&s->gb, 8);
724 p->data[0][0]= get_bits(&s->gb, 8);
726 switch(s->predictor){
729 decode_422_bitstream(s, width-2);
730 lefty= add_left_prediction(p->data[0] + 2, s->temp[0], width-2, lefty);
731 if(!(s->flags&CODEC_FLAG_GRAY)){
732 leftu= add_left_prediction(p->data[1] + 1, s->temp[1], width2-1, leftu);
733 leftv= add_left_prediction(p->data[2] + 1, s->temp[2], width2-1, leftv);
736 for(cy=y=1; y<s->height; y++,cy++){
737 uint8_t *ydst, *udst, *vdst;
739 if(s->bitstream_bpp==12){
740 decode_gray_bitstream(s, width);
742 ydst= p->data[0] + p->linesize[0]*y;
744 lefty= add_left_prediction(ydst, s->temp[0], width, lefty);
745 if(s->predictor == PLANE){
747 s->dsp.add_bytes(ydst, ydst - fake_ystride, width);
750 if(y>=s->height) break;
755 ydst= p->data[0] + p->linesize[0]*y;
756 udst= p->data[1] + p->linesize[1]*cy;
757 vdst= p->data[2] + p->linesize[2]*cy;
759 decode_422_bitstream(s, width);
760 lefty= add_left_prediction(ydst, s->temp[0], width, lefty);
761 if(!(s->flags&CODEC_FLAG_GRAY)){
762 leftu= add_left_prediction(udst, s->temp[1], width2, leftu);
763 leftv= add_left_prediction(vdst, s->temp[2], width2, leftv);
765 if(s->predictor == PLANE){
766 if(cy>s->interlaced){
767 s->dsp.add_bytes(ydst, ydst - fake_ystride, width);
768 if(!(s->flags&CODEC_FLAG_GRAY)){
769 s->dsp.add_bytes(udst, udst - fake_ustride, width2);
770 s->dsp.add_bytes(vdst, vdst - fake_vstride, width2);
775 draw_slice(s, height);
779 /* first line except first 2 pixels is left predicted */
780 decode_422_bitstream(s, width-2);
781 lefty= add_left_prediction(p->data[0] + 2, s->temp[0], width-2, lefty);
782 if(!(s->flags&CODEC_FLAG_GRAY)){
783 leftu= add_left_prediction(p->data[1] + 1, s->temp[1], width2-1, leftu);
784 leftv= add_left_prediction(p->data[2] + 1, s->temp[2], width2-1, leftv);
789 /* second line is left predicted for interlaced case */
791 decode_422_bitstream(s, width);
792 lefty= add_left_prediction(p->data[0] + p->linesize[0], s->temp[0], width, lefty);
793 if(!(s->flags&CODEC_FLAG_GRAY)){
794 leftu= add_left_prediction(p->data[1] + p->linesize[2], s->temp[1], width2, leftu);
795 leftv= add_left_prediction(p->data[2] + p->linesize[1], s->temp[2], width2, leftv);
800 /* next 4 pixels are left predicted too */
801 decode_422_bitstream(s, 4);
802 lefty= add_left_prediction(p->data[0] + fake_ystride, s->temp[0], 4, lefty);
803 if(!(s->flags&CODEC_FLAG_GRAY)){
804 leftu= add_left_prediction(p->data[1] + fake_ustride, s->temp[1], 2, leftu);
805 leftv= add_left_prediction(p->data[2] + fake_vstride, s->temp[2], 2, leftv);
808 /* next line except the first 4 pixels is median predicted */
809 lefttopy= p->data[0][3];
810 decode_422_bitstream(s, width-4);
811 add_median_prediction(p->data[0] + fake_ystride+4, p->data[0]+4, s->temp[0], width-4, &lefty, &lefttopy);
812 if(!(s->flags&CODEC_FLAG_GRAY)){
813 lefttopu= p->data[1][1];
814 lefttopv= p->data[2][1];
815 add_median_prediction(p->data[1] + fake_ustride+2, p->data[1]+2, s->temp[1], width2-2, &leftu, &lefttopu);
816 add_median_prediction(p->data[2] + fake_vstride+2, p->data[2]+2, s->temp[2], width2-2, &leftv, &lefttopv);
820 for(; y<height; y++,cy++){
821 uint8_t *ydst, *udst, *vdst;
823 if(s->bitstream_bpp==12){
825 decode_gray_bitstream(s, width);
826 ydst= p->data[0] + p->linesize[0]*y;
827 add_median_prediction(ydst, ydst - fake_ystride, s->temp[0], width, &lefty, &lefttopy);
834 decode_422_bitstream(s, width);
836 ydst= p->data[0] + p->linesize[0]*y;
837 udst= p->data[1] + p->linesize[1]*cy;
838 vdst= p->data[2] + p->linesize[2]*cy;
840 add_median_prediction(ydst, ydst - fake_ystride, s->temp[0], width, &lefty, &lefttopy);
841 if(!(s->flags&CODEC_FLAG_GRAY)){
842 add_median_prediction(udst, udst - fake_ustride, s->temp[1], width2, &leftu, &lefttopu);
843 add_median_prediction(vdst, vdst - fake_vstride, s->temp[2], width2, &leftv, &lefttopv);
847 draw_slice(s, height);
853 int leftr, leftg, leftb;
854 const int last_line= (height-1)*p->linesize[0];
856 if(s->bitstream_bpp==32){
857 p->data[0][last_line+3]= get_bits(&s->gb, 8);
858 leftr= p->data[0][last_line+2]= get_bits(&s->gb, 8);
859 leftg= p->data[0][last_line+1]= get_bits(&s->gb, 8);
860 leftb= p->data[0][last_line+0]= get_bits(&s->gb, 8);
862 leftr= p->data[0][last_line+2]= get_bits(&s->gb, 8);
863 leftg= p->data[0][last_line+1]= get_bits(&s->gb, 8);
864 leftb= p->data[0][last_line+0]= get_bits(&s->gb, 8);
865 skip_bits(&s->gb, 8);
869 switch(s->predictor){
872 decode_bgr_bitstream(s, width-1);
873 add_left_prediction_bgr32(p->data[0] + last_line+4, s->temp[0], width-1, &leftr, &leftg, &leftb);
875 for(y=s->height-2; y>=0; y--){ //yes its stored upside down
876 decode_bgr_bitstream(s, width);
878 add_left_prediction_bgr32(p->data[0] + p->linesize[0]*y, s->temp[0], width, &leftr, &leftg, &leftb);
879 if(s->predictor == PLANE){
880 if((y&s->interlaced)==0){
881 s->dsp.add_bytes(p->data[0] + p->linesize[0]*y,
882 p->data[0] + p->linesize[0]*y + fake_ystride, fake_ystride);
886 draw_slice(s, height); // just 1 large slice as this isnt possible in reverse order
889 av_log(avctx, AV_LOG_ERROR, "prediction type not supported!\n");
893 av_log(avctx, AV_LOG_ERROR, "BGR24 output isnt implemenetd yet\n");
900 *data_size = sizeof(AVFrame);
902 return (get_bits_count(&s->gb)+31)/32*4;
905 static int decode_end(AVCodecContext *avctx)
907 HYuvContext *s = avctx->priv_data;
911 free_vlc(&s->vlc[i]);
917 static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){
918 HYuvContext *s = avctx->priv_data;
919 AVFrame *pict = data;
920 const int width= s->width;
921 const int width2= s->width>>1;
922 const int height= s->height;
923 const int fake_ystride= s->interlaced ? pict->linesize[0]*2 : pict->linesize[0];
924 const int fake_ustride= s->interlaced ? pict->linesize[1]*2 : pict->linesize[1];
925 const int fake_vstride= s->interlaced ? pict->linesize[2]*2 : pict->linesize[2];
926 AVFrame * const p= &s->picture;
929 init_put_bits(&s->pb, buf, buf_size);
932 p->pict_type= FF_I_TYPE;
935 if(avctx->pix_fmt == PIX_FMT_YUV422P || avctx->pix_fmt == PIX_FMT_YUV420P){
936 int lefty, leftu, leftv, y, cy;
938 put_bits(&s->pb, 8, leftv= p->data[2][0]);
939 put_bits(&s->pb, 8, lefty= p->data[0][1]);
940 put_bits(&s->pb, 8, leftu= p->data[1][0]);
941 put_bits(&s->pb, 8, p->data[0][0]);
943 lefty= sub_left_prediction(s, s->temp[0], p->data[0]+2, width-2 , lefty);
944 leftu= sub_left_prediction(s, s->temp[1], p->data[1]+1, width2-1, leftu);
945 leftv= sub_left_prediction(s, s->temp[2], p->data[2]+1, width2-1, leftv);
947 encode_422_bitstream(s, width-2);
949 if(s->predictor==MEDIAN){
950 int lefttopy, lefttopu, lefttopv;
953 lefty= sub_left_prediction(s, s->temp[0], p->data[0]+p->linesize[0], width , lefty);
954 leftu= sub_left_prediction(s, s->temp[1], p->data[1]+p->linesize[1], width2, leftu);
955 leftv= sub_left_prediction(s, s->temp[2], p->data[2]+p->linesize[2], width2, leftv);
957 encode_422_bitstream(s, width);
961 lefty= sub_left_prediction(s, s->temp[0], p->data[0]+fake_ystride, 4, lefty);
962 leftu= sub_left_prediction(s, s->temp[1], p->data[1]+fake_ystride, 2, leftu);
963 leftv= sub_left_prediction(s, s->temp[2], p->data[2]+fake_ystride, 2, leftv);
965 encode_422_bitstream(s, 4);
967 lefttopy= p->data[0][3];
968 lefttopu= p->data[1][1];
969 lefttopv= p->data[2][1];
970 s->dsp.sub_hfyu_median_prediction(s->temp[0], p->data[0]+4, p->data[0] + fake_ystride+4, width-4 , &lefty, &lefttopy);
971 s->dsp.sub_hfyu_median_prediction(s->temp[1], p->data[1]+2, p->data[1] + fake_ustride+2, width2-2, &leftu, &lefttopu);
972 s->dsp.sub_hfyu_median_prediction(s->temp[2], p->data[2]+2, p->data[2] + fake_vstride+2, width2-2, &leftv, &lefttopv);
973 encode_422_bitstream(s, width-4);
976 for(; y<height; y++,cy++){
977 uint8_t *ydst, *udst, *vdst;
979 if(s->bitstream_bpp==12){
981 ydst= p->data[0] + p->linesize[0]*y;
982 s->dsp.sub_hfyu_median_prediction(s->temp[0], ydst - fake_ystride, ydst, width , &lefty, &lefttopy);
983 encode_gray_bitstream(s, width);
988 ydst= p->data[0] + p->linesize[0]*y;
989 udst= p->data[1] + p->linesize[1]*cy;
990 vdst= p->data[2] + p->linesize[2]*cy;
992 s->dsp.sub_hfyu_median_prediction(s->temp[0], ydst - fake_ystride, ydst, width , &lefty, &lefttopy);
993 s->dsp.sub_hfyu_median_prediction(s->temp[1], udst - fake_ustride, udst, width2, &leftu, &lefttopu);
994 s->dsp.sub_hfyu_median_prediction(s->temp[2], vdst - fake_vstride, vdst, width2, &leftv, &lefttopv);
996 encode_422_bitstream(s, width);
999 for(cy=y=1; y<height; y++,cy++){
1000 uint8_t *ydst, *udst, *vdst;
1002 /* encode a luma only line & y++ */
1003 if(s->bitstream_bpp==12){
1004 ydst= p->data[0] + p->linesize[0]*y;
1006 if(s->predictor == PLANE && s->interlaced < y){
1007 s->dsp.diff_bytes(s->temp[1], ydst, ydst - fake_ystride, width);
1009 lefty= sub_left_prediction(s, s->temp[0], s->temp[1], width , lefty);
1011 lefty= sub_left_prediction(s, s->temp[0], ydst, width , lefty);
1013 encode_gray_bitstream(s, width);
1015 if(y>=height) break;
1018 ydst= p->data[0] + p->linesize[0]*y;
1019 udst= p->data[1] + p->linesize[1]*cy;
1020 vdst= p->data[2] + p->linesize[2]*cy;
1022 if(s->predictor == PLANE && s->interlaced < cy){
1023 s->dsp.diff_bytes(s->temp[1], ydst, ydst - fake_ystride, width);
1024 s->dsp.diff_bytes(s->temp[2], udst, udst - fake_ustride, width2);
1025 s->dsp.diff_bytes(s->temp[2] + 1250, vdst, vdst - fake_vstride, width2);
1027 lefty= sub_left_prediction(s, s->temp[0], s->temp[1], width , lefty);
1028 leftu= sub_left_prediction(s, s->temp[1], s->temp[2], width2, leftu);
1029 leftv= sub_left_prediction(s, s->temp[2], s->temp[2] + 1250, width2, leftv);
1031 lefty= sub_left_prediction(s, s->temp[0], ydst, width , lefty);
1032 leftu= sub_left_prediction(s, s->temp[1], udst, width2, leftu);
1033 leftv= sub_left_prediction(s, s->temp[2], vdst, width2, leftv);
1036 encode_422_bitstream(s, width);
1040 av_log(avctx, AV_LOG_ERROR, "Format not supported!\n");
1044 size= (put_bits_count(&s->pb)+31)/32;
1046 if((s->flags&CODEC_FLAG_PASS1) && (s->picture_number&31)==0){
1048 char *p= avctx->stats_out;
1050 for(j=0; j<256; j++){
1051 sprintf(p, "%llu ", s->stats[i][j]);
1059 flush_put_bits(&s->pb);
1060 s->dsp.bswap_buf((uint32_t*)buf, (uint32_t*)buf, size);
1063 s->picture_number++;
1068 static int encode_end(AVCodecContext *avctx)
1070 // HYuvContext *s = avctx->priv_data;
1072 av_freep(&avctx->extradata);
1073 av_freep(&avctx->stats_out);
1078 static const AVOption huffyuv_options[] =
1080 AVOPTION_CODEC_INT("prediction_method", "prediction_method", prediction_method, 0, 2, 0),
1084 AVCodec huffyuv_decoder = {
1088 sizeof(HYuvContext),
1093 CODEC_CAP_DR1 | CODEC_CAP_DRAW_HORIZ_BAND,
1097 #ifdef CONFIG_ENCODERS
1099 AVCodec huffyuv_encoder = {
1103 sizeof(HYuvContext),
1107 .options = huffyuv_options,
1110 #endif //CONFIG_ENCODERS