Beispiel #1
0
        public static ComPtr <IDiaSymbol> GetSymbol(this IDiaSymbol symbol, SymTagEnum symTag, string name, Predicate <IDiaSymbol> filter = null)
        {
            ComPtr <IDiaSymbol> result = new ComPtr <IDiaSymbol>();

            symbol.findChildren(symTag, name, 1, out IDiaEnumSymbols enumSymbols);
            using (ComPtr.Create(enumSymbols))
            {
                int n = enumSymbols.count;
                if (n == 0)
                {
                    Debug.Fail("Symbol '" + name + "' was not found.");
                    throw new ArgumentException();
                }

                try
                {
                    for (int i = 0; i < n; ++i)
                    {
                        using (ComPtr <T> item = ComPtr.Create(enumSymbols.Item((uint)i)))
                        {
                            if (filter == null || filter(item.Object))
                            {
                                if (result.Object == null)
                                {
                                    result = item.Detach();
                                }
                                else
                                {
                                    Debug.Fail("Found more than one symbol named '" + name + "' and matching the filter.");
                                    throw new ArgumentException();
                                }
                            }
                        }
                    }
                }
                catch
                {
                    result.Dispose();
                    throw;
                }
            }

            return(result);
        }
Beispiel #2
0
        public WicImageFrame(WicImageContainer decoder, uint index)
        {
            Container = decoder;

            using var frame = default(ComPtr <IWICBitmapFrameDecode>);
            HRESULT.Check(decoder.WicDecoder->GetFrame(index, frame.GetAddressOf()));

            using var source = new ComPtr <IWICBitmapSource>((IWICBitmapSource *)frame.Get());

            double dpix, dpiy;

            HRESULT.Check(frame.Get()->GetResolution(&dpix, &dpiy));
            (DpiX, DpiY) = (dpix, dpiy);

            uint frameWidth, frameHeight;

            HRESULT.Check(frame.Get()->GetSize(&frameWidth, &frameHeight));

            using var metareader = default(ComPtr <IWICMetadataQueryReader>);
            if (SUCCEEDED(frame.Get()->GetMetadataQueryReader(metareader.GetAddressOf())))
            {
                string orientationPath =
                    MagicImageProcessor.EnableXmpOrientation ? Wic.Metadata.OrientationWindowsPolicy :
                    Container.ContainerFormat == FileFormat.Jpeg ? Wic.Metadata.OrientationJpeg :
                    Wic.Metadata.OrientationExif;

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

            using var preview = default(ComPtr <IWICBitmapSource>);
            if (decoder.IsRawContainer && index == 0 && SUCCEEDED(decoder.WicDecoder->GetPreview(preview.GetAddressOf())))
            {
                uint pw, ph;
                HRESULT.Check(preview.Get()->GetSize(&pw, &ph));

                if (pw == frameWidth && ph == frameHeight)
                {
                    source.Attach(preview.Detach());
                }
            }

            using var transform = default(ComPtr <IWICBitmapSourceTransform>);
            if (SUCCEEDED(source.Get()->QueryInterface(__uuidof <IWICBitmapSourceTransform>(), (void **)transform.GetAddressOf())))
            {
                uint tw = 1, th = 1;
                HRESULT.Check(transform.Get()->GetClosestSize(&tw, &th));

                SupportsNativeScale = tw < frameWidth || th < frameHeight;
            }

            using var ptransform = default(ComPtr <IWICPlanarBitmapSourceTransform>);
            if (SUCCEEDED(source.Get()->QueryInterface(__uuidof <IWICPlanarBitmapSourceTransform>(), (void **)ptransform.GetAddressOf())))
            {
                var fmts = WicTransforms.PlanarPixelFormats;
                var desc = stackalloc WICBitmapPlaneDescription[fmts.Length];
                fixed(Guid *pfmt = fmts)
                {
                    uint tw = frameWidth, th = frameHeight, st = 0;

                    HRESULT.Check(ptransform.Get()->DoesSupportTransform(
                                      &tw, &th,
                                      WICBitmapTransformOptions.WICBitmapTransformRotate0, WICPlanarOptions.WICPlanarOptionsDefault,
                                      pfmt, desc, (uint)fmts.Length, (int *)&st
                                      ));

                    SupportsPlanarProcessing = st != 0;
                }

                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;
            }

            var guid = default(Guid);

            HRESULT.Check(source.Get()->GetPixelFormat(&guid));
            if (PixelFormat.FromGuid(guid).NumericRepresentation == PixelNumericRepresentation.Indexed)
            {
                var newFormat = PixelFormat.Bgr24Bpp;
                if (Container.ContainerFormat == FileFormat.Gif && Container.FrameCount > 1)
                {
                    newFormat = PixelFormat.Bgra32Bpp;
                }
                else
                {
                    using var pal = default(ComPtr <IWICPalette>);
                    HRESULT.Check(Wic.Factory->CreatePalette(pal.GetAddressOf()));
                    HRESULT.Check(source.Get()->CopyPalette(pal));

                    int bval;
                    if (SUCCEEDED(pal.Get()->HasAlpha(&bval)) && bval != 0)
                    {
                        newFormat = PixelFormat.Bgra32Bpp;
                    }
                    else if ((SUCCEEDED(pal.Get()->IsGrayscale(&bval)) && bval != 0) || (SUCCEEDED(pal.Get()->IsBlackWhite(&bval)) && bval != 0))
                    {
                        newFormat = PixelFormat.Grey8Bpp;
                    }
                }

                var nfmt = newFormat.FormatGuid;
                using var conv = default(ComPtr <IWICFormatConverter>);
                HRESULT.Check(Wic.Factory->CreateFormatConverter(conv.GetAddressOf()));
                HRESULT.Check(conv.Get()->Initialize(source, &nfmt, WICBitmapDitherType.WICBitmapDitherTypeNone, null, 0.0, WICBitmapPaletteType.WICBitmapPaletteTypeCustom));

                source.Attach((IWICBitmapSource *)conv.Detach());
            }

            WicFrame  = frame.Detach();
            WicSource = source.Detach();
        }