You've already forked FFmpeg
							
							
				mirror of
				https://github.com/FFmpeg/FFmpeg.git
				synced 2025-10-30 23:18:11 +02: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:
		| @@ -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; | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user