diff options
Diffstat (limited to 'plugins/AdvaImg/src/FreeImage/PluginTARGA.cpp')
-rw-r--r-- | plugins/AdvaImg/src/FreeImage/PluginTARGA.cpp | 112 |
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; |