private static Bitmap ExportTextureIndexed(Peg.Texture texture, byte[] bytes, bool oneBitAlpha) { var bitmap = new Bitmap(texture.Width, texture.Height, PixelFormat.Format8bppIndexed); var palette = bitmap.Palette; int dataOffset; switch (texture.FormatArgument) { case 1: { for (int i = 0, o = 0; i < 256; i++, o += 2) { var r = (bytes[o + 0] & 0x1F) << 3; var g = (((bytes[o + 0] & 0xE0) >> 5) | ((bytes[o + 1] & 0x03) << 3)) << 3; var b = (bytes[o + 1] & 0x7C) << 1; var a = (bytes[o + 1] & 0x80) != 0 ? 0xFF : 0x00; palette.Entries[MungePaletteIndex(i)] = Color.FromArgb(a, r, g, b); } dataOffset = 512; break; } case 2: { for (int i = 0, o = 0; i < 256; i++, o += 4) { palette.Entries[MungePaletteIndex(i)] = Color.FromArgb( oneBitAlpha == false ? bytes[o + 3] : bytes[o + 3] != 0 ? 0xFF : 0, bytes[o + 0], bytes[o + 1], bytes[o + 2]); } dataOffset = 1024; break; } default: { throw new NotSupportedException(); } } bitmap.Palette = palette; var area = new Rectangle(0, 0, bitmap.Width, bitmap.Height); var bitmapData = bitmap.LockBits(area, ImageLockMode.WriteOnly, bitmap.PixelFormat); var scan = bitmapData.Scan0; var pitch = texture.Width; for (int y = 0; y < bitmap.Height; y++) { Marshal.Copy(bytes, dataOffset, scan, pitch); scan += bitmapData.Stride; dataOffset += pitch; } bitmap.UnlockBits(bitmapData); return(bitmap); }
private static Bitmap ExportTextureA8R8G8B8(Peg.Texture texture, byte[] bytes, bool oneBitAlpha) { var swappedBytes = new byte[bytes.Length]; for (int i = 0; i < bytes.Length; i += 4) { swappedBytes[i + 0] = bytes[i + 2]; swappedBytes[i + 1] = bytes[i + 1]; swappedBytes[i + 2] = bytes[i + 0]; swappedBytes[i + 3] = oneBitAlpha == false ? bytes[i + 3] : (byte)(bytes[i + 3] != 0 ? 0xFF : 0); } var bitmap = new Bitmap(texture.Width, texture.Height, PixelFormat.Format32bppArgb); var area = new Rectangle(0, 0, bitmap.Width, bitmap.Height); var bitmapData = bitmap.LockBits(area, ImageLockMode.WriteOnly, bitmap.PixelFormat); var scan = bitmapData.Scan0; int dataOffset = 0; var pitch = bitmap.Width * 4; for (int y = 0; y < bitmap.Height; y++) { Marshal.Copy(swappedBytes, dataOffset, scan, pitch); scan += bitmapData.Stride; dataOffset += pitch; } bitmap.UnlockBits(bitmapData); return(bitmap); }
private static Bitmap ExportTextureA1R5G5B5(Peg.Texture texture, byte[] bytes) { var swappedBytes = new byte[bytes.Length]; for (int i = 0; i < bytes.Length; i += 2) { // rrrrrggg ggbbbbba -> bbbbbggg ggrrrrra var r = (byte)(bytes[i + 0] & 0x1F); var b = (byte)((bytes[i + 1] & 0x7C) >> 2); swappedBytes[i + 0] = bytes[i + 0]; swappedBytes[i + 0] &= 0xE0; swappedBytes[i + 0] |= b; swappedBytes[i + 1] = bytes[i + 1]; swappedBytes[i + 1] &= 0x83; swappedBytes[i + 1] |= (byte)(r << 2); } var bitmap = new Bitmap(texture.Width, texture.Height, PixelFormat.Format16bppArgb1555); var area = new Rectangle(0, 0, bitmap.Width, bitmap.Height); var bitmapData = bitmap.LockBits(area, ImageLockMode.WriteOnly, bitmap.PixelFormat); var scan = bitmapData.Scan0; int dataOffset = 0; var pitch = bitmap.Width * 2; for (int y = 0; y < bitmap.Height; y++) { Marshal.Copy(swappedBytes, dataOffset, scan, pitch); scan += bitmapData.Stride; dataOffset += pitch; } bitmap.UnlockBits(bitmapData); return(bitmap); }
private static Bitmap ExportTexture(Peg.Texture texture, byte[] bytes, bool oneBitAlpha) { switch (texture.Format) { case Peg.TextureFormat.A1R5G5B5: { return(ExportTextureA1R5G5B5(texture, bytes)); } case Peg.TextureFormat.Indexed: { return(ExportTextureIndexed(texture, bytes, oneBitAlpha)); } case Peg.TextureFormat.A8R8G8B8: { return(ExportTextureA8R8G8B8(texture, bytes, oneBitAlpha)); } } throw new NotSupportedException(); }
private static int ComputeFrameSize(Peg.Texture texture) { int blockSize = 0; var mipWidth = (int)texture.Width; var mipHeight = (int)texture.Height; for (int i = 0; i < texture.MipCount; i++) { blockSize += mipWidth * mipHeight; mipWidth /= 2; mipHeight /= 2; } int size; switch (texture.Format) { case (Peg.TextureFormat) 1: case (Peg.TextureFormat) 2: case (Peg.TextureFormat) 13: case (Peg.TextureFormat) 14: { throw new NotSupportedException(); } case Peg.TextureFormat.A8R8G8B8: { size = 4 * blockSize; break; } case Peg.TextureFormat.A1R5G5B5: case (Peg.TextureFormat) 12: { size = 2 * blockSize; break; } case Peg.TextureFormat.Indexed: { int paletteSize; switch (texture.FormatArgument) { case 1: { paletteSize = 512; break; } case 2: { paletteSize = 1024; break; } default: { throw new NotSupportedException(); } } size = paletteSize + blockSize; break; } case (Peg.TextureFormat) 5: { int paletteSize; switch (texture.FormatArgument) { case 1: { paletteSize = 32; break; } case 2: { paletteSize = 64; break; } default: { throw new NotSupportedException(); } } size = paletteSize + blockSize / 2; break; } case (Peg.TextureFormat) 6: case (Peg.TextureFormat) 9: case (Peg.TextureFormat) 10: { throw new NotSupportedException(); } case (Peg.TextureFormat) 11: { int paletteSize; switch (texture.FormatArgument) { case 1: { paletteSize = 512; break; } case 2: { paletteSize = 1024; break; } default: { throw new NotSupportedException(); } } size = paletteSize + blockSize; throw new NotSupportedException(); break; } default: { throw new NotSupportedException(); } } return(size); }
public void Deserialize(Stream input) { var baseOffset = input.Position; var magic = input.ReadValueU32(Endian.Little); if (magic != Signature && magic.Swap() != Signature) { throw new FormatException("not a peg file"); } var endian = magic == Signature ? Endian.Little : Endian.Big; var version = input.ReadValueU32(endian); if (version != 6) { throw new FormatException("unsupported peg version"); } var textureHeaderSize = input.ReadValueU32(endian); if (baseOffset + 32 + textureHeaderSize > input.Length) { throw new EndOfStreamException(); } var dataSize = input.ReadValueU32(endian); if (baseOffset + 32 + textureHeaderSize + dataSize > input.Length) { throw new EndOfStreamException(); } var textureCount = input.ReadValueU32(endian); var unknown14 = input.ReadValueU32(endian); var frameCount = input.ReadValueU32(endian); var unknown1C = input.ReadValueU32(endian); if (unknown14 != 0 || unknown1C != 16) { throw new FormatException("unexpected unknown values"); } var textures = new Peg.Texture[textureCount]; int totalFrames = 0; for (int i = 0; i < textures.Length; i++) { var texture = textures[i] = Peg.Texture.Read(input, endian); if (texture.FrameCount == 0) { throw new FormatException("frame count is 0"); } totalFrames += texture.FrameCount > 1 ? (1 + texture.FrameCount) : 1; } if (totalFrames != frameCount) { throw new FormatException("did not read correct amount of frames"); } this._Endian = endian; this._Version = version; this._DataSize = dataSize; this._Textures.Clear(); this._Textures.AddRange(textures); }