Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / wpf / src / Core / CSharp / System / Windows / Media / ColorContext.cs / 1 / ColorContext.cs
//------------------------------------------------------------------------------ // Microsoft Windows Client Platform // Copyright (c) Microsoft Corporation, All Rights Reserved. // // File: ColorContext.cs //----------------------------------------------------------------------------- #pragma warning disable 1634, 1691 // Allow suppression of certain presharp messages using System; using MS.Internal; using MS.Internal.PresentationCore; using MS.Win32; using System.IO; using System.Runtime.InteropServices; using System.Windows.Media; using System.Resources; using System.Security; using System.Security.Permissions; using System.Collections; using System.ComponentModel; using System.ComponentModel.Design.Serialization; using System.Reflection; using System.Diagnostics; using System.Globalization; using Microsoft.Win32.SafeHandles; using System.Net; using System.IO.Packaging; using System.Windows.Navigation; using System.Diagnostics.CodeAnalysis; using System.Text; using SR=MS.Internal.PresentationCore.SR; using SRID=MS.Internal.PresentationCore.SRID; using UnsafeNativeMethods=MS.Win32.PresentationCore.UnsafeNativeMethods; namespace System.Windows.Media { ////// Color Context /// public class ColorContext { #region Constructors ////// Don't allow construction of ColorContext with no params. /// private ColorContext() { _profileHeader.phSize = 0; // profile size in bytes _profileHeader.phCMMType = 0; // CMM for this profile _profileHeader.phVersion = 0; // profile format version number _profileHeader.phClass = 0; // type of profile _profileHeader.phDataColorSpace = 0; // color space of data _profileHeader.phConnectionSpace = 0; // PCS _profileHeader.phDateTime_0 = 0; // date profile was created _profileHeader.phDateTime_1 = 0; // date profile was created _profileHeader.phDateTime_2 = 0; // date profile was created _profileHeader.phSignature = 0; // magic number _profileHeader.phPlatform = 0; // primary platform _profileHeader.phProfileFlags = 0; // various bit settings _profileHeader.phManufacturer = 0; // device manufacturer _profileHeader.phModel = 0; // device model number _profileHeader.phAttributes_0 = 0; // device attributes _profileHeader.phAttributes_1 = 0; // device attributes _profileHeader.phRenderingIntent = 0; // rendering intent _profileHeader.phIlluminant_0 = 0; // profile illuminant _profileHeader.phIlluminant_1 = 0; // profile illuminant _profileHeader.phIlluminant_2 = 0; // profile illuminant _profileHeader.phCreator = 0; // profile creator _profileHeader.phReserved = IntPtr.Zero; // reserved for future use } ////// Create a ColorContext from an unmanaged color context /// ////// SecurityCritical: This code sets a critical data member /// SecurityTreatAsSafe: Handle is SafeMILHandle that cannot be constructed with an arbitrary IntPtr /// [SecurityCritical, SecurityTreatAsSafe] internal ColorContext(SafeMILHandle colorContextHandle) { _profileHash = 9999; // ISSUE: Is this correct? _colorContextHandle = colorContextHandle; } ////// Creates a new ColorContext object from a .icm or .icc color profile specified by profileUri. /// /// Specifies the URI of a color profile used by the newly created ColorContext. public ColorContext(Uri profileUri) { Initialize(profileUri, /* isStandardProfileUriNotFromUser = */ false); } ////// Given a pixel format, this function will return the closest standard color space (sRGB, scRGB, etc) /// [SecurityCritical] public ColorContext(PixelFormat pixelFormat) { switch (pixelFormat.Format) { case PixelFormatEnum.Default: case PixelFormatEnum.Indexed1: case PixelFormatEnum.Indexed2: case PixelFormatEnum.Indexed4: case PixelFormatEnum.Indexed8: case PixelFormatEnum.Bgr555: case PixelFormatEnum.Bgr565: case PixelFormatEnum.Bgr24: case PixelFormatEnum.Rgb24: case PixelFormatEnum.Bgr32: case PixelFormatEnum.Bgra32: case PixelFormatEnum.Pbgra32: default: Initialize(GetStandardColorSpaceProfile(), /* isStandardProfileUriNotFromUser = */ true); break; case PixelFormatEnum.Rgba64: case PixelFormatEnum.Prgba64: case PixelFormatEnum.Rgba128Float: case PixelFormatEnum.Prgba128Float: case PixelFormatEnum.BlackWhite: case PixelFormatEnum.Gray2: case PixelFormatEnum.Gray4: case PixelFormatEnum.Gray8: case PixelFormatEnum.Gray32Float: case PixelFormatEnum.Cmyk32: throw new NotSupportedException(); // standard scRGB profile does not exist yet } } #endregion #region Public Methods ////// SecurityCritical: Calls the SecurityCritical method GetStandardColorSpaceProfile() /// PublicOK: doesn't reveal any sensitive information /// ////// Data /// ////// SecurityCritical: This code calls critical code (unmanaged) /// PublicOK: Calls to retrieve safe data. Additionally AllocHGlobal is happening here /// so no need to demand permissions /// [SecurityCritical] public Stream OpenProfileStream() { IntPtr pdwSize = IntPtr.Zero; IntPtr pBuffer = IntPtr.Zero; byte[] prb = new byte[1]; try { pdwSize = Marshal.AllocHGlobal((int)sizeof(int)); Marshal.WriteInt32(pdwSize, (int)0); _colorContextHelper.GetColorProfileFromHandle(IntPtr.Zero, pdwSize); pBuffer = Marshal.AllocHGlobal(Marshal.ReadInt32(pdwSize)); _colorContextHelper.GetColorProfileFromHandle(pBuffer, pdwSize); prb = new byte[Marshal.ReadInt32(pdwSize)]; Marshal.Copy(pBuffer, prb, 0, Marshal.ReadInt32(pdwSize)); } finally { if (pdwSize!=IntPtr.Zero) { Marshal.FreeHGlobal(pdwSize); } if (pBuffer!=IntPtr.Zero) { Marshal.FreeHGlobal(pBuffer); } } return new MemoryStream(prb); } #endregion Public Methods #region Public Properties ////// ProfileUri /// ////// SecurityCritical: Returns the profile uri which could be a sensitive local path like %WINDIR% /// that shouldn't be given out in partial trust /// PublicOK: demands appropriate permissions /// public Uri ProfileUri { [SecurityCritical] get { Uri uri = _profileUri.Value; // // We don't need to demand permission if the user gave us the uri because the user // already knows the value. If the user didn't give us the value, then the uri has // to be a file path because we got it from GetStandardColorSpaceProfile // if (_isProfileUriNotFromUser.Value) { Invariant.Assert(uri.IsFile); SecurityHelper.DemandPathDiscovery(uri.LocalPath); } return uri; } } #endregion Public Properties #region Internal Properties ////// ProfileHandle /// ////// SecurityCritical: This comes out of an elevation needs to be critical and tracked. /// internal SafeProfileHandle ProfileHandle { [SecurityCritical] get { return _colorContextHelper.ProfileHandle; } } ////// ColorContextHandleHandle /// ////// SecurityCritical: Retrieves a critical data member (unmanaged pointer) /// SecurityTreatAsSafe: Its ok to give the SafeMILHandle out (since no set is allowed) /// internal SafeMILHandle ColorContextHandle { [SecurityCritical, SecurityTreatAsSafe] get { return _colorContextHandle; } } ////// NumChannels /// ////// SecurityCritical: This code reference critical data /// SecurityTreatAsSafe: Even it reference the critical data but it only check it is null or valid /// return data (_numChannels) is safe /// internal int NumChannels { [SecurityCritical, SecurityTreatAsSafe] get { if (_colorContextHelper.IsInvalid) // sRGB or scRGB return 3; return _numChannels; } } ////// ColorType /// internal UInt32 ColorType { get { return (UInt32)_colorTypeFromChannels[NumChannels]; } } ////// ColorSpaceFamily /// ////// SecurityCritical: This code reference critical data /// SecurityTreatAsSafe: Even it reference the critical data but it only check it is null or valid /// return data (_colorSpaceFamily) is safe /// internal StandardColorSpace ColorSpaceFamily { [SecurityCritical, SecurityTreatAsSafe] get { if (_colorContextHelper.IsInvalid) // sRGB or scRGB { return StandardColorSpace.Srgb; } else { return _colorSpaceFamily; } } } #endregion //----------------------------------------------------- // // Equality Methods/Properties // //----------------------------------------------------- #region Equality methods and Properties ////// Equals method /// override public bool Equals(object obj ) { ColorContext context = obj as ColorContext; return (context == this); } ////// GetHashCode /// override public int GetHashCode() { return (int)_profileHash; } ////// Operator== /// public static bool operator==(ColorContext context1, ColorContext context2) { object obj1 = context1; object obj2 = context2; if (obj1 == null && obj2 == null) { return true; } else if (obj1 != null && obj2 != null) { #pragma warning disable 6506 return ( (context1._profileHeader.phSize == context2._profileHeader.phSize) && (context1._profileHeader.phCMMType == context2._profileHeader.phCMMType) && (context1._profileHeader.phVersion == context2._profileHeader.phVersion) && (context1._profileHeader.phClass == context2._profileHeader.phClass) && (context1._profileHeader.phDataColorSpace == context2._profileHeader.phDataColorSpace) && (context1._profileHeader.phConnectionSpace == context2._profileHeader.phConnectionSpace) && (context1._profileHeader.phDateTime_0 == context2._profileHeader.phDateTime_0) && (context1._profileHeader.phDateTime_1 == context2._profileHeader.phDateTime_1) && (context1._profileHeader.phDateTime_2 == context2._profileHeader.phDateTime_2) && (context1._profileHeader.phSignature == context2._profileHeader.phSignature) && (context1._profileHeader.phPlatform == context2._profileHeader.phPlatform) && (context1._profileHeader.phProfileFlags == context2._profileHeader.phProfileFlags) && (context1._profileHeader.phManufacturer == context2._profileHeader.phManufacturer) && (context1._profileHeader.phModel == context2._profileHeader.phModel) && (context1._profileHeader.phAttributes_0 == context2._profileHeader.phAttributes_0) && (context1._profileHeader.phAttributes_1 == context2._profileHeader.phAttributes_1) && (context1._profileHeader.phRenderingIntent == context2._profileHeader.phRenderingIntent) && (context1._profileHeader.phIlluminant_0 == context2._profileHeader.phIlluminant_0) && (context1._profileHeader.phIlluminant_1 == context2._profileHeader.phIlluminant_1) && (context1._profileHeader.phIlluminant_2 == context2._profileHeader.phIlluminant_2) && (context1._profileHeader.phCreator == context2._profileHeader.phCreator) ); #pragma warning restore 6506 } else { return false; } } ////// Operator!= /// public static bool operator!=(ColorContext context1, ColorContext context2) { return !(context1 == context2); } #endregion #region Private Methods ////// Loads color profile given by profileUri /// ////// SecurityCritical: method calls SecurityCritical code, profileUri could contain /// sensitive path information /// SecurityTreatAsSafe: WebRequest demands the necessary permissions /// and the Uri isn't exposed /// [SecurityCritical, SecurityTreatAsSafe] private void Initialize(Uri profileUri, bool isStandardProfileUriNotFromUser) { bool tryProfileFromResource = false; if (profileUri == null) { throw new ArgumentNullException("profileUri"); } if (!profileUri.IsAbsoluteUri) { throw new ArgumentException(SR.Get(SRID.UriNotAbsolute), "profileUri"); } _profileUri = new SecurityCriticalData(profileUri); _isProfileUriNotFromUser = new SecurityCriticalDataForSet (isStandardProfileUriNotFromUser); Stream profileStream = null; try { profileStream = WpfWebRequestHelper.CreateRequestAndGetResponseStream(profileUri); } catch (WebException) { // // If we couldn't load the system's default color profile (e.g. in partial trust), load a color profile from // a resource so the image shows up at least. If the user specified a color profile and we weren't // able to load it, we'll fail to avoid letting the user use this resource fallback as a way to discover // files on disk. // if (isStandardProfileUriNotFromUser) { tryProfileFromResource = true; } } if (profileStream == null) { if (tryProfileFromResource) { ResourceManager resourceManager = new ResourceManager(_colorProfileResources, Assembly.GetAssembly(typeof(ColorContext))); byte[] sRGBProfile = (byte[])resourceManager.GetObject(_sRGBProfileName); profileStream = new MemoryStream(sRGBProfile); } else { // // SECURITY WARNING: This exception includes the profile URI which may contain sensitive information. However, as of right now, // this is safe because it can only happen when the URI is given to us by the user. // Invariant.Assert(!isStandardProfileUriNotFromUser); throw new FileNotFoundException(SR.Get(SRID.FileNotFoundExceptionWithFileName, profileUri.AbsolutePath), profileUri.AbsolutePath); } } FromStream(profileStream, profileUri.AbsolutePath); } /// /// Obtains the system color profile path /// ////// SecurityCritical: This code calls critical code (unmanaged) and returns /// path information that can be set by an outside party and/or may include /// sensitive paths like %WINDIR% /// [SecurityCritical] private static Uri GetStandardColorSpaceProfile() { const int SIZE = NativeMethods.MAX_PATH; uint dwProfileID = (uint)ICMConstants.sRGB; uint bufferSize = SIZE; StringBuilder buffer = new StringBuilder(SIZE); HRESULT.Check(UnsafeNativeMethods.Mscms.GetStandardColorSpaceProfile(IntPtr.Zero, dwProfileID, buffer, out bufferSize)); Uri profilePath; string profilePathString = buffer.ToString(); if (!Uri.TryCreate(profilePathString, UriKind.Absolute, out profilePath)) { // // GetStandardColorSpaceProfile() returns whatever was given to SetStandardColorSpaceProfile(). // If it were set to a relative path by the user, we should throw an exception to avoid any possible // security issues. However, the Vista control panel uses the same API and sometimes likes to set // relative paths. Since we can't tell the difference and we want people to be able to change // their color profile from the control panel, we'll tack on the system directory. // // bufferSize was modified by GetStandardColorSpaceProfile so set it again bufferSize = SIZE; HRESULT.Check(UnsafeNativeMethods.Mscms.GetColorDirectory(IntPtr.Zero, buffer, out bufferSize)); profilePath = new Uri(Path.Combine(buffer.ToString(), profilePathString)); } return profilePath; } private void FromStream(Stream stm, string filename) { Debug.Assert(stm != null); int bufferSize = _bufferSizeIncrement; if (stm.CanSeek) { bufferSize = (int)stm.Length + 1; // If this stream is seekable (most cases), we will only have one buffer alloc and read below // otherwise, we will incrementally grow the buffer and read until end of profile. // profiles are typcially small, so usually one allocation will suffice } byte[] rawBytes = new byte[bufferSize]; int numBytesRead = 0; while (bufferSize < _maximumColorContextLength) { numBytesRead += stm.Read(rawBytes, numBytesRead, bufferSize-numBytesRead); if (numBytesRead < bufferSize) { FromRawBytes(rawBytes, numBytesRead); // Create the ColorContextHandle GetColorContextHandlerFromProfileBytes(rawBytes, numBytesRead); return; } else { bufferSize += _bufferSizeIncrement; byte[] newRawBytes = new byte[bufferSize]; rawBytes.CopyTo(newRawBytes, 0); rawBytes = newRawBytes; } } throw new ArgumentException(SR.Get(SRID.ColorContext_FileTooLarge), filename); } ////// SecurityCritical: This code calls critical code (unmanaged) /// SecurityTreatAsSafe: Calls to retrieve safe data. Additionally AllocHGlobal is happening here /// so no need to demand permissions /// [SecurityCritical,SecurityTreatAsSafe] private void FromRawBytes(byte[] data, int dataLength) // Note: often the data buffer is larger than the actual data in it. { // Technically, we should only compute our hash on the data in the buffer that is valid. // However, it shouldn't really matter - the rest of the buffer is cleared when the // managed array is allocated. And changing this method requires updating asmmeta and // such, which we may not want to do for an SP fix. Crc32Helper crc32 = new Crc32Helper(); crc32.ComputeCrc32(data); _profileHash = crc32.Crc32Value; profileStruct profileStruct; IntPtr pColorSpaceFamily = IntPtr.Zero; IntPtr pNumChannels = IntPtr.Zero; profileStruct.dwType = (UInt32)ICMConstants.PROFILE_MEMBUFFER; int ndataLength = dataLength; profileStruct.cbDataSize = (uint)ndataLength; IntPtr pProfile = IntPtr.Zero; IntPtr pHeader = IntPtr.Zero; try { profileStruct.pProfileData = Marshal.AllocHGlobal(ndataLength); Marshal.Copy(data, 0, profileStruct.pProfileData, ndataLength); pProfile = Marshal.AllocHGlobal(sizeOfProfile()); Marshal.StructureToPtr(profileStruct, pProfile, true); Initialize(); _colorContextHelper.OpenColorProfile(pProfile); pHeader = Marshal.AllocHGlobal(256); _colorContextHelper.GetColorProfileHeader(pHeader); _profileHeader = (ProfileHeaderStruct)Marshal.PtrToStructure(pHeader, typeof(ProfileHeaderStruct)); } finally { Marshal.FreeHGlobal(pProfile); pProfile = IntPtr.Zero; Marshal.FreeHGlobal(pHeader); pHeader = IntPtr.Zero; } if (profileStruct.pProfileData != IntPtr.Zero) { Marshal.FreeHGlobal(profileStruct.pProfileData); profileStruct.pProfileData = IntPtr.Zero; } switch ((ICMConstants)_profileHeader.phDataColorSpace) { case ICMConstants.XYZ: case ICMConstants.Lab: case ICMConstants.Luv: case ICMConstants.YCbr: case ICMConstants.Yxy: case ICMConstants.HSV: case ICMConstants.HLS: case ICMConstants.CMY: _numChannels = 3; _colorSpaceFamily = StandardColorSpace.Unknown; break; case ICMConstants.RGB: _colorSpaceFamily = StandardColorSpace.Rgb; _numChannels = 3; break; case ICMConstants.GRAY: _colorSpaceFamily = StandardColorSpace.Gray; _numChannels = 1; break; case ICMConstants.CMYK: _colorSpaceFamily = StandardColorSpace.Cmyk; _numChannels = 4; break; case ICMConstants._2CLR: _colorSpaceFamily = StandardColorSpace.Multichannel; _numChannels = 2; break; case ICMConstants._3CLR: _colorSpaceFamily = StandardColorSpace.Multichannel; _numChannels = 3; break; case ICMConstants._4CLR: _colorSpaceFamily = StandardColorSpace.Multichannel; _numChannels = 4; break; case ICMConstants._5CLR: _numChannels = 5; _colorSpaceFamily = StandardColorSpace.Multichannel; break; case ICMConstants._6CLR: _numChannels = 6; _colorSpaceFamily = StandardColorSpace.Multichannel; break; case ICMConstants._7CLR: _numChannels = 7; _colorSpaceFamily = StandardColorSpace.Multichannel; break; case ICMConstants._8CLR: _numChannels = 8; _colorSpaceFamily = StandardColorSpace.Multichannel; break; case ICMConstants._9CLR: _numChannels = 9; _colorSpaceFamily = StandardColorSpace.Multichannel; break; case ICMConstants.ACLR: _numChannels = 10; _colorSpaceFamily = StandardColorSpace.Multichannel; break; case ICMConstants.BCLR: _numChannels = 11; _colorSpaceFamily = StandardColorSpace.Multichannel; break; case ICMConstants.CCLR: _numChannels = 12; _colorSpaceFamily = StandardColorSpace.Multichannel; break; case ICMConstants.DCLR: _numChannels = 13; _colorSpaceFamily = StandardColorSpace.Multichannel; break; case ICMConstants.ECLR: _numChannels = 14; _colorSpaceFamily = StandardColorSpace.Multichannel; break; case ICMConstants.FCLR: _numChannels = 15; _colorSpaceFamily = StandardColorSpace.Multichannel; break; default: _numChannels = 0; _colorSpaceFamily = StandardColorSpace.Unknown; break; } } ////// SecurityCritical: This code calls critical code (unmanaged) /// SecurityTreatAsSafe: Calls to retrieve safe data. /// [SecurityCritical, SecurityTreatAsSafe] private void GetColorContextHandlerFromProfileBytes(byte[] pProfileBytes, int nNumberofProfileBytes) { IntPtr pBuffer = IntPtr.Zero; try { using (FactoryMaker factoryMaker = new FactoryMaker()) { HRESULT.Check(UnsafeNativeMethods.WICCodec.CreateColorContext(factoryMaker.ImagingFactoryPtr, out _colorContextHandle)); pBuffer = Marshal.AllocHGlobal(nNumberofProfileBytes); Marshal.Copy(pProfileBytes, 0, pBuffer, nNumberofProfileBytes); HRESULT.Check(UnsafeNativeMethods.WICCodec.ColorContext_InitializeFromMemory(_colorContextHandle, pBuffer, (UInt32)nNumberofProfileBytes)); } } finally { Marshal.FreeHGlobal(pBuffer); pBuffer = IntPtr.Zero; } } unsafe private int sizeOfProfile() { return (sizeof(profileStruct)); } ////// SecurityCritical: This code calls critical code (unmanaged) /// [SecurityCritical] private void Initialize() { _colorContextHelper = new ColorContextHelper(); } #endregion #region Private Fields internal struct profileStruct { public UInt32 dwType; // profile type public IntPtr pProfileData; // it is profile bytes buffer containing color profile profile // we have our own copy instead of retain to the unmanaged code public UInt32 cbDataSize; // size of profile data }; ////// SecurityCritical: This comes out of an elevation needs to be critical and tracked. /// [SecurityCritical] private ColorContextHelper _colorContextHelper; private StandardColorSpace _colorSpaceFamily; private int _numChannels; ////// SecurityCritical: May contain sensitive path information like %WINDIR% /// private SecurityCriticalData_profileUri; /// /// SecurityCritical: Determines whether or not _profileUri contains sensitive data /// that we need to demand access to /// private SecurityCriticalDataForSet_isProfileUriNotFromUser; private struct ProfileHeaderStruct { public uint phSize; // profile size in bytes public uint phCMMType; // CMM for this profile public uint phVersion; // profile format version number public uint phClass; // type of profile public uint phDataColorSpace; // color space of data public uint phConnectionSpace; // PCS public uint phDateTime_0; // date profile was created public uint phDateTime_1; // date profile was created public uint phDateTime_2; // date profile was created public uint phSignature; // magic number public uint phPlatform; // primary platform public uint phProfileFlags; // various bit settings public uint phManufacturer; // device manufacturer public uint phModel; // device model number public uint phAttributes_0; // device attributes public uint phAttributes_1; // device attributes public uint phRenderingIntent; // rendering intent public uint phIlluminant_0; // profile illuminant public uint phIlluminant_1; // profile illuminant public uint phIlluminant_2; // profile illuminant public uint phCreator; // profile creator public IntPtr phReserved; // reserved for future use }; private UInt32 _profileHash; private ProfileHeaderStruct _profileHeader; /// /// SecurityCritical: Unmanaged ColorContext handle /// [SecurityCritical] private SafeMILHandle _colorContextHandle; private const int _bufferSizeIncrement = 1024 * 1024; // 1 Mb private const int _maximumColorContextLength = _bufferSizeIncrement * 32; // 32 Mb private static ICMConstants[] _colorTypeFromChannels = new ICMConstants[9] { ICMConstants.COLORTYPE_UNDEFINED, ICMConstants.COLORTYPE_UNDEFINED, ICMConstants.COLORTYPE_UNDEFINED, ICMConstants.COLOR_3_CHANNEL, ICMConstants.COLOR_CMYK, ICMConstants.COLOR_5_CHANNEL, ICMConstants.COLOR_6_CHANNEL, ICMConstants.COLOR_7_CHANNEL, ICMConstants.COLOR_8_CHANNEL }; private static string _colorProfileResources = "ColorProfiles"; private static string _sRGBProfileName = "sRGB_icm"; internal enum StandardColorSpace : int { Unknown = 0, Srgb = 1, ScRgb = 2, Rgb = 3, Cmyk = 4, Gray = 6, Multichannel = 7 } private enum ICMConstants : uint { PROFILE_MEMBUFFER = 2, COLORTYPE_UNDEFINED = 0xFF, COLORTYPE_RGB = 2, COLOR_3_CHANNEL = 6, COLOR_CMYK = 7, COLOR_5_CHANNEL = 8, COLOR_6_CHANNEL = 9, COLOR_7_CHANNEL = 10, COLOR_8_CHANNEL = 11, sRGB = 0x73524742, XYZ = 0x58595A20, Lab = 0x4C616220, Luv = 0x4C757620, YCbr = 0x59436272, Yxy = 0x59787920, HSV = 0x48535620, HLS = 0x484C5320, CMY = 0x434D5920, RGB = 0x52474220, GRAY = 0x47524159, CMYK = 0x434D594B, _2CLR = 0x32434C52, _3CLR = 0x33434C52, _4CLR = 0x34434C52, _5CLR = 0x35434C52, _6CLR = 0x36434C52, _7CLR = 0x37434C52, _8CLR = 0x38434C52, _9CLR = 0x39434C52, ACLR = 0x41434C52, BCLR = 0x42434C52, CCLR = 0x43434C52, DCLR = 0x44434C52, ECLR = 0x45434C52, FCLR = 0x46434C52 } #endregion } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. //------------------------------------------------------------------------------ // Microsoft Windows Client Platform // Copyright (c) Microsoft Corporation, All Rights Reserved. // // File: ColorContext.cs //----------------------------------------------------------------------------- #pragma warning disable 1634, 1691 // Allow suppression of certain presharp messages using System; using MS.Internal; using MS.Internal.PresentationCore; using MS.Win32; using System.IO; using System.Runtime.InteropServices; using System.Windows.Media; using System.Resources; using System.Security; using System.Security.Permissions; using System.Collections; using System.ComponentModel; using System.ComponentModel.Design.Serialization; using System.Reflection; using System.Diagnostics; using System.Globalization; using Microsoft.Win32.SafeHandles; using System.Net; using System.IO.Packaging; using System.Windows.Navigation; using System.Diagnostics.CodeAnalysis; using System.Text; using SR=MS.Internal.PresentationCore.SR; using SRID=MS.Internal.PresentationCore.SRID; using UnsafeNativeMethods=MS.Win32.PresentationCore.UnsafeNativeMethods; namespace System.Windows.Media { ////// Color Context /// public class ColorContext { #region Constructors ////// Don't allow construction of ColorContext with no params. /// private ColorContext() { _profileHeader.phSize = 0; // profile size in bytes _profileHeader.phCMMType = 0; // CMM for this profile _profileHeader.phVersion = 0; // profile format version number _profileHeader.phClass = 0; // type of profile _profileHeader.phDataColorSpace = 0; // color space of data _profileHeader.phConnectionSpace = 0; // PCS _profileHeader.phDateTime_0 = 0; // date profile was created _profileHeader.phDateTime_1 = 0; // date profile was created _profileHeader.phDateTime_2 = 0; // date profile was created _profileHeader.phSignature = 0; // magic number _profileHeader.phPlatform = 0; // primary platform _profileHeader.phProfileFlags = 0; // various bit settings _profileHeader.phManufacturer = 0; // device manufacturer _profileHeader.phModel = 0; // device model number _profileHeader.phAttributes_0 = 0; // device attributes _profileHeader.phAttributes_1 = 0; // device attributes _profileHeader.phRenderingIntent = 0; // rendering intent _profileHeader.phIlluminant_0 = 0; // profile illuminant _profileHeader.phIlluminant_1 = 0; // profile illuminant _profileHeader.phIlluminant_2 = 0; // profile illuminant _profileHeader.phCreator = 0; // profile creator _profileHeader.phReserved = IntPtr.Zero; // reserved for future use } ////// Create a ColorContext from an unmanaged color context /// ////// SecurityCritical: This code sets a critical data member /// SecurityTreatAsSafe: Handle is SafeMILHandle that cannot be constructed with an arbitrary IntPtr /// [SecurityCritical, SecurityTreatAsSafe] internal ColorContext(SafeMILHandle colorContextHandle) { _profileHash = 9999; // ISSUE: Is this correct? _colorContextHandle = colorContextHandle; } ////// Creates a new ColorContext object from a .icm or .icc color profile specified by profileUri. /// /// Specifies the URI of a color profile used by the newly created ColorContext. public ColorContext(Uri profileUri) { Initialize(profileUri, /* isStandardProfileUriNotFromUser = */ false); } ////// Given a pixel format, this function will return the closest standard color space (sRGB, scRGB, etc) /// [SecurityCritical] public ColorContext(PixelFormat pixelFormat) { switch (pixelFormat.Format) { case PixelFormatEnum.Default: case PixelFormatEnum.Indexed1: case PixelFormatEnum.Indexed2: case PixelFormatEnum.Indexed4: case PixelFormatEnum.Indexed8: case PixelFormatEnum.Bgr555: case PixelFormatEnum.Bgr565: case PixelFormatEnum.Bgr24: case PixelFormatEnum.Rgb24: case PixelFormatEnum.Bgr32: case PixelFormatEnum.Bgra32: case PixelFormatEnum.Pbgra32: default: Initialize(GetStandardColorSpaceProfile(), /* isStandardProfileUriNotFromUser = */ true); break; case PixelFormatEnum.Rgba64: case PixelFormatEnum.Prgba64: case PixelFormatEnum.Rgba128Float: case PixelFormatEnum.Prgba128Float: case PixelFormatEnum.BlackWhite: case PixelFormatEnum.Gray2: case PixelFormatEnum.Gray4: case PixelFormatEnum.Gray8: case PixelFormatEnum.Gray32Float: case PixelFormatEnum.Cmyk32: throw new NotSupportedException(); // standard scRGB profile does not exist yet } } #endregion #region Public Methods ////// SecurityCritical: Calls the SecurityCritical method GetStandardColorSpaceProfile() /// PublicOK: doesn't reveal any sensitive information /// ////// Data /// ////// SecurityCritical: This code calls critical code (unmanaged) /// PublicOK: Calls to retrieve safe data. Additionally AllocHGlobal is happening here /// so no need to demand permissions /// [SecurityCritical] public Stream OpenProfileStream() { IntPtr pdwSize = IntPtr.Zero; IntPtr pBuffer = IntPtr.Zero; byte[] prb = new byte[1]; try { pdwSize = Marshal.AllocHGlobal((int)sizeof(int)); Marshal.WriteInt32(pdwSize, (int)0); _colorContextHelper.GetColorProfileFromHandle(IntPtr.Zero, pdwSize); pBuffer = Marshal.AllocHGlobal(Marshal.ReadInt32(pdwSize)); _colorContextHelper.GetColorProfileFromHandle(pBuffer, pdwSize); prb = new byte[Marshal.ReadInt32(pdwSize)]; Marshal.Copy(pBuffer, prb, 0, Marshal.ReadInt32(pdwSize)); } finally { if (pdwSize!=IntPtr.Zero) { Marshal.FreeHGlobal(pdwSize); } if (pBuffer!=IntPtr.Zero) { Marshal.FreeHGlobal(pBuffer); } } return new MemoryStream(prb); } #endregion Public Methods #region Public Properties ////// ProfileUri /// ////// SecurityCritical: Returns the profile uri which could be a sensitive local path like %WINDIR% /// that shouldn't be given out in partial trust /// PublicOK: demands appropriate permissions /// public Uri ProfileUri { [SecurityCritical] get { Uri uri = _profileUri.Value; // // We don't need to demand permission if the user gave us the uri because the user // already knows the value. If the user didn't give us the value, then the uri has // to be a file path because we got it from GetStandardColorSpaceProfile // if (_isProfileUriNotFromUser.Value) { Invariant.Assert(uri.IsFile); SecurityHelper.DemandPathDiscovery(uri.LocalPath); } return uri; } } #endregion Public Properties #region Internal Properties ////// ProfileHandle /// ////// SecurityCritical: This comes out of an elevation needs to be critical and tracked. /// internal SafeProfileHandle ProfileHandle { [SecurityCritical] get { return _colorContextHelper.ProfileHandle; } } ////// ColorContextHandleHandle /// ////// SecurityCritical: Retrieves a critical data member (unmanaged pointer) /// SecurityTreatAsSafe: Its ok to give the SafeMILHandle out (since no set is allowed) /// internal SafeMILHandle ColorContextHandle { [SecurityCritical, SecurityTreatAsSafe] get { return _colorContextHandle; } } ////// NumChannels /// ////// SecurityCritical: This code reference critical data /// SecurityTreatAsSafe: Even it reference the critical data but it only check it is null or valid /// return data (_numChannels) is safe /// internal int NumChannels { [SecurityCritical, SecurityTreatAsSafe] get { if (_colorContextHelper.IsInvalid) // sRGB or scRGB return 3; return _numChannels; } } ////// ColorType /// internal UInt32 ColorType { get { return (UInt32)_colorTypeFromChannels[NumChannels]; } } ////// ColorSpaceFamily /// ////// SecurityCritical: This code reference critical data /// SecurityTreatAsSafe: Even it reference the critical data but it only check it is null or valid /// return data (_colorSpaceFamily) is safe /// internal StandardColorSpace ColorSpaceFamily { [SecurityCritical, SecurityTreatAsSafe] get { if (_colorContextHelper.IsInvalid) // sRGB or scRGB { return StandardColorSpace.Srgb; } else { return _colorSpaceFamily; } } } #endregion //----------------------------------------------------- // // Equality Methods/Properties // //----------------------------------------------------- #region Equality methods and Properties ////// Equals method /// override public bool Equals(object obj ) { ColorContext context = obj as ColorContext; return (context == this); } ////// GetHashCode /// override public int GetHashCode() { return (int)_profileHash; } ////// Operator== /// public static bool operator==(ColorContext context1, ColorContext context2) { object obj1 = context1; object obj2 = context2; if (obj1 == null && obj2 == null) { return true; } else if (obj1 != null && obj2 != null) { #pragma warning disable 6506 return ( (context1._profileHeader.phSize == context2._profileHeader.phSize) && (context1._profileHeader.phCMMType == context2._profileHeader.phCMMType) && (context1._profileHeader.phVersion == context2._profileHeader.phVersion) && (context1._profileHeader.phClass == context2._profileHeader.phClass) && (context1._profileHeader.phDataColorSpace == context2._profileHeader.phDataColorSpace) && (context1._profileHeader.phConnectionSpace == context2._profileHeader.phConnectionSpace) && (context1._profileHeader.phDateTime_0 == context2._profileHeader.phDateTime_0) && (context1._profileHeader.phDateTime_1 == context2._profileHeader.phDateTime_1) && (context1._profileHeader.phDateTime_2 == context2._profileHeader.phDateTime_2) && (context1._profileHeader.phSignature == context2._profileHeader.phSignature) && (context1._profileHeader.phPlatform == context2._profileHeader.phPlatform) && (context1._profileHeader.phProfileFlags == context2._profileHeader.phProfileFlags) && (context1._profileHeader.phManufacturer == context2._profileHeader.phManufacturer) && (context1._profileHeader.phModel == context2._profileHeader.phModel) && (context1._profileHeader.phAttributes_0 == context2._profileHeader.phAttributes_0) && (context1._profileHeader.phAttributes_1 == context2._profileHeader.phAttributes_1) && (context1._profileHeader.phRenderingIntent == context2._profileHeader.phRenderingIntent) && (context1._profileHeader.phIlluminant_0 == context2._profileHeader.phIlluminant_0) && (context1._profileHeader.phIlluminant_1 == context2._profileHeader.phIlluminant_1) && (context1._profileHeader.phIlluminant_2 == context2._profileHeader.phIlluminant_2) && (context1._profileHeader.phCreator == context2._profileHeader.phCreator) ); #pragma warning restore 6506 } else { return false; } } ////// Operator!= /// public static bool operator!=(ColorContext context1, ColorContext context2) { return !(context1 == context2); } #endregion #region Private Methods ////// Loads color profile given by profileUri /// ////// SecurityCritical: method calls SecurityCritical code, profileUri could contain /// sensitive path information /// SecurityTreatAsSafe: WebRequest demands the necessary permissions /// and the Uri isn't exposed /// [SecurityCritical, SecurityTreatAsSafe] private void Initialize(Uri profileUri, bool isStandardProfileUriNotFromUser) { bool tryProfileFromResource = false; if (profileUri == null) { throw new ArgumentNullException("profileUri"); } if (!profileUri.IsAbsoluteUri) { throw new ArgumentException(SR.Get(SRID.UriNotAbsolute), "profileUri"); } _profileUri = new SecurityCriticalData(profileUri); _isProfileUriNotFromUser = new SecurityCriticalDataForSet (isStandardProfileUriNotFromUser); Stream profileStream = null; try { profileStream = WpfWebRequestHelper.CreateRequestAndGetResponseStream(profileUri); } catch (WebException) { // // If we couldn't load the system's default color profile (e.g. in partial trust), load a color profile from // a resource so the image shows up at least. If the user specified a color profile and we weren't // able to load it, we'll fail to avoid letting the user use this resource fallback as a way to discover // files on disk. // if (isStandardProfileUriNotFromUser) { tryProfileFromResource = true; } } if (profileStream == null) { if (tryProfileFromResource) { ResourceManager resourceManager = new ResourceManager(_colorProfileResources, Assembly.GetAssembly(typeof(ColorContext))); byte[] sRGBProfile = (byte[])resourceManager.GetObject(_sRGBProfileName); profileStream = new MemoryStream(sRGBProfile); } else { // // SECURITY WARNING: This exception includes the profile URI which may contain sensitive information. However, as of right now, // this is safe because it can only happen when the URI is given to us by the user. // Invariant.Assert(!isStandardProfileUriNotFromUser); throw new FileNotFoundException(SR.Get(SRID.FileNotFoundExceptionWithFileName, profileUri.AbsolutePath), profileUri.AbsolutePath); } } FromStream(profileStream, profileUri.AbsolutePath); } /// /// Obtains the system color profile path /// ////// SecurityCritical: This code calls critical code (unmanaged) and returns /// path information that can be set by an outside party and/or may include /// sensitive paths like %WINDIR% /// [SecurityCritical] private static Uri GetStandardColorSpaceProfile() { const int SIZE = NativeMethods.MAX_PATH; uint dwProfileID = (uint)ICMConstants.sRGB; uint bufferSize = SIZE; StringBuilder buffer = new StringBuilder(SIZE); HRESULT.Check(UnsafeNativeMethods.Mscms.GetStandardColorSpaceProfile(IntPtr.Zero, dwProfileID, buffer, out bufferSize)); Uri profilePath; string profilePathString = buffer.ToString(); if (!Uri.TryCreate(profilePathString, UriKind.Absolute, out profilePath)) { // // GetStandardColorSpaceProfile() returns whatever was given to SetStandardColorSpaceProfile(). // If it were set to a relative path by the user, we should throw an exception to avoid any possible // security issues. However, the Vista control panel uses the same API and sometimes likes to set // relative paths. Since we can't tell the difference and we want people to be able to change // their color profile from the control panel, we'll tack on the system directory. // // bufferSize was modified by GetStandardColorSpaceProfile so set it again bufferSize = SIZE; HRESULT.Check(UnsafeNativeMethods.Mscms.GetColorDirectory(IntPtr.Zero, buffer, out bufferSize)); profilePath = new Uri(Path.Combine(buffer.ToString(), profilePathString)); } return profilePath; } private void FromStream(Stream stm, string filename) { Debug.Assert(stm != null); int bufferSize = _bufferSizeIncrement; if (stm.CanSeek) { bufferSize = (int)stm.Length + 1; // If this stream is seekable (most cases), we will only have one buffer alloc and read below // otherwise, we will incrementally grow the buffer and read until end of profile. // profiles are typcially small, so usually one allocation will suffice } byte[] rawBytes = new byte[bufferSize]; int numBytesRead = 0; while (bufferSize < _maximumColorContextLength) { numBytesRead += stm.Read(rawBytes, numBytesRead, bufferSize-numBytesRead); if (numBytesRead < bufferSize) { FromRawBytes(rawBytes, numBytesRead); // Create the ColorContextHandle GetColorContextHandlerFromProfileBytes(rawBytes, numBytesRead); return; } else { bufferSize += _bufferSizeIncrement; byte[] newRawBytes = new byte[bufferSize]; rawBytes.CopyTo(newRawBytes, 0); rawBytes = newRawBytes; } } throw new ArgumentException(SR.Get(SRID.ColorContext_FileTooLarge), filename); } ////// SecurityCritical: This code calls critical code (unmanaged) /// SecurityTreatAsSafe: Calls to retrieve safe data. Additionally AllocHGlobal is happening here /// so no need to demand permissions /// [SecurityCritical,SecurityTreatAsSafe] private void FromRawBytes(byte[] data, int dataLength) // Note: often the data buffer is larger than the actual data in it. { // Technically, we should only compute our hash on the data in the buffer that is valid. // However, it shouldn't really matter - the rest of the buffer is cleared when the // managed array is allocated. And changing this method requires updating asmmeta and // such, which we may not want to do for an SP fix. Crc32Helper crc32 = new Crc32Helper(); crc32.ComputeCrc32(data); _profileHash = crc32.Crc32Value; profileStruct profileStruct; IntPtr pColorSpaceFamily = IntPtr.Zero; IntPtr pNumChannels = IntPtr.Zero; profileStruct.dwType = (UInt32)ICMConstants.PROFILE_MEMBUFFER; int ndataLength = dataLength; profileStruct.cbDataSize = (uint)ndataLength; IntPtr pProfile = IntPtr.Zero; IntPtr pHeader = IntPtr.Zero; try { profileStruct.pProfileData = Marshal.AllocHGlobal(ndataLength); Marshal.Copy(data, 0, profileStruct.pProfileData, ndataLength); pProfile = Marshal.AllocHGlobal(sizeOfProfile()); Marshal.StructureToPtr(profileStruct, pProfile, true); Initialize(); _colorContextHelper.OpenColorProfile(pProfile); pHeader = Marshal.AllocHGlobal(256); _colorContextHelper.GetColorProfileHeader(pHeader); _profileHeader = (ProfileHeaderStruct)Marshal.PtrToStructure(pHeader, typeof(ProfileHeaderStruct)); } finally { Marshal.FreeHGlobal(pProfile); pProfile = IntPtr.Zero; Marshal.FreeHGlobal(pHeader); pHeader = IntPtr.Zero; } if (profileStruct.pProfileData != IntPtr.Zero) { Marshal.FreeHGlobal(profileStruct.pProfileData); profileStruct.pProfileData = IntPtr.Zero; } switch ((ICMConstants)_profileHeader.phDataColorSpace) { case ICMConstants.XYZ: case ICMConstants.Lab: case ICMConstants.Luv: case ICMConstants.YCbr: case ICMConstants.Yxy: case ICMConstants.HSV: case ICMConstants.HLS: case ICMConstants.CMY: _numChannels = 3; _colorSpaceFamily = StandardColorSpace.Unknown; break; case ICMConstants.RGB: _colorSpaceFamily = StandardColorSpace.Rgb; _numChannels = 3; break; case ICMConstants.GRAY: _colorSpaceFamily = StandardColorSpace.Gray; _numChannels = 1; break; case ICMConstants.CMYK: _colorSpaceFamily = StandardColorSpace.Cmyk; _numChannels = 4; break; case ICMConstants._2CLR: _colorSpaceFamily = StandardColorSpace.Multichannel; _numChannels = 2; break; case ICMConstants._3CLR: _colorSpaceFamily = StandardColorSpace.Multichannel; _numChannels = 3; break; case ICMConstants._4CLR: _colorSpaceFamily = StandardColorSpace.Multichannel; _numChannels = 4; break; case ICMConstants._5CLR: _numChannels = 5; _colorSpaceFamily = StandardColorSpace.Multichannel; break; case ICMConstants._6CLR: _numChannels = 6; _colorSpaceFamily = StandardColorSpace.Multichannel; break; case ICMConstants._7CLR: _numChannels = 7; _colorSpaceFamily = StandardColorSpace.Multichannel; break; case ICMConstants._8CLR: _numChannels = 8; _colorSpaceFamily = StandardColorSpace.Multichannel; break; case ICMConstants._9CLR: _numChannels = 9; _colorSpaceFamily = StandardColorSpace.Multichannel; break; case ICMConstants.ACLR: _numChannels = 10; _colorSpaceFamily = StandardColorSpace.Multichannel; break; case ICMConstants.BCLR: _numChannels = 11; _colorSpaceFamily = StandardColorSpace.Multichannel; break; case ICMConstants.CCLR: _numChannels = 12; _colorSpaceFamily = StandardColorSpace.Multichannel; break; case ICMConstants.DCLR: _numChannels = 13; _colorSpaceFamily = StandardColorSpace.Multichannel; break; case ICMConstants.ECLR: _numChannels = 14; _colorSpaceFamily = StandardColorSpace.Multichannel; break; case ICMConstants.FCLR: _numChannels = 15; _colorSpaceFamily = StandardColorSpace.Multichannel; break; default: _numChannels = 0; _colorSpaceFamily = StandardColorSpace.Unknown; break; } } ////// SecurityCritical: This code calls critical code (unmanaged) /// SecurityTreatAsSafe: Calls to retrieve safe data. /// [SecurityCritical, SecurityTreatAsSafe] private void GetColorContextHandlerFromProfileBytes(byte[] pProfileBytes, int nNumberofProfileBytes) { IntPtr pBuffer = IntPtr.Zero; try { using (FactoryMaker factoryMaker = new FactoryMaker()) { HRESULT.Check(UnsafeNativeMethods.WICCodec.CreateColorContext(factoryMaker.ImagingFactoryPtr, out _colorContextHandle)); pBuffer = Marshal.AllocHGlobal(nNumberofProfileBytes); Marshal.Copy(pProfileBytes, 0, pBuffer, nNumberofProfileBytes); HRESULT.Check(UnsafeNativeMethods.WICCodec.ColorContext_InitializeFromMemory(_colorContextHandle, pBuffer, (UInt32)nNumberofProfileBytes)); } } finally { Marshal.FreeHGlobal(pBuffer); pBuffer = IntPtr.Zero; } } unsafe private int sizeOfProfile() { return (sizeof(profileStruct)); } ////// SecurityCritical: This code calls critical code (unmanaged) /// [SecurityCritical] private void Initialize() { _colorContextHelper = new ColorContextHelper(); } #endregion #region Private Fields internal struct profileStruct { public UInt32 dwType; // profile type public IntPtr pProfileData; // it is profile bytes buffer containing color profile profile // we have our own copy instead of retain to the unmanaged code public UInt32 cbDataSize; // size of profile data }; ////// SecurityCritical: This comes out of an elevation needs to be critical and tracked. /// [SecurityCritical] private ColorContextHelper _colorContextHelper; private StandardColorSpace _colorSpaceFamily; private int _numChannels; ////// SecurityCritical: May contain sensitive path information like %WINDIR% /// private SecurityCriticalData_profileUri; /// /// SecurityCritical: Determines whether or not _profileUri contains sensitive data /// that we need to demand access to /// private SecurityCriticalDataForSet_isProfileUriNotFromUser; private struct ProfileHeaderStruct { public uint phSize; // profile size in bytes public uint phCMMType; // CMM for this profile public uint phVersion; // profile format version number public uint phClass; // type of profile public uint phDataColorSpace; // color space of data public uint phConnectionSpace; // PCS public uint phDateTime_0; // date profile was created public uint phDateTime_1; // date profile was created public uint phDateTime_2; // date profile was created public uint phSignature; // magic number public uint phPlatform; // primary platform public uint phProfileFlags; // various bit settings public uint phManufacturer; // device manufacturer public uint phModel; // device model number public uint phAttributes_0; // device attributes public uint phAttributes_1; // device attributes public uint phRenderingIntent; // rendering intent public uint phIlluminant_0; // profile illuminant public uint phIlluminant_1; // profile illuminant public uint phIlluminant_2; // profile illuminant public uint phCreator; // profile creator public IntPtr phReserved; // reserved for future use }; private UInt32 _profileHash; private ProfileHeaderStruct _profileHeader; /// /// SecurityCritical: Unmanaged ColorContext handle /// [SecurityCritical] private SafeMILHandle _colorContextHandle; private const int _bufferSizeIncrement = 1024 * 1024; // 1 Mb private const int _maximumColorContextLength = _bufferSizeIncrement * 32; // 32 Mb private static ICMConstants[] _colorTypeFromChannels = new ICMConstants[9] { ICMConstants.COLORTYPE_UNDEFINED, ICMConstants.COLORTYPE_UNDEFINED, ICMConstants.COLORTYPE_UNDEFINED, ICMConstants.COLOR_3_CHANNEL, ICMConstants.COLOR_CMYK, ICMConstants.COLOR_5_CHANNEL, ICMConstants.COLOR_6_CHANNEL, ICMConstants.COLOR_7_CHANNEL, ICMConstants.COLOR_8_CHANNEL }; private static string _colorProfileResources = "ColorProfiles"; private static string _sRGBProfileName = "sRGB_icm"; internal enum StandardColorSpace : int { Unknown = 0, Srgb = 1, ScRgb = 2, Rgb = 3, Cmyk = 4, Gray = 6, Multichannel = 7 } private enum ICMConstants : uint { PROFILE_MEMBUFFER = 2, COLORTYPE_UNDEFINED = 0xFF, COLORTYPE_RGB = 2, COLOR_3_CHANNEL = 6, COLOR_CMYK = 7, COLOR_5_CHANNEL = 8, COLOR_6_CHANNEL = 9, COLOR_7_CHANNEL = 10, COLOR_8_CHANNEL = 11, sRGB = 0x73524742, XYZ = 0x58595A20, Lab = 0x4C616220, Luv = 0x4C757620, YCbr = 0x59436272, Yxy = 0x59787920, HSV = 0x48535620, HLS = 0x484C5320, CMY = 0x434D5920, RGB = 0x52474220, GRAY = 0x47524159, CMYK = 0x434D594B, _2CLR = 0x32434C52, _3CLR = 0x33434C52, _4CLR = 0x34434C52, _5CLR = 0x35434C52, _6CLR = 0x36434C52, _7CLR = 0x37434C52, _8CLR = 0x38434C52, _9CLR = 0x39434C52, ACLR = 0x41434C52, BCLR = 0x42434C52, CCLR = 0x43434C52, DCLR = 0x44434C52, ECLR = 0x45434C52, FCLR = 0x46434C52 } #endregion } } // 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
- ManagedFilter.cs
- PathFigureCollection.cs
- Grid.cs
- MasterPageBuildProvider.cs
- LinqToSqlWrapper.cs
- AlphaSortedEnumConverter.cs
- DynamicRenderer.cs
- DBParameter.cs
- BookmarkScopeManager.cs
- ListCardsInFileRequest.cs
- BufferModeSettings.cs
- LogEntrySerializer.cs
- _DigestClient.cs
- SystemColors.cs
- SortQuery.cs
- ExpanderAutomationPeer.cs
- DataGridViewDataErrorEventArgs.cs
- Queue.cs
- DataGridViewCellContextMenuStripNeededEventArgs.cs
- TPLETWProvider.cs
- CodeFieldReferenceExpression.cs
- CqlGenerator.cs
- GeometryHitTestResult.cs
- WebBrowserUriTypeConverter.cs
- BaseTreeIterator.cs
- EntityClientCacheEntry.cs
- ObjectStateFormatter.cs
- FragmentNavigationEventArgs.cs
- MarshalByRefObject.cs
- GZipStream.cs
- ProcessProtocolHandler.cs
- ConfigurationPropertyCollection.cs
- OdbcException.cs
- GlobalId.cs
- unitconverter.cs
- VisualStyleTypesAndProperties.cs
- ProtectedConfigurationProviderCollection.cs
- TablePatternIdentifiers.cs
- CategoriesDocument.cs
- IgnoreFileBuildProvider.cs
- ListMarkerLine.cs
- ResolveCriteria11.cs
- ListViewItem.cs
- SystemIcmpV4Statistics.cs
- StorageAssociationSetMapping.cs
- ClientRoleProvider.cs
- RangeValidator.cs
- Message.cs
- EnumerableRowCollection.cs
- SignatureHelper.cs
- TypeBuilderInstantiation.cs
- EventInfo.cs
- WorkflowMessageEventArgs.cs
- SyntaxCheck.cs
- MultiBindingExpression.cs
- ModelUIElement3D.cs
- XmlSchemaSet.cs
- _IPv4Address.cs
- HScrollProperties.cs
- _UriTypeConverter.cs
- TextServicesCompartmentEventSink.cs
- DSACryptoServiceProvider.cs
- RawStylusInput.cs
- SQLBinary.cs
- GcHandle.cs
- DoubleCollectionConverter.cs
- HeaderUtility.cs
- SqlDataReader.cs
- BuildResult.cs
- cookiecollection.cs
- WorkflowDebuggerSteppingAttribute.cs
- WebPartCollection.cs
- CodeCommentStatement.cs
- RemoteWebConfigurationHostStream.cs
- util.cs
- ResetableIterator.cs
- VisualBasicReference.cs
- DefaultDiscoveryServiceExtension.cs
- RoutedEventConverter.cs
- ValidatorCompatibilityHelper.cs
- AspProxy.cs
- PlainXmlDeserializer.cs
- EventHandlersStore.cs
- validation.cs
- util.cs
- Context.cs
- formatter.cs
- XXXInfos.cs
- PeerApplicationLaunchInfo.cs
- TextBox.cs
- xml.cs
- ValidationSummary.cs
- LayoutUtils.cs
- EntityDataSourceStatementEditorForm.cs
- IconHelper.cs
- DataBoundControlHelper.cs
- HtmlInputReset.cs
- DbMetaDataCollectionNames.cs
- EncryptedXml.cs
- InstanceOwnerException.cs