summaryrefslogtreecommitdiff
path: root/plugins/AdvaImg/src/FreeImage/PluginTARGA.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/AdvaImg/src/FreeImage/PluginTARGA.cpp')
-rw-r--r--plugins/AdvaImg/src/FreeImage/PluginTARGA.cpp112
1 files changed, 70 insertions, 42 deletions
diff --git a/plugins/AdvaImg/src/FreeImage/PluginTARGA.cpp b/plugins/AdvaImg/src/FreeImage/PluginTARGA.cpp
index 5fb1f53ee0..f12d7286ce 100644
--- a/plugins/AdvaImg/src/FreeImage/PluginTARGA.cpp
+++ b/plugins/AdvaImg/src/FreeImage/PluginTARGA.cpp
@@ -358,6 +358,7 @@ MimeType() {
static BOOL
isTARGA20(FreeImageIO *io, fi_handle handle) {
const unsigned sizeofSig = 18;
+ BYTE signature[sizeofSig];
// tga_signature = "TRUEVISION-XFILE." (TGA 2.0 only)
BYTE tga_signature[sizeofSig] = { 84, 82, 85, 69, 86, 73, 83, 73, 79, 78, 45, 88, 70, 73, 76, 69, 46, 0 };
// get the start offset
@@ -366,13 +367,10 @@ isTARGA20(FreeImageIO *io, fi_handle handle) {
io->seek_proc(handle, 0, SEEK_END);
const long eof = io->tell_proc(handle);
// read the signature
-
io->seek_proc(handle, start_offset + eof - sizeofSig, SEEK_SET);
- BYTE signature[sizeofSig];
- io->read_proc(&signature, 1, sizeofSig, handle);
-
- // rewind
- io->seek_proc(handle, start_offset, SEEK_SET);
+ io->read_proc(&signature, 1, sizeofSig, handle);
+ // rewind
+ io->seek_proc(handle, start_offset, SEEK_SET);
return (memcmp(tga_signature, signature, sizeofSig) == 0);
}
@@ -384,41 +382,61 @@ Validate(FreeImageIO *io, fi_handle handle) {
}
// not a 2.0 image, try testing if it's a valid TGA anyway (not robust)
- BOOL bResult = FALSE;
-
- const long start_offset = io->tell_proc(handle);
-
- TGAHEADER header;
- io->read_proc(&header, sizeof(tagTGAHEADER), 1, handle);
-
- // rewind
- io->seek_proc(handle, start_offset, SEEK_SET);
+ {
+ const long start_offset = io->tell_proc(handle);
+
+ // get the header
+ TGAHEADER header;
+ io->read_proc(&header, sizeof(tagTGAHEADER), 1, handle);
+#ifdef FREEIMAGE_BIGENDIAN
+ SwapHeader(&header);
+#endif
+ // rewind
+ io->seek_proc(handle, start_offset, SEEK_SET);
- switch(header.image_type) {
- case TGA_CMAP :
- case TGA_RGB:
- case TGA_MONO :
- case TGA_RLECMAP:
- case TGA_RLERGB:
- case TGA_RLEMONO:
- switch(header.is_pixel_depth) {
- case 8 :
- case 16:
- case 24:
- case 32:
- bResult = TRUE;
- break;
- default:
- bResult = FALSE;
- break;
+ // the color map type should be a 0 or a 1...
+ if(header.color_map_type != 0 && header.color_map_type != 1) {
+ return FALSE;
+ }
+ // if the color map type is 1 then we validate the map entry information...
+ if(header.color_map_type > 0) {
+ // It doesn't make any sense if the first entry is larger than the color map table
+ if(header.cm_first_entry >= header.cm_length) {
+ return FALSE;
}
- break;
- default:
- bResult = FALSE;
- break;
+ }
+ // check header.cm_size, don't allow 0 or anything bigger than 32
+ if(header.cm_size == 0 || header.cm_size > 32) {
+ return FALSE;
+ }
+ // the width/height shouldn't be 0, right ?
+ if(header.is_width == 0 || header.is_height == 0) {
+ return FALSE;
+ }
+ // let's now verify all the types that are supported by FreeImage (this is our final verification)
+ switch(header.image_type) {
+ case TGA_CMAP :
+ case TGA_RGB:
+ case TGA_MONO :
+ case TGA_RLECMAP:
+ case TGA_RLERGB:
+ case TGA_RLEMONO:
+ switch(header.is_pixel_depth) {
+ case 8 :
+ case 16:
+ case 24:
+ case 32:
+ return TRUE;
+ default:
+ return FALSE;
+ }
+ break;
+ default:
+ return FALSE;
+ }
}
-
- return bResult;
+
+ return FALSE;
}
static BOOL DLL_CALLCONV
@@ -731,8 +749,12 @@ Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
// calculate the color map size
csize = header.cm_length * header.cm_size / 8;
+
+ // read the color map
BYTE *cmap = (BYTE*)malloc(csize * sizeof(BYTE));
-
+ if (cmap == NULL) {
+ throw FI_MSG_ERROR_DIB_MEMORY;
+ }
io->read_proc(cmap, sizeof(BYTE), csize, handle);
// build the palette
@@ -740,8 +762,10 @@ Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
switch (header.cm_size) {
case 16: {
WORD *rgb555 = (WORD*)&cmap[0];
+ unsigned start = (unsigned)header.cm_first_entry;
+ unsigned stop = MIN((unsigned)256, (unsigned)header.cm_length);
- for (count = header.cm_first_entry; count < header.cm_length; count++) {
+ for (count = start; count < stop; count++) {
palette[count].rgbRed = (BYTE)((((*rgb555 & FI16_555_RED_MASK) >> FI16_555_RED_SHIFT) * 0xFF) / 0x1F);
palette[count].rgbGreen = (BYTE)((((*rgb555 & FI16_555_GREEN_MASK) >> FI16_555_GREEN_SHIFT) * 0xFF) / 0x1F);
palette[count].rgbBlue = (BYTE)((((*rgb555 & FI16_555_BLUE_MASK) >> FI16_555_BLUE_SHIFT) * 0xFF) / 0x1F);
@@ -752,8 +776,10 @@ Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
case 24: {
FILE_BGR *bgr = (FILE_BGR*)&cmap[0];
+ unsigned start = (unsigned)header.cm_first_entry;
+ unsigned stop = MIN((unsigned)256, (unsigned)header.cm_length);
- for (count = header.cm_first_entry; count < header.cm_length; count++) {
+ for (count = start; count < stop; count++) {
palette[count].rgbBlue = bgr->b;
palette[count].rgbGreen = bgr->g;
palette[count].rgbRed = bgr->r;
@@ -769,8 +795,10 @@ Load(FreeImageIO *io, fi_handle handle, int page, int flags, void *data) {
memset(trns, 0xFF, 256);
FILE_BGRA *bgra = (FILE_BGRA*)&cmap[0];
+ unsigned start = (unsigned)header.cm_first_entry;
+ unsigned stop = MIN((unsigned)256, (unsigned)header.cm_length);
- for (count = header.cm_first_entry; count < header.cm_length; count++) {
+ for (count = start; count < stop; count++) {
palette[count].rgbBlue = bgra->b;
palette[count].rgbGreen = bgra->g;
palette[count].rgbRed = bgra->r;