private void EnsureMetadata(bool createBitmapMetadata) { if (!_supportsGlobalMetadata) { return; } if (_metadataHandle == null) { SafeMILHandle /* IWICMetadataQueryWriter */ metadataHandle = new SafeMILHandle(); int hr = UnsafeNativeMethods.WICBitmapEncoder.GetMetadataQueryWriter( _encoderHandle, out metadataHandle ); if (hr == (int)WinCodecErrors.WINCODEC_ERR_UNSUPPORTEDOPERATION) { _supportsGlobalMetadata = false; return; } HRESULT.Check(hr); _metadataHandle = metadataHandle; } if (createBitmapMetadata && _metadata == null && _metadataHandle != null) { _metadata = new BitmapMetadata(_metadataHandle, false, IsMetadataFixedSize, _metadataHandle); } }
/// /// Create from WICBitmapSource /// 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 override void SetupFrame(SafeMILHandle frameEncodeHandle, SafeMILHandle encoderOptions) { HRESULT.Check(UnsafeNativeMethods.WICBitmapFrameEncode.Initialize( frameEncodeHandle, encoderOptions )); }
/// <summary> /// Setups the encoder and other properties before encoding each frame /// </summary> internal override void SetupFrame(SafeMILHandle frameEncodeHandle, SafeMILHandle encoderOptions) { PROPBAG2 propBag = new PROPBAG2(); PROPVARIANT propValue = new PROPVARIANT(); // There is only one encoder option supported here: if (_compressionMethod != c_defaultCompressionMethod) { try { propBag.Init("TiffCompressionMethod"); propValue.Init((byte)_compressionMethod); HRESULT.Check(UnsafeNativeMethods.IPropertyBag2.Write( encoderOptions, 1, ref propBag, ref propValue)); } finally { propBag.Clear(); propValue.Clear(); } } HRESULT.Check(UnsafeNativeMethods.WICBitmapFrameEncode.Initialize( frameEncodeHandle, encoderOptions )); }
/// <summary> /// /// </summary> private void Init(Guid containerFormat, bool readOnly, bool fixedSize) { int hr = 0; IntPtr /* IWICMetadataQueryWriter */ queryWriter = IntPtr.Zero; using (FactoryMaker factoryMaker = new FactoryMaker()) { Guid vendorMicrosoft = new Guid(MILGuidData.GUID_VendorMicrosoft); // If it's a metadata format, create a Query Writer to wrap it. hr = UnsafeNativeMethods.WICImagingFactory.CreateQueryWriter( factoryMaker.ImagingFactoryPtr, ref containerFormat, ref vendorMicrosoft, out queryWriter ); } if (HRESULT.Succeeded(hr)) { _readOnly = readOnly; _fixedSize = fixedSize; _blockWriter = null; _metadataHandle = new SafeMILHandle(queryWriter); _syncObject = _metadataHandle; } else { InitializeFromBlockWriter(containerFormat, readOnly, fixedSize); } }
/// <summary> /// This method is part of an interface that is only called by way of WindowsCodec. It is not /// publicly exposed or accessible in any way. /// </summary> public int SetWriterByIndex( UInt32 index, IntPtr /* IWICMetadataWriter */ pIMetadataWriter ) { if (index >= _metadataBlocks.Count) { return((int)WinCodecErrors.WINCODEC_ERR_PROPERTYNOTFOUND); } if (pIMetadataWriter == IntPtr.Zero) { return((int)WinCodecErrors.WINCODEC_ERR_INVALIDPARAMETER); } if (_fixedSize) { return((int)WinCodecErrors.WINCODEC_ERR_UNSUPPORTEDOPERATION); } SafeMILHandle metadataWriter = new SafeMILHandle(pIMetadataWriter); UnsafeNativeMethods.MILUnknown.AddRef(metadataWriter); _metadataBlocks[(int)index] = metadataWriter; return(MS.Win32.NativeMethods.S_OK); }
internal BitmapPalette(SafeMILHandle unmanagedPalette) { _palette = unmanagedPalette; // Fill in the Colors property. UpdateManaged(); }
/// <summary> /// /// </summary> internal InPlaceBitmapMetadataWriter( SafeMILHandle /* IWICFastMetadataEncoder */ fmeHandle, SafeMILHandle /* IWICMetadataQueryWriter */ metadataHandle, object syncObject ) : base(metadataHandle, false, false, syncObject) { _fmeHandle = fmeHandle; }
internal InPlaceBitmapMetadataWriter( SafeMILHandle /* IWICFastMetadataEncoder */ fmeHandle, SafeMILHandle /* IWICMetadataQueryWriter */ metadataHandle, object syncObject ) : base(metadataHandle, false, false, syncObject) { _fmeHandle = fmeHandle; }
internal static extern int /* HRESULT */ Create( uint width, uint height, double dpiX, double dpiY, ref Guid pixelFormatGuid, SafeMILHandle /* IWICPalette */ pPalette, out SafeMILHandle /* CSwDoubleBufferedBitmap */ ppSwDoubleBufferedBitmap);
private void EnsureThumbnail() { if (_isThumbnailCached || IsDownloading) { return; } else { EnsureSource(); IntPtr /* IWICBitmapSource */ thumbnail = IntPtr.Zero; lock (_syncObject) { // Check if there is embedded thumbnail or not int hr = UnsafeNativeMethods.WICBitmapFrameDecode.GetThumbnail( _frameSource, out thumbnail ); if (hr != (int)WinCodecErrors.WINCODEC_ERR_CODECNOTHUMBNAIL) { HRESULT.Check(hr); } } _isThumbnailCached = true; if (thumbnail != IntPtr.Zero) { BitmapSourceSafeMILHandle thumbHandle = new BitmapSourceSafeMILHandle(thumbnail); SafeMILHandle unmanagedPalette = BitmapPalette.CreateInternalPalette(); BitmapPalette palette = null; int hr = UnsafeNativeMethods.WICBitmapSource.CopyPalette( thumbHandle, unmanagedPalette ); if (hr == HRESULT.S_OK) { palette = new BitmapPalette(unmanagedPalette); } _thumbnail = new UnmanagedBitmapWrapper( CreateCachedBitmap( null, thumbHandle, BitmapCreateOptions.PreservePixelFormat, _cacheOption, palette )); _thumbnail.Freeze(); } } }
internal BitmapMetadataEnumerator(SafeMILHandle metadataHandle) { Debug.Assert(metadataHandle != null && !metadataHandle.IsInvalid); HRESULT.Check(UnsafeNativeMethods.WICMetadataQueryReader.GetEnumerator( metadataHandle, out _enumeratorHandle)); _current = null; _fStarted = false; }
internal override void SetupFrame(SafeMILHandle frameEncodeHandle, SafeMILHandle encoderOptions) { PROPBAG2 propBag = new PROPBAG2(); PROPVARIANT propValue = new PROPVARIANT(); // There are only two encoder options supported here: if (_transformation != c_defaultTransformation) { try { propBag.Init("BitmapTransform"); propValue.Init((byte)_transformation); HRESULT.Check(UnsafeNativeMethods.IPropertyBag2.Write( encoderOptions, 1, ref propBag, ref propValue)); } finally { propBag.Clear(); propValue.Clear(); } } if (_qualityLevel != c_defaultQualityLevel) { try { propBag.Init("ImageQuality"); propValue.Init(((float)_qualityLevel) / 100.0f); HRESULT.Check(UnsafeNativeMethods.IPropertyBag2.Write( encoderOptions, 1, ref propBag, ref propValue)); } finally { propBag.Clear(); propValue.Clear(); } } HRESULT.Check(UnsafeNativeMethods.WICBitmapFrameEncode.Initialize( frameEncodeHandle, encoderOptions )); }
/// <summary> /// /// </summary> internal BitmapMetadata( SafeMILHandle metadataHandle, bool readOnly, bool fixedSize, object syncObject ) { _metadataHandle = metadataHandle; _readOnly = readOnly; _fixedSize = fixedSize; _blockWriter = null; _syncObject = syncObject; }
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); }
/// <summary> /// Internal Constructor /// </summary> internal GifBitmapDecoder( SafeMILHandle decoderHandle, BitmapDecoder decoder, Uri baseUri, Uri uri, Stream stream, BitmapCreateOptions createOptions, BitmapCacheOption cacheOption, bool insertInDecoderCache, bool originalWritable, Stream uriStream, UnmanagedMemoryStream unmanagedMemoryStream, SafeFileHandle safeFilehandle ) : base(decoderHandle, decoder, baseUri, uri, stream, createOptions, cacheOption, insertInDecoderCache, originalWritable, uriStream, unmanagedMemoryStream, safeFilehandle) { }
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; } }
/// <summary> /// /// </summary> private void InitializeFromMetadataWriter(SafeMILHandle metadataHandle, object syncObject) { int hr; IntPtr queryWriter = IntPtr.Zero; Guid guidVendor = new Guid(MILGuidData.GUID_VendorMicrosoft); // Create a query writer for this metadata format try { using (FactoryMaker factoryMaker = new FactoryMaker()) { lock (syncObject) { hr = UnsafeNativeMethods.WICImagingFactory.CreateQueryWriterFromReader( factoryMaker.ImagingFactoryPtr, metadataHandle, ref guidVendor, out queryWriter); } } if (HRESULT.Succeeded(hr)) { _readOnly = false; _fixedSize = false; _blockWriter = null; _metadataHandle = new SafeMILHandle(queryWriter); queryWriter = IntPtr.Zero; _syncObject = _metadataHandle; } else if (!HRESULT.IsWindowsCodecError(hr)) { HRESULT.Check(hr); } } finally { if (queryWriter != IntPtr.Zero) { #pragma warning suppress 6031 // Return value ignored on purpose. UnsafeNativeMethods.MILUnknown.Release(queryWriter); } } }
/// <summary> /// /// </summary> private void InitializeFromBlockWriter(BitmapMetadataBlockWriter sourceBlockWriter, object syncObject) { IntPtr /* IWICMetadataBlockWriter */ blockWriter = IntPtr.Zero; IntPtr /* IWICMetadataQueryWriter */ queryWriter = IntPtr.Zero; using (FactoryMaker factoryMaker = new FactoryMaker()) { try { // Otherwise, simulate a metadata block writer for this imaging container format. _blockWriter = new BitmapMetadataBlockWriter(sourceBlockWriter, syncObject); blockWriter = Marshal.GetComInterfaceForObject( _blockWriter, typeof(System.Windows.Media.Imaging.BitmapMetadata.IWICMetadataBlockWriter)); HRESULT.Check(UnsafeNativeMethods.WICComponentFactory.CreateQueryWriterFromBlockWriter( factoryMaker.ImagingFactoryPtr, blockWriter, ref queryWriter )); _readOnly = false; _fixedSize = false; _metadataHandle = new SafeMILHandle(queryWriter); queryWriter = IntPtr.Zero; _syncObject = _metadataHandle; } finally { if (blockWriter != IntPtr.Zero) { #pragma warning suppress 6031 // Return value ignored on purpose. UnsafeNativeMethods.MILUnknown.Release(blockWriter); } if (queryWriter != IntPtr.Zero) { #pragma warning suppress 6031 // Return value ignored on purpose. UnsafeNativeMethods.MILUnknown.Release(queryWriter); } } } }
static internal BitmapPalette CreateFromBitmapSource(BitmapSource source) { Debug.Assert(source != null); SafeMILHandle bitmapSource = source.WicSourceHandle; Debug.Assert(bitmapSource != null && !bitmapSource.IsInvalid); SafeMILHandle unmanagedPalette = CreateInternalPalette(); BitmapPalette palette; // Don't throw on the HRESULT from this method. If it returns failure, // that likely means that the source doesn't have a palette. lock (source.SyncObject) { int hr = UnsafeNativeMethods.WICBitmapSource.CopyPalette( bitmapSource, unmanagedPalette); if (hr != HRESULT.S_OK) { return(null); } } WICPaletteType paletteType; bool hasAlpha; HRESULT.Check(UnsafeNativeMethods.WICPalette.GetType(unmanagedPalette, out paletteType)); HRESULT.Check(UnsafeNativeMethods.WICPalette.HasAlpha(unmanagedPalette, out hasAlpha)); if (paletteType == WICPaletteType.WICPaletteTypeCustom || paletteType == WICPaletteType.WICPaletteTypeOptimal) { palette = new BitmapPalette(unmanagedPalette); } else { palette = BitmapPalettes.FromMILPaletteType(paletteType, hasAlpha); Debug.Assert(palette != null); } return(palette); }
internal BitmapMetadataBlockWriter(BitmapMetadataBlockWriter blockWriter, object syncObject) { Guid guidVendor = new Guid(MILGuidData.GUID_VendorMicrosoft); _fixedSize = blockWriter._fixedSize; _containerFormat = blockWriter._containerFormat; _metadataBlocks = new ArrayList(); ArrayList metadataBlocks = blockWriter.MetadataBlocks; using (FactoryMaker factoryMaker = new FactoryMaker()) { foreach (SafeMILHandle metadataHandle in metadataBlocks) { lock (syncObject) { IntPtr pIMetadataWriter = IntPtr.Zero; try { HRESULT.Check(UnsafeNativeMethods.WICComponentFactory.CreateMetadataWriterFromReader( factoryMaker.ImagingFactoryPtr, metadataHandle, ref guidVendor, out pIMetadataWriter )); SafeMILHandle metadataWriter = new SafeMILHandle(pIMetadataWriter); pIMetadataWriter = IntPtr.Zero; _metadataBlocks.Add(metadataWriter); } finally { if (pIMetadataWriter != IntPtr.Zero) { #pragma warning suppress 6031 // Return value ignored on purpose. UnsafeNativeMethods.MILUnknown.Release(pIMetadataWriter); } } } } } }
/// <summary> /// This method is part of an interface that is only called by way of WindowsCodec. It is not /// publicly exposed or accessible in any way. /// </summary> public int GetWriterByIndex( UInt32 index, out IntPtr /* IWICMetadataWriter */ pIMetadataWriter ) { if (index >= _metadataBlocks.Count) { pIMetadataWriter = IntPtr.Zero; return((int)WinCodecErrors.WINCODEC_ERR_PROPERTYNOTFOUND); } SafeMILHandle metadataWriter = (SafeMILHandle)_metadataBlocks[(int)index]; Guid wicMetadataWriter = MILGuidData.IID_IWICMetadataWriter; return(UnsafeNativeMethods.MILUnknown.QueryInterface( metadataWriter, ref wicMetadataWriter, out pIMetadataWriter)); }
/// <summary> /// This method is part of an interface that is only called by way of WindowsCodec. It is not /// publicly exposed or accessible in any way. /// </summary> public int AddWriter( IntPtr /* IWICMetadataWriter */ pIMetadataWriter ) { if (pIMetadataWriter == IntPtr.Zero) { return((int)WinCodecErrors.WINCODEC_ERR_INVALIDPARAMETER); } if (_fixedSize && _metadataBlocks.Count > 0) { return((int)WinCodecErrors.WINCODEC_ERR_UNSUPPORTEDOPERATION); } SafeMILHandle metadataWriter = new SafeMILHandle(pIMetadataWriter); UnsafeNativeMethods.MILUnknown.AddRef(metadataWriter); _metadataBlocks.Add(metadataWriter); return(MS.Win32.NativeMethods.S_OK); }
/// <summary> /// This method is part of an interface that is only called by way of WindowsCodec. It is not /// publicly exposed or accessible in any way. /// </summary> public int Next( UInt32 celt, out IntPtr /* IUnknown ** */ rgelt, ref UInt32 pceltFetched ) { // This implementation only supports single enumeration. if (celt > 1) { rgelt = IntPtr.Zero; pceltFetched = 0; return((int)WinCodecErrors.WINCODEC_ERR_UNSUPPORTEDOPERATION); } if (_index >= _metadataBlocks.Count || celt == 0) { rgelt = IntPtr.Zero; pceltFetched = 0; return(MS.Win32.NativeMethods.S_FALSE); } else { SafeMILHandle metadataHandle = (SafeMILHandle)_metadataBlocks[(int)_index]; Guid wicMetadataReader = MILGuidData.IID_IWICMetadataReader; int hr = UnsafeNativeMethods.MILUnknown.QueryInterface( metadataHandle, ref wicMetadataReader, out rgelt); if (HRESULT.Succeeded(hr)) { pceltFetched = 1; _index++; } return(hr); } }
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; } } }
public BitmapPalette(BitmapSource bitmapSource, int maxColorCount) { // Note: we will never return a palette from BitmapPalettes. if (bitmapSource == null) { throw new ArgumentNullException("bitmapSource"); } SafeMILHandle unmanagedBitmap = bitmapSource.WicSourceHandle; _palette = CreateInternalPalette(); lock (bitmapSource.SyncObject) { HRESULT.Check(UnsafeNativeMethods.WICPalette.InitializeFromBitmap( _palette, unmanagedBitmap, maxColorCount, false)); } UpdateManaged(); }
/// <summary> /// /// </summary> static internal InPlaceBitmapMetadataWriter CreateFromDecoder(SafeMILHandle decoderHandle, object syncObject) { Invariant.Assert(decoderHandle != null); SafeMILHandle /* IWICFastMetadataEncoder */ fmeHandle = null; SafeMILHandle /* IWICMetadataQueryWriter */ metadataHandle = null; using (FactoryMaker factoryMaker = new FactoryMaker()) { lock (syncObject) { HRESULT.Check(UnsafeNativeMethods.WICImagingFactory.CreateFastMetadataEncoderFromDecoder( factoryMaker.ImagingFactoryPtr, decoderHandle, out fmeHandle)); } } HRESULT.Check(UnsafeNativeMethods.WICFastMetadataEncoder.GetMetadataQueryWriter( fmeHandle, out metadataHandle)); return(new InPlaceBitmapMetadataWriter(fmeHandle, metadataHandle, syncObject)); }
internal BitmapSourceSafeMILHandle(IntPtr handle, SafeMILHandle copyMemoryPressureFrom) : this(handle) { CopyMemoryPressure(copyMemoryPressureFrom); }
// End WMPhoto-Specific Encoder Parameter Properties /// <summary> /// Setups the encoder and other properties before encoding each frame /// </summary> internal override void SetupFrame(SafeMILHandle frameEncodeHandle, SafeMILHandle encoderOptions) { PROPBAG2 propBag = new PROPBAG2(); PROPVARIANT propValue = new PROPVARIANT(); if (_imagequalitylevel != c_defaultImageQualityLevel) { try { propBag.Init("ImageQuality"); propValue.Init((float)_imagequalitylevel); HRESULT.Check(UnsafeNativeMethods.IPropertyBag2.Write( encoderOptions, 1, ref propBag, ref propValue)); } finally { propBag.Clear(); propValue.Clear(); } } if (_transformation != c_defaultTransformation) { try { propBag.Init("BitmapTransform"); propValue.Init((byte)_transformation); HRESULT.Check(UnsafeNativeMethods.IPropertyBag2.Write( encoderOptions, 1, ref propBag, ref propValue)); } finally { propBag.Clear(); propValue.Clear(); } } if (_lossless != c_defaultLossless) { try { propBag.Init("Lossless"); propValue.Init((bool)_lossless); HRESULT.Check(UnsafeNativeMethods.IPropertyBag2.Write( encoderOptions, 1, ref propBag, ref propValue)); } finally { propBag.Clear(); propValue.Clear(); } } if (_usecodecoptions != c_defaultUseCodecOptions) { try { propBag.Init("UseCodecOptions"); propValue.Init((bool)_usecodecoptions); HRESULT.Check(UnsafeNativeMethods.IPropertyBag2.Write( encoderOptions, 1, ref propBag, ref propValue)); } finally { propBag.Clear(); propValue.Clear(); } } if (_qualitylevel != c_defaultQualityLevel) { try { propBag.Init("Quality"); propValue.Init((byte)_qualitylevel); HRESULT.Check(UnsafeNativeMethods.IPropertyBag2.Write( encoderOptions, 1, ref propBag, ref propValue)); } finally { propBag.Clear(); propValue.Clear(); } } if (_subsamplinglevel != c_defaultSubsamplingLevel) { try { propBag.Init("Subsampling"); propValue.Init((byte)_subsamplinglevel); HRESULT.Check(UnsafeNativeMethods.IPropertyBag2.Write( encoderOptions, 1, ref propBag, ref propValue)); } finally { propBag.Clear(); propValue.Clear(); } } if (_overlaplevel != c_defaultOverlapLevel) { try { propBag.Init("Overlap"); propValue.Init((byte)_overlaplevel); HRESULT.Check(UnsafeNativeMethods.IPropertyBag2.Write( encoderOptions, 1, ref propBag, ref propValue)); } finally { propBag.Clear(); propValue.Clear(); } } if (_horizontaltileslices != c_defaultHorizontalTileSlices) { try { propBag.Init("HorizontalTileSlices"); propValue.Init((ushort)_horizontaltileslices); HRESULT.Check(UnsafeNativeMethods.IPropertyBag2.Write( encoderOptions, 1, ref propBag, ref propValue)); } finally { propBag.Clear(); propValue.Clear(); } } if (_verticaltileslices != c_defaultVerticalTileSlices) { try { propBag.Init("VerticalTileSlices"); propValue.Init((ushort)_verticaltileslices); HRESULT.Check(UnsafeNativeMethods.IPropertyBag2.Write( encoderOptions, 1, ref propBag, ref propValue)); } finally { propBag.Clear(); propValue.Clear(); } } if (_frequencyorder != c_defaultFrequencyOrder) { try { propBag.Init("FrequencyOrder"); propValue.Init((bool)_frequencyorder); HRESULT.Check(UnsafeNativeMethods.IPropertyBag2.Write( encoderOptions, 1, ref propBag, ref propValue)); } finally { propBag.Clear(); propValue.Clear(); } } if (_interleavedalpha != c_defaultInterleavedAlpha) { try { propBag.Init("InterleavedAlpha"); propValue.Init((bool)_interleavedalpha); HRESULT.Check(UnsafeNativeMethods.IPropertyBag2.Write( encoderOptions, 1, ref propBag, ref propValue)); } finally { propBag.Clear(); propValue.Clear(); } } if (_alphaqualitylevel != c_defaultAlphaQualityLevel) { try { propBag.Init("AlphaQuality"); propValue.Init((byte)_alphaqualitylevel); HRESULT.Check(UnsafeNativeMethods.IPropertyBag2.Write( encoderOptions, 1, ref propBag, ref propValue)); } finally { propBag.Clear(); propValue.Clear(); } } if (_compresseddomaintranscode != c_defaultCompressedDomainTranscode) { try { propBag.Init("CompressedDomainTranscode"); propValue.Init((bool)_compresseddomaintranscode); HRESULT.Check(UnsafeNativeMethods.IPropertyBag2.Write( encoderOptions, 1, ref propBag, ref propValue)); } finally { propBag.Clear(); propValue.Clear(); } } if (_imagedatadiscardlevel != c_defaultImageDataDiscardLevel) { try { propBag.Init("ImageDataDiscard"); propValue.Init((byte)_imagedatadiscardlevel); HRESULT.Check(UnsafeNativeMethods.IPropertyBag2.Write( encoderOptions, 1, ref propBag, ref propValue)); } finally { propBag.Clear(); propValue.Clear(); } } if (_alphadatadiscardlevel != c_defaultAlphaDataDiscardLevel) { try { propBag.Init("AlphaDataDiscard"); propValue.Init((byte)_alphadatadiscardlevel); HRESULT.Check(UnsafeNativeMethods.IPropertyBag2.Write( encoderOptions, 1, ref propBag, ref propValue)); } finally { propBag.Clear(); propValue.Clear(); } } if (_ignoreoverlap != c_defaultIgnoreOverlap) { try { propBag.Init("IgnoreOverlap"); propValue.Init((bool)_ignoreoverlap); HRESULT.Check(UnsafeNativeMethods.IPropertyBag2.Write( encoderOptions, 1, ref propBag, ref propValue)); } finally { propBag.Clear(); propValue.Clear(); } } HRESULT.Check(UnsafeNativeMethods.WICBitmapFrameEncode.Initialize( frameEncodeHandle, encoderOptions )); }
/// <summary> /// Internal Constructor /// </summary> internal BitmapCodecInfoInternal(SafeMILHandle codecInfoHandle) : base(codecInfoHandle) { }
/// <summary> /// Internal Constructor /// </summary> internal BitmapCodecInfo(SafeMILHandle codecInfoHandle) { Debug.Assert(codecInfoHandle != null); _isBuiltIn = true; _codecInfoHandle = codecInfoHandle; }
private static long ComputeEstimatedSize(IntPtr bitmapObject) { long estimatedSize = 0; if (bitmapObject != null && bitmapObject != IntPtr.Zero) { IntPtr wicBitmap; // // QueryInterface for the bitmap source to ensure we are // calling through the right vtable on the pinvoke. // int hr = UnsafeNativeMethods.MILUnknown.QueryInterface( bitmapObject, ref _uuidBitmap, out wicBitmap ); if (hr == HRESULT.S_OK) { Debug.Assert(wicBitmap != IntPtr.Zero); // // The safe handle will release the ref added by the above QI // // There's no need to copy memory pressure. Partly because this SafeMILHandle // is temporary and will be collected after this method returns, partly // because there might no memory pressure calculated yet. // SafeMILHandle bitmapSourceSafeHandle = new SafeMILHandle(wicBitmap); uint pixelWidth = 0; uint pixelHeight = 0; hr = UnsafeNativeMethods.WICBitmapSource.GetSize( bitmapSourceSafeHandle, out pixelWidth, out pixelHeight); if (hr == HRESULT.S_OK) { Guid guidFormat; hr = UnsafeNativeMethods.WICBitmapSource.GetPixelFormat(bitmapSourceSafeHandle, out guidFormat); if (hr == HRESULT.S_OK) { // // Go to long space to avoid overflow and check for overflow // PixelFormat pixelFormat = new PixelFormat(guidFormat); long scanlineSize = (long)pixelWidth * pixelFormat.InternalBitsPerPixel / 8; // // Check that scanlineSize is small enough that we can multiply by pixelHeight // without an overflow. Since pixelHeight is a 32-bit value and we multiply by pixelHeight, // then we can only have a 32-bit scanlineSize. Since we need a sign bit as well, // we need to check that scanlineSize can fit in 30 bits. // if (scanlineSize < 0x40000000) { estimatedSize = pixelHeight * scanlineSize; } } } } } return estimatedSize; }
internal object ToObject(object syncObject) { VarEnum vt = (VarEnum)varType; if ((vt & VarEnum.VT_VECTOR) != 0) { switch (vt & (~VarEnum.VT_VECTOR)) { case VarEnum.VT_EMPTY: return(null); case VarEnum.VT_I1: { sbyte[] array = new sbyte[ca.cElems]; for (int i = 0; i < ca.cElems; i++) { array[i] = (sbyte)Marshal.ReadByte(ca.pElems, i); } return(array); } case VarEnum.VT_UI1: { byte[] array = new byte[ca.cElems]; Marshal.Copy(ca.pElems, array, 0, (int)ca.cElems); return(array); } case VarEnum.VT_I2: { short[] array = new short[ca.cElems]; Marshal.Copy(ca.pElems, array, 0, (int)ca.cElems); return(array); } case VarEnum.VT_UI2: { ushort[] array = new ushort[ca.cElems]; for (int i = 0; i < ca.cElems; i++) { array[i] = (ushort)Marshal.ReadInt16(ca.pElems, i * sizeof(ushort)); } return(array); } case VarEnum.VT_I4: { int[] array = new int[ca.cElems]; Marshal.Copy(ca.pElems, array, 0, (int)ca.cElems); return(array); } case VarEnum.VT_UI4: { uint[] array = new uint[ca.cElems]; for (int i = 0; i < ca.cElems; i++) { array[i] = (uint)Marshal.ReadInt32(ca.pElems, i * sizeof(uint)); } return(array); } case VarEnum.VT_I8: { Int64[] array = new Int64[ca.cElems]; Marshal.Copy(ca.pElems, array, 0, (int)ca.cElems); return(array); } case VarEnum.VT_UI8: { UInt64[] array = new UInt64[ca.cElems]; for (int i = 0; i < ca.cElems; i++) { array[i] = (UInt64)Marshal.ReadInt64(ca.pElems, i * sizeof(UInt64)); } return(array); } case VarEnum.VT_R4: { float[] array = new float[ca.cElems]; Marshal.Copy(ca.pElems, array, 0, (int)ca.cElems); return(array); } case VarEnum.VT_R8: { double[] array = new double[ca.cElems]; Marshal.Copy(ca.pElems, array, 0, (int)ca.cElems); return(array); } case VarEnum.VT_BOOL: { bool[] array = new bool[ca.cElems]; for (int i = 0; i < ca.cElems; i++) { array[i] = (bool)(Marshal.ReadInt16(ca.pElems, i * sizeof(ushort)) != 0); } return(array); } case VarEnum.VT_CLSID: { Guid[] array = new Guid[ca.cElems]; for (int i = 0; i < ca.cElems; i++) { byte[] guid = new byte[16]; Marshal.Copy(ca.pElems, guid, i * 16, 16); array[i] = new Guid(guid); } return(array); } case VarEnum.VT_LPSTR: { String[] array = new String[ca.cElems]; int sizeIntPtr = 0; unsafe { sizeIntPtr = sizeof(IntPtr); } for (int i = 0; i < ca.cElems; i++) { IntPtr ptr = Marshal.ReadIntPtr(ca.pElems, i * sizeIntPtr); array[i] = Marshal.PtrToStringAnsi(ptr); } return(array); } case VarEnum.VT_LPWSTR: { String[] array = new String[ca.cElems]; int sizeIntPtr = 0; unsafe { sizeIntPtr = sizeof(IntPtr); } for (int i = 0; i < ca.cElems; i++) { IntPtr ptr = Marshal.ReadIntPtr(ca.pElems, i * sizeIntPtr); array[i] = Marshal.PtrToStringUni(ptr); } return(array); } case VarEnum.VT_UNKNOWN: default: break; } } else { switch (vt) { case VarEnum.VT_EMPTY: return(null); case VarEnum.VT_I1: return(cVal); case VarEnum.VT_UI1: return(bVal); case VarEnum.VT_I2: return(iVal); case VarEnum.VT_UI2: return(uiVal); case VarEnum.VT_I4: return(intVal); case VarEnum.VT_UI4: return(uintVal); case VarEnum.VT_I8: return(lVal); case VarEnum.VT_UI8: return(ulVal); case VarEnum.VT_R4: return(fltVal); case VarEnum.VT_R8: return(dblVal); case VarEnum.VT_FILETIME: return(filetime); case VarEnum.VT_BOOL: return((bool)(boolVal != 0)); case VarEnum.VT_CLSID: byte[] guid = new byte[16]; Marshal.Copy(pclsidVal, guid, 0, 16); return(new Guid(guid)); case VarEnum.VT_LPSTR: return(Marshal.PtrToStringAnsi(pszVal)); case VarEnum.VT_LPWSTR: return(Marshal.PtrToStringUni(pwszVal)); case VarEnum.VT_BLOB: { byte[] blob = new byte[ca.cElems]; Marshal.Copy(ca.pElems, blob, 0, (int)ca.cElems); return(new BitmapMetadataBlob(blob)); } case VarEnum.VT_UNKNOWN: { IntPtr queryHandle = IntPtr.Zero; Guid guidIWICQueryWriter = MILGuidData.IID_IWICMetadataQueryWriter; Guid guidIWICQueryReader = MILGuidData.IID_IWICMetadataQueryReader; try { int hr = UnsafeNativeMethods.MILUnknown.QueryInterface(punkVal, ref guidIWICQueryWriter, out queryHandle); if (hr == HRESULT.S_OK) { // It's a IWICMetadataQueryWriter interface - read and write SafeMILHandle metadataHandle = new SafeMILHandle(queryHandle); // To avoid releasing the queryHandle in finally. queryHandle = IntPtr.Zero; return(new BitmapMetadata(metadataHandle, false, false, syncObject)); } else { hr = UnsafeNativeMethods.MILUnknown.QueryInterface(punkVal, ref guidIWICQueryReader, out queryHandle); if (hr == HRESULT.S_OK) { // It's a IWICMetadataQueryReader interface - read only SafeMILHandle metadataHandle = new SafeMILHandle(queryHandle); // To avoid releasing the queryHandle in finally. queryHandle = IntPtr.Zero; return(new BitmapMetadata(metadataHandle, true, false, syncObject)); } HRESULT.Check(hr); } } finally { if (queryHandle != IntPtr.Zero) { UnsafeNativeMethods.MILUnknown.ReleaseInterface(ref queryHandle); } } break; } default: break; } } throw new System.NotSupportedException(SR.Get(SRID.Image_PropertyNotSupported)); }
internal void Init(object value) { if (value == null) { varType = (ushort)VarEnum.VT_EMPTY; } else if (value is Array) { Type type = value.GetType(); if (type == typeof(sbyte[])) { InitVector(value as Array, typeof(sbyte), VarEnum.VT_I1); } else if (type == typeof(byte[])) { InitVector(value as Array, typeof(byte), VarEnum.VT_UI1); } else if (value is char[]) { varType = (ushort)VarEnum.VT_LPSTR; pszVal = Marshal.StringToCoTaskMemAnsi(new String(value as char[])); } else if (value is char[][]) { char[][] charArray = value as char[][]; String[] strArray = new String[charArray.GetLength(0)]; for (int i = 0; i < charArray.Length; i++) { strArray[i] = new String(charArray[i] as char[]); } Init(strArray, true); } else if (type == typeof(short[])) { InitVector(value as Array, typeof(short), VarEnum.VT_I2); } else if (type == typeof(ushort[])) { InitVector(value as Array, typeof(ushort), VarEnum.VT_UI2); } else if (type == typeof(int[])) { InitVector(value as Array, typeof(int), VarEnum.VT_I4); } else if (type == typeof(uint[])) { InitVector(value as Array, typeof(uint), VarEnum.VT_UI4); } else if (type == typeof(Int64[])) { InitVector(value as Array, typeof(Int64), VarEnum.VT_I8); } else if (type == typeof(UInt64[])) { InitVector(value as Array, typeof(UInt64), VarEnum.VT_UI8); } else if (value is float[]) { InitVector(value as Array, typeof(float), VarEnum.VT_R4); } else if (value is double[]) { InitVector(value as Array, typeof(double), VarEnum.VT_R8); } else if (value is Guid[]) { InitVector(value as Array, typeof(Guid), VarEnum.VT_CLSID); } else if (value is String[]) { Init(value as String[], false); } else if (value is bool[]) { bool[] boolArray = value as bool[]; short[] array = new short[boolArray.Length]; for (int i = 0; i < boolArray.Length; i++) { array[i] = (short)(boolArray[i] ? -1 : 0); } InitVector(array, typeof(short), VarEnum.VT_BOOL); } else { throw new System.InvalidOperationException(SR.Get(SRID.Image_PropertyNotSupported)); } } else { Type type = value.GetType(); if (value is String) { varType = (ushort)VarEnum.VT_LPWSTR; pwszVal = Marshal.StringToCoTaskMemUni(value as String); } else if (type == typeof(sbyte)) { varType = (ushort)VarEnum.VT_I1; cVal = (sbyte)value; } else if (type == typeof(byte)) { varType = (ushort)VarEnum.VT_UI1; bVal = (byte)value; } else if (type == typeof(System.Runtime.InteropServices.ComTypes.FILETIME)) { varType = (ushort)VarEnum.VT_FILETIME; filetime = (System.Runtime.InteropServices.ComTypes.FILETIME)value; } else if (value is char) { varType = (ushort)VarEnum.VT_LPSTR; pszVal = Marshal.StringToCoTaskMemAnsi(new String(new char[] { (char)value })); } else if (type == typeof(short)) { varType = (ushort)VarEnum.VT_I2; iVal = (short)value; } else if (type == typeof(ushort)) { varType = (ushort)VarEnum.VT_UI2; uiVal = (ushort)value; } else if (type == typeof(int)) { varType = (ushort)VarEnum.VT_I4; intVal = (int)value; } else if (type == typeof(uint)) { varType = (ushort)VarEnum.VT_UI4; uintVal = (uint)value; } else if (type == typeof(Int64)) { varType = (ushort)VarEnum.VT_I8; lVal = (Int64)value; } else if (type == typeof(UInt64)) { varType = (ushort)VarEnum.VT_UI8; ulVal = (UInt64)value; } else if (value is float) { varType = (ushort)VarEnum.VT_R4; fltVal = (float)value; } else if (value is double) { varType = (ushort)VarEnum.VT_R8; dblVal = (double)value; } else if (value is Guid) { byte[] guid = ((Guid)value).ToByteArray(); varType = (ushort)VarEnum.VT_CLSID; pclsidVal = Marshal.AllocCoTaskMem(guid.Length); Marshal.Copy(guid, 0, pclsidVal, guid.Length); } else if (value is bool) { varType = (ushort)VarEnum.VT_BOOL; boolVal = (short)(((bool)value) ? -1 : 0); } else if (value is BitmapMetadataBlob) { Init((value as BitmapMetadataBlob).InternalGetBlobValue(), typeof(byte), VarEnum.VT_BLOB); } else if (value is BitmapMetadata) { IntPtr punkTemp = IntPtr.Zero; BitmapMetadata metadata = value as BitmapMetadata; SafeMILHandle metadataHandle = metadata.InternalMetadataHandle; if (metadataHandle == null || metadataHandle.IsInvalid) { throw new NotImplementedException(); } Guid wicMetadataQueryReader = MILGuidData.IID_IWICMetadataQueryReader; HRESULT.Check(UnsafeNativeMethods.MILUnknown.QueryInterface( metadataHandle, ref wicMetadataQueryReader, out punkTemp)); varType = (ushort)VarEnum.VT_UNKNOWN; punkVal = punkTemp; } else { throw new System.InvalidOperationException(SR.Get(SRID.Image_PropertyNotSupported)); } } }
/// <summary> /// Compute a rough estimate of the size in bytes for the image /// </summary> private static long ComputeEstimatedSize(IntPtr bitmapObject) { long estimatedSize = 0; if (bitmapObject != IntPtr.Zero) { IntPtr wicBitmap; // // QueryInterface for the bitmap source to ensure we are // calling through the right vtable on the pinvoke. // int hr = UnsafeNativeMethods.MILUnknown.QueryInterface( bitmapObject, ref _uuidBitmap, out wicBitmap ); if (hr == HRESULT.S_OK) { Debug.Assert(wicBitmap != IntPtr.Zero); // // The safe handle will release the ref added by the above QI // // There's no need to copy memory pressure. Partly because this SafeMILHandle // is temporary and will be collected after this method returns, partly // because there might no memory pressure calculated yet. // SafeMILHandle bitmapSourceSafeHandle = new SafeMILHandle(wicBitmap); uint pixelWidth = 0; uint pixelHeight = 0; hr = UnsafeNativeMethods.WICBitmapSource.GetSize( bitmapSourceSafeHandle, out pixelWidth, out pixelHeight); if (hr == HRESULT.S_OK) { Guid guidFormat; hr = UnsafeNativeMethods.WICBitmapSource.GetPixelFormat(bitmapSourceSafeHandle, out guidFormat); if (hr == HRESULT.S_OK) { // // Go to long space to avoid overflow and check for overflow // PixelFormat pixelFormat = new PixelFormat(guidFormat); long scanlineSize = (long)pixelWidth * pixelFormat.InternalBitsPerPixel / 8; // // Check that scanlineSize is small enough that we can multiply by pixelHeight // without an overflow. Since pixelHeight is a 32-bit value and we multiply by pixelHeight, // then we can only have a 32-bit scanlineSize. Since we need a sign bit as well, // we need to check that scanlineSize can fit in 30 bits. // if (scanlineSize < 0x40000000) { estimatedSize = pixelHeight * scanlineSize; } } } } } return(estimatedSize); }
static internal InPlaceBitmapMetadataWriter CreateFromDecoder(SafeMILHandle decoderHandle, object syncObject) { Invariant.Assert(decoderHandle != null); SafeMILHandle /* IWICFastMetadataEncoder */ fmeHandle = null; SafeMILHandle /* IWICMetadataQueryWriter */ metadataHandle = null; using (FactoryMaker factoryMaker = new FactoryMaker()) { lock (syncObject) { HRESULT.Check(UnsafeNativeMethods.WICImagingFactory.CreateFastMetadataEncoderFromDecoder( factoryMaker.ImagingFactoryPtr, decoderHandle, out fmeHandle)); } } HRESULT.Check(UnsafeNativeMethods.WICFastMetadataEncoder.GetMetadataQueryWriter( fmeHandle, out metadataHandle)); return new InPlaceBitmapMetadataWriter(fmeHandle, metadataHandle, syncObject); }
internal object ToObject(object syncObject) { VarEnum vt = (VarEnum) varType; if ((vt & VarEnum.VT_VECTOR) != 0) { switch (vt & (~VarEnum.VT_VECTOR)) { case VarEnum.VT_EMPTY: return null; case VarEnum.VT_I1: { sbyte[] array = new sbyte[ca.cElems]; for (int i=0; i<ca.cElems; i++) array[i] = (sbyte) Marshal.ReadByte(ca.pElems, i); return array; } case VarEnum.VT_UI1: { byte[] array = new byte[ca.cElems]; Marshal.Copy(ca.pElems, array, 0, (int)ca.cElems); return array; } case VarEnum.VT_I2: { short[] array = new short[ca.cElems]; Marshal.Copy(ca.pElems, array, 0, (int)ca.cElems); return array; } case VarEnum.VT_UI2: { ushort[] array = new ushort[ca.cElems]; for (int i=0; i<ca.cElems; i++) array[i] = (ushort) Marshal.ReadInt16(ca.pElems, i*sizeof(ushort)); return array; } case VarEnum.VT_I4: { int[] array = new int[ca.cElems]; Marshal.Copy(ca.pElems, array, 0, (int)ca.cElems); return array; } case VarEnum.VT_UI4: { uint[] array = new uint[ca.cElems]; for (int i=0; i<ca.cElems; i++) array[i] = (uint) Marshal.ReadInt32(ca.pElems, i*sizeof(uint)); return array; } case VarEnum.VT_I8: { Int64[] array = new Int64[ca.cElems]; Marshal.Copy(ca.pElems, array, 0, (int)ca.cElems); return array; } case VarEnum.VT_UI8: { UInt64[] array = new UInt64[ca.cElems]; for (int i=0; i<ca.cElems; i++) array[i] = (UInt64) Marshal.ReadInt64(ca.pElems, i*sizeof(UInt64)); return array; } case VarEnum.VT_R4: { float[] array = new float[ca.cElems]; Marshal.Copy(ca.pElems, array, 0, (int)ca.cElems); return array; } case VarEnum.VT_R8: { double[] array = new double[ca.cElems]; Marshal.Copy(ca.pElems, array, 0, (int)ca.cElems); return array; } case VarEnum.VT_BOOL: { bool[] array = new bool[ca.cElems]; for (int i=0; i<ca.cElems; i++) array[i] = (bool) (Marshal.ReadInt16(ca.pElems, i*sizeof(ushort)) != 0); return array; } case VarEnum.VT_CLSID: { Guid[] array = new Guid[ca.cElems]; for (int i=0; i<ca.cElems; i++) { byte[] guid = new byte[16]; Marshal.Copy(ca.pElems, guid, i*16, 16); array[i] = new Guid(guid); } return array; } case VarEnum.VT_LPSTR: { String[] array = new String[ca.cElems]; int sizeIntPtr = 0; unsafe { sizeIntPtr = sizeof(IntPtr); } for (int i=0; i<ca.cElems; i++) { IntPtr ptr = Marshal.ReadIntPtr(ca.pElems, i*sizeIntPtr); array[i] = Marshal.PtrToStringAnsi(ptr); } return array; } case VarEnum.VT_LPWSTR: { String[] array = new String[ca.cElems]; int sizeIntPtr = 0; unsafe { sizeIntPtr = sizeof(IntPtr); } for (int i=0; i<ca.cElems; i++) { IntPtr ptr = Marshal.ReadIntPtr(ca.pElems, i*sizeIntPtr); array[i] = Marshal.PtrToStringUni(ptr); } return array; } case VarEnum.VT_UNKNOWN: default: break; } } else { switch (vt) { case VarEnum.VT_EMPTY: return null; case VarEnum.VT_I1: return cVal; case VarEnum.VT_UI1: return bVal; case VarEnum.VT_I2: return iVal; case VarEnum.VT_UI2: return uiVal; case VarEnum.VT_I4: return intVal; case VarEnum.VT_UI4: return uintVal; case VarEnum.VT_I8: return lVal; case VarEnum.VT_UI8: return ulVal; case VarEnum.VT_R4: return fltVal; case VarEnum.VT_R8: return dblVal; case VarEnum.VT_FILETIME: return filetime; case VarEnum.VT_BOOL: return (bool) (boolVal != 0); case VarEnum.VT_CLSID: byte[] guid = new byte[16]; Marshal.Copy(pclsidVal, guid, 0, 16); return new Guid(guid); case VarEnum.VT_LPSTR: return Marshal.PtrToStringAnsi(pszVal); case VarEnum.VT_LPWSTR: return Marshal.PtrToStringUni(pwszVal); case VarEnum.VT_BLOB: { byte[] blob = new byte[ca.cElems]; Marshal.Copy(ca.pElems, blob, 0, (int)ca.cElems); return new BitmapMetadataBlob(blob); } case VarEnum.VT_UNKNOWN: { IntPtr queryHandle = IntPtr.Zero; Guid guidIWICQueryWriter = MILGuidData.IID_IWICMetadataQueryWriter; Guid guidIWICQueryReader = MILGuidData.IID_IWICMetadataQueryReader; try { int hr = UnsafeNativeMethods.MILUnknown.QueryInterface(punkVal, ref guidIWICQueryWriter, out queryHandle); if (hr == HRESULT.S_OK) { // It's a IWICMetadataQueryWriter interface - read and write SafeMILHandle metadataHandle = new SafeMILHandle(queryHandle); // To avoid releasing the queryHandle in finally. queryHandle = IntPtr.Zero; return new BitmapMetadata(metadataHandle, false, false, syncObject); } else { hr = UnsafeNativeMethods.MILUnknown.QueryInterface(punkVal, ref guidIWICQueryReader, out queryHandle); if (hr == HRESULT.S_OK) { // It's a IWICMetadataQueryReader interface - read only SafeMILHandle metadataHandle = new SafeMILHandle(queryHandle); // To avoid releasing the queryHandle in finally. queryHandle = IntPtr.Zero; return new BitmapMetadata(metadataHandle, true, false, syncObject); } HRESULT.Check(hr); } } finally { if (queryHandle != IntPtr.Zero) { UnsafeNativeMethods.MILUnknown.ReleaseInterface(ref queryHandle); } } break; } default: break; } } throw new System.NotSupportedException(SR.Get(SRID.Image_PropertyNotSupported)); }