예제 #1
0
        public WicFrameReader(WicDecoder dec, WicProcessingContext ctx)
        {
            Frame   = AddRef(dec.Decoder.GetFrame((uint)ctx.Settings.FrameIndex));
            Source  = Frame;
            Context = ctx;

            if (ctx.ContainerFormat == Consts.GUID_ContainerFormatRaw && ctx.Settings.FrameIndex == 0)
            {
                try { Source = AddRef(dec.Decoder.GetPreview()); } catch { }
            }

            ctx.PixelFormat = Source.GetPixelFormat();
            Source.GetSize(out ctx.Width, out ctx.Height);

            var ptrans = Source as IWICPlanarBitmapSourceTransform;

            if (ptrans != null)
            {
                uint pw = ctx.Width, ph = ctx.Height;
                var  pdesc = new WICBitmapPlaneDescription[2];
                var  pfmts = new Guid[] { Consts.GUID_WICPixelFormat8bppY, Consts.GUID_WICPixelFormat16bppCbCr };
                ctx.SupportsPlanar = ptrans.DoesSupportTransform(ref pw, ref ph, WICBitmapTransformOptions.WICBitmapTransformRotate0, WICPlanarOptions.WICPlanarOptionsPreserveSubsampling, pfmts, pdesc, 2);
                ctx.IsSubsampled   = pdesc[0].Width != pdesc[1].Width || pdesc[0].Height != pdesc[1].Height;
            }
        }
        public static void ProcessImage(Stream istm, Stream ostm, ProcessImageSettings s)
        {
            if (istm == null)
            {
                throw new ArgumentNullException(nameof(istm));
            }
            if (ostm == null)
            {
                throw new ArgumentNullException(nameof(ostm));
            }
            if (!istm.CanSeek || !istm.CanRead)
            {
                throw new ArgumentException("Input Stream must allow Seek and Read", nameof(istm));
            }
            if (!ostm.CanSeek || !ostm.CanWrite)
            {
                throw new ArgumentException("Output Stream must allow Seek and Write", nameof(ostm));
            }
            if (istm.Length <= 0 || istm.Position >= istm.Length)
            {
                throw new ArgumentException("Input Stream is empty or positioned at its end", nameof(istm));
            }

            using (var ctx = new WicProcessingContext(s))
                using (var dec = new WicDecoder(istm, ctx))
                    processImage(dec, ctx, ostm);
        }
        private static void processImage(WicDecoder dec, WicProcessingContext ctx, Stream ostm)
        {
            using (var frm = new WicFrameReader(dec, ctx))
                using (var met = new WicMetadataReader(frm))
                {
                    if (!ctx.Settings.Normalized)
                    {
                        ctx.Settings.Fixup((int)ctx.Width, (int)ctx.Height, ctx.IsRotated90);
                    }

                    if (EnablePlanarPipeline && ctx.SupportsPlanar)
                    {
                        MagicPlanarImageProcessor.ProcessImage(met, ctx, ostm);
                        return;
                    }

                    using (var qsc = new WicNativeScaler(met))
                        using (var rot = new WicExifRotator(qsc))
                            using (var cac = new WicConditionalCache(rot))
                                using (var crp = new WicCropper(cac))
                                    using (var pix = new WicPixelFormatConverter(crp))
                                        using (var cmy = new WicCmykConverter(pix))
                                            using (var res = new WicScaler(cmy, true))
                                                using (var lll = new WicConvertToCustomPixelFormat(res))
                                                    using (var mmm = new WicHighQualityScaler(lll))
                                                        using (var mat = new WicMatteTransform(mmm))
                                                            using (var ggg = new WicConvertFromCustomPixelFormat(mat))
                                                                using (var csc = new WicColorspaceConverter(ggg))
                                                                    using (var sss = new WicUnsharpMask(csc))
                                                                        using (var dit = new WicPaletizer(sss))
                                                                            using (var enc = new WicEncoder(ostm.AsIStream(), ctx))
                                                                                enc.WriteSource(dit);
                }
        }
예제 #4
0
        private static void processImage(WicDecoder dec, WicProcessingContext ctx, Stream ostm)
        {
            using (var frm = new WicFrameReader(dec, ctx))
                using (var met = new WicMetadataReader(frm))
                {
                    if (!ctx.Settings.Normalized)
                    {
                        ctx.Settings.Fixup((int)ctx.Width, (int)ctx.Height, ctx.IsRotated90);
                    }

                    ctx.Settings.HybridMode = HybridScaleMode.Turbo;
                    //ctx.NeedsCache = true;

                    using (var qsc = new WicNativeScaler(met))
                        using (var rot = new WicExifRotator(qsc))
                            using (var cac = new WicConditionalCache(rot))
                                using (var crp = new WicCropper(cac))
                                    using (var pix = new WicPixelFormatConverter(crp))
                                        using (var cmy = new WicCmykConverter(pix))
                                            using (var res = new WicScaler(cmy))
                                                using (var csc = new WicColorspaceConverter(res))
                                                    using (var mat = new WicMatteTransform(csc))
                                                        using (var pal = new WicPaletizer(mat, 256))
                                                            using (var enc = new WicEncoder(ostm.AsIStream(), ctx))
                                                                enc.WriteSource(pal);
                }
        }
예제 #5
0
        private void loadInfo(WicDecoder dec, WicProcessingContext ctx)
        {
            ContainerType = FileFormat.Unknown;
            if (ctx.ContainerFormat == Consts.GUID_ContainerFormatJpeg)
            {
                ContainerType = FileFormat.Jpeg;
            }
            else if (ctx.ContainerFormat == Consts.GUID_ContainerFormatPng)
            {
                ContainerType = FileFormat.Png;
            }
            else if (ctx.ContainerFormat == Consts.GUID_ContainerFormatGif)
            {
                ContainerType = FileFormat.Gif;
            }
            else if (ctx.ContainerFormat == Consts.GUID_ContainerFormatBmp)
            {
                ContainerType = FileFormat.Bmp;
            }
            else if (ctx.ContainerFormat == Consts.GUID_ContainerFormatTiff)
            {
                ContainerType = FileFormat.Tiff;
            }

            Frames = new FrameInfo[ctx.ContainerFrameCount];
            for (int i = 0; i < ctx.ContainerFrameCount; i++)
            {
                ctx.Settings.FrameIndex = i;
                using (var frm = new WicFrameReader(dec, ctx))
                    using (var met = new WicMetadataReader(frm, basicOnly: true))
                    {
                        Frames[i] = new FrameInfo((int)ctx.Width, (int)ctx.Height, ctx.IsRotated90, ctx.HasAlpha);
                    }
            }
        }
예제 #6
0
        private static ProcessImageResult processImage(WicDecoder dec, WicProcessingContext ctx, Stream ostm)
        {
            var frm = new WicFrameReader(ctx);

            WicTransforms.AddMetadataReader(ctx);

            ctx.FinalizeSettings();

            WicTransforms.AddNativeScaler(ctx);
            WicTransforms.AddExifRotator(ctx);
            WicTransforms.AddConditionalCache(ctx);
            WicTransforms.AddCropper(ctx);
            WicTransforms.AddPixelFormatConverter(ctx);
            WicTransforms.AddScaler(ctx);
            WicTransforms.AddColorspaceConverter(ctx);
            MagicTransforms.AddMatte(ctx);
            MagicTransforms.AddPad(ctx);
            WicTransforms.AddIndexedColorConverter(ctx);

            var enc = new WicEncoder(ctx, ostm.AsIStream());

            enc.WriteSource(ctx);

            return(new ProcessImageResult {
                Settings = ctx.UsedSettings, Stats = ctx.Stats
            });
        }
예제 #7
0
        public static void ProcessImage(byte[] imgBuffer, Stream ostm, ProcessImageSettings s)
        {
            Contract.Requires <ArgumentNullException>(imgBuffer != null, nameof(imgBuffer));
            Contract.Requires <ArgumentNullException>(ostm != null, nameof(ostm));
            Contract.Requires <ArgumentException>(ostm.CanSeek && ostm.CanWrite, "Output Stream must allow Seek and Write");

            using (var ctx = new WicProcessingContext(s))
                using (var dec = new WicDecoder(imgBuffer, ctx))
                    processImage(dec, ctx, ostm);
        }
예제 #8
0
        /// <summary>Constructs a new processing pipeline from which pixels can be retrieved.</summary>
        /// <param name="imgStream">A stream containing a supported input image container.</param>
        /// <param name="settings">The settings for this processing operation.</param>
        /// <returns>A <see cref="ProcessingPipeline" /> containing the <see cref="IPixelSource" />, settings used, and basic instrumentation for the pipeline.</returns>
        public static ProcessingPipeline BuildPipeline(Stream imgStream, ProcessImageSettings settings)
        {
            checkInStream(imgStream);

            var ctx = new WicProcessingContext(settings);
            var dec = new WicDecoder(imgStream, ctx);

            buildPipeline(ctx, false);
            return(new ProcessingPipeline(ctx));
        }
예제 #9
0
        public ImageFileInfo(byte[] imgBuffer, DateTime lastModified)
        {
            Contract.Requires <ArgumentNullException>(imgBuffer != null, nameof(imgBuffer));

            using (var ctx = new WicProcessingContext(new ProcessImageSettings()))
                using (var dec = new WicDecoder(imgBuffer, ctx))
                    loadInfo(dec, ctx);

            FileSize = imgBuffer.Length;
            FileDate = lastModified;
        }
예제 #10
0
        public static void ProcessImage(Stream istm, Stream ostm, ProcessImageSettings s)
        {
            Contract.Requires <ArgumentNullException>(istm != null, nameof(istm));
            Contract.Requires <ArgumentNullException>(ostm != null, nameof(ostm));
            Contract.Requires <ArgumentException>(istm.CanSeek && istm.CanRead, "Input Stream must allow Seek and Read");
            Contract.Requires <ArgumentException>(ostm.CanSeek && ostm.CanWrite, "Output Stream must allow Seek and Write");
            Contract.Assume(istm.Position < istm.Length, "Input Stream Position is at the end.  Did you forget to Seek?");

            using (var ctx = new WicProcessingContext(s))
                using (var dec = new WicDecoder(istm, ctx))
                    processImage(dec, ctx, ostm);
        }
예제 #11
0
        /// <summary>All-in-one processing of an image according to the specified <paramref name="settings" />.</summary>
        /// <param name="imgStream">A stream containing a supported input image container.</param>
        /// <param name="outStream">The stream to which the output image will be written.</param>
        /// <param name="settings">The settings for this processing operation.</param>
        /// <returns>A <see cref="ProcessImageResult" /> containing the settings used and basic instrumentation for the pipeline.</returns>
        public static ProcessImageResult ProcessImage(Stream imgStream, Stream outStream, ProcessImageSettings settings)
        {
            checkInStream(imgStream);
            checkOutStream(outStream);

            using (var ctx = new WicProcessingContext(settings))
            {
                var dec = new WicDecoder(imgStream, ctx);
                buildPipeline(ctx);
                return(executePipeline(ctx, outStream));
            }
        }
예제 #12
0
        /// <summary>Constructs a new processing pipeline from which pixels can be retrieved.</summary>
        /// <param name="imgSource">A custom pixel source to use as input.</param>
        /// <param name="settings">The settings for this processing operation.</param>
        /// <returns>A <see cref="ProcessingPipeline" /> containing the <see cref="IPixelSource" />, settings used, and basic instrumentation for the pipeline.</returns>
        public static ProcessingPipeline BuildPipeline(IPixelSource imgSource, ProcessImageSettings settings)
        {
            if (imgSource is null)
            {
                throw new ArgumentNullException(nameof(imgSource));
            }

            var ctx = new WicProcessingContext(settings);
            var dec = new WicDecoder(imgSource, ctx);

            buildPipeline(ctx, false);
            return(new ProcessingPipeline(ctx));
        }
예제 #13
0
        /// <summary>Constructs a new processing pipeline from which pixels can be retrieved.</summary>
        /// <param name="imgBuffer">A buffer containing a supported input image container.</param>
        /// <param name="settings">The settings for this processing operation.</param>
        /// <returns>A <see cref="ProcessingPipeline" /> containing the <see cref="IPixelSource" />, settings used, and basic instrumentation for the pipeline.</returns>
        public static ProcessingPipeline BuildPipeline(ReadOnlySpan <byte> imgBuffer, ProcessImageSettings settings)
        {
            if (imgBuffer == default)
            {
                throw new ArgumentNullException(nameof(imgBuffer));
            }

            var ctx = new WicProcessingContext(settings);
            var dec = new WicDecoder(imgBuffer, ctx);

            buildPipeline(ctx, false);
            return(new ProcessingPipeline(ctx));
        }
예제 #14
0
        public static ProcessingPipeline BuildPipeline(string imgPath, ProcessImageSettings settings)
        {
            if (imgPath == null)
            {
                throw new ArgumentNullException(nameof(imgPath));
            }

            var ctx = new WicProcessingContext(settings);
            var dec = new WicDecoder(imgPath, ctx);

            buildPipeline(ctx, false);
            return(new ProcessingPipeline(ctx));
        }
예제 #15
0
        public ImageFileInfo(byte[] imgBuffer, DateTime lastModified)
        {
            if (imgBuffer == null)
            {
                throw new ArgumentNullException(nameof(imgBuffer));
            }

            using (var ctx = new WicProcessingContext(new ProcessImageSettings()))
                using (var dec = new WicDecoder(imgBuffer, ctx))
                    loadInfo(dec, ctx);

            FileSize = imgBuffer.Length;
            FileDate = lastModified;
        }
예제 #16
0
        public ImageFileInfo(Stream istm, DateTime lastModified)
        {
            Contract.Requires <ArgumentNullException>(istm != null, nameof(istm));
            Contract.Requires <ArgumentException>(istm.CanSeek && istm.CanRead, "Input Stream must allow Seek and Read");
            Contract.Assert(istm.Length > 0, "Input Stream cannot be empty");
            Contract.Assume(istm.Position < istm.Length, "Input Stream Position is at the end.  Did you forget to Seek?");

            using (var ctx = new WicProcessingContext(new ProcessImageSettings()))
                using (var dec = new WicDecoder(istm, ctx))
                    loadInfo(dec, ctx);

            FileSize = istm.Length;
            FileDate = lastModified;
        }
예제 #17
0
        /// <summary>All-in-one processing of an image according to the specified <paramref name="settings" />.</summary>
        /// <param name="imgBuffer">A buffer containing a supported input image container.</param>
        /// <param name="outStream">The stream to which the output image will be written.</param>
        /// <param name="settings">The settings for this processing operation.</param>
        /// <returns>A <see cref="ProcessImageResult" /> containing the settings used and basic instrumentation for the pipeline.</returns>
        public static ProcessImageResult ProcessImage(ReadOnlySpan <byte> imgBuffer, Stream outStream, ProcessImageSettings settings)
        {
            if (imgBuffer == default)
            {
                throw new ArgumentNullException(nameof(imgBuffer));
            }
            checkOutStream(outStream);

            using (var ctx = new WicProcessingContext(settings))
            {
                var dec = new WicDecoder(imgBuffer, ctx);
                buildPipeline(ctx);
                return(executePipeline(ctx, outStream));
            }
        }
예제 #18
0
        /// <summary>All-in-one processing of an image according to the specified <paramref name="settings" />.</summary>
        /// <param name="imgPath">The path to a file containing the input image.</param>
        /// <param name="outStream">The stream to which the output image will be written.</param>
        /// <param name="settings">The settings for this processing operation.</param>
        /// <returns>A <see cref="ProcessImageResult" /> containing the settings used and basic instrumentation for the pipeline.</returns>
        public static ProcessImageResult ProcessImage(string imgPath, Stream outStream, ProcessImageSettings settings)
        {
            if (imgPath is null)
            {
                throw new ArgumentNullException(nameof(imgPath));
            }
            checkOutStream(outStream);

            using (var ctx = new WicProcessingContext(settings))
            {
                var dec = new WicDecoder(imgPath, ctx);
                buildPipeline(ctx);
                return(executePipeline(ctx, outStream));
            }
        }
예제 #19
0
        private void loadInfo(WicDecoder dec, WicProcessingContext ctx)
        {
            ContainerType = ctx.Decoder.ContainerFormat;
            Frames        = new FrameInfo[ctx.Decoder.FrameCount];
            for (int i = 0; i < ctx.Decoder.FrameCount; i++)
            {
                ctx.Settings.FrameIndex = i;
                var frm = new WicFrameReader(ctx);
                WicTransforms.AddMetadataReader(ctx, basicOnly: true);

                int width  = (int)(frm.ExifOrientation.RequiresDimensionSwap() ? ctx.Source.Height : ctx.Source.Width);
                int height = (int)(frm.ExifOrientation.RequiresDimensionSwap() ? ctx.Source.Width : ctx.Source.Height);
                Frames[i] = new FrameInfo(width, height, ctx.Source.Format.AlphaRepresentation != PixelAlphaRepresentation.None, frm.ExifOrientation);
            }
        }
예제 #20
0
        public ImageFileInfo(string imgPath)
        {
            var fi = new FileInfo(imgPath);

            if (!fi.Exists)
            {
                throw new FileNotFoundException("File not found", imgPath);
            }

            using (var ctx = new WicProcessingContext(new ProcessImageSettings()))
                using (var dec = new WicDecoder(imgPath, ctx))
                    loadInfo(dec, ctx);

            FileSize = fi.Length;
            FileDate = fi.LastWriteTimeUtc;
        }
예제 #21
0
        public static ProcessingPipeline BuildPipeline(ArraySegment <byte> imgBuffer, ProcessImageSettings settings)
        {
            if (imgBuffer == null)
            {
                throw new ArgumentNullException(nameof(imgBuffer));
            }
            if (imgBuffer.Offset != 0)
            {
                throw new ArgumentException($"{nameof(imgBuffer.Offset)} must be 0", nameof(imgBuffer));
            }

            var ctx = new WicProcessingContext(settings);
            var dec = new WicDecoder(imgBuffer, ctx);

            buildPipeline(ctx, false);
            return(new ProcessingPipeline(ctx));
        }
예제 #22
0
        public ImageFileInfo(string imgPath)
        {
            Contract.Requires <ArgumentNullException>(imgPath != null, nameof(imgPath));

            var fi = new FileInfo(imgPath);

            if (!fi.Exists)
            {
                throw new ArgumentException("File does not exist");
            }

            using (var ctx = new WicProcessingContext(new ProcessImageSettings()))
                using (var dec = new WicDecoder(imgPath, ctx))
                    loadInfo(dec, ctx);

            FileSize = fi.Length;
            FileDate = fi.LastWriteTimeUtc;
        }
        public static void ProcessImage(byte[] imgBuffer, Stream ostm, ProcessImageSettings s)
        {
            if (imgBuffer == null)
            {
                throw new ArgumentNullException(nameof(imgBuffer));
            }
            if (ostm == null)
            {
                throw new ArgumentNullException(nameof(ostm));
            }
            if (!ostm.CanSeek || !ostm.CanWrite)
            {
                throw new ArgumentException("Output Stream must allow Seek and Write", nameof(ostm));
            }

            using (var ctx = new WicProcessingContext(s))
                using (var dec = new WicDecoder(imgBuffer, ctx))
                    processImage(dec, ctx, ostm);
        }
예제 #24
0
        public WicFrameReader(WicDecoder dec, WicProcessingContext ctx) : base(ctx)
        {
            Frame  = AddRef(dec.Decoder.GetFrame((uint)ctx.Settings.FrameIndex));
            Source = Frame;

            if (ctx.ContainerFormat == Consts.GUID_ContainerFormatRaw && ctx.Settings.FrameIndex == 0 && dec.Decoder.TryGetPreview(out var preview))
            {
                Source = AddRef(preview);
            }

            ctx.PixelFormat = PixelFormat.Cache[Source.GetPixelFormat()];
            Source.GetSize(out ctx.Width, out ctx.Height);
            Source.GetResolution(out ctx.DpiX, out ctx.DpiY);

            if (Source is IWICPlanarBitmapSourceTransform ptrans)
            {
                uint pw = ctx.Width, ph = ctx.Height;
                var  pdesc = new WICBitmapPlaneDescription[2];
                var  pfmts = new Guid[] { Consts.GUID_WICPixelFormat8bppY, Consts.GUID_WICPixelFormat16bppCbCr };
                ctx.SupportsPlanar = ptrans.DoesSupportTransform(ref pw, ref ph, WICBitmapTransformOptions.WICBitmapTransformRotate0, WICPlanarOptions.WICPlanarOptionsDefault, pfmts, pdesc, 2);
            }
        }
예제 #25
0
        public ImageFileInfo(Stream istm, DateTime lastModified)
        {
            if (istm == null)
            {
                throw new ArgumentNullException(nameof(istm));
            }
            if (!istm.CanSeek || !istm.CanRead)
            {
                throw new ArgumentException("Input Stream must allow Seek and Read", nameof(istm));
            }
            if (istm.Length <= 0 || istm.Position >= istm.Length)
            {
                throw new ArgumentException("Input Stream is empty or positioned at its end", nameof(istm));
            }

            using (var ctx = new WicProcessingContext(new ProcessImageSettings()))
                using (var dec = new WicDecoder(istm, ctx))
                    loadInfo(dec, ctx);

            FileSize = istm.Length;
            FileDate = lastModified;
        }
예제 #26
0
        private static void processImage(WicDecoder dec, WicProcessingContext ctx, Stream ostm)
        {
            using (var frm = new WicFrameReader(dec, ctx))
                using (var met = new WicMetadataReader(frm))
                {
                    if (!ctx.Settings.Normalized)
                    {
                        ctx.Settings.Fixup((int)ctx.Width, (int)ctx.Height, ctx.IsRotated90);
                    }

                    bool mod1   = (!ctx.IsSubsampled || ctx.Settings.HybridScaleRatio > 1d || (ctx.Settings.Crop.Width % 2 == 0 && ctx.Settings.Crop.Height % 2 == 0) || (ctx.Settings.Crop.Width == ctx.Width && ctx.Settings.Crop.Height == ctx.Height));
                    bool planar = ctx.SupportsPlanar && mod1;
                    if (planar && ctx.Settings.HybridMode != HybridScaleMode.Off)
                    {
                        MagicPlanarImageProcessor.ProcessImage(met, ctx, ostm);
                        return;
                    }

                    using (var qsc = new WicNativeScaler(met))
                        using (var rot = new WicExifRotator(qsc))
                            using (var cac = new WicConditionalCache(rot))
                                using (var crp = new WicCropper(cac))
                                    using (var pix = new WicPixelFormatConverter(crp))
                                        using (var cmy = new WicCmykConverter(pix))
                                            using (var res = new WicScaler(cmy, true))
                                                using (var lll = new WicGammaExpand(res))
                                                    using (var mmm = new WicHighQualityScaler(lll))
                                                        using (var mat = new WicMatteTransform(mmm))
                                                            using (var ggg = new WicGammaCompress(mat))
                                                                using (var csc = new WicColorspaceConverter(ggg))
                                                                    using (var sss = new WicUnsharpMask(csc))
                                                                        using (var dit = new WicPaletizer(sss, 256))
                                                                            using (var enc = new WicEncoder(ostm.AsIStream(), ctx))
                                                                                enc.WriteSource(dit);
                }
        }
예제 #27
0
 public static void ProcessImage(byte[] imgBuffer, Stream ostm, ProcessImageSettings s)
 {
     using (var ctx = new WicProcessingContext(s))
         using (var dec = new WicDecoder(imgBuffer, ctx))
             processImage(dec, ctx, ostm);
 }
예제 #28
0
 public static void ProcessImage(string imgPath, Stream ostm, ProcessImageSettings s)
 {
     using (var ctx = new WicProcessingContext(s))
         using (var dec = new WicDecoder(imgPath, ctx))
             processImage(dec, ctx, ostm);
 }