From 05e896af7eaeda2ce134d335ed82d15e2f4b4930 Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Fri, 10 May 2019 00:04:49 +0100 Subject: [PATCH] Add support for type 9 (colour mapped, compressed) TGA images. --- src/osgPlugins/tga/ReaderWriterTGA.cpp | 86 +++++++++++++++++++++++++- 1 file changed, 85 insertions(+), 1 deletion(-) diff --git a/src/osgPlugins/tga/ReaderWriterTGA.cpp b/src/osgPlugins/tga/ReaderWriterTGA.cpp index cdb9071d2..f1e9944e7 100644 --- a/src/osgPlugins/tga/ReaderWriterTGA.cpp +++ b/src/osgPlugins/tga/ReaderWriterTGA.cpp @@ -391,7 +391,7 @@ int *numComponents_ret) fin.seekg(18); /* check for reasonable values in case this is not a tga file */ - if ((type != 1 && type != 2 && type != 10) || + if ((type != 1 && type != 2 && type != 9 && type != 10) || (width < 0 || width > 4096) || (height < 0 || height > 4096) || (depth < 1 || depth > 4)) @@ -564,6 +564,90 @@ int *numComponents_ret) } } break; + case 9: /* colormap, compressed */ + { + if (colormapLen == 0 || colormapDepth == 0) + { + tgaerror = ERR_UNSUPPORTED; /* colormap missing or empty */ + return NULL; + } + SafeArray formattedMap(colormapLen * format); + if (formattedMap == NULL) + { + tgaerror = ERR_MEM; + return NULL; + } + for (int i = 0; i < colormapLen; i++) + { + convert_data(colormap, formattedMap, i, colormapDepth, format); + } + + int size, x, y; + int pos = fin.tellg(); + + fin.seekg(0, std::ios::end); + // This is the size of the rest of the TGA file, not just the image section + size = (int)fin.tellg() - pos; + fin.seekg(pos, std::ios::beg); + SafeArray buf(size); + if (buf == NULL) + { + tgaerror = ERR_MEM; + return NULL; + } + unsigned char* src = buf; + + fin.read((char*)buf, size); + if (fin.gcount() == (std::streamsize)size) + { + for (y = 0; y < height; y++) + { + rle_decode(&src, linebuf, width*depth, &rleRemaining, + &rleIsCompressed, rleCurrent, rleEntrySize); + assert(src <= buf + size); + + for (x = 0; x < width; x++) + { + int index; + switch (depth) + { + case 1: + index = linebuf[x]; + break; + case 2: + index = getInt16(linebuf + x * 2); + break; + case 3: + index = getInt24(linebuf + x * 3); + break; + case 4: + index = getInt32(linebuf + x * 4); + break; + default: + tgaerror = ERR_UNSUPPORTED; + return NULL; /* unreachable code - (depth < 1 || depth > 4) rejected by "check for reasonable values in case this is not a tga file" near the start of this function*/ + } + + if (index >= colormapLen) + { + tgaerror = ERR_UNSUPPORTED; + return NULL; + } + + int adjustedX = bLeftToRight ? x : (width - 1) - x; + for (int i = 0; i < format; i++) + (dest + adjustedX * format)[i] = (formattedMap + index * format)[i]; + } + dest += lineoffset; + } + } + else + { + tgaerror = ERR_READ; + return NULL; + } + } + break; case 10: /* RGB, compressed */ { int size, x, y;