public void DecompressMipmap(TexMipmap mipmap) { if (mipmap.IsLZ4Compressed) { mipmap.Bytes = Lz4Decompress(mipmap.Bytes, mipmap.PixelCount); mipmap.IsLZ4Compressed = false; } if (mipmap.Format.IsImage()) { return; } switch (mipmap.Format) { case MipmapFormat.CompressedDXT5: mipmap.Bytes = DXT.DecompressImage(mipmap.Width, mipmap.Height, mipmap.Bytes, DXT.DXTFlags.DXT5); mipmap.Format = MipmapFormat.RGBA8888; break; case MipmapFormat.CompressedDXT3: mipmap.Bytes = DXT.DecompressImage(mipmap.Width, mipmap.Height, mipmap.Bytes, DXT.DXTFlags.DXT3); mipmap.Format = MipmapFormat.RGBA8888; break; case MipmapFormat.CompressedDXT1: mipmap.Bytes = DXT.DecompressImage(mipmap.Width, mipmap.Height, mipmap.Bytes, DXT.DXTFlags.DXT1); mipmap.Format = MipmapFormat.RGBA8888; break; } }
private void BtnExportPNG_Click(object sender, EventArgs e) { if (LstTextures.SelectedIndex > -1) { using (SaveFileDialog SaveDlg = new SaveFileDialog()) { SaveDlg.Filter = "PNG image|*.png"; if (SaveDlg.ShowDialog() == DialogResult.OK) { IDDTexture Texture = CurrentFile.Textures[LstTextures.SelectedIndex]; byte[] Data = Texture.TextureData; int Width = Texture.Resolution.Width; int Height = Texture.Resolution.Height; switch (Texture.Format) { case TextureFormat.DXT1: DXT.DXT1_Decode(Data, Width, Height).Save(SaveDlg.FileName); break; case TextureFormat.DXT3: DXT.DXT3_Decode(Data, Width, Height).Save(SaveDlg.FileName); break; case TextureFormat.DXT5: DXT.DXT5_Decode(Data, Width, Height).Save(SaveDlg.FileName); break; } } } } }
public bool Decode(TexFormat format, byte[] input, int width, int height, out byte[] output) { output = null; return(false); switch (format) { case TexFormat.BC1_UNORM: output = DXT.DecompressBC1(input, width, height, false); break; case TexFormat.BC1_SRGB: output = DXT.DecompressBC1(input, width, height, true); break; case TexFormat.BC2_UNORM: output = DXT.DecompressBC2(input, width, height, false); break; case TexFormat.BC2_SRGB: output = DXT.DecompressBC2(input, width, height, true); break; case TexFormat.BC3_UNORM: output = DXT.DecompressBC3(input, width, height, false); break; case TexFormat.BC3_SRGB: output = DXT.DecompressBC3(input, width, height, true); break; case TexFormat.BC4_UNORM: output = DXT.DecompressBC4(input, width, height, false); break; case TexFormat.BC4_SNORM: output = DXT.DecompressBC4(input, width, height, true); break; case TexFormat.BC5_UNORM: output = DXT.DecompressBC5(input, width, height, false); break; case TexFormat.BC5_SNORM: output = DXT.DecompressBC5(input, width, height, true); break; } return(output != null); }
private void DisplayTexture(IDDTexture Texture) { byte[] Data = Texture.TextureData; int Width = Texture.Resolution.Width; int Height = Texture.Resolution.Height; switch (Texture.Format) { case TextureFormat.DXT1: TextureImg.Image = DXT.DXT1_Decode(Data, Width, Height); break; case TextureFormat.DXT3: TextureImg.Image = DXT.DXT3_Decode(Data, Width, Height); break; case TextureFormat.DXT5: TextureImg.Image = DXT.DXT5_Decode(Data, Width, Height); break; } }
private void BtnImportPNG_Click(object sender, EventArgs e) { if (LstTextures.SelectedIndex > -1) { using (OpenFileDialog OpenDlg = new OpenFileDialog()) { OpenDlg.Filter = "PNG image|*.png"; if (OpenDlg.ShowDialog() == DialogResult.OK && File.Exists(OpenDlg.FileName)) { Bitmap Img = new Bitmap(OpenDlg.FileName); IDDTexture Texture = CurrentFile.Textures[LstTextures.SelectedIndex]; if (Img.Size != Texture.Resolution) { MessageBox.Show( "The image can't be imported because the size is different!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); return; } byte[] Data = null; switch (Texture.Format) { case TextureFormat.DXT1: Data = DXT.DXT1_Encode(Img); break; case TextureFormat.DXT3: Data = DXT.DXT3_Encode(Img); break; case TextureFormat.DXT5: Data = DXT.DXT5_Encode(Img); break; } if (Data != null) { Texture.TextureData = Data; CurrentFile.Textures.RemoveAt(LstTextures.SelectedIndex); CurrentFile.Textures.Insert(LstTextures.SelectedIndex, Texture); DisplayTexture(Texture); } } } } }
public TextureGCN(string f, string sf, GTFS fs, bool useGTFSView = false) { file = f; safefilename = sf; //-- bool flip = true; fs.Position = 0; int magic = GT.ReadInt32(fs, 4, flip); int stuff = GT.ReadInt32(fs, 4, flip); width = GT.ReadInt32(fs, 4, flip); height = GT.ReadInt32(fs, 4, flip); int unknown = GT.ReadInt32(fs, 4, flip); int format = GT.ReadInt32(fs, 4, flip); fs.Position = 0x20; //Only for Gamecube Color[][] blocks = DXT.ReadCMPR(fs, flip, width, height); bitmap = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format32bppArgb); int bi = 0; for (int y = 0; y < height / 4; y++) { for (int x = 0; x < width / 4; x++) { for (int i = 0; i < 16; i++) { int row = i / 4; int col = i - (row * 4); bitmap.SetPixel(x * 4 + col, y * 4 + row, blocks[bi][i]); } bi++; } } }
public void DecompressMipmap(ITexMipmap mipmap) { if (mipmap == null) { throw new ArgumentNullException(nameof(mipmap)); } if (mipmap.IsLZ4Compressed) { mipmap.Bytes = Lz4Decompress(mipmap.Bytes, mipmap.DecompressedBytesCount); mipmap.IsLZ4Compressed = false; } if (mipmap.Format.IsImage()) { return; } switch (mipmap.Format) { case MipmapFormat.CompressedDXT5: mipmap.Bytes = DXT.DecompressImage(mipmap.Width, mipmap.Height, mipmap.Bytes, DXTFlags.DXT5); mipmap.Format = MipmapFormat.RGBA8888; break; case MipmapFormat.CompressedDXT3: mipmap.Bytes = DXT.DecompressImage(mipmap.Width, mipmap.Height, mipmap.Bytes, DXTFlags.DXT3); mipmap.Format = MipmapFormat.RGBA8888; break; case MipmapFormat.CompressedDXT1: mipmap.Bytes = DXT.DecompressImage(mipmap.Width, mipmap.Height, mipmap.Bytes, DXTFlags.DXT1); mipmap.Format = MipmapFormat.RGBA8888; break; } }
/// <summary> /// Writes an entire .dds file to the temporary path using the fileName /// </summary> /// <param name="fileName"></param> /// <param name="imageData"></param> /// <param name="width"></param> /// <param name="height"></param> /// <param name="mipmapCount"></param> /// <param name="dxtType"></param> /// <param name="completedAction"></param> public static void WriteTempDDS(string fileName, byte[] imageData, int width, int height, int mipmapCount, DXT dxtType, Action completedAction) { Console.WriteLine("DXT: " + dxtType.ToString()); char[] dxtArr = { 'D', 'X', '\x0', '\x0' }; int pls = imageData.Length; //Math.Max(1, (width + 3) / 4) * 8 try { using (FileStream stream = new FileStream($"{GetTempPath(fileName)}.dds", FileMode.Create, FileAccess.Write, FileShare.None)) { using (BinaryWriter writer = new BinaryWriter(stream)) { foreach (char c in new char[] { 'D', 'D', 'S', ' ' }) // DDS magic { writer.Write(c); } writer.Write(124); // size of DDS header writer.Write(659463); // flags writer.Write(height); // height writer.Write(width); // width writer.Write(pls); // pitch or linear size writer.Write(0); // depth writer.Write(1); // mipmap count, "1" for now for (int i = 0; i < 11; i++) // reserved { writer.Write(0); } writer.Write(32); // size of PIXELFORMAT chunk if (dxtType == 0 ? false : (int)dxtType != 7) // flags { writer.Write(4); } else { writer.Write(64); } foreach (char c in DXTExtensions.GetDXTAsChars((int)dxtType)) // DXT type/four CC { writer.Write(c); } for (int n = 0; n < 5; n++) // RGBBitCount, RBitMask, GBitMask, BBitMask, ABitMask { writer.Write(0); } writer.Write(4198408); // caps for (int i = 0; i < 4; i++) // caps2, caps3, caps4, reserved2 { writer.Write(0); } if (dxtType.ToString().Contains("DX10")) // add the DX10 header, if necessary { string fileNameNoExt = Path.GetFileNameWithoutExtension(fileName); if (fileNameNoExt.Contains("NormalMap") || fileNameNoExt.EndsWith("_Map")) // this stays until I devise a better tactic { writer.Write(98); // normal maps } else { writer.Write(72); // all others use BC1_UNORM_SRGB } writer.Write(3); // resourceDimension writer.Write(0); // miscFlags writer.Write(1); // array size writer.Write(0); // miscFlags2 } writer.Write(imageData); // image data } } } catch (IOException e) { MessageBox.Show($"Could not create a dds file due an error:\n{e.Message}", "Failure"); } completedAction(); }
public TextureXbox(string f, string sf, GTFS fs, bool useGTFSView = false) { file = f; safefilename = sf; bool flip = false; fs.Position = 0; int magic = GT.ReadInt32(fs, 4, flip); //Width? int stuff = GT.ReadInt32(fs, 4, flip); //Height? width = GT.ReadInt32(fs, 4, flip); height = GT.ReadInt32(fs, 4, flip); int unknown = GT.ReadInt32(fs, 4, flip); //fs.Position = 0x14; int format = GT.ReadInt32(fs, 4, flip); fs.Position = 0x80; //Only for Xbox //Console.WriteLine("Texture: " + sf + " Unknown: " + unknown); Color[][] blocks = null; if (format == 0) { blocks = DXT.ReadDXT1(fs, flip, width, height); } else if (format == 1) { blocks = DXT.ReadDXT3(fs, flip, width, height); } else if (format == 2) { //Morton Order blocks = new Color[height][]; for (int y = 0; y < height; y++) { blocks[y] = new Color[width]; for (int x = 0; x < width; x++) { int idx = DXT.Morton2D(y, x); if ((idx * 4 + 4) > fs.Length - 0x80) { idx = 0; } fs.Position = 128 + idx * 4; blocks[y][x] = Color.FromArgb(GT.ReadInt32(fs, 4, flip)); } } } else if (format == 3) { Console.WriteLine(); } else { throw new Exception(); } bitmap = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format32bppArgb); if (blocks.Length == height) { //RGB Style for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { bitmap.SetPixel(x, y, blocks[y][x]); } } } else { //DXT Style int bi = 0; for (int y = 0; y < height / 4; y++) { for (int x = 0; x < width / 4; x++) { for (int i = 0; i < 16; i++) { int row = i / 4; int col = i - (row * 4); bitmap.SetPixel(x * 4 + col, y * 4 + row, blocks[bi][i]); } bi++; } } } }
/// <summary> /// Writes an entire .dds file to the temporary path using the fileName /// </summary> /// <param name="fileName"></param> /// <param name="imageData"></param> /// <param name="width"></param> /// <param name="height"></param> /// <param name="mipmapCount"></param> /// <param name="dxtType"></param> /// <param name="completedAction"></param> public static void WriteTempDDS(string fileName, byte[] imageData, int width, int height, int mipmapCount, DXT dxtType, Action completedAction) { Console.WriteLine("DXT: " + dxtType.ToString()); char[] dxtArr = { 'D', 'X', '\x0', '\x0' }; try { using (FileStream stream = new FileStream($"{GetTempPath(fileName)}.dds", FileMode.Create, FileAccess.Write, FileShare.None)) { using (BinaryWriter writer = new BinaryWriter(stream)) { foreach (char c in new char[] { 'D', 'D', 'S', ' ' }) // DDS magic { writer.Write(c); } writer.Write(BitConverter.GetBytes(124)); // size of DDS header writer.Write(new byte[] { 0x7, 0x10, 0x8, 0x0 }); // flags writer.Write(height); // height writer.Write(width); // width writer.Write(BitConverter.GetBytes(2048)); // pitch or linear size writer.Write(1); // depth writer.Write(1); // mipmap count, "1" for now for (int i = 0; i < 11; i++) // reserved { writer.Write(0); } // DDS_PIXELFORMAT writer.Write(32); // size of PIXELFORMAT if (dxtType == 0 ? false : (int)dxtType != 7) // flags { writer.Write(BitConverter.GetBytes(4)); } else { writer.Write(BitConverter.GetBytes(64)); } foreach (char c in DXTExtensions.GetDXTAsChars((int)dxtType)) // DXT type/four CC { writer.Write(c); } for (int n = 0; n < 5; n++) // RGBBitCount, RBitMask, GBitMask, BBitMask, ABitMask { writer.Write(0); } writer.Write(4198408); // caps for (int i = 0; i < 4; i++) // caps2, caps3, caps4, reserved2 { writer.Write(0); } // DDS_HEADER_DX10 if (dxtType.ToString().Contains("DX10")) // add the DX10 header, if necessary { string fileNameNoExt = Path.GetFileNameWithoutExtension(fileName); if (fileNameNoExt.Contains("NormalMap") || fileNameNoExt.EndsWith("_Map")) // this stays until I devise a better tactic { writer.Write(BitConverter.GetBytes(98)); // BC7_UNORM (normal maps) } else if (false) { writer.Write(BitConverter.GetBytes(71)); // BC1_UNORM (mask maps) } else { writer.Write(BitConverter.GetBytes(72)); // BC1_UNORM_SRGB } writer.Write(BitConverter.GetBytes(3)); // resource dimension writer.Write(0); // misc flags writer.Write(BitConverter.GetBytes(1)); // array size writer.Write(0); // misc flags 2 } // image data writer.Write(imageData); } } } catch (IOException e) { Message.Fail("Could not create a DDS file. " + e.Message + e.StackTrace); } completedAction(); }