/// <summary> /// Create the unmanaged media resources /// </summary> private void CreateMedia(MediaPlayer mediaPlayer) { SafeMILHandle unmanagedProxy = null; MediaEventsHelper.CreateMediaEventsHelper(mediaPlayer, out _mediaEventsHelper, out unmanagedProxy); try { using (FactoryMaker myFactory = new FactoryMaker()) { HRESULT.Check(UnsafeNativeMethods.MILFactory2.CreateMediaPlayer( myFactory.FactoryPtr, unmanagedProxy, true, out _nativeMedia )); } } catch { if (_nativeMedia != null && !_nativeMedia.IsInvalid) { _nativeMedia.Close(); } throw; } _helper = new Helper(_nativeMedia); AppDomain.CurrentDomain.ProcessExit += _helper.ProcessExitHandler; }
internal InteropBitmap(IntPtr hbitmap, IntPtr hpalette, Int32Rect sourceRect, BitmapSizeOptions sizeOptions, WICBitmapAlphaChannelOption alphaOptions) : base(true) // Use virtuals { _bitmapInit.BeginInit(); using (FactoryMaker myFactory = new FactoryMaker()) { HRESULT.Check(UnsafeNativeMethods.WICImagingFactory.CreateBitmapFromHBITMAP( myFactory.ImagingFactoryPtr, hbitmap, hpalette, alphaOptions, out _unmanagedSource)); Debug.Assert (_unmanagedSource != null && !_unmanagedSource.IsInvalid); } _unmanagedSource.CalculateSize(); _sizeOptions = sizeOptions; _sourceRect = sourceRect; _syncObject = _unmanagedSource; _bitmapInit.EndInit(); FinalizeCreation(); }
private void CreateMedia(MediaPlayer mediaPlayer) { CheckMediaDisabledFlags(); SafeMILHandle unmanagedProxy = null; MediaEventsHelper.CreateMediaEventsHelper(mediaPlayer, out _mediaEventsHelper, out unmanagedProxy); try { using (FactoryMaker myFactory = new FactoryMaker()) { HRESULT.Check(UnsafeNativeMethods.MILFactory2.CreateMediaPlayer( myFactory.FactoryPtr, unmanagedProxy, SecurityHelper.CallerHasMediaPermission(MediaPermissionAudio.AllAudio, MediaPermissionVideo.AllVideo, MediaPermissionImage.NoImage), out _nativeMedia )); } } catch { if (_nativeMedia != null && !_nativeMedia.IsInvalid) { _nativeMedia.Close(); } throw; } _helper = new Helper(_nativeMedia); AppDomain.CurrentDomain.ProcessExit += _helper.ProcessExitHandler; }
/// <summary> /// Helper method that will retrieve ColorContexts from an unmanaged object (e.g. BitmapDecoder or BitmapFrameDecode) /// </summary> internal static IList <ColorContext> GetColorContextsHelper(GetColorContextsDelegate getColorContexts) { uint numContexts = 0; List <ColorContext> colorContextsList = null; int hr = getColorContexts(ref numContexts, null); if (hr != (int)WinCodecErrors.WINCODEC_ERR_UNSUPPORTEDOPERATION) { HRESULT.Check(hr); } if (numContexts > 0) { // GetColorContexts does not create new IWICColorContexts. Instead, it initializes existing // ones so we must create them beforehand. SafeMILHandle[] colorContextHandles = new SafeMILHandle[numContexts]; using (FactoryMaker factoryMaker = new FactoryMaker()) { for (uint i = 0; i < numContexts; ++i) { HRESULT.Check(UnsafeNativeMethodsMilCoreApi.WICCodec.CreateColorContext(factoryMaker.ImagingFactoryPtr, out colorContextHandles[i])); } } // The Marshal is unable to handle SafeMILHandle[] so we will convert it to an IntPtr[] ourselves. { IntPtr[] colorContextPtrs = new IntPtr[numContexts]; for (uint i = 0; i < numContexts; ++i) { colorContextPtrs[i] = colorContextHandles[i].DangerousGetHandle(); } HRESULT.Check(getColorContexts(ref numContexts, colorContextPtrs)); } colorContextsList = new List <ColorContext>((int)numContexts); for (uint i = 0; i < numContexts; ++i) { colorContextsList.Add(new ColorContext(colorContextHandles[i])); } } return(colorContextsList); }
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, /* dontThrowException = */ false); using (FactoryMaker factoryMaker = new FactoryMaker()) { HRESULT.Check(UnsafeNativeMethodsMilCoreApi.WICCodec.CreateColorContext(factoryMaker.ImagingFactoryPtr, out _colorContextHandle)); HRESULT.Check(IWICCC.InitializeFromMemory(_colorContextHandle, rawBytes, (uint)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); }
internal static IntPtr IStreamFrom(IntPtr memoryBuffer, int bufferSize) { IntPtr pIStream = IntPtr.Zero; using (FactoryMaker myFactory = new FactoryMaker()) { if (HRESULT.Failed(UnsafeNativeMethods.WICImagingFactory.CreateStream(myFactory.ImagingFactoryPtr, out pIStream))) { return(IntPtr.Zero); } if (HRESULT.Failed(UnsafeNativeMethods.WICStream.InitializeFromMemory(pIStream, memoryBuffer, (uint)bufferSize))) { UnsafeNativeMethods.MILUnknown.ReleaseInterface(ref pIStream); return(IntPtr.Zero); } } return(pIStream); }
internal IntPtr CreatePixelFormatInfo() { IntPtr componentInfo = IntPtr.Zero; IntPtr pixelFormatInfo = IntPtr.Zero; using (FactoryMaker myFactory = new FactoryMaker()) { try { Guid guidPixelFormat = this.Guid; int hr = UnsafeNativeMethods.WICImagingFactory.CreateComponentInfo( myFactory.ImagingFactoryPtr, ref guidPixelFormat, out componentInfo); if (hr == (int)WinCodecErrors.WINCODEC_ERR_COMPONENTINITIALIZEFAILURE || hr == (int)WinCodecErrors.WINCODEC_ERR_COMPONENTNOTFOUND) { throw new System.NotSupportedException(SR.Get(SRID.Image_NoPixelFormatFound)); } HRESULT.Check(hr); Guid guidPixelFormatInfo = MILGuidData.IID_IWICPixelFormatInfo; HRESULT.Check(UnsafeNativeMethods.MILUnknown.QueryInterface( componentInfo, ref guidPixelFormatInfo, out pixelFormatInfo)); } finally { if (componentInfo != IntPtr.Zero) { UnsafeNativeMethods.MILUnknown.ReleaseInterface(ref componentInfo); } } } return(pixelFormatInfo); }
private void EnsureUnmanagedEncoder() { if (_encoderHandle == null) { using (FactoryMaker myFactory = new FactoryMaker()) { SafeMILHandle encoderHandle = null; Guid vendorMicrosoft = new Guid(MILGuidData.GUID_VendorMicrosoft); Guid containerFormat = ContainerFormat; HRESULT.Check(UnsafeNativeMethods.WICImagingFactory.CreateEncoder( myFactory.ImagingFactoryPtr, ref containerFormat, ref vendorMicrosoft, out encoderHandle )); _encoderHandle = encoderHandle; } } }
internal override void FinalizeCreation() { _bitmapInit.EnsureInitializedComplete(); BitmapSourceSafeMILHandle wicClipper = null; Int32Rect rect = SourceRect; BitmapSource source = Source; if (rect.IsEmpty) { rect.Width = source.PixelWidth; rect.Height = source.PixelHeight; } using (FactoryMaker factoryMaker = new FactoryMaker()) { try { IntPtr wicFactory = factoryMaker.ImagingFactoryPtr; HRESULT.Check(UnsafeNativeMethods.WICImagingFactory.CreateBitmapClipper( wicFactory, out wicClipper)); lock (_syncObject) { HRESULT.Check(UnsafeNativeMethods.WICBitmapClipper.Initialize( wicClipper, source.WicSourceHandle, ref rect)); } // // This is just a link in a BitmapSource chain. The memory is being used by // the BitmapSource at the end of the chain, so no memory pressure needs // to be added here. // WicSourceHandle = wicClipper; _isSourceCached = source.IsSourceCached; wicClipper = null; } catch { _bitmapInit.Reset(); throw; } finally { if (wicClipper != null) { wicClipper.Close(); } } } CreationCompleted = true; UpdateCachedSettings(); }
internal static SafeMILHandle SetupDecoderFromUriOrStream( Uri uri, Stream stream, BitmapCacheOption cacheOption, out Guid clsId, out bool isOriginalWritable, out Stream uriStream, out UnmanagedMemoryStream unmanagedMemoryStream, out SafeFileHandle safeFilehandle ) { SafeMILHandle decoderHandle; IntPtr decoder = IntPtr.Zero; System.IO.Stream bitmapStream = null; string mimeType = String.Empty; // check to ensure that images are allowed in partial trust NOP in full trust DemandIfImageBlocked(); unmanagedMemoryStream = null; safeFilehandle = null; isOriginalWritable = false; uriStream = null; if ((uri != null) && (stream != null)) { // In this case we expect the Uri to be http(s) Debug.Assert((uri.Scheme == Uri.UriSchemeHttp) || (uri.Scheme == Uri.UriSchemeHttps)); Debug.Assert(stream.CanSeek); } // Uri if (uri != null) { if (uri.IsAbsoluteUri) { // In this case we first check to see if the consumer has media permissions for // safe media (Site of Origin + Cross domain) SecurityHelper.DemandMediaPermission(MediaPermissionAudio.NoAudio, MediaPermissionVideo.NoVideo, MediaPermissionImage.SiteOfOriginImage) ; // This code path executes only for pack web requests if (String.Compare(uri.Scheme, PackUriHelper.UriSchemePack, StringComparison.OrdinalIgnoreCase) == 0) { WebResponse response = WpfWebRequestHelper.CreateRequestAndGetResponse(uri); mimeType = response.ContentType; bitmapStream = response.GetResponseStream(); uriStream = bitmapStream; } } if ((bitmapStream == null) || (bitmapStream == System.IO.Stream.Null)) { // We didn't get a stream from the pack web request, so we have // to try to create one ourselves. if (uri.IsAbsoluteUri) { // The Uri class can't tell if it is a file unless it // has an absolute path. int targetZone = SecurityHelper.MapUrlToZoneWrapper(uri); if (targetZone == MS.Win32.NativeMethods.URLZONE_LOCAL_MACHINE) { if (uri.IsFile) { // FileStream does a demand for us, so no need to do a demand bitmapStream = new System.IO.FileStream(uri.LocalPath, FileMode.Open, FileAccess.Read, FileShare.Read); } } else // Any other zone { // UNC path for a file which is not http if (uri.IsFile && uri.IsUnc) // for UNC { bitmapStream = ProcessUncFiles(uri); } else if (uri.Scheme == Uri.UriSchemeHttp) // for http { bitmapStream = ProcessHttpFiles(uri,stream); } else if (uri.Scheme == Uri.UriSchemeHttps) // for https { bitmapStream = ProcessHttpsFiles(uri,stream); } else { // The Uri is a custom Uri. Try to grab the stream from its WebResponse. bitmapStream = WpfWebRequestHelper.CreateRequestAndGetResponseStream(uri); } } } else { #pragma warning disable 6518 // We don't have an absolute URI, so we don't necessarily know // if it is a file, but we'll have to assume it is and try to // create a stream from the original string. bitmapStream = new System.IO.FileStream(uri.OriginalString, FileMode.Open, FileAccess.Read, FileShare.Read); #pragma warning restore 6518 } uriStream = bitmapStream; } } // We need to use the stream created from the Uri. if (bitmapStream != null) { stream = bitmapStream; } else { // Note whether the original stream is writable. isOriginalWritable = stream.CanSeek && stream.CanWrite; } // Make sure we always use a seekable stream to avoid problems with http Uris etc. stream = GetSeekableStream(stream); if (stream is UnmanagedMemoryStream) { unmanagedMemoryStream = stream as UnmanagedMemoryStream; } IntPtr comStream = IntPtr.Zero; if (stream is System.IO.FileStream) { System.IO.FileStream filestream = stream as System.IO.FileStream; try { safeFilehandle = filestream.SafeFileHandle; } catch { // If Filestream doesn't support SafeHandle then revert to old code path. safeFilehandle = null; } } try { Guid vendorMicrosoft = new Guid(MILGuidData.GUID_VendorMicrosoft); UInt32 metadataFlags = (uint)WICMetadataCacheOptions.WICMetadataCacheOnDemand; if (cacheOption == BitmapCacheOption.OnLoad) { metadataFlags = (uint)WICMetadataCacheOptions.WICMetadataCacheOnLoad; } // We have a SafeHandle. if (safeFilehandle != null) { using (FactoryMaker myFactory = new FactoryMaker()) { HRESULT.Check(UnsafeNativeMethods.WICImagingFactory.CreateDecoderFromFileHandle( myFactory.ImagingFactoryPtr, safeFilehandle, ref vendorMicrosoft, metadataFlags, out decoder )); } } else { comStream = BitmapDecoder.GetIStreamFromStream(ref stream); using (FactoryMaker myFactory = new FactoryMaker()) { // This does an add-ref on the comStream HRESULT.Check(UnsafeNativeMethods.WICImagingFactory.CreateDecoderFromStream( myFactory.ImagingFactoryPtr, comStream, ref vendorMicrosoft, metadataFlags, out decoder )); } } Debug.Assert(decoder != IntPtr.Zero); decoderHandle = new SafeMILHandle(decoder); } catch { #pragma warning disable 6500 decoderHandle = null; throw; #pragma warning restore 6500 } finally { UnsafeNativeMethods.MILUnknown.ReleaseInterface(ref comStream); } string decoderMimeTypes; clsId = GetCLSIDFromDecoder(decoderHandle, out decoderMimeTypes); // If the mime type of the file does not match the associated decoder, // and if we are in a Partial trust scenario, throw! if ((mimeType != String.Empty) && (decoderMimeTypes.IndexOf(mimeType, StringComparison.OrdinalIgnoreCase) == -1)) { try { SecurityHelper.DemandUnmanagedCode(); } catch(SecurityException) { throw new ArgumentException(SR.Get(SRID.Image_ContentTypeDoesNotMatchDecoder)); } } return decoderHandle; }
internal override void FinalizeCreation() { _bitmapInit.EnsureInitializedComplete(); BitmapSourceSafeMILHandle wicTransformer = null; double scaleX, scaleY; WICBitmapTransformOptions options; GetParamsFromTransform(Transform, out scaleX, out scaleY, out options); using (FactoryMaker factoryMaker = new FactoryMaker()) { try { IntPtr wicFactory = factoryMaker.ImagingFactoryPtr; wicTransformer = _source.WicSourceHandle; if (!DoubleUtil.IsOne(scaleX) || !DoubleUtil.IsOne(scaleY)) { uint width = Math.Max(1, (uint)(scaleX * _source.PixelWidth + 0.5)); uint height = Math.Max(1, (uint)(scaleY * _source.PixelHeight + 0.5)); HRESULT.Check(UnsafeNativeMethods.WICImagingFactory.CreateBitmapScaler( wicFactory, out wicTransformer)); lock (_syncObject) { HRESULT.Check(UnsafeNativeMethods.WICBitmapScaler.Initialize( wicTransformer, _source.WicSourceHandle, width, height, WICInterpolationMode.Fant)); } } if (options != WICBitmapTransformOptions.WICBitmapTransformRotate0) { // Rotations are extremely slow if we're pulling from a decoder because we end // up decoding multiple times. Caching the source lets us rotate faster at the cost // of increased memory usage. wicTransformer = CreateCachedBitmap( null, wicTransformer, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default, _source.Palette); // BitmapSource.CreateCachedBitmap already calculates memory pressure for // the new bitmap, so there's no need to do it before setting it to // WicSourceHandle. BitmapSourceSafeMILHandle rotator = null; HRESULT.Check(UnsafeNativeMethods.WICImagingFactory.CreateBitmapFlipRotator( wicFactory, out rotator)); lock (_syncObject) { HRESULT.Check(UnsafeNativeMethods.WICBitmapFlipRotator.Initialize( rotator, wicTransformer, options)); } wicTransformer = rotator; } // If we haven't introduced either a scaler or rotator, add a null rotator // so that our WicSourceHandle isn't the same as our Source's. if (options == WICBitmapTransformOptions.WICBitmapTransformRotate0 && DoubleUtil.IsOne(scaleX) && DoubleUtil.IsOne(scaleY)) { HRESULT.Check(UnsafeNativeMethods.WICImagingFactory.CreateBitmapFlipRotator( wicFactory, out wicTransformer)); lock (_syncObject) { HRESULT.Check(UnsafeNativeMethods.WICBitmapFlipRotator.Initialize( wicTransformer, _source.WicSourceHandle, WICBitmapTransformOptions.WICBitmapTransformRotate0)); } } WicSourceHandle = wicTransformer; _isSourceCached = _source.IsSourceCached; } catch { _bitmapInit.Reset(); throw; } } CreationCompleted = true; UpdateCachedSettings(); }
internal override void FinalizeCreation() { BitmapSourceSafeMILHandle wicClipper = null; BitmapSourceSafeMILHandle wicTransformer = null; BitmapSourceSafeMILHandle transformedSource = _unmanagedSource; HRESULT.Check(UnsafeNativeMethods.WICBitmap.SetResolution(_unmanagedSource, 96, 96)); using (FactoryMaker factoryMaker = new FactoryMaker()) { IntPtr wicFactory = factoryMaker.ImagingFactoryPtr; if (!_sourceRect.IsEmpty) { HRESULT.Check(UnsafeNativeMethods.WICImagingFactory.CreateBitmapClipper( wicFactory, out wicClipper)); lock (_syncObject) { HRESULT.Check(UnsafeNativeMethods.WICBitmapClipper.Initialize( wicClipper, transformedSource, ref _sourceRect)); } transformedSource = wicClipper; } if (_sizeOptions != null) { if (_sizeOptions.DoesScale) { Debug.Assert(_sizeOptions.Rotation == Rotation.Rotate0); uint width, height; _sizeOptions.GetScaledWidthAndHeight( (uint)_sizeOptions.PixelWidth, (uint)_sizeOptions.PixelHeight, out width, out height); HRESULT.Check(UnsafeNativeMethods.WICImagingFactory.CreateBitmapScaler( wicFactory, out wicTransformer)); lock (_syncObject) { HRESULT.Check(UnsafeNativeMethods.WICBitmapScaler.Initialize( wicTransformer, transformedSource, width, height, WICInterpolationMode.Fant)); } } else if (_sizeOptions.Rotation != Rotation.Rotate0) { HRESULT.Check(UnsafeNativeMethods.WICImagingFactory.CreateBitmapFlipRotator( wicFactory, out wicTransformer)); lock (_syncObject) { HRESULT.Check(UnsafeNativeMethods.WICBitmapFlipRotator.Initialize( wicTransformer, transformedSource, _sizeOptions.WICTransformOptions)); } } if (wicTransformer != null) { transformedSource = wicTransformer; } } WicSourceHandle = transformedSource; // Since the original source is an HICON, HBITMAP or section, we know it's cached. // FlipRotate and Clipper do not affect our cache performance. _isSourceCached = true; } CreationCompleted = true; UpdateCachedSettings(); }
/// <summary> /// Create a ColorContext from an unmanaged color context /// </summary> private ColorContext(SafeMILHandle colorContextHandle) { _colorContextHandle = colorContextHandle; // // For 3.* backwards compat, we aren't going to HRESULT.Check() anywhere because // that could introduce new exceptions. If anything fails, _colorContextHelper // will be invalid and we'll emulate the old failure behavior later in // OpenProfileStream() // IWICCC.WICColorContextType type; if (HRESULT.Failed(IWICCC.GetType(_colorContextHandle, out type))) { return; } switch (type) { case IWICCC.WICColorContextType.WICColorContextProfile: uint cbProfileActual; int hr = IWICCC.GetProfileBytes(_colorContextHandle, 0, null, out cbProfileActual); if (HRESULT.Succeeded(hr) && cbProfileActual != 0) { byte[] profileData = new byte[cbProfileActual]; if (HRESULT.Failed(IWICCC.GetProfileBytes( _colorContextHandle, cbProfileActual, profileData, out cbProfileActual)) ) { return; } FromRawBytes(profileData, (int)cbProfileActual, /* dontThrowException = */ true); } break; case IWICCC.WICColorContextType.WICColorContextExifColorSpace: uint colorSpace; if (HRESULT.Failed(IWICCC.GetExifColorSpace(_colorContextHandle, out colorSpace))) { return; } // // From MSDN: // "1" is sRGB. We will use our built-in sRGB profile. // "2" is Adobe RGB. WIC says we should never see this because they are nonstandard and instead a // real profile will be returned. // "3-65534" is unused. // // From the Exif spec: // B. Tag Relating to Color Space // ColorSpace // // The color space information tag (ColorSpace) is always recorded as the color space specifier. // Normally sRGB (=1) is used to define the color space based on the PC monitor conditions and environment. If a // color space other than sRGB is used, Uncalibrated (=FFFF.H) is set. Image data recorded as Uncalibrated can be // treated as sRGB when it is converted to Flashpix. On sRGB see Annex E. // Tag = 40961 (A001.H) // Type = SHORT // Count = 1 // 1 = sRGB // FFFF.H = Uncalibrated // // So for 65535 we will return sRGB since it is acceptible rather than having an invalid ColorContext. The Exif // CC should always be the second one so the real one is given priority. Alternatively, we could ignore the // uncalibrated CC but that would be a breaking change with 3.* (returning 1 instead of 2). // // If anything other than 1 or 65535 happens, _colorContextHelper will remain invalid and we will emulate // the old crash behavior in OpenProfileStream(). // if (colorSpace == 1 || colorSpace == 65535) { ResourceManager resourceManager = new ResourceManager( _colorProfileResources, Assembly.GetAssembly(typeof(ColorContext)) ); byte[] sRGBProfile = (byte[])resourceManager.GetObject(_sRGBProfileName); // The existing ColorContext has already been initialized as Exif so we can't initialize it again // and instead must create a new one. using (FactoryMaker factoryMaker = new FactoryMaker()) { _colorContextHandle.Dispose(); _colorContextHandle = null; if (HRESULT.Failed(UnsafeNativeMethodsMilCoreApi.WICCodec.CreateColorContext( factoryMaker.ImagingFactoryPtr, out _colorContextHandle)) ) { return; } if (HRESULT.Failed(IWICCC.InitializeFromMemory( _colorContextHandle, sRGBProfile, (uint)sRGBProfile.Length)) ) { return; } } // Finally, fill in _colorContextHelper FromRawBytes(sRGBProfile, sRGBProfile.Length, /* dontThrowException = */ true); } else if (Invariant.Strict) { Invariant.Assert(false, String.Format(CultureInfo.InvariantCulture, "IWICColorContext::GetExifColorSpace returned {0}.", colorSpace)); } break; default: if (Invariant.Strict) { Invariant.Assert(false, "IWICColorContext::GetType() returned WICColorContextUninitialized."); } break; } // SECURITY NOTE: This constructor does not set a Uri because the profile comes from raw file // data. Thus, we don't set _isProfileUriNotFromUser to true because we // don't want get_ProfileUri to demand permission to return null. Debug.Assert(_profileUri.Value == null); }
internal static IList<ColorContext> GetColorContextsHelper(GetColorContextsDelegate getColorContexts) { uint numContexts = 0; List<ColorContext> colorContextsList = null; int hr = getColorContexts(ref numContexts, null); if (hr != (int)WinCodecErrors.WINCODEC_ERR_UNSUPPORTEDOPERATION) { HRESULT.Check(hr); } if (numContexts > 0) { // GetColorContexts does not create new IWICColorContexts. Instead, it initializes existing // ones so we must create them beforehand. SafeMILHandle[] colorContextHandles = new SafeMILHandle[numContexts]; using (FactoryMaker factoryMaker = new FactoryMaker()) { for (uint i = 0; i < numContexts; ++i) { HRESULT.Check(UnsafeNativeMethodsMilCoreApi.WICCodec.CreateColorContext(factoryMaker.ImagingFactoryPtr, out colorContextHandles[i])); } } // The Marshal is unable to handle SafeMILHandle[] so we will convert it to an IntPtr[] ourselves. { IntPtr[] colorContextPtrs = new IntPtr[numContexts]; for (uint i = 0; i < numContexts; ++i) { colorContextPtrs[i] = colorContextHandles[i].DangerousGetHandle(); } HRESULT.Check(getColorContexts(ref numContexts, colorContextPtrs)); } colorContextsList = new List<ColorContext>((int)numContexts); for (uint i = 0; i < numContexts; ++i) { colorContextsList.Add(new ColorContext(colorContextHandles[i])); } } return colorContextsList;
private ColorContext(SafeMILHandle colorContextHandle) { _colorContextHandle = colorContextHandle; // // For 3.* backwards compat, we aren't going to HRESULT.Check() anywhere because // that could introduce new exceptions. If anything fails, _colorContextHelper // will be invalid and we'll emulate the old failure behavior later in // OpenProfileStream() // IWICCC.WICColorContextType type; if (HRESULT.Failed(IWICCC.GetType(_colorContextHandle, out type))) { return; } switch (type) { case IWICCC.WICColorContextType.WICColorContextProfile: uint cbProfileActual; int hr = IWICCC.GetProfileBytes(_colorContextHandle, 0, null, out cbProfileActual); if (HRESULT.Succeeded(hr) && cbProfileActual != 0) { byte[] profileData = new byte[cbProfileActual]; if (HRESULT.Failed(IWICCC.GetProfileBytes( _colorContextHandle, cbProfileActual, profileData, out cbProfileActual)) ) { return; } FromRawBytes(profileData, (int)cbProfileActual, /* dontThrowException = */ true); } break; case IWICCC.WICColorContextType.WICColorContextExifColorSpace: uint colorSpace; if (HRESULT.Failed(IWICCC.GetExifColorSpace(_colorContextHandle, out colorSpace))) { return; } // // From MSDN: // "1" is sRGB. We will use our built-in sRGB profile. // "2" is Adobe RGB. WIC says we should never see this because they are nonstandard and instead a // real profile will be returned. // "3-65534" is unused. // // From the Exif spec: // B. Tag Relating to Color Space // ColorSpace // // The color space information tag (ColorSpace) is always recorded as the color space specifier. // Normally sRGB (=1) is used to define the color space based on the PC monitor conditions and environment. If a // color space other than sRGB is used, Uncalibrated (=FFFF.H) is set. Image data recorded as Uncalibrated can be // treated as sRGB when it is converted to Flashpix. On sRGB see Annex E. // Tag = 40961 (A001.H) // Type = SHORT // Count = 1 // 1 = sRGB // FFFF.H = Uncalibrated // // So for 65535 we will return sRGB since it is acceptible rather than having an invalid ColorContext. The Exif // CC should always be the second one so the real one is given priority. Alternatively, we could ignore the // uncalibrated CC but that would be a breaking change with 3.* (returning 1 instead of 2). // // If anything other than 1 or 65535 happens, _colorContextHelper will remain invalid and we will emulate // the old crash behavior in OpenProfileStream(). // if (colorSpace == 1 || colorSpace == 65535) { ResourceManager resourceManager = new ResourceManager( _colorProfileResources, Assembly.GetAssembly(typeof(ColorContext)) ); byte[] sRGBProfile = (byte[])resourceManager.GetObject(_sRGBProfileName); // The existing ColorContext has already been initialized as Exif so we can't initialize it again // and instead must create a new one. using (FactoryMaker factoryMaker = new FactoryMaker()) { _colorContextHandle.Dispose(); _colorContextHandle = null; if (HRESULT.Failed(UnsafeNativeMethodsMilCoreApi.WICCodec.CreateColorContext( factoryMaker.ImagingFactoryPtr, out _colorContextHandle)) ) { return; } if (HRESULT.Failed(IWICCC.InitializeFromMemory( _colorContextHandle, sRGBProfile, (uint)sRGBProfile.Length)) ) { return; } } // Finally, fill in _colorContextHelper FromRawBytes(sRGBProfile, sRGBProfile.Length, /* dontThrowException = */ true); } else if (Invariant.Strict) { Invariant.Assert(false, String.Format(CultureInfo.InvariantCulture, "IWICColorContext::GetExifColorSpace returned {0}.", colorSpace)); } break; default: if (Invariant.Strict) { Invariant.Assert(false, "IWICColorContext::GetType() returned WICColorContextUninitialized."); } break; } // SECURITY NOTE: This constructor does not set a Uri because the profile comes from raw file // data. Thus, we don't set _isProfileUriNotFromUser to true because we // don't want get_ProfileUri to demand permission to return null. Debug.Assert(_profileUri.Value == null); }
private void InitFromMemoryPtr( int pixelWidth, int pixelHeight, double dpiX, double dpiY, PixelFormat pixelFormat, BitmapPalette palette, IntPtr buffer, int bufferSize, int stride ) { if (pixelFormat.Palettized == true && palette == null) throw new InvalidOperationException(SR.Get(SRID.Image_IndexedPixelFormatRequiresPalette)); if (pixelFormat.Format == PixelFormatEnum.Default && pixelFormat.Guid == WICPixelFormatGUIDs.WICPixelFormatDontCare) { throw new System.ArgumentException( SR.Get(SRID.Effect_PixelFormat, pixelFormat), "pixelFormat" ); } _bitmapInit.BeginInit(); try { BitmapSourceSafeMILHandle wicBitmap; // Create the unmanaged resources Guid guidFmt = pixelFormat.Guid; using (FactoryMaker factoryMaker = new FactoryMaker()) { HRESULT.Check(UnsafeNativeMethods.WICImagingFactory.CreateBitmapFromMemory( factoryMaker.ImagingFactoryPtr, (uint)pixelWidth, (uint)pixelHeight, ref guidFmt, (uint)stride, (uint)bufferSize, buffer, out wicBitmap)); wicBitmap.CalculateSize(); } HRESULT.Check(UnsafeNativeMethods.WICBitmap.SetResolution( wicBitmap, dpiX, dpiY)); if (pixelFormat.Palettized) { HRESULT.Check(UnsafeNativeMethods.WICBitmap.SetPalette( wicBitmap, palette.InternalPalette)); } WicSourceHandle = wicBitmap; _isSourceCached = true; } catch { _bitmapInit.Reset(); throw; } _createOptions = BitmapCreateOptions.PreservePixelFormat; _cacheOption = BitmapCacheOption.OnLoad; _syncObject = WicSourceHandle; _bitmapInit.EndInit(); UpdateCachedSettings(); }
private void CreateMedia(MediaPlayer mediaPlayer) { CheckMediaDisabledFlags(); SafeMILHandle unmanagedProxy = null; MediaEventsHelper.CreateMediaEventsHelper(mediaPlayer, out _mediaEventsHelper, out unmanagedProxy); try { using (FactoryMaker myFactory = new FactoryMaker()) { HRESULT.Check(UnsafeNativeMethods.MILFactory2.CreateMediaPlayer( myFactory.FactoryPtr, unmanagedProxy, SecurityHelper.CallerHasMediaPermission(MediaPermissionAudio.AllAudio, MediaPermissionVideo.AllVideo, MediaPermissionImage.NoImage), out _nativeMedia )); } } catch { if (_nativeMedia != null && !_nativeMedia.IsInvalid) { _nativeMedia.Close(); } throw; } _helper = new Helper(_nativeMedia); AppDomain.CurrentDomain.ProcessExit += _helper.ProcessExitHandler; }
internal InteropBitmap(IntPtr hicon, Int32Rect sourceRect, BitmapSizeOptions sizeOptions) : base(true) // Use virtuals { SecurityHelper.DemandUnmanagedCode(); _bitmapInit.BeginInit(); using (FactoryMaker myFactory = new FactoryMaker()) { HRESULT.Check(UnsafeNativeMethods.WICImagingFactory.CreateBitmapFromHICON( myFactory.ImagingFactoryPtr, hicon, out _unmanagedSource)); Debug.Assert (_unmanagedSource != null && !_unmanagedSource.IsInvalid); } _unmanagedSource.CalculateSize(); _sourceRect = sourceRect; _sizeOptions = sizeOptions; _syncObject = _unmanagedSource; _bitmapInit.EndInit(); FinalizeCreation(); }
internal static BitmapSourceSafeMILHandle CreateCachedBitmap( BitmapFrame frame, BitmapSourceSafeMILHandle wicSource, BitmapCreateOptions createOptions, BitmapCacheOption cacheOption, BitmapPalette palette ) { BitmapSourceSafeMILHandle wicConverter = null; BitmapSourceSafeMILHandle wicConvertedSource = null; // For NoCache, return the original if (cacheOption == BitmapCacheOption.None) { return wicSource; } using (FactoryMaker factoryMaker = new FactoryMaker()) { IntPtr wicFactory = factoryMaker.ImagingFactoryPtr; bool changeFormat = false; PixelFormat originalFmt = PixelFormats.Pbgra32; WICBitmapCreateCacheOptions wicCache = WICBitmapCreateCacheOptions.WICBitmapCacheOnLoad; if (cacheOption == BitmapCacheOption.OnDemand) { wicCache = WICBitmapCreateCacheOptions.WICBitmapCacheOnDemand; } originalFmt = PixelFormat.GetPixelFormat(wicSource); PixelFormat destFmt = originalFmt; // check that we need to change the format of the bitmap if (0 == (createOptions & BitmapCreateOptions.PreservePixelFormat)) { if (!IsCompatibleFormat(originalFmt)) changeFormat = true; destFmt = BitmapSource.GetClosestDUCEFormat(originalFmt, palette); } if (frame != null && (createOptions & BitmapCreateOptions.IgnoreColorProfile) == 0 && frame.ColorContexts != null && frame.ColorContexts[0] != null && frame.ColorContexts[0].IsValid && !frame._isColorCorrected && PixelFormat.GetPixelFormat(wicSource).Format != PixelFormatEnum.Extended ) { ColorContext destinationColorContext; // We need to make sure, we can actually create the ColorContext for the destination destFmt // If the destFmt is gray or scRGB, the following is not supported, so we cannot // create the ColorConvertedBitmap try { destinationColorContext = new ColorContext(destFmt); } catch (NotSupportedException) { destinationColorContext = null; } if (destinationColorContext != null) { // NOTE: Never do this for a non-MIL pixel format, because the format converter has // special knowledge to deal with the profile bool conversionSuccess = false; bool badColorContext = false; // First try if the color converter can handle the source format directly // Its possible that the color converter does not support certain pixelformats, so put a try/catch here. try { ColorConvertedBitmap colorConvertedBitmap = new ColorConvertedBitmap( frame, frame.ColorContexts[0], destinationColorContext, destFmt ); wicSource = colorConvertedBitmap.WicSourceHandle; frame._isColorCorrected = true; conversionSuccess = true; changeFormat = false; // Changeformat no longer necessary, because destFmt already created // by ColorConvertedBitmap } catch (NotSupportedException) { } catch (FileFormatException) { // If the file contains a bad color context, we catch the exception here // and don't bother trying the color conversion below, since color transform isn't possible // with the given color context. badColorContext = true; } if (!conversionSuccess && changeFormat && !badColorContext) { // If the conversion failed, we first use // a FormatConvertedBitmap, and then Color Convert that one... changeFormat = false; FormatConvertedBitmap formatConvertedBitmap = new FormatConvertedBitmap(frame, destFmt, null, 0.0); ColorConvertedBitmap colorConvertedBitmap = new ColorConvertedBitmap( formatConvertedBitmap, frame.ColorContexts[0], destinationColorContext, destFmt ); wicSource = colorConvertedBitmap.WicSourceHandle; frame._isColorCorrected = true; Debug.Assert(destFmt == colorConvertedBitmap.Format); changeFormat = false; // Changeformat no longer necessary, because destFmt already created // by ColorConvertedBitmap } } } if (changeFormat) { // start up a format converter Guid fmtDestFmt = destFmt.Guid; HRESULT.Check(UnsafeNativeMethods.WICCodec.WICConvertBitmapSource( ref fmtDestFmt, wicSource, out wicConverter)); // dump the converted contents into a bitmap HRESULT.Check(UnsafeNativeMethods.WICImagingFactory.CreateBitmapFromSource( wicFactory, wicConverter, wicCache, out wicConvertedSource)); } else { // Create the unmanaged resources HRESULT.Check(UnsafeNativeMethods.WICImagingFactory.CreateBitmapFromSource( wicFactory, wicSource, wicCache, out wicConvertedSource)); } wicConvertedSource.CalculateSize(); } return wicConvertedSource; }
internal override void FinalizeCreation() { try { using (FactoryMaker myFactory = new FactoryMaker()) { SafeMILHandle renderTargetBitmap = null; HRESULT.Check(UnsafeNativeMethods.MILFactory2.CreateBitmapRenderTarget( myFactory.FactoryPtr, (uint)_pixelWidth, (uint)_pixelHeight, _format.Format, (float)_dpiX, (float)_dpiY, MILRTInitializationFlags.MIL_RT_INITIALIZE_DEFAULT, out renderTargetBitmap)); Debug.Assert(renderTargetBitmap != null && !renderTargetBitmap.IsInvalid); BitmapSourceSafeMILHandle bitmapSource = null; HRESULT.Check(MILRenderTargetBitmap.GetBitmap( renderTargetBitmap, out bitmapSource)); Debug.Assert(bitmapSource != null && !bitmapSource.IsInvalid); lock (_syncObject) { _renderTargetBitmap = renderTargetBitmap; bitmapSource.CalculateSize(); WicSourceHandle = bitmapSource; // For the purpose of rendering a RenderTargetBitmap, we always treat it as if it's // not cached. This is to ensure we never render and write to the same bitmap source // by the UCE thread and managed thread. _isSourceCached = false; } } CreationCompleted = true; UpdateCachedSettings(); } catch { _bitmapInit.Reset(); throw; } }
static internal SafeMILHandle CreateInternalPalette() { SafeMILHandle palette = null; using (FactoryMaker myFactory = new FactoryMaker()) { HRESULT.Check(UnsafeNativeMethods.WICImagingFactory.CreatePalette( myFactory.ImagingFactoryPtr, out palette)); Debug.Assert(palette != null && !palette.IsInvalid); } return palette; }
internal override void FinalizeCreation() { _bitmapInit.EnsureInitializedComplete(); BitmapSourceSafeMILHandle wicFormatter = null; using (FactoryMaker factoryMaker = new FactoryMaker()) { try { IntPtr wicFactory = factoryMaker.ImagingFactoryPtr; HRESULT.Check(UnsafeNativeMethods.WICImagingFactory.CreateFormatConverter( wicFactory, out wicFormatter)); SafeMILHandle internalPalette; if (DestinationPalette != null) internalPalette = DestinationPalette.InternalPalette; else internalPalette = new SafeMILHandle(); Guid format = DestinationFormat.Guid; lock (_syncObject) { HRESULT.Check(UnsafeNativeMethods.WICFormatConverter.Initialize( wicFormatter, Source.WicSourceHandle, ref format, DitherType.DitherTypeErrorDiffusion, internalPalette, AlphaThreshold, WICPaletteType.WICPaletteTypeOptimal )); } // // This is just a link in a BitmapSource chain. The memory is being used by // the BitmapSource at the end of the chain, so no memory pressure needs // to be added here. // WicSourceHandle = wicFormatter; // Even if our source is cached, format conversion is expensive and so we'll // always maintain our own cache for the purpose of rendering. _isSourceCached = false; } catch { _bitmapInit.Reset(); throw; } finally { if (wicFormatter != null) { wicFormatter.Close(); } } } CreationCompleted = true; UpdateCachedSettings(); }
[SecurityCritical] 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, /* dontThrowException = */ false); using (FactoryMaker factoryMaker = new FactoryMaker()) { HRESULT.Check(UnsafeNativeMethodsMilCoreApi.WICCodec.CreateColorContext(factoryMaker.ImagingFactoryPtr, out _colorContextHandle)); HRESULT.Check(IWICCC.InitializeFromMemory(_colorContextHandle, rawBytes, (uint)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);
private void InitFromWICSource( SafeMILHandle wicSource ) { _bitmapInit.BeginInit(); BitmapSourceSafeMILHandle bitmapSource = null; lock (_syncObject) { using (FactoryMaker factoryMaker = new FactoryMaker()) { HRESULT.Check(UnsafeNativeMethods.WICImagingFactory.CreateBitmapFromSource( factoryMaker.ImagingFactoryPtr, wicSource, WICBitmapCreateCacheOptions.WICBitmapCacheOnLoad, out bitmapSource)); } bitmapSource.CalculateSize(); } WicSourceHandle = bitmapSource; _isSourceCached = true; _bitmapInit.EndInit(); UpdateCachedSettings(); }
internal static IntPtr IStreamFrom(IntPtr memoryBuffer, int bufferSize) { IntPtr pIStream = IntPtr.Zero; using (FactoryMaker myFactory = new FactoryMaker()) { if (HRESULT.Failed(UnsafeNativeMethods.WICImagingFactory.CreateStream(myFactory.ImagingFactoryPtr, out pIStream))) { return IntPtr.Zero; } if (HRESULT.Failed(UnsafeNativeMethods.WICStream.InitializeFromMemory(pIStream, memoryBuffer, (uint) bufferSize))) { UnsafeNativeMethods.MILUnknown.ReleaseInterface(ref pIStream); return IntPtr.Zero; } } return pIStream; }
private void CopyCommon(RenderTargetBitmap sourceBitmap) { _bitmapInit.BeginInit(); _pixelWidth = sourceBitmap._pixelWidth; _pixelHeight = sourceBitmap._pixelHeight; _dpiX = sourceBitmap._dpiX; _dpiY = sourceBitmap._dpiY; _format = sourceBitmap._format; // // In order to make a deep clone we need to // create a new bitmap with the contents of the // existing bitmap and then create a render target // from the new bitmap. // using (FactoryMaker myFactory = new FactoryMaker()) { // Create an IWICBitmap BitmapSourceSafeMILHandle newBitmapHandle = BitmapSource.CreateCachedBitmap( null, WicSourceHandle, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnLoad, null); lock (_syncObject) { WicSourceHandle = newBitmapHandle; } // Now create a Render target from that Bitmap HRESULT.Check(UnsafeNativeMethods.MILFactory2.CreateBitmapRenderTargetForBitmap( myFactory.FactoryPtr, newBitmapHandle, out _renderTargetBitmap )); } _bitmapInit.EndInit(); }