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
- DbConnectionStringCommon.cs
- WebServiceParameterData.cs
- TreeNodeCollection.cs
- Function.cs
- Int32AnimationBase.cs
- TdsParserStateObject.cs
- DbConnectionStringCommon.cs
- SimpleBitVector32.cs
- GrowingArray.cs
- ComplexBindingPropertiesAttribute.cs
- PassportIdentity.cs
- HTMLTagNameToTypeMapper.cs
- TitleStyle.cs
- PieceDirectory.cs
- SchemaImporterExtensionElement.cs
- EtwTrace.cs
- ControlCollection.cs
- DataGridColumnHeader.cs
- XamlClipboardData.cs
- WebPartDisplayModeEventArgs.cs
- MediaTimeline.cs
- AssemblyNameProxy.cs
- WindowsScroll.cs
- RandomNumberGenerator.cs
- COM2PropertyDescriptor.cs
- AttributeEmitter.cs
- ConfigurationManagerInternal.cs
- Positioning.cs
- UriGenerator.cs
- EdmEntityTypeAttribute.cs
- BasicCommandTreeVisitor.cs
- WebRequestModulesSection.cs
- MonthCalendar.cs
- ButtonBaseAdapter.cs
- OpCodes.cs
- CmsUtils.cs
- DoubleLinkListEnumerator.cs
- XmlNavigatorStack.cs
- FigureHelper.cs
- SessionStateContainer.cs
- NestPullup.cs
- AsymmetricSignatureDeformatter.cs
- Listen.cs
- SHA384Cng.cs
- ServicePoint.cs
- EntityDataSourceWizardForm.cs
- TimersDescriptionAttribute.cs
- VisualStateGroup.cs
- ToolBarTray.cs
- EventSinkHelperWriter.cs
- HybridDictionary.cs
- TextServicesHost.cs
- ToolStripArrowRenderEventArgs.cs
- WebColorConverter.cs
- FamilyTypeface.cs
- ShaderRenderModeValidation.cs
- basemetadatamappingvisitor.cs
- ToolboxItemFilterAttribute.cs
- XmlEnumAttribute.cs
- PopupControlService.cs
- VisualTransition.cs
- DmlSqlGenerator.cs
- CopyCodeAction.cs
- PropertyCondition.cs
- BrowserCapabilitiesFactory.cs
- PKCS1MaskGenerationMethod.cs
- SecurityPolicySection.cs
- XmlNodeChangedEventArgs.cs
- EventlogProvider.cs
- HttpException.cs
- HttpModuleCollection.cs
- SchemaCompiler.cs
- EditorPartChrome.cs
- RestHandlerFactory.cs
- DataTemplateSelector.cs
- XmlElementCollection.cs
- HtmlInputButton.cs
- ConfigXmlWhitespace.cs
- EntitySqlException.cs
- EdmToObjectNamespaceMap.cs
- StatusStrip.cs
- ClickablePoint.cs
- FrameworkReadOnlyPropertyMetadata.cs
- RowToParametersTransformer.cs
- XmlNamespaceManager.cs
- ColorEditor.cs
- ISO2022Encoding.cs
- DataGridDefaultColumnWidthTypeConverter.cs
- SizeConverter.cs
- TerminatorSinks.cs
- Model3DCollection.cs
- HiddenFieldPageStatePersister.cs
- TypeSystem.cs
- ImageButton.cs
- MemberRelationshipService.cs
- AxisAngleRotation3D.cs
- OneOfTypeConst.cs
- SecurityAlgorithmSuite.cs
- PolicyChain.cs
- TabRenderer.cs