private void Load(EndianBinaryReader input, GxGame game) { if (game == GxGame.SuperMonkeyBallDX) { input.ReadInt32(); } int numTextures = input.ReadInt32(); // Load texture definition headers TextureHeader[] texHdr = new TextureHeader[numTextures]; for (int i = 0; i < numTextures; i++) { texHdr[i].FormatRaw = input.ReadInt32(); texHdr[i].Offset = input.ReadInt32(); texHdr[i].Width = Convert.ToInt32(input.ReadUInt16()); texHdr[i].Height = Convert.ToInt32(input.ReadUInt16()); texHdr[i].LevelCount = Convert.ToInt32(input.ReadUInt16()); UInt16 check = input.ReadUInt16(); if ((game != GxGame.SuperMonkeyBallDX && check != 0x1234) || (game == GxGame.SuperMonkeyBallDX && check != 0x3412)) { throw new InvalidTplFileException("Invalid texture header (Field @0x0E)."); } } // Load textures data for (int i = 0; i < numTextures; i++) { TplTexture tex = new TplTexture(); if (texHdr[i].Offset != 0 && texHdr[i].Width != 0 && texHdr[i].Height != 0 && texHdr[i].LevelCount != 0) // Texture with defined levels { if (!Enum.IsDefined(typeof(GxTextureFormat), texHdr[i].FormatRaw)) { throw new InvalidTplFileException("Invalid texture header (invalid format."); } if (game == GxGame.SuperMonkeyBallDX) { input.BaseStream.Position = texHdr[i].Offset + 0x20; } else { input.BaseStream.Position = texHdr[i].Offset; } tex.LoadTextureData(input, game, (GxTextureFormat)texHdr[i].FormatRaw, texHdr[i].Width, texHdr[i].Height, texHdr[i].LevelCount); } else if (texHdr[i].Offset == 0 && texHdr[i].Width == 0 && texHdr[i].Height == 0 && texHdr[i].LevelCount == 0) // Texture with no defined levels { tex.DefineEmptyTexture(texHdr[i].FormatRaw); } else { throw new InvalidTplFileException("Invalid texture header (invalid combination of fields)."); } Add(tex); } }
public static DDSHeader ToDDSHeader(this TextureHeader header) { DDSHeader ret = new DDSHeader { magic = 0x20534444, size = 124, flags = (0x1 | 0x2 | 0x4 | 0x1000 | 0x20000), height = header.height, width = header.width, linearSize = 0, depth = 0, mipmapCount = 1, format = header.Format().ToPixelFormat(), caps1 = 0x1000, caps2 = 0, caps3 = 0, caps4 = 0, reserved2 = 0 }; if (header.surfaces > 1) { ret.caps1 = (0x8 | 0x1000); ret.format = TextureType.Unknown.ToPixelFormat(); } if (header.IsCubemap()) { ret.caps2 = 0xFE00; } if (header.mips > 1 && (header.indice == 1 || header.IsCubemap())) { ret.mipmapCount = header.mips; ret.caps1 = (0x8 | 0x1000 | 0x400000); } return(ret); }
public override void ReadFromStream(Stream stream) { EndianBinaryReader reader = new EndianBinaryReader(stream, Program.Endianness); Unknown0x00 = reader.ReadUInt32(); TextureHeader = new TextureHeader(stream); PixelFormat pixelFormat; byte[] pixelData; if (!pixelFormatMap.ContainsKey(TextureHeader.Format) || !pixelFormatProviders.ContainsKey(TextureHeader.Format)) { pixelFormat = PixelFormat.Format32bppArgb; pixelData = new byte[TextureHeader.Width * TextureHeader.Height * (Bitmap.GetPixelFormatSize(pixelFormat) / 8)]; } else { pixelFormatProviders[TextureHeader.Format](reader, TextureHeader, out pixelFormat, out pixelData); } Image = new Bitmap(TextureHeader.Width, TextureHeader.Height, pixelFormat); BitmapData bmpData = Image.LockBits(new Rectangle(0, 0, Image.Width, Image.Height), ImageLockMode.ReadWrite, Image.PixelFormat); byte[] pixelsForBmp = new byte[bmpData.Height * bmpData.Stride]; int bytesPerPixel = (Bitmap.GetPixelFormatSize(Image.PixelFormat) / 8); for (int y = 0; y < bmpData.Height; y++) { Buffer.BlockCopy(pixelData, y * bmpData.Width * bytesPerPixel, pixelsForBmp, y * bmpData.Stride, bmpData.Width * bytesPerPixel); } Marshal.Copy(pixelsForBmp, 0, bmpData.Scan0, pixelsForBmp.Length); Image.UnlockBits(bmpData); }
public static void WriteFile(TextureHeader header, byte[] data, string path) { using (var output = File.Create(path)) { WriteFile(header, data, output); } }
public static TextureHeader Read(BinaryReader aReader, InfoHeader aInfo) { var texture = new TextureHeader(); texture.ReadBase(aReader); // Textures contain an EntryListOffset var entryListAddress = aReader.ReadInt32() + aInfo.RootAddress; // Addresses we read are offset from the RootAddress stored in the InfoHeader. aReader.BaseStream.Position = entryListAddress; // Now we read the EntryListHeader var entryListHeader = EntryListHeader.Read(aInfo, aReader); // Then we read the entries, which are located at ListAddress + (index * 20) + 4 foreach (int index in Enumerable.Range(0, (int)entryListHeader.Count)) { aReader.BaseStream.Position = entryListHeader.ListAddress + (index * 20) + 4; var entry = Entry.Read(aInfo, aReader); texture.Entries.Add(entry); } texture.GoToEnd(aReader); return(texture); }
private static void SetupExtendedHeader(out ExtendedHeader header, TextureHeader textureHeader) { header.Format = DDSHelpers.GetDXGIFormat(textureHeader.Format); header.Dimension = 3; header.MiscFlags = 0; header.ArraySize = 1; header.MiscFlags2 = 0; }
/// <summary> /// /// </summary> // Start is called before the first frame update void Start() { isPause = false; isPlay = false; isFinish = false; isAsyncGPUReadBackFinish = false; renderTexture = null; textureHeader = null; StartCoroutine(VideoRecoder()); }
private static bool ConvertTexture(Superbundle.BundleInfo bundleInfo, Superbundle.ResourceInfo resourceInfo, ICatalogEntryInfo entry, string outputPath, CatalogLookup catalogLookup, List <TableOfContentsFile> commonBundles) { TextureHeader textureHeader; using (var temp = new MemoryStream()) { Extraction.Extract(resourceInfo, entry, temp); temp.Position = 0; textureHeader = TextureHeader.Read(temp); if (temp.Position != temp.Length) { throw new FormatException(); } } if (textureHeader.Type != TextureType._2d) { return(false); } if (textureHeader.Unknown00 != 0 || textureHeader.Unknown04 != 0 || textureHeader.Unknown10 != 0 || textureHeader.Unknown14 != 0 || textureHeader.Unknown1C != 1) { throw new FormatException(); } SHA1 chunkSHA1; if (GetChunkSHA1(bundleInfo, commonBundles, textureHeader.DataChunkId, out chunkSHA1) == false) { throw new InvalidOperationException(); } var dataEntry = catalogLookup.GetEntry(chunkSHA1, textureHeader.TotalSize); byte[] dataBytes; using (var temp = new MemoryStream()) { Extraction.Extract(dataEntry, textureHeader.TotalSize, temp); temp.Position = 0; dataBytes = temp.GetBuffer(); } DDSUtils.WriteFile(textureHeader, dataBytes, outputPath + ".dds"); return(true); }
private static void SetupHeader(out Header header, TextureHeader textureHeader) { header = Header.GetDefault(); header.Size = Header.GetSize(); header.Width = textureHeader.Width; header.Height = textureHeader.Height; header.MipMapCount = textureHeader.MipCount; header.Flags = textureHeader.MipCount > 1 ? (HeaderFlags)0x2100F : (HeaderFlags)0xA1007; //header.PitchOrLinearSize = ... header.PixelFormat.Size = PixelFormat.GetSize(); header.SurfaceFlags = 0x401008; }
public Texture(Stream headerStream, Stream dataStream) { using (BinaryReader headerReader = new BinaryReader(headerStream)) using (BinaryReader dataReader = new BinaryReader(dataStream)) { header = headerReader.Read <TextureHeader>(); if (header.dataSize != 0) { return; } format = header.Format(); if (format == TextureType.Unknown) { return; } rawHeader = dataReader.Read <RawTextureHeader>(); size = rawHeader.imageSize / header.Format().ByteSize(); color1 = new uint[size]; color2 = new uint[size]; color3 = new ushort[size]; color4 = new ushort[size]; color5 = new uint[size]; if ((byte)header.format > 72) { for (int i = 0; i < size; ++i) { color3[i] = dataReader.ReadUInt16(); } for (int i = 0; i < size; ++i) { color4[i] = dataReader.ReadUInt16(); color5[i] = dataReader.ReadUInt32(); } } if ((byte)header.format < 80) { for (int i = 0; i < size; ++i) { color1[i] = dataReader.ReadUInt32(); } for (int i = 0; i < size; ++i) { color2[i] = dataReader.ReadUInt32(); } } } loaded = true; }
public static HwTexture FromData(BinaryReader reader) { var header = new TextureHeader(); // 32 byte texture header header.Type = (BaseTextureType)reader.ReadByte(); // 0 _ = reader.ReadByte(); // 1 header.Width = reader.ReadUInt16(); // 2 header.Height = reader.ReadUInt16(); // 4 header.TexArraySliceCount = 1; header.Tex3DDepth = 1; switch (header.Type) { case BaseTextureType._2D: case BaseTextureType.CubeMap: _ = reader.ReadUInt16(); break; case BaseTextureType._3D: header.Tex3DDepth = 1u << reader.ReadByte(); _ = reader.ReadByte(); break; case BaseTextureType._2DArray: header.TexArraySliceCount = reader.ReadUInt16(); break; default: throw new NotImplementedException("Unknown texture type"); } header.MipCount = reader.ReadByte(); // 8 header.PixelFormat = (BasePixelFormat)reader.ReadByte(); // 9 header.Unknown1 = reader.ReadByte(); // 10 header.Unknown2 = reader.ReadByte(); // 11 header.Unknown3 = reader.ReadByte(); // 12 header.Flags = reader.ReadByte(); // 13 header.Unknown4 = reader.ReadByte(); // 14 Something to do with mips. Autogen? header.Unknown5 = reader.ReadByte(); // 15 header.ResourceGUID = new BaseGGUUID().FromData(reader); // 16 var x = new HwTexture(); x.Header = header; uint hwTextureSize = reader.ReadUInt32(); x.HwTextureData = reader.ReadBytesStrict(hwTextureSize); return(x); }
private static bool ConvertTexture(MemoryStream data, string outputPath, ChunkLookup chunkLookup, ChunkLoader chunkLoader) { var textureHeader = TextureHeader.Read(data); if (textureHeader.Type != TextureType._2d) { return(false); } if (textureHeader.Unknown10 != 0 || (textureHeader.Flags != TextureFlags.None && textureHeader.Flags != TextureFlags.Unknown0 && textureHeader.Flags != (TextureFlags.Unknown0 | TextureFlags.Unknown3) && textureHeader.Flags != TextureFlags.Unknown5) || textureHeader.Unknown1C != 1) { throw new FormatException(); } SHA1 chunkSHA1; long size; if (chunkLookup.GetChunkSHA1(textureHeader.DataChunkId, out chunkSHA1, out size) == false) { throw new InvalidOperationException(); } var dataChunkInfo = chunkLookup.GetChunkVariant(chunkSHA1, size); if (dataChunkInfo == null) { throw new InvalidOperationException(); } byte[] dataBytes; using (var temp = new MemoryStream()) { chunkLoader.Load(dataChunkInfo, textureHeader.TotalSize, temp); temp.Position = 0; dataBytes = temp.GetBuffer(); } using (var output = File.Create(outputPath)) { DDSUtils.WriteFile(textureHeader, dataBytes, output); } return(true); }
internal Texture(AssetManager manager, string name, string file, TextureLoadSettings loadSettings, TextureImporterBase importer) : base(manager, AssetType.File, name, file) { if (importer == null) { throw new ArgumentNullException("importer"); } this.loadSettings = loadSettings; this.importer = importer; this.header = importer.LoadHeader(file, loadSettings); }
private void Read(BinaryReader reader) { Header = reader.Read <TextureHeader>(); if (Header.DataSize == 0 || Header.PayloadCount > 0) { PayloadRequired = true; return; } reader.Seek(128); Data = new byte[Header.DataSize]; reader.Read(Data, 0, (int)Header.DataSize); }
static void SplitPalettes(string filename, bool isTEX) { TextureHeader header; var palettes = new List <TexturePalette>(); using (FileStream infile = new FileStream(filename, FileMode.Open, FileAccess.Read)) { if (isTEX) { header = TextureHeader.ReadFromTEXFile(infile); } else { header = TextureHeader.ReadFromCDPFile(infile); } for (int i = 0; i < header.PaletteCount; i++) { if (isTEX) { palettes.Add(TexturePalette.ReadFromFile <TEXPalette>(infile, i, header.PaletteIDs[i])); } else { palettes.Add(TexturePalette.ReadFromFile <CDPPalette>(infile, i, header.PaletteIDs[i])); } } } filename = filename.Replace('.', '_'); string paletteIDsText = ""; foreach (TexturePalette palette in palettes) { string paletteID = string.Format("{0:X2}", palette.PaletteID); paletteIDsText += paletteID + "\r\n"; using (FileStream paletteFile = new FileStream(filename + "_" + paletteID + ".gtp", FileMode.Create, FileAccess.Write)) { paletteFile.Write(palette.PaletteData, 0, palette.PaletteData.Length); } } using (FileStream indexFile = new FileStream(filename + ".txt", FileMode.Create, FileAccess.Write)) { byte[] stringBytes = Encoding.ASCII.GetBytes(paletteIDsText.ToCharArray()); indexFile.Write(stringBytes, 0, stringBytes.Length); } }
public override TextureHeader LoadHeader(string file, TextureLoadSettings settings) { if (file == null) { throw new ArgumentNullException("file"); } header = new TextureHeader(); FileStream stream = new FileStream(file, FileMode.Open); BinaryReader reader = new BinaryReader(stream); try { //Header + Magic Word int magicWordSize = 4; byte[] magicWordData = reader.ReadBytes(magicWordSize); string magicWord = Encoding.ASCII.GetString(magicWordData).Trim(); if (magicWord == "DDS") { int headerSize = 124; byte[] headerData = reader.ReadBytes(headerSize); this.headerDDS = DDSTextureImporter.ByteArrayToStruct <Header>(headerData, 0); header.Width = (int)this.headerDDS.Width; header.Height = (int)this.headerDDS.Height; header.Depth = (int)Depth; header.MipLevels = this.headerDDS.MipMapCount > 0 ? (int)this.headerDDS.MipMapCount : 1; headerDXT10 = new HeaderDXT10(); if (this.headerDDS.PixelFormat.Flags == PixelFormatFlags.FourCC && this.headerDDS.PixelFormat.FourCC == "DXT10") { hasHeaderDXT10 = true; byte[] headerDxt10Data = reader.ReadBytes(Marshal.SizeOf(typeof(HeaderDXT10))); headerDXT10 = DDSTextureImporter.ByteArrayToStruct <HeaderDXT10>(headerDxt10Data, 0); } header.Format = GetTextureFormat(); } } finally { reader.Close(); stream.Close(); } IsHeaderLoaded = true; return(header); }
private static void PixelProviderARGB4444(EndianBinaryReader reader, TextureHeader header, out PixelFormat pixelFormat, out byte[] pixelData) { byte[] tempData; PixelProviderDirect(reader, header, out pixelFormat, out tempData); pixelFormat = pixelFormatMap[header.Format]; pixelData = new byte[tempData.Length << 1]; for (int i = 0, j = 0; i < tempData.Length; i += 2, j += 4) { pixelData[j + 0] = (byte)((tempData[i] & 0x0F) | ((tempData[i] & 0x0F) << 4)); pixelData[j + 1] = (byte)((tempData[i] & 0xF0) | ((tempData[i] & 0xF0) >> 4)); pixelData[j + 2] = (byte)((tempData[i + 1] & 0x0F) | ((tempData[i + 1] & 0x0F) << 4)); pixelData[j + 3] = (byte)((tempData[i + 1] & 0xF0) | ((tempData[i + 1] & 0xF0) >> 4)); } }
internal Texture(AssetManager manager, string name, ITexture2D handle) : base(manager, AssetType.Wrapper, name, null) { if (handle == null) { throw new ArgumentNullException("handle"); } this.handle = handle; this.header = new TextureHeader() { Format = handle.Format, Width = handle.Width, Height = handle.Height }; }
private static void PixelProviderDirect(EndianBinaryReader reader, TextureHeader header, out PixelFormat pixelFormat, out byte[] pixelData) { pixelFormat = pixelFormatMap[header.Format]; int bytesPerPixel = (Bitmap.GetPixelFormatSize(pixelFormat) / 8); pixelData = new byte[header.Width * header.Height * bytesPerPixel]; for (int i = 0; i < pixelData.Length; i += bytesPerPixel) { for (int j = bytesPerPixel - 1; j >= 0; j--) { pixelData[i + j] = reader.ReadByte(); } } }
public void DeserializeExtraData(BinaryReader reader) { Header = new TextureHeader(); // 32 byte texture header Header.Type = (ETextureType)reader.ReadByte(); // 0 _ = reader.ReadByte(); // 1 Header.Width = reader.ReadUInt16(); // 2 Header.Height = reader.ReadUInt16(); // 4 Header.TexArraySliceCount = 1; Header.Tex3DDepth = 1; switch (Header.Type) { case ETextureType._2D: case ETextureType.CubeMap: _ = reader.ReadUInt16(); break; case ETextureType._3D: Header.Tex3DDepth = 1u << reader.ReadByte(); _ = reader.ReadByte(); break; case ETextureType._2DArray: Header.TexArraySliceCount = reader.ReadUInt16(); break; default: throw new NotImplementedException("Unknown texture type"); } Header.MipCount = reader.ReadByte(); // 8 Header.PixelFormat = (EPixelFormat)reader.ReadByte(); // 9 Header.Unknown1 = reader.ReadByte(); // 10 Header.Unknown2 = reader.ReadByte(); // 11 Header.Unknown3 = reader.ReadByte(); // 12 Header.Flags = reader.ReadByte(); // 13 Header.Unknown4 = reader.ReadByte(); // 14 Something to do with mips. Autogen? Header.Unknown5 = reader.ReadByte(); // 15 Header.ResourceGUID = GGUUID.FromData(reader); // 16 uint hwTextureSize = reader.ReadUInt32(); HwTextureData = reader.ReadBytesStrict(hwTextureSize); }
public TextureLinear(Stream imageStream, bool keepOpen = false) { using (BinaryReader imageReader = new BinaryReader(imageStream, System.Text.Encoding.Default, keepOpen)) { header = imageReader.Read <TextureHeader>(); size = header.dataSize; format = header.format; if (header.dataSize == 0) { return; } imageStream.Seek(128, SeekOrigin.Begin); data = new byte[header.dataSize]; imageStream.Read(data, 0, (int)header.dataSize); } loaded = true; }
public void Extract(WpdEntry entry, Stream output, Lazy <Stream> headers, Lazy <Stream> content, Byte[] buff) { headers.Value.Position = entry.Offset; SectionHeader sectionHeader = headers.Value.ReadContent <SectionHeader>(); TextureHeader textureHeader = headers.Value.ReadContent <TextureHeader>(); GtexData gtex = headers.Value.ReadContent <GtexData>(); DdsHeader header = DdsHeaderDecoder.FromGtexHeader(gtex.Header); DdsHeaderEncoder.ToFileStream(header, output); foreach (GtexMipMapLocation mipMap in gtex.MipMapData) { content.Value.Position = mipMap.Offset; content.Value.CopyToStream(output, mipMap.Length, buff); } }
protected static TextureHeader ReadFromFile(FileStream file, int paletteCountPosition, int paletteIDListPosition) { var header = new TextureHeader(); long originalPosition = file.Position; file.Position = paletteCountPosition; header.PaletteCount = (byte)file.ReadByte(); file.Position = paletteIDListPosition; for (int i = 0; i < header.PaletteCount; i++) { header.PaletteIDs.Add((byte)file.ReadByte()); } file.Position = originalPosition; return(header); }
private void Read(BinaryReader reader) { Header = reader.Read <TextureHeader>(); if (Header.PayloadCount == 1) { Logger.Debug("teTexture", $"texture {((reader.BaseStream is GuidStream gs) ? teResourceGUID.AsString(gs.GUID) : "internal") } is mip"); } if (Header.DataSize == 0 || Header.PayloadCount > 0) { PayloadRequired = true; Payloads = new teTexturePayload[Header.PayloadCount]; return; } reader.Seek(0x20); Data = new byte[Header.DataSize]; reader.Read(Data, 0, (int)Header.DataSize); }
private void ReadFile(BinaryReader aReader) { string identifier = new string(aReader.ReadChars(4)); // The first section should be the Info Section Header. Trace.Assert(HeaderTag.Info.Equals(identifier)); var info = Xno.InfoHeader.Read(aReader); // Now we read the rest of the sections for (var i = 0; i < info.SectionCount; ++i) { identifier = new string(aReader.ReadChars(4)); switch (identifier) { case HeaderTag.Texture: TextureHeader.Read(aReader, info); break; case HeaderTag.Effect: EffectHeader.Read(aReader); break; case HeaderTag.Bones: BoneHeader.Read(aReader); break; case HeaderTag.Object: ObjectHeader.Read(aReader, info); break; case HeaderTag.Motion: MotionHeader.Read(aReader); break; } } identifier = new string(aReader.ReadChars(4)); Trace.Assert(HeaderTag.Offset.Equals(identifier)); var offsetHeader = OffsetHeader.Read(aReader); identifier = new string(aReader.ReadChars(4)); Trace.Assert(HeaderTag.Footer.Equals(identifier)); var footerHeader = FooterHeader.Read(aReader); identifier = new string(aReader.ReadChars(4)); Trace.Assert(HeaderTag.End.Equals(identifier)); var endHeader = EndHeader.Read(aReader); }
private void OnMessageEvent(MessageEventArgs args) { //Debug.Log("OnMessageEvent"); var json = System.Text.Encoding.ASCII.GetString(args.data); editorSendData = JsonUtility.FromJson <PlayerView.EditorSendData>(json); switch (editorSendData.command) { case PlayerView.Command.Play: { frameCountMax = editorSendData.frameCount; if (editorSendData.isUseAsyncGPUReadback && SystemInfo.supportsAsyncGPUReadback) { captureMode = CaptureMode.AsyncGPUReadBack; } else { captureMode = CaptureMode.Normal; } frameCount = 0; isPlay = true; isAsyncGPUReadBackFinish = true; textureHeader = null; } break; case PlayerView.Command.Pause: { isPause = !isPause; } break; case PlayerView.Command.Stop: { isPlay = false; } break; } }
private void Load(EndianBinaryReader input, GxGame game, GeneratedTextureHeader?newHeader) { if (game == GxGame.SuperMonkeyBallDX) { input.ReadInt32(); } // If there is a header, use the value from that header, otherwise use the generated header value int numTextures = (newHeader == null) ? (numTextures = input.ReadInt32()) : (numTextures = newHeader.Value.textureCount); // Load texture definition headers TextureHeader[] texHdr = new TextureHeader[numTextures]; if (newHeader == null) { for (int i = 0; i < numTextures; i++) { texHdr[i].FormatRaw = input.ReadInt32(); texHdr[i].Offset = input.ReadInt32(); texHdr[i].Width = Convert.ToInt32(input.ReadUInt16()); texHdr[i].Height = Convert.ToInt32(input.ReadUInt16()); texHdr[i].LevelCount = Convert.ToInt32(input.ReadUInt16()); UInt16 check = input.ReadUInt16(); if ((game != GxGame.SuperMonkeyBallDX && check != 0x1234) || (game == GxGame.SuperMonkeyBallDX && check != 0x3412)) { throw new InvalidTplFileException("Invalid texture header (Field @0x0E)."); } } } // Creates a new texture header from provided texture header characteristics else { // The length of the header after this operation's completion int initialOffset = newHeader.Value.textureCount * 16; // Size of a texture based on how many bytes per pixel int texSize = newHeader.Value.textureHeight * newHeader.Value.textureWidth * GxTextureFormatCodec.GetCodec(newHeader.Value.textureFormat).BitsPerPixel / 8; // Maximum possible offset for the TPL int maxOffset = initialOffset + (texSize) * numTextures; // Iteration variable for referencing the index of the texture header int iteration; for (int iterateOffset = initialOffset; iterateOffset < maxOffset; iterateOffset += texSize) { iteration = (iterateOffset - initialOffset) / texSize; texHdr[iteration].FormatRaw = (int)newHeader.Value.textureFormat; texHdr[iteration].Width = newHeader.Value.textureWidth; texHdr[iteration].Height = newHeader.Value.textureHeight; texHdr[iteration].Offset = iterateOffset; texHdr[iteration].LevelCount = newHeader.Value.textureMipmapCount; } } // Load textures data for (int i = 0; i < numTextures; i++) { TplTexture tex = new TplTexture(); if (texHdr[i].Offset != 0 && texHdr[i].Width != 0 && texHdr[i].Height != 0 && texHdr[i].LevelCount != 0) // Texture with defined levels { if (game != GxGame.SuperMonkeyBallDX && !Enum.IsDefined(typeof(GxTextureFormat), texHdr[i].FormatRaw)) { throw new InvalidTplFileException("Invalid texture header (invalid format."); } if (game == GxGame.SuperMonkeyBallDX) { input.BaseStream.Position = texHdr[i].Offset; int formatRaw = input.ReadInt32(); switch (formatRaw) { case 0x0C: texHdr[i].FormatRaw = 0x0E; break; case 0x1A: texHdr[i].FormatRaw = 0x01; break; case 0x0E: texHdr[i].FormatRaw = 0x05; break; default: int x = 5; break; } texHdr[i].Width = input.ReadInt32(); texHdr[i].Height = input.ReadInt32(); texHdr[i].LevelCount = input.ReadInt32(); // Compressed? input.ReadInt32(); // If uncompressed, data length? input.ReadInt32(); // Some other length (for compressed)? input.ReadInt32(); // Zero? input.ReadInt32(); if (!Enum.IsDefined(typeof(GxTextureFormat), texHdr[i].FormatRaw)) { throw new InvalidTplFileException("Invalid texture header (invalid format."); } } else { if (newHeader == null) { input.BaseStream.Position = texHdr[i].Offset; } else { input.BaseStream.Position = texHdr[i].Offset - (newHeader.Value.textureCount * 16); } } tex.LoadTextureData(input, game, (GxTextureFormat)texHdr[i].FormatRaw, texHdr[i].Width, texHdr[i].Height, texHdr[i].LevelCount); } else if (texHdr[i].Offset == 0 && texHdr[i].Width == 0 && texHdr[i].Height == 0 && texHdr[i].LevelCount == 0) // Texture with no defined levels { tex.DefineEmptyTexture(texHdr[i].FormatRaw); } else { throw new InvalidTplFileException("Invalid texture header (invalid combination of fields)."); } Add(tex); } }
private void Load(EndianBinaryReader input, GcGame game) { int numTextures = input.ReadInt32(); // Load texture definition headers TextureHeader[] texHdr = new TextureHeader[numTextures]; for (int i = 0; i < numTextures; i++) { texHdr[i].FormatRaw = input.ReadInt32(); texHdr[i].Offset = input.ReadInt32(); texHdr[i].Width = Convert.ToInt32(input.ReadUInt16()); texHdr[i].Height = Convert.ToInt32(input.ReadUInt16()); texHdr[i].LevelCount = Convert.ToInt32(input.ReadUInt16()); if (input.ReadUInt16() != 0x1234) { throw new InvalidTplFileException("Invalid texture header (Field @0x0E)."); } } // Load textures data for (int i = 0; i < numTextures; i++) { TplTexture tex = new TplTexture(); if (texHdr[i].Offset != 0 && texHdr[i].Width != 0 && texHdr[i].Height != 0 && texHdr[i].LevelCount != 0) // Texture with defined levels { if (!Enum.IsDefined(typeof(GcTextureFormat), texHdr[i].FormatRaw)) { throw new InvalidTplFileException("Invalid texture header (invalid format)."); } // Calculate the size of the texture from the next non-empty texture offset int endOffset = Convert.ToInt32(input.BaseStream.Length); for (int j = i + 1; j < numTextures; j++) { if (texHdr[j].Offset != 0) { endOffset = texHdr[j].Offset; break; } } int size = endOffset - texHdr[i].Offset; input.BaseStream.Position = texHdr[i].Offset; tex.LoadTextureData(input, game, (GcTextureFormat)texHdr[i].FormatRaw, size, texHdr[i].Width, texHdr[i].Height, texHdr[i].LevelCount); } else if (texHdr[i].Offset == 0 && texHdr[i].Width == 0 && texHdr[i].Height == 0 && texHdr[i].LevelCount == 0) // Texture with no defined levels { tex.DefineEmptyTexture(texHdr[i].FormatRaw); } else { throw new InvalidTplFileException("Invalid texture header (invalid combination of fields)."); } Add(tex); } }
public static void WriteFile(TextureHeader textureHeader, byte[] data, Stream output) { const Endian endian = Endian.Little; output.WriteString("DDS ", Encoding.ASCII); switch (textureHeader.Format) { case TextureFormat.BC1_UNORM: case TextureFormat.BC1_SRGB: case TextureFormat.BC2_UNORM: case TextureFormat.BC2_SRGB: case TextureFormat.BC3_UNORM: case TextureFormat.BC3_SRGB: case TextureFormat.BC4_UNORM: case TextureFormat.BC5_UNORM: { Header header; SetupHeader(out header, textureHeader); header.PixelFormat.FourCC = DDSHelpers.GetFourCC(textureHeader.Format); header.PixelFormat.Flags = (PixelFormatFlags)4; header.Write(output, endian); output.WriteBytes(data); break; } case TextureFormat.BC6U_FLOAT: case TextureFormat.BC7_UNORM: case TextureFormat.BC7_SRGB: case TextureFormat.R9G9B9E5_FLOAT: // TODO(gibbed): probably not right { Header header; ExtendedHeader extendedHeader; SetupHeader(out header, textureHeader); header.PixelFormat.FourCC = 0x30315844; header.PixelFormat.Flags = (PixelFormatFlags)4; SetupExtendedHeader(out extendedHeader, textureHeader); header.Write(output, endian); extendedHeader.Write(output, endian); output.WriteBytes(data); break; } case TextureFormat.R8_UNORM: { Header header; SetupHeader(out header, textureHeader); header.PixelFormat.RedBitMask = 0x000000FF; header.PixelFormat.GreenBitMask = 0x00000000; header.PixelFormat.BlueBitMask = 0x00000000; header.PixelFormat.AlphaBitMask = 0x00000000; header.PixelFormat.RGBBitCount = 8; header.PitchOrLinearSize = textureHeader.Width; header.PixelFormat.Flags = PixelFormatFlags.Luminance; header.Write(output, endian); output.WriteBytes(data); break; } case TextureFormat.R8G8B8A8_UNORM: case (TextureFormat)20: // R8G8B8A8_SRGB //case GX2SurfaceFormat.TCS_R8_G8_B8_A8_SRGB: { Header header; SetupHeader(out header, textureHeader); header.PixelFormat.RedBitMask = 0x000000FF; header.PixelFormat.GreenBitMask = 0x0000FF00; header.PixelFormat.BlueBitMask = 0x00FF0000; header.PixelFormat.AlphaBitMask = 0xFF000000; header.PixelFormat.RGBBitCount = 32; header.PitchOrLinearSize = (uint)textureHeader.Width * 4; header.PixelFormat.Flags = PixelFormatFlags.RGBA; header.Write(output, endian); output.WriteBytes(data); break; } case TextureFormat.R10G10B10A2_UNORM: { Header header; SetupHeader(out header, textureHeader); header.PixelFormat.RedBitMask = 0x000003FF; header.PixelFormat.GreenBitMask = 0x000FFC00; header.PixelFormat.BlueBitMask = 0x3FF00000; header.PixelFormat.AlphaBitMask = 0xC0000000; header.PixelFormat.RGBBitCount = 32; header.PitchOrLinearSize = (uint)textureHeader.Width * 4; header.PixelFormat.Flags = PixelFormatFlags.RGBA; header.Write(output, endian); output.WriteBytes(data); break; } case TextureFormat.R32G32B32A32_FLOAT: { Header header; SetupHeader(out header, textureHeader); header.PixelFormat.FourCC = 0x00000074; header.PitchOrLinearSize = (uint)textureHeader.Width * 16; header.PixelFormat.Flags = (PixelFormatFlags)4; header.Write(output, endian); output.WriteBytes(data); break; } case TextureFormat.R16G16B16A16_FLOAT: { Header header; SetupHeader(out header, textureHeader); header.PixelFormat.FourCC = 0x00000071; header.PitchOrLinearSize = (uint)textureHeader.Width * 8; header.PixelFormat.Flags = (PixelFormatFlags)4; header.Write(output, endian); output.WriteBytes(data); break; } default: { throw new NotSupportedException(); } } }
private static void PixelProviderDXTx(EndianBinaryReader reader, TextureHeader header, out PixelFormat pixelFormat, out byte[] pixelData) { pixelFormat = pixelFormatMap[header.Format]; pixelData = DXTx.Decompress(reader, header); }