summaryrefslogtreecommitdiff
path: root/src/gd_tga.c
diff options
context:
space:
mode:
authorChristoph M. Becker <cmbecker69@gmx.de>2016-08-16 14:27:23 +0200
committerChristoph M. Becker <cmbecker69@gmx.de>2016-08-16 14:27:23 +0200
commit4f8e26f2a40ffaa3a5b77be6a49989a1a42e2b83 (patch)
tree11f1a2bdcc71102ff42d1c3296d4e41ba9650038 /src/gd_tga.c
parentf756f3d9e48ebff358701cbfd0af9dfb1fb416f7 (diff)
downloadlibgd-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.c18
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);
}