public byte[] DecodeImage(STGenericTexture texture, byte[] data, uint width, uint height, int array, int mip) { if (BlockHeightLog2 == 0) { uint blkHeight = TextureFormatHelper.GetBlockHeight(OutputFormat); uint blockHeight = TegraX1Swizzle.GetBlockHeight(TegraX1Swizzle.DIV_ROUND_UP(height, blkHeight)); BlockHeightLog2 = (uint)Convert.ToString(blockHeight, 2).Length - 1; } return(Switch.TegraX1Swizzle.GetImageData(texture, data, array, mip, 0, BlockHeightLog2, Target, LinearMode)); }
public bool Decode(TexFormat format, byte[] input, int width, int height, out byte[] output) { output = null; if (format.ToString().StartsWith("ASTC")) { var x = (int)TextureFormatHelper.GetBlockWidth(format); var y = (int)TextureFormatHelper.GetBlockHeight(format); var z = (int)TextureFormatHelper.GetBlockDepth(format); output = ASTCDecoder.DecodeToRGBA8888(input, x, y, z, width, height, 1); } return(output != null); }
public byte[] DecodeImage(STGenericTexture texture, byte[] data, uint width, uint height, int array, int mip) { if (data.Length == 0) { throw new Exception("Data is empty! Failed to swizzle image!"); } if (BlockHeightLog2 == 0) { uint blkHeight = TextureFormatHelper.GetBlockHeight(OutputFormat); uint blockHeight = TegraX1Swizzle.GetBlockHeight(TegraX1Swizzle.DIV_ROUND_UP(texture.Height, blkHeight)); BlockHeightLog2 = (uint)Convert.ToString(blockHeight, 2).Length; if (OutputFormat != TexFormat.ASTC_8x5_UNORM) { BlockHeightLog2 -= 1; } } return(TegraX1Swizzle.GetImageData(texture, data, array, mip, 0, BlockHeightLog2, Target, LinearMode)); }
public static List <uint[]> GenerateMipSizes(TexFormat Format, uint Width, uint Height, uint Depth, uint SurfaceCount, uint MipCount, uint ImageSize) { List <uint[]> MipMapSizes = new List <uint[]>(); uint bpp = TextureFormatHelper.GetBytesPerPixel(Format); uint blkWidth = TextureFormatHelper.GetBlockWidth(Format); uint blkHeight = TextureFormatHelper.GetBlockHeight(Format); uint blkDepth = TextureFormatHelper.GetBlockDepth(Format); uint blockHeight = TegraX1Swizzle.GetBlockHeight(TegraX1Swizzle.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 = TegraX1Swizzle.DIV_ROUND_UP(width, blkWidth) * TegraX1Swizzle.DIV_ROUND_UP(height, blkHeight) * bpp; if (TegraX1Swizzle.pow2_round_up(TegraX1Swizzle.DIV_ROUND_UP(height, blkWidth)) < linesPerBlockHeight) { blockHeightShift += 1; } uint width__ = TegraX1Swizzle.DIV_ROUND_UP(width, blkWidth); uint height__ = TegraX1Swizzle.DIV_ROUND_UP(height, blkHeight); //Calculate the mip size instead byte[] AlignedData = new byte[(TegraX1Swizzle.round_up(SurfaceSize, DataAlignment) - SurfaceSize)]; SurfaceSize += (uint)AlignedData.Length; MipOffsets[mipLevel] = (SurfaceSize); //Get the first mip offset and current one and the total image size int msize = (int)((MipOffsets[0] + ImageSize - MipOffsets[mipLevel]) / ArrayCount); Pitch = TegraX1Swizzle.round_up(width__ * bpp, 64); SurfaceSize += Pitch * TegraX1Swizzle.round_up(height__, Math.Max(1, blockHeight >> blockHeightShift) * 8); } ArrayOffset += (uint)(ImageSize / ArrayCount); MipMapSizes.Add(MipOffsets); } return(MipMapSizes); }