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]);
        }