internal static Bitmap Parse(BinaryReader reader, ImageHeader header, bool ignoreAlpha = false) { var Result = new Bitmap(header.Width, header.Height, PixelFormat.Format32bppArgb); try { var Raw = Result.LockBits(new Rectangle(0, 0, Result.Width, Result.Height), ImageLockMode.WriteOnly, Result.PixelFormat); var PixelCount = header.Height * header.Width; unsafe { var Buffer = (byte*)Raw.Scan0; Color[] Palette = null; byte[] BitFields = null; bool EightCount = header.BitCount == 8; if (EightCount) { // 8-bit, with palette Palette = new Color[256]; for (var i = 0; i < 256; ++i) { Palette[i] = ReadColor(reader, 32); } BitFields = reader.ReadBytes(PixelCount); } for (var Pixel = 0; Pixel < PixelCount; ++Pixel) { var Color = EightCount ? Palette[BitFields[Pixel]] : ReadColor(reader, header.BitCount); Buffer[4 * Pixel + 0] = Color.B; Buffer[4 * Pixel + 1] = Color.G; Buffer[4 * Pixel + 2] = Color.R; Buffer[4 * Pixel + 3] = ignoreAlpha ? (byte)255 : Color.A; } } Result.UnlockBits(Raw); Result.RotateFlip(RotateFlipType.RotateNoneFlipY); } catch { Result.Dispose(); throw; } return Result; }
internal static Bitmap Parse(BinaryReader reader, ImageHeader header, bool ignoreAlpha = false) { var Format = (header.Type == ImageType.DXT2 || header.Type == ImageType.DXT4) ? PixelFormat.Format32bppPArgb : PixelFormat.Format32bppArgb; var Result = new Bitmap(header.Width, header.Height, Format); try { var Raw = Result.LockBits(new Rectangle(0, 0, Result.Width, Result.Height), ImageLockMode.WriteOnly, Result.PixelFormat); var TexelBlockCount = (header.Width * header.Height) / (4 * 4); unsafe { var Buffer = (byte*)Raw.Scan0; for (var Texel = 0; Texel < TexelBlockCount; ++Texel) { var TexelBlock = ReadTexelBlock(reader, header.Type); var PixelOffsetX = 4 * (Texel % (header.Width / 4)); var PixelOffsetY = 4 * (Texel / (header.Width / 4)) * (Raw.Stride / 4); var Index = 4 * (PixelOffsetX + PixelOffsetY); for (var Y = 0; Y < 4; ++Y, Index += Raw.Stride - 16) { for (var X = 0; X < 4; ++X, Index += 4) { var Lookup = X + 4 * Y; Buffer[Index + 0] = TexelBlock[Lookup].B; Buffer[Index + 1] = TexelBlock[Lookup].G; Buffer[Index + 2] = TexelBlock[Lookup].R; Buffer[Index + 3] = ignoreAlpha ? (byte)255 : TexelBlock[Lookup].A; } } } } Result.UnlockBits(Raw); } catch { Result.Dispose(); throw; } return Result; }