From 67a0f815e4be5527f5830d0973d87743dd37a7b2 Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Sat, 19 Aug 2017 22:22:20 +0100 Subject: [PATCH] Add support for type-1 (colour-mapped, uncompressed) targa images to the osgTGA plugin --- src/osgPlugins/tga/ReaderWriterTGA.cpp | 100 ++++++++++++++++++++++--- 1 file changed, 89 insertions(+), 11 deletions(-) diff --git a/src/osgPlugins/tga/ReaderWriterTGA.cpp b/src/osgPlugins/tga/ReaderWriterTGA.cpp index 57e37259e..af3b789c7 100644 --- a/src/osgPlugins/tga/ReaderWriterTGA.cpp +++ b/src/osgPlugins/tga/ReaderWriterTGA.cpp @@ -174,6 +174,22 @@ static int getInt16(unsigned char *ptr) return res | (tmp<<8); } +static int getInt24(unsigned char *ptr) +{ + int temp1 = ptr[0]; + int temp2 = ptr[1]; + int temp3 = ptr[2]; + return temp1 | (temp2 << 8) | (temp3 << 16); +} + +static int getInt32(unsigned char *ptr) +{ + int temp1 = ptr[0]; + int temp2 = ptr[1]; + int temp3 = ptr[2]; + int temp4 = ptr[3]; + return temp1 | (temp2 << 8) | (temp3 << 16) | (temp4 << 24); +} /* */ /* decode a new rle packet */ @@ -257,6 +273,7 @@ int *numComponents_ret) int flags; int format; unsigned char *colormap; + int colormapLen; int indexsize; int rleIsCompressed; int rleRemaining; @@ -283,10 +300,10 @@ int *numComponents_ret) flags = header[17]; /* check for reasonable values in case this is not a tga file */ - if ((type != 2 && type != 10) || + if ((type != 1 && type != 2 && type != 10) || (width < 0 || width > 4096) || (height < 0 || height > 4096) || - (depth < 2 || depth > 4)) + (depth < 1 || depth > 4)) { tgaerror = ERR_UNSUPPORTED; return NULL; @@ -298,18 +315,28 @@ int *numComponents_ret) colormap = NULL; if (header[1] == 1) /* there is a colormap */ { - int len = getInt16(&header[5]); + colormapLen = getInt16(&header[5]); indexsize = header[7]>>3; - colormap = new unsigned char [len*indexsize]; - fin.read((char*)colormap,len*indexsize); - } + colormap = new unsigned char [colormapLen*indexsize]; + fin.read((char*)colormap,colormapLen*indexsize); - if (depth == 2) /* 16 bits */ - { - if (flags & 1) format = 4; - else format = 3; + if (indexsize == 2) /* 16 bits */ + { + if (flags & 1) format = 4; + else format = 3; + } + else + format = indexsize; + } + else + { + if (depth == 2) /* 16 bits */ + { + if (flags & 1) format = 4; + else format = 3; + } + else format = depth; } - else format = depth; /* SoDebugError::postInfo("simage_tga_load", "TARGA file: %d %d %d %d %d\n", */ /* type, width, height, depth, format); */ @@ -331,6 +358,57 @@ int *numComponents_ret) switch(type) { + case 1: /* colormap, uncompressed */ + { + unsigned char * formattedMap = new unsigned char[colormapLen * format]; + for (int i = 0; i < colormapLen; i++) + { + convert_data(colormap, formattedMap, i, indexsize, format); + } + + int x, y; + for (y = 0; y < height; y++) + { + fin.read((char*)linebuf, width*depth); + if (fin.gcount() != (std::streamsize) (width*depth)) + { + tgaerror = ERR_READ; + break; + } + + 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; + break; + } + + int adjustedX = bLeftToRight ? x : (width - 1) - x; + for (int i = 0; i < format; i++) + (dest + adjustedX * format)[i] = (formattedMap + index * format)[i]; + } + dest += lineoffset; + } + + if (formattedMap) + delete[] formattedMap; + } + break; case 2: /* RGB, uncompressed */ { int x, y;