public static Bitmap GetBitmap(Texture texture, int ArrayLevel = 0, int MipLevel = 0, int DepthLevel = 0) { int width = (int)Math.Max(1, texture.Width >> MipLevel); int height = (int)Math.Max(1, texture.Height >> MipLevel); TextureFormatInfo formatInfo = TextureFormatInfo.FormatTable[texture.Format]; Memory <byte> data = GetImageData(texture, ArrayLevel, MipLevel, DepthLevel); if (AstcDecoder.CanHandle(texture)) { if (AstcDecoder.TryDecodeToRgba8(data, (int)formatInfo.BlockWidth, (int)formatInfo.BlockHeight, width, height, 1, 1, out var decoded)) { return(GetBitmapFromBytes(ConvertBgraToRgba(decoded), width, height, PixelFormat.Format32bppArgb)); } } else if (DDSDecoder.CanHandle(texture)) { return(DDSDecoder.Decompress(data.Span, width, height, texture.Format)); } else if (RgbaDecoder.CanHandle(texture)) { return(RgbaDecoder.Decode(data.Span, width, height, texture.Format)); } return(null); }
public static Memory <byte> GetImageData(Texture texture, int targetArrayLevel = 0, int targetMipLevel = 0, int targetDepthLevel = 0) { TextureFormatInfo formatInfo = TextureFormatInfo.FormatTable[texture.Format]; int target = 1; uint blkWidth = formatInfo.BlockWidth; uint blkHeight = formatInfo.BlockHeight; int linesPerBlockHeight = (1 << (int)texture.BlockHeightLog2) * 8; uint bpp = formatInfo.BytesPerPixel; uint numDepth = 1; for (int depthLevel = 0; depthLevel < numDepth; depthLevel++) { for (int arrayLevel = 0; arrayLevel < texture.TextureData.Count; arrayLevel++) { int blockHeightShift = 0; for (int mipLevel = 0; mipLevel < texture.TextureData[arrayLevel].Count; mipLevel++) { uint width = Math.Max(1, texture.Width >> mipLevel); uint height = Math.Max(1, texture.Height >> mipLevel); uint size = TegraX1Swizzle.DivRoundUp(width, blkWidth) * TegraX1Swizzle.DivRoundUp(height, blkHeight) * bpp; if (TegraX1Swizzle.Pow2RoundUp(TegraX1Swizzle.DivRoundUp(height, blkWidth)) < linesPerBlockHeight) { blockHeightShift += 1; } if (targetArrayLevel == arrayLevel && targetMipLevel == mipLevel && targetDepthLevel == depthLevel) { //Console.WriteLine($"{width} {height} {depth} {blkWidth} {blkHeight} {blkDepth} {target} {bpp} {texture.TileMode} {(int)Math.Max(0, texture.BlockHeightLog2 - blockHeightShift)} {texture.TextureData[arrayLevel][mipLevel].Length}"); var result = TegraX1Swizzle.Deswizzle(width, height, blkWidth, blkHeight, target, bpp, (uint)texture.TileMode, (int)Math.Max(0, texture.BlockHeightLog2 - blockHeightShift), texture.TextureData[arrayLevel][mipLevel]); return(new ArraySegment <byte>(result, 0, (int)size)); } } } } return(new byte[0]); }