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
- activationcontext.cs
- ConfigurationManagerInternalFactory.cs
- TextDataBindingHandler.cs
- WSHttpBinding.cs
- URI.cs
- EndSelectCardRequest.cs
- DesignerCalendarAdapter.cs
- ExceptionHelpers.cs
- TypeViewSchema.cs
- StructuredType.cs
- ActivityInterfaces.cs
- ValidatorCompatibilityHelper.cs
- DataServiceRequest.cs
- NameTable.cs
- BoundingRectTracker.cs
- TypefaceMetricsCache.cs
- IntSecurity.cs
- ActivitySurrogateSelector.cs
- TextFormatterImp.cs
- SqlUtil.cs
- SqlProcedureAttribute.cs
- ObservableDictionary.cs
- RightsManagementEncryptionTransform.cs
- DocumentXPathNavigator.cs
- Executor.cs
- BindingCompleteEventArgs.cs
- WebReferencesBuildProvider.cs
- SmtpDigestAuthenticationModule.cs
- GacUtil.cs
- WebPartActionVerb.cs
- BasePattern.cs
- RectangleHotSpot.cs
- CacheSection.cs
- PriorityChain.cs
- ClickablePoint.cs
- DecimalFormatter.cs
- WebColorConverter.cs
- XmlSchemaObjectCollection.cs
- PackagingUtilities.cs
- DateTimeFormatInfoScanner.cs
- RMEnrollmentPage3.cs
- StartFileNameEditor.cs
- TCPClient.cs
- DispatcherTimer.cs
- ArraySortHelper.cs
- ResourceProperty.cs
- Scene3D.cs
- EntityContainerEntitySetDefiningQuery.cs
- DiscoveryClientBindingElement.cs
- FormatterServices.cs
- TemplateControlCodeDomTreeGenerator.cs
- LogExtent.cs
- Point3DIndependentAnimationStorage.cs
- CustomAttribute.cs
- TrackPointCollection.cs
- StopStoryboard.cs
- MergablePropertyAttribute.cs
- BaseServiceProvider.cs
- SqlStream.cs
- FontStretchConverter.cs
- DES.cs
- ExpressionBuilder.cs
- DataSourceHelper.cs
- UTF8Encoding.cs
- RightsManagementPermission.cs
- safemediahandle.cs
- DocumentAutomationPeer.cs
- ManipulationBoundaryFeedbackEventArgs.cs
- ServiceDurableInstanceContextProvider.cs
- CompilerInfo.cs
- BinaryNode.cs
- UrlUtility.cs
- DocumentViewerAutomationPeer.cs
- SynchronizationHandlesCodeDomSerializer.cs
- BaseCollection.cs
- Soap12FormatExtensions.cs
- ToolboxItemFilterAttribute.cs
- StringArrayConverter.cs
- EventNotify.cs
- DataGridState.cs
- VariableQuery.cs
- ContentType.cs
- ConnectionPoint.cs
- StaticExtension.cs
- Config.cs
- SqlRewriteScalarSubqueries.cs
- ExtensionFile.cs
- TdsParameterSetter.cs
- MobileSysDescriptionAttribute.cs
- EmptyQuery.cs
- VectorCollectionConverter.cs
- DependencyPropertyDescriptor.cs
- DrawingVisualDrawingContext.cs
- XmlStreamedByteStreamReader.cs
- TextAnchor.cs
- FormatConvertedBitmap.cs
- DataGridViewMethods.cs
- Package.cs
- StyleModeStack.cs
- ConfigUtil.cs