public List <Bitmap> GetBitmaps() { List <Bitmap> list = new List <Bitmap>(); for (uint depth = 0; depth < TXM.Depth; ++depth) { Data.Position = 0; Stream plane = TXM.GetSinglePlane(Data, depth); switch (TXM.Format) { case TextureFormat.DXT1a: case TextureFormat.DXT1b: case TextureFormat.DXT5a: case TextureFormat.DXT5b: { plane.Position = 0; DDSHeader header = DDSHeader.Generate(TXM.Width, TXM.Height, TXM.Mipmaps, (TXM.Format == TextureFormat.DXT1a || TXM.Format == TextureFormat.DXT1b) ? Textures.TextureFormat.DXT1a : Textures.TextureFormat.DXT5); list.Add(new DDS(header, plane).ConvertToBitmap()); } break; default: for (uint mip = 0; mip < TXM.Mipmaps; ++mip) { (uint width, uint height, IPixelOrderIterator pxit, IColorFetchingIterator colit) = GenerateIterators(plane, mip); var bmp = colit.ConvertToBitmap(pxit, width, height); list.Add(bmp); } break; } } return(list); }
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 static Texture Encode(Stream source) { var ddsHeader = new DDSHeader(source); int depth = 1; if (ddsHeader.Flags.HasFlag(DDSHeaderFlags.Depth)) { depth = ddsHeader.Depth; } int mipMapCount = 1; if (ddsHeader.Flags.HasFlag(DDSHeaderFlags.MipMapCount)) { mipMapCount = ddsHeader.MipMapCount; } var format = TextureUtilities.GetTextureFormat(ddsHeader.PixelFormat); var texture = new Texture(ddsHeader.Width, ddsHeader.Height, format, depth, mipMapCount); foreach (var level in texture.EnumerateLevels()) { foreach (var mipMap in level) { source.Read(mipMap.Data, 0, mipMap.Data.Length); } } return(texture); }
private void ExportDXT5(string path = "") { bool ok = !(path == ""); SaveFileDialog FileDialog1 = new SaveFileDialog(); FileDialog1.Filter = "DDS Files(*.dds)|*.dds"; if (ok || FileDialog1.ShowDialog() == DialogResult.OK) { if (!ok) { path = FileDialog1.FileName; } FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write); DDS = CreateHeaderDDS(); DDS.dwWidth = ImageSizeX; DDS.dwHeight = ImageSizeY; DDS.ddspf.dwFourCC = 0x35545844; byte[] buff = StructureToByteArray(DDS); fs.Write(buff, 0, buff.Length); fs.Write(memory, 0, memsize); fs.Close(); if (!ok) { MessageBox.Show("Done"); } } }
public FieldTexturePS3(byte[] ddsData) { Field00 = 0x020200FF; Field08 = 0x00000001; Field0C = 0x00000000; Flags = FieldTextureFlags.Flag2 | FieldTextureFlags.Flag4 | FieldTextureFlags.Flag80; var ddsHeader = new DDSHeader(ddsData); var data = new byte[ddsData.Length - ddsHeader.Size - 4]; Array.Copy(ddsData, ddsHeader.Size + 4, data, 0, data.Length); if (ddsHeader.PixelFormat.FourCC == DDSPixelFormatFourCC.DXT3) { Flags |= FieldTextureFlags.DXT3; } else if (ddsHeader.PixelFormat.FourCC == DDSPixelFormatFourCC.DXT5) { Flags |= FieldTextureFlags.DXT5; } MipMapCount = ( byte )ddsHeader.MipMapCount; Field1A = 2; Field1B = 0; Field1C = 0xAAE4; Width = ( short )ddsHeader.Width; Height = ( short )ddsHeader.Height; Field24 = 1; Data = data; }
private static void LoadDXT(out UTexture2D tex, string effectivePath, bool mipmap, string fileNamePath) { byte[] bytes = SIO.File.ReadAllBytes(effectivePath); SIO.BinaryReader binaryReader = new SIO.BinaryReader(new SIO.MemoryStream(bytes)); uint num = binaryReader.ReadUInt32(); if (num != DDSValues.uintMagic) { throw new Error("DDS: File {0} is not a DDS format file!", fileNamePath); } DDSHeader ddSHeader = new DDSHeader(binaryReader); TextureFormat tf = TextureFormat.Alpha8; if (ddSHeader.ddspf.dwFourCC == DDSValues.uintDXT1) { tf = TextureFormat.DXT1; } if (ddSHeader.ddspf.dwFourCC == DDSValues.uintDXT5) { tf = TextureFormat.DXT5; } if (tf == TextureFormat.Alpha8) { throw new Error("DDS: TextureFormat {0} File {1} is not supported!", tf, fileNamePath); } tex = LoadDXT(bytes, tf, mipmap); }
public DDSHeader CreateHeader(int pixelWidth, int pixelHeight, uint fourCC) { if (pixelHeight < 0 || pixelWidth < 0) { throw new InvalidOperationException("Image width or height is negative."); } var pixelFormat = new DDSPixelFormat { Size = 32, Flags = 0x4, FourCC = fourCC }; var header = new DDSHeader { Size = 124, // has to be 124bytes ¯\_(ツ)_/¯ Flags = Helpers.DDSMinFlags(), Height = (uint)pixelHeight, Width = (uint)pixelWidth, PixelFormat = pixelFormat, MipMapCount = 0, Caps = 0x1000 // texture, we don't handle harder things right now }; header.PitchOrLinearSize = Math.Max(1, (header.Width + 3) / 4) * Math.Max(1, (header.Height + 3) / 4) * 8; return(header); }
internal static DDSHeader Read(BinaryReader br) { var h = new DDSHeader(); h.size = br.ReadInt32(); h.flags = br.ReadInt32(); h.height = br.ReadInt32(); h.width = br.ReadInt32(); h.sizeOrPitch = br.ReadInt32(); h.depth = br.ReadInt32(); h.mipMapCount = br.ReadInt32(); h.reserved1 = new int[11]; for (var i = 0; i < 11; ++i) { h.reserved1[i] = br.ReadInt32(); } h.pixelFormat = DDSPixelFormat.Read(br); h.caps = DDSCaps.Read(br); h.reserved2 = br.ReadInt32(); return(h); }
private byte[] CreateDDS() { DDSHeader header = new DDSHeader(); header.dwWidth = Width; header.dwHeight = Height; if (Format == TextureFormat.DXT1) { header.ddspf.dwFourCC = DDSPixelFormat.PF_DXT1; } else if (Format == TextureFormat.DXT5) { header.ddspf.dwFourCC = DDSPixelFormat.PF_DXT5; } else { throw new TextureException("Unsupported DDS format " + Format + " (" + Name + ")"); } if (MipMap) { header.dwFlags |= DDSHeader.DDS_HEADER_FLAGS_MIPMAP; header.dwCaps |= DDSHeader.DDS_SURFACE_FLAGS_MIPMAP; header.dwMipMapCount = header.MipMapCount; } header.dwFlags |= DDSHeader.DDS_HEADER_FLAGS_LINEARSIZE; if (header.ddspf.dwFourCC != 0) { header.dwPitchOrLinearSize = header.dwWidth * header.dwHeight; if (Format == TextureFormat.DXT1) { header.dwPitchOrLinearSize /= 2; } header.ddspf.dwFlags |= DDSPixelFormat.DDPF_FOURCC; } else { header.dwPitchOrLinearSize = (Width * Height * header.ddspf.dwRGBBitCount) / 8; } _data.ResetPos(); using (var ms = new MemoryStream()) using (BinaryWriter bw = new BinaryWriter(ms)) { byte[] bytes = new byte[Size]; _data.Read(bytes, 0, Size); header.write(bw); bw.Write(bytes); return(ms.ToArray()); } }
private MemoryStream ExportDXT1() { MemoryStream m = new MemoryStream(); DDS = CreateHeaderDDS(); DDS.dwWidth = ImageSizeX; DDS.dwHeight = ImageSizeY; byte[] buff = StructureToByteArray(DDS); m.Write(buff, 0, buff.Length); m.Write(memory, 0, memsize); return(m); }
public static BitmapType DetectType(DDSHeader dds) { if ((dds.Caps2 & DDSSurfaceInfoFlags.CubeMap) != 0) { return(BitmapType.CubeMap); } if ((dds.Caps2 & DDSSurfaceInfoFlags.Volume) != 0) { return(BitmapType.Texture3D); } return(BitmapType.Texture2D); }
public void ExtractBitmap(Bitmap bitmap, int imageIndex, Stream outStream) { var resource = bitmap.Resources[imageIndex]; var resourceContext = new ResourceSerializationContext(CacheContext, resource.Resource); var definition = ExtractResourceDefinition(resource, resourceContext); var header = new DDSHeader(definition.Texture.Definition); header.Write(new EndianWriter(outStream)); ExtractResourceData(definition, resource, outStream); }
public static void SetUpHeaderForFormat(BitmapFormat format, DDSHeader header) { if (!ExtractionDefinitions.TryGetValue(format, out BitmapFormatDefinition definition)) { throw new InvalidOperationException("Invalid bitmap format: " + format); } header.PixelFormat.RGBBitCount = definition.BitsPerPixel; header.PixelFormat.RBitMask = definition.RBitMask; header.PixelFormat.GBitMask = definition.GBitMask; header.PixelFormat.BBitMask = definition.BBitMask; header.PixelFormat.ABitMask = definition.ABitMask; header.PixelFormat.FourCC = definition.FourCc; }
public SpdTexture(byte[] ddsData) { var ddsHeader = new DDSHeader(new MemoryStream(ddsData)); Id = 1; Field04 = 0; Width = ddsHeader.Width; Height = ddsHeader.Height; Field18 = 0; Field1C = 0; Description = "Created with <3 by Amicitia"; Data = ddsData; }
/// <ReadDDSHeader> /// This reads the binary stream from the import file and /// creates the DDSHeader object from it. /// </summary> /// <param name="reader">The import file</param> /// <returns>A DDSHeader object</returns> private static DDSHeader ReadDDSHeader(BinaryReader reader) { var signature = reader.ReadBytes(4); if (!(signature[0] == 'D' && signature[1] == 'D' && signature[2] == 'S' && signature[3] == ' ')) { throw new Exception("Invalid File Type"); } var header = new DDSHeader(); header.size = reader.ReadUInt32(); if (header.size != 124) { throw new Exception("Invalid File Type"); } header.flags = reader.ReadUInt32(); header.height = reader.ReadUInt32(); header.width = reader.ReadUInt32(); header.sizeorpitch = reader.ReadUInt32(); header.depth = reader.ReadUInt32(); header.mipmapcount = reader.ReadUInt32(); header.alphabitdepth = reader.ReadUInt32(); header.reserved = new uint[10]; for (var i = 0; i < 10; i++) { header.reserved[i] = reader.ReadUInt32(); } header.pixelformat.size = reader.ReadUInt32(); header.pixelformat.flags = reader.ReadUInt32(); header.pixelformat.fourcc = reader.ReadUInt32(); header.pixelformat.rgbbitcount = reader.ReadUInt32(); header.pixelformat.rbitmask = reader.ReadUInt32(); header.pixelformat.gbitmask = reader.ReadUInt32(); header.pixelformat.bbitmask = reader.ReadUInt32(); header.pixelformat.alphabitmask = reader.ReadUInt32(); header.ddscaps.caps1 = reader.ReadUInt32(); header.ddscaps.caps2 = reader.ReadUInt32(); header.ddscaps.caps3 = reader.ReadUInt32(); header.ddscaps.caps4 = reader.ReadUInt32(); header.texturestage = reader.ReadUInt32(); return(header); }
/// <summary> /// Loads the specified image. /// </summary> /// <param name="image">The image.</param> /// <param name="libraryData">The library data.</param> /// <param name="loader">The loader.</param> /// <exception cref="TextureToolsException">Loading dds file failed</exception> private void Load(TexImage image, DxtTextureLibraryData libraryData, LoadingRequest loader) { Log.Info("Loading " + loader.FilePath + " ..."); libraryData = new DxtTextureLibraryData(); image.LibraryData[this] = libraryData; libraryData.Image = new ScratchImage(); libraryData.Metadata = new TexMetadata(); HRESULT hr = Utilities.LoadDDSFile(loader.FilePath, DDS_FLAGS.DDS_FLAGS_NONE, out libraryData.Metadata, libraryData.Image); if (hr != HRESULT.S_OK) { Log.Error("Loading dds file " + loader.FilePath + " failed: " + hr); throw new TextureToolsException("Loading dds file " + loader.FilePath + " failed: " + hr); } libraryData.DxtImages = libraryData.Image.GetImages(); // adapt the image format based on whether input image is sRGB or not var format = (PixelFormat)libraryData.Metadata.format; ChangeDxtImageType(libraryData, (DXGI_FORMAT)(loader.LoadAsSRgb ? format.ToSRgb() : format.ToNonSRgb())); image.DisposingLibrary = this; if (libraryData.Metadata.miscFlags == TEX_MISC_FLAG.TEX_MISC_TEXTURECUBE) { image.Dimension = TexImage.TextureDimension.TextureCube; } else { switch (libraryData.Metadata.dimension) { case TEX_DIMENSION.TEX_DIMENSION_TEXTURE1D: image.Dimension = TexImage.TextureDimension.Texture1D; break; case TEX_DIMENSION.TEX_DIMENSION_TEXTURE2D: image.Dimension = TexImage.TextureDimension.Texture2D; break; case TEX_DIMENSION.TEX_DIMENSION_TEXTURE3D: image.Dimension = TexImage.TextureDimension.Texture3D; break; } } UpdateImage(image, libraryData); var alphaSize = DDSHeader.GetAlphaDepth(loader.FilePath); image.OriginalAlphaDepth = alphaSize != -1 ? alphaSize : image.Format.AlphaSizeInBits(); }
private void ExtractBitmap(CacheFile.IndexItem blamTag, string directory) { Console.WriteLine($"{blamTag.Name}"); // // Load the Blam tag definition // var blamContext = new CacheSerializationContext(ref BlamCache, blamTag); var bitmap = BlamCache.Deserializer.Deserialize <Bitmap>(blamContext); var ddsOutDir = directory; string bitmap_name = blamTag.Name.Replace('\\', '_'); if (bitmap.Images.Count > 1) { ddsOutDir = Path.Combine(directory, bitmap_name); Directory.CreateDirectory(ddsOutDir); } for (var i = 0; i < bitmap.Images.Count; i++) { var outPath = Path.Combine(ddsOutDir, ((bitmap.Images.Count > 1) ? i.ToString() : bitmap_name) + ".dds"); var image = bitmap.Images[i]; // // Get bitmap data and write file // BaseBitmap baseBitmap = ExtractBitmapData(bitmap, i); // Bitmap is not valid (not a failure to convert, tag data is not valid / no data to convert if (baseBitmap == null) { return; } var header = new DDSHeader(baseBitmap); using (var outStream = File.Open(outPath, FileMode.Create, FileAccess.Write)) { header.Write(new EndianWriter(outStream)); var dataStream = new MemoryStream(baseBitmap.Data); StreamUtil.Copy(dataStream, outStream, baseBitmap.Data.Length); } } }
public DDSHeader CreateHeaderDDS() { DDSHeader temp = new DDSHeader(); temp.magic = 0x20534444; temp.dwSize = 0x7C; temp.dwFlags = 0x1007; temp.dwPitchOrLinearSize = 0; unsafe { temp.dwReserved1[9] = 0x5454564E; } unsafe { temp.dwReserved1[10] = 0x20006; } temp.ddspf.dwSize = 0x20; temp.ddspf.dwFlags = 0x4; temp.ddspf.dwFourCC = 0x31545844; temp.dwCaps = 0x1000; return(temp); }
// TODO: Duplicated code between GetBitmaps() and GetDiskWritableStreams().. public List <Bitmap> GetBitmaps() { List <Bitmap> list = new List <Bitmap>(); for (uint depth = 0; depth < TXM.Depth; ++depth) { Data.Position = 0; Stream plane = TXM.GetSinglePlane(Data, depth); switch (TXM.Format) { case TextureFormat.DXT1a: case TextureFormat.DXT1b: case TextureFormat.DXT5a: case TextureFormat.DXT5b: { plane.Position = 0; DDSHeader header = DDSHeader.Generate(TXM.Width, TXM.Height, TXM.Mipmaps, (TXM.Format == TextureFormat.DXT1a || TXM.Format == TextureFormat.DXT1b) ? Textures.TextureFormat.DXT1 : Textures.TextureFormat.DXT5); list.Add(new DDS(header, plane).ConvertToBitmap()); } break; case TextureFormat.ARGBa: case TextureFormat.ARGBb: for (uint mip = 0; mip < TXM.Mipmaps; ++mip) { var dims = TXM.GetDimensions((int)mip); IPixelOrderIterator pxit; if (TXM.Format == TextureFormat.ARGBa) { pxit = new ARGBaPixelOrderIterator((int)dims.width, (int)dims.height); } else { pxit = new LinearPixelOrderIterator((int)dims.width, (int)dims.height); } var bmp = new ColorFetcherARGB8888(plane, dims.width, dims.height).ConvertToBitmap(pxit, dims.width, dims.height); list.Add(bmp); } break; default: throw new Exception("Unhandled texture format " + TXM.Format); } } return(list); }
/// <ExportAsDDS> /// This method converts a byte array from the CR2W to a dds format byte array /// This should only be used when exporting from a CSwfTexture var (swfTexture). /// </summary> /// <param name="bytes">Byte array to export from the CR2W file</param> /// <returns>The bytes to export</returns> public static byte[] ExportAsDDS(byte[] bytes) { var mem = new MemoryStream(bytes); var reader = new BinaryReader(mem); var header = new DDSHeader(); //Values from the CR2W file var unk1 = reader.ReadUInt32(); var unk2 = reader.ReadUInt32(); header.width = reader.ReadUInt32(); header.height = reader.ReadUInt32(); var unk5 = reader.ReadUInt32(); header.sizeorpitch = reader.ReadUInt32(); var unk7 = reader.ReadUInt32(); //Hard Coded values //No idea how to get these values from the CR2W file //However they seem to be the same for all images from //uncooking the game. //No issues with the exported images when using these values. header.size = Convert.ToUInt32(124); //Always needs to be 124 - standard dds headers are 128 excluding this. header.flags = Convert.ToUInt32(659463); header.depth = Convert.ToUInt32(1); header.mipmapcount = Convert.ToUInt32(1); header.pixelformat.size = Convert.ToUInt32(32); header.pixelformat.flags = Convert.ToUInt32(4); header.pixelformat.fourcc = Convert.ToUInt32(894720068); header.ddscaps.caps1 = Convert.ToUInt32(4096); header.reserved = new uint[10]; var headerBytes = ConstructDDSHeader(header); var memout = new MemoryStream(); var writer = new BinaryWriter(memout); writer.Write(headerBytes); var left = Convert.ToInt32(reader.BaseStream.Length - reader.BaseStream.Position); writer.Write(reader.ReadBytes(left)); return(memout.ToArray()); }
public static void DecodeToDDS(Texture texture, Stream destination) { var ddsHeader = new DDSHeader(texture.Width, texture.Height, TextureUtilities.GetDDSPixelFormat(texture.Format)); if (texture.UsesDepth) { ddsHeader.Depth = texture.Depth; ddsHeader.Flags |= DDSHeaderFlags.Depth; ddsHeader.Caps |= DDSHeaderCaps.Complex; ddsHeader.Caps2 |= DDSHeaderCaps2.CubeMap | DDSHeaderCaps2.CubeMapPositiveX | DDSHeaderCaps2.CubeMapNegativeX | DDSHeaderCaps2.CubeMapPositiveY | DDSHeaderCaps2.CubeMapNegativeY | DDSHeaderCaps2.CubeMapPositiveZ | DDSHeaderCaps2.CubeMapNegativeZ; } if (texture.UsesMipMaps) { ddsHeader.MipMapCount = texture.MipMapCount; ddsHeader.Flags |= DDSHeaderFlags.MipMapCount; ddsHeader.Caps |= DDSHeaderCaps.Complex; } ddsHeader.Save(destination); if (texture.UsesDepth) { foreach (int i in CubeMapToDDSCubeMap()) { foreach (var mipMap in texture.EnumerateMipMaps(i)) { destination.Write(mipMap.Data, 0, mipMap.Data.Length); } } } else { foreach (var mipMap in texture.EnumerateMipMaps()) { destination.Write(mipMap.Data, 0, mipMap.Data.Length); } } }
public void Save(Stream ddsStream, bool keepOpen = false) { if (!Loaded) { return; } using (BinaryWriter ddsWriter = new BinaryWriter(ddsStream, System.Text.Encoding.Default, keepOpen)) { DDSHeader dds = Header.ToDDSHeader(); ddsWriter.Write(dds); if (dds.format.fourCC == 808540228) { DDS_HEADER_DXT10 d10 = new DDS_HEADER_DXT10 { format = (uint)Header.format, dimension = D3D10_RESOURCE_DIMENSION.TEXTURE2D, misc = (uint)(Header.IsCubemap() ? 0x4 : 0), size = (uint)(Header.IsCubemap() ? 1 : Header.surfaces), misc2 = 0 }; ddsWriter.Write(d10); } if (Header.Format() == TextureType.Unknown) { ddsWriter.Write(RawData); } else { for (int i = 0; i < Size; ++i) { if ((byte)Header.format > 72) { ddsWriter.Write(Color3[i]); ddsWriter.Write(Color4[i]); ddsWriter.Write(Color5[i]); } if ((byte)Header.format < 80) { ddsWriter.Write(Color1[i]); ddsWriter.Write(Color2[i]); } } } } }
public static BitmapFormat DetectFormat(DDSHeader header) { InitInjectionDefinitions(); var definition = new BitmapFormatDefinition { BitsPerPixel = header.PixelFormat.RGBBitCount, RBitMask = header.PixelFormat.RBitMask, GBitMask = header.PixelFormat.GBitMask, BBitMask = header.PixelFormat.BBitMask, ABitMask = header.PixelFormat.ABitMask, FourCc = header.PixelFormat.FourCC }; if (!_injectionDefinitions.TryGetValue(definition, out BitmapFormat result)) { throw new InvalidOperationException("Unsupported pixel format"); } return(result); }
/// <summary> /// Encodes the DDS Header and if DX10, the DX10 Header /// </summary> /// <param name="header">DDS Header</param> /// <param name="dx10Header">DX10 Header</param> /// <returns>Resulting DDS File Header in bytes</returns> public static byte[] EncodeDDSHeader(DDSHeader header, DX10Header dx10Header) { // Create stream using (var output = new BinaryWriter(new MemoryStream())) { // Write DDS Magic output.Write(DDSHeader.DDSMagic); // Write Header output.Write(StructToBytes(header)); // Check for DX10 Header if (header.PixelFormat.FourCC == PixelFormats.DX10.FourCC) { // Write Header output.Write(StructToBytes(dx10Header)); } // Done return(((MemoryStream)(output.BaseStream)).ToArray()); } }
/// <ConstructDDSHeader> /// This takes a DDSHeader and constructs the byte /// array for a dds image file from it. /// </summary> /// <param name="header">The header object</param> /// <returns>Byte array of the header</returns> private static byte[] ConstructDDSHeader(DDSHeader header) { var memout = new MemoryStream(); var writer = new BinaryWriter(memout); writer.Write(Convert.ToByte('D')); writer.Write(Convert.ToByte('D')); writer.Write(Convert.ToByte('S')); writer.Write(Convert.ToByte(' ')); writer.Write(header.size); writer.Write(header.flags); writer.Write(header.height); writer.Write(header.width); writer.Write(header.sizeorpitch); writer.Write(header.depth); writer.Write(header.mipmapcount); writer.Write(header.alphabitdepth); for (var i = 0; i < 10; i++) { writer.Write(header.reserved[i]); } writer.Write(header.pixelformat.size); writer.Write(header.pixelformat.flags); writer.Write(header.pixelformat.fourcc); writer.Write(header.pixelformat.rgbbitcount); writer.Write(header.pixelformat.rbitmask); writer.Write(header.pixelformat.gbitmask); writer.Write(header.pixelformat.bbitmask); writer.Write(header.pixelformat.alphabitmask); writer.Write(header.ddscaps.caps1); writer.Write(header.ddscaps.caps2); writer.Write(header.ddscaps.caps3); writer.Write(header.ddscaps.caps4); writer.Write(header.texturestage); return(memout.ToArray()); }
public static DDSFile ExtractBitmap(GameCache cache, Bitmap bitmap, int imageIndex) { if (cache is GameCacheHaloOnlineBase) { byte[] data = ExtractBitmapData(cache, bitmap, imageIndex); DDSHeader header = new DDSHeader(bitmap.Images[imageIndex]); return(new DDSFile(header, data)); } else if (cache.GetType() == typeof(GameCacheGen3)) { var baseBitmap = BitmapConverter.ConvertGen3Bitmap(cache, bitmap, imageIndex, true); if (baseBitmap == null) { return(null); } return(new DDSFile(baseBitmap)); } else { return(null); } }
public DDSHeader ToDDSHeader() { DDSHeader ret = new DDSHeader { Magic = 0x20534444, Size = 124, Flags = 0x1 | 0x2 | 0x4 | 0x1000 | 0x20000, Height = Height, Width = Width, LinearSize = 0, Depth = 0, MipmapCount = 1, Format = GetTextureType().ToPixelFormat(), Caps1 = 0x1000, Caps2 = 0, Caps3 = 0, Caps4 = 0, Reserved2 = 0 }; if (Surfaces > 1) { ret.Caps1 = 0x8 | 0x1000; ret.Format = TextureType.Unknown.ToPixelFormat(); } if (IsCubemap()) { ret.Caps2 = 0xFE00; } if (Mips > 1 && (Indice == 1 || IsCubemap())) { ret.MipmapCount = Mips; ret.Caps1 = 0x8 | 0x1000 | 0x400000; } return(ret); }
public void Save(Stream output, bool keepOpen = false) { if (!loaded) { return; } using (BinaryWriter ddsWriter = new BinaryWriter(output, System.Text.Encoding.Default, keepOpen)) { DDSHeader dds = header.ToDDSHeader(); ddsWriter.Write(dds); if (dds.format.fourCC == 808540228) { DDS_HEADER_DXT10 d10 = new DDS_HEADER_DXT10 { format = (uint)header.format, dimension = D3D10_RESOURCE_DIMENSION.TEXTURE2D, misc = (uint)(header.IsCubemap() ? 0x4 : 0), size = (uint)(header.IsCubemap() ? 1 : header.surfaces), misc2 = 0 }; ddsWriter.Write(d10); } ddsWriter.Write(data, 0, (int)header.dataSize); } }
// These textures are potentially too big to make a Texture2D of, so just load directly into the byte array private void LoadTexture(String path) { path = KSPUtil.ApplicationRootPath + "GameData/" + path; if (File.Exists(path)) { try { if (path.ToLower().EndsWith(".dds")) { // Borrowed from stock KSP 1.0 DDS loader (hi Mike!) // Also borrowed the extra bits from Sarbian. BinaryReader binaryReader = new BinaryReader(File.OpenRead(path)); UInt32 num = binaryReader.ReadUInt32(); if (num == DDSValues.uintMagic) { DDSHeader ddsHeader = new DDSHeader(binaryReader); if (ddsHeader.ddspf.dwFourCC == DDSValues.uintDX10) { // ReSharper disable once ObjectCreationAsStatement new DDSHeaderDX10(binaryReader); } Boolean alpha = (ddsHeader.ddspf.dwFlags & 0x00000002) != 0; Boolean fourcc = (ddsHeader.ddspf.dwFlags & 0x00000004) != 0; Boolean rgb = (ddsHeader.ddspf.dwFlags & 0x00000040) != 0; Boolean alphapixel = (ddsHeader.ddspf.dwFlags & 0x00000001) != 0; Boolean luminance = (ddsHeader.ddspf.dwFlags & 0x00020000) != 0; Boolean mipmap = (ddsHeader.dwCaps & DDSPixelFormatCaps.MIPMAP) != 0u; if (fourcc) { Debug.Log("[Kopernicus]: Compressed textures are not are supported for large maps."); } else { TextureFormat textureFormat = TextureFormat.ARGB32; Boolean ok = true; if (!rgb && alpha != luminance && (ddsHeader.ddspf.dwRGBBitCount == 8 || ddsHeader.ddspf.dwRGBBitCount == 16)) { if (ddsHeader.ddspf.dwRGBBitCount == 8) { // A8 format or Luminance 8 if (alpha) { textureFormat = TextureFormat.Alpha8; } else { textureFormat = TextureFormat.R8; } } else if (ddsHeader.ddspf.dwRGBBitCount == 16) { // R16 format textureFormat = TextureFormat.R16; } } else { ok = false; Debug.Log("[Kopernicus]: Only A8, R8, and R16 are supported"); } if (ok) { _name = name; _width = (Int32)ddsHeader.dwWidth; _height = (Int32)ddsHeader.dwHeight; _isCompiled = false; if (textureFormat == TextureFormat.R16) { _bpp = (Int32)MapDepth.HeightAlpha; } else { _bpp = (Int32)MapDepth.Greyscale; } _rowWidth = _width * _bpp; Int32 dataSize = _rowWidth * _height; Image = new NativeByteArray(dataSize); byte[] ddsData = binaryReader.ReadBytes(dataSize); for (Int32 i = 0; i < dataSize; i++) { Image[i] = ddsData[i]; } Debug.Log("[Kopernicus]: Loaded large map: " + path); } } } else { Debug.Log("[Kopernicus]: Bad DDS header."); } } else { Debug.Log("[Kopernicus]: Only DDS is supported for large maps."); } } catch (Exception ex) { Debug.Log("[Kopernicus]: failed to load " + path + " with exception " + ex.Message); } } else { Debug.Log("[Kopernicus]: texture does not exist! " + path); } }
public DXT4Decoder(DDSHeader header) : base(header) { }
public override void EncodeToFile( Stream input, string outFileName, Codec.CodecData data ) { // Unwrap codecDataPtr - data is cleaned by calling function var imgData = (ImageData)data; // Check size for cube map faces var isCubeMap = imgData.size == Image.CalculateSize( imgData.numMipMaps, 6, imgData.width, imgData.height, imgData.depth, imgData.format ); // Establish texture attributes var isVolume = imgData.depth > 1; var isFloat32r = imgData.format == PixelFormat.FLOAT32_R; var hasAlpha = false; var notImplemented = false; var notImplementedString = string.Empty; // Check for all the 'not implemented' conditions if ( imgData.numMipMaps != 0 ) { // No mip map functionality yet notImplemented = true; notImplementedString += " mipmaps"; } if ( ( isVolume == true ) && ( imgData.width != imgData.height ) ) { // Square textures only notImplemented = true; notImplementedString += " non square textures"; } var size = 1; while ( size < imgData.width ) { size <<= 1; } if ( size != imgData.width ) { // Power two textures only notImplemented = true; notImplementedString += " non power two textures"; } switch ( imgData.format ) { case PixelFormat.A8R8G8B8: case PixelFormat.X8R8G8B8: case PixelFormat.R8G8B8: case PixelFormat.FLOAT32_R: break; default: // No crazy FOURCC or 565 et al. file formats at this stage notImplemented = true; notImplementedString = " unsupported pixel format"; break; } // Except if any 'not implemented' conditions were met if ( notImplemented ) { throw new NotImplementedException( string.Format( "DDS encoding for{0} not supported", notImplementedString ) ); } else { // Build header and write to disk // Variables for some DDS header flags var ddsHeaderFlags = 0; var ddsHeaderRgbBits = 0; var ddsHeaderSizeOrPitch = 0; var ddsHeaderCaps1 = 0; var ddsHeaderCaps2 = 0; var ddsMagic = this.DDS_MAGIC; // Initalise the header flags ddsHeaderFlags = ( isVolume ) ? DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_DEPTH | DDSD_PIXELFORMAT : DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT; // Initalise the rgbBits flags switch ( imgData.format ) { case PixelFormat.A8R8G8B8: ddsHeaderRgbBits = 8*4; hasAlpha = true; break; case PixelFormat.X8R8G8B8: ddsHeaderRgbBits = 8*4; break; case PixelFormat.R8G8B8: ddsHeaderRgbBits = 8*3; break; case PixelFormat.FLOAT32_R: ddsHeaderRgbBits = 32; break; default: ddsHeaderRgbBits = 0; break; } ; // Initalise the SizeOrPitch flags (power two textures for now) ddsHeaderSizeOrPitch = ddsHeaderRgbBits*imgData.width; // Initalise the caps flags ddsHeaderCaps1 = ( isVolume || isCubeMap ) ? DDSCAPS_COMPLEX | DDSCAPS_TEXTURE : DDSCAPS_TEXTURE; if ( isVolume ) { ddsHeaderCaps2 = DDSCAPS2_VOLUME; } else if ( isCubeMap ) { ddsHeaderCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEX | DDSCAPS2_CUBEMAP_NEGATIVEX | DDSCAPS2_CUBEMAP_POSITIVEY | DDSCAPS2_CUBEMAP_NEGATIVEY | DDSCAPS2_CUBEMAP_POSITIVEZ | DDSCAPS2_CUBEMAP_NEGATIVEZ; } // Populate the DDS header information var ddsHeader = new DDSHeader(); ddsHeader.size = DDS_HEADER_SIZE; ddsHeader.flags = ddsHeaderFlags; ddsHeader.width = imgData.width; ddsHeader.height = imgData.height; ddsHeader.depth = isVolume ? imgData.depth : 0; ddsHeader.depth = isCubeMap ? 6 : ddsHeader.depth; ddsHeader.mipMapCount = 0; ddsHeader.sizeOrPitch = ddsHeaderSizeOrPitch; ddsHeader.reserved1 = new int[11]; ddsHeader.reserved2 = 0; ddsHeader.pixelFormat.size = DDS_PIXELFORMAT_SIZE; ddsHeader.pixelFormat.flags = ( hasAlpha ) ? DDPF_RGB | DDPF_ALPHAPIXELS : DDPF_RGB; ddsHeader.pixelFormat.flags = ( isFloat32r ) ? DDPF_FOURCC : ddsHeader.pixelFormat.flags; ddsHeader.pixelFormat.fourCC = ( isFloat32r ) ? D3DFMT_R32F : 0; ddsHeader.pixelFormat.rgbBits = ddsHeaderRgbBits; ddsHeader.pixelFormat.alphaMask = hasAlpha ? unchecked( (int)0xFF000000 ) : 0x00000000; ddsHeader.pixelFormat.alphaMask = isFloat32r ? 0x00000000 : ddsHeader.pixelFormat.alphaMask; ddsHeader.pixelFormat.redMask = isFloat32r ? unchecked( (int)0xFFFFFFFF ) : 0x00FF0000; ddsHeader.pixelFormat.greenMask = isFloat32r ? 0x00000000 : 0x0000FF00; ddsHeader.pixelFormat.blueMask = isFloat32r ? 0x00000000 : 0x000000FF; ddsHeader.caps.caps1 = ddsHeaderCaps1; ddsHeader.caps.caps2 = ddsHeaderCaps2; ddsHeader.caps.reserved[ 0 ] = 0; ddsHeader.caps.reserved[ 1 ] = 0; // Swap endian using ( var wrap = BufferBase.Wrap( ddsMagic, 2 ) ) { _flipEndian( wrap, sizeof ( uint ), 1 ); } using ( var wrap = BufferBase.Wrap( ddsHeader, Memory.SizeOf( typeof( DDSHeader ) ) ) ) { _flipEndian( wrap, 4, Memory.SizeOf( typeof ( DDSHeader ) )/4 ); } // Write the file using ( var br = new BinaryWriter( File.Open( outFileName, FileMode.OpenOrCreate, FileAccess.Write ) ) ) { br.Write( ddsMagic ); ddsHeader.Write( br ); // XXX flipEndian on each pixel chunk written unless isFloat32r ? var inputData = new byte[(int)input.Length]; input.Read( inputData, 0, inputData.Length ); br.Write( inputData ); } } }
internal static DDSHeader Read( BinaryReader br ) { var h = new DDSHeader(); h.size = br.ReadInt32(); h.flags = br.ReadInt32(); h.height = br.ReadInt32(); h.width = br.ReadInt32(); h.sizeOrPitch = br.ReadInt32(); h.depth = br.ReadInt32(); h.mipMapCount = br.ReadInt32(); h.reserved1 = new int[11]; for ( var i = 0; i < 11; ++i ) { h.reserved1[ i ] = br.ReadInt32(); } h.pixelFormat = DDSPixelFormat.Read( br ); h.caps = DDSCaps.Read( br ); h.reserved2 = br.ReadInt32(); return h; }
/// <summary> /// Create DDS Texture From Image. /// </summary> /// <param name="image">Main Image.</param> /// <param name="mipMaps">Number of MipMaps.</param> /// <param name="format">Destination Format.</param> /// <param name="bw">Binary Writer To Save Output DDS Texture.</param> public static void CreateFromBitmap(Bitmap image, uint mipMaps, DDSImageDestination format, BinaryWriter bw) { if (mipMaps < 1) mipMaps = 1; bool asRgb32 = false; switch (format) { case DDSImageDestination.BC1: case DDSImageDestination.BC2: case DDSImageDestination.BC3: case DDSImageDestination.BC4: case DDSImageDestination.BC5: case DDSImageDestination.Dxt1: case DDSImageDestination.Dxt3: case DDSImageDestination.Dxt5: asRgb32 = true; break; } DDSHeader cheader = null; byte[] buffer = new byte[0]; if (asRgb32) { int step = Bitmap.GetPixelFormatSize(image.PixelFormat); bool alpha = (step == 32); char[] chrs = new char[4]; SquishFlags flag = SquishFlags.Dxt1; switch (format) { case DDSImageDestination.BC1: case DDSImageDestination.Dxt1: chrs = new char[] { 'D', 'X', 'T', '1' }; flag = SquishFlags.Dxt1; break; case DDSImageDestination.BC2: case DDSImageDestination.Dxt3: chrs = new char[] { 'D', 'X', 'T', '3' }; flag = SquishFlags.Dxt3; break; case DDSImageDestination.Dxt5: case DDSImageDestination.BC3: chrs = new char[] { 'D', 'X', 'T', '5' }; flag = SquishFlags.Dxt5; break; case DDSImageDestination.BC4: chrs = new char[] { 'A', 'T', 'I', '1' }; flag = SquishFlags.BC4; break; case DDSImageDestination.BC5: chrs = new char[] { 'A', 'T', 'I', '2' }; flag = SquishFlags.BC5; break; } SquishFlags fit = CompressionFlags & (SquishFlags.ColourIterativeClusterFit | SquishFlags.ColourClusterFit | SquishFlags.ColourRangeFit); SquishFlags metric = CompressionFlags & (SquishFlags.ColourMetricPerceptual | SquishFlags.ColourMetricUniform); SquishFlags extra = CompressionFlags & SquishFlags.WeightColourByAlpha; if (fit != SquishFlags.ColourRangeFit) fit = SquishFlags.ColourClusterFit; if (metric != SquishFlags.ColourMetricUniform) metric = SquishFlags.ColourMetricPerceptual; flag |= fit | metric | extra; cheader = new DDSHeader() { Size = 124, Flags = DDSFlagsTexture, Height = (uint)image.Height, Width = (uint)image.Width, PitchOrLinearSize = 0, Depth = 32, MipMapCount = mipMaps, Reserved1 = new uint[11], Caps = DDSCaps.DDSCAPS_TEXTURE | DDSCaps.DDSCAPS_MIPMAP, Caps2 = (DDSCaps2)0, Caps3 = 0, Caps4 = 0, Reserved2 = 0 }; cheader.PixelFormat = new DDSPixelFormat() { Size = 32, Flags = DDSPixelFormatFlags.DDPF_FOURCC, FourCC = new string(chrs), RGBBitCount = 32, RBitMask = 0, GBitMask = 0, BBitMask = 0, ABitMask = 0 }; List<byte> _cbuff = new List<byte>(); Bitmap cimage = (Bitmap)image.Clone(); for (int i = 0; i < mipMaps; i++) { byte[] cbuf1 = FlipImageData(GetImageData(cimage, true)); cbuf1 = SharpSquish.CompressImage(cbuf1, cimage.Width, cimage.Height, flag); _cbuff.AddRange(cbuf1); int width = Math.Max(cimage.Width / 2, 1); int height = Math.Max(cimage.Height / 2, 1); cimage = ResizeImage(cimage, width, height); } cimage.Dispose(); buffer = _cbuff.ToArray(); } else { int step = Bitmap.GetPixelFormatSize(image.PixelFormat); bool alpha = (step == 32); cheader = new DDSHeader() { Size = 124, Flags = DDSFlags.DDSD_CAPS | DDSFlags.DDSD_HEIGHT | DDSFlags.DDSD_MIPMAPCOUNT | DDSFlags.DDSD_PIXELFORMAT| DDSFlags.DDSD_WIDTH, Height = (uint)image.Height, Width = (uint)image.Width, PitchOrLinearSize = 0, Depth = 1, MipMapCount = mipMaps, Reserved1 = new uint[11], Caps = DDSCaps.DDSCAPS_TEXTURE | DDSCaps.DDSCAPS_MIPMAP, Caps2 = (DDSCaps2)0, Caps3 = 0, Caps4 = 0, Reserved2 = 0 }; uint dwRBitMask = 0, dwGBitMask = 0, dwBBitMask = 0, dwABitMask = 0; switch (step) { case 32: dwRBitMask = 0xff; dwGBitMask = 0xff00; dwBBitMask = 0xff0000; dwABitMask = 0xff000000; break; case 24: dwRBitMask = 0xff0000; dwGBitMask = 0xff00; dwBBitMask = 0xff; break; case 16: dwRBitMask = 0x7c00; dwGBitMask = 0x3e0; dwBBitMask = 0x1f; break; } cheader.PixelFormat = new DDSPixelFormat() { Size = 32, Flags = DDSPixelFormatFlags.DDPF_RGB | ((alpha) ? DDSPixelFormatFlags.DDPF_ALPHAPIXELS : (DDSPixelFormatFlags)0), FourCC = new string(new char[] { '\0', '\0', '\0', '\0' }), RGBBitCount = (uint)step, ABitMask = dwABitMask, RBitMask = dwRBitMask, BBitMask = dwBBitMask, GBitMask = dwGBitMask }; List<byte> _cbuff = new List<byte>(); Bitmap cimage = (Bitmap)image.Clone(); for (int i = 0; i < mipMaps; i++) { byte[] cbuf1 = GetImageData(cimage, false); _cbuff.AddRange(cbuf1); int width = Math.Max(cimage.Width / 2, 1); int height = Math.Max(cimage.Height / 2, 1); if (cimage != null) cimage.Dispose(); cimage = ResizeImage(cimage, width, height); } cimage.Dispose(); buffer = _cbuff.ToArray(); } bw.Write((uint)0x20534444); cheader.WriteTo(bw); bw.Write(buffer); }
/// <summary> /// Load Texture From Binary Reader. /// </summary> /// <param name="br">The Binary Reader.</param> /// <returns></returns> public bool LoadFrom(BinaryReader br) { _header = null; _volumeTexture = null; _cubeMapTexture = null; _texture = null; _lastError = ""; uint id = br.ReadUInt32(); if (id != 0x20534444) return SetLastError("Invalid DDS Image File."); _header = new DDSHeader(br); bool isCompressed = false; SquishFlags compressFlag = SquishFlags.Dxt1; if (IsFourCC()) { isCompressed = true; switch (_header.PixelFormat.FourCC) { case FOURCC_DXT1: isCompressed = true; compressFlag = SquishFlags.Dxt1; break; case FOURCC_DXT3: compressFlag = SquishFlags.Dxt3; break; case FOURCC_DXT5: compressFlag = SquishFlags.Dxt5; break; case FOURCC_ATI1: compressFlag = SquishFlags.BC4; break; case FOURCC_ATI2: compressFlag = SquishFlags.BC5; break; default: isCompressed = false; break; } } uint mipMaps = 1; if (HasMipMaps()) mipMaps = _header.MipMapCount; if (IsVolumeTexture()) { uint ui_slices = _header.Depth; uint ui_width = _header.Width; uint ui_height = _header.Height; _volumeTexture = new VolumeTextureData((int)mipMaps); for (int i = 0; i < mipMaps; i++) { _volumeTexture.Mipmaps[i] = new VolumeTextureMipMap((int)ui_slices); for (int j = 0; j < ui_slices; j++) { int dataSize = (int)(ui_width * ui_height * (_header.PixelFormat.RGBBitCount / 8)); if (isCompressed) dataSize = SharpSquish.GetStorageRequirements((int)ui_width, (int)ui_height, compressFlag); byte[] m_slice = br.ReadBytes(dataSize); _volumeTexture.Mipmaps[i].Slices[j] = new MipmapData() { Width = ui_width, Height = ui_height, Data = m_slice }; } ui_width = Math.Max(ui_width / 2, 1); ui_height = Math.Max(ui_height / 2, 1); ui_slices = Math.Max(ui_slices / 2, 1); } } else if (isCubeMapTexture()) { _cubeMapTexture = new CubeMapTextureData(); bool posX = ((_header.Caps2 & DDSCaps2.DDSCAPS2_CUBEMAP_POSITIVEX) != 0); bool negX = ((_header.Caps2 & DDSCaps2.DDSCAPS2_CUBEMAP_NEGATIVEX) != 0); bool posY = ((_header.Caps2 & DDSCaps2.DDSCAPS2_CUBEMAP_POSITIVEY) != 0); bool negY = ((_header.Caps2 & DDSCaps2.DDSCAPS2_CUBEMAP_NEGATIVEY) != 0); bool posZ = ((_header.Caps2 & DDSCaps2.DDSCAPS2_CUBEMAP_POSITIVEZ) != 0); bool negZ = ((_header.Caps2 & DDSCaps2.DDSCAPS2_CUBEMAP_NEGATIVEZ) != 0); if (posX) _cubeMapTexture.PositiveX = ReadFace(br, mipMaps, isCompressed, compressFlag); else _cubeMapTexture.PositiveX = null; if (negX) _cubeMapTexture.NegativeX = ReadFace(br, mipMaps, isCompressed, compressFlag); else _cubeMapTexture.NegativeX = null; if (posY) _cubeMapTexture.PositiveY = ReadFace(br, mipMaps, isCompressed, compressFlag); else _cubeMapTexture.PositiveY = null; if (negY) _cubeMapTexture.NegativeY = ReadFace(br, mipMaps, isCompressed, compressFlag); else _cubeMapTexture.NegativeY = null; if (posZ) _cubeMapTexture.PositiveZ = ReadFace(br, mipMaps, isCompressed, compressFlag); else _cubeMapTexture.PositiveZ = null; if (negZ) _cubeMapTexture.NegativeZ = ReadFace(br, mipMaps, isCompressed, compressFlag); else _cubeMapTexture.NegativeZ = null; } else { _texture = new MipmapData[(int)mipMaps]; uint ui_width = _header.Width; uint ui_height = _header.Height; for (int i = 0; i < mipMaps; i++) { int dataSize = (int)(ui_width * ui_height * (_header.PixelFormat.RGBBitCount / 8)); if (isCompressed) dataSize = SharpSquish.GetStorageRequirements((int)ui_width, (int)ui_height, compressFlag); byte[] m_slice = br.ReadBytes(dataSize); _texture[i] = new MipmapData() { Width = ui_width, Height = ui_height, Data = m_slice }; ui_width = Math.Max(ui_width / 2, 1); ui_height = Math.Max(ui_height / 2, 1); } } return true; }
public static Texture2D LoadTexture(string url) { // Check cache for texture Texture2D texture; try { string path = "GameData/" + url; // PNG loading if (File.Exists(path) && path.Contains(".png")) { texture = new Texture2D(2, 2, TextureFormat.RGBA32, false); texture.LoadImage(File.ReadAllBytes(path.Replace('/', Path.DirectorySeparatorChar))); } // DDS loading else if (File.Exists(path) && path.Contains(".dds")) { BinaryReader br = new BinaryReader(new MemoryStream(File.ReadAllBytes(path))); if (br.ReadUInt32() != DDSValues.uintMagic) { throw new Exception("Format issue with DDS texture '" + path + "'!"); } DDSHeader ddsHeader = new DDSHeader(br); if (ddsHeader.ddspf.dwFourCC == DDSValues.uintDX10) { DDSHeaderDX10 ddsHeaderDx10 = new DDSHeaderDX10(br); } TextureFormat texFormat; if (ddsHeader.ddspf.dwFourCC == DDSValues.uintDXT1) { texFormat = UnityEngine.TextureFormat.DXT1; } else if (ddsHeader.ddspf.dwFourCC == DDSValues.uintDXT3) { texFormat = UnityEngine.TextureFormat.DXT1 | UnityEngine.TextureFormat.Alpha8; } else if (ddsHeader.ddspf.dwFourCC == DDSValues.uintDXT5) { texFormat = UnityEngine.TextureFormat.DXT5; } else { throw new Exception("Unhandled DDS format!"); } texture = new Texture2D((int)ddsHeader.dwWidth, (int)ddsHeader.dwHeight, texFormat, false); texture.LoadRawTextureData(br.ReadBytes((int)(br.BaseStream.Length - br.BaseStream.Position))); texture.Apply(false, true); } else { throw new Exception("Couldn't find file for image '" + url + "'"); } } catch (Exception e) { LoggingUtil.LogError(typeof(TextureUtil), "Couldn't create texture for '" + url + "'!"); Debug.LogException(e); texture = null; } return texture; }
/// <summary> /// Gets the contract icon for the given id and seed (color). /// </summary> /// <param name="url">URL of the icon</param> /// <param name="seed">Seed to use for generating the color</param> /// <returns>The texture</returns> public static Texture2D GetContractIcon(string url, int seed) { // Check cache for texture Texture2D texture; Color color = SystemUtilities.RandomColor(seed, 1.0f, 1.0f, 1.0f); if (!contractIcons.ContainsKey(url)) { contractIcons[url] = new Dictionary<Color, Texture2D>(); } if (!contractIcons[url].ContainsKey(color)) { Texture2D baseTexture = ContractDefs.sprites[url].texture; try { Texture2D loadedTexture = null; string path = (url.Contains('/') ? "GameData/" : "GameData/Squad/Contracts/Icons/") + url; // PNG loading if (File.Exists(path + ".png")) { path += ".png"; loadedTexture = new Texture2D(baseTexture.width, baseTexture.height, TextureFormat.RGBA32, false); loadedTexture.LoadImage(File.ReadAllBytes(path.Replace('/', Path.DirectorySeparatorChar))); } // DDS loading else if (File.Exists(path + ".dds")) { path += ".dds"; BinaryReader br = new BinaryReader(new MemoryStream(File.ReadAllBytes(path))); if (br.ReadUInt32() != DDSValues.uintMagic) { throw new Exception("Format issue with DDS texture '" + path + "'!"); } DDSHeader ddsHeader = new DDSHeader(br); if (ddsHeader.ddspf.dwFourCC == DDSValues.uintDX10) { DDSHeaderDX10 ddsHeaderDx10 = new DDSHeaderDX10(br); } TextureFormat texFormat; if (ddsHeader.ddspf.dwFourCC == DDSValues.uintDXT1) { texFormat = UnityEngine.TextureFormat.DXT1; } else if (ddsHeader.ddspf.dwFourCC == DDSValues.uintDXT3) { texFormat = UnityEngine.TextureFormat.DXT1 | UnityEngine.TextureFormat.Alpha8; } else if (ddsHeader.ddspf.dwFourCC == DDSValues.uintDXT5) { texFormat = UnityEngine.TextureFormat.DXT5; } else { throw new Exception("Unhandled DDS format!"); } loadedTexture = new Texture2D((int)ddsHeader.dwWidth, (int)ddsHeader.dwHeight, texFormat, false); loadedTexture.LoadRawTextureData(br.ReadBytes((int)(br.BaseStream.Length - br.BaseStream.Position))); } else { throw new Exception("Couldn't find file for icon '" + url + "'"); } Color[] pixels = loadedTexture.GetPixels(); for (int i = 0; i < pixels.Length; i++) { pixels[i] *= color; } texture = new Texture2D(baseTexture.width, baseTexture.height, TextureFormat.RGBA32, false); texture.SetPixels(pixels); texture.Apply(false, false); contractIcons[url][color] = texture; UnityEngine.Object.Destroy(loadedTexture); } catch (Exception e) { Debug.LogError("WaypointManager: Couldn't create texture for '" + url + "'!"); Debug.LogException(e); texture = contractIcons[url][color] = baseTexture; } } else { texture = contractIcons[url][color]; } return texture; }