private IImage ExtractEmbeddedDXT5A(byte[] bytes, HWBinaryResourceChunk chunk) { // Get raw embedded DXT5 texture from resource file var width = (int)Math.Sqrt(chunk.Size * 2); var height = width; // For some godforsaken reason, every pair of bytes is flipped so we need // to fix it here. This was really annoying to figure out, haha. for (var i = 0; i < chunk.Size; i += 2) { var offset = (int)chunk.Offset + i; var byte0 = bytes[offset + 0]; var byte1 = bytes[offset + 1]; bytes[offset + 0] = byte1; bytes[offset + 1] = byte0; } return(DxtDecoder.DecompressDxt5a(bytes, (int)chunk.Offset, width, height)); }
ImageData Unpack() { byte[] pixels; switch (m_texture.m_TextureFormat) { case TextureFormat.DXT5: { var decoder = new DxtDecoder(m_texture.m_Data, Info); pixels = decoder.UnpackDXT5(); break; } case TextureFormat.Alpha8: case TextureFormat.R16: case TextureFormat.RGB24: case TextureFormat.BGRA32: case TextureFormat.RGB565: pixels = m_texture.m_Data; break; default: throw new NotImplementedException("Not supported Unity Texture2D format."); } return(ImageData.CreateFlipped(Info, Format, null, pixels, (int)Info.Width * ((Format.BitsPerPixel + 7) / 8))); }
public static void Main(string[] args) { if (args.Length < 4) { Console.WriteLine("Format: {fileName} {width} {height} {mode}"); Console.WriteLine("mode: 0 - DXT1; 1 - DXT3; 2 - DXT5"); Console.ReadKey(); return; } string path = args[0]; int width = int.Parse(args[1]); int height = int.Parse(args[2]); int mode = int.Parse(args[3]); using (DirectBitmap bitmap = new DirectBitmap(width, height)) { byte[] data = File.ReadAllBytes(path); Stopwatch stopwatch = new Stopwatch(); for (int i = 0; i < 5; i++) { stopwatch.Start(); for (int j = 0; j < 5; j++) { switch (mode) { case 0: DxtDecoder.DecompressDXT1(data, width, height, bitmap.Bits); break; case 1: DxtDecoder.DecompressDXT3(data, width, height, bitmap.Bits); break; case 2: DxtDecoder.DecompressDXT5(data, width, height, bitmap.Bits); break; default: throw new Exception(mode.ToString()); } } stopwatch.Stop(); Console.WriteLine("Processed " + stopwatch.ElapsedMilliseconds); stopwatch.Reset(); } string dirPath = Path.GetDirectoryName(path); string fileName = Path.GetFileNameWithoutExtension(path); string outPath = Path.Combine(dirPath, fileName + ".png"); bitmap.Bitmap.RotateFlip(System.Drawing.RotateFlipType.RotateNoneFlipY); bitmap.Bitmap.Save(outPath, ImageFormat.Png); } Console.WriteLine("Finished!"); }
ImageData Unpack() { if (null == m_texture.m_Data || 0 == m_texture.m_Data.Length) { m_texture.LoadData(m_reader); } byte[] pixels; switch (m_texture.m_TextureFormat) { case TextureFormat.DXT1: { var decoder = new DxtDecoder(m_texture.m_Data, Info); pixels = decoder.UnpackDXT1(); break; } case TextureFormat.DXT5: { var decoder = new DxtDecoder(m_texture.m_Data, Info); pixels = decoder.UnpackDXT5(); break; } case TextureFormat.Alpha8: case TextureFormat.R16: case TextureFormat.RGB24: case TextureFormat.BGRA32: case TextureFormat.RGB565: pixels = m_texture.m_Data; break; case TextureFormat.ARGB32: pixels = ConvertArgb(m_texture.m_Data); break; case TextureFormat.RGBA32: pixels = ConvertRgba(m_texture.m_Data); break; case TextureFormat.ARGB4444: pixels = ConvertArgb16(m_texture.m_Data); break; case TextureFormat.BC7: { var decoder = new Bc7Decoder(m_texture.m_Data, Info); pixels = decoder.Unpack(); break; } default: throw new NotImplementedException(string.Format("Not supported Unity Texture2D format '{0}'.", m_texture.m_TextureFormat)); } return(ImageData.CreateFlipped(Info, Format, null, pixels, (int)Info.Width * ((Format.BitsPerPixel + 7) / 8))); }
private IImage ExtractEmbeddedDXT1(byte[] bytes, HWBinaryResourceChunk chunk) { // Decompress DXT1 texture and turn it into a Bitmap var width = BinaryUtils.ReadInt32BigEndian(bytes, (int)chunk.Offset + 4); var height = BinaryUtils.ReadInt32BigEndian(bytes, (int)chunk.Offset + 8); return(DxtDecoder.DecompressDXT1(bytes, (int)chunk.Offset + 16, width, height)); }
byte[] UnpackDXT5(byte[] input, GxtMetaData info) { var decoder = new DxtDecoder(input, info); int src = 0; for (int y = 0; y < info.iHeight; y += 4) { for (int x = 0; x < info.iWidth; x += 4) { int px, py; GetSwizzledCoords(x / 4, y / 4, info.iWidth / 4, info.iHeight / 4, out px, out py); decoder.DecompressDXT5Block(input, src, py * 4, px * 4); src += 16; } } return(decoder.Output); }
public static DirectBitmap DXTTextureToBitmap(Texture2D texture, byte[] data) { int width = texture.Width; int height = texture.Height; DirectBitmap bitmap = new DirectBitmap(width, height); try { switch (texture.TextureFormat) { case TextureFormat.DXT1: case TextureFormat.DXT1Crunched: DxtDecoder.DecompressDXT1(data, width, height, bitmap.Bits); break; case TextureFormat.DXT3: DxtDecoder.DecompressDXT3(data, width, height, bitmap.Bits); break; case TextureFormat.DXT5: case TextureFormat.DXT5Crunched: DxtDecoder.DecompressDXT5(data, width, height, bitmap.Bits); break; default: throw new Exception(texture.TextureFormat.ToString()); } bitmap.Bitmap.RotateFlip(RotateFlipType.RotateNoneFlipY); return(bitmap); } catch { bitmap.Dispose(); throw; } }