コード例 #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);
            }
        }
コード例 #2
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, 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
ファイル: OGLTexture.cs プロジェクト: FearlessTobi/Ryujinx
        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
        /// <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));
            }
        }
コード例 #8
0
ファイル: TextureDecoder.cs プロジェクト: fangguanya/FModel
        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));
        }