/// <summary> /// Gets file extension of supported surface formats. /// Doesn't include preceding dot. /// </summary> /// <param name="format">Format to get file extension for.</param> /// <returns>File extension without dot.</returns> static string GetExtensionOfFormat(ImageEngineFormat format) { string formatString = format.ToString().ToLowerInvariant(); if (formatString.Contains('_')) { formatString = "dds"; } return(formatString); }
public override async Task SetObject(string filename, List <DomainNameTableEntry> nameTable) { ImageEngineImage image = await Task.Run(() => new ImageEngineImage(filename)); int width = image.Width; int height = image.Height; DomainPropertyIntValue sizeX = PropertyHeader.GetProperty("SizeX").FirstOrDefault()?.Value as DomainPropertyIntValue; DomainPropertyIntValue sizeY = PropertyHeader.GetProperty("SizeY").FirstOrDefault()?.Value as DomainPropertyIntValue; sizeX?.SetPropertyValue(width); sizeY?.SetPropertyValue(height); DomainPropertyIntValue mipTailBaseIdx = PropertyHeader.GetProperty("MipTailBaseIdx").FirstOrDefault()?.Value as DomainPropertyIntValue; mipTailBaseIdx?.SetPropertyValue((int)Math.Log(width > height ? width : height, 2)); DomainPropertyStringValue filePath = PropertyHeader.GetProperty("SourceFilePath").FirstOrDefault()?.Value as DomainPropertyStringValue; DomainPropertyStringValue fileTime = PropertyHeader.GetProperty("SourceFileTimestamp").FirstOrDefault()?.Value as DomainPropertyStringValue; filePath?.SetPropertyValue(filename); fileTime?.SetPropertyValue(File.GetLastWriteTime(filename).ToString("yyyy-MM-dd hh:mm:ss")); DomainPropertyByteValue pfFormat = PropertyHeader.GetProperty("Format").FirstOrDefault()?.Value as DomainPropertyByteValue; ImageEngineFormat imageFormat = image.Format.InternalFormat; if (!imageFormat.ToString().Contains("DDS")) { throw new Exception($"Image is not in a DDS format. It is actually {imageFormat}."); } if (pfFormat != null) { string formatStr = imageFormat.ToString().Replace("DDS", "PF"); if (formatStr.Contains("ARGB")) { formatStr = "PF_A8R8G8B8"; } else if (formatStr.Contains("G8")) { formatStr = "PF_G8"; } DomainNameTableEntry formatTableEntry = nameTable.SingleOrDefault(nt => nt.Name.String == formatStr) ?? nameTable.AddDomainNameTableEntry(formatStr); pfFormat.SetPropertyValue(formatTableEntry); } MipMaps.Clear(); while (true) { MemoryStream stream = new MemoryStream(); image.Save(stream, imageFormat, MipHandling.KeepTopOnly); await stream.FlushAsync(); MipMaps.Add(new DomainMipMap { ImageData = (await ByteArrayReader.CreateNew(stream.ToArray(), 0x80).Splice()).GetBytes(), // Strip off 128 bytes for the DDS header Width = image.Width, Height = image.Height }); if (width == 1 && height == 1) { break; } if (width > 1) { width /= 2; } if (height > 1) { height /= 2; } if (image.Width > 4 && image.Height > 4) { image.Resize(0.5, false); } } }
/// <summary> /// Determines if given format supports mipmapping. /// </summary> /// <param name="format">Image format to check.</param> /// <returns></returns> static bool IsFormatMippable(ImageEngineFormat format) { return(format.ToString().Contains("DDS")); }
/// <summary> /// Determines if given format supports mipmapping. /// </summary> /// <param name="format">Image format to check.</param> /// <returns></returns> public static bool IsFormatMippable(ImageEngineFormat format) { return format.ToString().Contains("DDS"); }
/// <summary> /// Gets file extension of supported surface formats. /// Doesn't include preceding dot. /// </summary> /// <param name="format">Format to get file extension for.</param> /// <returns>File extension without dot.</returns> public static string GetExtensionOfFormat(ImageEngineFormat format) { string formatString = format.ToString().ToLowerInvariant(); if (formatString.Contains('_')) formatString = "dds"; return formatString; }
public static string StringifyFormat(ImageEngineFormat format) { return(format.ToString().Replace("DDS_", "").Replace("_3Dc", "")); }
public static string StringifyFormat(ImageEngineFormat format) { return format.ToString().Replace("DDS_", "").Replace("_3Dc",""); }
internal static byte[] Save(List<MipMap> mipMaps, ImageEngineFormat saveFormat, AlphaSettings alphaSetting, List<uint> customMasks = null) { // Set compressor for Block Compressed textures Action<byte[], int, int, byte[], int, AlphaSettings> compressor = null; bool needCheckSize = saveFormat.ToString().Contains("DXT") || saveFormat.ToString().Contains("ATI"); switch (saveFormat) { case ImageEngineFormat.DDS_ATI1: compressor = DDS_Encoders.CompressBC4Block; break; case ImageEngineFormat.DDS_ATI2_3Dc: compressor = DDS_Encoders.CompressBC5Block; break; case ImageEngineFormat.DDS_DX10: Debugger.Break(); break; // TODO: NOT SUPPORTED YET. DX10 case ImageEngineFormat.DDS_DXT1: compressor = DDS_Encoders.CompressBC1Block; break; case ImageEngineFormat.DDS_DXT2: case ImageEngineFormat.DDS_DXT3: compressor = DDS_Encoders.CompressBC2Block; break; case ImageEngineFormat.DDS_DXT4: case ImageEngineFormat.DDS_DXT5: compressor = DDS_Encoders.CompressBC3Block; break; } int height = mipMaps[0].Height; int width = mipMaps[0].Width; if (needCheckSize && !CheckSize_DXT(width, height)) throw new InvalidOperationException($"DXT compression formats require dimensions to be multiples of 4. Got: {width}x{height}."); int fullSize = GetCompressedSizeOfImage(mipMaps.Count, saveFormat, width, height); // +1 to get the full size, not just the offset of the last mip. //int fullSize = GetMipOffset(mipMaps.Count + 1, saveFormat, mipMaps[0].Width, mipMaps[0].Height); byte[] destination = new byte[fullSize]; // Create header and write to destination DDS_Header header = new DDS_Header(mipMaps.Count, height, width, saveFormat, customMasks); header.WriteToArray(destination, 0); int blockSize = ImageFormats.GetBlockSize(saveFormat); if (ImageFormats.IsBlockCompressed(saveFormat)) { int mipOffset = 128; foreach (MipMap mipmap in mipMaps) mipOffset = WriteCompressedMipMap(destination, mipOffset, mipmap, blockSize, compressor, alphaSetting); } else { // UNCOMPRESSED var action = new Action<int>(mipIndex => { if (alphaSetting == AlphaSettings.RemoveAlphaChannel) { // Remove alpha by setting AMask = 0 var ddspf = header.ddspf; ddspf.dwABitMask = 0; header.ddspf = ddspf; } // Get MipOffset int offset = GetMipOffset(mipIndex, saveFormat, width, height); WriteUncompressedMipMap(destination, offset, mipMaps[mipIndex], saveFormat, header.ddspf); }); if (ImageEngine.EnableThreading) Parallel.For(0, mipMaps.Count, new ParallelOptions { MaxDegreeOfParallelism = ImageEngine.NumThreads }, action); else for (int i = 0; i < mipMaps.Count; i++) action(i); } return destination; }