Beispiel #1
0
        public void AddFileCodeModel(FileCodeModel fileCodeModel)
        {
            var handle = new ComHandle<EnvDTE80.FileCodeModel2, FileCodeModel>(fileCodeModel);
            var globalNodeKeys = fileCodeModel.GetCurrentNodeKeys();

            _nodeKeysMap.Add(handle, globalNodeKeys);
        }
 private PartialTypeCollection(
     CodeModelState state,
     FileCodeModel fileCodeModel,
     AbstractCodeType parent)
     : base(state, parent)
 {
     _fileCodeModelHandle = new ComHandle<EnvDTE.FileCodeModel, FileCodeModel>(fileCodeModel);
 }
        public bool TryGetCachedFileCodeModel(string fileName, out ComHandle<EnvDTE80.FileCodeModel2, FileCodeModel> fileCodeModelHandle)
        {
            var handle = GetCodeModelCache()?.GetComHandleForFileCodeModel(fileName);

            fileCodeModelHandle = handle != null
                ? handle.Value
                : default(ComHandle<EnvDTE80.FileCodeModel2, FileCodeModel>);

            return handle != null;
        }
Beispiel #4
0
        private TypeCollection(
            CodeModelState state,
            object parent,
            FileCodeModel fileCodeModel,
            SyntaxNodeKey nodeKey)
            : base(state, parent)
        {
            Debug.Assert(fileCodeModel != null);

            _fileCodeModel = new ComHandle<EnvDTE.FileCodeModel, FileCodeModel>(fileCodeModel);
            _nodeKey = nodeKey;
        }
Beispiel #5
0
 public NodeSnapshot(
     CodeModelState state,
     ComHandle<EnvDTE.FileCodeModel, FileCodeModel> fileCodeModel,
     SyntaxNode parentNode,
     AbstractCodeElement parentElement,
     ImmutableArray<SyntaxNode> nodes)
 {
     _state = state;
     _fileCodeModel = fileCodeModel;
     _parentNode = parentNode;
     _parentElement = parentElement;
     _nodes = nodes;
 }
Beispiel #6
0
        private BasesCollection(
            CodeModelState state,
            object parent,
            FileCodeModel fileCodeModel,
            SyntaxNodeKey nodeKey,
            bool interfaces)
            : base(state, parent)
        {
            Debug.Assert(fileCodeModel != null);

            _fileCodeModel = new ComHandle<EnvDTE.FileCodeModel, FileCodeModel>(fileCodeModel);
            _nodeKey = nodeKey;
            _interfaces = interfaces;
        }
Beispiel #7
0
        private FileCodeModel(
            CodeModelState state,
            object parent,
            DocumentId documentId,
            ITextManagerAdapter textManagerAdapter)
            : base(state)
        {
            Debug.Assert(documentId != null);
            Debug.Assert(textManagerAdapter != null);

            _parentHandle      = new ComHandle <object, object>(parent);
            _documentId        = documentId;
            TextManagerAdapter = textManagerAdapter;

            _codeElementTable = new CleanableWeakComHandleTable <SyntaxNodeKey, EnvDTE.CodeElement>(state.ThreadingContext);

            _batchMode      = false;
            _batchDocument  = null;
            _lastSyntaxTree = GetSyntaxTree();
        }
Beispiel #8
0
        private FileCodeModel(
            CodeModelState state,
            object?parent,
            DocumentId documentId,
            bool isSourceGeneratedOutput,
            ITextManagerAdapter textManagerAdapter)
            : base(state)
        {
            RoslynDebug.AssertNotNull(documentId);
            RoslynDebug.AssertNotNull(textManagerAdapter);

            _parentHandle            = new ComHandle <object?, object?>(parent);
            _documentId              = documentId;
            _isSourceGeneratedOutput = isSourceGeneratedOutput;
            TextManagerAdapter       = textManagerAdapter;

            _codeElementTable = new CleanableWeakComHandleTable <SyntaxNodeKey, EnvDTE.CodeElement>(state.ThreadingContext);

            _batchMode      = false;
            _batchDocument  = null;
            _lastSyntaxTree = GetSyntaxTree();
        }
Beispiel #9
0
        private void writeFrame(BufferFrame src)
        {
            var  curFormat = ctx.Source.Format;
            var  newFormat = PixelFormat.Indexed8Bpp;
            bool alpha     = src.Trans || src.Disposal != GifDisposalMethod.RestoreBackground;

            using var pal = ComHandle.Wrap(Wic.Factory.CreatePalette());
            pal.ComObject.InitializeFromBitmap(wicSource, 256u, alpha);
            ctx.WicContext.DestPalette = pal.ComObject;

            using var conv = ComHandle.Wrap(Wic.Factory.CreateFormatConverter());
            conv.ComObject.Initialize(wicSource, newFormat.FormatGuid, WICBitmapDitherType.WICBitmapDitherTypeErrorDiffusion, pal.ComObject, 25.0, WICBitmapPaletteType.WICBitmapPaletteTypeCustom);
            ctx.Source = conv.ComObject.AsPixelSource($"{nameof(IWICFormatConverter)}: {curFormat.Name}->{newFormat.Name}", false);

            using var frm = new WicImageEncoderFrame(ctx, encoder, src.Area);

            using var frmmeta = ComHandle.Wrap(frm.WicEncoderFrame.GetMetadataQueryWriter());
            var fm = frmmeta.ComObject;

            fm.SetMetadataByName(Wic.Metadata.Gif.FrameDisposal, new PropVariant((byte)src.Disposal));
            fm.SetMetadataByName(Wic.Metadata.Gif.FrameDelay, new PropVariant((ushort)src.Delay));

            if (src.Area.X != 0)
            {
                fm.SetMetadataByName(Wic.Metadata.Gif.FrameLeft, new PropVariant((ushort)src.Area.X));
            }
            if (src.Area.Y != 0)
            {
                fm.SetMetadataByName(Wic.Metadata.Gif.FrameTop, new PropVariant((ushort)src.Area.Y));
            }

            if (alpha)
            {
                fm.SetMetadataByName(Wic.Metadata.Gif.TransparencyFlag, new PropVariant(true));
                fm.SetMetadataByName(Wic.Metadata.Gif.TransparentColorIndex, new PropVariant((byte)(pal.ComObject.GetColorCount() - 1)));
            }

            frm.WriteSource(ctx, src.Area);
        }
Beispiel #10
0
        public WicGifContainer(IWICBitmapDecoder dec, WicPipelineContext ctx) : base(dec, ctx, FileFormat.Gif)
        {
            using var wicmeta = ComHandle.Wrap(dec.GetMetadataQueryReader());
            var meta = wicmeta.ComObject;

            ScreenWidth  = meta.GetValueOrDefault <ushort>(Wic.Metadata.Gif.LogicalScreenWidth);
            ScreenHeight = meta.GetValueOrDefault <ushort>(Wic.Metadata.Gif.LogicalScreenHeight);

            if (meta.GetValueOrDefault <bool>(Wic.Metadata.Gif.GlobalPaletteFlag))
            {
                using var wicpal = ComHandle.Wrap(Wic.Factory.CreatePalette());
                var pal = wicpal.ComObject;
                dec.CopyPalette(pal);

                uint pcc = pal.GetColorCount();
                uint idx = meta.GetValueOrDefault <byte>(Wic.Metadata.Gif.BackgroundColorIndex);
                if (idx < pcc)
                {
                    var buff = ArrayPool <uint> .Shared.Rent((int)pcc);

                    pal.GetColors(pcc, buff);
                    BackgroundColor = buff[idx];

                    ArrayPool <uint> .Shared.Return(buff);
                }
            }

            var appext = meta.GetValueOrDefault <byte[]>(Wic.Metadata.Gif.AppExtension).AsSpan();

            if (appext.Length == 11 && netscape2_0.SequenceEqual(appext) || animexts1_0.SequenceEqual(appext))
            {
                var appdata = meta.GetValueOrDefault <byte[]>(Wic.Metadata.Gif.AppExtensionData).AsSpan();
                if (appdata.Length >= 4 && appdata[0] >= 3 && appdata[1] == 1)
                {
                    LoopCount = BinaryPrimitives.ReadUInt16LittleEndian(appdata.Slice(2));
                }
            }
        }
Beispiel #11
0
        public void WriteGlobalMetadata()
        {
            var cnt = ctx.ImageContainer as WicGifContainer ?? throw new InvalidOperationException("Source must be a GIF");

            using var decmeta = ComHandle.Wrap(cnt.WicDecoder.GetMetadataQueryReader());
            using var encmeta = ComHandle.Wrap(encoder.WicEncoder.GetMetadataQueryWriter());
            var dm = decmeta.ComObject;
            var em = encmeta.ComObject;

            if (dm.TryGetMetadataByName(Wic.Metadata.Gif.AppExtension, out var appext))
            {
                em.SetMetadataByName(Wic.Metadata.Gif.AppExtension, appext);
            }
            if (dm.TryGetMetadataByName(Wic.Metadata.Gif.AppExtensionData, out var appdata))
            {
                em.SetMetadataByName(Wic.Metadata.Gif.AppExtensionData, appdata);
            }
            if (dm.TryGetMetadataByName(Wic.Metadata.Gif.PixelAspectRatio, out var aspect))
            {
                em.SetMetadataByName(Wic.Metadata.Gif.PixelAspectRatio, aspect);
            }

            // TODO WIC ignores these and sets the logical screen descriptor dimensions from the first frame
            //em.SetMetadataByName(Wic.Metadata.Gif.LogicalScreenWidth, new PropVariant((ushort)ctx.Source.Width));
            //em.SetMetadataByName(Wic.Metadata.Gif.LogicalScreenHeight, new PropVariant((ushort)ctx.Source.Height));

            if (dm.GetValueOrDefault <bool>(Wic.Metadata.Gif.GlobalPaletteFlag))
            {
                using var pal = ComHandle.Wrap(Wic.Factory.CreatePalette());
                cnt.WicDecoder.CopyPalette(pal.ComObject);
                encoder.WicEncoder.SetPalette(pal.ComObject);

                if (dm.TryGetMetadataByName(Wic.Metadata.Gif.PixelAspectRatio, out var bgidx))
                {
                    em.SetMetadataByName(Wic.Metadata.Gif.BackgroundColorIndex, bgidx);
                }
            }
        }
Beispiel #12
0
        public WicImageEncoderFrame(PipelineContext ctx, WicImageEncoder encoder, PixelArea area = default)
        {
            var fmt       = ctx.Settings.SaveFormat;
            var encArea   = area.IsEmpty ? ctx.Source.Area : area;
            var colorMode = ctx.Settings.ColorProfileMode;

            var bag = default(IPropertyBag2);

            encoder.WicEncoder.CreateNewFrame(out var frame, ref bag);
            encoderFrame = ComHandle.Wrap(frame);

            using (var cbag = ComHandle.Wrap(bag))
            {
                if (fmt == FileFormat.Jpeg)
                {
                    bag.Write("ImageQuality", ctx.Settings.JpegQuality / 100f);
                }

                if (fmt == FileFormat.Jpeg && ctx.Settings.JpegSubsampleMode != ChromaSubsampleMode.Default)
                {
                    bag.Write("JpegYCrCbSubsampling", (byte)ctx.Settings.JpegSubsampleMode);
                }

                if (fmt == FileFormat.Tiff)
                {
                    bag.Write("TiffCompressionMethod", (byte)WICTiffCompressionOption.WICTiffCompressionNone);
                }

                if (fmt == FileFormat.Bmp && ctx.Source.Format.AlphaRepresentation != PixelAlphaRepresentation.None)
                {
                    bag.Write("EnableV5Header32bppBGRA", true);
                }

                frame.Initialize(bag);
            }

            frame.SetSize((uint)encArea.Width, (uint)encArea.Height);
            frame.SetResolution(ctx.Settings.DpiX > 0d ? ctx.Settings.DpiX : ctx.ImageFrame.DpiX, ctx.Settings.DpiY > 0d ? ctx.Settings.DpiY : ctx.ImageFrame.DpiY);

            bool copySourceMetadata = ctx.ImageFrame is WicImageFrame srcFrame && srcFrame.WicMetadataReader is not null && ctx.Settings.MetadataNames != Enumerable.Empty <string>();
            bool writeOrientation   = ctx.Settings.OrientationMode == OrientationMode.Preserve && ctx.ImageFrame.ExifOrientation != Orientation.Normal;
            bool writeColorContext  = colorMode == ColorProfileMode.NormalizeAndEmbed || colorMode == ColorProfileMode.Preserve || (colorMode == ColorProfileMode.Normalize && ctx.DestColorProfile != ColorProfile.sRGB && ctx.DestColorProfile != ColorProfile.sGrey);

            if ((copySourceMetadata || writeOrientation) && frame.TryGetMetadataQueryWriter(out var metawriter))
            {
                using var cmeta = ComHandle.Wrap(metawriter);
                if (copySourceMetadata)
                {
                    var wicFrame = (WicImageFrame)ctx.ImageFrame;
                    foreach (string prop in ctx.Settings.MetadataNames)
                    {
                        if (wicFrame.WicMetadataReader !.TryGetMetadataByName(prop, out var pvar) && pvar.Value is not null)
                        {
                            metawriter.TrySetMetadataByName(prop, pvar);
                        }
                    }
                }

                if (writeOrientation)
                {
                    string orientationPath = ctx.Settings.SaveFormat == FileFormat.Jpeg ? Wic.Metadata.OrientationJpeg : Wic.Metadata.OrientationExif;
                    metawriter.TrySetMetadataByName(orientationPath, new PropVariant((ushort)ctx.ImageFrame.ExifOrientation));
                }
            }

            if (writeColorContext)
            {
                Debug.Assert(ctx.WicContext.DestColorContext is not null || ctx.DestColorProfile is not null);

                var cc = ctx.WicContext.DestColorContext;
                if (ctx.DestColorProfile == ColorProfile.sRGB)
                {
                    cc = WicColorProfile.SrgbCompact.Value.WicColorContext;
                }
                else if (ctx.DestColorProfile == ColorProfile.sGrey)
                {
                    cc = WicColorProfile.GreyCompact.Value.WicColorContext;
                }
                else if (ctx.DestColorProfile == ColorProfile.AdobeRgb)
                {
                    cc = WicColorProfile.AdobeRgb.Value.WicColorContext;
                }
                else if (ctx.DestColorProfile == ColorProfile.DisplayP3)
                {
                    cc = WicColorProfile.DisplayP3Compact.Value.WicColorContext;
                }

                frame.TrySetColorContexts(cc ?? ctx.WicContext.AddRef(WicColorProfile.CreateContextFromProfile(ctx.DestColorProfile !.ProfileBytes)));
            }
        }
Beispiel #13
0
 public WicImageEncoder(FileFormat format, IStream stm)
 {
     encoder = ComHandle.Wrap(Wic.Factory.CreateEncoder(formatMap.GetValueOrDefault(format, Consts.GUID_ContainerFormatPng), null));
     encoder.ComObject.Initialize(stm, WICBitmapEncoderCacheOption.WICBitmapEncoderNoCache);
 }
Beispiel #14
0
        private static ReadOnlyDictionary <Guid, PixelFormat> getFormatCache()
        {
            var dic = new Dictionary <Guid, PixelFormat> {
                [Grey16BppUQ15.FormatGuid]          = Grey16BppUQ15,
                [Grey16BppLinearUQ15.FormatGuid]    = Grey16BppLinearUQ15,
                [Grey32BppFloat.FormatGuid]         = Grey32BppFloat,
                [Grey32BppLinearFloat.FormatGuid]   = Grey32BppLinearFloat,
                [Bgr48BppLinearUQ15.FormatGuid]     = Bgr48BppLinearUQ15,
                [Bgr96BppFloat.FormatGuid]          = Bgr96BppFloat,
                [Bgr96BppLinearFloat.FormatGuid]    = Bgr96BppLinearFloat,
                [Pbgra64BppLinearUQ15.FormatGuid]   = Pbgra64BppLinearUQ15,
                [Pbgra128BppFloat.FormatGuid]       = Pbgra128BppFloat,
                [Pbgra128BppLinearFloat.FormatGuid] = Pbgra128BppLinearFloat,
                [Y16BppLinearUQ15.FormatGuid]       = Y16BppLinearUQ15,
                [Y32BppFloat.FormatGuid]            = Y32BppFloat,
                [Y32BppLinearFloat.FormatGuid]      = Y32BppLinearFloat,
                [CbCr64BppFloat.FormatGuid]         = CbCr64BppFloat,
                [Cb32BppFloat.FormatGuid]           = Cb32BppFloat,
                [Cr32BppFloat.FormatGuid]           = Cr32BppFloat,
                [Bgrx128BppFloat.FormatGuid]        = Bgrx128BppFloat,
                [Bgrx128BppLinearFloat.FormatGuid]  = Bgrx128BppLinearFloat
            };

            uint count   = 10u;
            var  formats = new object[count];

            using var cenum = new ComHandle <IEnumUnknown>(Wic.Factory.CreateComponentEnumerator(WICComponentType.WICPixelFormat, WICComponentEnumerateOptions.WICComponentEnumerateDefault));

            do
            {
                count = cenum.ComObject.Next(count, formats);
                for (int i = 0; i < count; i++)
                {
                    using var pixh = new ComHandle <IWICPixelFormatInfo2>(formats[i]);
                    var pix = pixh.ComObject;

                    uint cch = pix.GetFriendlyName(0, null);
                    var  sbn = new StringBuilder((int)cch);
                    pix.GetFriendlyName(cch, sbn);
                    string pfn = sbn.ToString();

                    var numericRep = (PixelNumericRepresentation)pix.GetNumericRepresentation();
                    var colorRep   =
                        pfn.Contains("BGR") ? PixelColorRepresentation.Bgr :
                        pfn.Contains("RGB") ? PixelColorRepresentation.Rgb :
                        pfn.Contains("CMYK") ? PixelColorRepresentation.Cmyk :
                        pfn.Contains("Gray") || pfn.EndsWith(" Y") ? PixelColorRepresentation.Grey :
                        PixelColorRepresentation.Unspecified;
                    var valEncoding = colorRep == PixelColorRepresentation.Grey || colorRep == PixelColorRepresentation.Bgr || colorRep == PixelColorRepresentation.Rgb ?
                                      numericRep == PixelNumericRepresentation.Fixed || numericRep == PixelNumericRepresentation.Float ? PixelValueEncoding.scRgb :
                                      PixelValueEncoding.Companded :
                                      PixelValueEncoding.Unspecified;

                    var fmt = new PixelFormat(
                        guid: pix.GetFormatGUID(),
                        name: pfn,
                        bpp: (int)pix.GetBitsPerPixel(),
                        channels: (int)pix.GetChannelCount(),
                        numericRepresentation: numericRep,
                        colorRepresentation: colorRep,
                        alphaRepresentation: pfn.Contains("pBGRA") || pfn.Contains("pRGBA") ? PixelAlphaRepresentation.Associated :
                        pix.SupportsTransparency() ? PixelAlphaRepresentation.Unassociated :
                        PixelAlphaRepresentation.None,
                        encoding: valEncoding,
                        isWic: true
                        );

                    dic.Add(fmt.FormatGuid, fmt);
                }
            } while (count > 0);

            return(new ReadOnlyDictionary <Guid, PixelFormat>(dic));
        }
 public CacheEntry(ComHandle <EnvDTE80.FileCodeModel2, FileCodeModel> handle)
 {
     _fileCodeModelWeakComHandle = new WeakComHandle <EnvDTE80.FileCodeModel2, FileCodeModel>(handle);
 }
 public CacheEntry(ComHandle<EnvDTE80.FileCodeModel2, FileCodeModel> handle)
 {
     _fileCodeModelWeakComHandle = new WeakComHandle<EnvDTE80.FileCodeModel2, FileCodeModel>(handle);
 }
Beispiel #17
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;
            }
        }
Beispiel #18
0
        unsafe public void WriteAnimatedGif(PipelineContext ctx)
        {
            var cnt = ctx.ImageContainer as WicGifContainer ?? throw new NotSupportedException("Source must be a GIF");

            using (var decmeta = ComHandle.Wrap(cnt.WicDecoder.GetMetadataQueryReader()))
                using (var encmeta = ComHandle.Wrap(WicEncoder.GetMetadataQueryWriter()))
                {
                    if (decmeta.ComObject.TryGetMetadataByName(Wic.Metadata.Gif.AppExtension, out var appext))
                    {
                        encmeta.ComObject.SetMetadataByName(Wic.Metadata.Gif.AppExtension, appext);
                    }
                    if (decmeta.ComObject.TryGetMetadataByName(Wic.Metadata.Gif.AppExtensionData, out var appdata))
                    {
                        encmeta.ComObject.SetMetadataByName(Wic.Metadata.Gif.AppExtensionData, appdata);
                    }
                    if (decmeta.ComObject.TryGetMetadataByName(Wic.Metadata.Gif.PixelAspectRatio, out var aspect))
                    {
                        encmeta.ComObject.SetMetadataByName(Wic.Metadata.Gif.PixelAspectRatio, aspect);
                    }
                }

            using var buffer = new FrameBufferSource(ctx.Source.Width, ctx.Source.Height, ctx.Source.Format);
            var bspan      = buffer.Span;
            var lastSource = ctx.Source;
            var wicBuffer  = buffer.AsIWICBitmapSource();

            var anictx = cnt.AnimationContext ??= new GifAnimationContext();

            for (int i = 0; i < ctx.ImageContainer.FrameCount; i++)
            {
                if (i > 0)
                {
                    ctx.Settings.FrameIndex = i;

                    ctx.ImageFrame.Dispose();
                    ctx.ImageFrame = ctx.ImageContainer.GetFrame(ctx.Settings.FrameIndex);

                    if (ctx.ImageFrame is WicImageFrame wicFrame)
                    {
                        ctx.Source = wicFrame.WicSource.AsPixelSource(nameof(IWICBitmapFrameDecode), true);
                    }
                    else
                    {
                        ctx.Source = ctx.ImageFrame.PixelSource.AsPixelSource();
                    }

                    MagicTransforms.AddGifFrameBuffer(ctx, false);

                    if (lastSource is ChainedPixelSource chain)
                    {
                        chain.ReInit(ctx.Source);
                        ctx.Source = chain;
                    }
                }

                fixed(byte *pbuff = bspan)
                {
                    ctx.Source.CopyPixels(ctx.Source.Area, buffer.Stride, bspan.Length, (IntPtr)pbuff);

                    var  curFormat = ctx.Source.Format;
                    var  newFormat = PixelFormat.Indexed8Bpp;
                    bool alpha     = curFormat.AlphaRepresentation != PixelAlphaRepresentation.None;

                    using var pal = ComHandle.Wrap(Wic.Factory.CreatePalette());
                    pal.ComObject.InitializeFromBitmap(wicBuffer, 256u, alpha);
                    ctx.WicContext.DestPalette = pal.ComObject;

                    using var conv = ComHandle.Wrap(Wic.Factory.CreateFormatConverter());
                    conv.ComObject.Initialize(wicBuffer, newFormat.FormatGuid, WICBitmapDitherType.WICBitmapDitherTypeErrorDiffusion, pal.ComObject, 10.0, WICBitmapPaletteType.WICBitmapPaletteTypeCustom);
                    ctx.Source = conv.ComObject.AsPixelSource($"{nameof(IWICFormatConverter)}: {curFormat.Name}->{newFormat.Name}", false);

                    using var frm = new WicImageEncoderFrame(ctx, this);

                    var srcmeta = ((WicImageFrame)ctx.ImageFrame).WicMetadataReader !;

                    using (var frmmeta = ComHandle.Wrap(frm.WicEncoderFrame.GetMetadataQueryWriter()))
                    {
                        var disp = srcmeta.TryGetMetadataByName(Wic.Metadata.Gif.FrameDisposal, out var fdisp) && (byte)fdisp.Value ! == (byte)GifDisposalMethod.RestoreBackground ? GifDisposalMethod.RestoreBackground : GifDisposalMethod.Undefined;

                        frmmeta.ComObject.SetMetadataByName(Wic.Metadata.Gif.FrameDisposal, new PropVariant((byte)disp));
                        if (srcmeta.TryGetMetadataByName(Wic.Metadata.Gif.FrameDelay, out var delay))
                        {
                            frmmeta.ComObject.SetMetadataByName(Wic.Metadata.Gif.FrameDelay, delay);
                        }
                        if (alpha)
                        {
                            frmmeta.ComObject.SetMetadataByName(Wic.Metadata.Gif.TransparencyFlag, new PropVariant(true));
                            frmmeta.ComObject.SetMetadataByName(Wic.Metadata.Gif.TransparentColorIndex, new PropVariant((byte)(pal.ComObject.GetColorCount() - 1)));
                        }
                    }

                    frm.WriteSource(ctx);
                }
            }
        }
Beispiel #19
0
        static PixelFormat()
        {
            var dic = new Dictionary <Guid, PixelFormat> {
                [Grey16BppUQ15.FormatGuid]          = Grey16BppUQ15,
                [Grey16BppLinearUQ15.FormatGuid]    = Grey16BppLinearUQ15,
                [Grey32BppFloat.FormatGuid]         = Grey32BppFloat,
                [Grey32BppLinearFloat.FormatGuid]   = Grey32BppLinearFloat,
                [Bgr48BppLinearUQ15.FormatGuid]     = Bgr48BppLinearUQ15,
                [Bgr96BppFloat.FormatGuid]          = Bgr96BppFloat,
                [Bgr96BppLinearFloat.FormatGuid]    = Bgr96BppLinearFloat,
                [Pbgra64BppLinearUQ15.FormatGuid]   = Pbgra64BppLinearUQ15,
                [Pbgra128BppFloat.FormatGuid]       = Pbgra128BppFloat,
                [Pbgra128BppLinearFloat.FormatGuid] = Pbgra128BppLinearFloat,
                [Y16BppLinearUQ15.FormatGuid]       = Y16BppLinearUQ15,
                [Y32BppFloat.FormatGuid]            = Y32BppFloat,
                [Y32BppLinearFloat.FormatGuid]      = Y32BppLinearFloat,
                [CbCr64BppFloat.FormatGuid]         = CbCr64BppFloat,
                [Bgrx128BppFloat.FormatGuid]        = Bgrx128BppFloat,
                [Bgrx128BppLinearFloat.FormatGuid]  = Bgrx128BppLinearFloat
            };

            uint count   = 10u;
            var  formats = new object[count];

            using (var cenum = new ComHandle <IEnumUnknown>(Wic.Factory.CreateComponentEnumerator(WICComponentType.WICPixelFormat, WICComponentEnumerateOptions.WICComponentEnumerateDefault)))
                do
                {
                    count = cenum.ComObject.Next(count, formats);
                    for (int i = 0; i < count; i++)
                    {
                        using (var pixh = new ComHandle <IWICPixelFormatInfo2>(formats[i]))
                        {
                            var  pix = pixh.ComObject;
                            uint cch = pix.GetFriendlyName(0, null);
                            var  sbn = new StringBuilder((int)cch);
                            pix.GetFriendlyName(cch, sbn);
                            string pfn = sbn.ToString();

                            var fmt = new PixelFormat {
                                FormatGuid            = pix.GetFormatGUID(),
                                Name                  = pfn,
                                IsWicNative           = true,
                                BitsPerPixel          = (int)pix.GetBitsPerPixel(),
                                ChannelCount          = (int)pix.GetChannelCount(),
                                NumericRepresentation = (PixelNumericRepresentation)pix.GetNumericRepresentation(),
                                ColorRepresentation   = pfn.Contains("BGR") ? PixelColorRepresentation.Bgr :
                                                        pfn.Contains("RGB") ? PixelColorRepresentation.Rgb :
                                                        pfn.Contains("CMYK") ? PixelColorRepresentation.Cmyk :
                                                        pfn.Contains("Gray") || pfn.EndsWith(" Y") ? PixelColorRepresentation.Grey :
                                                        PixelColorRepresentation.Unspecified,
                                AlphaRepresentation = pfn.Contains("pBGRA") || pfn.Contains("pRGBA") ? PixelAlphaRepresentation.Associated :
                                                      pix.SupportsTransparency() ? PixelAlphaRepresentation.Unassociated :
                                                      PixelAlphaRepresentation.None
                            };

                            if (fmt.ColorRepresentation == PixelColorRepresentation.Grey || fmt.ColorRepresentation == PixelColorRepresentation.Bgr || fmt.ColorRepresentation == PixelColorRepresentation.Rgb)
                            {
                                fmt.Colorspace = fmt.NumericRepresentation == PixelNumericRepresentation.Fixed || fmt.NumericRepresentation == PixelNumericRepresentation.Float ? PixelColorspace.scRgb : PixelColorspace.sRgb;
                            }

                            dic.Add(fmt.FormatGuid, fmt);
                        }
                    }
                } while (count > 0);

            Cache = new ReadOnlyDictionary <Guid, PixelFormat>(dic);
        }
Beispiel #20
0
 public ParentHandle(T parent)
 {
     _comHandle = new ComHandle <object, object>(parent);
 }
 public CacheEntry(ComHandle <EnvDTE80.FileCodeModel2, FileCodeModel> handle) =>
Beispiel #22
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);
                }
            }
        }