Example #1
0
        public WicImageFrame(WicImageContainer decoder, uint index)
        {
            if (index >= (uint)decoder.FrameCount)
            {
                throw new IndexOutOfRangeException("Frame index does not exist");
            }

            WicFrame  = comHandles.AddRef(decoder.WicDecoder.GetFrame(index));
            WicSource = WicFrame;
            WicFrame.GetSize(out uint frameWidth, out uint frameHeight);
            container = decoder;

            if (decoder.IsRawContainer && index == 0 && decoder.WicDecoder.TryGetPreview(out var preview))
            {
                using var pvwSource = new ComHandle <IWICBitmapSource>(preview);
                preview.GetSize(out uint pw, out uint ph);

                if (pw == frameWidth && ph == frameHeight)
                {
                    WicSource = comHandles.AddOwnRef(preview);
                }
            }

            WicFrame.GetResolution(out double dpix, out double dpiy);
            DpiX = dpix;
            DpiY = dpiy;

            if (PixelFormat.FromGuid(WicSource.GetPixelFormat()).NumericRepresentation == PixelNumericRepresentation.Indexed)
            {
                var pal = comHandles.AddRef(Wic.Factory.CreatePalette());
                WicSource.CopyPalette(pal);

                var newFormat = Consts.GUID_WICPixelFormat24bppBGR;
                if (pal.HasAlpha())
                {
                    newFormat = Consts.GUID_WICPixelFormat32bppBGRA;
                }
                else if (pal.IsGrayscale() || pal.IsBlackWhite())
                {
                    newFormat = Consts.GUID_WICPixelFormat8bppGray;
                }

                var conv = comHandles.AddRef(Wic.Factory.CreateFormatConverter());
                conv.Initialize(WicSource, newFormat, WICBitmapDitherType.WICBitmapDitherTypeNone, null, 0.0, WICBitmapPaletteType.WICBitmapPaletteTypeCustom);
                WicSource = conv;
            }

            if (WicSource is IWICBitmapSourceTransform trans)
            {
                uint pw = 1, ph = 1;
                trans.GetClosestSize(ref pw, ref ph);

                SupportsNativeScale     = pw < frameWidth || ph < frameHeight;
                SupportsNativeTransform = trans.DoesSupportTransform(WICBitmapTransformOptions.WICBitmapTransformRotate270);
            }

            if (WicSource is IWICPlanarBitmapSourceTransform ptrans)
            {
                var desc = ArrayPool <WICBitmapPlaneDescription> .Shared.Rent(WicTransforms.PlanarPixelFormats.Length);

                SupportsPlanarProcessing = ptrans.DoesSupportTransform(ref frameWidth, ref frameHeight, WICBitmapTransformOptions.WICBitmapTransformRotate0, WICPlanarOptions.WICPlanarOptionsDefault, WicTransforms.PlanarPixelFormats, desc, (uint)WicTransforms.PlanarPixelFormats.Length);
                ChromaSubsampling        =
                    desc[1].Width < desc[0].Width && desc[1].Height < desc[0].Height ? WICJpegYCrCbSubsamplingOption.WICJpegYCrCbSubsampling420 :
                    desc[1].Width < desc[0].Width ? WICJpegYCrCbSubsamplingOption.WICJpegYCrCbSubsampling422 :
                    desc[1].Height < desc[0].Height ? WICJpegYCrCbSubsamplingOption.WICJpegYCrCbSubsampling440 :
                    WICJpegYCrCbSubsamplingOption.WICJpegYCrCbSubsampling444;

                ArrayPool <WICBitmapPlaneDescription> .Shared.Return(desc);
            }

            if (WicFrame.TryGetMetadataQueryReader(out var metareader))
            {
                WicMetadataReader = comHandles.AddRef(metareader);

                string orientationPath =
                    MagicImageProcessor.EnableXmpOrientation ? Wic.Metadata.OrientationWindowsPolicy :
                    decoder.ContainerFormat == FileFormat.Jpeg ? Wic.Metadata.OrientationJpegPath :
                    Wic.Metadata.OrientationExifPath;

                if (metareader.TryGetMetadataByName(orientationPath, out var pvorient) && pvorient.UnmanagedType == VarEnum.VT_UI2)
                {
                    ExifOrientation = (Orientation)Math.Min(Math.Max((ushort)Orientation.Normal, (ushort)pvorient.Value !), (ushort)Orientation.Rotate270);
                }
            }
        }
Example #2
0
        public WicImageFrame(WicImageContainer decoder, uint index)
        {
            WicFrame  = comHandles.AddRef(decoder.WicDecoder.GetFrame(index));
            WicSource = WicFrame;
            Container = decoder;

            WicFrame.GetResolution(out double dpix, out double dpiy);
            DpiX = dpix;
            DpiY = dpiy;

            WicFrame.GetSize(out uint frameWidth, out uint frameHeight);

            if (WicFrame.TryGetMetadataQueryReader(out var metareader))
            {
                WicMetadataReader = comHandles.AddRef(metareader);

                string orientationPath =
                    MagicImageProcessor.EnableXmpOrientation ? Wic.Metadata.OrientationWindowsPolicy :
                    Container.ContainerFormat == FileFormat.Jpeg ? Wic.Metadata.OrientationJpeg :
                    Wic.Metadata.OrientationExif;

                ExifOrientation = ((Orientation)metareader.GetValueOrDefault <ushort>(orientationPath)).Clamp();
            }

            if (decoder.IsRawContainer && index == 0 && decoder.WicDecoder.TryGetPreview(out var preview))
            {
                using var pvwSource = ComHandle.Wrap(preview);
                preview.GetSize(out uint pw, out uint ph);

                if (pw == frameWidth && ph == frameHeight)
                {
                    WicSource = comHandles.AddOwnRef(preview);
                }
            }

            if (WicSource is IWICBitmapSourceTransform trans)
            {
                uint pw = 1, ph = 1;
                trans.GetClosestSize(ref pw, ref ph);

                SupportsNativeScale = pw < frameWidth || ph < frameHeight;
            }

            if (WicSource is IWICPlanarBitmapSourceTransform ptrans)
            {
                var desc = ArrayPool <WICBitmapPlaneDescription> .Shared.Rent(WicTransforms.PlanarPixelFormats.Length);

                uint twidth = frameWidth, theight = frameHeight;
                SupportsPlanarProcessing = ptrans.DoesSupportTransform(
                    ref twidth, ref theight,
                    WICBitmapTransformOptions.WICBitmapTransformRotate0, WICPlanarOptions.WICPlanarOptionsDefault,
                    WicTransforms.PlanarPixelFormats, desc, (uint)WicTransforms.PlanarPixelFormats.Length
                    );

                ChromaSubsampling =
                    desc[1].Width < desc[0].Width && desc[1].Height < desc[0].Height ? WICJpegYCrCbSubsamplingOption.WICJpegYCrCbSubsampling420 :
                    desc[1].Width < desc[0].Width ? WICJpegYCrCbSubsamplingOption.WICJpegYCrCbSubsampling422 :
                    desc[1].Height < desc[0].Height ? WICJpegYCrCbSubsamplingOption.WICJpegYCrCbSubsampling440 :
                    WICJpegYCrCbSubsamplingOption.WICJpegYCrCbSubsampling444;

                ArrayPool <WICBitmapPlaneDescription> .Shared.Return(desc);
            }

            if (PixelFormat.FromGuid(WicSource.GetPixelFormat()).NumericRepresentation == PixelNumericRepresentation.Indexed)
            {
                var newFormat = PixelFormat.Bgr24Bpp;
                if (Container.ContainerFormat == FileFormat.Gif && Container.FrameCount > 1)
                {
                    newFormat = PixelFormat.Bgra32Bpp;
                }
                else
                {
                    using var wicpal = ComHandle.Wrap(Wic.Factory.CreatePalette());
                    var pal = wicpal.ComObject;
                    WicSource.CopyPalette(pal);

                    if (pal.HasAlpha())
                    {
                        newFormat = PixelFormat.Bgra32Bpp;
                    }
                    else if (pal.IsGrayscale() || pal.IsBlackWhite())
                    {
                        newFormat = PixelFormat.Grey8Bpp;
                    }
                }

                var conv = comHandles.AddRef(Wic.Factory.CreateFormatConverter());
                conv.Initialize(WicSource, newFormat.FormatGuid, WICBitmapDitherType.WICBitmapDitherTypeNone, null, 0.0, WICBitmapPaletteType.WICBitmapPaletteTypeCustom);
                WicSource = conv;
            }
        }