Mercurial > libavformat.hg
changeset 430:153985f24e5b libavformat
patch courtesy of Todd Kirby:
* Fixes a small memory leak in read_rle_sgi()
* Remove temp buffer in read_rle_sgi(). Write rle data directly to image
buffer.
* Adds sanity check to read_rle_sgi() to insure decoded rle data row
equals image width.
author | melanson |
---|---|
date | Sat, 10 Apr 2004 15:09:46 +0000 |
parents | 983639863758 |
children | fe91c780d26a |
files | sgi.c |
diffstat | 1 files changed, 21 insertions(+), 34 deletions(-) [+] |
line wrap: on
line diff
--- a/sgi.c Fri Apr 09 16:46:12 2004 +0000 +++ b/sgi.c Sat Apr 10 15:09:46 2004 +0000 @@ -86,9 +86,7 @@ AVPicture *pict, ByteIOContext *f) { int x, y, z, chan_offset, ret = 0; - uint8_t *dest_row, *tmp_row = NULL; - - tmp_row = av_malloc(si->xsize); + uint8_t *dest_row; /* skip header */ url_fseek(f, SGI_HEADER_SIZE, SEEK_SET); @@ -108,28 +106,23 @@ for (y = si->ysize - 1; y >= 0; y--) { dest_row = pict->data[0] + (y * si->xsize * si->zsize); - if (!get_buffer(f, tmp_row, si->xsize)) { - ret = -1; - goto cleanup; - } for (x = 0; x < si->xsize; x++) { - dest_row[chan_offset] = tmp_row[x]; + dest_row[chan_offset] = get_byte(f); dest_row += si->zsize; } } } -cleanup: - av_free(tmp_row); return ret; } /* expand an rle row into a channel */ -static void expand_rle_row(unsigned char *optr, unsigned char *iptr, +static int expand_rle_row(ByteIOContext *f, unsigned char *optr, int chan_offset, int pixelstride) { unsigned char pixel, count; + int length = 0; #ifndef WORDS_BIGENDIAN /* rgba -> bgra for rgba32 on little endian cpus */ @@ -141,22 +134,23 @@ optr += chan_offset; while (1) { - pixel = *iptr++; + pixel = get_byte(f); if (!(count = (pixel & 0x7f))) { - return; + return length; } if (pixel & 0x80) { while (count--) { - *optr = *iptr; + *optr = get_byte(f); + length++; optr += pixelstride; - iptr++; } } else { - pixel = *iptr++; + pixel = get_byte(f); while (count--) { *optr = pixel; + length++; optr += pixelstride; } } @@ -168,18 +162,16 @@ static int read_rle_sgi(const SGIInfo *sgi_info, AVPicture *pict, ByteIOContext *f) { - uint8_t *dest_row, *rle_data = NULL; - unsigned long *start_table, *length_table; + uint8_t *dest_row; + unsigned long *start_table; int y, z, xsize, ysize, zsize, tablen; - long start_offset, run_length; + long start_offset; int ret = 0; xsize = sgi_info->xsize; ysize = sgi_info->ysize; zsize = sgi_info->zsize; - rle_data = av_malloc(xsize); - /* skip header */ url_fseek(f, SGI_HEADER_SIZE, SEEK_SET); @@ -187,40 +179,35 @@ tablen = ysize * zsize * sizeof(long); start_table = (unsigned long *)av_malloc(tablen); - length_table = (unsigned long *)av_malloc(tablen); if (!get_buffer(f, (uint8_t *)start_table, tablen)) { - ret = -1; + ret = AVERROR_IO; goto fail; } - if (!get_buffer(f, (uint8_t *)length_table, tablen)) { - ret = -1; - goto fail; - } + /* skip run length table */ + url_fseek(f, tablen, SEEK_CUR); for (z = 0; z < zsize; z++) { for (y = 0; y < ysize; y++) { dest_row = pict->data[0] + (ysize - 1 - y) * (xsize * zsize); start_offset = BE_32(&start_table[y + z * ysize]); - run_length = BE_32(&length_table[y + z * ysize]); - /* don't seek if already in the correct spot */ + /* don't seek if already at the next rle start offset */ if (url_ftell(f) != start_offset) { url_fseek(f, start_offset, SEEK_SET); } - get_buffer(f, rle_data, run_length); - - expand_rle_row(dest_row, rle_data, z, zsize); + if (expand_rle_row(f, dest_row, z, zsize) != xsize) { + ret = AVERROR_INVALIDDATA; + goto fail; + } } } fail: av_free(start_table); - av_free(length_table); - av_free(rle_data); return ret; }