mirror of
https://git.do.srb2.org/STJr/UltimateZoneBuilder.git
synced 2025-02-21 11:20:58 +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)]
|
[DllImport("kernel32.dll", EntryPoint = "RtlZeroMemory", SetLastError = false)]
|
||||||
internal static extern void ZeroMemory(IntPtr dest, int size);
|
internal static extern void ZeroMemory(IntPtr dest, int size);
|
||||||
|
|
||||||
[DllImport("kernel32.dll", EntryPoint = "RtlMoveMemory", SetLastError = false)]
|
//[DllImport("kernel32.dll", EntryPoint = "RtlMoveMemory", SetLastError = false)]
|
||||||
internal static extern unsafe void CopyMemory(void* dst, void* src, uint length);
|
//internal static extern unsafe void CopyMemory(void* dst, void* src, uint length);
|
||||||
|
|
||||||
[DllImport("user32.dll", EntryPoint = "SendMessage", SetLastError = true, CallingConvention = CallingConvention.StdCall)]
|
[DllImport("user32.dll", EntryPoint = "SendMessage", SetLastError = true, CallingConvention = CallingConvention.StdCall)]
|
||||||
internal static extern int SendMessage(IntPtr hwnd, uint Msg, int wParam, int lParam);
|
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 { WriteLogLine(exceptionmsg); } catch { }
|
||||||
|
|
||||||
// Try displaying it to the user...
|
// 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(); }
|
finally { Process.GetCurrentProcess().Kill(); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2202,7 +2202,7 @@ namespace CodeImp.DoomBuilder
|
||||||
try { WriteLogLine(exceptionmsg); } catch {}
|
try { WriteLogLine(exceptionmsg); } catch {}
|
||||||
|
|
||||||
// Try displaying it to the user...
|
// 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(); }
|
finally { Process.GetCurrentProcess().Kill(); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,7 +83,7 @@ namespace CodeImp.DoomBuilder.IO
|
||||||
int width, height;
|
int width, height;
|
||||||
|
|
||||||
// Read pixel data
|
// Read pixel data
|
||||||
PixelColorBlock pixeldata = ReadAsPixelData(stream, out width, out height);
|
PixelColor[] pixeldata = ReadAsPixelData(stream, out width, out height);
|
||||||
if(pixeldata != null)
|
if(pixeldata != null)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -93,8 +93,10 @@ namespace CodeImp.DoomBuilder.IO
|
||||||
BitmapData bitmapdata = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
|
BitmapData bitmapdata = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
|
||||||
PixelColor* targetdata = (PixelColor*)bitmapdata.Scan0.ToPointer();
|
PixelColor* targetdata = (PixelColor*)bitmapdata.Scan0.ToPointer();
|
||||||
|
|
||||||
// Copy the pixels
|
//mxd. Copy the pixels
|
||||||
General.CopyMemory(targetdata, pixeldata.Pointer, (uint)(width * height * sizeof(PixelColor)));
|
int size = pixeldata.Length - 1;
|
||||||
|
for(PixelColor* cp = targetdata + size; cp >= targetdata; cp--)
|
||||||
|
*cp = pixeldata[size--];
|
||||||
|
|
||||||
// Done
|
// Done
|
||||||
bmp.UnlockBits(bitmapdata);
|
bmp.UnlockBits(bitmapdata);
|
||||||
|
@ -151,7 +153,7 @@ namespace CodeImp.DoomBuilder.IO
|
||||||
|
|
||||||
// This creates pixel color data from the given data
|
// This creates pixel color data from the given data
|
||||||
// Returns null on failure
|
// 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
|
// Image will be 128x128
|
||||||
width = 128;
|
width = 128;
|
||||||
|
@ -163,8 +165,7 @@ namespace CodeImp.DoomBuilder.IO
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Allocate memory
|
// Allocate memory
|
||||||
PixelColorBlock pixeldata = new PixelColorBlock(width, height);
|
PixelColor[] pixeldata = new PixelColor[width * height];
|
||||||
pixeldata.Clear();
|
|
||||||
|
|
||||||
// Read flat bytes from stream
|
// Read flat bytes from stream
|
||||||
byte[] bytes = new byte[width * height];
|
byte[] bytes = new byte[width * height];
|
||||||
|
@ -189,11 +190,11 @@ namespace CodeImp.DoomBuilder.IO
|
||||||
|
|
||||||
// We make the borders slightly brighter and darker
|
// We make the borders slightly brighter and darker
|
||||||
if((py == 0) || (px == 0))
|
if((py == 0) || (px == 0))
|
||||||
pixeldata.Pointer[p] = bc1;
|
pixeldata[p] = bc1;
|
||||||
else if((py == 7) || (px == 7))
|
else if((py == 7) || (px == 7))
|
||||||
pixeldata.Pointer[p] = bc2;
|
pixeldata[p] = bc2;
|
||||||
else
|
else
|
||||||
pixeldata.Pointer[p] = bc;
|
pixeldata[p] = bc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,7 +83,7 @@ namespace CodeImp.DoomBuilder.IO
|
||||||
Bitmap bmp;
|
Bitmap bmp;
|
||||||
|
|
||||||
// Read pixel data
|
// Read pixel data
|
||||||
PixelColorBlock pixeldata = ReadAsPixelData(stream, out width, out height);
|
PixelColor[] pixeldata = ReadAsPixelData(stream, out width, out height);
|
||||||
if(pixeldata != null)
|
if(pixeldata != null)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -93,8 +93,10 @@ namespace CodeImp.DoomBuilder.IO
|
||||||
BitmapData bitmapdata = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
|
BitmapData bitmapdata = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
|
||||||
PixelColor* targetdata = (PixelColor*)bitmapdata.Scan0.ToPointer();
|
PixelColor* targetdata = (PixelColor*)bitmapdata.Scan0.ToPointer();
|
||||||
|
|
||||||
// Copy the pixels
|
//mxd. Copy the pixels
|
||||||
General.CopyMemory(targetdata, pixeldata.Pointer, (uint)(width * height * sizeof(PixelColor)));
|
int size = pixeldata.Length - 1;
|
||||||
|
for(PixelColor* cp = targetdata + size; cp >= targetdata; cp--)
|
||||||
|
*cp = pixeldata[size--];
|
||||||
|
|
||||||
// Done
|
// Done
|
||||||
bmp.UnlockBits(bitmapdata);
|
bmp.UnlockBits(bitmapdata);
|
||||||
|
@ -153,7 +155,7 @@ namespace CodeImp.DoomBuilder.IO
|
||||||
|
|
||||||
// This creates pixel color data from the given data
|
// This creates pixel color data from the given data
|
||||||
// Returns null on failure
|
// 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
|
// Check if the flat is square
|
||||||
float sqrlength = (float)Math.Sqrt(stream.Length);
|
float sqrlength = (float)Math.Sqrt(stream.Length);
|
||||||
|
@ -187,15 +189,14 @@ namespace CodeImp.DoomBuilder.IO
|
||||||
if((width <= 0) || (height <= 0)) return null;
|
if((width <= 0) || (height <= 0)) return null;
|
||||||
|
|
||||||
// Allocate memory
|
// Allocate memory
|
||||||
PixelColorBlock pixeldata = new PixelColorBlock(width, height);
|
PixelColor[] pixeldata = new PixelColor[width * height];
|
||||||
pixeldata.Clear();
|
|
||||||
|
|
||||||
// Read flat bytes from stream
|
// Read flat bytes from stream
|
||||||
byte[] bytes = new byte[width * height];
|
byte[] bytes = new byte[width * height];
|
||||||
stream.Read(bytes, 0, width * height);
|
stream.Read(bytes, 0, width * height);
|
||||||
|
|
||||||
// Convert bytes with palette
|
// 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 pointer
|
||||||
return pixeldata;
|
return pixeldata;
|
||||||
|
|
|
@ -102,7 +102,7 @@ namespace CodeImp.DoomBuilder.IO
|
||||||
Bitmap bmp;
|
Bitmap bmp;
|
||||||
|
|
||||||
// Read pixel data
|
// 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)
|
if(pixeldata != null)
|
||||||
{
|
{
|
||||||
// Create bitmap and lock pixels
|
// 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);
|
BitmapData bitmapdata = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
|
||||||
PixelColor* targetdata = (PixelColor*)bitmapdata.Scan0.ToPointer();
|
PixelColor* targetdata = (PixelColor*)bitmapdata.Scan0.ToPointer();
|
||||||
|
|
||||||
// Copy the pixels
|
//mxd. Copy the pixels
|
||||||
General.CopyMemory(targetdata, pixeldata.Pointer, (uint)(width * height * sizeof(PixelColor)));
|
int size = pixeldata.Length - 1;
|
||||||
|
for(PixelColor* cp = targetdata + size; cp >= targetdata; cp--)
|
||||||
|
*cp = pixeldata[size--];
|
||||||
|
|
||||||
// Done
|
// Done
|
||||||
bmp.UnlockBits(bitmapdata);
|
bmp.UnlockBits(bitmapdata);
|
||||||
|
@ -142,7 +144,7 @@ namespace CodeImp.DoomBuilder.IO
|
||||||
int width, height, ox, oy;
|
int width, height, ox, oy;
|
||||||
|
|
||||||
// Read pixel data
|
// 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)
|
if(pixeldata != null)
|
||||||
{
|
{
|
||||||
// Go for all source pixels
|
// Go for all source pixels
|
||||||
|
@ -152,22 +154,26 @@ namespace CodeImp.DoomBuilder.IO
|
||||||
for(oy = 0; oy < height; oy++)
|
for(oy = 0; oy < height; oy++)
|
||||||
{
|
{
|
||||||
// Copy this pixel?
|
// 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
|
// Calculate target pixel and copy when within bounds
|
||||||
int tx = x + ox;
|
int tx = x + ox;
|
||||||
int ty = y + oy;
|
int ty = y + oy;
|
||||||
if((tx >= 0) && (tx < targetwidth) && (ty >= 0) && (ty < targetheight))
|
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
|
// This creates pixel color data from the given data
|
||||||
// Returns null on failure
|
// 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);
|
BinaryReader reader = new BinaryReader(stream);
|
||||||
|
|
||||||
|
@ -200,8 +206,7 @@ namespace CodeImp.DoomBuilder.IO
|
||||||
for(int x = 0; x < width; x++) columns[x] = reader.ReadInt32();
|
for(int x = 0; x < width; x++) columns[x] = reader.ReadInt32();
|
||||||
|
|
||||||
// Allocate memory
|
// Allocate memory
|
||||||
PixelColorBlock pixeldata = new PixelColorBlock(width, height);
|
PixelColor[] pixeldata = new PixelColor[width * height];
|
||||||
pixeldata.Clear();
|
|
||||||
|
|
||||||
// Go for all columns
|
// Go for all columns
|
||||||
for(int x = 0; x < width; x++)
|
for(int x = 0; x < width; x++)
|
||||||
|
@ -228,8 +233,12 @@ namespace CodeImp.DoomBuilder.IO
|
||||||
// Read pixel color index
|
// Read pixel color index
|
||||||
int p = reader.ReadByte();
|
int p = reader.ReadByte();
|
||||||
|
|
||||||
|
//mxd. Sanity check required...
|
||||||
|
int offset = (y + yo) * width + x;
|
||||||
|
if(offset > pixeldata.Length - 1) return null;
|
||||||
|
|
||||||
// Draw pixel
|
// Draw pixel
|
||||||
pixeldata.Pointer[(y + yo) * width + x] = palette[p];
|
pixeldata[offset] = palette[p];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Skip unused pixel
|
// Skip unused pixel
|
||||||
|
@ -237,7 +246,7 @@ namespace CodeImp.DoomBuilder.IO
|
||||||
|
|
||||||
// Read next post start
|
// Read next post start
|
||||||
read_y = reader.ReadByte();
|
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