Code:
/ DotNET / DotNET / 8.0 / untmp / WIN_WINDOWS / lh_tools_devdiv_wpf / Windows / wcp / Print / Reach / Serialization / ImageSourceTypeConverter.cs / 3 / ImageSourceTypeConverter.cs
/*++ Copyright (C) 2004 - 2005 Microsoft Corporation All rights reserved. Module Name: ImageSourceTypeConverter.cs Abstract: This file implements the ImageSourceTypeConverter used by the Xps Serialization APIs for serializing images to a Xps package. Author: [....] ([....]) 1-December-2004 Revision History: --*/ using System; using System.Net; using System.Collections; using System.Collections.Specialized; using System.Collections.Generic; using System.ComponentModel; using System.IO; using System.IO.Packaging; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Xps.Packaging; using System.Security; using System.Security.Permissions; using MS.Internal.ReachFramework; using System.Windows.Markup; using MS.Internal.IO.Packaging; namespace System.Windows.Xps.Serialization { ////// This class implements a type converter for converting /// images to Uris. It handles the writing of the image /// to a Xps package and returns a package URI to the /// caller. It also handles reading an image from a /// Xps package given a Uri. /// public class ImageSourceTypeConverter : ExpandableObjectConverter { #region Public overrides for ExpandableObjectConverted ////// Returns whether this converter can convert an object /// of the given type to the type of this converter. /// /// /// An ITypeDescriptorContext that provides a format context. /// /// /// A Type that represents the type you want to convert from. /// ////// true if this converter can perform the conversion; /// otherwise, false. /// public override bool CanConvertFrom( ITypeDescriptorContext context, Type sourceType ) { return IsSupportedType(sourceType); } ////// Returns whether this converter can convert the object /// to the specified type. /// /// /// An ITypeDescriptorContext that provides a format context. /// /// /// A Type that represents the type you want to convert to. /// ////// true if this converter can perform the conversion; /// otherwise, false. /// public override bool CanConvertTo( ITypeDescriptorContext context, Type destinationType ) { return IsSupportedType(destinationType); } ////// Converts the given value to the type of this converter. /// /// /// An ITypeDescriptorContext that provides a format context. /// /// /// The CultureInfo to use as the current culture. /// /// /// The Object to convert. /// ////// An Object that represents the converted value. /// public override object ConvertFrom( ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value ) { if( value == null ) { throw new ArgumentNullException("value"); } if (!IsSupportedType(value.GetType())) { throw new NotSupportedException(ReachSR.Get(ReachSRID.Converter_ConvertFromNotSupported)); } throw new NotImplementedException(); } ////// Converts the given value object to the specified type, /// using the arguments. /// /// /// An ITypeDescriptorContext that provides a format context. /// /// /// A CultureInfo object. If null is passed, the current /// culture is assumed. /// /// /// The Object to convert. /// /// /// The Type to convert the value parameter to. /// ////// The Type to convert the value parameter to. /// ////// Critical - 1) Calls GetImageMimeType which is security critical /// /// /// 2) Calls ReEncodeBitmap which is security critical /// /// TreatAsSafe: /// 1) MimeTypes demands Unrestriced registry access. Presumably /// to discover registered bitmaps. Registry information is not passed to caller. /// /// 2) Getting codecinfo data is OK (Direct quote from CodecInfo ) /// /// 3) Uses the information to detrmine Bitmap Source type so it can be serialzied into stream with the same type. /// [SecurityCritical, SecurityTreatAsSafe] public override object ConvertTo( ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType ) { Toolbox.StartEvent(MS.Utility.EventTraceGuidId.DRXCONVERTIMAGEGUID); if( context == null ) { throw new ArgumentNullException("context"); } if (!IsSupportedType(destinationType)) { throw new NotSupportedException(ReachSR.Get(ReachSRID.Converter_ConvertToNotSupported)); } // // Check that we have a valid BitmapSource instance. // BitmapSource bitmapSource = (BitmapSource)value; if (bitmapSource == null) { throw new ArgumentException(ReachSR.Get(ReachSRID.MustBeOfType, "value", "BitmapSource")); } // // Get the current serialization manager. // PackageSerializationManager manager = (PackageSerializationManager)context.GetService(typeof(XpsSerializationManager)); //Get the image Uri if it has already been serialized Uri imageUri = GetBitmapSourceFromImageTable(manager, bitmapSource); // // Get the current page image cache // DictionarycurrentPageImageTable = manager.ResourcePolicy.CurrentPageImageTable; if (imageUri != null) { int uriHashCode = imageUri.GetHashCode(); if(!currentPageImageTable.ContainsKey(uriHashCode)) { // // Also, add a relationship for the current page to this image // resource. This is needed to conform with Xps specification. // manager.AddRelationshipToCurrentPage(imageUri, XpsS0Markup.ResourceRelationshipName); currentPageImageTable.Add(uriHashCode, imageUri); } } else { // // This image as never serialized before so we will do it now. // Retrieve the image serialization service from the resource policy // IServiceProvider resourceServiceProvider = manager.ResourcePolicy; XpsImageSerializationService imageService = (XpsImageSerializationService)resourceServiceProvider.GetService(typeof(XpsImageSerializationService)); if (imageService == null) { throw new XpsSerializationException(ReachSR.Get(ReachSRID.ReachSerialization_NoImageService)); } // // Obtain a valid encoder for the image. // BitmapEncoder encoder = imageService.GetEncoder(bitmapSource); string imageMimeType = GetImageMimeType(encoder); bool isSupportedMimeType = imageService.IsSupportedMimeType(bitmapSource); // // Acquire a writable stream from the serialization manager and encode // and serialize the image into the stream. // XpsResourceStream resourceStream = manager.AcquireResourceStream(typeof(BitmapSource), imageMimeType); bool bCopiedStream = false; BitmapFrame bitmapFrame = bitmapSource as BitmapFrame; if (isSupportedMimeType && bitmapFrame != null && bitmapFrame.Decoder != null ) { BitmapDecoder decoder = bitmapFrame.Decoder; try { Uri sourceUri = new Uri(decoder.ToString()); Stream srcStream = MS.Internal.WpfWebRequestHelper.CreateRequestAndGetResponseStream(sourceUri); CopyImageStream(srcStream, resourceStream.Stream); srcStream.Close(); bCopiedStream = true; } catch (UriFormatException) { //the uri was not valid we will re-encode the image below } catch (WebException) { //Web Request failed we will re-encode the image below } } if (!bCopiedStream) { Stream stream = new MemoryStream(); ReEncodeImage(bitmapSource, encoder, stream); stream.Position = 0; CopyImageStream(stream, resourceStream.Stream); } // // Make sure to commit the resource stream by releasing it. // imageUri = resourceStream.Uri; manager.ReleaseResourceStream(typeof(BitmapSource)); AddBitmapSourceToImageTables(manager, imageUri); } Toolbox.EndEvent(MS.Utility.EventTraceGuidId.DRXCONVERTIMAGEGUID); return imageUri; } /// /// Gets a collection of properties for the type of object /// specified by the value parameter. /// /// /// An ITypeDescriptorContext that provides a format context. /// /// /// An Object that specifies the type of object to get the /// properties for. /// /// /// An array of type Attribute that will be used as a filter. /// ////// A PropertyDescriptorCollection with the properties that are /// exposed for the component, or null if there are no properties. /// public override PropertyDescriptorCollection GetProperties( ITypeDescriptorContext context, object value, Attribute[] attributes ) { throw new NotImplementedException(); } #endregion Public overrides for ExpandableObjectConverted #region Private static helper methods ////// Looks up the type in a table to determine /// whether this type is supported by this /// class. /// /// /// Type to lookup in table. /// ////// True is supported; otherwise false. /// private static bool IsSupportedType( Type type ) { bool isSupported = false; foreach (Type t in SupportedTargetTypes) { if (t.Equals(type)) { isSupported = true; break; } } return isSupported; } private static void CopyImageStream( Stream sourceStream, Stream destinationStream ) { byte[] buffer= new byte[_readBlockSize]; int bytesRead = PackagingUtilities.ReliableRead( sourceStream, buffer, 0, _readBlockSize); while( bytesRead > 0 ) { destinationStream.Write(buffer, 0, bytesRead); bytesRead = PackagingUtilities.ReliableRead( sourceStream, buffer, 0, _readBlockSize); } } ////// Critical - 1) Asserts mediaAccessPermission for non site of origin data /// [SecurityCritical] private static void ReEncodeImage(BitmapSource bitmapSource, BitmapEncoder encoder, Stream stream ) { BitmapFrame bitmapFrame = null; // // The uri the BitmapFrame.Create will use is null since it is accessing metadata at // construction and its uri is still null // CodeAccessPermission mediaAccessPermission = SecurityHelper.CreateMediaAccessPermission(null); if (mediaAccessPermission != null) { mediaAccessPermission.Assert(); //BlessedAssert } try { bitmapFrame = BitmapFrame.Create(bitmapSource); } finally { if (mediaAccessPermission != null) { CodeAccessPermission.RevertAssert(); } } encoder.Frames.Add(bitmapFrame); if (mediaAccessPermission != null) { mediaAccessPermission.Assert(); //BlessedAssert } try { encoder.Save(stream); } finally { if (mediaAccessPermission != null) { CodeAccessPermission.RevertAssert(); } } } ////// Calculates a Crc32 value for a given BitmapSource. /// /// /// BitmapSource containing image data to calculate /// the Crc32 value for. /// ////// A 32-bit unsigned integer Crc32 value. /// ////// Critical: This code calls an inernal PresentationCore function CriticalCopyPixels /// TreatAsSafe: We just calcualte 32-bit CRC, image itself is not exposed /// [SecurityCritical, SecurityTreatAsSafe] private static UInt32 CalculateImageCrc32( BitmapSource bitmapSource ) { Crc32 crc32 = new Crc32(); int width = bitmapSource.PixelWidth; int height = bitmapSource.PixelHeight; int stride = (width * bitmapSource.Format.BitsPerPixel + 7) / 8; Int32Rect rect = new Int32Rect(0, 0, width, 1); byte[] pixels = new byte[stride]; for (int i = 0; i < height; i += 1) { bitmapSource.CriticalCopyPixels(rect, pixels, stride, 0); rect.Y++; crc32.AddData(pixels); } return crc32.Crc32Value; } ////// Critical - 1) Asserts to access the registry. May return path information which /// could disclose windows directory (ie. c:\windows\media\sound.wav) /// /// 2) Access unmanaged code, codecs /// /// [SecurityCritical] private static string GetImageMimeType( BitmapEncoder encoder ) { string mimetypes; string imageMimeType = "image/unknown"; // // To determine the mime-type of the image we just grab // the first one supported by this encoder and use that. // PermissionSet permissions = new PermissionSet(null); permissions.AddPermission(new SecurityPermission(SecurityPermissionFlag.UnmanagedCode)); permissions.AddPermission(new RegistryPermission(PermissionState.Unrestricted)); permissions.Assert(); try { mimetypes = encoder.CodecInfo.MimeTypes; } finally { CodeAccessPermission.RevertAssert(); } int comma = mimetypes.IndexOf(','); if (comma != -1) { imageMimeType = mimetypes.Substring(0, comma); } else { imageMimeType = mimetypes; } return imageMimeType; } private Uri GetBitmapSourceFromImageTable(PackageSerializationManager manager, BitmapSource bitmapSource) { Uri imageUri = null; //Initialize cache values _uriHashValue = 0; _crc32HashValue = 0; BitmapFrame bitmapFrame = bitmapSource as BitmapFrame; //Use the Uri hash table if we have a bitmap with a Uri if (bitmapFrame != null && bitmapFrame.Decoder != null) { String sourceUri = bitmapFrame.Decoder.ToString(); if (sourceUri != null) { _uriHashValue = sourceUri.GetHashCode(); DictionaryimageUriHashTable = manager.ResourcePolicy.ImageUriHashTable; if (imageUriHashTable.ContainsKey(_uriHashValue)) { imageUri = imageUriHashTable[_uriHashValue]; } } } //Checking the UriHash for zero tells us if the uri of the bitmap was checked and if it returned a valid Uri if (_uriHashValue == 0) { // // Calculate the image Crc32 value. This is used as a key // into the image cache. // _crc32HashValue = CalculateImageCrc32(bitmapSource); // // Get the current image cache // Dictionary imageCrcTable = manager.ResourcePolicy.ImageCrcTable; // // The image has already been cached (and therefore serialized). // No need to serialize it again so we just return the Uri in the // package where the original was serialized. For that Uri returned // a relationship is only created if this has not been included on // the current page before. // if (imageCrcTable.ContainsKey(_crc32HashValue)) { imageUri = imageCrcTable[_crc32HashValue]; } } return imageUri; } private void AddBitmapSourceToImageTables(PackageSerializationManager manager, Uri imageUri) { if (_uriHashValue != 0) { manager.ResourcePolicy.ImageUriHashTable.Add(_uriHashValue,imageUri); _uriHashValue = 0; } else { manager.ResourcePolicy.ImageCrcTable.Add(_crc32HashValue, imageUri); _crc32HashValue = 0; } manager.ResourcePolicy.CurrentPageImageTable.Add(imageUri.GetHashCode(), imageUri); } #endregion Private static helper methods #region Private static data /// /// A table of supported types for this type converter /// private static Type[] SupportedTargetTypes = { typeof(Uri) }; private static readonly int _readBlockSize = 1048576; //1MB ////// Cached hash values for image tables /// private int _uriHashValue; private UInt32 _crc32HashValue; #endregion Private static data } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- WebPartTracker.cs
- DeferredBinaryDeserializerExtension.cs
- ColumnBinding.cs
- RemotingServices.cs
- OperationAbortedException.cs
- IListConverters.cs
- DataException.cs
- DescriptionAttribute.cs
- ToolStripDropDown.cs
- Claim.cs
- assemblycache.cs
- Function.cs
- Event.cs
- LazyTextWriterCreator.cs
- FormsAuthentication.cs
- PageCodeDomTreeGenerator.cs
- ListViewUpdatedEventArgs.cs
- ConfigXmlComment.cs
- BStrWrapper.cs
- ResXBuildProvider.cs
- AccessorTable.cs
- MD5Cng.cs
- CacheModeValueSerializer.cs
- basevalidator.cs
- SettingsPropertyValue.cs
- RegexCompilationInfo.cs
- LoginName.cs
- SqlClientFactory.cs
- AlignmentYValidation.cs
- WmlCommandAdapter.cs
- AQNBuilder.cs
- UniqueIdentifierService.cs
- unitconverter.cs
- keycontainerpermission.cs
- WebBrowserPermission.cs
- ImageDrawing.cs
- SessionStateItemCollection.cs
- HttpDebugHandler.cs
- ZipIOCentralDirectoryFileHeader.cs
- PasswordPropertyTextAttribute.cs
- RegexBoyerMoore.cs
- QuaternionKeyFrameCollection.cs
- AncillaryOps.cs
- ReferenceSchema.cs
- InternalRelationshipCollection.cs
- WebPartConnectionsConfigureVerb.cs
- Converter.cs
- BaseValidator.cs
- SHA384.cs
- SoapEnumAttribute.cs
- CellConstant.cs
- ContentFilePart.cs
- DataGridCaption.cs
- ToolboxDataAttribute.cs
- SchemaMerger.cs
- PositiveTimeSpanValidator.cs
- ServiceCredentials.cs
- PriorityBindingExpression.cs
- XmlEncodedRawTextWriter.cs
- RectAnimationClockResource.cs
- MediaContext.cs
- SplineQuaternionKeyFrame.cs
- SerializableAttribute.cs
- XmlSchemaSimpleContentRestriction.cs
- XPathNodeList.cs
- DataGridViewEditingControlShowingEventArgs.cs
- X500Name.cs
- ConfigurationLockCollection.cs
- NavigationHelper.cs
- compensatingcollection.cs
- WebPartCatalogCloseVerb.cs
- XpsInterleavingPolicy.cs
- PersonalizationProviderHelper.cs
- GradientStopCollection.cs
- ReflectionHelper.cs
- XmlConverter.cs
- AndCondition.cs
- KeyEvent.cs
- ResourceExpression.cs
- TextRunTypographyProperties.cs
- TypeUtil.cs
- Fault.cs
- ReliableInputConnection.cs
- CodeLabeledStatement.cs
- TextServicesCompartmentContext.cs
- ActivityInstanceMap.cs
- WindowsFormsSynchronizationContext.cs
- InputLanguage.cs
- FixedHighlight.cs
- SystemWebCachingSectionGroup.cs
- EmptyStringExpandableObjectConverter.cs
- Timer.cs
- ImageListImageEditor.cs
- WsdlBuildProvider.cs
- MultiDataTrigger.cs
- ImageMapEventArgs.cs
- SqlDependencyListener.cs
- ConnectionStringsExpressionBuilder.cs
- QilReplaceVisitor.cs
- ClassGenerator.cs