[Ffmpeg-devel] [RFC] .tga decoder

Michael Niedermayer michaelni
Tue Oct 10 09:32:47 CEST 2006


Hi

On Mon, Oct 09, 2006 at 02:08:20PM +0300, Kostya wrote:
> Here is my Targa files decoder. It tested to work on .tga files
> created with ImageMagick and on movs with different depth which can
> be found here: http://www.openquicktime.org/files.php (named aletrek-*.mov)

[...]
> +static void targa_decode_rle(AVCodecContext *avctx, TargaContext *s, uint8_t *src, uint8_t *dst, int w, int h, int stride, int bpp)
> +{
> +    int i, x, y;
> +    int depth = (bpp + 1) / 8;
> +    int type, count;
> +    int diff;
> +
> +    diff = stride - w * depth;
> +    x = y = 0;
> +    while(y < h){
> +        type = *src++;
> +        count = (type & 0x7F) + 1;
> +        if((x + count > w) && (y + (x + count + 1)/w > h)){

x + count + 1 > (h - y)*w
avoids the /


> +            av_log(avctx, AV_LOG_ERROR, "Packet went out of bounds: position (%i,%i) size %i\n", x, y, count);
> +            return;
> +        }
> +        if(type & 0x80){ // RLE
> +            for(i = 0; i < count; i++){
> +                switch(depth){
> +                case 1:
> +                    *dst = *src;
> +                    break;
> +                case 2:
> +                    *((uint16_t*)dst) = LE_16(src);
> +                    break;
> +                case 3:
> +                    dst[0] = src[0];
> +                    dst[1] = src[1];
> +                    dst[2] = src[2];
> +                    break;
> +                }
> +                dst += depth;
> +                x++;
> +                if(x == w){
> +                    x = 0;
> +                    y++;
> +                    dst += diff;
> +                }
> +            }
> +            src += depth;
> +        }else{ // copy
> +            for(i = 0; i < count; i++){
> +                switch(depth){
> +                case 1:
> +                    *dst++ = *src++;
> +                    break;
> +                case 2:
> +                    *((uint16_t*)dst) = LE_16(src);
> +                    dst += 2; src += 2;
> +                    break;
> +                case 3:
> +                    *dst++ = *src++;
> +                    *dst++ = *src++;
> +                    *dst++ = *src++;
> +                    break;
> +                }
> +                x++;
> +                if(x == w){
> +                    x = 0;
> +                    y++;
> +                    dst += diff;
> +                }
> +            }
> +        }

for(i = 0; i < count; i++){
    switch(depth){
    case 1:
        *dst = *src;
        break;
    case 2:
        *((uint16_t*)dst) = LE_16(src);
        break;
    case 3:
        dst[0] = src[0];
        dst[1] = src[1];
        dst[2] = src[2];
        break;
    }
    dst += depth;
    if(!(type & 0x80))
        src += depth;
    x++;
    if(x == w){
        x = 0;
        y++;
        dst += diff;
    }
}

and if speed matters then an always_inline function which has type&0x80 and
depth as "constant" arguments should help


[...]
> +            uint16_t *dst16;
> +            for(y = 0; y < s->height; y++){
> +                switch(s->bpp){
> +                case 8:
> +                    memcpy(dst, buf, s->width);
> +                    break;
> +                case 15:
> +                case 16:
> +                    dst16 = (uint16_t*)dst;
> +                    for(x = 0; x < s->width; x++)
> +                        dst16[x] = LE_16(buf + x*2);
> +                    break;
> +                case 24:
> +                    memcpy(dst, buf, s->width * 3);
> +                    break;
> +                }
> +                dst += stride;
> +                buf += s->width * ((s->bpp + 1) >> 3);
> +            }

#ifdef WORDS_BIGENDIAN
    if(s->bpp>>3 == 2){
        uint16_t *dst16 = (uint16_t*)dst;
        for(x = 0; x < s->width; x++)
            dst16[x] = LE_16(buf + x*2);
    }else
#endif
        memcpy(dst, buf, s->width*(s->bpp>>3));


[...]
-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

In the past you could go to a library and read, borrow or copy any book
Today you'd get arrested for mere telling someone where the library is




More information about the ffmpeg-devel mailing list