Code:
/ DotNET / DotNET / 8.0 / untmp / WIN_WINDOWS / lh_tools_devdiv_wpf / Windows / wcp / Core / System / Windows / Media / Imaging / WriteableBitmap.cs / 1 / WriteableBitmap.cs
//------------------------------------------------------------------------------ // Microsoft Avalon // Copyright (c) Microsoft Corporation. All Rights Reserved. // // File: WriteableBitmap.cs // //----------------------------------------------------------------------------- using System; using System.IO; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.ComponentModel.Design.Serialization; using System.Reflection; using MS.Internal; using MS.Win32.PresentationCore; using System.Security; using System.Security.Permissions; using System.Diagnostics; using System.Windows.Media; using System.Globalization; using System.Runtime.InteropServices; using System.Windows; using System.Windows.Media.Animation; using System.Windows.Media.Composition; using SR=MS.Internal.PresentationCore.SR; using SRID=MS.Internal.PresentationCore.SRID; using MS.Internal.PresentationCore; // SecurityHelper namespace System.Windows.Media.Imaging { #region WriteableBitmap ////// WriteableBitmap provides caching functionality for a BitmapSource. /// public sealed class WriteableBitmap : System.Windows.Media.Imaging.BitmapSource { ////// Internal constructor /// internal WriteableBitmap() { } ////// Construct a WriteableBitmap /// /// Input BitmapSource ////// Critical: Accesses _wicSource /// PublicOK: Inputs are safe /// [SecurityCritical] public WriteableBitmap(BitmapSource source) : base(true) // Use base class virtuals { if (source == null) { throw new ArgumentNullException("source"); } BeginInit(); _syncObject = source.SyncObject; lock (_syncObject) { WicSourceHandle = CreateCachedBitmap( null, source.WicSourceHandle, BitmapCreateOptions.None, BitmapCacheOption.OnLoad, source.Palette ); } EndInit(); } ////// Construct a WriteableBitmap /// /// Width of the Bitmap /// Height of the Bitmap /// Horizontal DPI of the Bitmap /// Vertical DPI of the Bitmap /// Format of the Bitmap /// Palette of the Bitmap ////// Critical: Accesses _wicSource /// PublicOK: Inputs are safe /// [SecurityCritical] public WriteableBitmap( int pixelWidth, int pixelHeight, double dpiX, double dpiY, PixelFormat pixelFormat, BitmapPalette palette ) : base(true) // Use base class virtuals { BeginInit(); if (pixelFormat.Palettized) { if (palette == null) { throw new InvalidOperationException(SR.Get(SRID.Image_IndexedPixelFormatRequiresPalette)); } } int i = Array.IndexOf(s_supportedDUCEFormats, pixelFormat); if (i == -1) { throw new System.ArgumentException(SR.Get(SRID.Effect_PixelFormat, pixelFormat), "pixelFormat"); } using (FactoryMaker factoryMaker = new FactoryMaker()) { BitmapSourceSafeMILHandle /* IWICBitmapSource */ pIWICSource = null; Guid formatGuid = pixelFormat.Guid; HRESULT.Check(UnsafeNativeMethods.WICImagingFactory.CreateBitmap( factoryMaker.ImagingFactoryPtr, (uint)pixelWidth, (uint)pixelHeight, ref formatGuid, WICBitmapCreateCacheOptions.WICBitmapCacheOnLoad, out pIWICSource )); HRESULT.Check(UnsafeNativeMethods.WICBitmap.SetResolution(pIWICSource, dpiX, dpiY)); if (pixelFormat.Palettized) { HRESULT.Check(UnsafeNativeMethods.WICBitmap.SetPalette(pIWICSource, palette.InternalPalette)); } _syncObject = pIWICSource; WicSourceHandle = pIWICSource; } EndInit(); } #region Public Methods ////// Shadows inherited Copy() with a strongly typed /// version for convenience. /// public new WriteableBitmap Clone() { return (WriteableBitmap)base.Clone(); } ////// Shadows inherited CloneCurrentValue() with a /// strongly typed version for convenience. /// public new WriteableBitmap CloneCurrentValue() { return (WriteableBitmap)base.CloneCurrentValue(); } ////// Update the pixels of this Bitmap /// /// Area to update /// Input buffer /// Size of the buffer /// Stride ////// Critical - access critical code, accepts pointer arguments /// PublicOK - demands unmanaged code permission /// [SecurityCritical] public unsafe void WritePixels( Int32Rect sourceRect, IntPtr buffer, int bufferSize, int stride ) { SecurityHelper.DemandUnmanagedCode(); WritePreamble(); if (bufferSize < 1) { throw new ArgumentOutOfRangeException("bufferSize", SR.Get(SRID.ParameterCannotBeLessThan, 1)); } if (stride < 1) { throw new ArgumentOutOfRangeException("stride", SR.Get(SRID.ParameterCannotBeLessThan, 1)); } if (sourceRect.IsEmpty || sourceRect.Width <= 0 || sourceRect.Height <= 0) { return; } SafeMILHandle pILock = null; HRESULT.Check(UnsafeNativeMethods.WICBitmap.Lock( WicSourceHandle, ref sourceRect, LockFlags.MIL_LOCK_WRITE, out pILock )); try { uint lockBufferSize = 0; IntPtr pData = IntPtr.Zero; HRESULT.Check(UnsafeNativeMethods.WICBitmapLock.GetDataPointer( pILock, ref lockBufferSize, ref pData )); uint lockBufferStride = 0; HRESULT.Check(UnsafeNativeMethods.WICBitmapLock.GetStride( pILock, ref lockBufferStride )); uint copyStride = (uint)(((Format.InternalBitsPerPixel * sourceRect.Width) + 7) / 8); if (bufferSize < (copyStride * sourceRect.Height)) { HRESULT.Check((int)WinCodecErrors.WINCODEC_ERR_INSUFFICIENTBUFFER); } unsafe { CopyPixelBuffer( (byte*)pData, lockBufferStride, (byte*)buffer, (uint)stride, sourceRect.Height, copyStride ); } } finally { // // Release the lock as having it GC'd can // cause issues when reacquiring // pILock.Dispose(); pILock = null; } // Add the source rect to the update list if (_updateRects == null) { _updateRects = new ArrayList(); } _updateRects.Add(sourceRect); // Trigger a update of the UCE resource _needsUpdate = true; RegisterForAsyncUpdateResource(); WritePostscript(); } ////// Update the pixels of this Bitmap /// /// Area to update /// Input buffer /// Stride /// Input buffer offset ////// Critical - Access critical code - WicSourceHandle /// PublicOk - Input is a managed buffer which is safe, other inputs are safe as well /// [SecurityCritical, SecurityTreatAsSafe] public void WritePixels( Int32Rect sourceRect, Array pixels, int stride, int offset ) { WritePreamble(); if (sourceRect.IsEmpty || sourceRect.Width <= 0 || sourceRect.Height <= 0) { return; } if (pixels == null) { throw new System.ArgumentNullException("pixels"); } if (pixels.Rank != 1) { throw new ArgumentException (SR.Get(SRID.Collection_BadRank), "pixels"); } if (stride < 1) { throw new ArgumentOutOfRangeException("stride", SR.Get(SRID.ParameterCannotBeLessThan, 1)); } if (offset < 0) { throw new ArgumentOutOfRangeException("stride", SR.Get(SRID.ParameterCannotBeLessThan, 0)); } int elementSize = -1; if (pixels is byte[]) { elementSize = 1; } else if (pixels is short[] || pixels is ushort[]) { elementSize = 2; } else if (pixels is int[] || pixels is uint[] || pixels is float[]) { elementSize = 4; } else if (pixels is double[]) { elementSize = 8; } if (elementSize == -1) { throw new ArgumentException(SR.Get(SRID.Image_InvalidArrayForPixel)); } uint inputBufferSize = (uint)(elementSize * (pixels.Length - offset)); SafeMILHandle pILock = null; HRESULT.Check(UnsafeNativeMethods.WICBitmap.Lock( WicSourceHandle, ref sourceRect, LockFlags.MIL_LOCK_WRITE, out pILock )); try { uint lockBufferSize = 0; IntPtr pData = IntPtr.Zero; HRESULT.Check(UnsafeNativeMethods.WICBitmapLock.GetDataPointer( pILock, ref lockBufferSize, ref pData )); uint lockBufferStride = 0; HRESULT.Check(UnsafeNativeMethods.WICBitmapLock.GetStride( pILock, ref lockBufferStride )); uint copyStride = (uint)(((Format.InternalBitsPerPixel * sourceRect.Width) + 7) / 8); if (inputBufferSize < (copyStride * sourceRect.Height)) { HRESULT.Check((int)WinCodecErrors.WINCODEC_ERR_INSUFFICIENTBUFFER); } unsafe { if (pixels is byte[]) { fixed (void *pixelArray = &((byte[])pixels)[offset]) { CopyPixelBuffer( (byte*)pData, lockBufferStride, (byte*)pixelArray, (uint)stride, sourceRect.Height, copyStride ); } } else if (pixels is short[]) { fixed (void *pixelArray = &((short[])pixels)[offset]) { CopyPixelBuffer( (byte*)pData, lockBufferStride, (byte*)pixelArray, (uint)stride, sourceRect.Height, copyStride ); } } else if (pixels is ushort[]) { fixed (void *pixelArray = &((ushort[])pixels)[offset]) { CopyPixelBuffer( (byte*)pData, lockBufferStride, (byte*)pixelArray, (uint)stride, sourceRect.Height, copyStride ); } } else if (pixels is int[]) { fixed (void *pixelArray = &((int[])pixels)[offset]) { CopyPixelBuffer( (byte*)pData, lockBufferStride, (byte*)pixelArray, (uint)stride, sourceRect.Height, copyStride ); } } else if (pixels is uint[]) { fixed (void *pixelArray = &((uint[])pixels)[offset]) { CopyPixelBuffer( (byte*)pData, lockBufferStride, (byte*)pixelArray, (uint)stride, sourceRect.Height, copyStride ); } } else if (pixels is float[]) { fixed (void *pixelArray = &((float[])pixels)[offset]) { CopyPixelBuffer( (byte*)pData, lockBufferStride, (byte*)pixelArray, (uint)stride, sourceRect.Height, copyStride ); } } else if (pixels is double[]) { fixed (void *pixelArray = &((double[])pixels)[offset]) { CopyPixelBuffer( (byte*)pData, lockBufferStride, (byte*)pixelArray, (uint)stride, sourceRect.Height, copyStride ); } } } } finally { // // Release the lock as having it GC'd can // cause issues when reacquiring // pILock.Dispose(); pILock = null; } // Add the source rect to the update list if (_updateRects == null) { _updateRects = new ArrayList(); } _updateRects.Add(sourceRect); // Trigger a update of the UCE resource _needsUpdate = true; RegisterForAsyncUpdateResource(); WritePostscript(); } #endregion #region Protected Methods ////// Implementation of ///Freezable.CreateInstanceCore . ///The new Freezable. ////// Critical - accesses critical code. /// TreatAsSafe - method only produces clone of original image. /// [SecurityCritical, SecurityTreatAsSafe] protected override Freezable CreateInstanceCore() { return new WriteableBitmap(); } ////// Implementation of ///Freezable.CloneCore . ////// Critical - accesses critical code. /// TreatAsSafe - method only produces clone of original image. /// [SecurityCritical, SecurityTreatAsSafe] protected override void CloneCore(Freezable sourceFreezable) { WriteableBitmap sourceBitmap = (WriteableBitmap) sourceFreezable; base.CloneCore(sourceFreezable); CopyCommon(sourceBitmap); } ////// Implementation of ///Freezable.CloneCurrentValueCore . ////// Critical - accesses critical code. /// TreatAsSafe - method only produces clone of original image. /// [SecurityCritical, SecurityTreatAsSafe] protected override void CloneCurrentValueCore(Freezable sourceFreezable) { WriteableBitmap sourceBitmap = (WriteableBitmap) sourceFreezable; base.CloneCurrentValueCore(sourceFreezable); CopyCommon(sourceBitmap); } ////// Implementation of ///Freezable.GetAsFrozenCore . ////// Critical - accesses critical code. /// TreatAsSafe - method only produces GetAsFrozen of original image. /// [SecurityCritical, SecurityTreatAsSafe] protected override void GetAsFrozenCore(Freezable sourceFreezable) { WriteableBitmap sourceBitmap = (WriteableBitmap)sourceFreezable; base.GetAsFrozenCore(sourceFreezable); CopyCommon(sourceBitmap); } ////// Implementation of ///Freezable.GetCurrentValueAsFrozenCore . ////// Critical - accesses critical code. /// TreatAsSafe - method only produces GetCurrentValueAsFrozen of original image. /// [SecurityCritical, SecurityTreatAsSafe] protected override void GetCurrentValueAsFrozenCore(Freezable sourceFreezable) { WriteableBitmap sourceBitmap = (WriteableBitmap)sourceFreezable; base.GetCurrentValueAsFrozenCore(sourceFreezable); CopyCommon(sourceBitmap); } #endregion #region Private/Internal Methods ////// Common implementation for CloneCore(), CloneCurrentValueCore(), /// GetAsFrozenCore(), and GetCurrentValueAsFrozenCore(). /// ////// Critical - access critical code -- WicSourceHandle /// [SecurityCritical] private void CopyCommon(WriteableBitmap sourceBitmap) { // Avoid Animatable requesting resource updates for invalidations that occur during construction Animatable_IsResourceInvalidationNecessary = false; BeginInit(); using (FactoryMaker factoryMaker = new FactoryMaker()) { BitmapSourceSafeMILHandle wicSource = null; HRESULT.Check(UnsafeNativeMethods.WICImagingFactory.CreateBitmapFromSource( factoryMaker.ImagingFactoryPtr, sourceBitmap.WicSourceHandle, WICBitmapCreateCacheOptions.WICBitmapCacheOnLoad, out wicSource )); _syncObject = wicSource; WicSourceHandle = wicSource; } EndInit(); // The next invalidation will cause Animatable to register an UpdateResource callback Animatable_IsResourceInvalidationNecessary = true; } // ISupportInitialize ////// Prepare the bitmap to accept initialize paramters. /// private void BeginInit() { _bitmapInit.BeginInit(); } ////// Prepare the bitmap to accept initialize paramters. /// ////// Critical - access critical resources /// TreatAsSafe - All inputs verified /// [SecurityCritical, SecurityTreatAsSafe] private void EndInit() { _bitmapInit.EndInit(); FinalizeCreation(); } /// /// Create the unmanaged resources /// ////// Critical - access critical resource /// [SecurityCritical] internal override void FinalizeCreation() { _isWriteable = true; IsSourceCached = true; CreationCompleted = true; UpdateCachedSettings(); } /// Takes a buffer and copies it to the output buffer ////// Critical: Does unsafe pointer operations /// [SecurityCritical] private unsafe void CopyPixelBuffer( byte *pOutputBuffer, uint outputBufferStride, byte *pInputBuffer, uint inputBufferStride, int height, uint copyStride ) { for (int i = 0; i < height; i++) { for (int j = 0; j < copyStride; j++) { pOutputBuffer[j] = pInputBuffer[j]; } pOutputBuffer += outputBufferStride; pInputBuffer += inputBufferStride; } } /// Retrieves the update Rect and clears the array internal override Int32Rect GetUpdateRect() { if (_updateRects == null || _updateRects.Count == 0) { return Int32Rect.Empty; } Int32Rect updateRect = (Int32Rect)_updateRects[0]; Invariant.Assert(!updateRect.IsEmpty && updateRect.Width > 0 && updateRect.Height > 0); Int32 right = updateRect.X + updateRect.Width - 1; Int32 bottom = updateRect.Y + updateRect.Height - 1; for (int i = 1; i < _updateRects.Count; i++) { Int32Rect currentRect = (Int32Rect)_updateRects[i]; updateRect.X = Math.Min(updateRect.X, currentRect.X); updateRect.Y = Math.Min(updateRect.X, currentRect.Y); right = Math.Max(right, currentRect.X + currentRect.Width - 1); bottom = Math.Max(bottom, currentRect.Y + currentRect.Height - 1); } updateRect.Width = right - updateRect.X + 1; updateRect.Height = bottom - updateRect.Y + 1; Invariant.Assert(!updateRect.IsEmpty && updateRect.Width > 0 && updateRect.Height > 0); _updateRects.Clear(); return updateRect; } #endregion #region Data Members ArrayList _updateRects; #endregion } #endregion // WriteableBitmap } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- DataGridColumnCollection.cs
- SafeLocalMemHandle.cs
- Native.cs
- BitmapEffectDrawingContent.cs
- SqlDelegatedTransaction.cs
- Transform3D.cs
- TextMessageEncoder.cs
- BaseUriHelper.cs
- JsonStringDataContract.cs
- RepeatBehavior.cs
- CallbackTimeoutsBehavior.cs
- ProcessHostFactoryHelper.cs
- CannotUnloadAppDomainException.cs
- UIntPtr.cs
- QueueTransferProtocol.cs
- AuthenticationService.cs
- Parsers.cs
- SourceChangedEventArgs.cs
- MaskedTextProvider.cs
- NamedElement.cs
- securitycriticaldata.cs
- JsonFormatMapping.cs
- PropertyBuilder.cs
- SessionStateUtil.cs
- DataAdapter.cs
- GraphicsContext.cs
- StylusEditingBehavior.cs
- IndexedString.cs
- HandlerBase.cs
- BackgroundFormatInfo.cs
- Baml2006Reader.cs
- Calendar.cs
- VirtualDirectoryMapping.cs
- SqlTransaction.cs
- PartialTrustVisibleAssemblyCollection.cs
- Emitter.cs
- ConfigLoader.cs
- StrokeDescriptor.cs
- ProxyAttribute.cs
- PaintEvent.cs
- MachineKeyValidationConverter.cs
- PhysicalFontFamily.cs
- GeneralTransform2DTo3DTo2D.cs
- PartialCachingControl.cs
- SurrogateEncoder.cs
- ThemeDirectoryCompiler.cs
- TableRowGroup.cs
- XomlCompiler.cs
- ProjectionNode.cs
- ImageMapEventArgs.cs
- XPathNavigatorKeyComparer.cs
- PropertyCollection.cs
- NameValueConfigurationCollection.cs
- CharacterString.cs
- DelegateCompletionCallbackWrapper.cs
- Header.cs
- PrefixHandle.cs
- LowerCaseStringConverter.cs
- DecoderFallbackWithFailureFlag.cs
- LambdaCompiler.Expressions.cs
- MatrixStack.cs
- WinInet.cs
- AggregateNode.cs
- MetadataException.cs
- WebPartTracker.cs
- PropertyIDSet.cs
- SortableBindingList.cs
- FormsAuthenticationModule.cs
- TimeStampChecker.cs
- TaiwanLunisolarCalendar.cs
- ValidatorCompatibilityHelper.cs
- AppDomainInfo.cs
- Parameter.cs
- ToolStripHighContrastRenderer.cs
- LZCodec.cs
- TripleDES.cs
- StateMachine.cs
- ImageAttributes.cs
- AspCompat.cs
- BinaryWriter.cs
- OrElse.cs
- XmlSecureResolver.cs
- ConfigErrorGlyph.cs
- DataGridViewRowPostPaintEventArgs.cs
- CachingHintValidation.cs
- StaticResourceExtension.cs
- DirectoryGroupQuery.cs
- PublisherMembershipCondition.cs
- WindowsToolbar.cs
- MemoryStream.cs
- GrammarBuilder.cs
- DataServiceStreamResponse.cs
- PrimaryKeyTypeConverter.cs
- XmlSchemaElement.cs
- HelpKeywordAttribute.cs
- DependencyPropertyAttribute.cs
- AmbiguousMatchException.cs
- RoleManagerModule.cs
- SqlError.cs
- SoapReflectionImporter.cs