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
- QueryReaderSettings.cs
- Camera.cs
- Range.cs
- CapabilitiesAssignment.cs
- PowerModeChangedEventArgs.cs
- GridItemPattern.cs
- XmlSignificantWhitespace.cs
- XmlILCommand.cs
- ProfileParameter.cs
- ProviderSettings.cs
- NullableConverter.cs
- DynamicValidator.cs
- OleCmdHelper.cs
- WebPartEditorCancelVerb.cs
- RemoteArgument.cs
- SocketPermission.cs
- SerializationObjectManager.cs
- ProvidePropertyAttribute.cs
- XPathNodeInfoAtom.cs
- GeneralTransform3D.cs
- SchemaTypeEmitter.cs
- CursorConverter.cs
- TreeNodeMouseHoverEvent.cs
- SQLInt64.cs
- ResourceAttributes.cs
- XamlSerializerUtil.cs
- DataGridViewRowStateChangedEventArgs.cs
- ExpressionBindingCollection.cs
- DynamicMetaObject.cs
- Fonts.cs
- CatalogPartDesigner.cs
- BaseAsyncResult.cs
- SoapSchemaExporter.cs
- KeyValueConfigurationElement.cs
- TrackingServices.cs
- XmlNamedNodeMap.cs
- UserNamePasswordValidator.cs
- ThumbAutomationPeer.cs
- FrameworkPropertyMetadata.cs
- _SSPISessionCache.cs
- HtmlElement.cs
- SessionStateContainer.cs
- DataGridViewRowPrePaintEventArgs.cs
- ProfileModule.cs
- AssociatedControlConverter.cs
- CalendarDataBindingHandler.cs
- FontStretch.cs
- DummyDataSource.cs
- XmlDocument.cs
- KeyFrames.cs
- ContextMenu.cs
- Subordinate.cs
- WmlCalendarAdapter.cs
- COM2IDispatchConverter.cs
- ServicePointManagerElement.cs
- ObjectDataSourceStatusEventArgs.cs
- MemoryStream.cs
- CategoryGridEntry.cs
- QuadTree.cs
- WorkerRequest.cs
- CodeGenerator.cs
- Model3D.cs
- CellConstantDomain.cs
- TagMapCollection.cs
- RegexBoyerMoore.cs
- ContextMenuService.cs
- RefType.cs
- AssociatedControlConverter.cs
- UICuesEvent.cs
- ThreadSafeList.cs
- RequestCacheValidator.cs
- Thickness.cs
- CustomPeerResolverService.cs
- ElapsedEventArgs.cs
- ArgumentNullException.cs
- StaticFileHandler.cs
- ColumnMap.cs
- ApplicationGesture.cs
- UIntPtr.cs
- SqlLiftWhereClauses.cs
- OutOfMemoryException.cs
- AutomationProperty.cs
- CharConverter.cs
- DropShadowEffect.cs
- RuleSettingsCollection.cs
- Debug.cs
- FileDetails.cs
- QilStrConcat.cs
- DesignerAutoFormatCollection.cs
- SHA256.cs
- TemplateGroupCollection.cs
- UnionCodeGroup.cs
- UrlAuthorizationModule.cs
- SmiMetaData.cs
- IDQuery.cs
- PrincipalPermission.cs
- SmiContext.cs
- ResourceContainer.cs
- DurationConverter.cs
- SecureEnvironment.cs