Пример #1
0
        public WicGammaCompress(WicTransform prev) : base(prev)
        {
            var fmt  = Source.GetPixelFormat();
            var conv = (WicGammaFormatConverter)null;

            if (fmt == Consts.GUID_WICPixelFormat64bppBGRA)
            {
                conv = new WicGammaFormatConverter(Source, Consts.GUID_WICPixelFormat32bppBGRA);
            }
            else if (fmt == Consts.GUID_WICPixelFormat48bppBGR)
            {
                conv = new WicGammaFormatConverter(Source, Consts.GUID_WICPixelFormat24bppBGR);
            }
            else if (fmt == Consts.GUID_WICPixelFormat16bppGray)
            {
                conv = new WicGammaFormatConverter(Source, Context.SupportsPlanar ? Consts.GUID_WICPixelFormat8bppY : Consts.GUID_WICPixelFormat8bppGray);
            }

            if (conv == null)
            {
                return;
            }

            Source = conv;
            Context.PixelFormat = Source.GetPixelFormat();
        }
Пример #2
0
        public WicPixelFormatConverter(WicTransform prev) : base(prev)
        {
            var newFormat = Consts.GUID_WICPixelFormat24bppBGR;

            if (Context.HasAlpha)
            {
                newFormat = Context.PixelFormat.FormatGuid == Consts.GUID_WICPixelFormat32bppPBGRA ? Consts.GUID_WICPixelFormat32bppPBGRA : Consts.GUID_WICPixelFormat32bppBGRA;
            }
            else if (Context.IsGreyscale)
            {
                newFormat = Consts.GUID_WICPixelFormat8bppGray;
            }
            else if (Context.PixelFormat.ColorRepresentation == PixelColorRepresentation.Cmyk)
            {
                newFormat = Consts.GUID_WICPixelFormat32bppCMYK;
            }

            if (Context.PixelFormat.FormatGuid == newFormat)
            {
                return;
            }

            var conv = AddRef(Wic.CreateFormatConverter());

            if (!conv.CanConvert(Context.PixelFormat.FormatGuid, newFormat))
            {
                throw new NotSupportedException("Can't convert to destination pixel format");
            }

            conv.Initialize(Source, newFormat, WICBitmapDitherType.WICBitmapDitherTypeNone, null, 0.0, WICBitmapPaletteType.WICBitmapPaletteTypeCustom);
            Source = conv;
            Context.PixelFormat = PixelFormat.Cache[Source.GetPixelFormat()];
        }
Пример #3
0
        public WicGammaExpand(WicTransform prev) : base(prev)
        {
            if (Context.Settings.BlendingMode != GammaMode.Linear)
            {
                return;
            }

            var fmt  = Source.GetPixelFormat();
            var conv = (WicLinearFormatConverter)null;

            if (fmt == Consts.GUID_WICPixelFormat32bppBGRA)
            {
                conv = new WicLinearFormatConverter(Source, Consts.GUID_WICPixelFormat64bppBGRA);
            }
            else if (fmt == Consts.GUID_WICPixelFormat24bppBGR)
            {
                conv = new WicLinearFormatConverter(Source, Consts.GUID_WICPixelFormat48bppBGR);
            }
            else if (fmt == Consts.GUID_WICPixelFormat8bppGray || fmt == Consts.GUID_WICPixelFormat8bppY)
            {
                conv = new WicLinearFormatConverter(Source, Consts.GUID_WICPixelFormat16bppGray);
            }

            if (conv == null)
            {
                return;
            }

            Source = conv;
            Context.PixelFormat = Source.GetPixelFormat();
        }
Пример #4
0
        public WicPaletizer(WicTransform prev, uint colors = 256u) : base(prev)
        {
            var newFormat = Consts.GUID_WICPixelFormat8bppIndexed;

            if (!Context.Settings.IndexedColor || Context.PixelFormat.FormatGuid == newFormat || Context.IsGreyscale)
            {
                return;
            }

            var conv = AddRef(Wic.CreateFormatConverter());

            if (!conv.CanConvert(Context.PixelFormat.FormatGuid, newFormat))
            {
                throw new NotSupportedException("Can't convert to destination pixel format");
            }

            var bmp = AddRef(Wic.CreateBitmapFromSource(Source, WICBitmapCreateCacheOption.WICBitmapCacheOnDemand));

            var pal = AddRef(Wic.CreatePalette());

            pal.InitializeFromBitmap(bmp, colors, false);
            Context.DestPalette = pal;

            conv.Initialize(bmp, newFormat, WICBitmapDitherType.WICBitmapDitherTypeErrorDiffusion, pal, 10.0, WICBitmapPaletteType.WICBitmapPaletteTypeCustom);
            Source = conv;
            Context.PixelFormat = PixelFormat.Cache[Source.GetPixelFormat()];
        }
Пример #5
0
        public void WriteSource(WicTransform prev)
        {
            var src = prev.Source;

            var iformat = src.GetPixelFormat();
            var oformat = iformat;

            Frame.SetPixelFormat(ref oformat);
            if (oformat != iformat)
            {
                var pal = default(IWICPalette);
                var ptt = WICBitmapPaletteType.WICBitmapPaletteTypeCustom;
                if (PixelFormat.Cache[oformat].NumericRepresentation == PixelNumericRepresentation.Indexed)
                {
                    pal = AddRef(Wic.CreatePalette());
                    pal.InitializePredefined(WICBitmapPaletteType.WICBitmapPaletteTypeFixedGray256, false);
                    ptt = WICBitmapPaletteType.WICBitmapPaletteTypeFixedGray256;
                }

                var conv = AddRef(Wic.CreateFormatConverter());
                conv.Initialize(src, oformat, WICBitmapDitherType.WICBitmapDitherTypeNone, pal, 0.0, ptt);
                src = conv;
            }

            Frame.WriteSource(src, null);

            Frame.Commit();
            Encoder.Commit();
        }
        public WicConvertFromCustomPixelFormat(WicTransform prev) : base(prev)
        {
            var ifmt = Source.GetPixelFormat();
            var ofmt = ifmt;

            if (ifmt == Consts.GUID_WICPixelFormat32bppGrayFloat || ifmt == PixelFormat.Grey32BppLinearFloat.FormatGuid || ifmt == PixelFormat.Grey16BppLinearUQ15.FormatGuid)
            {
                ofmt = Consts.GUID_WICPixelFormat8bppGray;
            }
            else if (ifmt == PixelFormat.Y32BppFloat.FormatGuid || ifmt == PixelFormat.Y32BppLinearFloat.FormatGuid || ifmt == PixelFormat.Y16BppLinearUQ15.FormatGuid)
            {
                ofmt = Consts.GUID_WICPixelFormat8bppY;
            }
            else if (ifmt == PixelFormat.Bgr96BppFloat.FormatGuid || ifmt == PixelFormat.Bgr96BppLinearFloat.FormatGuid || ifmt == PixelFormat.Bgr48BppLinearUQ15.FormatGuid)
            {
                ofmt = Consts.GUID_WICPixelFormat24bppBGR;
            }
            else if (ifmt == PixelFormat.Pbgra128BppFloat.FormatGuid || ifmt == PixelFormat.Pbgra128BppLinearFloat.FormatGuid || ifmt == PixelFormat.Bgra64BppLinearUQ15.FormatGuid || ifmt == PixelFormat.Pbgra64BppLinearUQ15.FormatGuid)
            {
                ofmt = Consts.GUID_WICPixelFormat32bppBGRA;
            }
            else if (ifmt == PixelFormat.CbCr64BppFloat.FormatGuid)
            {
                ofmt = Consts.GUID_WICPixelFormat16bppCbCr;
            }

            if (ofmt == ifmt)
            {
                return;
            }

            Source = conv = new WicCustomPixelFormatConverter(Source, ofmt);
            Context.PixelFormat = PixelFormat.Cache[Source.GetPixelFormat()];
        }
Пример #7
0
        public WicMatteTransform(WicTransform prev) : base(prev)
        {
            if (Context.Settings.MatteColor.IsEmpty || (Context.PixelFormat != Consts.GUID_WICPixelFormat32bppBGRA && Context.PixelFormat != Consts.GUID_WICPixelFormat64bppBGRA))
            {
                return;
            }

            var mat = new WicMatte(Source, Context.Settings.MatteColor);

            Source = mat;
        }
Пример #8
0
        public void WriteSource(WicTransform prevY, WicTransform prevCbCr)
        {
            var oformat = Consts.GUID_WICPixelFormat24bppBGR;

            Frame.SetPixelFormat(ref oformat);

            PlanarFrame.WriteSource(new IWICBitmapSource[] { prevY.Source, prevCbCr.Source }, 2, null);

            Frame.Commit();
            Encoder.Commit();
        }
Пример #9
0
        public WicColorspaceConverter(WicTransform prev) : base(prev)
        {
            if (Context.SourceColorContext == null)
            {
                return;
            }

            var trans = AddRef(Wic.CreateColorTransform());

            trans.Initialize(Source, Context.SourceColorContext, Context.DestColorContext, Context.PixelFormat.FormatGuid);

            Source = trans;
        }
Пример #10
0
        public WicColorspaceConverter(WicTransform prev) : base(prev)
        {
            if (Context.SourceColorContext == null)
            {
                return;
            }

            var trans = AddRef(Wic.CreateColorTransform());

            trans.Initialize(Source, Context.SourceColorContext, Context.DestColorContext, Context.IsCmyk ? Context.HasAlpha ? Consts.GUID_WICPixelFormat32bppBGRA : Consts.GUID_WICPixelFormat24bppBGR : Context.PixelFormat);

            Source = trans;
        }
Пример #11
0
        public WicUnsharpMask(WicTransform prev) : base(prev)
        {
            var ss = Context.Settings.UnsharpMask;

            if (ss.Radius <= 0 || ss.Amount <= 0)
            {
                return;
            }

            var mapx = KernelMap.MakeBlurMap(Context.Width, ss.Radius);
            var mapy = KernelMap.MakeBlurMap(Context.Height, ss.Radius);

            Source = new WicUnsharpMask8bpc(Source, mapx, mapy, ss);
        }
Пример #12
0
        public WicCmykConverter(WicTransform prev) : base(prev)
        {
            if (Context.PixelFormat.ColorRepresentation != PixelColorRepresentation.Cmyk)
            {
                return;
            }

            var trans = AddRef(Wic.CreateColorTransform());

            trans.Initialize(Source, Context.SourceColorContext, Context.DestColorContext, Context.PixelFormat.AlphaRepresentation != PixelAlphaRepresentation.None ? Consts.GUID_WICPixelFormat32bppBGRA : Consts.GUID_WICPixelFormat24bppBGR);

            Source = trans;
            Context.SourceColorContext = null;
        }
        public WicMatteTransform(WicTransform prev) : base(prev)
        {
            if (Context.PixelFormat == PixelFormat.Pbgra128BppFloat)
            {
                Source = conv = new WicCustomPixelFormatConverter(Source, Consts.GUID_WICPixelFormat32bppBGRA);
                Context.PixelFormat = PixelFormat.Cache[Source.GetPixelFormat()];
            }

            if (Context.Settings.MatteColor.IsEmpty || Context.PixelFormat.ColorRepresentation != PixelColorRepresentation.Bgr || Context.PixelFormat.AlphaRepresentation == PixelAlphaRepresentation.None)
            {
                return;
            }

            Source = new WicMatte(Source, Context.Settings.MatteColor);
        }
Пример #14
0
        public WicExifRotator(WicTransform prev) : base(prev)
        {
            if (Context.TransformOptions == WICBitmapTransformOptions.WICBitmapTransformRotate0)
            {
                return;
            }

            var rotator = AddRef(Wic.CreateBitmapFlipRotator());

            rotator.Initialize(Source, Context.TransformOptions);

            Source = rotator;
            Source.GetSize(out Context.Width, out Context.Height);
            Context.NeedsCache = Context.TransformOptions != WICBitmapTransformOptions.WICBitmapTransformFlipHorizontal;
        }
Пример #15
0
        public WicConditionalCache(WicTransform prev) : base(prev)
        {
            if (!Context.NeedsCache)
            {
                return;
            }

            var crop = Context.Settings.Crop;
            var bmp  = AddRef(Wic.CreateBitmapFromSourceRect(Source, (uint)crop.X, (uint)crop.Y, (uint)crop.Width, (uint)crop.Height));

            Source = bmp;
            Source.GetSize(out Context.Width, out Context.Height);
            Context.Settings.Crop = new Rectangle(0, 0, (int)Context.Width, (int)Context.Height);
            Context.NeedsCache    = false;
        }
Пример #16
0
        public WicPlanarConverter(WicTransform prevY, WicTransform prevCbCr) : base(prevY)
        {
            var cfmt  = Consts.GUID_WICPixelFormat24bppBGR;
            var conv  = AddRef(Wic.CreateFormatConverter());
            var pconv = conv as IWICPlanarFormatConverter;

            pconv.Initialize(new IWICBitmapSource[] { prevY.Source, prevCbCr.Source }, 2, cfmt, WICBitmapDitherType.WICBitmapDitherTypeNone, null, 0.0, WICBitmapPaletteType.WICBitmapPaletteTypeCustom);
            Source = pconv;

            if (Context.SourceColorContext != null)
            {
                var trans = AddRef(Wic.CreateColorTransform());
                trans.Initialize(Source, Context.SourceColorContext, Context.DestColorContext, cfmt);
                Source = trans;
            }
        }
        public WicUnsharpMask(WicTransform prev) : base(prev)
        {
            var ss = Context.Settings.UnsharpMask;

            if (ss.Radius <= 0d || ss.Amount <= 0)
            {
                return;
            }

            var fmt = PixelFormat.Cache[Source.GetPixelFormat()];

            mapx = KernelMap <int> .MakeBlurMap(Context.Width, ss.Radius, 1u, fmt.AlphaRepresentation != PixelAlphaRepresentation.None);

            mapy = KernelMap <int> .MakeBlurMap(Context.Height, ss.Radius, 1u, fmt.AlphaRepresentation != PixelAlphaRepresentation.None);

            Source = source = new WicUnsharpMask <byte, int>(Source, mapx, mapy, ss);
        }
        public static void ProcessImage(WicTransform prev, WicProcessingContext ctx, Stream ostm)
        {
            bool savePlanar = ctx.Settings.SaveFormat == FileFormat.Jpeg && ctx.SourceColorContext == null;

            using (var rot = new WicExifRotator(prev))
                using (var pln = new WicPlanarCache(rot))
                    using (var ply = new WicPlanarSplitter(pln, WicPlane.Luma))
                        using (var lll = new WicConvertToCustomPixelFormat(ply))
                            using (var mmm = new WicHighQualityScaler(lll))
                                using (var ggg = new WicConvertFromCustomPixelFormat(mmm))
                                    using (var sss = new WicUnsharpMask(ggg))

                                        using (var enc = new WicEncoder(ostm.AsIStream(), ctx))
                                            using (var plc = new WicPlanarSplitter(pln, WicPlane.Chroma))
                                            {
                                                if (savePlanar)
                                                {
                                                    var subsample = ctx.Settings.JpegSubsampleMode;
                                                    if (subsample == ChromaSubsampleMode.Subsample420)
                                                    {
                                                        ctx.Settings.Height = (int)Math.Ceiling(ctx.Settings.Height / 2d);
                                                    }

                                                    if (subsample == ChromaSubsampleMode.Subsample420 || subsample == ChromaSubsampleMode.Subsample422)
                                                    {
                                                        ctx.Settings.Width = (int)Math.Ceiling(ctx.Settings.Width / 2d);
                                                    }

                                                    using (var fff = new WicConvertToCustomPixelFormat(plc))
                                                        using (var res = new WicHighQualityScaler(fff))
                                                            using (var bbb = new WicConvertFromCustomPixelFormat(res))
                                                                using (var pen = new WicPlanarEncoder(enc))
                                                                    pen.WriteSource(sss, bbb);
                                                }
                                                else
                                                {
                                                    using (var fff = new WicConvertToCustomPixelFormat(plc))
                                                        using (var res = new WicHighQualityScaler(fff))
                                                            using (var bbb = new WicConvertFromCustomPixelFormat(res))
                                                                using (var con = new WicPlanarConverter(sss, bbb))
                                                                    using (var pal = new WicPaletizer(con))
                                                                        enc.WriteSource(pal);
                                                }
                                            }
        }
Пример #19
0
        public WicCropper(WicTransform prev) : base(prev)
        {
            var crop = Context.Settings.Crop;

            if (crop == Rectangle.FromLTRB(0, 0, (int)Context.Width, (int)Context.Height))
            {
                return;
            }

            var cropper = AddRef(Wic.CreateBitmapClipper());

            cropper.Initialize(Source, new WICRect {
                X = crop.X, Y = crop.Y, Width = crop.Width, Height = crop.Height
            });

            Source = cropper;
            Source.GetSize(out Context.Width, out Context.Height);
        }
Пример #20
0
        public WicScaler(WicTransform prev, bool hybrid = false) : base(prev)
        {
            if (Context.Settings.Width == Context.Width && Context.Settings.Height == Context.Height)
            {
                return;
            }

            double rat = Context.Settings.HybridScaleRatio;

            if (hybrid && rat == 1d)
            {
                return;
            }

            if (Source is IWICBitmapSourceTransform)
            {
                // null crop to disable IWICBitmapSourceTransform scaling
                var clip = AddRef(Wic.CreateBitmapClipper());
                clip.Initialize(Source, new WICRect {
                    X = 0, Y = 0, Width = (int)Context.Width, Height = (int)Context.Height
                });

                Source = clip;
            }

            uint ow   = hybrid ? (uint)Math.Ceiling(Context.Width / rat) : (uint)Context.Settings.Width;
            uint oh   = hybrid ? (uint)Math.Ceiling(Context.Height / rat) : (uint)Context.Settings.Height;
            var  mode = hybrid ? WICBitmapInterpolationMode.WICBitmapInterpolationModeFant :
                        Context.Settings.Interpolation.WeightingFunction.Support <0.1 ? WICBitmapInterpolationMode.WICBitmapInterpolationModeNearestNeighbor :
                                                                                  Context.Settings.Interpolation.WeightingFunction.Support> 1.0 ? Context.Settings.ScaleRatio < 1.0 ? WICBitmapInterpolationMode.WICBitmapInterpolationModeCubic : WICBitmapInterpolationMode.WICBitmapInterpolationModeHighQualityCubic :
                        WICBitmapInterpolationMode.WICBitmapInterpolationModeFant;

            var scaler = AddRef(Wic.CreateBitmapScaler());

            scaler.Initialize(Source, ow, oh, mode);

            Source = scaler;
            Source.GetSize(out Context.Width, out Context.Height);

            if (hybrid)
            {
                Context.Settings.Crop = new Rectangle(0, 0, (int)Context.Width, (int)Context.Height);
            }
        }
Пример #21
0
        public WicHighQualityScaler(WicTransform prev) : base(prev)
        {
            uint width = (uint)Context.Settings.Width, height = (uint)Context.Settings.Height;
            var  interpolatorx = width == Context.Width ? InterpolationSettings.NearestNeighbor : Context.Settings.Interpolation;
            var  interpolatory = height == Context.Height ? InterpolationSettings.NearestNeighbor : Context.Settings.Interpolation;

            var mapx = KernelMap.MakeScaleMap(Context.Width, width, interpolatorx);
            var mapy = KernelMap.MakeScaleMap(Context.Height, height, interpolatory);

            if (Context.Settings.BlendingMode == GammaMode.Linear)
            {
                Source = new WicConvolution16bpc(Source, mapx, mapy);
            }
            else
            {
                Source = new WicConvolution8bpc(Source, mapx, mapy);
            }

            Source.GetSize(out Context.Width, out Context.Height);
        }
        public WicHighQualityScaler(WicTransform prev) : base(prev)
        {
            uint width = (uint)Context.Settings.Width, height = (uint)Context.Settings.Height;
            var  interpolatorx = width == Context.Width ? InterpolationSettings.NearestNeighbor : Context.Settings.Interpolation;
            var  interpolatory = height == Context.Height ? InterpolationSettings.NearestNeighbor : Context.Settings.Interpolation;

            var fmt = PixelFormat.Cache[Source.GetPixelFormat()];

            if (fmt.NumericRepresentation == PixelNumericRepresentation.Float)
            {
                var mx = KernelMap <float> .MakeScaleMap(Context.Width, width, fmt.ColorChannelCount, fmt.AlphaRepresentation != PixelAlphaRepresentation.None, true, interpolatorx);

                var my = KernelMap <float> .MakeScaleMap(Context.Height, height, fmt.ColorChannelCount, fmt.AlphaRepresentation != PixelAlphaRepresentation.None, true, interpolatory);

                source = new WicConvolution <float, float>(Source, mx, my);

                mapx = mx;
                mapy = my;
            }
            else
            {
                var mx = KernelMap <int> .MakeScaleMap(Context.Width, width, 1, fmt.AlphaRepresentation == PixelAlphaRepresentation.Unassociated, false, interpolatorx);

                var my = KernelMap <int> .MakeScaleMap(Context.Height, height, 1, fmt.AlphaRepresentation == PixelAlphaRepresentation.Unassociated, false, interpolatory);

                if (fmt.NumericRepresentation == PixelNumericRepresentation.Fixed)
                {
                    source = new WicConvolution <ushort, int>(Source, mx, my);
                }
                else
                {
                    source = new WicConvolution <byte, int>(Source, mx, my);
                }

                mapx = mx;
                mapy = my;
            }

            Source = source;
            Source.GetSize(out Context.Width, out Context.Height);
        }
Пример #23
0
        public WicNativeScaler(WicTransform prev) : base(prev)
        {
            double rat = Context.Settings.HybridScaleRatio;

            if (rat == 1d)
            {
                return;
            }

            var trans = Source as IWICBitmapSourceTransform;

            if (trans == null)
            {
                return;
            }

            uint ow = Context.Width, oh = Context.Height;
            uint cw = (uint)Math.Ceiling(ow / rat), ch = (uint)Math.Ceiling(oh / rat);

            trans.GetClosestSize(ref cw, ref ch);

            if (cw == ow && ch == oh)
            {
                return;
            }

            double wrat = (double)ow / cw, hrat = (double)oh / ch;

            var crop = Context.Settings.Crop;

            Context.Settings.Crop = new Rectangle((int)Math.Floor(crop.X / wrat), (int)Math.Floor(crop.Y / hrat), (int)Math.Ceiling(crop.Width / wrat), (int)Math.Ceiling(crop.Height / hrat));

            var scaler = AddRef(Wic.CreateBitmapScaler());

            scaler.Initialize(Source, cw, ch, WICBitmapInterpolationMode.WICBitmapInterpolationModeFant);

            Source = scaler;
            Source.GetSize(out Context.Width, out Context.Height);
        }
        public WicPlanarCache(WicTransform prev) : base(prev)
        {
            if (!(prev.Source is IWICPlanarBitmapSourceTransform))
            {
                throw new NotSupportedException("Transform chain doesn't support planar mode.  Only JPEG Decoder, Rotator, Scaler, and ColorSpaceConverter are allowed");
            }
            var trans = (IWICPlanarBitmapSourceTransform)prev.Source;

            double rat = Context.Settings.HybridScaleRatio.Clamp(1d, 8d);

            Context.Width  = (uint)Math.Ceiling(Context.Width / rat);
            Context.Height = (uint)Math.Ceiling(Context.Height / rat);

            // Although generally the last scan has the least significant bit(s) of the luma plane and skipping it could be very beneficial performance-wise, there is no guarantee of scan order.  Might be able to do something with more decoder support.
            //var prog = Frame as IWICProgressiveLevelControl;
            //if (prog != null)
            //{
            //	uint levels = prog.GetLevelCount();
            //	uint level = (uint)Math.Ceiling(levels / rat) + (Context.Settings.HybridMode == HybridScaleMode.FavorQuality || Context.Settings.HybridMode == HybridScaleMode.Off ? (uint)Math.Ceiling(levels / 8d) : 0u);
            //	prog.SetCurrentLevel(Math.Min(level, levels - (Context.Settings.ScaleRatio >= 2d && levels > 7u ? 2u : 1u)));
            //}

            var fmts = new Guid[] { Consts.GUID_WICPixelFormat8bppY, Consts.GUID_WICPixelFormat16bppCbCr };
            var desc = new WICBitmapPlaneDescription[2];

            if (!trans.DoesSupportTransform(ref Context.Width, ref Context.Height, Context.TransformOptions, WICPlanarOptions.WICPlanarOptionsDefault, fmts, desc, 2))
            {
                throw new NotSupportedException("Requested planar transform not supported");
            }

            var crop = new WICRect {
                X = Context.Settings.Crop.X, Y = Context.Settings.Crop.Y, Width = Context.Settings.Crop.Width, Height = Context.Settings.Crop.Height
            };

            cacheSource = new WicPlanarCacheSource(trans, desc[0], desc[1], crop, Context.TransformOptions, Context.Width, Context.Height, rat, Context.NeedsCache);

            SourceY    = cacheSource.GetPlane(WicPlane.Luma);
            SourceCbCr = cacheSource.GetPlane(WicPlane.Chroma);
        }
Пример #25
0
        public void WriteSource(WicTransform prev)
        {
            var src = prev.Source;

            var iformat = src.GetPixelFormat();
            var oformat = iformat;

            Frame.SetPixelFormat(ref oformat);
            if (oformat != iformat)
            {
                // TODO grey -> indexed support
                //var pal = AddRef(Wic.CreatePalette());
                //pal.InitializePredefined(WICBitmapPaletteType.WICBitmapPaletteTypeFixedGray256, false);
                var conv = AddRef(Wic.CreateFormatConverter());
                conv.Initialize(src, oformat, WICBitmapDitherType.WICBitmapDitherTypeNone, null, 0.0, WICBitmapPaletteType.WICBitmapPaletteTypeCustom);
                src = conv;
            }

            Frame.WriteSource(src, null);

            Frame.Commit();
            Encoder.Commit();
        }
Пример #26
0
        public WicPlanarCache(WicTransform prev) : base(prev)
        {
            Contract.Requires <NotSupportedException>(prev.Source is IWICPlanarBitmapSourceTransform, "Transform chain doesn't support planar mode.  Only JPEG Decoder, Rotator, Scaler, and ColorSpaceConverter are allowed");
            var trans = (IWICPlanarBitmapSourceTransform)prev.Source;

            double rat = Context.Settings.HybridScaleRatio.Clamp(1d, 8d);

            Context.Width  = (uint)Math.Ceiling(Context.Width / rat);
            Context.Height = (uint)Math.Ceiling(Context.Height / rat);

            var prog = Frame as IWICProgressiveLevelControl;

            if (prog != null)             // TODO needs work
            {
                uint levels = prog.GetLevelCount();
                uint level  = (uint)Math.Ceiling(levels / rat) + (Context.Settings.HybridMode == HybridScaleMode.FavorQuality || Context.Settings.HybridMode == HybridScaleMode.Off ? (uint)Math.Ceiling(levels / 8d) : 0u);
                prog.SetCurrentLevel(Math.Min(level, levels - (Context.Settings.ScaleRatio >= 2d && levels > 7u ? 2u : 1u)));
            }

            var fmts = new Guid[] { Consts.GUID_WICPixelFormat8bppY, Consts.GUID_WICPixelFormat16bppCbCr };
            var desc = new WICBitmapPlaneDescription[2];

            if (!trans.DoesSupportTransform(ref Context.Width, ref Context.Height, Context.TransformOptions, WICPlanarOptions.WICPlanarOptionsPreserveSubsampling, fmts, desc, 2))
            {
                throw new NotSupportedException("Planar Transform not supported");
            }

            var crop = new WICRect()
            {
                X = Context.Settings.Crop.X, Y = Context.Settings.Crop.Y, Width = Context.Settings.Crop.Width, Height = Context.Settings.Crop.Height
            };
            var source = new WicPlanarCacheSource(trans, desc[0], desc[1], crop, Context.TransformOptions, Context.Width, Context.Height, rat);

            SourceY    = source.GetPlane(WicPlane.Luma);
            SourceCbCr = source.GetPlane(WicPlane.Chroma);
        }
Пример #27
0
        public WicMetadataReader(WicTransform prev, bool basicOnly = false) : base(prev)
        {
            var pfi = AddRef(Wic.CreateComponentInfo(Context.PixelFormat)) as IWICPixelFormatInfo2;

            if (pfi.GetNumericRepresentation() == WICPixelFormatNumericRepresentation.WICPixelFormatNumericRepresentationIndexed)
            {
                var pal = AddRef(Wic.CreatePalette());
                Frame.CopyPalette(pal);

                Context.HasAlpha    = pal.HasAlpha();
                Context.IsGreyscale = pal.IsGrayscale();
            }
            else
            {
                uint chans = pfi.GetChannelCount();
                bool trans = pfi.SupportsTransparency();
                Context.HasAlpha    = trans;
                Context.IsGreyscale = chans == 1u;
                Context.IsCmyk      = (chans == 4u && !trans) || (chans == 5u && trans);
            }

            var metareader = Frame.GetMetadataQueryReaderNoThrow();

            if (metareader != null)
            {
                AddRef(metareader);
                // Exif orientation
                if (metareader.HasMetadataName("System.Photo.Orientation"))
                {
                    ushort orientation = 1;
                    var    ovar        = new PropVariant();
                    metareader.GetMetadataByName("System.Photo.Orientation", ovar);
                    if (ovar.UnmanagedType == VarEnum.VT_UI2)
                    {
                        orientation = (ushort)ovar.Value;
                    }

                    var opt = WICBitmapTransformOptions.WICBitmapTransformRotate0;
                    if (orientation == 3 || orientation == 4)
                    {
                        opt = WICBitmapTransformOptions.WICBitmapTransformRotate180;
                    }
                    else if (orientation == 6 || orientation == 7)
                    {
                        opt = WICBitmapTransformOptions.WICBitmapTransformRotate90;
                    }
                    else if (orientation == 5 || orientation == 8)
                    {
                        opt = WICBitmapTransformOptions.WICBitmapTransformRotate270;
                    }

                    if (orientation == 2 || orientation == 4 || orientation == 5 || orientation == 7)
                    {
                        opt |= WICBitmapTransformOptions.WICBitmapTransformFlipHorizontal;
                    }

                    Context.TransformOptions = opt;
                }

                if (basicOnly)
                {
                    return;
                }

                // other requested properties
                var propdic = new Dictionary <string, PropVariant>();
                foreach (string prop in Context.Settings.MetadataNames ?? Enumerable.Empty <string>())
                {
                    if (metareader.HasMetadataName(prop))
                    {
                        var pvar = new PropVariant();
                        metareader.GetMetadataByName(prop, pvar);
                        if (pvar.Value != null)
                        {
                            propdic[prop] = pvar;
                        }
                    }
                }

                Context.Metadata = propdic;
            }

            // ICC profiles
            //http://ninedegreesbelow.com/photography/embedded-color-space-information.html
            uint ccc      = Frame.GetColorContextCount();
            var  profiles = new IWICColorContext[ccc];
            var  profile  = (IWICColorContext)null;

            if (ccc > 0)
            {
                for (int i = 0; i < ccc; i++)
                {
                    profiles[i] = AddRef(Wic.CreateColorContext());
                }

                Frame.GetColorContexts(ccc, profiles);
            }

            foreach (var cc in profiles)
            {
                var cct = cc.GetType();
                if (cct == WICColorContextType.WICColorContextProfile)
                {
                    uint ccs = cc.GetProfileBytes(0, null);
                    var  ccb = new byte[ccs];
                    cc.GetProfileBytes(ccs, ccb);

                    // match only color profiles that match our intended use. if we have a standard sRGB profile, don't save it; we don't need to convert
                    var cp = new ColorProfileInfo(ccb);
                    if (cp.IsValid && ((cp.IsDisplayRgb && !cp.IsStandardSrgb) || (Context.IsCmyk && cp.IsCmyk) /* || (Context.IsGreyscale && cp.DataColorSpace == "GRAY") */))
                    {
                        profile = cc;
                        break;
                    }
                }
                else if (cct == WICColorContextType.WICColorContextExifColorSpace && cc.GetExifColorSpace() == ExifColorSpace.AdobeRGB)
                {
                    profile = cc;
                    break;
                }
            }

            Context.SourceColorContext = profile ?? (Context.IsCmyk ? cmykProfile.Value : null);
            Context.DestColorContext   = srgbProfile.Value;
        }
Пример #28
0
 public WicTransform(WicTransform prev)
 {
     Context = prev.Context;
     Frame   = prev.Frame;
     Source  = prev.Source;
 }
        public WicConvertToCustomPixelFormat(WicTransform prev) : base(prev)
        {
            var  ifmt   = Source.GetPixelFormat();
            var  ofmt   = ifmt;
            bool linear = Context.Settings.BlendingMode == GammaMode.Linear;

            if (MagicImageProcessor.EnableSimd)
            {
                if (ifmt == Consts.GUID_WICPixelFormat8bppGray)
                {
                    ofmt = linear ? PixelFormat.Grey32BppLinearFloat.FormatGuid : Consts.GUID_WICPixelFormat32bppGrayFloat;
                }
                else if (ifmt == Consts.GUID_WICPixelFormat8bppY)
                {
                    ofmt = linear ? PixelFormat.Y32BppLinearFloat.FormatGuid : PixelFormat.Y32BppFloat.FormatGuid;
                }
                else if (ifmt == Consts.GUID_WICPixelFormat24bppBGR)
                {
                    ofmt = linear ? PixelFormat.Bgr96BppLinearFloat.FormatGuid : PixelFormat.Bgr96BppFloat.FormatGuid;
                }
                else if (ifmt == Consts.GUID_WICPixelFormat32bppBGRA || ifmt == Consts.GUID_WICPixelFormat32bppPBGRA)
                {
                    ofmt = linear ? PixelFormat.Pbgra128BppLinearFloat.FormatGuid : PixelFormat.Pbgra128BppFloat.FormatGuid;
                }
                else if (ifmt == Consts.GUID_WICPixelFormat16bppCbCr)
                {
                    ofmt = PixelFormat.CbCr64BppFloat.FormatGuid;
                }
            }
            else if (linear)
            {
                if (ifmt == Consts.GUID_WICPixelFormat8bppGray)
                {
                    ofmt = PixelFormat.Grey16BppLinearUQ15.FormatGuid;
                }
                else if (ifmt == Consts.GUID_WICPixelFormat8bppY)
                {
                    ofmt = PixelFormat.Y16BppLinearUQ15.FormatGuid;
                }
                else if (ifmt == Consts.GUID_WICPixelFormat24bppBGR)
                {
                    ofmt = PixelFormat.Bgr48BppLinearUQ15.FormatGuid;
                }
                else if (ifmt == Consts.GUID_WICPixelFormat32bppBGRA)
                {
                    ofmt = PixelFormat.Bgra64BppLinearUQ15.FormatGuid;
                }
                else if (ifmt == Consts.GUID_WICPixelFormat32bppPBGRA)
                {
                    ofmt = PixelFormat.Pbgra64BppLinearUQ15.FormatGuid;
                }
            }

            if (ofmt == ifmt)
            {
                return;
            }

            Source = conv = new WicCustomPixelFormatConverter(Source, ofmt);
            Context.PixelFormat = PixelFormat.Cache[Source.GetPixelFormat()];
        }
Пример #30
0
        public WicMetadataReader(WicTransform prev, bool basicOnly = false) : base(prev)
        {
            if (Context.PixelFormat.NumericRepresentation == PixelNumericRepresentation.Indexed)
            {
                var pal = AddRef(Wic.CreatePalette());
                Frame.CopyPalette(pal);

                Context.HasAlpha    = pal.HasAlpha();
                Context.IsGreyscale = pal.IsGrayscale();
            }
            else
            {
                Context.HasAlpha    = Context.PixelFormat.AlphaRepresentation != PixelAlphaRepresentation.None;
                Context.IsGreyscale = Context.PixelFormat.ColorRepresentation == PixelColorRepresentation.Grey;
            }

#if NET46
            if (Frame.TryGetMetadataQueryReader(out var metareader))
            {
                AddRef(metareader);

                // Exif orientation
                if (metareader.TryGetMetadataByName("System.Photo.Orientation", out var ovar))
                {
                    ushort orientation = 1;
                    if (ovar.UnmanagedType == VarEnum.VT_UI2)
                    {
                        orientation = (ushort)ovar.Value;
                    }

                    var opt = WICBitmapTransformOptions.WICBitmapTransformRotate0;
                    if (orientation == 3 || orientation == 4)
                    {
                        opt = WICBitmapTransformOptions.WICBitmapTransformRotate180;
                    }
                    else if (orientation == 6 || orientation == 7)
                    {
                        opt = WICBitmapTransformOptions.WICBitmapTransformRotate90;
                    }
                    else if (orientation == 5 || orientation == 8)
                    {
                        opt = WICBitmapTransformOptions.WICBitmapTransformRotate270;
                    }

                    if (orientation == 2 || orientation == 4 || orientation == 5 || orientation == 7)
                    {
                        opt |= WICBitmapTransformOptions.WICBitmapTransformFlipHorizontal;
                    }

                    Context.TransformOptions = opt;
                }

                if (basicOnly)
                {
                    return;
                }

                // other requested properties
                var propdic = new Dictionary <string, PropVariant>();
                foreach (string prop in Context.Settings.MetadataNames ?? Enumerable.Empty <string>())
                {
                    if (metareader.TryGetMetadataByName(prop, out var pvar) && pvar.Value != null)
                    {
                        propdic[prop] = pvar;
                    }
                }

                Context.Metadata = propdic;
            }
#endif

            // ICC profiles
            //http://ninedegreesbelow.com/photography/embedded-color-space-information.html
            uint ccc      = Frame.GetColorContextCount();
            var  profiles = new IWICColorContext[ccc];
            var  profile  = default(IWICColorContext);

            if (ccc > 0)
            {
                for (int i = 0; i < ccc; i++)
                {
                    profiles[i] = AddRef(Wic.CreateColorContext());
                }

                Frame.GetColorContexts(ccc, profiles);
            }

            foreach (var cc in profiles)
            {
                var cct = cc.GetType();
                if (cct == WICColorContextType.WICColorContextProfile)
                {
                    uint ccs = cc.GetProfileBytes(0, null);
                    var  ccb = ArrayPool <byte> .Shared.Rent((int)ccs);

                    cc.GetProfileBytes(ccs, ccb);

                    var cp = new ColorProfileInfo(new ArraySegment <byte>(ccb, 0, (int)ccs));
                    ArrayPool <byte> .Shared.Return(ccb);

                    // match only color profiles that match our intended use. if we have a standard sRGB profile, don't save it; we don't need to convert
                    if (cp.IsValid && ((cp.IsDisplayRgb && !cp.IsStandardSrgb) || (cp.IsCmyk && Context.PixelFormat.ColorRepresentation == PixelColorRepresentation.Cmyk) /* || (Context.IsGreyscale && cp.DataColorSpace == "GRAY") */))
                    {
                        profile = cc;
                        break;
                    }
                }
                else if (cct == WICColorContextType.WICColorContextExifColorSpace && cc.GetExifColorSpace() == ExifColorSpace.AdobeRGB)
                {
                    profile = cc;
                    break;
                }
            }

            Context.SourceColorContext = profile ?? (Context.PixelFormat.ColorRepresentation == PixelColorRepresentation.Cmyk ? cmykProfile.Value : null);
            Context.DestColorContext   = srgbProfile.Value;
        }