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