dfb8fa52创建于 2025年8月19日历史提交
diff --git a/src/osgPlugins/tga/ReaderWriterTGA.cpp b/src/osgPlugins/tga/ReaderWriterTGA.cpp
index 7249bfe2..30f9fb44 100644
--- a/src/osgPlugins/tga/ReaderWriterTGA.cpp
+++ b/src/osgPlugins/tga/ReaderWriterTGA.cpp
@@ -339,7 +339,8 @@ unsigned char *
 simage_tga_load(std::istream& fin,
 int *width_ret,
 int *height_ret,
-int *numComponents_ret)
+int *numComponents_ret,
+bool ignoreTGA2Fields)
 {
     unsigned char header[18];
     unsigned char footer[26];
@@ -382,50 +383,54 @@ int *numComponents_ret)
 
     fin.seekg(-26, std::ios::end);
     endOfImage = fin.tellg() + (std::streamoff)26;
-    fin.read((char*)footer, 26);
-    if (fin.gcount() != 26)
-    {
-        tgaerror = ERR_READ;
-        return NULL;
-    }
 
-    // TGA footer signature is null-terminated, so works like a C string
-    if (strcmp((char*)&footer[8], "TRUEVISION-XFILE.") == 0)
+    if (!ignoreTGA2Fields)
     {
-        endOfImage -= 26;
-        unsigned int extensionAreaOffset = getInt32(&footer[0]);
-        unsigned int developerAreaOffset = getInt32(&footer[4]);
+        fin.read((char*)footer, 26);
+        if (fin.gcount() != 26)
+        {
+            tgaerror = ERR_READ;
+            return NULL;
+        }
 
-        if (extensionAreaOffset != 0)
+        // TGA footer signature is null-terminated, so works like a C string
+        if (strcmp((char*)&footer[8], "TRUEVISION-XFILE.") == 0)
         {
-            endOfImage = std::min(endOfImage, (std::streampos)extensionAreaOffset);
-            
-            // We only need the last few fields of the extension area
-            fin.seekg(extensionAreaOffset + 482);
-            unsigned char extensionAreaBuffer[13];
-            fin.read((char*)extensionAreaBuffer, 13);
-            if (fin.gcount() != 13)
+            endOfImage -= 26;
+            unsigned int extensionAreaOffset = getInt32(&footer[0]);
+            unsigned int developerAreaOffset = getInt32(&footer[4]);
+
+            if (extensionAreaOffset != 0)
             {
-                tgaerror = ERR_READ;
-                return NULL;
-            }
+                endOfImage = std::min(endOfImage, (std::streampos)extensionAreaOffset);
 
-            unsigned int colorCorrectionOffset = getInt32(&extensionAreaBuffer[0]);
-            unsigned int postageStampOffset = getInt32(&extensionAreaBuffer[4]);
-            unsigned int scanLineOffset = getInt32(&extensionAreaBuffer[8]);
+                // We only need the last few fields of the extension area
+                fin.seekg(extensionAreaOffset + 482);
+                unsigned char extensionAreaBuffer[13];
+                fin.read((char*)extensionAreaBuffer, 13);
+                if (fin.gcount() != 13)
+                {
+                    tgaerror = ERR_READ;
+                    return NULL;
+                }
 
-            if (colorCorrectionOffset != 0)
-                endOfImage = std::min(endOfImage, (std::streampos)colorCorrectionOffset);
-            if (postageStampOffset != 0)
-                endOfImage = std::min(endOfImage, (std::streampos)postageStampOffset);
-            if (scanLineOffset != 0)
-                endOfImage = std::min(endOfImage, (std::streampos)scanLineOffset);
+                unsigned int colorCorrectionOffset = getInt32(&extensionAreaBuffer[0]);
+                unsigned int postageStampOffset = getInt32(&extensionAreaBuffer[4]);
+                unsigned int scanLineOffset = getInt32(&extensionAreaBuffer[8]);
 
-            attributeType = (AttributeType) extensionAreaBuffer[12];
-        }
+                if (colorCorrectionOffset != 0)
+                    endOfImage = std::min(endOfImage, (std::streampos)colorCorrectionOffset);
+                if (postageStampOffset != 0)
+                    endOfImage = std::min(endOfImage, (std::streampos)postageStampOffset);
+                if (scanLineOffset != 0)
+                    endOfImage = std::min(endOfImage, (std::streampos)scanLineOffset);
+
+                attributeType = (AttributeType)extensionAreaBuffer[12];
+            }
 
-        if (developerAreaOffset != 0)
-            endOfImage = std::min(endOfImage, (std::streampos)developerAreaOffset);
+            if (developerAreaOffset != 0)
+                endOfImage = std::min(endOfImage, (std::streampos)developerAreaOffset);
+        }
     }
 
     fin.seekg(18);
@@ -800,18 +805,19 @@ class ReaderWriterTGA : public osgDB::ReaderWriter
         ReaderWriterTGA()
         {
             supportsExtension("tga","Tga Image format");
+            supportsOption("ignoreTga2Fields", "(Read option) Ignore TGA 2.0 fields, even if present. Makes it possible to read files as a TGA 1.0 reader would, helpful when dealing with malformed TGA 2.0 files which are still valid TGA 1.0 files, such as when an image ends with data resembling a TGA 2.0 footer by coincidence.");
         }
 
         virtual const char* className() const { return "TGA Image Reader"; }
 
-        ReadResult readTGAStream(std::istream& fin) const
+        ReadResult readTGAStream(std::istream& fin, bool ignoreTGA2Fields) const
         {
             unsigned char *imageData = NULL;
             int width_ret;
             int height_ret;
             int numComponents_ret;
 
-            imageData = simage_tga_load(fin,&width_ret,&height_ret,&numComponents_ret);
+            imageData = simage_tga_load(fin, &width_ret, &height_ret, &numComponents_ret, ignoreTGA2Fields);
 
             if (imageData==NULL) return ReadResult::FILE_NOT_HANDLED;
 
@@ -852,9 +858,9 @@ class ReaderWriterTGA : public osgDB::ReaderWriter
             return readImage(file, options);
         }
 
-        virtual ReadResult readImage(std::istream& fin,const Options* =NULL) const
+        virtual ReadResult readImage(std::istream& fin, const Options* options = NULL) const
         {
-            return readTGAStream(fin);
+            return readTGAStream(fin, options && options->getOptionString().find("ignoreTga2Fields") != std::string::npos);
         }
 
         virtual ReadResult readImage(const std::string& file, const osgDB::ReaderWriter::Options* options) const
@@ -867,7 +873,7 @@ class ReaderWriterTGA : public osgDB::ReaderWriter
 
             osgDB::ifstream istream(fileName.c_str(), std::ios::in | std::ios::binary);
             if(!istream) return ReadResult::FILE_NOT_HANDLED;
-            ReadResult rr = readTGAStream(istream);
+            ReadResult rr = readTGAStream(istream, options && options->getOptionString().find("ignoreTga2Fields") != std::string::npos);
             if(rr.validImage()) rr.getImage()->setFileName(file);
             return rr;
         }