public static STChannelType[] SetChannelsByFormat(TEX_FORMAT Format) { STChannelType[] channels = new STChannelType[4]; switch (Format) { case TEX_FORMAT.BC5: channels[0] = STChannelType.Red; channels[1] = STChannelType.Green; channels[2] = STChannelType.Zero; channels[3] = STChannelType.One; break; case TEX_FORMAT.BC4: channels[0] = STChannelType.Red; channels[1] = STChannelType.Red; channels[2] = STChannelType.Red; channels[3] = STChannelType.Red; break; default: channels[0] = STChannelType.Red; channels[1] = STChannelType.Green; channels[2] = STChannelType.Blue; channels[3] = STChannelType.Alpha; break; } return(channels); }
public static GTXImporterSettings SetImporterSettings(string name, TEX_FORMAT DefaultFormat = TEX_FORMAT.UNKNOWN) { var importer = new GTXImporterSettings(); string ext = System.IO.Path.GetExtension(name); ext = ext.ToLower(); switch (ext) { case ".dds": case ".dds2": importer.LoadDDS(name); break; default: importer.LoadBitMap(name); //Override the format setting. This only will do this for images not as dds or astc if (DefaultFormat != TEX_FORMAT.UNKNOWN) { importer.Format = (GX2.GX2SurfaceFormat)ConvertToGx2Format(DefaultFormat); } break; } return(importer); }
public static PICASurfaceFormat ConvertToPICAFormat(TEX_FORMAT GenericFormat) { switch (GenericFormat) { case TEX_FORMAT.B5G6R5_UNORM: return(PICASurfaceFormat.RGB565); case TEX_FORMAT.R8G8_UNORM: return(PICASurfaceFormat.RGB8); case TEX_FORMAT.B5G5R5A1_UNORM: return(PICASurfaceFormat.RGBA5551); case TEX_FORMAT.B4G4R4A4_UNORM: return(PICASurfaceFormat.RGBA4); case TEX_FORMAT.LA8: return(PICASurfaceFormat.LA8); case TEX_FORMAT.HIL08: return(PICASurfaceFormat.HiLo8); case TEX_FORMAT.L8: return(PICASurfaceFormat.L8); case TEX_FORMAT.A8_UNORM: return(PICASurfaceFormat.A8); case TEX_FORMAT.LA4: return(PICASurfaceFormat.LA4); case TEX_FORMAT.A4: return(PICASurfaceFormat.A4); case TEX_FORMAT.ETC1: return(PICASurfaceFormat.ETC1); case TEX_FORMAT.ETC1_A4: return(PICASurfaceFormat.ETC1A4); default: throw new NotImplementedException("Unsupported format! " + GenericFormat); } }
public static bool IsCompressed(TEX_FORMAT Format) { switch (Format) { case TEX_FORMAT.BC1_UNORM: case TEX_FORMAT.BC1_UNORM_SRGB: case TEX_FORMAT.BC1_TYPELESS: case TEX_FORMAT.BC2_UNORM_SRGB: case TEX_FORMAT.BC2_UNORM: case TEX_FORMAT.BC2_TYPELESS: case TEX_FORMAT.BC3_UNORM_SRGB: case TEX_FORMAT.BC3_UNORM: case TEX_FORMAT.BC3_TYPELESS: case TEX_FORMAT.BC4_UNORM: case TEX_FORMAT.BC4_TYPELESS: case TEX_FORMAT.BC4_SNORM: case TEX_FORMAT.BC5_UNORM: case TEX_FORMAT.BC5_TYPELESS: case TEX_FORMAT.BC5_SNORM: case TEX_FORMAT.BC6H_UF16: case TEX_FORMAT.BC6H_SF16: case TEX_FORMAT.BC7_UNORM: case TEX_FORMAT.BC7_UNORM_SRGB: return(true); default: return(false); } }
public byte[] GenerateMipsAndCompress(Bitmap bitmap, TEX_FORMAT Format, float alphaRef = 0.5f) { byte[] DecompressedData = BitmapExtension.ImageToByte(bitmap); DecompressedData = ConvertBgraToRgba(DecompressedData); Bitmap Image = BitmapExtension.GetBitmap(DecompressedData, bitmap.Width, bitmap.Height); List <byte[]> mipmaps = new List <byte[]>(); mipmaps.Add(STGenericTexture.CompressBlock(DecompressedData, bitmap.Width, bitmap.Height, Format, alphaRef)); for (int mipLevel = 0; mipLevel < MipCount; mipLevel++) { if (Image.Width / 2 > 0 && Image.Height / 2 > 0) { Image = BitmapExtension.Resize(Image, Image.Width / 2, Image.Height / 2); mipmaps.Add(STGenericTexture.CompressBlock(BitmapExtension.ImageToByte(Image), Image.Width, Image.Height, Format, alphaRef)); } } Image.Dispose(); return(Utils.CombineByteArray(mipmaps.ToArray())); }
public void LoadDDS(string FileName, byte[] FileData = null) { TexName = STGenericTexture.SetNameFromPath(FileName); DDS dds = new DDS(); if (FileData != null) { dds.Load(new FileReader(new MemoryStream(FileData))); } else { dds.Load(new FileReader(FileName)); } MipCount = dds.header.mipmapCount; TexWidth = dds.header.width; TexHeight = dds.header.height; var surfaces = DDS.GetArrayFaces(dds, dds.ArrayCount); RedComp = dds.RedChannel; GreenComp = dds.GreenChannel; BlueComp = dds.BlueChannel; AlphaComp = dds.AlphaChannel; foreach (var surface in surfaces) { DataBlockOutput.Add(Utils.CombineByteArray(surface.mipmaps.ToArray())); } Format = dds.Format; }
public static TextureFormats FromGenericFormat(TEX_FORMAT Format) { switch (Format) { case TEX_FORMAT.C14X2: return(TextureFormats.C14X2); case TEX_FORMAT.C4: return(TextureFormats.C4); case TEX_FORMAT.C8: return(TextureFormats.C8); case TEX_FORMAT.CMPR: return(TextureFormats.CMPR); case TEX_FORMAT.I4: return(TextureFormats.I4); case TEX_FORMAT.I8: return(TextureFormats.I8); case TEX_FORMAT.IA4: return(TextureFormats.IA4); case TEX_FORMAT.IA8: return(TextureFormats.IA8); case TEX_FORMAT.RGB565: return(TextureFormats.RGB565); case TEX_FORMAT.RGB5A3: return(TextureFormats.RGB5A3); case TEX_FORMAT.RGBA32: return(TextureFormats.RGBA32); default: throw new Exception("Unknown Format " + Format); } }
private void LoadComponents(TEX_FORMAT Format, bool isBc4Alpha) { switch (Format) { case TEX_FORMAT.BC5_SNORM: case TEX_FORMAT.BC5_UNORM: RedChannel = STChannelType.Red; GreenChannel = STChannelType.Red; BlueChannel = STChannelType.Red; AlphaChannel = STChannelType.Green; break; case TEX_FORMAT.BC4_SNORM: case TEX_FORMAT.BC4_UNORM: RedChannel = STChannelType.Red; GreenChannel = STChannelType.Red; BlueChannel = STChannelType.Red; AlphaChannel = STChannelType.One; if (isBc4Alpha) { RedChannel = STChannelType.One; GreenChannel = STChannelType.One; BlueChannel = STChannelType.One; AlphaChannel = STChannelType.Red; } break; } }
private static byte[] GetComponentsFromPixel(TEX_FORMAT format, int pixel, byte[] comp) { switch (format) { case TEX_FORMAT.L8: comp[0] = (byte)(pixel & 0xFF); break; case TEX_FORMAT.LA8: comp[0] = (byte)(pixel & 0xFF); comp[1] = (byte)((pixel & 0xFF00) >> 8); break; case TEX_FORMAT.LA4: comp[0] = (byte)((pixel & 0xF) * 17); comp[1] = (byte)(((pixel & 0xF0) >> 4) * 17); break; case TEX_FORMAT.R5G5B5_UNORM: comp[0] = (byte)((pixel & 0x1F) / 0x1F * 0xFF); comp[1] = (byte)(((pixel & 0x7E0) >> 5) / 0x3F * 0xFF); comp[2] = (byte)(((pixel & 0xF800) >> 11) / 0x1F * 0xFF); break; case TEX_FORMAT.B5G6R5_UNORM: comp[0] = (byte)(((pixel & 0xF800) >> 11) / 0x1F * 0xFF); comp[1] = (byte)(((pixel & 0x7E0) >> 5) / 0x3F * 0xFF); comp[2] = (byte)((pixel & 0x1F) / 0x1F * 0xFF); break; } return(comp); }
public static GX2SurfaceFormat ConvertToGx2Format(TEX_FORMAT texFormat) { switch (texFormat) { case TEX_FORMAT.BC1_UNORM: return(GX2SurfaceFormat.T_BC1_UNorm); case TEX_FORMAT.BC1_UNORM_SRGB: return(GX2SurfaceFormat.T_BC1_SRGB); case TEX_FORMAT.BC2_UNORM: return(GX2SurfaceFormat.T_BC2_UNorm); case TEX_FORMAT.BC2_UNORM_SRGB: return(GX2SurfaceFormat.T_BC2_SRGB); case TEX_FORMAT.BC3_UNORM: return(GX2SurfaceFormat.T_BC3_UNorm); case TEX_FORMAT.BC3_UNORM_SRGB: return(GX2SurfaceFormat.T_BC3_SRGB); case TEX_FORMAT.BC4_UNORM: return(GX2SurfaceFormat.T_BC4_UNorm); case TEX_FORMAT.BC4_SNORM: return(GX2SurfaceFormat.T_BC4_SNorm); case TEX_FORMAT.BC5_UNORM: return(GX2SurfaceFormat.T_BC5_UNorm); case TEX_FORMAT.BC5_SNORM: return(GX2SurfaceFormat.T_BC5_SNorm); case TEX_FORMAT.B5G5R5A1_UNORM: return(GX2SurfaceFormat.TC_R5_G5_B5_A1_UNorm); case TEX_FORMAT.B4G4R4A4_UNORM: return(GX2SurfaceFormat.TC_R4_G4_B4_A4_UNorm); case TEX_FORMAT.B5G6R5_UNORM: return(GX2SurfaceFormat.TCS_R5_G6_B5_UNorm); case TEX_FORMAT.R8G8B8A8_UNORM: return(GX2SurfaceFormat.TCS_R8_G8_B8_A8_UNorm); case TEX_FORMAT.R8G8B8A8_UNORM_SRGB: return(GX2SurfaceFormat.TCS_R8_G8_B8_A8_SRGB); case TEX_FORMAT.R10G10B10A2_UNORM: return(GX2SurfaceFormat.TCS_R10_G10_B10_A2_UNorm); case TEX_FORMAT.R11G11B10_FLOAT: return(GX2SurfaceFormat.TC_R11_G11_B10_Float); case TEX_FORMAT.R16_UNORM: return(GX2SurfaceFormat.TCD_R16_UNorm); case TEX_FORMAT.R32_FLOAT: return(GX2SurfaceFormat.TCD_R32_Float); case TEX_FORMAT.R8G8_UNORM: return(GX2SurfaceFormat.TC_R8_G8_UNorm); case TEX_FORMAT.R8G8_SNORM: return(GX2SurfaceFormat.TC_R8_G8_SNorm); case TEX_FORMAT.R8_UNORM: return(GX2SurfaceFormat.TC_R8_UNorm); case TEX_FORMAT.A8_UNORM: return(GX2SurfaceFormat.TC_R8_UNorm); case TEX_FORMAT.B8G8R8A8_UNORM: return(GX2SurfaceFormat.TCS_R8_G8_B8_A8_UNorm); case TEX_FORMAT.B8G8R8A8_UNORM_SRGB: return(GX2SurfaceFormat.TCS_R8_G8_B8_A8_SRGB); case TEX_FORMAT.R32G8X24_FLOAT: return(GX2SurfaceFormat.T_R32_Float_X8_X24); default: throw new Exception($"Cannot convert format {texFormat}"); } }
public void LoadBitMap(string FileName, BntxFile bntxFile) { DecompressedData.Clear(); TexName = Path.GetFileNameWithoutExtension(FileName); bntx = bntxFile; Format = TEX_FORMAT.BC1; FormatType = TEX_FORMAT_TYPE.SRGB; GenerateMipmaps = true; Bitmap Image = new Bitmap(FileName); Image = STGenericTexture.SwapBlueRedChannels(Image); TexWidth = (uint)Image.Width; TexHeight = (uint)Image.Height; MipCount = (uint)GetTotalMipCount(); DecompressedData.Add(BitmapExtension.ImageToByte(Image)); Image.Dispose(); if (DecompressedData.Count == 0) { throw new Exception("Failed to load " + Format); } }
public void CreateGenericTexture(uint width, uint height, List <Surface> surfaces, TEX_FORMAT format) { Width = width; Height = height; Surfaces = surfaces; Surfaces = surfaces; Format = format; }
private void formatCB_SelectedIndexChanged(object sender, EventArgs e) { if (formatCB.SelectedIndex >= 0) { Format = (TEX_FORMAT)formatCB.SelectedItem; UpdateImage(); } }
//Method from https://github.com/aboood40091/BNTX-Editor/blob/master/formConv.py public static byte[] Decode(byte[] data, int width, int height, TEX_FORMAT format) { uint bpp = STGenericTexture.GetBytesPerPixel(format); int size = width * height * 4; bpp = (uint)(data.Length / (width * height)); byte[] output = new byte[size]; int inPos = 0; int outPos = 0; byte[] comp = new byte[] { 0, 0, 0, 0xFF, 0, 0xFF }; byte[] compSel = new byte[4] { 0, 1, 2, 3 }; if (format == TEX_FORMAT.LA8) { compSel = new byte[4] { 0, 0, 0, 1 }; bpp = 2; } else if (format == TEX_FORMAT.L8) { compSel = new byte[4] { 0, 0, 0, 5 } } ; for (int Y = 0; Y < height; Y++) { for (int X = 0; X < width; X++) { inPos = (Y * width + X) * (int)bpp; outPos = (Y * width + X) * 4; int pixel = 0; for (int i = 0; i < bpp; i++) { pixel |= data[inPos + i] << (8 * i); } comp = GetComponentsFromPixel(format, pixel, comp); output[outPos + 3] = comp[compSel[3]]; output[outPos + 2] = comp[compSel[2]]; output[outPos + 1] = comp[compSel[1]]; output[outPos + 0] = comp[compSel[0]]; } } return(output); } }
/// <summary> /// Decodes a byte array of image data given the source image in bytes, width, height, and DXGI format. /// </summary> /// <param name="byte[]">The byte array of the image</param> /// <param name="Width">The width of the image in pixels.</param> /// <param name="Height">The height of the image in pixels.</param> /// <param name=" DDS.DXGI_FORMAT">The image format.</param> /// <returns>Returns a byte array of decoded data. </returns> public static byte[] DecodeBlock(byte[] data, uint Width, uint Height, TEX_FORMAT Format, PlatformSwizzle PlatformSwizzle = PlatformSwizzle.None) { if (data == null) { throw new Exception($"Data is null!"); } if (Format <= 0) { throw new Exception($"Invalid Format!"); } if (data.Length <= 0) { throw new Exception($"Data is empty!"); } if (Width <= 0) { throw new Exception($"Invalid width size {Width}!"); } if (Height <= 0) { throw new Exception($"Invalid height size {Height}!"); } if (PlatformSwizzle == PlatformSwizzle.Platform_3DS && !IsCompressed(Format)) { return(CTR_3DS.DecodeBlock(data, (int)Width, (int)Height, Format)); } if (Format == TEX_FORMAT.R32G8X24_FLOAT) { return(ConvertBgraToRgba(DDSCompressor.DecodePixelBlock(data, (int)Width, (int)Height, DDS.DXGI_FORMAT.DXGI_FORMAT_R32G8X24_TYPELESS))); } if (Format == TEX_FORMAT.BC5_SNORM) { return(ConvertBgraToRgba(DDSCompressor.DecompressBC5(data, (int)Width, (int)Height, true, true))); } if (IsCompressed(Format)) { return(ConvertBgraToRgba(DDSCompressor.DecompressBlock(data, (int)Width, (int)Height, (DDS.DXGI_FORMAT)Format))); } else { //If blue channel becomes first, do not swap them! // if (Format.ToString().StartsWith("B") || Format == TEX_FORMAT.B5G6R5_UNORM) // return DDSCompressor.DecodePixelBlock(data, (int)Width, (int)Height, (DDS.DXGI_FORMAT)Format); if (IsAtscFormat(Format)) { return(ConvertBgraToRgba(ASTCDecoder.DecodeToRGBA8888(data, (int)GetBlockWidth(Format), (int)GetBlockHeight(Format), 1, (int)Width, (int)Height, 1))); } else { return(ConvertBgraToRgba(DDSCompressor.DecodePixelBlock(data, (int)Width, (int)Height, (DDS.DXGI_FORMAT)Format))); } } }
private void EditInExternalProgram(bool UseDefaultEditor = true) { if (!ActiveTexture.CanEdit || !IsFinished) { return; } ImageProgramSettings settings = new ImageProgramSettings(); settings.LoadImage(ActiveTexture); if (settings.ShowDialog() == DialogResult.OK) { UseDefaultEditor = !settings.OpenDefaultProgramSelection; string UseExtension = settings.GetSelectedExtension(); FormatToChange = settings.GetSelectedImageFormat(); string TemporaryName = Path.GetTempFileName(); Utils.DeleteIfExists(Path.ChangeExtension(TemporaryName, UseExtension)); File.Move(TemporaryName, Path.ChangeExtension(TemporaryName, UseExtension)); TemporaryName = Path.ChangeExtension(TemporaryName, UseExtension); switch (UseExtension) { case ".dds": ActiveTexture.SaveDDS(TemporaryName, true, false, CurArrayDisplayLevel, CurMipDisplayLevel); break; case ".astc": ActiveTexture.SaveASTC(TemporaryName, true, false, CurArrayDisplayLevel, CurMipDisplayLevel); break; case ".tga": ActiveTexture.SaveTGA(TemporaryName, true, false, CurArrayDisplayLevel, CurMipDisplayLevel); break; default: ActiveTexture.SaveBitMap(TemporaryName, true, false, CurArrayDisplayLevel, CurMipDisplayLevel); break; } if (UseDefaultEditor) { Process.Start(TemporaryName); } else { ShowOpenWithDialog(TemporaryName); } FileWatcher.Filter = Path.GetFileName(TemporaryName); //Start watching for changes FileWatcher.EnableRaisingEvents = true; } }
public static Tuple <SurfaceFormat, SurfaceFormatType> GetSurfaceFormat(TEX_FORMAT format, TEX_FORMAT_TYPE type) { var surfaceFormat = SurfaceFormat.Invalid; var surfaceType = SurfaceFormatType.UNORM; Enum.TryParse(format.ToString(), out surfaceFormat); Enum.TryParse(type.ToString(), out surfaceType); return(Tuple.Create(surfaceFormat, surfaceType)); }
public WtaProperties(TEX_FORMAT format, uint width, uint height, uint depth, SurfaceType type, ulong imageSize, uint headerSize) { Format = format; Width = width; Height = height; Depth = depth; SurfaceType = type; ImageSize = imageSize; HeaderSize = headerSize; }
public static bool IsAtscFormat(TEX_FORMAT Format) { if (Format.ToString().Contains("ASTC")) { return(true); } else { return(false); } }
public static DXGI_FORMAT GetDXGI_Format(TEX_FORMAT Format, TEX_FORMAT_TYPE type) { DXGI_FORMAT format = DXGI_FORMAT.DXGI_FORMAT_UNKNOWN; string formatSTR = GetFormatString(Format); string typeSTR = GetFormatTypeString(type, Format); Enum.TryParse(formatSTR + typeSTR, out format); return(format); }
public void LoadBitMap(Image Image, string Name) { DecompressedData.Clear(); TexName = STGenericTexture.SetNameFromPath(Name); Format = Runtime.PreferredTexFormat; GenerateMipmaps = true; LoadImage(new Bitmap(Image)); }
public static byte[] CompressBlock(byte[] data, int width, int height, TEX_FORMAT format, float alphaRef, STCompressionMode CompressionMode = STCompressionMode.Fast) { if (IsCompressed(format)) { return(DDSCompressor.CompressBlock(data, width, height, (DDS.DXGI_FORMAT)format, alphaRef, CompressionMode)); } else if (IsAtscFormat(format)) { return(null); } else { return(DDSCompressor.EncodePixelBlock(data, width, height, (DDS.DXGI_FORMAT)format)); } }
public static byte[] CompressBlock(byte[] data, int width, int height, TEX_FORMAT format, TEX_FORMAT_TYPE type, float alphaRef) { if (IsCompressed(format)) { return(DDSCompressor.CompressBlock(data, width, height, DDS.GetDXGI_Format(format, type), alphaRef)); } else if (IsAtscFormat(format)) { return(null); } else { return(DDSCompressor.EncodePixelBlock(data, width, height, DDS.GetDXGI_Format(format, type))); } }
public static bool IsCompressed(TEX_FORMAT Format) { switch (Format) { case TEX_FORMAT.BC1: case TEX_FORMAT.BC2: case TEX_FORMAT.BC3: case TEX_FORMAT.BC4: case TEX_FORMAT.BC5: case TEX_FORMAT.BC6: case TEX_FORMAT.BC7: return(true); default: return(false); } }
//Get only type private static string GetFormatTypeString(TEX_FORMAT_TYPE type, TEX_FORMAT format) { switch (type) { case TEX_FORMAT_TYPE.FLOAT: if (format == TEX_FORMAT.BC6) { return("SF16"); } else { return("FLOAT"); } case TEX_FORMAT_TYPE.UFLOAT: if (format == TEX_FORMAT.BC6) { return("UF16"); } else { return("UFLOAT"); } case TEX_FORMAT_TYPE.SINT: return("SINT"); case TEX_FORMAT_TYPE.UINT: return("UINT"); case TEX_FORMAT_TYPE.SNORM: return("SNORM"); case TEX_FORMAT_TYPE.UNORM: return("UNORM"); case TEX_FORMAT_TYPE.TYPELESS: return("TYPELESS"); case TEX_FORMAT_TYPE.SRGB: return("UNORM_SRGB"); default: return(""); } }
public void LoadASTC(string FileName) { DecompressedData.Clear(); TexName = STGenericTexture.SetNameFromPath(FileName); ASTC astc = new ASTC(); astc.Load(new FileStream(FileName, FileMode.Open)); MipCount = 0; TexWidth = (uint)astc.Width; TexHeight = (uint)astc.Height; DataBlockOutput.Add(astc.DataBlock); Format = astc.Format; }
public static BFLIMFormat ConvertFormatGenericToBflim(TEX_FORMAT Format) { switch (Format) { case TEX_FORMAT.A8_UNORM: return(BFLIMFormat.L8_UNORM); case TEX_FORMAT.R8G8_UNORM: return(BFLIMFormat.LA8); case TEX_FORMAT.R8G8_SNORM: return(BFLIMFormat.LA8); case TEX_FORMAT.B5G6R5_UNORM: return(BFLIMFormat.RGB565); case TEX_FORMAT.B5G5R5A1_UNORM: return(BFLIMFormat.RGB5A1); case TEX_FORMAT.R8G8B8A8_UNORM: return(BFLIMFormat.RGBA8); case TEX_FORMAT.R8G8B8A8_UNORM_SRGB: return(BFLIMFormat.RGBA8_SRGB); case TEX_FORMAT.R10G10B10A2_UNORM: return(BFLIMFormat.RGB10A2_UNORM); case TEX_FORMAT.B4G4R4A4_UNORM: return(BFLIMFormat.RGBA4); case TEX_FORMAT.BC1_UNORM: return(BFLIMFormat.BC1_UNORM); case TEX_FORMAT.BC1_UNORM_SRGB: return(BFLIMFormat.BC1_SRGB); case TEX_FORMAT.BC2_UNORM: return(BFLIMFormat.BC2_UNORM); case TEX_FORMAT.BC2_UNORM_SRGB: return(BFLIMFormat.BC2_SRGB); case TEX_FORMAT.BC3_UNORM: return(BFLIMFormat.BC3_UNORM); case TEX_FORMAT.BC3_UNORM_SRGB: return(BFLIMFormat.BC3_SRGB); case TEX_FORMAT.BC4_UNORM: return(BFLIMFormat.BC4A_UNORM); case TEX_FORMAT.BC4_SNORM: return(BFLIMFormat.BC4L_UNORM); case TEX_FORMAT.BC5_UNORM: return(BFLIMFormat.BC5_UNORM); default: throw new Exception("Unsupported format " + Format); } }
public static NUTEXImageFormat ConvertGenericToNutFormat(TEX_FORMAT nutFormat) { switch (nutFormat) { case TEX_FORMAT.B8G8R8A8_UNORM_SRGB: return(NUTEXImageFormat.B8G8R8A8_SRGB); case TEX_FORMAT.B8G8R8A8_UNORM: return(NUTEXImageFormat.B8G8R8A8_UNORM); case TEX_FORMAT.BC1_UNORM_SRGB: return(NUTEXImageFormat.BC1_SRGB); case TEX_FORMAT.BC1_UNORM: return(NUTEXImageFormat.BC1_UNORM); case TEX_FORMAT.BC2_UNORM: return(NUTEXImageFormat.BC2_UNORM); case TEX_FORMAT.BC3_UNORM: return(NUTEXImageFormat.BC3_UNORM); case TEX_FORMAT.BC3_UNORM_SRGB: return(NUTEXImageFormat.BC3_SRGB); case TEX_FORMAT.BC4_UNORM: return(NUTEXImageFormat.BC4_UNORM); case TEX_FORMAT.BC4_SNORM: return(NUTEXImageFormat.BC4_SNORM); case TEX_FORMAT.BC5_UNORM: return(NUTEXImageFormat.BC5_UNORM); case TEX_FORMAT.BC5_SNORM: return(NUTEXImageFormat.BC5_SNORM); case TEX_FORMAT.BC6H_UF16: return(NUTEXImageFormat.BC6_UFLOAT); case TEX_FORMAT.BC6H_SF16: return(NUTEXImageFormat.BC6_SFLOAT); case TEX_FORMAT.BC7_UNORM: return(NUTEXImageFormat.BC7_UNORM); case TEX_FORMAT.BC7_UNORM_SRGB: return(NUTEXImageFormat.BC7_SRGB); case TEX_FORMAT.R32G32B32A32_FLOAT: return(NUTEXImageFormat.R32G32B32A32_FLOAT); case TEX_FORMAT.R8G8B8A8_UNORM_SRGB: return(NUTEXImageFormat.R8G8B8A8_SRGB); case TEX_FORMAT.R8G8B8A8_UNORM: return(NUTEXImageFormat.R8G8B8A8_UNORM); default: throw new Exception($"Cannot convert format {nutFormat}"); } }
public static List <uint[]> GenerateMipSizes(TEX_FORMAT Format, uint Width, uint Height, uint Depth, uint SurfaceCount, uint MipCount, uint ImageSize) { List <uint[]> MipMapSizes = new List <uint[]>(); uint bpp = STGenericTexture.GetBytesPerPixel(Format); uint blkWidth = STGenericTexture.GetBlockWidth(Format); uint blkHeight = STGenericTexture.GetBlockHeight(Format); uint blkDepth = STGenericTexture.GetBlockDepth(Format); uint blockHeight = GetBlockHeight(DIV_ROUND_UP(Height, blkHeight)); uint BlockHeightLog2 = (uint)Convert.ToString(blockHeight, 2).Length - 1; uint Pitch = 0; uint DataAlignment = 512; int linesPerBlockHeight = (1 << (int)BlockHeightLog2) * 8; uint ArrayCount = SurfaceCount; uint ArrayOffset = 0; for (int arrayLevel = 0; arrayLevel < ArrayCount; arrayLevel++) { uint SurfaceSize = 0; int blockHeightShift = 0; uint[] MipOffsets = new uint[MipCount]; for (int mipLevel = 0; mipLevel < MipCount; mipLevel++) { uint width = (uint)Math.Max(1, Width >> mipLevel); uint height = (uint)Math.Max(1, Height >> mipLevel); uint depth = (uint)Math.Max(1, Depth >> mipLevel); uint size = DIV_ROUND_UP(width, blkWidth) * DIV_ROUND_UP(height, blkHeight) * bpp; MipOffsets[mipLevel] = size; } ArrayOffset += (uint)(ImageSize / ArrayCount); MipMapSizes.Add(MipOffsets); } return(MipMapSizes); }
/// <summary> /// Decodes a byte array of image data given the source image in bytes, width, height, and DXGI format. /// </summary> /// <param name="byte[]">The byte array of the image</param> /// <param name="Width">The width of the image in pixels.</param> /// <param name="Height">The height of the image in pixels.</param> /// <param name=" DDS.DXGI_FORMAT">The image format.</param> /// <returns>Returns a byte array of decoded data. </returns> public static byte[] DecodeBlock(byte[] data, uint Width, uint Height, TEX_FORMAT Format) { if (Format <= 0) { throw new Exception($"Invalid Format!"); } if (data.Length <= 0) { throw new Exception($"Data is empty!"); } if (Width <= 0) { throw new Exception($"Invalid width size {Width}!"); } if (Height <= 0) { throw new Exception($"Invalid height size {Height}!"); } if (Format == TEX_FORMAT.BC5) { return(ConvertBgraToRgba(DDSCompressor.DecompressBC5(data, (int)Width, (int)Height, true, true))); } if (IsCompressed(Format)) { return(ConvertBgraToRgba(DDSCompressor.DecompressBlock(data, (int)Width, (int)Height, (DDS.DXGI_FORMAT)Format))); } else { //If blue channel becomes first, do not swap them if (Format.ToString().Contains("FORMAT_B")) { return(DDSCompressor.DecodePixelBlock(data, (int)Width, (int)Height, (DDS.DXGI_FORMAT)Format)); } else { return(ConvertBgraToRgba(DDSCompressor.DecodePixelBlock(data, (int)Width, (int)Height, (DDS.DXGI_FORMAT)Format))); } } }