public GxtBinary(Stream stream) { BinaryReader reader = new BinaryReader(stream); Header = new SceGxtHeader(stream); Func <Stream, SceGxtTextureInfo> textureInfoGeneratorFunc; switch (Header.Version) { case 0x10000003: textureInfoGeneratorFunc = new Func <Stream, SceGxtTextureInfo>((s) => { return(new SceGxtTextureInfoV301(s)); }); break; case 0x10000002: textureInfoGeneratorFunc = new Func <Stream, SceGxtTextureInfo>((s) => { return(new SceGxtTextureInfoV201(s)); }); break; case 0x10000001: textureInfoGeneratorFunc = new Func <Stream, SceGxtTextureInfo>((s) => { return(new SceGxtTextureInfoV101(s)); }); break; default: throw new VersionNotImplementedException(Header.Version); } TextureInfos = new SceGxtTextureInfo[Header.NumTextures]; for (int i = 0; i < TextureInfos.Length; i++) { TextureInfos[i] = textureInfoGeneratorFunc(stream); } // TODO: any other way to detect these? if (Encoding.ASCII.GetString(reader.ReadBytes(4)) == BUVChunk.ExpectedMagicNumber) { stream.Seek(-4, SeekOrigin.Current); BUVChunk = new BUVChunk(stream); } ReadAllBasePalettes(reader); ReadAllTextures(reader); if (BUVChunk != null) { // TODO: is it always texture 0? TextureBundle bundle = TextureBundles[0]; BUVTextures = new Bitmap[BUVChunk.Entries.Length]; for (int i = 0; i < BUVTextures.Length; i++) { BUVEntry entry = BUVChunk.Entries[i]; using (Bitmap sourceImage = bundle.CreateTexture(FetchPalette(bundle.TextureFormat, entry.PaletteIndex))) { BUVTextures[i] = sourceImage.Clone(new Rectangle(entry.X, entry.Y, entry.Width, entry.Height), sourceImage.PixelFormat); } } } }
private static void ProcessInputFile(FileInfo inputFile, DirectoryInfo inputDir, DirectoryInfo outputDir) { try { if (!outputDir.Exists) { Directory.CreateDirectory(outputDir.FullName); } string displayPath = inputFile.FullName.Replace(inputDir.FullName, string.Empty).TrimStart(directorySeparators); IndentWriteLine("File '{0}'... ", displayPath); baseIndent = indent++; string relativeDirectory = inputFile.DirectoryName.TrimEnd(directorySeparators).Replace(inputDir.FullName.TrimEnd(directorySeparators), string.Empty).TrimStart(directorySeparators); if (keepFiles) { string existenceCheckPath = Path.Combine(outputDir.FullName, relativeDirectory); string existenceCheckPattern = Path.GetFileNameWithoutExtension(inputFile.Name) + "*"; if (Directory.Exists(existenceCheckPath) && Directory.EnumerateFiles(existenceCheckPath, existenceCheckPattern).Any()) { IndentWriteLine("Already exists."); return; } } using (FileStream fileStream = new FileStream(inputFile.FullName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { GxtBinary gxtInstance = new GxtBinary(fileStream); for (int i = 0; i < gxtInstance.TextureInfos.Length; i++) { string outputFilename = string.Format("{0} (Texture {1}).png", Path.GetFileNameWithoutExtension(inputFile.Name), i); FileInfo outputFile = new FileInfo(Path.Combine(outputDir.FullName, relativeDirectory, outputFilename)); SceGxtTextureInfo info = gxtInstance.TextureInfos[i]; IndentWriteLine("Texture #{0}: {1}x{2} ({3}, {4})", (i + 1), info.GetWidth(), info.GetHeight(), info.GetTextureFormat(), info.GetTextureType()); indent++; if (!outputFile.Directory.Exists) { Directory.CreateDirectory(outputFile.Directory.FullName); } gxtInstance.Textures[i].Save(outputFile.FullName, System.Drawing.Imaging.ImageFormat.Png); indent--; } if (gxtInstance.BUVChunk != null) { indent++; for (int i = 0; i < gxtInstance.BUVTextures.Length; i++) { string outputFilename = string.Format("{0} (Block {1}).png", Path.GetFileNameWithoutExtension(inputFile.Name), i); FileInfo outputFile = new FileInfo(Path.Combine(outputDir.FullName, relativeDirectory, outputFilename)); BUVEntry entry = gxtInstance.BUVChunk.Entries[i]; IndentWriteLine("Block #{0}: {1}x{2} (Origin X:{3}, Y:{4})", (i + 1), entry.Width, entry.Height, entry.X, entry.Y); indent++; if (!outputFile.Directory.Exists) { Directory.CreateDirectory(outputFile.Directory.FullName); } gxtInstance.BUVTextures[i].Save(outputFile.FullName, System.Drawing.Imaging.ImageFormat.Png); indent--; } indent--; } } } #if !DEBUG catch (VersionNotImplementedException vniEx) { IndentWriteLine("GXT version {0:D2} (0x{1:X8}) not implemented.", (vniEx.Version & 0xFFFF), vniEx.Version); } catch (FormatNotImplementedException fniEx) { IndentWriteLine("Format '{0}' not implemented.", fniEx.Format); } catch (PaletteNotImplementedException pniEx) { IndentWriteLine("Palette '{0}' not implemented.", pniEx.Format); } catch (TypeNotImplementedException tniEx) { IndentWriteLine("Type '{0}' not implemented.", tniEx.Type); } catch (UnknownMagicException umEx) { IndentWriteLine("Unknown magic number: {0}.", umEx.Message); } catch (Exception ex) { IndentWriteLine("Exception occured: {0}.", ex.Message); } #endif finally { indent = baseIndent; } }