Пример #1
0
        /// <summary>
        /// decode to image as an asynchronous operation.
        /// </summary>
        /// <param name="file">The file.</param>
        /// <returns>Image&lt;Rgba32&gt;[].</returns>
        public async Task <Image <Rgba32> > DecodeToImageAsync(DdsFile file)
        {
            Image <Rgba32> image   = null;
            var            decoder = new BcDecoder();

            if (file.Faces.Count == 6)
            {
                // Cubemap
                var right  = ColorMemoryToImage(await decoder.DecodeRaw2DAsync(file.Faces[0].MipMaps[0].Data, Convert.ToInt32(file.Faces[0].Width), Convert.ToInt32(file.Faces[0].Height), GetCompressionFormat(file, decoder.InputOptions)));
                var left   = ColorMemoryToImage(await decoder.DecodeRaw2DAsync(file.Faces[1].MipMaps[0].Data, Convert.ToInt32(file.Faces[1].Width), Convert.ToInt32(file.Faces[1].Height), GetCompressionFormat(file, decoder.InputOptions)));
                var top    = ColorMemoryToImage(await decoder.DecodeRaw2DAsync(file.Faces[2].MipMaps[0].Data, Convert.ToInt32(file.Faces[2].Width), Convert.ToInt32(file.Faces[2].Height), GetCompressionFormat(file, decoder.InputOptions)));
                var bottom = ColorMemoryToImage(await decoder.DecodeRaw2DAsync(file.Faces[3].MipMaps[0].Data, Convert.ToInt32(file.Faces[3].Width), Convert.ToInt32(file.Faces[3].Height), GetCompressionFormat(file, decoder.InputOptions)));
                var front  = ColorMemoryToImage(await decoder.DecodeRaw2DAsync(file.Faces[4].MipMaps[0].Data, Convert.ToInt32(file.Faces[4].Width), Convert.ToInt32(file.Faces[4].Height), GetCompressionFormat(file, decoder.InputOptions)));
                var back   = ColorMemoryToImage(await decoder.DecodeRaw2DAsync(file.Faces[5].MipMaps[0].Data, Convert.ToInt32(file.Faces[5].Width), Convert.ToInt32(file.Faces[5].Height), GetCompressionFormat(file, decoder.InputOptions)));
                var width  = left.Width + front.Width + right.Width + back.Width;
                var height = top.Height + front.Height + bottom.Height;
                image = new Image <Rgba32>(width, height);
                image.Mutate(i =>
                {
                    i.DrawImage(top, new Point(left.Width, 0), 1f);
                    i.DrawImage(left, new Point(0, top.Height), 1f);
                    i.DrawImage(front, new Point(left.Width, top.Height), 1f);
                    i.DrawImage(right, new Point(left.Width + front.Width, top.Height), 1f);
                    i.DrawImage(back, new Point(left.Width + front.Width + right.Width, top.Height), 1f);
                    i.DrawImage(bottom, new Point(left.Width, top.Height + front.Height), 1f);
                });
            }
            else
            {
                var bcnImage = await decoder.Decode2DAsync(file);

                image = ColorMemoryToImage(bcnImage);
            }
            return(image);
        }
Пример #2
0
        public void GetPreview()
        {
            var ddsReadSuccess = false;

            try
            {
                Preview = null;
                BCnEncoder.Shared.ImageFiles.DdsFile bcDds;
                using (var ms = new MemoryStream())
                {
                    var dds = Texture.ToDdsFile(false);
                    dds.Write(ms, -1);
                    ddsReadSuccess = true;

                    ms.Seek(0, SeekOrigin.Begin);
                    bcDds = BCnEncoder.Shared.ImageFiles.DdsFile.Load(ms);
                }

                var width   = (int)bcDds.header.dwWidth;
                var height  = (int)bcDds.header.dwHeight;
                var decoder = new BcDecoder();
                if (decoder.IsHdrFormat(bcDds))
                {
                    var pixels     = new byte[width * height * 3];
                    var pixelsSpan = MemoryMarshal.Cast <byte, Bgr24>(pixels);
                    decoder.DecodeDdsToPixels(bcDds, pixelsSpan);
                    var bmSource = BitmapSource.Create(width, height, 96.0, 96.0, PixelFormats.Bgr24, null, pixels, width * 3);
                    Preview = bmSource;
                }
                else
                {
                    var pixels     = new byte[width * height * 4];
                    var pixelsSpan = MemoryMarshal.Cast <byte, Bgra32>(pixels);
                    decoder.DecodeDdsToPixels(bcDds, pixelsSpan);
                    var bmSource = BitmapSource.Create(width, height, 96.0, 96.0, PixelFormats.Bgra32, null, pixels, width * 4);
                    Preview = bmSource;
                }

                PreviewErrorVisibility = Visibility.Collapsed;
                OnPropertyChanged(nameof(Width));
                OnPropertyChanged(nameof(Height));
                OnPropertyChanged(nameof(TextureInfo));
            }
            catch (Exception ex)
            {
                Preview = null;
                if (ddsReadSuccess)
                {
                    PreviewError = "Could not create preview! Export/Import may still work." + Environment.NewLine + Environment.NewLine + ex.Message;
                }
                else
                {
                    PreviewError = "Could not create preview! Failed to convert pssg texture to dds." + Environment.NewLine + Environment.NewLine + ex.Message;
                }
                PreviewErrorVisibility = Visibility.Visible;
            }
        }
        public void GetPreview()
        {
            Image <Rgba32> image          = null;
            bool           ddsReadSuccess = false;

            try
            {
                Preview = null;

                // Write and decode dds
                using (var ms = new MemoryStream())
                {
                    var dds = Texture.ToDdsFile(false);
                    dds.Write(ms, -1);
                    ddsReadSuccess = true;
                    ms.Seek(0, SeekOrigin.Begin);

                    var decoder = new BcDecoder();
                    image = decoder.DecodeToImageRgba32(ms);
                }

                // Copy pixels to WPF format
                var pixels     = new byte[image.Width * image.Height * 4];
                var pixelsSpan = MemoryMarshal.Cast <byte, Bgra32>(pixels);
                for (int r = 0; r < image.Height; ++r)
                {
                    var destRow = pixelsSpan.Slice(r * image.Width, image.Width);
                    var sorcRow = image.GetPixelRowSpan(r);
                    PixelOperations <Rgba32> .Instance.ToBgra32(Configuration.Default, sorcRow, destRow);
                }
                var bmSource = BitmapSource.Create(image.Width, image.Height, 96.0, 96.0, PixelFormats.Bgra32, null, pixels, image.Width * 4);
                this.Preview = bmSource;

                this.PreviewErrorVisibility = Visibility.Collapsed;
                OnPropertyChanged(nameof(Width));
                OnPropertyChanged(nameof(Height));
                OnPropertyChanged(nameof(TextureInfo));
            }
            catch (Exception ex)
            {
                Preview = null;
                if (ddsReadSuccess)
                {
                    this.PreviewError = "Could not create preview! Export/Import may still work." + Environment.NewLine + Environment.NewLine + ex.Message;
                }
                else
                {
                    this.PreviewError = "Could not create preview! Failed to convert pssg texture to dds." + Environment.NewLine + Environment.NewLine + ex.Message;
                }
                this.PreviewErrorVisibility = Visibility.Visible;
            }
            finally
            {
                image?.Dispose();
            }
        }
Пример #4
0
        public static float DecodeCheckPSNR(string filename, Image <Rgba32> original)
        {
            using FileStream fs = File.OpenRead(filename);
            var ktx     = KtxFile.Load(fs);
            var decoder = new BcDecoder();

            using var img = decoder.Decode(ktx);
            var pixels  = original.GetPixelSpan();
            var pixels2 = img.GetPixelSpan();

            return(ImageQuality.PeakSignalToNoiseRatio(pixels, pixels2, true));
        }
Пример #5
0
        public void ReadBc7()
        {
            using FileStream fs = File.OpenRead(@"../../../testImages/test_decompress_bc7.dds");
            BcDecoder decoder = new BcDecoder();
            var       images  = decoder.DecodeAllMipMaps(fs);

            for (int i = 0; i < images.Length; i++)
            {
                using FileStream outFs = File.OpenWrite($"decoding_test_dds_bc7_mip{i}.png");
                images[i].SaveAsPng(outFs);
                images[i].Dispose();
            }
        }
Пример #6
0
        public void Bc4Decode()
        {
            using FileStream fs = File.OpenRead(@"../../../testImages/test_decompress_bc4_unorm.ktx");
            KtxFile file = KtxFile.Load(fs);

            Assert.True(file.Header.VerifyHeader());
            Assert.Equal((uint)1, file.Header.NumberOfFaces);

            BcDecoder decoder = new BcDecoder();

            using var image = decoder.Decode(file);

            Assert.Equal((uint)image.Width, file.Header.PixelWidth);
            Assert.Equal((uint)image.Height, file.Header.PixelHeight);

            using FileStream outFs = File.OpenWrite("decoding_test_bc4.png");
            image.SaveAsPng(outFs);
        }
Пример #7
0
        public void ReadRgba()
        {
            using FileStream fs = File.OpenRead(@"../../../testImages/test_decompress_rgba.dds");
            DdsFile file = DdsFile.Load(fs);

            Assert.Equal(DXGI_FORMAT.DXGI_FORMAT_R8G8B8A8_UNORM, file.Header.ddsPixelFormat.DxgiFormat);
            Assert.Equal(file.Header.dwMipMapCount, (uint)file.Faces[0].MipMaps.Length);

            BcDecoder decoder = new BcDecoder();
            var       images  = decoder.DecodeAllMipMaps(file);

            Assert.Equal((uint)images[0].Width, file.Header.dwWidth);
            Assert.Equal((uint)images[0].Height, file.Header.dwHeight);

            for (int i = 0; i < images.Length; i++)
            {
                using FileStream outFs = File.OpenWrite($"decoding_test_dds_rgba_mip{i}.png");
                images[i].SaveAsPng(outFs);
                images[i].Dispose();
            }
        }
Пример #8
0
        private BcDecoder GetDecoder()
        {
            var decoder = new BcDecoder();

            switch (_format)
            {
            case BcFormat.Ati1A:
                decoder.OutputOptions.Bc4Component = ColorComponent.A;
                break;

            case BcFormat.Ati1L:
                decoder.OutputOptions.Bc4Component = ColorComponent.Luminance;
                break;

            case BcFormat.Ati2AL:
                decoder.OutputOptions.Bc5Component1 = ColorComponent.Luminance;
                decoder.OutputOptions.Bc5Component2 = ColorComponent.A;
                break;
            }

            return(decoder);
        }
Пример #9
0
        public void ReadBc1a()
        {
            using FileStream fs = File.OpenRead(@"../../../testImages/test_decompress_bc1a.dds");
            DdsFile file = DdsFile.Load(fs);

            Assert.Equal(DXGI_FORMAT.DXGI_FORMAT_BC1_UNORM, file.Header.ddsPixelFormat.DxgiFormat);
            Assert.Equal(file.Header.dwMipMapCount, (uint)file.Faces[0].MipMaps.Length);


            BcDecoder decoder = new BcDecoder();

            decoder.InputOptions.ddsBc1ExpectAlpha = true;
            var image = decoder.Decode(file);

            Assert.Equal((uint)image.Width, file.Header.dwWidth);
            Assert.Equal((uint)image.Height, file.Header.dwHeight);

            Assert.Contains(image.GetPixelSpan().ToArray(), x => x.A == 0);

            using FileStream outFs = File.OpenWrite($"decoding_test_dds_bc1a.png");
            image.SaveAsPng(outFs);
            image.Dispose();
        }
Пример #10
0
        public static void DecodeDdsToPixels <TPixel>(this BcDecoder decoder, DdsFile dds, Span <TPixel> pixels)
            where TPixel : unmanaged, IPixel <TPixel>
        {
            var width  = (int)dds.header.dwWidth;
            var height = (int)dds.header.dwHeight;

            if (decoder.IsHdrFormat(dds))
            {
                var source = decoder.DecodeHdr(dds).AsSpan();
                for (var r = 0; r < height; ++r)
                {
                    var start   = r * width;
                    var destRow = pixels.Slice(start, width);
                    var sorcRow = source.Slice(start, width);
                    for (var c = 0; c < destRow.Length; ++c)
                    {
                        ref var destPixel = ref destRow[c];
                        ref var sorcPixel = ref sorcRow[c];

                        var rgbVal = sorcPixel.ToVector3();
                        destPixel.FromScaledVector4(new Vector4(rgbVal, 1));
                    }
                }
Пример #11
0
        /// <summary>
        /// decode to image as an asynchronous operation.
        /// </summary>
        /// <param name="file">The file.</param>
        /// <returns>Image&lt;Rgba32&gt;[].</returns>
        public async Task <Image> DecodeToImageAsync(DdsFile file)
        {
            var            decoder = new BcDecoder();
            Image <Rgba32> image;

            if (file.Faces.Count == 6)
            {
                // Cubemap
                var right  = ColorMemoryToImage(await decoder.DecodeRaw2DAsync(file.Faces[0].MipMaps[0].Data, Convert.ToInt32(file.Faces[0].Width), Convert.ToInt32(file.Faces[0].Height), GetCompressionFormat(file, decoder.InputOptions)));
                var left   = ColorMemoryToImage(await decoder.DecodeRaw2DAsync(file.Faces[1].MipMaps[0].Data, Convert.ToInt32(file.Faces[1].Width), Convert.ToInt32(file.Faces[1].Height), GetCompressionFormat(file, decoder.InputOptions)));
                var top    = ColorMemoryToImage(await decoder.DecodeRaw2DAsync(file.Faces[2].MipMaps[0].Data, Convert.ToInt32(file.Faces[2].Width), Convert.ToInt32(file.Faces[2].Height), GetCompressionFormat(file, decoder.InputOptions)));
                var bottom = ColorMemoryToImage(await decoder.DecodeRaw2DAsync(file.Faces[3].MipMaps[0].Data, Convert.ToInt32(file.Faces[3].Width), Convert.ToInt32(file.Faces[3].Height), GetCompressionFormat(file, decoder.InputOptions)));
                var front  = ColorMemoryToImage(await decoder.DecodeRaw2DAsync(file.Faces[4].MipMaps[0].Data, Convert.ToInt32(file.Faces[4].Width), Convert.ToInt32(file.Faces[4].Height), GetCompressionFormat(file, decoder.InputOptions)));
                var back   = ColorMemoryToImage(await decoder.DecodeRaw2DAsync(file.Faces[5].MipMaps[0].Data, Convert.ToInt32(file.Faces[5].Width), Convert.ToInt32(file.Faces[5].Height), GetCompressionFormat(file, decoder.InputOptions)));
                return(GetCubeMap(right, left, top, bottom, front, back));
            }
            else
            {
                var bcnImage = await decoder.Decode2DAsync(file);

                image = ColorMemoryToImage(bcnImage);
            }
            return(image);
        }
Пример #12
0
                static async Task <MemoryStream> getDDS(Stream stream)
                {
                    if (stream.CanSeek)
                    {
                        stream.Seek(0, SeekOrigin.Begin);
                    }
                    var          exceptions = new List <Exception>();
                    MemoryStream ms         = null;

                    try
                    {
                        ms = new MemoryStream();
                        var file    = DdsFile.Load(stream);
                        var decoder = new BcDecoder();
                        var image   = decoder.Decode(file);
                        await image.SaveAsPngAsync(ms);
                    }
                    catch (Exception ex)
                    {
                        if (ms != null)
                        {
                            ms.Close();
                            await ms.DisposeAsync();
                        }
                        ms = null;
                        exceptions.Add(ex);
                    }
                    // fallback
                    if (ms == null)
                    {
                        if (stream.CanSeek)
                        {
                            stream.Seek(0, SeekOrigin.Begin);
                        }
                        try
                        {
                            using var pfimImage = Dds.Create(stream, new PfimConfig());
                            if (pfimImage.Compressed)
                            {
                                pfimImage.Decompress();
                            }
                            if (pfimImage.Format == ImageFormat.Rgba32)
                            {
                                ms = new MemoryStream();
                                using var image = Image.LoadPixelData <Bgra32>(tightData(pfimImage), pfimImage.Width, pfimImage.Height);
                                await image.SaveAsPngAsync(ms);
                            }
                            else if (pfimImage.Format == ImageFormat.Rgb24)
                            {
                                ms = new MemoryStream();
                                using var image = Image.LoadPixelData <Bgr24>(tightData(pfimImage), pfimImage.Width, pfimImage.Height);
                                await image.SaveAsPngAsync(ms);
                            }
                        }
                        catch (Exception ex)
                        {
                            if (ms != null)
                            {
                                ms.Close();
                                await ms.DisposeAsync();
                            }
                            ms = null;
                            exceptions.Add(ex);
                        }
                    }
                    // Fallback can result in memory stream being empty so throw aggregate exception only if both attempts failed
                    if (ms == null && exceptions.Count == 2)
                    {
                        throw new AggregateException(exceptions);
                    }
                    return(ms);
                }