[Ffmpeg-devel] [PATCH] ported SGI decoder to the new API
Xiaohui Sun
sunxiaohui
Sun Apr 1 04:40:14 CEST 2007
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Michael Niedermayer wrote:
> Hi
[...]
>> +} SgiState;
>> +
>> +/**
>> + * expand an RLE row into a channel
>> + * @param in_buf input buffer
>> + * @param out_buf output buffer
>> + * @param chan_offset offsets into input buffer
>> + * @param pixelstride pixel stride of input buffer
>> + * @return Size of output in bytes, -1 if buffer overflows
>> + */
>> +static int expand_rle_row(uint8_t *in_buf, uint8_t* end_buf,
>> + unsigned char *out_buf, int chan_offset, int pixelstride)
>> +{
>> + unsigned char pixel, count;
>> + unsigned char *orig = out_buf;
>> +
>> + out_buf += chan_offset;
>> +
>> + while (1) {
>> + if(in_buf + 1 > end_buf) return -1;
>> + pixel = bytestream_get_byte(&in_buf);
>> + if (!(count = (pixel & 0x7f))) {
>> + return (out_buf - orig) / pixelstride;
>> + }
>> +
>> + if (pixel & 0x80) {
>> + if(in_buf + count >= end_buf) return -1;
>> + while (count--) {
>> + *out_buf = bytestream_get_byte(&in_buf);
>> + out_buf += pixelstride;
>> + }
>> + } else {
>> + if(in_buf + 1 >= end_buf) return -1;
>> + pixel = bytestream_get_byte(&in_buf);
>> +
>> + while (count--) {
>> + *out_buf = pixel;
>> + out_buf += pixelstride;
>> + }
>> + }
>> + }
>> +}
>
> this code still lacks checks against buffer overflows
I find nowhere to get the out_buf size, I think it is linesize * s->height.
[...]
>> +
>> + for (z = 0; z < s->depth; z++) {
>> + dest_row = out_buf + s->height * s->linesize;
>> + for (y = 0; y < s->height; y++) {
>> + dest_row -= s->linesize;
>
>> + start_offset = bytestream_get_be32(&start_table);
>> + if(in_buf + start_offset > end_buf) {
>> + return AVERROR_INVALIDDATA;
>> + }
>
> this is better but it still does not catch all cases
Do you mean I should read the length_table and check if the encoded
length is overflow?
[...]
>
>
> [...]
>> +/**
>> + * Count up to 127 consecutive pixels which are either all the same or
>> + * all differ from the previous and next pixels.
>> + * @param start pointer to the first pixel
>> + * @param len maximum number of pixels
>> + * @param same 1 if searching for identical pixel values, 0 for differing
>> + * @return number of matching consecutive pixels found
>> + */
>> +static av_always_inline int count_pixels_1bpp(uint8_t *start, int len, int same)
>> +{
>> + uint8_t *pos;
>> + int count = 1;
>> +
>> + for (pos = start + 1; count < FFMIN(127, len); pos ++, count ++) {
>> + if (same != !(*(pos - 1) != * pos)) {
>> + if (!same) {
>> + /* if bpp == 1, then 0 1 1 0 is more efficiently encoded as a single
>> + * raw block of pixels. for larger bpp, RLE is as good or better */
>> + if (count + 1 < FFMIN(127, len) && *pos != *(pos + 1))
>> + continue;
>> +
>> + /* if RLE can encode the next block better than as a raw block,
>> + * back up and leave _all_ the identical pixels for RLE */
>> + count --;
>> + }
>> + break;
>> + }
>> + }
>> + return count;
>> +}
>> +
>> +/**
>> + * Count up to 127 consecutive pixels which are either all the same or
>> + * all differ from the previous and next pixels.
>> + * @param start Pointer to the first pixel
>> + * @param len Maximum number of pixels
>> + * @param bpp Bytes per pixel
>> + * @param same 1 if searching for identical pixel values, 0 for differing
>> + * @return number of matching consecutive pixels found
>> + */
>> +static av_always_inline int count_pixels_nbpp(uint8_t *start, int len, int bpp, int same)
>> +{
>> + uint8_t *pos;
>> + int count = 1;
>> +
>> + for (pos = start + bpp; count < FFMIN(127, len); pos += bpp, count ++) {
>> + if (same != !memcmp(pos - bpp, pos, bpp)) {
>> + if (!same) {
>> + /* if RLE can encode the next block better than as a raw block,
>> + * back up and leave _all_ the identical pixels for RLE */
>> + count --;
>> + }
>> + break;
>> + }
>> + }
>> + return count;
>> +}
>
> this is still duplicated relative to targaenc.c
I will put them in a separeate rle.c/rle.h and let targaenc.c call it.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
iD8DBQFGDxuN+BwsLu3sVWwRAmLbAJ0St5C8+euWIHbH3WDI+Cvc+g1dyACgwWLa
3lOs6ZxtzvieWpNK73wE9eY=
=3RNu
-----END PGP SIGNATURE-----
More information about the ffmpeg-devel
mailing list