예제 #1
0
        public void Create(long Key, byte[] Data, GalImage Image)
        {
            int Handle = GL.GenTexture();

            GL.BindTexture(TextureTarget.Texture2D, Handle);

            const int Level  = 0; //TODO: Support mipmap textures.
            const int Border = 0;

            TextureCache.AddOrUpdate(Key, new ImageHandler(Handle, Image), (uint)Data.Length);

            if (ImageUtils.IsCompressed(Image.Format) && !IsAstc(Image.Format))
            {
                InternalFormat InternalFmt = OGLEnumConverter.GetCompressedImageFormat(Image.Format);

                GL.CompressedTexImage2D(
                    TextureTarget.Texture2D,
                    Level,
                    InternalFmt,
                    Image.Width,
                    Image.Height,
                    Border,
                    Data.Length,
                    Data);
            }
            else
            {
                //TODO: Use KHR_texture_compression_astc_hdr when available
                if (IsAstc(Image.Format))
                {
                    int TextureBlockWidth  = ImageUtils.GetBlockWidth(Image.Format);
                    int TextureBlockHeight = ImageUtils.GetBlockHeight(Image.Format);

                    Data = ASTCDecoder.DecodeToRGBA8888(
                        Data,
                        TextureBlockWidth,
                        TextureBlockHeight, 1,
                        Image.Width,
                        Image.Height, 1);

                    Image.Format = GalImageFormat.RGBA8 | (Image.Format & GalImageFormat.TypeMask);
                }

                (PixelInternalFormat InternalFmt,
                 PixelFormat Format,
                 PixelType Type) = OGLEnumConverter.GetImageFormat(Image.Format);

                GL.TexImage2D(
                    TextureTarget.Texture2D,
                    Level,
                    InternalFmt,
                    Image.Width,
                    Image.Height,
                    Border,
                    Format,
                    Type,
                    Data);
            }
        }
        /// <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)));
                }
            }
        }
예제 #3
0
 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);
 }
예제 #4
0
        private static GalTexture ConvertAstcTextureToRgba(GalTexture Texture)
        {
            int TextureBlockWidth  = GetAstcBlockWidth(Texture.Format);
            int TextureBlockHeight = GetAstcBlockHeight(Texture.Format);

            Texture.Data = ASTCDecoder.DecodeToRGBA8888(
                Texture.Data,
                TextureBlockWidth,
                TextureBlockHeight, 1,
                Texture.Width,
                Texture.Height, 1);

            Texture.Format = GalTextureFormat.A8B8G8R8;

            return(Texture);
        }
예제 #5
0
        public void Create(long Key, byte[] Data, GalTexture Texture)
        {
            int Handle = GL.GenTexture();

            TextureCache.AddOrUpdate(Key, new TCE(Handle, Texture), (uint)Data.Length);

            GL.BindTexture(TextureTarget.Texture2D, Handle);

            const int Level  = 0; //TODO: Support mipmap textures.
            const int Border = 0;

            if (IsCompressedTextureFormat(Texture.Format))
            {
                InternalFormat InternalFmt = OGLEnumConverter.GetCompressedTextureFormat(Texture.Format);

                GL.CompressedTexImage2D(
                    TextureTarget.Texture2D,
                    Level,
                    InternalFmt,
                    Texture.Width,
                    Texture.Height,
                    Border,
                    Data.Length,
                    Data);
            }
            else
            {
                if (Texture.Format >= GalTextureFormat.Astc2D4x4)
                {
                    int TextureBlockWidth  = GetAstcBlockWidth(Texture.Format);
                    int TextureBlockHeight = GetAstcBlockHeight(Texture.Format);

                    Data = ASTCDecoder.DecodeToRGBA8888(
                        Data,
                        TextureBlockWidth,
                        TextureBlockHeight, 1,
                        Texture.Width,
                        Texture.Height, 1);

                    Texture.Format = GalTextureFormat.A8B8G8R8;
                }

                const PixelInternalFormat InternalFmt = PixelInternalFormat.Rgba;

                (PixelFormat Format, PixelType Type) = OGLEnumConverter.GetTextureFormat(Texture.Format);

                GL.TexImage2D(
                    TextureTarget.Texture2D,
                    Level,
                    InternalFmt,
                    Texture.Width,
                    Texture.Height,
                    Border,
                    Format,
                    Type,
                    Data);
            }

            int SwizzleR = (int)OGLEnumConverter.GetTextureSwizzle(Texture.XSource);
            int SwizzleG = (int)OGLEnumConverter.GetTextureSwizzle(Texture.YSource);
            int SwizzleB = (int)OGLEnumConverter.GetTextureSwizzle(Texture.ZSource);
            int SwizzleA = (int)OGLEnumConverter.GetTextureSwizzle(Texture.WSource);

            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureSwizzleR, SwizzleR);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureSwizzleG, SwizzleG);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureSwizzleB, SwizzleB);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureSwizzleA, SwizzleA);
        }
예제 #6
0
        public static SKImage DecodeImage(byte[] sequence, int width, int height, int depth, EPixelFormat format)
        {
            byte[]      data;
            SKColorType colorType;

            switch (format)
            {
            case EPixelFormat.PF_DXT5:
                data      = DXTDecoder.DecodeDXT5(sequence, width, height, depth);
                colorType = SKColorType.Rgba8888;
                break;

            case EPixelFormat.PF_DXT1:
                data      = DXTDecoder.DecodeDXT1(sequence, width, height, depth);
                colorType = SKColorType.Rgba8888;
                break;

            case EPixelFormat.PF_ASTC_8x8:
                var x = (int)TextureFormatHelper.GetBlockWidth(format);
                var y = (int)TextureFormatHelper.GetBlockHeight(format);
                var z = (int)TextureFormatHelper.GetBlockDepth(format);
                data      = ASTCDecoder.DecodeToRGBA8888(sequence, x, y, z, width, height, 1);
                colorType = SKColorType.Rgba8888;
                break;

            case EPixelFormat.PF_B8G8R8A8:
                data      = sequence;
                colorType = SKColorType.Bgra8888;
                break;

            case EPixelFormat.PF_BC5:
                data      = BCDecoder.DecodeBC5(sequence, width, height);
                colorType = SKColorType.Rgb888x;
                break;

            case EPixelFormat.PF_BC4:
                data      = BCDecoder.DecodeBC4(sequence, width, height);
                colorType = SKColorType.Rgb888x;
                break;

            case EPixelFormat.PF_G8:
                data      = sequence;
                colorType = SKColorType.Gray8;
                break;

            case EPixelFormat.PF_FloatRGBA:
                data      = sequence;
                colorType = SKColorType.RgbaF16;
                break;

            case EPixelFormat.PF_BC7:
                data = Detex.DecodeDetexLinear(sequence, width, height, isFloat: false,
                                               inputFormat: DetexTextureFormat.DETEX_TEXTURE_FORMAT_BPTC,
                                               outputPixelFormat: DetexPixelFormat.DETEX_PIXEL_FORMAT_RGBA8);
                colorType = SKColorType.Rgb888x;
                break;

            case EPixelFormat.PF_BC6H:
                data = Detex.DecodeDetexLinear(sequence, width, height, isFloat: true,
                                               inputFormat: DetexTextureFormat.DETEX_TEXTURE_FORMAT_BPTC_FLOAT,
                                               outputPixelFormat: DetexPixelFormat.DETEX_PIXEL_FORMAT_RGBX8); // Not sure whether that works, would actually be DETEX_PIXEL_FORMAT_FLOAT_RGBX32
                data      = Detex.DecodeBC6H(sequence, width, height);
                colorType = SKColorType.Rgb888x;
                break;

            case EPixelFormat.PF_ETC1:
                data = Detex.DecodeDetexLinear(sequence, width, height, isFloat: false,
                                               inputFormat: DetexTextureFormat.DETEX_TEXTURE_FORMAT_ETC1,
                                               outputPixelFormat: DetexPixelFormat.DETEX_PIXEL_FORMAT_RGBA8);
                colorType = SKColorType.Rgba8888;
                break;

            case EPixelFormat.PF_ETC2_RGB:
                data = Detex.DecodeDetexLinear(sequence, width, height, isFloat: false,
                                               inputFormat: DetexTextureFormat.DETEX_TEXTURE_FORMAT_ETC2,
                                               outputPixelFormat: DetexPixelFormat.DETEX_PIXEL_FORMAT_RGBA8);
                colorType = SKColorType.Rgba8888;
                break;

            case EPixelFormat.PF_ETC2_RGBA:
                data = Detex.DecodeDetexLinear(sequence, width, height, isFloat: false,
                                               inputFormat: DetexTextureFormat.DETEX_TEXTURE_FORMAT_ETC2_EAC,
                                               outputPixelFormat: DetexPixelFormat.DETEX_PIXEL_FORMAT_RGBA8);
                colorType = SKColorType.Rgba8888;
                break;

            default:
                throw new NotImplementedException($"Cannot decode {format} format");
            }

            using var bitmap = new SKBitmap(new SKImageInfo(width, height, colorType, SKAlphaType.Unpremul));
            unsafe
            {
                fixed(byte *p = data)
                {
                    bitmap.SetPixels(new IntPtr(p));
                }
            }
            return(SKImage.FromBitmap(bitmap));
        }
예제 #7
0
        public static void DecodeTexture(FTexture2DMipMap mip, EPixelFormat format, bool isNormalMap, out byte[] data, out SKColorType colorType)
        {
            switch (format)
            {
            case EPixelFormat.PF_DXT1:
                data      = DXTDecoder.DXT1(mip.Data.Data, mip.SizeX, mip.SizeY, mip.SizeZ);
                colorType = SKColorType.Rgba8888;
                break;

            case EPixelFormat.PF_DXT5:
                data      = DXTDecoder.DXT5(mip.Data.Data, mip.SizeX, mip.SizeY, mip.SizeZ);
                colorType = SKColorType.Rgba8888;
                break;

            case EPixelFormat.PF_ASTC_4x4:
            case EPixelFormat.PF_ASTC_6x6:
            case EPixelFormat.PF_ASTC_8x8:
            case EPixelFormat.PF_ASTC_10x10:
            case EPixelFormat.PF_ASTC_12x12:
                data = ASTCDecoder.RGBA8888(
                    mip.Data.Data,
                    FormatHelper.GetBlockWidth(format),
                    FormatHelper.GetBlockHeight(format),
                    FormatHelper.GetBlockDepth(format),
                    mip.SizeX, mip.SizeY, mip.SizeZ);
                colorType = SKColorType.Rgba8888;

                if (isNormalMap)
                {
                    // UE4 drops blue channel for normal maps before encoding, restore it
                    unsafe
                    {
                        var offset = 0;
                        fixed(byte *d = data)
                        {
                            for (var i = 0; i < mip.SizeX * mip.SizeY; i++)
                            {
                                d[offset + 2] = BCDecoder.GetZNormal(d[offset], d[offset + 1]);
                                offset       += 4;
                            }
                        }
                    }
                }

                break;

            case EPixelFormat.PF_BC4:
                data      = BCDecoder.BC4(mip.Data.Data, mip.SizeX, mip.SizeY);
                colorType = SKColorType.Rgb888x;
                break;

            case EPixelFormat.PF_BC5:
                data      = BCDecoder.BC5(mip.Data.Data, mip.SizeX, mip.SizeY);
                colorType = SKColorType.Rgb888x;
                break;

            case EPixelFormat.PF_BC6H:
                // BC6H doesn't work no matter the pixel format, the closest we can get is either
                // Rgb565 DETEX_PIXEL_FORMAT_FLOAT_RGBX16 or Rgb565 DETEX_PIXEL_FORMAT_FLOAT_BGRX16

                data = Detex.DecodeDetexLinear(mip.Data.Data, mip.SizeX, mip.SizeY, true,
                                               DetexTextureFormat.DETEX_TEXTURE_FORMAT_BPTC_FLOAT,
                                               DetexPixelFormat.DETEX_PIXEL_FORMAT_FLOAT_RGBX16);
                colorType = SKColorType.Rgb565;
                break;

            case EPixelFormat.PF_BC7:
                data = Detex.DecodeDetexLinear(mip.Data.Data, mip.SizeX, mip.SizeY, false,
                                               DetexTextureFormat.DETEX_TEXTURE_FORMAT_BPTC,
                                               DetexPixelFormat.DETEX_PIXEL_FORMAT_RGBA8);
                colorType = SKColorType.Rgba8888;
                break;

            case EPixelFormat.PF_ETC1:
                data = Detex.DecodeDetexLinear(mip.Data.Data, mip.SizeX, mip.SizeY, false,
                                               DetexTextureFormat.DETEX_TEXTURE_FORMAT_ETC1,
                                               DetexPixelFormat.DETEX_PIXEL_FORMAT_RGBA8);
                colorType = SKColorType.Rgba8888;
                break;

            case EPixelFormat.PF_ETC2_RGB:
                data = Detex.DecodeDetexLinear(mip.Data.Data, mip.SizeX, mip.SizeY, false,
                                               DetexTextureFormat.DETEX_TEXTURE_FORMAT_ETC2,
                                               DetexPixelFormat.DETEX_PIXEL_FORMAT_RGBA8);
                colorType = SKColorType.Rgba8888;
                break;

            case EPixelFormat.PF_ETC2_RGBA:
                data = Detex.DecodeDetexLinear(mip.Data.Data, mip.SizeX, mip.SizeY, false,
                                               DetexTextureFormat.DETEX_TEXTURE_FORMAT_ETC2_EAC,
                                               DetexPixelFormat.DETEX_PIXEL_FORMAT_RGBA8);
                colorType = SKColorType.Rgba8888;
                break;

            case EPixelFormat.PF_R16F:
            case EPixelFormat.PF_R16F_FILTER:
                unsafe
                {
                    fixed(byte *d = mip.Data.Data)
                    {
                        data = ConvertRawR16DataToRGB888X(mip.SizeX, mip.SizeY, d, mip.SizeX * 2);     // 2 BPP
                    }
                }

                colorType = SKColorType.Rgb888x;
                break;

            case EPixelFormat.PF_B8G8R8A8:
                data      = mip.Data.Data;
                colorType = SKColorType.Bgra8888;
                break;

            case EPixelFormat.PF_G8:
                data      = mip.Data.Data;
                colorType = SKColorType.Gray8;
                break;

            case EPixelFormat.PF_FloatRGBA:
                unsafe
                {
                    fixed(byte *d = mip.Data.Data)
                    {
                        data = ConvertRawR16G16B16A16FDataToRGBA8888(mip.SizeX, mip.SizeY, d, mip.SizeX * 8, false);     // 8 BPP
                    }
                }

                colorType = SKColorType.Rgba8888;
                break;

            default: throw new NotImplementedException($"Unknown pixel format: {format}");
            }
        }
예제 #8
0
        /// <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, byte[] paletteData, ImageParameters parameters, PALETTE_FORMAT PaletteFormat = PALETTE_FORMAT.None, 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}!");
            }

            byte[] imageData  = new byte[0];
            bool   DontSwapRG = false;

            if (PlatformSwizzle == PlatformSwizzle.Platform_3DS)
            {
                imageData  = CTR_3DS.DecodeBlock(data, (int)Width, (int)Height, Format);
                DontSwapRG = true;
            }
            else if (PlatformSwizzle == PlatformSwizzle.Platform_Gamecube)
            {
                imageData = Decode_Gamecube.DecodeData(data, paletteData, Width, Height, Format, PaletteFormat);
            }
            else
            {
                if (Format == TEX_FORMAT.R32G8X24_FLOAT)
                {
                    imageData = DDSCompressor.DecodePixelBlock(data, (int)Width, (int)Height, DDS.DXGI_FORMAT.DXGI_FORMAT_R32G8X24_TYPELESS);
                }

                if (Format == TEX_FORMAT.BC5_SNORM)
                {
                    imageData = DDSCompressor.DecompressBC5(data, (int)Width, (int)Height, true, true);
                }

                if (Format == TEX_FORMAT.L8)
                {
                    return(RGBAPixelDecoder.Decode(data, (int)Width, (int)Height, Format));
                }
                if (Format == TEX_FORMAT.LA8)
                {
                    return(RGBAPixelDecoder.Decode(data, (int)Width, (int)Height, Format));
                }
                if (Format == TEX_FORMAT.R5G5B5A1_UNORM)
                {
                    return(RGBAPixelDecoder.Decode(data, (int)Width, (int)Height, Format));
                }

                if (IsCompressed(Format))
                {
                    imageData = DDSCompressor.DecompressBlock(data, (int)Width, (int)Height, (DDS.DXGI_FORMAT)Format);
                }
                else
                {
                    if (IsAtscFormat(Format))
                    {
                        imageData = ASTCDecoder.DecodeToRGBA8888(data, (int)GetBlockWidth(Format), (int)GetBlockHeight(Format), 1, (int)Width, (int)Height, 1);
                    }
                    else
                    {
                        imageData = DDSCompressor.DecodePixelBlock(data, (int)Width, (int)Height, (DDS.DXGI_FORMAT)Format);
                    }

                    //    imageData = RGBAPixelDecoder.Decode(data, (int)Width, (int)Height, Format);
                }
            }

            if (parameters.DontSwapRG || DontSwapRG)
            {
                return(imageData);
            }
            else
            {
                return(ConvertBgraToRgba(imageData));
            }
        }
예제 #9
0
        private static void DecodeTexture(FTexture2DMipMap mip, EPixelFormat format, out byte[] data, out SKColorType colorType)
        {
            switch (format)
            {
            case EPixelFormat.PF_DXT1:
                data      = DXTDecoder.DXT1(mip.Data.Data, mip.SizeX, mip.SizeY, mip.SizeZ);
                colorType = SKColorType.Rgba8888;
                break;

            case EPixelFormat.PF_DXT5:
                data      = DXTDecoder.DXT5(mip.Data.Data, mip.SizeX, mip.SizeY, mip.SizeZ);
                colorType = SKColorType.Rgba8888;
                break;

            case EPixelFormat.PF_ASTC_8x8:
                data = ASTCDecoder.RGBA8888(
                    mip.Data.Data,
                    FormatHelper.GetBlockWidth(format),
                    FormatHelper.GetBlockHeight(format),
                    FormatHelper.GetBlockDepth(format),
                    mip.SizeX, mip.SizeY, mip.SizeZ);
                colorType = SKColorType.Rgba8888;
                break;

            case EPixelFormat.PF_BC4:
                data      = BCDecoder.BC4(mip.Data.Data, mip.SizeX, mip.SizeY);
                colorType = SKColorType.Rgb888x;
                break;

            case EPixelFormat.PF_BC5:
                data      = BCDecoder.BC5(mip.Data.Data, mip.SizeX, mip.SizeY);
                colorType = SKColorType.Rgb888x;
                break;

            case EPixelFormat.PF_BC6H:
                // BC6H doesn't work no matter the pixel format, the closest we can get is either
                // Rgb565 DETEX_PIXEL_FORMAT_FLOAT_RGBX16 or Rgb565 DETEX_PIXEL_FORMAT_FLOAT_BGRX16

                data = Detex.DecodeDetexLinear(mip.Data.Data, mip.SizeX, mip.SizeY, true,
                                               inputFormat: DetexTextureFormat.DETEX_TEXTURE_FORMAT_BPTC_FLOAT,
                                               outputPixelFormat: DetexPixelFormat.DETEX_PIXEL_FORMAT_FLOAT_RGBX16);
                colorType = SKColorType.Rgb565;
                break;

            case EPixelFormat.PF_BC7:
                data = Detex.DecodeDetexLinear(mip.Data.Data, mip.SizeX, mip.SizeY, false,
                                               inputFormat: DetexTextureFormat.DETEX_TEXTURE_FORMAT_BPTC,
                                               outputPixelFormat: DetexPixelFormat.DETEX_PIXEL_FORMAT_RGBA8);
                colorType = SKColorType.Rgb888x;
                break;

            case EPixelFormat.PF_ETC1:
                data = Detex.DecodeDetexLinear(mip.Data.Data, mip.SizeX, mip.SizeY, false,
                                               inputFormat: DetexTextureFormat.DETEX_TEXTURE_FORMAT_ETC1,
                                               outputPixelFormat: DetexPixelFormat.DETEX_PIXEL_FORMAT_RGBA8);
                colorType = SKColorType.Rgba8888;
                break;

            case EPixelFormat.PF_ETC2_RGB:
                data = Detex.DecodeDetexLinear(mip.Data.Data, mip.SizeX, mip.SizeY, false,
                                               inputFormat: DetexTextureFormat.DETEX_TEXTURE_FORMAT_ETC2,
                                               outputPixelFormat: DetexPixelFormat.DETEX_PIXEL_FORMAT_RGBA8);
                colorType = SKColorType.Rgba8888;
                break;

            case EPixelFormat.PF_ETC2_RGBA:
                data = Detex.DecodeDetexLinear(mip.Data.Data, mip.SizeX, mip.SizeY, false,
                                               inputFormat: DetexTextureFormat.DETEX_TEXTURE_FORMAT_ETC2_EAC,
                                               outputPixelFormat: DetexPixelFormat.DETEX_PIXEL_FORMAT_RGBA8);
                colorType = SKColorType.Rgba8888;
                break;

            case EPixelFormat.PF_B8G8R8A8:
                data      = mip.Data.Data;
                colorType = SKColorType.Bgra8888;
                break;

            case EPixelFormat.PF_G8:
                data      = mip.Data.Data;
                colorType = SKColorType.Gray8;
                break;

            case EPixelFormat.PF_FloatRGBA:
                data      = mip.Data.Data;
                colorType = SKColorType.RgbaF16;
                break;

            default: throw new NotImplementedException($"Unknown pixel format: {format}");
            }
        }
예제 #10
0
        public static SKImage DecodeImage(byte[] sequence, int width, int height, int depth, EPixelFormat format)
        {
            byte[]      data;
            SKColorType colorType;

            switch (format)
            {
            case EPixelFormat.PF_DXT5:
                data      = DXTDecoder.DecodeDXT5(sequence, width, height, depth);
                colorType = SKColorType.Rgba8888;
                break;

            case EPixelFormat.PF_DXT1:
                data      = DXTDecoder.DecodeDXT1(sequence, width, height, depth);
                colorType = SKColorType.Rgba8888;
                break;

            case EPixelFormat.PF_ASTC_8x8:
                var x = (int)TextureFormatHelper.GetBlockWidth(format);
                var y = (int)TextureFormatHelper.GetBlockHeight(format);
                var z = (int)TextureFormatHelper.GetBlockDepth(format);
                data      = ASTCDecoder.DecodeToRGBA8888(sequence, x, y, z, width, height, 1);
                colorType = SKColorType.Rgba8888;
                break;

            case EPixelFormat.PF_B8G8R8A8:
                data      = sequence;
                colorType = SKColorType.Bgra8888;
                break;

            case EPixelFormat.PF_BC5:
                data      = BCDecoder.DecodeBC5(sequence, width, height);
                colorType = SKColorType.Bgra8888;
                break;

            case EPixelFormat.PF_BC4:
                data      = BCDecoder.DecodeBC4(sequence, width, height);
                colorType = SKColorType.Bgra8888;
                break;

            case EPixelFormat.PF_G8:
                data      = sequence;
                colorType = SKColorType.Gray8;
                break;

            case EPixelFormat.PF_FloatRGBA:
                data      = sequence;
                colorType = SKColorType.RgbaF16;
                break;

            default:
                throw new NotImplementedException($"Cannot decode {format} format");
            }

            using var bitmap = new SKBitmap(new SKImageInfo(width, height, colorType, SKAlphaType.Unpremul));
            unsafe
            {
                fixed(byte *p = data)
                {
                    bitmap.SetPixels(new IntPtr(p));
                }
            }
            return(SKImage.FromBitmap(bitmap));
        }