Implement alpha channel decoding for BGR HuffYUV.

Since BGR24 is decoded as BGR32, fill its alpha channel with 255
using the appropriate predictors.

Originally committed as revision 21211 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
Alexander Strange 2010-01-14 01:32:49 +00:00
parent ff5ab5c8c9
commit f267d3ac75
3 changed files with 20 additions and 9 deletions

View File

@ -3632,35 +3632,42 @@ static int add_hfyu_left_prediction_c(uint8_t *dst, const uint8_t *src, int w, i
#define B 3 #define B 3
#define G 2 #define G 2
#define R 1 #define R 1
#define A 0
#else #else
#define B 0 #define B 0
#define G 1 #define G 1
#define R 2 #define R 2
#define A 3
#endif #endif
static void add_hfyu_left_prediction_bgr32_c(uint8_t *dst, const uint8_t *src, int w, int *red, int *green, int *blue){ static void add_hfyu_left_prediction_bgr32_c(uint8_t *dst, const uint8_t *src, int w, int *red, int *green, int *blue, int *alpha){
int i; int i;
int r,g,b; int r,g,b,a;
r= *red; r= *red;
g= *green; g= *green;
b= *blue; b= *blue;
a= *alpha;
for(i=0; i<w; i++){ for(i=0; i<w; i++){
b+= src[4*i+B]; b+= src[4*i+B];
g+= src[4*i+G]; g+= src[4*i+G];
r+= src[4*i+R]; r+= src[4*i+R];
a+= src[4*i+A];
dst[4*i+B]= b; dst[4*i+B]= b;
dst[4*i+G]= g; dst[4*i+G]= g;
dst[4*i+R]= r; dst[4*i+R]= r;
dst[4*i+A]= a;
} }
*red= r; *red= r;
*green= g; *green= g;
*blue= b; *blue= b;
*alpha= a;
} }
#undef B #undef B
#undef G #undef G
#undef R #undef R
#undef A
#define BUTTERFLY2(o1,o2,i1,i2) \ #define BUTTERFLY2(o1,o2,i1,i2) \
o1= (i1)+(i2);\ o1= (i1)+(i2);\

View File

@ -350,7 +350,7 @@ typedef struct DSPContext {
void (*sub_hfyu_median_prediction)(uint8_t *dst, const uint8_t *src1, const uint8_t *src2, int w, int *left, int *left_top); 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); 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); 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_bgr32)(uint8_t *dst, const uint8_t *src, int w, int *red, int *green, int *blue, int *alpha);
/* this might write to dst[w] */ /* 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 (*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); void (*bswap_buf)(uint32_t *dst, const uint32_t *src, int w);

View File

@ -39,10 +39,12 @@
#define B 3 #define B 3
#define G 2 #define G 2
#define R 1 #define R 1
#define A 0
#else #else
#define B 0 #define B 0
#define G 1 #define G 1
#define R 2 #define R 2
#define A 3
#endif #endif
typedef enum Predictor{ typedef enum Predictor{
@ -406,7 +408,7 @@ static av_cold void alloc_temp(HYuvContext *s){
s->temp[i]= av_malloc(s->width + 16); s->temp[i]= av_malloc(s->width + 16);
} }
}else{ }else{
s->temp[0]= av_malloc(4*s->width + 16); s->temp[0]= av_mallocz(4*s->width + 16);
} }
} }
@ -836,7 +838,7 @@ static av_always_inline void decode_bgr_1(HYuvContext *s, int count, int decorre
s->temp[0][4*i+R] = get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3); s->temp[0][4*i+R] = get_vlc2(&s->gb, s->vlc[2].table, VLC_BITS, 3);
} }
if(alpha) 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);
} }
} }
@ -1116,11 +1118,11 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac
} }
}else{ }else{
int y; int y;
int leftr, leftg, leftb; int leftr, leftg, leftb, lefta;
const int last_line= (height-1)*p->linesize[0]; const int last_line= (height-1)*p->linesize[0];
if(s->bitstream_bpp==32){ 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); leftr= p->data[0][last_line+R]= get_bits(&s->gb, 8);
leftg= p->data[0][last_line+G]= 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); leftb= p->data[0][last_line+B]= get_bits(&s->gb, 8);
@ -1128,6 +1130,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac
leftr= p->data[0][last_line+R]= 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); leftg= p->data[0][last_line+G]= get_bits(&s->gb, 8);
leftb= p->data[0][last_line+B]= get_bits(&s->gb, 8); leftb= p->data[0][last_line+B]= get_bits(&s->gb, 8);
lefta= p->data[0][last_line+A]= 255;
skip_bits(&s->gb, 8); skip_bits(&s->gb, 8);
} }
@ -1136,13 +1139,14 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac
case LEFT: case LEFT:
case PLANE: case PLANE:
decode_bgr_bitstream(s, width-1); 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); s->dsp.add_hfyu_left_prediction_bgr32(p->data[0] + last_line+4, s->temp[0], width-1, &leftr, &leftg, &leftb, &lefta);
for(y=s->height-2; y>=0; y--){ //Yes it is stored upside down. for(y=s->height-2; y>=0; y--){ //Yes it is stored upside down.
decode_bgr_bitstream(s, width); 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); s->dsp.add_hfyu_left_prediction_bgr32(p->data[0] + p->linesize[0]*y, s->temp[0], width, &leftr, &leftg, &leftb, &lefta);
if(s->predictor == PLANE){ if(s->predictor == PLANE){
if(s->bitstream_bpp!=32) lefta=0;
if((y&s->interlaced)==0 && y<s->height-1-s->interlaced){ if((y&s->interlaced)==0 && y<s->height-1-s->interlaced){
s->dsp.add_bytes(p->data[0] + p->linesize[0]*y, s->dsp.add_bytes(p->data[0] + p->linesize[0]*y,
p->data[0] + p->linesize[0]*y + fake_ystride, fake_ystride); p->data[0] + p->linesize[0]*y + fake_ystride, fake_ystride);