mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2024-12-28 02:12:28 +00:00
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. Originally committed as revision 2993 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
2b382987fd
commit
44f110f509
@ -86,9 +86,7 @@ static int read_uncompressed_sgi(const SGIInfo *si,
|
||||
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 @@ static int read_uncompressed_sgi(const SGIInfo *si,
|
||||
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 @@ static void expand_rle_row(unsigned char *optr, unsigned char *iptr,
|
||||
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 void expand_rle_row(unsigned char *optr, unsigned char *iptr,
|
||||
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 @@ static int read_rle_sgi(const SGIInfo *sgi_info,
|
||||
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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user