示例#1
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_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));
            }
        }
示例#2
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));
        }
示例#3
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}");
            }
        }
示例#4
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}");
            }
        }
示例#5
0
        public static void DecodeTexturePlaystation(FTexture2DMipMap mip, EPixelFormat format, bool isNormalMap, out byte[] data, out SKColorType colorType)
        {
            switch (format)
            {
            case EPixelFormat.PF_DXT5:
            {
                var uBlockSize  = mip.SizeX / 4;
                var vBlockSize  = mip.SizeY / 4;
                var totalBlocks = mip.Data.Data.Length / 16;

                if (uBlockSize * vBlockSize > totalBlocks)
                {
                    throw new ParserException($"Texture unable to be untiled: {format}");
                }

                var d = PlatformDeswizzlers.DeswizzlePS4(mip.Data.Data, mip.SizeX, mip.SizeY, 4, 4, 16);
                data      = DXTDecoder.DXT5(d, mip.SizeX, mip.SizeY, mip.SizeZ);
                colorType = SKColorType.Rgba8888;
                break;
            }

            case EPixelFormat.PF_DXT1:
            {
                var uBlockSize  = mip.SizeX / 4;
                var vBlockSize  = mip.SizeY / 4;
                var totalBlocks = mip.Data.Data.Length / 8;

                if (uBlockSize * vBlockSize > totalBlocks)
                {
                    throw new ParserException($"Texture unable to be untiled: {format}");
                }

                var d = PlatformDeswizzlers.DeswizzlePS4(mip.Data.Data, mip.SizeX, mip.SizeY, 4, 4, 8);
                data      = DXTDecoder.DXT1(d, mip.SizeX, mip.SizeY, mip.SizeZ);
                colorType = SKColorType.Rgba8888;
                break;
            }

            case EPixelFormat.PF_B8G8R8A8:
            {
                var uBlockSize  = mip.SizeX / 4;
                var vBlockSize  = mip.SizeY / 4;
                var totalBlocks = mip.Data.Data.Length / 4;

                if (uBlockSize * vBlockSize > totalBlocks)
                {
                    throw new ParserException($"Texture unable to be untiled: {format}");
                }

                data      = PlatformDeswizzlers.DeswizzlePS4(mip.Data.Data, mip.SizeX, mip.SizeY, 1, 1, 4);
                colorType = SKColorType.Bgra8888;
                break;
            }

            case EPixelFormat.PF_G8:
            {
                var uBlockSize  = mip.SizeX / 4;
                var vBlockSize  = mip.SizeY / 4;
                var totalBlocks = mip.Data.Data.Length / 1;

                if (uBlockSize * vBlockSize > totalBlocks)
                {
                    throw new ParserException($"Texture unable to be untiled: {format}");
                }

                data      = PlatformDeswizzlers.DeswizzlePS4(mip.Data.Data, mip.SizeX, mip.SizeY, 1, 1, 1);
                colorType = SKColorType.Gray8;
                break;
            }

            case EPixelFormat.PF_BC5:
            {
                var uBlockSize  = mip.SizeX / 4;
                var vBlockSize  = mip.SizeY / 4;
                var totalBlocks = mip.Data.Data.Length / 16;

                if (uBlockSize * vBlockSize > totalBlocks)
                {
                    throw new ParserException($"Texture unable to be untiled: {format}");
                }

                var d = PlatformDeswizzlers.DeswizzlePS4(mip.Data.Data, mip.SizeX, mip.SizeY, 4, 4, 16);
                data      = BCDecoder.BC5(d, mip.SizeX, mip.SizeY);
                colorType = SKColorType.Rgb888x;
                break;
            }

            case EPixelFormat.PF_BC4:
            {
                var uBlockSize  = mip.SizeX / 4;
                var vBlockSize  = mip.SizeY / 4;
                var totalBlocks = mip.Data.Data.Length / 8;

                if (uBlockSize * vBlockSize > totalBlocks)
                {
                    throw new ParserException($"Texture unable to be untiled: {format}");
                }

                var d = PlatformDeswizzlers.DeswizzlePS4(mip.Data.Data, mip.SizeX, mip.SizeY, 4, 4, 8);
                data      = BCDecoder.BC4(d, mip.SizeX, mip.SizeY);
                colorType = SKColorType.Rgb888x;
                break;
            }

            default:
            {
                TextureDecoder.DecodeTexture(mip, format, isNormalMap, out data, out colorType);
                break;
            }
            }
        }