private void CG_ExportThumbButton_Click(object sender, RoutedEventArgs e) { // Show error if DAL: RR is not installed as its needed to export if (!_game.EnableResourceLoading) { MessageBox.Show("This feature requires DATE A LIVE: Rio Reincarnation to be installed!", "DAL: RR not found!", MessageBoxButton.OK, MessageBoxImage.Error); return; } var sfd = new SaveFileDialog(); sfd.Filter = "Portable Network Graphics (*.png)|*.png"; if (sfd.ShowDialog(this) == true) { if (CG_ListView.SelectedIndex == -1) { return; // Return if no item is selected } int id = (CG_ListView.SelectedItem as STSCFileDatabase.CGEntry).CGID; var game = (CG_ListView.SelectedItem as STSCFileDatabase.CGEntry).GameID; if (_CGThumbnailTextureArchive.GetFileData($"{Consts.GAMEDIRNAME[(int)game]}/MA{id:D6}.tex") is byte[] data) { // Change Character Image var tex = new TEXFile(); using (var stream = new MemoryStream(data)) tex.Load(stream); tex.SaveSheetImage(sfd.FileName); } } }
/// <summary> /// Loads Game Resources into memory /// </summary> public void LoadGameFiles() { // Check if files should not be loaded if (!_game.EnableResourceLoading) { return; } try { // Load Archives and Textures _nameTextureArchive.Load(Path.Combine(_game.LangPath, "Event\\Name.pck"), true); _movieTextureArchive.Load(Path.Combine(_game.LangPath, "Extra\\mov\\movieThumb.pck"), true); _CGThumbnailTextureArchive.Load(Path.Combine(_game.GamePath, "Data\\Data\\Extra\\gal\\GalThumb.pck"), true); _novelTextureArchive.Load(Path.Combine(_game.LangPath, "Extra\\nov\\NovData.pck"), true); _novelthumbnailTextureArchive.Load(Path.Combine(_game.LangPath, "Extra\\nov\\NovThumb.pck"), true); (_optionTexture = new TEXFile()).Load(Path.Combine(_game.LangPath, "Init\\option.tex"), true); // Create and Set ImageSource VN_BG = ImageTools.ConvertToSource(_optionTexture.CreateBitmapFromFrame(27)); VN_FR = ImageTools.ConvertToSource(_optionTexture.CreateBitmapFromFrame(26)); } catch (Exception e) { // Disable Resources after failing the first time _game.EnableResourceLoading = false; // Show error new ExceptionWindow(e).ShowDialog(); } }
private void AB_SelectionChanged(object sender, SelectionChangedEventArgs e) { var list = sender as ListView; if (list.SelectedIndex == -1) { return; // Return if no item is selected } // Check if files should not be loaded if (!_game.EnableResourceLoading) { return; } string path = (list.SelectedItem as STSCFileDatabase.ArtBookPageEntry).PagePathData; if (_novelTextureArchive.GetFileData($"{path}.tex") is byte[] data) { var tex = new TEXFile(); using (var stream = new MemoryStream(data)) tex.Load(stream); AB_PG = ImageTools.ConvertToSource(tex.CreateBitmap()); tex.Dispose(); } }
public static void BuildSheet(TEXFile tex, string path) { byte[] pixels = new byte[tex.SheetWidth * tex.SheetHeight * 4]; tex.SheetData = new byte[tex.SheetWidth * tex.SheetHeight * 4]; for (int i = 0; i < tex.Frames.Count; ++i) { var frame = tex.Frames[i]; var data = LoadImageBytes(string.Format(path, i)); int l = (int)Math.Round((tex.SheetWidth) * frame.LeftScale); int t = (int)Math.Round((tex.SheetHeight) * frame.TopScale); int r = (int)Math.Round((tex.SheetWidth) * frame.RightScale); int b = (int)Math.Round((tex.SheetHeight) * frame.BottomScale); int w = (int)frame.FrameWidth; for (int x = l; x < r; ++x) { for (int y = t; y < b; ++y) { tex.SheetData[(y * tex.SheetWidth + x) * 4 + 0] = data[((y - t) * w + (x - l)) * 4 + 0]; tex.SheetData[(y * tex.SheetWidth + x) * 4 + 1] = data[((y - t) * w + (x - l)) * 4 + 1]; tex.SheetData[(y * tex.SheetWidth + x) * 4 + 2] = data[((y - t) * w + (x - l)) * 4 + 2]; tex.SheetData[(y * tex.SheetWidth + x) * 4 + 3] = data[((y - t) * w + (x - l)) * 4 + 3]; } } } ImageTools.FlipColors(tex.SheetData); }
public static void BuildTEX(ref TEXFile tex, string name) { // Remove Extension if it has one if (Path.HasExtension(name)) { name = RemoveExtension(name); } var serializer = new XmlSerializer(typeof(TEXFile)); if (File.Exists(name + ".xml")) { using (var stream = File.OpenRead(name + ".xml")) tex = serializer.Deserialize(stream) as TEXFile; } else { Console.WriteLine("WARNING: No Frame Data was found! Please Extract it using the -i switch."); } if (Directory.Exists(name)) { BuildSheet(tex, Path.Combine(name, "frame{0:d2}.png")); } else if (File.Exists(name + ".png")) { tex.LoadSheetImage(name + ".png"); } else { Console.WriteLine("WARNING: No Image was found! Please Extract it using the -s or -p switch."); } }
/// <summary> /// Splits the image from a TEXFile region /// </summary> /// <param name="file">TEXFile to load the image data from</param> /// <param name="x">The left(X) position of the region</param> /// <param name="y">The top(Y) position of the region</param> /// <param name="width">The width of the region</param> /// <param name="height">The height of the region</param> /// <returns>Array of colours</returns> public static byte[] SplitImage(this TEXFile tex, int x, int y, int width, int height) { var output = new byte[width * height * 4]; for (int ix = 0; ix < width; ++ix) { for (int iy = 0; iy < height; ++iy) { if ((y + iy) >= tex.SheetHeight) { continue; } if ((x + ix) >= tex.SheetWidth) { continue; } if ((x + ix) < 0) { continue; } if ((y + iy) < 0) { continue; } output[(ix + iy * width) * 4 + 0] = tex.SheetData[(x + ix + (y + iy) * tex.SheetWidth) * 4 + 2]; output[(ix + iy * width) * 4 + 1] = tex.SheetData[(x + ix + (y + iy) * tex.SheetWidth) * 4 + 1]; output[(ix + iy * width) * 4 + 2] = tex.SheetData[(x + ix + (y + iy) * tex.SheetWidth) * 4 + 0]; output[(ix + iy * width) * 4 + 3] = tex.SheetData[(x + ix + (y + iy) * tex.SheetWidth) * 4 + 3]; } } return(output); }
private void CG_ListView_SelectionChanged(object sender, SelectionChangedEventArgs e) { var list = sender as ListView; if (list.SelectedIndex == -1) { return; // Return if no item is selected } // Check if files should not be loaded if (!_game.EnableResourceLoading) { return; } int id = (list.SelectedItem as STSCFileDatabase.CGEntry).CGID; var game = (list.SelectedItem as STSCFileDatabase.CGEntry).GameID; string filepath = Path.Combine(_game.GamePath, $"Data\\Data\\Ma\\{Consts.GAMEDIRNAME[(int)game]}\\MA{id:D6}.pck"); if (_CGThumbnailTextureArchive.GetFileData($"{Consts.GAMEDIRNAME[(int)game]}/MA{id:D6}.tex") is byte[] data) { // Change Character Image var tex = new TEXFile(); using (var stream = new MemoryStream(data)) tex.Load(stream); CG_IM = ImageTools.ConvertToSource(tex.CreateBitmap()); } }
public static void BuildTEX(ref TEXFile tex, string sheetpath, string frameXML) { var serializer = new XmlSerializer(typeof(TEXFile)); using (var stream = File.OpenRead(frameXML)) tex = serializer.Deserialize(stream) as TEXFile; tex.LoadSheetImage(sheetpath); }
/// <summary> /// Creates a Bitmap from a TEXFile frame /// </summary> /// <param name="file">TEXFile to load the image data from</param> /// <param name="frame">The ID of the frame to use</param> /// <returns>The converted Bitmap</returns> public static Bitmap CreateBitmapFromFrame(this TEXFile file, int frame) { int x = (int)(file.Frames[frame].LeftScale * file.SheetWidth); int y = (int)(file.Frames[frame].TopScale * file.SheetHeight); int width = (int)file.Frames[frame].FrameWidth; int height = (int)file.Frames[frame].FrameHeight; return(CreateBitmap(file, x, y, width, height)); }
/// <summary> /// Creates a Bitmap from a TEXFile region /// </summary> /// <param name="file">TEXFile to load the image data from</param> /// <param name="x">The left(X) position of the region</param> /// <param name="y">The top(Y) position of the region</param> /// <param name="width">The width of the region</param> /// <param name="height">The height of the region</param> /// <returns>The converted Bitmap</returns> public static Bitmap CreateBitmap(this TEXFile file, int x, int y, int width, int height) { var image = new Bitmap(width, height, PixelFormat.Format32bppArgb); // Copy Data into Bitmap var bitmap = image.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, image.PixelFormat); Marshal.Copy(file.SplitImage(x, y, width, height), 0, bitmap.Scan0, width * height * 4); image.UnlockBits(bitmap); return(image); }
public static void SaveAllFrameInformation(TEXFile tex, string filepath) { if (!Path.HasExtension(filepath)) { filepath += ".xml"; } var serializer = new XmlSerializer(typeof(TEXFile)); using (var stream = File.Create(filepath)) serializer.Serialize(stream, tex); }
/// <summary> /// Creates a Bitmap from a TEXFile sheet /// </summary> /// <param name="file">TEXFile to load the image data from</param> /// <returns>The converted Bitmap</returns> public static Bitmap CreateBitmap(this TEXFile file) { var image = new Bitmap(file.SheetWidth, file.SheetHeight, PixelFormat.Format32bppArgb); // Copy Data into Bitmap var bitmap = image.LockBits(new Rectangle(0, 0, file.SheetWidth, file.SheetHeight), ImageLockMode.ReadWrite, image.PixelFormat); Marshal.Copy(FlipColorsCopy(file.SheetData), 0, bitmap.Scan0, file.SheetWidth * file.SheetHeight * 4); image.UnlockBits(bitmap); return(image); }
public void LoadFile(string path) { if (path == null) { return; } // Check if its a PCK if (path.ToLowerInvariant().Contains(".pck")) { LoadFontPCK(path); return; } // Check if file is valid and make sure FilePath is the .code if (path.ToLowerInvariant().Contains("_data.tex") || path.ToLowerInvariant().Contains(".code")) { FilePath = path.Replace("_data.tex", ".code"); } else { MessageBox.Show($"Unknown file type\n{path}", "Error", MessageBoxButton.OK, MessageBoxImage.Error); return; } // Recreate Objects FontImageTexFile = new TEXFile(); FontCodeFile = new FontFile(); FontCodeFile.MonospaceOnly = MonospaceOnly; try { // Load Font TEX FontImageTexFile.Load(FilePath.Replace(".code", "_data.tex")); UI_FontImage.Source = ImageTools.ConvertToSource(FontImageTexFile.CreateBitmap()); } catch { MessageBox.Show("Failed to load Texture!", "Error", MessageBoxButton.OK, MessageBoxImage.Error); } LastIndex = -1; HoverIndex = -1; // Load FontCode FontCodeFile.Load(FilePath); // Reload ReloadUI(); UI_SaveButton.IsEnabled = true; }
// TODO: Update image when path changes public void UpdateImage() { if (_archive != null) { var file = _archive.GetFileData($"{Movie.FilePath}.tex"); if (file == null) { return; } using (var stream = new MemoryStream(file)) (_texture = new TEXFile()).Load(stream); ThumbnailImage.Source = ImageTools.ConvertToSource(_texture.CreateBitmap()); } }
// TODO: Update Image when ID changes public void UpdateImage() { if (_archive != null) { var file = _archive.GetFileData($"chrName{Character.ID:D3}.tex"); if (file == null) { return; } using (var stream = new MemoryStream(file)) (_texture = new TEXFile()).Load(stream); EventNameImage.Source = ImageTools.ConvertToSource(_texture.CreateBitmap()); } }
public void LoadFontPCK(string path) { FilePath = path; PCKFontArchive = new PCKFile(); PCKFontArchive.Load(path); var textureFilePath = PCKFontArchive.SearchForFile(".tex"); var fontCodeFilePath = PCKFontArchive.SearchForFile(".code"); FontImageTexFile = new TEXFile(); FontCodeFile = new FontFile(); FontCodeFile.MonospaceOnly = MonospaceOnly; // Load Font Code if (fontCodeFilePath != null) { FontCodeFile.Load(PCKFontArchive.GetFileStream(fontCodeFilePath)); } else { MessageBox.Show("Failed to load Code File!", "Error", MessageBoxButton.OK, MessageBoxImage.Error); } if (textureFilePath != null) { // Load Texture FontImageTexFile.Load(PCKFontArchive.GetFileStream(textureFilePath)); // Set Texture UI_FontImage.Source = ImageTools.ConvertToSource(FontImageTexFile.CreateBitmap()); } else { MessageBox.Show("Failed to load Texture!", "Error", MessageBoxButton.OK, MessageBoxImage.Error); } LastIndex = -1; HoverIndex = -1; // Reload ReloadUI(); UI_SaveButton.IsEnabled = true; }
public static void SaveFrame(TEXFile tex, int index, string filename) { var frame = tex.Frames[index]; int l = (int)Math.Round((tex.SheetWidth) * frame.LeftScale); int t = (int)Math.Round((tex.SheetHeight) * frame.TopScale); int r = (int)Math.Round((tex.SheetWidth) * frame.RightScale); int b = (int)Math.Round((tex.SheetHeight) * frame.BottomScale); int w = (int)frame.FrameWidth; int h = (int)frame.FrameHeight; byte[] pixels = new byte[w * h * 4]; for (int x = l; x < r; ++x) { for (int y = t; y < b; ++y) { pixels[((y - t) * w + (x - l)) * 4 + 0] = tex.SheetData[(y * tex.SheetWidth + x) * 4 + 0]; pixels[((y - t) * w + (x - l)) * 4 + 1] = tex.SheetData[(y * tex.SheetWidth + x) * 4 + 1]; pixels[((y - t) * w + (x - l)) * 4 + 2] = tex.SheetData[(y * tex.SheetWidth + x) * 4 + 2]; pixels[((y - t) * w + (x - l)) * 4 + 3] = tex.SheetData[(y * tex.SheetWidth + x) * 4 + 3]; } } SaveImage(filename, w, h, pixels); }
public static void Main(string[] args) { var tex = new TEXFile(); if (args.Length == 0) { ShowHelp("Not Enough Arguments!"); return; } // Preprocess if (args.Length > 1) { string path = ""; for (int i = 0; i < args.Length; ++i) { if (args[i].StartsWith("-") && args[i].Length > 1) { switch (args[i][1]) { case 'z': tex.UseSmallSig = true; break; case 'e': tex.UseBigEndian = true; break; case 'c': CheckOverwrite = false; break; case 'o': path = args[i + 1]; break; default: break; } continue; } } // Actions for (int i = args.Length - 1; i >= 0; --i) { if (args[i].StartsWith("-") && args[i].Length > 1) { switch (args[i][1]) { case 'p': tex.Load(args[args.Length - 1]); if (string.IsNullOrEmpty(path)) { path = RemoveExtension(args[args.Length - 1]); } Directory.CreateDirectory(path); for (int ii = 0; ii < tex.Frames.Count; ++ii) { SaveFrame(tex, ii, Path.Combine(path, $"frame{ii:d2}.png")); } break; case 's': tex.Load(args[args.Length - 1]); if (string.IsNullOrEmpty(path)) { path = Path.ChangeExtension(args[args.Length - 1], ".png"); } if (CheckForOverwrite(path)) { tex.SaveSheetImage(path); } break; case 'i': tex.Load(args[args.Length - 1]); if (string.IsNullOrEmpty(path)) { path = Path.ChangeExtension(args[args.Length - 1], ".xml"); } SaveAllFrameInformation(tex, path); break; case 'f': tex.Load(args[args.Length - 1]); if (CheckForOverwrite(path)) { SaveFrame(tex, int.Parse(args[i + 1]), path); } break; case 'b': BuildTEX(ref tex, args[i + 1], args[i + 2]); if (string.IsNullOrEmpty(path)) { path = Path.ChangeExtension(args[args.Length - 1], ".tex"); } if (CheckForOverwrite(path)) { tex.Save(path); } break; case 'm': BuildTEX(ref tex, args[i + 1]); if (string.IsNullOrEmpty(path)) { path = Path.ChangeExtension(args[args.Length - 1], ".tex"); } if (CheckForOverwrite(path)) { tex.Save(path); } break; } } } } else { if (Path.GetExtension(args[0]) == ".png" || Path.GetExtension(args[0]) == ".xml" || Directory.Exists(args[0])) { Console.WriteLine("Building Files detected, Building..."); BuildTEX(ref tex, args[0]); string path = Path.ChangeExtension(args[0], ".tex"); if (CheckForOverwrite(path)) { tex.Save(path); } } else { tex.Load(args[0]); tex.SaveSheetImage(Path.ChangeExtension(args[0], ".png")); SaveAllFrameInformation(tex, Path.ChangeExtension(args[0], ".xml")); } } }
// TODO: Test Font Spacing, Should be removed. public static Bitmap RenderFont(this FontFile file, TEXFile texture, string text) { int width = 0; byte[][] fontPixels = new byte[text.Length][]; for (int i = 0; i < text.Length; ++i) { var entry = file.Characters.FirstOrDefault(t => t.Character == text[i]); if (entry == null) { continue; } width += entry.Width; float x = entry.XScale * texture.SheetWidth; float y = entry.YScale * texture.SheetHeight; fontPixels[i] = texture.SplitImage((int)x, (int)y, entry.Width + entry.Kerning, file.CharacterHeight); } byte[] finalBytes = new byte[width * file.CharacterHeight * 4]; int xPosition = 0; for (int i = 0; i < fontPixels.Length; ++i) { var entry = file.Characters.FirstOrDefault(t => t.Character == text[i]); if (entry == null) { continue; } if (fontPixels[i] == null) { continue; } for (int xx = 0; xx < (entry.Width + entry.Kerning); ++xx) { for (int yy = 0; yy < file.CharacterHeight; ++yy) { if (fontPixels[i][(xx + yy * (entry.Width + entry.Kerning)) * 4 + 3] == 0) { continue; } finalBytes[(xPosition - entry.Kerning + xx + yy * width) * 4 + 0] = fontPixels[i][(xx + yy * (entry.Width + entry.Kerning)) * 4 + 0]; finalBytes[(xPosition - entry.Kerning + xx + yy * width) * 4 + 1] = fontPixels[i][(xx + yy * (entry.Width + entry.Kerning)) * 4 + 1]; finalBytes[(xPosition - entry.Kerning + xx + yy * width) * 4 + 2] = fontPixels[i][(xx + yy * (entry.Width + entry.Kerning)) * 4 + 2]; finalBytes[(xPosition - entry.Kerning + xx + yy * width) * 4 + 3] = fontPixels[i][(xx + yy * (entry.Width + entry.Kerning)) * 4 + 3]; } } //xPosition -= entry.Kerning; xPosition += entry.Width; } if (width <= 0) { return(null); } var image = new Bitmap(width, file.CharacterHeight, PixelFormat.Format32bppArgb); // Copy Data into Bitmap var bitmap = image.LockBits(new Rectangle(0, 0, width, file.CharacterHeight), ImageLockMode.ReadWrite, image.PixelFormat); Marshal.Copy(finalBytes, 0, bitmap.Scan0, finalBytes.Length); image.UnlockBits(bitmap); return(image); }
// TODO: Needs Rewriting private void CG_ExportImage_Click(object sender, RoutedEventArgs e) { // Show error if DAL: RR is not installed as its needed to export if (!_game.EnableResourceLoading) { MessageBox.Show("Resource loading is currently disabled. Make sure DAL: RR is installed correctly", "Resource Loading Error!", MessageBoxButton.OK, MessageBoxImage.Error); return; } if (CG_ListView.SelectedIndex == -1) { return; // Return if no item is selected } int id = (CG_ListView.SelectedItem as STSCFileDatabase.CGEntry).CGID; var game = (CG_ListView.SelectedItem as STSCFileDatabase.CGEntry).GameID; var sfd = new SaveFileDialog(); sfd.FileName = $"{id}.png"; sfd.Filter = "Portable Network Graphics (*.png)|*.png"; if (sfd.ShowDialog(this) == true) { try { string filepath = Path.Combine(_game.GamePath, $"Data\\Data\\Ma\\{Consts.GAMEDIRNAME[(int)game]}\\MA{id:D6}.pck"); var pck = new PCKFile(); var ma = new MAFile(); pck.Load(filepath, true); using (var stream = new MemoryStream(pck.GetFileData(0))) ma.Load(stream); int width = (int)(ma.Layers[0].Verts[3].DestinX * ma.Layers[0].LayerWidth); int height = (int)(ma.Layers[0].Verts[3].DestinY * ma.Layers[0].LayerHeight); if (ma.Layers[0].Verts[3].DestinX == ma.Layers[0].LayerWidth) { width = (int)ma.Layers[0].LayerWidth; height = (int)ma.Layers[0].LayerHeight; } var bytes = new byte[width * height * 4]; for (int i = 0; i < ma.Layers.Count; ++i) { var layer = ma.Layers[i]; var tex = new TEXFile(); using (var stream = new MemoryStream(pck.GetFileData(layer.TextureID + 1))) tex.Load(stream); int sx = (int)(layer.Verts[0].SourceX * ma.Layers[i].LayerWidth); int dx = (int)(layer.Verts[0].DestinX * ma.Layers[i].LayerWidth + layer.LayerOffX); int sy = (int)(layer.Verts[0].SourceY * ma.Layers[i].LayerHeight); int dy = (int)(layer.Verts[0].DestinY * ma.Layers[i].LayerHeight + layer.LayerOffY); int sw = (int)(layer.Verts[3].SourceX * ma.Layers[i].LayerWidth); int sh = (int)(layer.Verts[3].SourceY * ma.Layers[i].LayerHeight); for (int y = 0; y < (sh - sy); ++y) { for (int x = 0; x < (sw - sx); ++x) { if ((y + sy) >= tex.SheetHeight || (x + sx) >= tex.SheetWidth) { break; } int index = ((y + sy) * tex.SheetWidth + (x + sx)) * 4; if (tex.SheetData[index + 3] != 255) { continue; } bytes[((y + dy) * width + x + dx) * 4 + 3] = tex.SheetData[index + 3]; bytes[((y + dy) * width + x + dx) * 4 + 0] = tex.SheetData[index + 0]; bytes[((y + dy) * width + x + dx) * 4 + 1] = tex.SheetData[index + 1]; bytes[((y + dy) * width + x + dx) * 4 + 2] = tex.SheetData[index + 2]; } } DALLib.Imaging.ImageTools.SaveImage(Path.Combine(Path.GetDirectoryName(sfd.FileName), Path.GetFileNameWithoutExtension(sfd.FileName) + $"_{i}.png"), width, height, bytes); } pck.Dispose(); } catch (Exception ex) { new ExceptionWindow(ex, "Failed to export CG frames").ShowDialog(); } } }
public static void Decode(this TEXFile file, Format format, ExtendedBinaryReader reader) { ImageBinary image; var endian = file.UseBigEndian ? Endian.BigEndian : Endian.LittleEndian; if ((format & Format.DXT1) != 0) { image = new ImageBinary(file.SheetWidth, file.SheetHeight, PixelDataFormat.FormatDXT1Rgba, endian, PixelDataFormat.FormatAbgr8888, Endian.LittleEndian, file.SheetData); file.SheetData = image.GetOutputPixelData(0); } else if ((format & Format.DXT5) != 0 || (format & Format.Large) != 0) { image = new ImageBinary(file.SheetWidth, file.SheetHeight, PixelDataFormat.FormatDXT5, endian, PixelDataFormat.FormatAbgr8888, Endian.LittleEndian, file.SheetData); file.SheetData = image.GetOutputPixelData(0); } else if ((format & Format.Luminance8) != 0) { image = new ImageBinary(file.SheetWidth, file.SheetHeight, PixelDataFormat.FormatLuminance8, endian, PixelDataFormat.FormatAbgr8888, Endian.LittleEndian, file.SheetData); file.SheetData = image.GetOutputPixelData(0); } else if ((format & Format.Luminance4) != 0) { image = new ImageBinary(file.SheetWidth, file.SheetHeight, PixelDataFormat.FormatLuminance4, endian, PixelDataFormat.FormatAbgr8888, Endian.LittleEndian, file.SheetData); file.SheetData = image.GetOutputPixelData(0); } else if ((format & Format.Unknown) != 0) { throw new InvalidTextureFormatException((int)format); } else if ((format & Format.Raster) != 0) { // Read Colour Palette reader.JumpBehind(256 * 4); var colorpalette = reader.ReadBytes(256 * 4); var indies = file.SheetData; file.SheetData = new byte[file.SheetWidth * file.SheetHeight * 4]; for (int i = 0; i < file.SheetWidth * file.SheetHeight; ++i) { file.SheetData[i * 4 + 0] = colorpalette[indies[i] * 4 + 0]; file.SheetData[i * 4 + 1] = colorpalette[indies[i] * 4 + 1]; file.SheetData[i * 4 + 2] = colorpalette[indies[i] * 4 + 2]; file.SheetData[i * 4 + 3] = colorpalette[indies[i] * 4 + 3]; } } else if ((format & Format.PNG) != 0) { using (var endStream = new MemoryStream()) using (var stream = new MemoryStream(file.SheetData)) { var imagePNG = new Bitmap(Image.FromStream(stream)); var bitmap = imagePNG.LockBits(new Rectangle(0, 0, file.SheetWidth, file.SheetHeight), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); file.SheetData = new byte[file.SheetWidth * file.SheetHeight * 4]; Marshal.Copy(bitmap.Scan0, file.SheetData, 0, file.SheetWidth * file.SheetHeight * 4); // Flip Red and Blue channels as this converter does not support ARGB if (file.UseBigEndian) { ImageTools.FlipColors(file.SheetData); } imagePNG.UnlockBits(bitmap); imagePNG.Dispose(); } } else if ((format & Format.BGRA) != 0) { return; } else { throw new InvalidTextureFormatException((int)format); } }
public void OpenFile(string filename, Stream stream) { CurrentFile = new TEXFile(stream); var EArgs = new FileOpenedEventArgs(filename); EArgs.Platform = ((TEXFile.Platform)CurrentFile.File.Header.Platform).ToString("F"); EArgs.Format = ((TEXFile.PixelFormat)CurrentFile.File.Header.PixelFormat).ToString("F"); EArgs.Mipmaps = CurrentFile.File.Header.NumMips.ToString(); EArgs.PreCave = CurrentFile.IsPreCaveUpdate(); EArgs.TexType = EnumHelper <TEXFile.TextureType> .GetEnumDescription(((TEXFile.TextureType)CurrentFile.File.Header.TextureType).ToString()); var mipmap = CurrentFile.GetMainMipmap(); EArgs.Size = mipmap.Width + "x" + mipmap.Height; OnOpenFile(EArgs); byte[] argbData; switch ((TEXFile.PixelFormat)CurrentFile.File.Header.PixelFormat) { case TEXFile.PixelFormat.DXT1: argbData = Squish.DecompressImage(mipmap.Data, mipmap.Width, mipmap.Height, SquishFlags.Dxt1); break; case TEXFile.PixelFormat.DXT3: argbData = Squish.DecompressImage(mipmap.Data, mipmap.Width, mipmap.Height, SquishFlags.Dxt3); break; case TEXFile.PixelFormat.DXT5: argbData = Squish.DecompressImage(mipmap.Data, mipmap.Width, mipmap.Height, SquishFlags.Dxt5); break; case TEXFile.PixelFormat.ARGB: argbData = mipmap.Data; break; default: throw new Exception("Unknown pixel format?"); } string atlasExt = "xml"; FileInfo fileInfo = new FileInfo(filename); string fileDir = fileInfo.DirectoryName; string fileNameWithoutExt = fileInfo.Name.Replace(fileInfo.Extension, ""); string atlasDataPath = fileDir + @"\" + fileNameWithoutExt + "." + atlasExt; List <KleiTextureAtlasElement> atlasElements = new List <KleiTextureAtlasElement>(); if (File.Exists(atlasDataPath)) { atlasElements = ReadAtlasData(atlasDataPath, mipmap.Width, mipmap.Height); } var imgReader = new BinaryReader(new MemoryStream(argbData)); Bitmap pt = new Bitmap((int)mipmap.Width, (int)mipmap.Height); for (int y = 0; y < mipmap.Height; y++) { for (int x = 0; x < mipmap.Width; x++) { byte r = imgReader.ReadByte(); byte g = imgReader.ReadByte(); byte b = imgReader.ReadByte(); byte a = imgReader.ReadByte(); pt.SetPixel(x, y, Color.FromArgb(a, r, g, b)); } if (OnProgressUpdate != null) { OnProgressUpdate(y * 100 / mipmap.Height); } } pt.RotateFlip(RotateFlipType.RotateNoneFlipY); CurrentFileRaw = pt; OnRawImage(new FileRawImageEventArgs(pt, atlasElements)); }
private void ConvertPNGToTex(string inputFile, FileStream outputStream) { TEXFile.PixelFormat PixelFormat = (TEXFile.PixelFormat)Enum.Parse(typeof(TEXFile.PixelFormat), this.pixelFormatComboBox.Text); InterpolationMode interpolationMode = (InterpolationMode)Enum.Parse(typeof(InterpolationMode), this.mipmapFilterComboBox.Text); Bitmap inputImage = (Bitmap)Bitmap.FromFile(inputFile); inputImage.RotateFlip(RotateFlipType.RotateNoneFlipY); bool GenerateMipmaps = generateMipmapsCheckBox.Checked; List <Mipmap> Mipmaps = new List <Mipmap>(); bool preMultiplyAlpha = preMultiplyAlphaCheckBox.Checked; Mipmaps.Add(GenerateMipmap(inputImage, PixelFormat, preMultiplyAlpha)); if (GenerateMipmaps) { var width = inputImage.Width; var height = inputImage.Height; while (Math.Max(width, height) > 1) { width = Math.Max(1, width >> 1); height = Math.Max(1, height >> 1); Mipmaps.Add(GenerateMipmap(inputImage, PixelFormat, width, height, interpolationMode, preMultiplyAlpha)); } } TEXFile outputTEXFile = new TEXFile(); outputTEXFile.File.Header.Platform = 0; outputTEXFile.File.Header.PixelFormat = (uint)PixelFormat; outputTEXFile.File.Header.TextureType = (uint)EnumHelper <TEXFile.TextureType> .GetValueFromDescription(this.textureTypeComboBox.Text); outputTEXFile.File.Header.NumMips = (uint)Mipmaps.Count; outputTEXFile.File.Header.Flags = 0; MemoryStream ms = new MemoryStream(); BinaryWriter writer = new BinaryWriter(ms); foreach (Mipmap mip in Mipmaps) { writer.Write(mip.Width); writer.Write(mip.Height); writer.Write(mip.Pitch); writer.Write((uint)mip.ARGBData.Length); } foreach (Mipmap mip in Mipmaps) { writer.Write(mip.ARGBData); } writer.Close(); outputTEXFile.File.Raw = ms.ToArray(); outputTEXFile.SaveFile(outputStream); }
private void UI_ImportTextureButton_Click(object sender, RoutedEventArgs e) { var ofd = new OpenFileDialog(); ofd.Filter = "All Supported Files|*.tex;*.png|Texture|*.tex|Supported Image Files|*.png"; if (ofd.ShowDialog() == true) { if (ofd.FileName.ToLower(CultureInfo.GetCultureInfo("en-US")).EndsWith(".tex")) { var textureFilePath = PCKFontArchive.SearchForFile(".tex"); var newTexture = new TEXFile(); // Set Sigless newTexture.Sigless = true; // Load new Texture newTexture.Load(ofd.FileName); // Check Dimensions if (FontImageTexFile.SheetData != null && (newTexture.SheetWidth != FontImageTexFile.SheetWidth || newTexture.SheetHeight != FontImageTexFile.SheetHeight)) { if (MessageBox.Show("Texture dimensions do not match!\n" + "FontEditor currently does not support rescaling, Do you want to continue?", "WARNING", MessageBoxButton.YesNo, MessageBoxImage.Warning) == MessageBoxResult.No) { return; } } // Import Texture into PCK PCKFontArchive.ReplaceFile(textureFilePath, File.ReadAllBytes(ofd.FileName)); // Set Texture UI_FontImage.Source = ImageTools.ConvertToSource((FontImageTexFile = newTexture).CreateBitmap()); } else { var textureFilePath = PCKFontArchive.SearchForFile(".tex"); var newTexture = new TEXFile(); // Set Sigless newTexture.Sigless = true; // Load Image to Texture newTexture.LoadSheetImage(ofd.FileName); // Check Dimensions if (FontImageTexFile.SheetData != null && (newTexture.SheetWidth != FontImageTexFile.SheetWidth || newTexture.SheetHeight != FontImageTexFile.SheetHeight)) { if (MessageBox.Show("Texture dimensions do not match!\n" + "FontEditor currently does not support rescaling, Do you want to continue?", "WARNING", MessageBoxButton.YesNo, MessageBoxImage.Warning) == MessageBoxResult.No) { return; } } // Save Texture to PCK using (var stream = new MemoryStream()) { newTexture.Save(stream); PCKFontArchive.ReplaceFile(textureFilePath, stream.ToArray()); } // Set Texture UI_FontImage.Source = ImageTools.ConvertToSource((FontImageTexFile = newTexture).CreateBitmap()); } } }
public static void Decode(this TEXFile file, Format format, ExtendedBinaryReader reader) { Decode(file, format, LoaderType.Default, reader); }