UltimateZoneBuilder/Source/Core/Data/ImageDataFormat.cs
2012-06-03 23:36:53 +00:00

142 lines
4.8 KiB
C#

#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.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
using System.IO;
using System.Drawing.Imaging;
using CodeImp.DoomBuilder.IO;
#endregion
namespace CodeImp.DoomBuilder.Data
{
internal static class ImageDataFormat
{
// Input guess formats
public const int UNKNOWN = 0; // No clue.
public const int DOOMPICTURE = 1; // Could be Doom Picture format (column list rendered data)
public const int DOOMFLAT = 2; // Could be Doom Flat format (raw 8-bit pixel data)
public const int DOOMCOLORMAP = 3; // Could be Doom Colormap format (raw 8-bit pixel palette mapping)
// File format signatures
private static readonly int[] PNG_SIGNATURE = new int[] { 137, 80, 78, 71, 13, 10, 26, 10 };
private static readonly int[] GIF_SIGNATURE = new int[] { 71, 73, 70 };
private static readonly int[] BMP_SIGNATURE = new int[] { 66, 77 };
private static readonly int[] DDS_SIGNATURE = new int[] { 68, 68, 83, 32 };
//mxd
private static readonly int[] PCX_SIGNATURE = new int[] { 10, 5, 1, 8 };
//char Manufacturer; // 10 = ZSoft .PCX
//char Version; // 0 = Version 2.5
// 2 = Version 2.8 with palette info
// 3 = Version 2.8 without palette info
// 5 = Version 3.0
//char Encoding; // 1 = .PCX encoding
//char BitsPerLayer; // bpp
// This check image data and returns the appropriate image reader
public static IImageReader GetImageReader(Stream data, int guessformat, Playpal palette)
{
BinaryReader bindata = new BinaryReader(data);
DoomPictureReader picreader;
DoomFlatReader flatreader;
DoomColormapReader colormapreader;
// First check the formats that provide the means to 'ensure' that
// it actually is that format. Then guess the Doom image format.
// Data long enough to check for signatures?
if(data.Length > 10)
{
// Check for PNG signature
data.Seek(0, SeekOrigin.Begin);
if(CheckSignature(data, PNG_SIGNATURE)) return new FileImageReader();
// Check for DDS signature
data.Seek(0, SeekOrigin.Begin);
if(CheckSignature(data, DDS_SIGNATURE)) return new FileImageReader();
// Check for GIF signature
data.Seek(0, SeekOrigin.Begin);
if(CheckSignature(data, GIF_SIGNATURE)) return new FileImageReader();
//mxd. Check for PCX signature
data.Seek(0, SeekOrigin.Begin);
if (CheckSignature(data, PCX_SIGNATURE)) return new FileImageReader();
// Check for BMP signature
data.Seek(0, SeekOrigin.Begin);
if(CheckSignature(data, BMP_SIGNATURE))
{
// Check if data size matches the size specified in the data
if(bindata.ReadUInt32() <= data.Length) return new FileImageReader();
}
}
// Could it be a doom picture?
if(guessformat == DOOMPICTURE)
{
// Check if data is valid for a doom picture
data.Seek(0, SeekOrigin.Begin);
picreader = new DoomPictureReader(palette);
if(picreader.Validate(data)) return picreader;
}
// Could it be a doom flat?
else if(guessformat == DOOMFLAT)
{
// Check if data is valid for a doom flat
data.Seek(0, SeekOrigin.Begin);
flatreader = new DoomFlatReader(palette);
if(flatreader.Validate(data)) return flatreader;
}
// Could it be a doom colormap?
else if(guessformat == DOOMCOLORMAP)
{
// Check if data is valid for a doom colormap
data.Seek(0, SeekOrigin.Begin);
colormapreader = new DoomColormapReader(palette);
if(colormapreader.Validate(data)) return colormapreader;
}
// Format not supported
return new UnknownImageReader();
}
// This checks a signature as byte array
// NOTE: Expects the stream position to be at the start of the
// signature, and expects the stream to be long enough.
private static bool CheckSignature(Stream data, int[] sig)
{
int b;
// Go for all bytes
for(int i = 0; i < sig.Length; i++)
{
// When byte doesnt match the signature, leave
b = data.ReadByte();
if(b != sig[i]) return false;
}
// Signature matches
return true;
}
}
}