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
//
Dictionary currentPageImageTable = 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();
Dictionary imageUriHashTable = 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
- Compiler.cs
- XmlMapping.cs
- BrowserDefinition.cs
- DesignTimeValidationFeature.cs
- ConfigurationSectionGroupCollection.cs
- XsdBuilder.cs
- MiniLockedBorderGlyph.cs
- SqlInternalConnectionSmi.cs
- HtmlInputText.cs
- NameTable.cs
- CodeCommentStatementCollection.cs
- SelectionRange.cs
- AspNetSynchronizationContext.cs
- ChildrenQuery.cs
- DoubleLinkList.cs
- Transactions.cs
- XhtmlTextWriter.cs
- TabItemWrapperAutomationPeer.cs
- LocalValueEnumerator.cs
- ObjectToIdCache.cs
- ChildTable.cs
- OrderingInfo.cs
- TextBox.cs
- WsdlInspector.cs
- MissingFieldException.cs
- SiteMapSection.cs
- GridEntry.cs
- Simplifier.cs
- DependencyPropertyValueSerializer.cs
- PresentationTraceSources.cs
- ToolStripDesignerUtils.cs
- OleDbRowUpdatedEvent.cs
- HttpProfileBase.cs
- TracePayload.cs
- BaseProcessProtocolHandler.cs
- DataContext.cs
- SqlFileStream.cs
- HttpSysSettings.cs
- DynamicDiscoveryDocument.cs
- ContextStack.cs
- CommonDialog.cs
- StringAnimationUsingKeyFrames.cs
- SqlFactory.cs
- DataServiceContext.cs
- StateBag.cs
- OutputCacheProfileCollection.cs
- UnicastIPAddressInformationCollection.cs
- StrictModeSecurityHeaderElementInferenceEngine.cs
- RowsCopiedEventArgs.cs
- PaginationProgressEventArgs.cs
- Activity.cs
- _ProxyChain.cs
- TextFragmentEngine.cs
- DateTimeValueSerializer.cs
- ISAPIApplicationHost.cs
- PKCS1MaskGenerationMethod.cs
- CryptoApi.cs
- ConfigXmlSignificantWhitespace.cs
- OrderedDictionary.cs
- WindowPattern.cs
- util.cs
- Behavior.cs
- NativeWindow.cs
- UseLicense.cs
- Rijndael.cs
- Rotation3D.cs
- DESCryptoServiceProvider.cs
- SqlNamer.cs
- BuildProviderCollection.cs
- DbDeleteCommandTree.cs
- GeometryCombineModeValidation.cs
- Compensate.cs
- AccessText.cs
- RowsCopiedEventArgs.cs
- ConversionContext.cs
- FontUnitConverter.cs
- MaterialGroup.cs
- X509CertificateCollection.cs
- InternalsVisibleToAttribute.cs
- MD5.cs
- ViewManager.cs
- DbProviderFactory.cs
- VirtualizingStackPanel.cs
- EnterpriseServicesHelper.cs
- MimeParameterWriter.cs
- XamlReader.cs
- MouseEventArgs.cs
- TypeDelegator.cs
- Helpers.cs
- TemplateKeyConverter.cs
- ImpersonationContext.cs
- SizeKeyFrameCollection.cs
- GlyphElement.cs
- BufferedWebEventProvider.cs
- Inline.cs
- XmlAttributes.cs
- ParameterElementCollection.cs
- SQlBooleanStorage.cs
- X509UI.cs
- QueryStringParameter.cs