diff options
author | Christoph M. Becker <cmbecker69@gmx.de> | 2016-08-16 14:27:23 +0200 |
---|---|---|
committer | Christoph M. Becker <cmbecker69@gmx.de> | 2016-08-16 14:27:23 +0200 |
commit | 4f8e26f2a40ffaa3a5b77be6a49989a1a42e2b83 (patch) | |
tree | 11f1a2bdcc71102ff42d1c3296d4e41ba9650038 /src/gd_tga.c | |
parent | f756f3d9e48ebff358701cbfd0af9dfb1fb416f7 (diff) | |
download | libgd-4f8e26f2a40ffaa3a5b77be6a49989a1a42e2b83.tar.gz |
Fix #290: TGA RLE decoding is broken
We make it work only, for now. Actually, it doesn't make sense that
`oTga::bitmap` is an `int *` as we're storing only bytes there. If this
will be changed, we can even get rid of the `conversion_buffer` in
`read_image_tga` altogether, and read the image data into the
`decompression_buffer` (if RLE'd) or the `tga->bitmap` (if uncompressed)
directly.
Diffstat (limited to 'src/gd_tga.c')
-rw-r--r-- | src/gd_tga.c | 18 |
1 files changed, 10 insertions, 8 deletions
diff --git a/src/gd_tga.c b/src/gd_tga.c index ec6781f..8737b04 100644 --- a/src/gd_tga.c +++ b/src/gd_tga.c @@ -207,12 +207,13 @@ int read_image_tga( gdIOCtx *ctx, oTga *tga ) { int pixel_block_size = (tga->bits / 8); int image_block_size = (tga->width * tga->height) * pixel_block_size; - uint8_t* decompression_buffer = NULL; + int* decompression_buffer = NULL; unsigned char* conversion_buffer = NULL; int buffer_caret = 0; int bitmap_caret = 0; int i = 0; int encoded_pixels; + int rle_size; if(overflow2(tga->width, tga->height)) { return -1; @@ -266,7 +267,7 @@ int read_image_tga( gdIOCtx *ctx, oTga *tga ) /*! \brief Read in RLE compressed RGB TGA * Chunk load the pixel data from an RLE compressed RGB type TGA. */ - decompression_buffer = (uint8_t*) gdMalloc(image_block_size * sizeof(uint8_t)); + decompression_buffer = (int*) gdMalloc(image_block_size * sizeof(int)); if (decompression_buffer == NULL) { return -1; } @@ -277,7 +278,8 @@ int read_image_tga( gdIOCtx *ctx, oTga *tga ) return -1; } - if (gdGetBuf(conversion_buffer, image_block_size, ctx) != image_block_size) { + rle_size = gdGetBuf(conversion_buffer, image_block_size, ctx); + if (rle_size <= 0) { gdFree(conversion_buffer); gdFree(decompression_buffer); return -1; @@ -285,7 +287,7 @@ int read_image_tga( gdIOCtx *ctx, oTga *tga ) buffer_caret = 0; - while( buffer_caret < image_block_size) { + while( buffer_caret < rle_size) { decompression_buffer[buffer_caret] = (int)conversion_buffer[buffer_caret]; buffer_caret++; } @@ -298,14 +300,14 @@ int read_image_tga( gdIOCtx *ctx, oTga *tga ) encoded_pixels = ( ( decompression_buffer[ buffer_caret ] & ~TGA_RLE_FLAG ) + 1 ); buffer_caret++; - if ((bitmap_caret + (encoded_pixels * pixel_block_size)) >= image_block_size) { + if ((bitmap_caret + (encoded_pixels * pixel_block_size)) > image_block_size) { gdFree( decompression_buffer ); gdFree( conversion_buffer ); return -1; } for (i = 0; i < encoded_pixels; i++) { - memcpy(tga->bitmap + bitmap_caret, decompression_buffer + buffer_caret, pixel_block_size); + memcpy(tga->bitmap + bitmap_caret, decompression_buffer + buffer_caret, pixel_block_size * sizeof(int)); bitmap_caret += pixel_block_size; } buffer_caret += pixel_block_size; @@ -314,13 +316,13 @@ int read_image_tga( gdIOCtx *ctx, oTga *tga ) encoded_pixels = decompression_buffer[ buffer_caret ] + 1; buffer_caret++; - if ((bitmap_caret + (encoded_pixels * pixel_block_size)) >= image_block_size) { + if ((bitmap_caret + (encoded_pixels * pixel_block_size)) > image_block_size) { gdFree( decompression_buffer ); gdFree( conversion_buffer ); return -1; } - memcpy(tga->bitmap + bitmap_caret, decompression_buffer + buffer_caret, encoded_pixels * pixel_block_size); + memcpy(tga->bitmap + bitmap_caret, decompression_buffer + buffer_caret, encoded_pixels * pixel_block_size * sizeof(int)); bitmap_caret += (encoded_pixels * pixel_block_size); buffer_caret += (encoded_pixels * pixel_block_size); } |