Index: ffmpeg/libavcodec/huffyuv.c =================================================================== --- ffmpeg/libavcodec/huffyuv.c (revision 20545) +++ ffmpeg/libavcodec/huffyuv.c (working copy) @@ -39,10 +39,12 @@ #define B 3 #define G 2 #define R 1 +#define A 0 #else #define B 0 #define G 1 #define R 2 +#define A 3 #endif typedef enum Predictor{ @@ -61,7 +63,6 @@ int bitstream_bpp; int version; int yuy2; //use yuy2 instead of 422P - int bgr32; //use bgr32 instead of bgr24 int width, height; int flags; int context; @@ -406,7 +407,8 @@ s->temp[i]= av_malloc(s->width + 16); } }else{ - s->temp[0]= av_malloc(4*s->width + 16); + int bytes = (s->bitstream_bpp==24) ? 3 : 4; + s->temp[0]= av_malloc(bytes*s->width + 16); } } @@ -436,7 +438,6 @@ avctx->coded_frame= &s->picture; s->interlaced= s->height > 288; -s->bgr32=1; //if(avctx->extradata) // printf("extradata:%X, extradata_size:%d\n", *(uint32_t*)avctx->extradata, avctx->extradata_size); if(avctx->extradata_size){ @@ -504,12 +505,10 @@ } break; case 24: + avctx->pix_fmt = PIX_FMT_BGR24; + break; case 32: - if(s->bgr32){ - avctx->pix_fmt = PIX_FMT_RGB32; - }else{ - avctx->pix_fmt = PIX_FMT_BGR24; - } + avctx->pix_fmt = PIX_FMT_RGB32; break; default: assert(0); @@ -820,7 +819,7 @@ } #endif /* CONFIG_HUFFYUV_ENCODER || CONFIG_FFVHUFF_ENCODER */ -static av_always_inline void decode_bgr_1(HYuvContext *s, int count, int decorrelate, int alpha){ +static av_always_inline void decode_bgr_1_32(HYuvContext *s, int count, int decorrelate){ int i; for(i=0; igb, s->vlc[3].table, VLC_BITS, 1); @@ -835,22 +834,40 @@ s->temp[0][4*i+G] = get_vlc2(&s->gb, s->vlc[1].table, VLC_BITS, 3); s->temp[0][4*i+R] = get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3); } - if(alpha) - get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3); //?! + s->temp[0][4*i+A] = get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3); } } +static av_always_inline void decode_bgr_1_24(HYuvContext *s, int count, int decorrelate){ + int i; + for(i=0; igb, s->vlc[3].table, VLC_BITS, 1); + if(code != -1){ + *(uint32_t*)&s->temp[0][3*i] = AV_RL32(&s->pix_bgr_map[code]); + }else if(decorrelate){ + // B = 0, G = 1, R = 2 for BGR24 no matter the endianness + s->temp[0][3*i+1] = get_vlc2(&s->gb, s->vlc[1].table, VLC_BITS, 3); + s->temp[0][3*i+0] = get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3) + s->temp[0][3*i+1]; + s->temp[0][3*i+2] = get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3) + s->temp[0][3*i+1]; + }else{ + s->temp[0][3*i+0] = get_vlc2(&s->gb, s->vlc[0].table, VLC_BITS, 3); + s->temp[0][3*i+1] = get_vlc2(&s->gb, s->vlc[1].table, VLC_BITS, 3); + s->temp[0][3*i+2] = get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3); + } + } +} + static void decode_bgr_bitstream(HYuvContext *s, int count){ if(s->decorrelate){ if(s->bitstream_bpp==24) - decode_bgr_1(s, count, 1, 0); + decode_bgr_1_24(s, count, 1); else - decode_bgr_1(s, count, 1, 1); + decode_bgr_1_32(s, count, 1); }else{ if(s->bitstream_bpp==24) - decode_bgr_1(s, count, 0, 0); + decode_bgr_1_24(s, count, 0); else - decode_bgr_1(s, count, 0, 1); + decode_bgr_1_32(s, count, 0); } } @@ -1116,32 +1133,38 @@ } }else{ int y; - int leftr, leftg, leftb; + int leftr, leftg, leftb, lefta; const int last_line= (height-1)*p->linesize[0]; if(s->bitstream_bpp==32){ - skip_bits(&s->gb, 8); + lefta= p->data[0][last_line+A]= get_bits(&s->gb, 8); leftr= p->data[0][last_line+R]= get_bits(&s->gb, 8); leftg= p->data[0][last_line+G]= get_bits(&s->gb, 8); leftb= p->data[0][last_line+B]= get_bits(&s->gb, 8); }else{ - leftr= p->data[0][last_line+R]= get_bits(&s->gb, 8); - leftg= p->data[0][last_line+G]= get_bits(&s->gb, 8); - leftb= p->data[0][last_line+B]= get_bits(&s->gb, 8); + leftr= p->data[0][last_line+2]= get_bits(&s->gb, 8); + leftg= p->data[0][last_line+1]= get_bits(&s->gb, 8); + leftb= p->data[0][last_line+0]= get_bits(&s->gb, 8); skip_bits(&s->gb, 8); } - if(s->bgr32){ switch(s->predictor){ case LEFT: case PLANE: decode_bgr_bitstream(s, width-1); - s->dsp.add_hfyu_left_prediction_bgr32(p->data[0] + last_line+4, s->temp[0], width-1, &leftr, &leftg, &leftb); + if(s->bitstream_bpp==32) + s->dsp.add_hfyu_left_prediction_bgr32(p->data[0] + last_line+4, s->temp[0], width-1, &leftr, &leftg, &leftb, &lefta); + else + s->dsp.add_hfyu_left_prediction_bgr24(p->data[0] + last_line+3, s->temp[0], width-1, &leftr, &leftg, &leftb); + for(y=s->height-2; y>=0; y--){ //Yes it is stored upside down. decode_bgr_bitstream(s, width); - s->dsp.add_hfyu_left_prediction_bgr32(p->data[0] + p->linesize[0]*y, s->temp[0], width, &leftr, &leftg, &leftb); + if(s->bitstream_bpp==32) + s->dsp.add_hfyu_left_prediction_bgr32(p->data[0] + p->linesize[0]*y, s->temp[0], width, &leftr, &leftg, &leftb, &lefta); + else + s->dsp.add_hfyu_left_prediction_bgr24(p->data[0] + p->linesize[0]*y, s->temp[0], width, &leftr, &leftg, &leftb); if(s->predictor == PLANE){ if((y&s->interlaced)==0 && yheight-1-s->interlaced){ s->dsp.add_bytes(p->data[0] + p->linesize[0]*y, @@ -1154,11 +1177,6 @@ default: av_log(avctx, AV_LOG_ERROR, "prediction type not supported!\n"); } - }else{ - - av_log(avctx, AV_LOG_ERROR, "BGR24 output is not implemented yet\n"); - return -1; - } } emms_c(); Index: ffmpeg/libavcodec/dsputil.c =================================================================== --- ffmpeg/libavcodec/dsputil.c (revision 20545) +++ ffmpeg/libavcodec/dsputil.c (working copy) @@ -3627,39 +3627,68 @@ return acc; } +static inline void add_hfyu_left_prediction_bgr24_c(uint8_t *dst, const uint8_t *src, int w, int *red, int *green, int *blue){ + int i; + int r,g,b; + r= *red; + g= *green; + b= *blue; + + for(i=0; iadd_hfyu_median_prediction= add_hfyu_median_prediction_c; c->sub_hfyu_median_prediction= sub_hfyu_median_prediction_c; c->add_hfyu_left_prediction = add_hfyu_left_prediction_c; + c->add_hfyu_left_prediction_bgr24 = add_hfyu_left_prediction_bgr24_c; c->add_hfyu_left_prediction_bgr32 = add_hfyu_left_prediction_bgr32_c; c->bswap_buf= bswap_buf; #if CONFIG_PNG_DECODER Index: ffmpeg/libavcodec/dsputil.h =================================================================== --- ffmpeg/libavcodec/dsputil.h (revision 20545) +++ ffmpeg/libavcodec/dsputil.h (working copy) @@ -350,7 +350,8 @@ void (*sub_hfyu_median_prediction)(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int w, int *left, int *left_top); void (*add_hfyu_median_prediction)(uint8_t *dst, const uint8_t *top, const uint8_t *diff, int w, int *left, int *left_top); int (*add_hfyu_left_prediction)(uint8_t *dst, const uint8_t *src, int w, int left); - void (*add_hfyu_left_prediction_bgr32)(uint8_t *dst, const uint8_t *src, int w, int *red, int *green, int *blue); + void (*add_hfyu_left_prediction_bgr24)(uint8_t *dst, const uint8_t *src, int w, int *red, int *green, int *blue); + void (*add_hfyu_left_prediction_bgr32)(uint8_t *dst, const uint8_t *src, int w, int *red, int *green, int *blue, int *alpha); /* this might write to dst[w] */ void (*add_png_paeth_prediction)(uint8_t *dst, uint8_t *src, uint8_t *top, int w, int bpp); void (*bswap_buf)(uint32_t *dst, const uint32_t *src, int w);