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
- ScriptControlDescriptor.cs
- KnownTypesProvider.cs
- StringValueSerializer.cs
- Publisher.cs
- GenericIdentity.cs
- LocalizationComments.cs
- DropShadowBitmapEffect.cs
- AmbientLight.cs
- HtmlUtf8RawTextWriter.cs
- DivideByZeroException.cs
- ILGenerator.cs
- DataContext.cs
- GeneralTransform3D.cs
- sqlnorm.cs
- TrustManagerPromptUI.cs
- RuntimeEnvironment.cs
- AdornedElementPlaceholder.cs
- FunctionDescription.cs
- CodeRegionDirective.cs
- CheckBox.cs
- AppLevelCompilationSectionCache.cs
- Lease.cs
- AuthorizationSection.cs
- SqlTransaction.cs
- SafeWaitHandle.cs
- PolicyManager.cs
- GradientSpreadMethodValidation.cs
- NamedPermissionSet.cs
- DataTablePropertyDescriptor.cs
- BaseResourcesBuildProvider.cs
- ReflectEventDescriptor.cs
- ZoneButton.cs
- DataPagerFieldCollection.cs
- InheritanceContextHelper.cs
- BitSet.cs
- SafeRegistryHandle.cs
- Expander.cs
- UTF32Encoding.cs
- WebServiceErrorEvent.cs
- XmlQueryRuntime.cs
- SqlWorkflowInstanceStoreLock.cs
- TableDetailsCollection.cs
- PartBasedPackageProperties.cs
- UInt32Converter.cs
- LinearKeyFrames.cs
- FileAuthorizationModule.cs
- BinaryObjectInfo.cs
- DictionaryContent.cs
- TypeReference.cs
- ControlBuilder.cs
- MiniCustomAttributeInfo.cs
- NavigationWindowAutomationPeer.cs
- TableColumn.cs
- Overlapped.cs
- CollectionContainer.cs
- InternalConfigHost.cs
- ObjectKeyFrameCollection.cs
- WindowsRichEdit.cs
- TypefaceCollection.cs
- Utils.cs
- ProcessHostServerConfig.cs
- WorkflowRuntimeService.cs
- StylusButtonCollection.cs
- CssStyleCollection.cs
- TreeNodeEventArgs.cs
- InkPresenterAutomationPeer.cs
- BindingsCollection.cs
- StringValidatorAttribute.cs
- XmlSiteMapProvider.cs
- RequestValidator.cs
- CatchBlock.cs
- XmlAttribute.cs
- SerializeAbsoluteContext.cs
- ConnectionsZone.cs
- TitleStyle.cs
- Simplifier.cs
- adornercollection.cs
- EntityDescriptor.cs
- DataGridViewSelectedColumnCollection.cs
- SystemPens.cs
- DataGridViewTextBoxCell.cs
- XpsFilter.cs
- OleTxTransaction.cs
- ListViewTableRow.cs
- FigureParagraph.cs
- ModelChangedEventArgsImpl.cs
- PackagePart.cs
- JournalNavigationScope.cs
- GrabHandleGlyph.cs
- AsnEncodedData.cs
- UIElementIsland.cs
- SynchronizingStream.cs
- FullTextState.cs
- BatchParser.cs
- MenuItem.cs
- XmlNotation.cs
- PolicyChain.cs
- StylusPlugin.cs
- GridViewRowPresenter.cs
- HostingPreferredMapPath.cs