diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2007-08-12 19:47:27 +0400 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2007-08-12 19:47:27 +0400 |
commit | b74fb935f814779826333a8bdb03dcbc3135835f (patch) | |
tree | 51f61e3d4be8c8c6b740b2dd6feb034bec455a6d /libavcodec/4xm.c | |
parent | 3ca96802e28d40eb108cb5460b3dce07e3c8199d (diff) |
support ifr2 from Toy-Story2_better-image-quality.4xa
Originally committed as revision 10091 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavcodec/4xm.c')
-rw-r--r-- | libavcodec/4xm.c | 49 |
1 files changed, 48 insertions, 1 deletions
diff --git a/libavcodec/4xm.c b/libavcodec/4xm.c index ef8eb1333b..2db167f699 100644 --- a/libavcodec/4xm.c +++ b/libavcodec/4xm.c @@ -575,6 +575,49 @@ static uint8_t *read_huffman_tables(FourXContext *f, uint8_t * const buf){ return ptr; } +static int mix(int c0, int c1){ + int blue = 2*(c0&0x001F) + (c1&0x001F); + int green= (2*(c0&0x03E0) + (c1&0x03E0))>>5; + int red = 2*(c0>>10) + (c1>>10); + return red/3*1024 + green/3*32 + blue/3; +} + +static int decode_i2_frame(FourXContext *f, uint8_t *buf, int length){ + int x, y, x2, y2; + const int width= f->avctx->width; + const int height= f->avctx->height; + uint16_t *dst= (uint16_t*)f->current_picture.data[0]; + const int stride= f->current_picture.linesize[0]>>1; + + for(y=0; y<height; y+=16){ + for(x=0; x<width; x+=16){ + unsigned int color[4], bits; + memset(color, 0, sizeof(color)); +//warning following is purely guessed ... + color[0]= AV_RN16(buf); buf+=2; //FIXME use bytestream + color[1]= AV_RN16(buf); buf+=2; + + if(color[0]&0x8000) av_log(NULL, AV_LOG_ERROR, "unk bit 1\n"); + if(color[1]&0x8000) av_log(NULL, AV_LOG_ERROR, "unk bit 2\n"); + + color[2]= mix(color[0], color[1]); + color[3]= mix(color[1], color[0]); + + bits= AV_RL32(buf); buf+= 4; + for(y2=0; y2<16; y2++){ + for(x2=0; x2<16; x2++){ + int index= 2*(x2>>2) + 8*(y2>>2); + dst[y2*stride+x2]= color[(bits>>index)&3]; + } + } + dst+=16; + } + dst += 16*stride - width; + } + + return 0; +} + static int decode_i_frame(FourXContext *f, uint8_t *buf, int length){ int x, y; const int width= f->avctx->width; @@ -702,7 +745,11 @@ static int decode_frame(AVCodecContext *avctx, return -1; } - if(frame_4cc == ff_get_fourcc("ifrm") || frame_4cc == ff_get_fourcc("ifr2")){ + if(frame_4cc == ff_get_fourcc("ifr2")){ + p->pict_type= I_TYPE; + if(decode_i2_frame(f, buf-4, frame_size) < 0) + return -1; + }else if(frame_4cc == ff_get_fourcc("ifrm")){ p->pict_type= I_TYPE; if(decode_i_frame(f, buf, frame_size) < 0) return -1; |