/// <summary> /// Construct a BitmapSource from an HICON. /// </summary> /// <param name="hicon"></param> /// <param name="sourceRect"></param> /// <param name="sizeOptions"></param> internal InteropBitmap(IntPtr hicon, Int32Rect sourceRect, BitmapSizeOptions sizeOptions) : base(true) // Use virtuals { SecurityHelper.DemandUnmanagedCode(); _bitmapInit.BeginInit(); using (FactoryMaker myFactory = new FactoryMaker()) { HRESULT.Check(UnsafeNativeMethods.WICImagingFactory.CreateBitmapFromHICON( myFactory.ImagingFactoryPtr, hicon, out _unmanagedSource)); Debug.Assert(_unmanagedSource != null && !_unmanagedSource.IsInvalid); } _unmanagedSource.CalculateSize(); _sourceRect = sourceRect; _sizeOptions = sizeOptions; _syncObject = _unmanagedSource; _bitmapInit.EndInit(); FinalizeCreation(); }
/// <summary> /// /// </summary> private void Init(Guid containerFormat, bool readOnly, bool fixedSize) { int hr = 0; IntPtr /* IWICMetadataQueryWriter */ queryWriter = IntPtr.Zero; using (FactoryMaker factoryMaker = new FactoryMaker()) { Guid vendorMicrosoft = new Guid(MILGuidData.GUID_VendorMicrosoft); // If it's a metadata format, create a Query Writer to wrap it. hr = UnsafeNativeMethods.WICImagingFactory.CreateQueryWriter( factoryMaker.ImagingFactoryPtr, ref containerFormat, ref vendorMicrosoft, out queryWriter ); } if (HRESULT.Succeeded(hr)) { _readOnly = readOnly; _fixedSize = fixedSize; _blockWriter = null; _metadataHandle = new SafeMILHandle(queryWriter); _syncObject = _metadataHandle; } else { InitializeFromBlockWriter(containerFormat, readOnly, fixedSize); } }
/// /// Create from WICBitmapSource /// private void InitFromWICSource( SafeMILHandle wicSource ) { _bitmapInit.BeginInit(); BitmapSourceSafeMILHandle bitmapSource = null; lock (_syncObject) { using (FactoryMaker factoryMaker = new FactoryMaker()) { HRESULT.Check(UnsafeNativeMethods.WICImagingFactory.CreateBitmapFromSource( factoryMaker.ImagingFactoryPtr, wicSource, WICBitmapCreateCacheOptions.WICBitmapCacheOnLoad, out bitmapSource)); } bitmapSource.CalculateSize(); } WicSourceHandle = bitmapSource; _isSourceCached = true; _bitmapInit.EndInit(); UpdateCachedSettings(); }
/// <summary> /// Construct a BitmapSource from an HBITMAP. /// </summary> /// <param name="hbitmap"></param> /// <param name="hpalette"></param> /// <param name="sourceRect"></param> /// <param name="sizeOptions"></param> /// <param name="alphaOptions"></param> internal InteropBitmap(IntPtr hbitmap, IntPtr hpalette, Int32Rect sourceRect, BitmapSizeOptions sizeOptions, WICBitmapAlphaChannelOption alphaOptions) : base(true) // Use virtuals { _bitmapInit.BeginInit(); using (FactoryMaker myFactory = new FactoryMaker()) { HRESULT.Check(UnsafeNativeMethods.WICImagingFactory.CreateBitmapFromHBITMAP( myFactory.ImagingFactoryPtr, hbitmap, hpalette, alphaOptions, out _unmanagedSource)); Debug.Assert(_unmanagedSource != null && !_unmanagedSource.IsInvalid); } _unmanagedSource.CalculateSize(); _sizeOptions = sizeOptions; _sourceRect = sourceRect; _syncObject = _unmanagedSource; _bitmapInit.EndInit(); FinalizeCreation(); }
public void should_create_orc_army() { IKingdomFactory kingdomFactory = FactoryMaker.Create(KingdomType.ORC); IArmy army = kingdomFactory.CreateArmy(); Assert.Equal("This is Orc army", army.Description); }
public void should_create_elven_king() { IKingdomFactory kingdomFactory = FactoryMaker.Create(KingdomType.ELF); IKing king = kingdomFactory.CreateKing(); Assert.Equal("This is Elven king", king.Description); }
public void should_create_elven_army() { IKingdomFactory kingdomFactory = FactoryMaker.Create(KingdomType.ELF); IArmy army = kingdomFactory.CreateArmy(); Assert.Equal("This is Elven army", army.Description); }
public void should_create_elven_castle() { IKingdomFactory kingdomFactory = FactoryMaker.Create(KingdomType.ELF); ICastle castle = kingdomFactory.CreateCastle(); Assert.Equal("This is Elven castle", castle.Description); }
public void should_create_orc_castle() { IKingdomFactory kingdomFactory = FactoryMaker.Create(KingdomType.ORC); ICastle castle = kingdomFactory.CreateCastle(); Assert.Equal("This is Orc castle", castle.Description); }
public void should_create_orc_king() { IKingdomFactory kingdomFactory = FactoryMaker.Create(KingdomType.ORC); IKing king = kingdomFactory.CreateKing(); Assert.Equal("This is Orc king", king.Description); }
internal override void FinalizeCreation() { _bitmapInit.EnsureInitializedComplete(); BitmapSourceSafeMILHandle wicClipper = null; Int32Rect rect = SourceRect; BitmapSource source = Source; if (rect.IsEmpty) { rect.Width = source.PixelWidth; rect.Height = source.PixelHeight; } using (FactoryMaker factoryMaker = new FactoryMaker()) { try { IntPtr wicFactory = factoryMaker.ImagingFactoryPtr; HRESULT.Check(UnsafeNativeMethods.WICImagingFactory.CreateBitmapClipper( wicFactory, out wicClipper)); lock (_syncObject) { HRESULT.Check(UnsafeNativeMethods.WICBitmapClipper.Initialize( wicClipper, source.WicSourceHandle, ref rect)); } // // This is just a link in a BitmapSource chain. The memory is being used by // the BitmapSource at the end of the chain, so no memory pressure needs // to be added here. // WicSourceHandle = wicClipper; _isSourceCached = source.IsSourceCached; wicClipper = null; } catch { _bitmapInit.Reset(); throw; } finally { if (wicClipper != null) { wicClipper.Close(); } } } CreationCompleted = true; UpdateCachedSettings(); }
static internal SafeMILHandle CreateInternalPalette() { SafeMILHandle palette = null; using (FactoryMaker myFactory = new FactoryMaker()) { HRESULT.Check(UnsafeNativeMethods.WICImagingFactory.CreatePalette( myFactory.ImagingFactoryPtr, out palette)); Debug.Assert(palette != null && !palette.IsInvalid); } return(palette); }
static void Main(string[] args) { var program = new Program(); Console.WriteLine("Elf Kingdom"); program.createKingdom(FactoryMaker.makeFactory(KingdomType.ELF)); Console.WriteLine(program.getArmy().getDescription()); Console.WriteLine(program.getCastle().getDescription()); Console.WriteLine(program.getKing().getDescription()); Console.WriteLine("Orc Kingdom"); program.createKingdom(FactoryMaker.makeFactory(KingdomType.ORC)); Console.WriteLine(program.getArmy().getDescription()); Console.WriteLine(program.getCastle().getDescription()); Console.WriteLine(program.getKing().getDescription()); }
/// <summary> /// /// </summary> private void InitializeFromMetadataWriter(SafeMILHandle metadataHandle, object syncObject) { int hr; IntPtr queryWriter = IntPtr.Zero; Guid guidVendor = new Guid(MILGuidData.GUID_VendorMicrosoft); // Create a query writer for this metadata format try { using (FactoryMaker factoryMaker = new FactoryMaker()) { lock (syncObject) { hr = UnsafeNativeMethods.WICImagingFactory.CreateQueryWriterFromReader( factoryMaker.ImagingFactoryPtr, metadataHandle, ref guidVendor, out queryWriter); } } if (HRESULT.Succeeded(hr)) { _readOnly = false; _fixedSize = false; _blockWriter = null; _metadataHandle = new SafeMILHandle(queryWriter); queryWriter = IntPtr.Zero; _syncObject = _metadataHandle; } else if (!HRESULT.IsWindowsCodecError(hr)) { HRESULT.Check(hr); } } finally { if (queryWriter != IntPtr.Zero) { #pragma warning suppress 6031 // Return value ignored on purpose. UnsafeNativeMethods.MILUnknown.Release(queryWriter); } } }
internal override void FinalizeCreation() { try { using (FactoryMaker myFactory = new FactoryMaker()) { SafeMILHandle renderTargetBitmap = null; HRESULT.Check(UnsafeNativeMethods.MILFactory2.CreateBitmapRenderTarget( myFactory.FactoryPtr, (uint)_pixelWidth, (uint)_pixelHeight, _format.Format, (float)_dpiX, (float)_dpiY, MILRTInitializationFlags.MIL_RT_INITIALIZE_DEFAULT, out renderTargetBitmap)); Debug.Assert(renderTargetBitmap != null && !renderTargetBitmap.IsInvalid); BitmapSourceSafeMILHandle bitmapSource = null; HRESULT.Check(MILRenderTargetBitmap.GetBitmap( renderTargetBitmap, out bitmapSource)); Debug.Assert(bitmapSource != null && !bitmapSource.IsInvalid); lock (_syncObject) { _renderTargetBitmap = renderTargetBitmap; bitmapSource.CalculateSize(); WicSourceHandle = bitmapSource; // For the purpose of rendering a RenderTargetBitmap, we always treat it as if it's // not cached. This is to ensure we never render and write to the same bitmap source // by the UCE thread and managed thread. _isSourceCached = false; } } CreationCompleted = true; UpdateCachedSettings(); } catch { _bitmapInit.Reset(); throw; } }
/// <summary> /// /// </summary> private void InitializeFromBlockWriter(BitmapMetadataBlockWriter sourceBlockWriter, object syncObject) { IntPtr /* IWICMetadataBlockWriter */ blockWriter = IntPtr.Zero; IntPtr /* IWICMetadataQueryWriter */ queryWriter = IntPtr.Zero; using (FactoryMaker factoryMaker = new FactoryMaker()) { try { // Otherwise, simulate a metadata block writer for this imaging container format. _blockWriter = new BitmapMetadataBlockWriter(sourceBlockWriter, syncObject); blockWriter = Marshal.GetComInterfaceForObject( _blockWriter, typeof(System.Windows.Media.Imaging.BitmapMetadata.IWICMetadataBlockWriter)); HRESULT.Check(UnsafeNativeMethods.WICComponentFactory.CreateQueryWriterFromBlockWriter( factoryMaker.ImagingFactoryPtr, blockWriter, ref queryWriter )); _readOnly = false; _fixedSize = false; _metadataHandle = new SafeMILHandle(queryWriter); queryWriter = IntPtr.Zero; _syncObject = _metadataHandle; } finally { if (blockWriter != IntPtr.Zero) { #pragma warning suppress 6031 // Return value ignored on purpose. UnsafeNativeMethods.MILUnknown.Release(blockWriter); } if (queryWriter != IntPtr.Zero) { #pragma warning suppress 6031 // Return value ignored on purpose. UnsafeNativeMethods.MILUnknown.Release(queryWriter); } } } }
internal BitmapMetadataBlockWriter(BitmapMetadataBlockWriter blockWriter, object syncObject) { Guid guidVendor = new Guid(MILGuidData.GUID_VendorMicrosoft); _fixedSize = blockWriter._fixedSize; _containerFormat = blockWriter._containerFormat; _metadataBlocks = new ArrayList(); ArrayList metadataBlocks = blockWriter.MetadataBlocks; using (FactoryMaker factoryMaker = new FactoryMaker()) { foreach (SafeMILHandle metadataHandle in metadataBlocks) { lock (syncObject) { IntPtr pIMetadataWriter = IntPtr.Zero; try { HRESULT.Check(UnsafeNativeMethods.WICComponentFactory.CreateMetadataWriterFromReader( factoryMaker.ImagingFactoryPtr, metadataHandle, ref guidVendor, out pIMetadataWriter )); SafeMILHandle metadataWriter = new SafeMILHandle(pIMetadataWriter); pIMetadataWriter = IntPtr.Zero; _metadataBlocks.Add(metadataWriter); } finally { if (pIMetadataWriter != IntPtr.Zero) { #pragma warning suppress 6031 // Return value ignored on purpose. UnsafeNativeMethods.MILUnknown.Release(pIMetadataWriter); } } } } } }
private void CopyCommon(RenderTargetBitmap sourceBitmap) { _bitmapInit.BeginInit(); _pixelWidth = sourceBitmap._pixelWidth; _pixelHeight = sourceBitmap._pixelHeight; _dpiX = sourceBitmap._dpiX; _dpiY = sourceBitmap._dpiY; _format = sourceBitmap._format; // // In order to make a deep clone we need to // create a new bitmap with the contents of the // existing bitmap and then create a render target // from the new bitmap. // using (FactoryMaker myFactory = new FactoryMaker()) { // Create an IWICBitmap BitmapSourceSafeMILHandle newBitmapHandle = BitmapSource.CreateCachedBitmap( null, WicSourceHandle, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnLoad, null); lock (_syncObject) { WicSourceHandle = newBitmapHandle; } // Now create a Render target from that Bitmap HRESULT.Check(UnsafeNativeMethods.MILFactory2.CreateBitmapRenderTargetForBitmap( myFactory.FactoryPtr, newBitmapHandle, out _renderTargetBitmap )); } _bitmapInit.EndInit(); }
private void EnsureUnmanagedEncoder() { if (_encoderHandle == null) { using (FactoryMaker myFactory = new FactoryMaker()) { SafeMILHandle encoderHandle = null; Guid vendorMicrosoft = new Guid(MILGuidData.GUID_VendorMicrosoft); Guid containerFormat = ContainerFormat; HRESULT.Check(UnsafeNativeMethods.WICImagingFactory.CreateEncoder( myFactory.ImagingFactoryPtr, ref containerFormat, ref vendorMicrosoft, out encoderHandle )); _encoderHandle = encoderHandle; } } }
/// <summary> /// /// </summary> static internal InPlaceBitmapMetadataWriter CreateFromDecoder(SafeMILHandle decoderHandle, object syncObject) { Invariant.Assert(decoderHandle != null); SafeMILHandle /* IWICFastMetadataEncoder */ fmeHandle = null; SafeMILHandle /* IWICMetadataQueryWriter */ metadataHandle = null; using (FactoryMaker factoryMaker = new FactoryMaker()) { lock (syncObject) { HRESULT.Check(UnsafeNativeMethods.WICImagingFactory.CreateFastMetadataEncoderFromDecoder( factoryMaker.ImagingFactoryPtr, decoderHandle, out fmeHandle)); } } HRESULT.Check(UnsafeNativeMethods.WICFastMetadataEncoder.GetMetadataQueryWriter( fmeHandle, out metadataHandle)); return(new InPlaceBitmapMetadataWriter(fmeHandle, metadataHandle, syncObject)); }
static internal InPlaceBitmapMetadataWriter CreateFromFrameDecode(BitmapSourceSafeMILHandle frameHandle, object syncObject) { Invariant.Assert(frameHandle != null); SafeMILHandle /* IWICFastMetadataEncoder */ fmeHandle = null; SafeMILHandle /* IWICMetadataQueryWriter */ metadataHandle = null; using (FactoryMaker factoryMaker = new FactoryMaker()) { lock (syncObject) { HRESULT.Check(UnsafeNativeMethods.WICImagingFactory.CreateFastMetadataEncoderFromFrameDecode( factoryMaker.ImagingFactoryPtr, frameHandle, out fmeHandle)); } } HRESULT.Check(UnsafeNativeMethods.WICFastMetadataEncoder.GetMetadataQueryWriter( fmeHandle, out metadataHandle)); return new InPlaceBitmapMetadataWriter(fmeHandle, metadataHandle, syncObject); }
internal override void FinalizeCreation() { _bitmapInit.EnsureInitializedComplete(); BitmapSourceSafeMILHandle wicFormatter = null; using (FactoryMaker factoryMaker = new FactoryMaker()) { try { IntPtr wicFactory = factoryMaker.ImagingFactoryPtr; HRESULT.Check(UnsafeNativeMethods.WICImagingFactory.CreateFormatConverter( wicFactory, out wicFormatter)); SafeMILHandle internalPalette; if (DestinationPalette != null) { internalPalette = DestinationPalette.InternalPalette; } else { internalPalette = new SafeMILHandle(); } Guid format = DestinationFormat.Guid; lock (_syncObject) { HRESULT.Check(UnsafeNativeMethods.WICFormatConverter.Initialize( wicFormatter, Source.WicSourceHandle, ref format, DitherType.DitherTypeErrorDiffusion, internalPalette, AlphaThreshold, WICPaletteType.WICPaletteTypeOptimal )); } // // This is just a link in a BitmapSource chain. The memory is being used by // the BitmapSource at the end of the chain, so no memory pressure needs // to be added here. // WicSourceHandle = wicFormatter; // Even if our source is cached, format conversion is expensive and so we'll // always maintain our own cache for the purpose of rendering. _isSourceCached = false; } catch { _bitmapInit.Reset(); throw; } finally { if (wicFormatter != null) { wicFormatter.Close(); } } } CreationCompleted = true; UpdateCachedSettings(); }
// ISupportInitialize /// /// Create the unmanaged resources /// internal override void FinalizeCreation() { BitmapSourceSafeMILHandle wicClipper = null; BitmapSourceSafeMILHandle wicTransformer = null; BitmapSourceSafeMILHandle transformedSource = _unmanagedSource; HRESULT.Check(UnsafeNativeMethods.WICBitmap.SetResolution(_unmanagedSource, 96, 96)); using (FactoryMaker factoryMaker = new FactoryMaker()) { IntPtr wicFactory = factoryMaker.ImagingFactoryPtr; if (!_sourceRect.IsEmpty) { HRESULT.Check(UnsafeNativeMethods.WICImagingFactory.CreateBitmapClipper( wicFactory, out wicClipper)); lock (_syncObject) { HRESULT.Check(UnsafeNativeMethods.WICBitmapClipper.Initialize( wicClipper, transformedSource, ref _sourceRect)); } transformedSource = wicClipper; } if (_sizeOptions != null) { if (_sizeOptions.DoesScale) { Debug.Assert(_sizeOptions.Rotation == Rotation.Rotate0); uint width, height; _sizeOptions.GetScaledWidthAndHeight( (uint)_sizeOptions.PixelWidth, (uint)_sizeOptions.PixelHeight, out width, out height); HRESULT.Check(UnsafeNativeMethods.WICImagingFactory.CreateBitmapScaler( wicFactory, out wicTransformer)); lock (_syncObject) { HRESULT.Check(UnsafeNativeMethods.WICBitmapScaler.Initialize( wicTransformer, transformedSource, width, height, WICInterpolationMode.Fant)); } } else if (_sizeOptions.Rotation != Rotation.Rotate0) { HRESULT.Check(UnsafeNativeMethods.WICImagingFactory.CreateBitmapFlipRotator( wicFactory, out wicTransformer)); lock (_syncObject) { HRESULT.Check(UnsafeNativeMethods.WICBitmapFlipRotator.Initialize( wicTransformer, transformedSource, _sizeOptions.WICTransformOptions)); } } if (wicTransformer != null) { transformedSource = wicTransformer; } } WicSourceHandle = transformedSource; // Since the original source is an HICON, HBITMAP or section, we know it's cached. // FlipRotate and Clipper do not affect our cache performance. _isSourceCached = true; } CreationCompleted = true; UpdateCachedSettings(); }
public FactoryFixture() { elfFactory = FactoryMaker.makeFactory(KingdomType.ELF); orcFactory = FactoryMaker.makeFactory(KingdomType.ORC); }
private void InitFromMemoryPtr( int pixelWidth, int pixelHeight, double dpiX, double dpiY, PixelFormat pixelFormat, BitmapPalette palette, IntPtr buffer, int bufferSize, int stride ) { if (pixelFormat.Palettized == true && palette == null) { throw new InvalidOperationException(SR.Get(SRID.Image_IndexedPixelFormatRequiresPalette)); } if (pixelFormat.Format == PixelFormatEnum.Default && pixelFormat.Guid == WICPixelFormatGUIDs.WICPixelFormatDontCare) { throw new System.ArgumentException( SR.Get(SRID.Effect_PixelFormat, pixelFormat), "pixelFormat" ); } _bitmapInit.BeginInit(); try { BitmapSourceSafeMILHandle wicBitmap; // Create the unmanaged resources Guid guidFmt = pixelFormat.Guid; using (FactoryMaker factoryMaker = new FactoryMaker()) { HRESULT.Check(UnsafeNativeMethods.WICImagingFactory.CreateBitmapFromMemory( factoryMaker.ImagingFactoryPtr, (uint)pixelWidth, (uint)pixelHeight, ref guidFmt, (uint)stride, (uint)bufferSize, buffer, out wicBitmap)); wicBitmap.CalculateSize(); } HRESULT.Check(UnsafeNativeMethods.WICBitmap.SetResolution( wicBitmap, dpiX, dpiY)); if (pixelFormat.Palettized) { HRESULT.Check(UnsafeNativeMethods.WICBitmap.SetPalette( wicBitmap, palette.InternalPalette)); } WicSourceHandle = wicBitmap; _isSourceCached = true; } catch { _bitmapInit.Reset(); throw; } _createOptions = BitmapCreateOptions.PreservePixelFormat; _cacheOption = BitmapCacheOption.OnLoad; _syncObject = WicSourceHandle; _bitmapInit.EndInit(); UpdateCachedSettings(); }
/// <summary> /// This method is part of an interface that is only called by way of WindowsCodec. It is not /// publicly exposed or accessible in any way. /// </summary> public int InitializeFromBlockReader( IntPtr /* IWICMetadataBlockReader */ pIBlockReader ) { Invariant.Assert(pIBlockReader != IntPtr.Zero); int hr = MS.Win32.NativeMethods.S_OK; UInt32 count = 0; Guid guidVendor = new Guid(MILGuidData.GUID_VendorMicrosoft); ArrayList metadataBlocks = new ArrayList(); hr = UnsafeNativeMethods.WICMetadataBlockReader.GetCount( pIBlockReader, out count ); if (HRESULT.Succeeded(hr)) { using (FactoryMaker factoryMaker = new FactoryMaker()) { for (UInt32 i = 0; i < count; i++) { SafeMILHandle pIMetadataReader = null; IntPtr pIMetadataWriter = IntPtr.Zero; try { hr = UnsafeNativeMethods.WICMetadataBlockReader.GetReaderByIndex( pIBlockReader, i, out pIMetadataReader ); if (HRESULT.Failed(hr)) { break; } hr = UnsafeNativeMethods.WICComponentFactory.CreateMetadataWriterFromReader( factoryMaker.ImagingFactoryPtr, pIMetadataReader, ref guidVendor, out pIMetadataWriter ); if (HRESULT.Failed(hr)) { break; } // pIMetadataWriter already has an active reference, give it to the safe handle. SafeMILHandle metadataWriter = new SafeMILHandle(pIMetadataWriter); pIMetadataWriter = IntPtr.Zero; metadataBlocks.Add(metadataWriter); } finally { if (pIMetadataReader != null) { pIMetadataReader.Dispose(); } if (pIMetadataWriter != IntPtr.Zero) { #pragma warning suppress 6031 // Return value ignored on purpose. UnsafeNativeMethods.MILUnknown.Release(pIMetadataWriter); } } } } _metadataBlocks = metadataBlocks; } return(hr); }
internal override void FinalizeCreation() { _bitmapInit.EnsureInitializedComplete(); BitmapSourceSafeMILHandle wicTransformer = null; double scaleX, scaleY; WICBitmapTransformOptions options; GetParamsFromTransform(Transform, out scaleX, out scaleY, out options); using (FactoryMaker factoryMaker = new FactoryMaker()) { try { IntPtr wicFactory = factoryMaker.ImagingFactoryPtr; wicTransformer = _source.WicSourceHandle; if (!DoubleUtil.IsOne(scaleX) || !DoubleUtil.IsOne(scaleY)) { uint width = Math.Max(1, (uint)(scaleX * _source.PixelWidth + 0.5)); uint height = Math.Max(1, (uint)(scaleY * _source.PixelHeight + 0.5)); HRESULT.Check(UnsafeNativeMethods.WICImagingFactory.CreateBitmapScaler( wicFactory, out wicTransformer)); lock (_syncObject) { HRESULT.Check(UnsafeNativeMethods.WICBitmapScaler.Initialize( wicTransformer, _source.WicSourceHandle, width, height, WICInterpolationMode.Fant)); } } if (options != WICBitmapTransformOptions.WICBitmapTransformRotate0) { // Rotations are extremely slow if we're pulling from a decoder because we end // up decoding multiple times. Caching the source lets us rotate faster at the cost // of increased memory usage. wicTransformer = CreateCachedBitmap( null, wicTransformer, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default, _source.Palette); // BitmapSource.CreateCachedBitmap already calculates memory pressure for // the new bitmap, so there's no need to do it before setting it to // WicSourceHandle. BitmapSourceSafeMILHandle rotator = null; HRESULT.Check(UnsafeNativeMethods.WICImagingFactory.CreateBitmapFlipRotator( wicFactory, out rotator)); lock (_syncObject) { HRESULT.Check(UnsafeNativeMethods.WICBitmapFlipRotator.Initialize( rotator, wicTransformer, options)); } wicTransformer = rotator; } // If we haven't introduced either a scaler or rotator, add a null rotator // so that our WicSourceHandle isn't the same as our Source's. if (options == WICBitmapTransformOptions.WICBitmapTransformRotate0 && DoubleUtil.IsOne(scaleX) && DoubleUtil.IsOne(scaleY)) { HRESULT.Check(UnsafeNativeMethods.WICImagingFactory.CreateBitmapFlipRotator( wicFactory, out wicTransformer)); lock (_syncObject) { HRESULT.Check(UnsafeNativeMethods.WICBitmapFlipRotator.Initialize( wicTransformer, _source.WicSourceHandle, WICBitmapTransformOptions.WICBitmapTransformRotate0)); } } WicSourceHandle = wicTransformer; _isSourceCached = _source.IsSourceCached; } catch { _bitmapInit.Reset(); throw; } } CreationCompleted = true; UpdateCachedSettings(); }