From 0beb3eb9be6f56e75b8f8b475893bf0840e93221 Mon Sep 17 00:00:00 2001 From: MaxED <j.maxed@gmail.com> Date: Fri, 15 Jan 2016 22:19:48 +0000 Subject: [PATCH] Fixed a crash during skybox textures search when searching for any image and not finding it in the first PK3 or Directory resource. Fixed: TGA image detection required a special approach... Fixed, Visual mode: built-in sky texture should not be mirrored like the classic ones. --- Source/Core/Data/DataManager.cs | 15 ++++++-- Source/Core/Data/ImageDataFormat.cs | 55 ++++++++++++++++------------- 2 files changed, 43 insertions(+), 27 deletions(-) diff --git a/Source/Core/Data/DataManager.cs b/Source/Core/Data/DataManager.cs index 7e1deaa9b..2dd68a9a8 100644 --- a/Source/Core/Data/DataManager.cs +++ b/Source/Core/Data/DataManager.cs @@ -1066,7 +1066,9 @@ namespace CodeImp.DoomBuilder.Data // This container has a lump with given name? if(containers[i] is PK3StructuredReader) { - name = ((PK3StructuredReader)containers[i]).FindFirstFile(name, true); + string foundname = ((PK3StructuredReader)containers[i]).FindFirstFile(name, true); + if(string.IsNullOrEmpty(foundname)) continue; + name = foundname; } else if(!(containers[i] is WADReader)) { @@ -2401,9 +2403,18 @@ namespace CodeImp.DoomBuilder.Data // Sky texture will be missing in ZDoom. Use internal texture if(skybox == null) { + // Whine and moan + if(string.IsNullOrEmpty(skytex)) + General.ErrorLogger.Add(ErrorType.Warning, "Skybox creation failed: Sky1 property is missing from the MAPINFO map definition"); + else + General.ErrorLogger.Add(ErrorType.Warning, "Skybox creation failed: unable to load \"" + skytex + "\" texture"); + + // Use the built-in texture ImageData tex = LoadInternalTexture("MissingSky3D.png"); tex.CreateTexture(); - skybox = MakeClassicSkyBox(new Bitmap(tex.GetBitmap())); + Bitmap sky = new Bitmap(tex.GetBitmap()); + sky.RotateFlip(RotateFlipType.RotateNoneFlipX); // We don't want our built-in image mirrored... + skybox = MakeClassicSkyBox(sky); tex.Dispose(); } } diff --git a/Source/Core/Data/ImageDataFormat.cs b/Source/Core/Data/ImageDataFormat.cs index 4e166477b..b00a1d6af 100644 --- a/Source/Core/Data/ImageDataFormat.cs +++ b/Source/Core/Data/ImageDataFormat.cs @@ -37,7 +37,6 @@ namespace CodeImp.DoomBuilder.Data private static readonly int[] BMP_SIGNATURE = new[] { 66, 77 }; private static readonly int[] DDS_SIGNATURE = new[] { 68, 68, 83, 32 }; private static readonly int[] JPG_SIGNATURE = new[] { 255, 216, 255 }; //mxd - private static readonly int[] TGA_SIGNATURE = new[] { 0, 0, 2, 0 }; //mxd private static readonly int[] PCX_SIGNATURE = new[] { 10, 5, 1, 8 }; //mxd // This check image data and returns the appropriate image reader @@ -49,39 +48,25 @@ namespace CodeImp.DoomBuilder.Data if(data.Length > 10) { // Check for PNG signature - data.Seek(0, SeekOrigin.Begin); - if(CheckSignature(data, PNG_SIGNATURE)) - return new FileImageReader(DevilImageType.IL_PNG); + if(CheckSignature(data, PNG_SIGNATURE)) return new FileImageReader(DevilImageType.IL_PNG); // Check for DDS signature - data.Seek(0, SeekOrigin.Begin); - if(CheckSignature(data, DDS_SIGNATURE)) - return new FileImageReader(DevilImageType.IL_DDS); - - // Check for GIF signature - data.Seek(0, SeekOrigin.Begin); - if(CheckSignature(data, GIF_SIGNATURE)) - return new UnknownImageReader(); //mxd. Not supported by (G)ZDoom + if(CheckSignature(data, DDS_SIGNATURE)) return new FileImageReader(DevilImageType.IL_DDS); //mxd. Check for PCX signature - data.Seek(0, SeekOrigin.Begin); - if(CheckSignature(data, PCX_SIGNATURE)) - return new FileImageReader(DevilImageType.IL_PCX); + if(CheckSignature(data, PCX_SIGNATURE)) return new FileImageReader(DevilImageType.IL_PCX); //mxd. Check for JPG signature - data.Seek(0, SeekOrigin.Begin); - if(CheckSignature(data, JPG_SIGNATURE)) - return new FileImageReader(DevilImageType.IL_JPG); + if(CheckSignature(data, JPG_SIGNATURE)) return new FileImageReader(DevilImageType.IL_JPG); - //mxd. Check for TGA signature - data.Seek(0, SeekOrigin.Begin); - if(CheckSignature(data, TGA_SIGNATURE)) - return new FileImageReader(DevilImageType.IL_TGA); + //mxd. TGA is VERY special in that it doesn't have a proper signature... + if(CheckTgaSignature(data)) return new FileImageReader(DevilImageType.IL_TGA); + + // Check for GIF signature + if(CheckSignature(data, GIF_SIGNATURE)) return new UnknownImageReader(); //mxd. Not supported by (G)ZDoom // Check for BMP signature - data.Seek(0, SeekOrigin.Begin); - if(CheckSignature(data, BMP_SIGNATURE)) - return new UnknownImageReader(); //mxd. Not supported by (G)ZDoom + if(CheckSignature(data, BMP_SIGNATURE)) return new UnknownImageReader(); //mxd. Not supported by (G)ZDoom } // Could it be a doom picture? @@ -118,6 +103,9 @@ namespace CodeImp.DoomBuilder.Data // signature, and expects the stream to be long enough. private static bool CheckSignature(Stream data, int[] sig) { + //mxd. Rewind the data first + data.Seek(0, SeekOrigin.Begin); + // Go for all bytes foreach(int s in sig) { @@ -128,5 +116,22 @@ namespace CodeImp.DoomBuilder.Data // Signature matches return true; } + + //mxd. This tries to guess if a given image is in TGA format... + private static bool CheckTgaSignature(Stream data) + { + // Rewind the data first + data.Seek(0, SeekOrigin.Begin); + + byte idfieldlength = (byte)data.ReadByte(); // Can be 0 or the length of ID string, whatever that is + byte colormap = (byte)data.ReadByte(); // Can be 0 or 1 + byte imagetype = (byte)data.ReadByte(); // Can be 0, 1, 2, 3, 9, 10, 11 + data.Position += 13; // Skip some stuff... + byte bitsperpixel = (byte)data.ReadByte(); // Can be 8, 15, 16, 24, 32 + + // Check if data is valid... + return ((colormap == 0 || colormap == 1) && (imagetype < 4 || (imagetype > 8 && imagetype < 12)) && + (bitsperpixel == 8 || bitsperpixel == 15 || bitsperpixel == 16 || bitsperpixel == 24 || bitsperpixel == 32)); + } } } -- GitLab