mirror of
https://git.do.srb2.org/STJr/UltimateZoneBuilder.git
synced 2025-02-20 10:53:19 +00:00
Fixed the editor crashing/locking up when trying to read TEXTUREX patch containing invalid data.
This commit is contained in:
parent
3e132f1cf2
commit
8570922d0d
5 changed files with 42 additions and 116 deletions
|
@ -60,8 +60,8 @@ namespace CodeImp.DoomBuilder
|
|||
[DllImport("kernel32.dll", EntryPoint = "RtlZeroMemory", SetLastError = false)]
|
||||
internal static extern void ZeroMemory(IntPtr dest, int size);
|
||||
|
||||
[DllImport("kernel32.dll", EntryPoint = "RtlMoveMemory", SetLastError = false)]
|
||||
internal static extern unsafe void CopyMemory(void* dst, void* src, uint length);
|
||||
//[DllImport("kernel32.dll", EntryPoint = "RtlMoveMemory", SetLastError = false)]
|
||||
//internal static extern unsafe void CopyMemory(void* dst, void* src, uint length);
|
||||
|
||||
[DllImport("user32.dll", EntryPoint = "SendMessage", SetLastError = true, CallingConvention = CallingConvention.StdCall)]
|
||||
internal static extern int SendMessage(IntPtr hwnd, uint Msg, int wParam, int lParam);
|
||||
|
@ -2168,7 +2168,7 @@ namespace CodeImp.DoomBuilder
|
|||
try { WriteLogLine(exceptionmsg); } catch { }
|
||||
|
||||
// Try displaying it to the user...
|
||||
try { MessageBox.Show("Fatal Windows Forms Error", exceptionmsg, MessageBoxButtons.OK, MessageBoxIcon.Stop); }
|
||||
try { MessageBox.Show(exceptionmsg, "Fatal Windows Forms Error", MessageBoxButtons.OK, MessageBoxIcon.Stop); }
|
||||
finally { Process.GetCurrentProcess().Kill(); }
|
||||
}
|
||||
}
|
||||
|
@ -2202,7 +2202,7 @@ namespace CodeImp.DoomBuilder
|
|||
try { WriteLogLine(exceptionmsg); } catch {}
|
||||
|
||||
// Try displaying it to the user...
|
||||
try { MessageBox.Show("Fatal Windows Forms Error", exceptionmsg, MessageBoxButtons.OK, MessageBoxIcon.Stop); }
|
||||
try { MessageBox.Show(exceptionmsg, "Fatal Non-UI Error", MessageBoxButtons.OK, MessageBoxIcon.Stop); }
|
||||
finally { Process.GetCurrentProcess().Kill(); }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -83,7 +83,7 @@ namespace CodeImp.DoomBuilder.IO
|
|||
int width, height;
|
||||
|
||||
// Read pixel data
|
||||
PixelColorBlock pixeldata = ReadAsPixelData(stream, out width, out height);
|
||||
PixelColor[] pixeldata = ReadAsPixelData(stream, out width, out height);
|
||||
if(pixeldata != null)
|
||||
{
|
||||
try
|
||||
|
@ -93,8 +93,10 @@ namespace CodeImp.DoomBuilder.IO
|
|||
BitmapData bitmapdata = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
|
||||
PixelColor* targetdata = (PixelColor*)bitmapdata.Scan0.ToPointer();
|
||||
|
||||
// Copy the pixels
|
||||
General.CopyMemory(targetdata, pixeldata.Pointer, (uint)(width * height * sizeof(PixelColor)));
|
||||
//mxd. Copy the pixels
|
||||
int size = pixeldata.Length - 1;
|
||||
for(PixelColor* cp = targetdata + size; cp >= targetdata; cp--)
|
||||
*cp = pixeldata[size--];
|
||||
|
||||
// Done
|
||||
bmp.UnlockBits(bitmapdata);
|
||||
|
@ -151,7 +153,7 @@ namespace CodeImp.DoomBuilder.IO
|
|||
|
||||
// This creates pixel color data from the given data
|
||||
// Returns null on failure
|
||||
private unsafe PixelColorBlock ReadAsPixelData(Stream stream, out int width, out int height)
|
||||
private PixelColor[] ReadAsPixelData(Stream stream, out int width, out int height)
|
||||
{
|
||||
// Image will be 128x128
|
||||
width = 128;
|
||||
|
@ -163,8 +165,7 @@ namespace CodeImp.DoomBuilder.IO
|
|||
#endif
|
||||
|
||||
// Allocate memory
|
||||
PixelColorBlock pixeldata = new PixelColorBlock(width, height);
|
||||
pixeldata.Clear();
|
||||
PixelColor[] pixeldata = new PixelColor[width * height];
|
||||
|
||||
// Read flat bytes from stream
|
||||
byte[] bytes = new byte[width * height];
|
||||
|
@ -189,11 +190,11 @@ namespace CodeImp.DoomBuilder.IO
|
|||
|
||||
// We make the borders slightly brighter and darker
|
||||
if((py == 0) || (px == 0))
|
||||
pixeldata.Pointer[p] = bc1;
|
||||
pixeldata[p] = bc1;
|
||||
else if((py == 7) || (px == 7))
|
||||
pixeldata.Pointer[p] = bc2;
|
||||
pixeldata[p] = bc2;
|
||||
else
|
||||
pixeldata.Pointer[p] = bc;
|
||||
pixeldata[p] = bc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -83,7 +83,7 @@ namespace CodeImp.DoomBuilder.IO
|
|||
Bitmap bmp;
|
||||
|
||||
// Read pixel data
|
||||
PixelColorBlock pixeldata = ReadAsPixelData(stream, out width, out height);
|
||||
PixelColor[] pixeldata = ReadAsPixelData(stream, out width, out height);
|
||||
if(pixeldata != null)
|
||||
{
|
||||
try
|
||||
|
@ -93,8 +93,10 @@ namespace CodeImp.DoomBuilder.IO
|
|||
BitmapData bitmapdata = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
|
||||
PixelColor* targetdata = (PixelColor*)bitmapdata.Scan0.ToPointer();
|
||||
|
||||
// Copy the pixels
|
||||
General.CopyMemory(targetdata, pixeldata.Pointer, (uint)(width * height * sizeof(PixelColor)));
|
||||
//mxd. Copy the pixels
|
||||
int size = pixeldata.Length - 1;
|
||||
for(PixelColor* cp = targetdata + size; cp >= targetdata; cp--)
|
||||
*cp = pixeldata[size--];
|
||||
|
||||
// Done
|
||||
bmp.UnlockBits(bitmapdata);
|
||||
|
@ -153,7 +155,7 @@ namespace CodeImp.DoomBuilder.IO
|
|||
|
||||
// This creates pixel color data from the given data
|
||||
// Returns null on failure
|
||||
private PixelColorBlock ReadAsPixelData(Stream stream, out int width, out int height)
|
||||
private PixelColor[] ReadAsPixelData(Stream stream, out int width, out int height)
|
||||
{
|
||||
// Check if the flat is square
|
||||
float sqrlength = (float)Math.Sqrt(stream.Length);
|
||||
|
@ -187,15 +189,14 @@ namespace CodeImp.DoomBuilder.IO
|
|||
if((width <= 0) || (height <= 0)) return null;
|
||||
|
||||
// Allocate memory
|
||||
PixelColorBlock pixeldata = new PixelColorBlock(width, height);
|
||||
pixeldata.Clear();
|
||||
PixelColor[] pixeldata = new PixelColor[width * height];
|
||||
|
||||
// Read flat bytes from stream
|
||||
byte[] bytes = new byte[width * height];
|
||||
stream.Read(bytes, 0, width * height);
|
||||
|
||||
// Convert bytes with palette
|
||||
for(uint i = 0; i < width * height; i++) pixeldata.Pointer[i] = palette[bytes[i]];
|
||||
for(uint i = 0; i < width * height; i++) pixeldata[i] = palette[bytes[i]];
|
||||
|
||||
// Return pointer
|
||||
return pixeldata;
|
||||
|
|
|
@ -102,7 +102,7 @@ namespace CodeImp.DoomBuilder.IO
|
|||
Bitmap bmp;
|
||||
|
||||
// Read pixel data
|
||||
PixelColorBlock pixeldata = ReadAsPixelData(stream, out width, out height, out offsetx, out offsety);
|
||||
PixelColor[] pixeldata = ReadAsPixelData(stream, out width, out height, out offsetx, out offsety);
|
||||
if(pixeldata != null)
|
||||
{
|
||||
// Create bitmap and lock pixels
|
||||
|
@ -112,8 +112,10 @@ namespace CodeImp.DoomBuilder.IO
|
|||
BitmapData bitmapdata = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
|
||||
PixelColor* targetdata = (PixelColor*)bitmapdata.Scan0.ToPointer();
|
||||
|
||||
// Copy the pixels
|
||||
General.CopyMemory(targetdata, pixeldata.Pointer, (uint)(width * height * sizeof(PixelColor)));
|
||||
//mxd. Copy the pixels
|
||||
int size = pixeldata.Length - 1;
|
||||
for(PixelColor* cp = targetdata + size; cp >= targetdata; cp--)
|
||||
*cp = pixeldata[size--];
|
||||
|
||||
// Done
|
||||
bmp.UnlockBits(bitmapdata);
|
||||
|
@ -142,7 +144,7 @@ namespace CodeImp.DoomBuilder.IO
|
|||
int width, height, ox, oy;
|
||||
|
||||
// Read pixel data
|
||||
PixelColorBlock pixeldata = ReadAsPixelData(stream, out width, out height, out ox, out oy);
|
||||
PixelColor[] pixeldata = ReadAsPixelData(stream, out width, out height, out ox, out oy);
|
||||
if(pixeldata != null)
|
||||
{
|
||||
// Go for all source pixels
|
||||
|
@ -152,22 +154,26 @@ namespace CodeImp.DoomBuilder.IO
|
|||
for(oy = 0; oy < height; oy++)
|
||||
{
|
||||
// Copy this pixel?
|
||||
if(pixeldata.Pointer[oy * width + ox].a > 0.5f)
|
||||
if(pixeldata[oy * width + ox].a > 0.5f)
|
||||
{
|
||||
// Calculate target pixel and copy when within bounds
|
||||
int tx = x + ox;
|
||||
int ty = y + oy;
|
||||
if((tx >= 0) && (tx < targetwidth) && (ty >= 0) && (ty < targetheight))
|
||||
target[ty * targetwidth + tx] = pixeldata.Pointer[oy * width + ox];
|
||||
target[ty * targetwidth + tx] = pixeldata[oy * width + ox];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidDataException("Failed to read pixeldata"); //mxd. Let's throw exception on failure
|
||||
}
|
||||
}
|
||||
|
||||
// This creates pixel color data from the given data
|
||||
// Returns null on failure
|
||||
private PixelColorBlock ReadAsPixelData(Stream stream, out int width, out int height, out int offsetx, out int offsety)
|
||||
private PixelColor[] ReadAsPixelData(Stream stream, out int width, out int height, out int offsetx, out int offsety)
|
||||
{
|
||||
BinaryReader reader = new BinaryReader(stream);
|
||||
|
||||
|
@ -200,8 +206,7 @@ namespace CodeImp.DoomBuilder.IO
|
|||
for(int x = 0; x < width; x++) columns[x] = reader.ReadInt32();
|
||||
|
||||
// Allocate memory
|
||||
PixelColorBlock pixeldata = new PixelColorBlock(width, height);
|
||||
pixeldata.Clear();
|
||||
PixelColor[] pixeldata = new PixelColor[width * height];
|
||||
|
||||
// Go for all columns
|
||||
for(int x = 0; x < width; x++)
|
||||
|
@ -228,8 +233,12 @@ namespace CodeImp.DoomBuilder.IO
|
|||
// Read pixel color index
|
||||
int p = reader.ReadByte();
|
||||
|
||||
//mxd. Sanity check required...
|
||||
int offset = (y + yo) * width + x;
|
||||
if(offset > pixeldata.Length - 1) return null;
|
||||
|
||||
// Draw pixel
|
||||
pixeldata.Pointer[(y + yo) * width + x] = palette[p];
|
||||
pixeldata[offset] = palette[p];
|
||||
}
|
||||
|
||||
// Skip unused pixel
|
||||
|
@ -237,7 +246,7 @@ namespace CodeImp.DoomBuilder.IO
|
|||
|
||||
// Read next post start
|
||||
read_y = reader.ReadByte();
|
||||
if(read_y < y || (height > 255 && read_y == y)) y += read_y; else y = read_y; //mxd. Fix for tall patches higher than 508 pixels
|
||||
if(read_y < y || (height > 256 && read_y == y)) y += read_y; else y = read_y; //mxd. Fix for tall patches higher than 508 pixels
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,85 +0,0 @@
|
|||
|
||||
#region ================== Copyright (c) 2007 Pascal vd Heiden
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Pascal vd Heiden, www.codeimp.com
|
||||
* This program is released under GNU General Public License
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Namespaces
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace CodeImp.DoomBuilder.Rendering
|
||||
{
|
||||
public unsafe class PixelColorBlock
|
||||
{
|
||||
#region ================== Variables
|
||||
|
||||
private int width;
|
||||
private int height;
|
||||
private int memorysize;
|
||||
private PixelColor* memory;
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Properties
|
||||
|
||||
public int Width { get { return width; } }
|
||||
public int Height { get { return height; } }
|
||||
public int Length { get { return memorysize; } }
|
||||
public PixelColor this[int index] { get { return memory[index]; } set { memory[index] = value; } }
|
||||
public PixelColor* Pointer { get { return memory; } }
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Constructor / Destructor
|
||||
|
||||
// Constructor
|
||||
public PixelColorBlock(int width, int height)
|
||||
{
|
||||
// Check input
|
||||
if((width <= 0) || (height <= 0)) throw new ArgumentException("Cannot allocate a memory block of zero size!");
|
||||
|
||||
// Initialize
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.memorysize = width * height * sizeof(PixelColor);
|
||||
this.memory = (PixelColor*)Marshal.AllocCoTaskMem(memorysize);
|
||||
if(this.memory == (PixelColor*)0) throw new OutOfMemoryException();
|
||||
GC.AddMemoryPressure(memorysize);
|
||||
}
|
||||
|
||||
// Destructor
|
||||
~PixelColorBlock()
|
||||
{
|
||||
// Terminate
|
||||
Marshal.FreeCoTaskMem(new IntPtr(memory));
|
||||
GC.RemoveMemoryPressure(memorysize);
|
||||
memorysize = 0;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Methods
|
||||
|
||||
// This clears the memory black
|
||||
public void Clear()
|
||||
{
|
||||
if(memorysize > 0) General.ZeroMemory(new IntPtr(memory), memorysize);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue