/// <summary>
/// The decode dds.
/// </summary>
/// <param name="sourceBytes">The source bytes.</param>
/// <param name="b2">The b 2.</param>
/// <returns></returns>
/// <remarks></remarks>
public static Bitmap DecodeDDS(byte[] sourceBytes, ParsedBitmap.BitmapInfo b2)
{
////
//// Check type name and handle 2D, 3D & Cubemaps
////
// b2.typename;
////
byte[] poo = new byte[0];
IntPtr ptr = new IntPtr();
PixelFormat o = new PixelFormat();
int poolength;
byte[] fu;
DecodeDXT decode = new DecodeDXT();
int oldwidth = b2.width;
if (b2.width % 16 != 0)
b2.width = (ushort)(b2.width + (16 - (b2.width % 16)));
int stride = b2.width;
if (b2.swizzle)
{
sourceBytes = Swizzler.Swizzle(sourceBytes, b2.width, b2.height, b2.depth, b2.bitsPerPixel, true);
}
switch (b2.formatname)
{
#region DXT1
case (ParsedBitmap.BitmapFormat)14:
if (b2.swizzle)
{
MessageBox.Show("Swizzled");
}
sourceBytes = decode.DecodeDXT1(b2.height, b2.width, sourceBytes);
stride *= 4;
o = PixelFormat.Format32bppArgb;
break;
#endregion
#region DXT2/3
case (ParsedBitmap.BitmapFormat)15:
if (b2.swizzle)
{
MessageBox.Show("Swizzled");
}
sourceBytes = decode.DecodeDXT23(b2.height, b2.width, sourceBytes);
stride *= 4;
o = PixelFormat.Format32bppArgb;
break;
#endregion
#region DXT 4/5
case (ParsedBitmap.BitmapFormat)16:
if (b2.swizzle)
{
MessageBox.Show("Swizzled");
}
sourceBytes = decode.DecodeDXT45(b2.height, b2.width, sourceBytes);
stride *= 4;
o = PixelFormat.Format32bppArgb;
break;
#endregion
#region A8R8G8B8
case (ParsedBitmap.BitmapFormat)11:
stride *= 4;
o = PixelFormat.Format32bppArgb;
break;
#endregion
#region X8R8G8B8
case (ParsedBitmap.BitmapFormat)10:
stride *= 4;
o = PixelFormat.Format32bppArgb;
break;
#endregion
#region // 16 bit \\
#region A4R4G4B4
case (ParsedBitmap.BitmapFormat)9:
stride *= 4;
o = PixelFormat.Format32bppArgb;
poolength = sourceBytes.Length;
fu = new byte[poolength * 2];
for (int e = 0; e < poolength / 2; e++)
{
int r = e * 2;
fu[r * 2 + 0] = (byte)((sourceBytes[r + 1] & 0xFF) >> 0); // Blue
fu[r * 2 + 1] = (byte)((sourceBytes[r + 0] & 0xFF) >> 0); // Green
fu[r * 2 + 2] = (byte)((sourceBytes[r + 0] & 0xFF) >> 0); // Red
fu[r * 2 + 3] = 255; // (byte)(((sourceBytes[r + 1] & 0xFF) >> 0)); // Alpha
}
sourceBytes = fu;
break;
#endregion
#region G8B8
case (ParsedBitmap.BitmapFormat)22:
stride *= 4;
o = PixelFormat.Format32bppArgb;
poolength = sourceBytes.Length;
fu = new byte[poolength / 2 * 4];
// These are actually signed (+/-128), so convert to unsigned
for (int e = 0; e < poolength / 2; e++)
{
int r = e * 2;
fu[r * 2 + 0] = (byte)(sourceBytes[r + 1] + 128); // Blue
fu[r * 2 + 1] = (byte)(sourceBytes[r + 1] + 128); // Green
fu[r * 2 + 2] = (byte)(sourceBytes[r + 0] + 128); // Red
fu[r * 2 + 3] = (byte)(sourceBytes[r + 0] + 128); // Alpha
}
sourceBytes = fu;
break;
#endregion
#region A1R5G5B5
case (ParsedBitmap.BitmapFormat)8:
stride *= 2;
o = PixelFormat.Format16bppRgb555;
break;
#endregion
#region R5G6B5
case (ParsedBitmap.BitmapFormat)6:
stride *= 2;
o = PixelFormat.Format16bppRgb565;
break;
#endregion
#region A8Y8
case (ParsedBitmap.BitmapFormat)3:
o = PixelFormat.Format32bppArgb;
poolength = sourceBytes.Length;
fu = new byte[poolength / 2 * 4];
for (int e = 0; e < poolength / 2; e++)
{
int r = e * 2;
fu[r * 2 + 0] = sourceBytes[r + 1];
fu[r * 2 + 1] = sourceBytes[r + 1];
fu[r * 2 + 2] = sourceBytes[r + 1];
fu[r * 2 + 3] = sourceBytes[r + 0];
}
sourceBytes = fu;
stride *= 4;
break;
#endregion
#endregion
#region // 8 bit \\
#region P8
case ParsedBitmap.BitmapFormat.BITM_FORMAT_P8:
o = PixelFormat.Format32bppArgb;
poolength = sourceBytes.Length;
fu = new byte[poolength * 4];
for (int e = 0; e < poolength; e++)
{
int r = e * 4;
fu[r + 0] = sourceBytes[e];
fu[r + 1] = sourceBytes[e];
fu[r + 2] = sourceBytes[e];
fu[r + 3] = 255;
}
sourceBytes = fu;
stride *= 4;
break;
#endregion
#region A8
case ParsedBitmap.BitmapFormat.BITM_FORMAT_A8:
o = PixelFormat.Format32bppArgb;
poolength = sourceBytes.Length;
fu = new byte[poolength * 4];
for (int e = 0; e < poolength; e++)
{
int r = e * 4;
fu[r + 0] = sourceBytes[e];
fu[r + 1] = sourceBytes[e];
fu[r + 2] = sourceBytes[e];
fu[r + 3] = 255;
}
sourceBytes = fu;
stride *= 4;
break;
#endregion
#region AY8
case ParsedBitmap.BitmapFormat.BITM_FORMAT_AY8:
o = PixelFormat.Format32bppArgb;
poolength = sourceBytes.Length;
fu = new byte[poolength * 4];
for (int e = 0; e < poolength; e++)
{
int r = e * 4;
/*
fu[r + 0] = (byte)((sourceBytes[e] & 0x0F) * 255 / 15 + 128);
fu[r + 1] = (byte)((sourceBytes[e] & 0x0F) * 255 / 15 + 128);
fu[r + 2] = (byte)((sourceBytes[e] & 0x0F) * 255 / 15 + 128);
*/
fu[r + 0] = (byte)(((sourceBytes[e] & 0xF0) >> 4) * 255 / 15);
fu[r + 1] = (byte)(((sourceBytes[e] & 0xF0) >> 4) * 255 / 15);
fu[r + 2] = (byte)(((sourceBytes[e] & 0xF0) >> 4) * 255 / 15);
fu[r + 3] = (byte)((sourceBytes[e] & 0x0F) * 255 / 15);
/*
fu[r + 0] = (byte)((sourceBytes[e] & 0x0F) * 255 / 15);
fu[r + 1] = (byte)((sourceBytes[e] & 0x0F) * 255 / 15);
fu[r + 2] = (byte)((sourceBytes[e] & 0x0F) * 255 / 15);
fu[r + 3] = (byte)(((sourceBytes[e] & 0xF0) >> 3) * 255 / 15);
if (sourceBytes[e] == 0)
fu[r + 3] = 0;
else
fu[r + 3] = 255;
*/
}
sourceBytes = fu;
stride *= 4;
break;
#endregion
#region Y8
case (ParsedBitmap.BitmapFormat)1:
o = PixelFormat.Format32bppArgb;
poolength = sourceBytes.Length;
fu = new byte[poolength * 4];
for (int e = 0; e < poolength; e++)
{
int r = e * 4;
fu[r + 0] = sourceBytes[e];
fu[r + 1] = sourceBytes[e];
fu[r + 2] = sourceBytes[e];
fu[r + 3] = 255;
}
sourceBytes = fu;
stride *= 4;
break;
#endregion
/*
#region LightMap
case ParsedBitmap.BitmapFormat.BITM_FORMAT_LIGHTMAP:
o = PixelFormat.Format32bppArgb;// Format32bppArgb;
poolength = sourceBytes.Length;
fu = new byte[poolength * 4];
int bspnumber = ident;
int paletteindex = -1;
if (visualchunkindex < 0)
{
int wtf = 0 - (visualchunkindex + 1);
paletteindex = map.BSP.sbsp[bspnumber].SceneryChunk_LightMap_Index[wtf];
}
if (paletteindex == -1)
for (int i = 0; i < map.BSP.sbsp[bspnumber].VisualChunk_Bitmap_Index.Length; i++)
if (map.BSP.sbsp[bspnumber].VisualChunk_Bitmap_Index[i] == visualchunkindex)
{
paletteindex = map.BSP.sbsp[bspnumber].VisualChunk_LightMap_Index[visualchunkindex];
break;
}
if (paletteindex == -1)
for (int i = 0; i < map.BSP.sbsp[bspnumber].SceneryChunk_Bitmap_Index.Length; i++)
if (map.BSP.sbsp[bspnumber].SceneryChunk_Bitmap_Index[i] == visualchunkindex)
{
paletteindex = map.BSP.sbsp[bspnumber].SceneryChunk_LightMap_Index[i];
break;
}
if (paletteindex == 255) return null;
for (int e = 0; e < poolength; e++)
{
int r = e * 4;
fu[r + 0] = (byte)map.BSP.sbsp[bspnumber].LightMap_Palettes[paletteindex][sourceBytes[e]].r;
fu[r + 1] = (byte)map.BSP.sbsp[bspnumber].LightMap_Palettes[paletteindex][sourceBytes[e]].g;
fu[r + 2] = (byte)map.BSP.sbsp[bspnumber].LightMap_Palettes[paletteindex][sourceBytes[e]].b;
fu[r + 3] = (byte)map.BSP.sbsp[bspnumber].LightMap_Palettes[paletteindex][sourceBytes[e]].a;
}
sourceBytes = fu;
stride *= 4;
break;
#endregion
*/
#endregion
default:
return null;
}
Marshal.FreeHGlobal(ptr);
ptr = Marshal.AllocHGlobal(sourceBytes.Length);
RtlMoveMemory(ptr, sourceBytes, sourceBytes.Length);
return new Bitmap(b2.width, b2.height, stride, o, ptr);
}