public static Texture MiloPngToTexture(Stream s) { var version = s.ReadUInt24BE(); if (version != 0x010818 && version != 0x010408) { throw new ArgumentException("Stream was not a supported png_xbox"); } s.Position += 4; var width = s.ReadInt16LE(); var height = s.ReadInt16LE(); s.Position = 32; if (width == 512) { s.Position += (512 * 512); width = 256; height = 256; } if (width != 256 || height != 256) { throw new Exception("Texture was not 512x512 or 256x256"); } var mipmaps = new Texture.Mipmap[7]; for (var i = 0; i < mipmaps.Length; i++) { var m = mipmaps[i] = new Texture.Mipmap { Width = width, Height = height, Data = new byte[width * height / 2] }; var bytes = s.ReadBytes(width * height / (version == 0x010818 ? 1 : 2)); for (int x = (version == 0x010818 ? 0 : -8), y = 0; y < m.Data.Length; x += (version == 0x010818 ? 16 : 8)) { m.Data[y] = bytes[x + 9]; m.Data[y + 1] = bytes[x + 8]; m.Data[y + 2] = bytes[x + 11]; m.Data[y + 3] = bytes[x + 10]; m.Data[y + 4] = bytes[x + 13]; m.Data[y + 5] = bytes[x + 12]; m.Data[y + 6] = bytes[x + 15]; m.Data[y + 7] = bytes[x + 14]; y += 8; } width /= 2; height /= 2; } return(new Texture { HeaderData = HeaderData256x256, FooterData = FooterData256x256, Version = 6, Mipmaps = mipmaps }); }
private static void DecodeDXT(Texture.Mipmap m, int[] imageData, bool DXT5) { int[] colors = new int[4]; using (var s = new MemoryStream(m.Data)) { ushort[] c = new ushort[4]; byte[] iData = new byte[4]; for (var y = 0; y < m.Height; y += 4) { for (var x = 0; x < m.Width; x += 4) { if (DXT5) { s.Seek(8, SeekOrigin.Current); } ushort c0 = s.ReadUInt16LE(); ushort c1 = s.ReadUInt16LE(); colors[0] = RGB565ToARGB(c0); colors[1] = RGB565ToARGB(c1); var color0 = Color.FromArgb(colors[0]); var color1 = Color.FromArgb(colors[1]); s.Read(iData, 0, 4); if (c0 > c1) { colors[2] = Color.FromArgb(0xFF, (color0.R * 2 + color1.R) / 3, (color0.G * 2 + color1.G) / 3, (color0.B * 2 + color1.B) / 3).ToArgb(); colors[3] = Color.FromArgb(0xFF, (color0.R + (color1.R * 2)) / 3, (color0.G + (color1.G * 2)) / 3, (color0.B + (color1.B * 2)) / 3).ToArgb(); } else { colors[2] = Color.FromArgb(0xFF, (color0.R + color1.R) / 2, (color0.G + color1.G) / 2, (color0.B + color1.B) / 2).ToArgb(); colors[3] = Color.Black.ToArgb(); } var offset = y * m.Width + x; for (var i = 0; i < 4; i++) { for (var j = 0; j < 4; j++) { var idx = (iData[i] >> (2 * j)) & 0x3; imageData[offset + i * m.Width + j] = colors[idx]; } } } } } }
public static Texture ToTexture(Image image) { Texture.Mipmap[] maps = new Texture.Mipmap[7]; for (var i = 0; i < maps.Length; i++) { maps[i] = new Texture.Mipmap { Width = 256 / (1 << i), Height = 256 / (1 << i), Data = EncodeDxt(image, i) }; } return(new Texture { HeaderData = HeaderData256x256, FooterData = FooterData256x256, Version = 6, Mipmaps = maps }); }