Beispiel #1
0
        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
                              ));
        }
Beispiel #2
0
        /// <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
                              ));
        }
Beispiel #3
0
        /// <summary>
        ///
        /// </summary>
        public object GetQuery(String query)
        {
            int hr;

            if (query == null)
            {
                throw new System.ArgumentNullException("query");
            }

            EnsureBitmapMetadata();

            PROPVARIANT propVar = new PROPVARIANT();

            try
            {
                propVar.Init(null);

                lock (_syncObject)
                {
                    hr = UnsafeNativeMethods.WICMetadataQueryReader.GetMetadataByName(
                        _metadataHandle,
                        query,
                        ref propVar
                        );
                }

                if (hr != (int)WinCodecErrors.WINCODEC_ERR_PROPERTYNOTFOUND)
                {
                    HRESULT.Check(hr);

                    object objValue = propVar.ToObject(_syncObject);

                    if (IsFrozenInternal)
                    {
                        BitmapMetadata metadata = objValue as BitmapMetadata;

                        if (metadata != null)
                        {
                            metadata.Freeze();
                        }
                    }

                    return(objValue);
                }
            }
            finally
            {
                propVar.Clear();
            }

            return(null);
        }
Beispiel #4
0
        // 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
                              ));
        }
Beispiel #5
0
        private void SaveFrame(SafeMILHandle frameEncodeHandle, SafeMILHandle encoderOptions, BitmapFrame frame)
        {
            SetupFrame(frameEncodeHandle, encoderOptions);

            // Helpful for debugging stress and remote dumps
            _encodeState = EncodeState.FrameEncodeInitialized;

            // Set the size
            HRESULT.Check(UnsafeNativeMethods.WICBitmapFrameEncode.SetSize(
                frameEncodeHandle,
                frame.PixelWidth,
                frame.PixelHeight
                ));

            // Helpful for debugging stress and remote dumps
            _encodeState = EncodeState.FrameEncodeSizeSet;

            // Set the resolution
            double dpiX = frame.DpiX;
            double dpiY = frame.DpiY;

            if (dpiX <= 0)
            {
                dpiX = 96;
            }
            if (dpiY <= 0)
            {
                dpiY = 96;
            }

            HRESULT.Check(UnsafeNativeMethods.WICBitmapFrameEncode.SetResolution(
                frameEncodeHandle,
                dpiX,
                dpiY
                ));

            // Helpful for debugging stress and remote dumps
            _encodeState = EncodeState.FrameEncodeResolutionSet;

            if (_supportsFrameThumbnails)
            {
                // Set the thumbnail.
                BitmapSource thumbnail = frame.Thumbnail;

                if (thumbnail != null)
                {
                    SafeMILHandle thumbnailHandle = thumbnail.WicSourceHandle;

                    lock (thumbnail.SyncObject)
                    {
                        HRESULT.Check(UnsafeNativeMethods.WICBitmapFrameEncode.SetThumbnail(
                            frameEncodeHandle,
                            thumbnailHandle
                            ));

                        // Helpful for debugging stress and remote dumps
                        _encodeState = EncodeState.FrameEncodeThumbnailSet;
                    }
                }
            }

            // if the source has been color corrected, we want to use a corresponding color profile
            if (frame._isColorCorrected)
            {
                ColorContext colorContext = new ColorContext(frame.Format);
                IntPtr[] colorContextPtrs = new IntPtr[1] { colorContext.ColorContextHandle.DangerousGetHandle() };

                int hr = UnsafeNativeMethods.WICBitmapFrameEncode.SetColorContexts(
                    frameEncodeHandle,
                    1,
                    colorContextPtrs
                    );

                // It's possible that some encoders may not support color contexts so don't check hr
                if (hr == HRESULT.S_OK)
                {
                    // Helpful for debugging stress and remote dumps
                    _encodeState = EncodeState.FrameEncodeColorContextsSet;
                }
            }
            // if the caller has explicitly provided color contexts, add them to the encoder
            else
            {
                IList<ColorContext> colorContexts = frame.ColorContexts;
                if (colorContexts != null && colorContexts.Count > 0)
                {             
                    int count = colorContexts.Count;

                    // Marshal can't convert SafeMILHandle[] so we must
                    {
                        IntPtr[] colorContextPtrs = new IntPtr[count];
                        for (int i = 0; i < count; ++i)
                        {
                            colorContextPtrs[i] = colorContexts[i].ColorContextHandle.DangerousGetHandle();
                        }

                        int hr = UnsafeNativeMethods.WICBitmapFrameEncode.SetColorContexts(
                            frameEncodeHandle,
                            (uint)count,
                            colorContextPtrs
                            );

                        // It's possible that some encoders may not support color contexts so don't check hr
                        if (hr == HRESULT.S_OK)
                        {
                            // Helpful for debugging stress and remote dumps
                            _encodeState = EncodeState.FrameEncodeColorContextsSet;
                        }
                    }
                }
            }

            // Set the pixel format and palette

            lock (frame.SyncObject)
            {
                SafeMILHandle outSourceHandle = new SafeMILHandle();
                SafeMILHandle bitmapSourceHandle = frame.WicSourceHandle;
                SafeMILHandle paletteHandle = new SafeMILHandle();

                // Set the pixel format and palette of the bitmap.
                // This could (but hopefully won't) introduce a format converter.
                HRESULT.Check(UnsafeNativeMethods.WICCodec.WICSetEncoderFormat(
                    bitmapSourceHandle,
                    paletteHandle,
                    frameEncodeHandle,
                    out outSourceHandle
                    ));

                // Helpful for debugging stress and remote dumps
                _encodeState = EncodeState.FrameEncodeFormatSet;
                _writeSourceHandles.Add(outSourceHandle);

                // Set the metadata
                if (_supportsFrameMetadata)
                {
                    BitmapMetadata metadata = frame.Metadata as BitmapMetadata;

                    // If the frame has metadata associated with a different container format, then we ignore it.
                    if (metadata != null && metadata.GuidFormat == ContainerFormat)
                    {
                        SafeMILHandle /* IWICMetadataQueryWriter */ metadataHandle = new SafeMILHandle();

                        HRESULT.Check(UnsafeNativeMethods.WICBitmapFrameEncode.GetMetadataQueryWriter(
                            frameEncodeHandle,
                            out metadataHandle
                            ));

                        PROPVARIANT propVar = new PROPVARIANT();

                        try
                        {
                            propVar.Init(metadata);

                            lock (metadata.SyncObject)
                            {
                                HRESULT.Check(UnsafeNativeMethods.WICMetadataQueryWriter.SetMetadataByName(
                                    metadataHandle,
                                    "/",
                                    ref propVar
                                    ));

                                // Helpful for debugging stress and remote dumps
                                _encodeState = EncodeState.FrameEncodeMetadataSet;
                            }
                        }
                        finally
                        {
                            propVar.Clear();
                        }
                    }
                }

                Int32Rect r = new Int32Rect();
                HRESULT.Check(UnsafeNativeMethods.WICBitmapFrameEncode.WriteSource(
                    frameEncodeHandle,
                    outSourceHandle,
                    ref r
                    ));

                // Helpful for debugging stress and remote dumps
                _encodeState = EncodeState.FrameEncodeSourceWritten;

                HRESULT.Check(UnsafeNativeMethods.WICBitmapFrameEncode.Commit(
                    frameEncodeHandle
                    ));

                // Helpful for debugging stress and remote dumps
                _encodeState = EncodeState.FrameEncodeCommitted;
            }
        }
Beispiel #6
0
        public virtual void Save(System.IO.Stream stream)
        {
            VerifyAccess();
            EnsureBuiltIn();
            EnsureUnmanagedEncoder();

            // No-op to get rid of build error
            if (_encodeState == EncodeState.None)
            {
            }

            if (_hasSaved)
            {
                throw new InvalidOperationException(SR.Get(SRID.Image_OnlyOneSave));
            }

            if (_frames == null)
            {
                throw new System.NotSupportedException(SR.Get(SRID.Image_NoFrames, null));
            }

            int count = _frames.Count;
            if (count <= 0)
            {
                throw new System.NotSupportedException(SR.Get(SRID.Image_NoFrames, null));
            }

            IntPtr comStream = IntPtr.Zero;
            SafeMILHandle encoderHandle = _encoderHandle;

            try
            {
                comStream = StreamAsIStream.IStreamFrom(stream);

                // does this addref the stream?
                HRESULT.Check(UnsafeNativeMethods.WICBitmapEncoder.Initialize(
                    encoderHandle,
                    comStream,
                    WICBitmapEncodeCacheOption.WICBitmapEncodeNoCache
                    ));

                // Helpful for debugging stress and remote dumps
                _encodeState = EncodeState.EncoderInitialized;

                // Save global thumbnail if any.
                if (_thumbnail != null)
                {
                    Debug.Assert(_supportsGlobalThumbnail);
                    SafeMILHandle thumbnailBitmapSource = _thumbnail.WicSourceHandle;

                    lock (_thumbnail.SyncObject)
                    {
                        HRESULT.Check(UnsafeNativeMethods.WICBitmapEncoder.SetThumbnail(
                            encoderHandle,
                            thumbnailBitmapSource
                            ));

                        // Helpful for debugging stress and remote dumps
                        _encodeState = EncodeState.EncoderThumbnailSet;
                    }
                }

                // Save global palette if any.
                if (_palette != null && _palette.Colors.Count > 0)
                {
                    SafeMILHandle paletteHandle = _palette.InternalPalette;

                    HRESULT.Check(UnsafeNativeMethods.WICBitmapEncoder.SetPalette(
                        encoderHandle,
                        paletteHandle
                        ));

                    // Helpful for debugging stress and remote dumps
                    _encodeState = EncodeState.EncoderPaletteSet;
                }

                // Save global metadata if any.
                if (_metadata != null && _metadata.GuidFormat == ContainerFormat)
                {
                    Debug.Assert(_supportsGlobalMetadata);

                    EnsureMetadata(false);

                    if (_metadata.InternalMetadataHandle != _metadataHandle)
                    {
                        PROPVARIANT propVar = new PROPVARIANT();

                        try
                        {
                            propVar.Init(_metadata);

                            lock (_metadata.SyncObject)
                            {
                                HRESULT.Check(UnsafeNativeMethods.WICMetadataQueryWriter.SetMetadataByName(
                                    _metadataHandle,
                                    "/",
                                    ref propVar
                                    ));
                            }
                        }
                        finally
                        {
                            propVar.Clear();
                        }
                    }
                }

                for (int i = 0; i < count; i++)
                {
                    SafeMILHandle frameEncodeHandle = new SafeMILHandle();
                    SafeMILHandle encoderOptions = new SafeMILHandle();
                    HRESULT.Check(UnsafeNativeMethods.WICBitmapEncoder.CreateNewFrame(
                        encoderHandle,
                        out frameEncodeHandle,
                        out encoderOptions
                        ));

                    // Helpful for debugging stress and remote dumps
                    _encodeState = EncodeState.EncoderCreatedNewFrame;
                    _frameHandles.Add(frameEncodeHandle);

                    SaveFrame(frameEncodeHandle, encoderOptions, _frames[i]);

                    // If multiple frames are not supported, break out
                    if (!_supportsMultipleFrames)
                    {
                        break;
                    }
                }

                // Now let the encoder know we are done encoding the file.
                HRESULT.Check(UnsafeNativeMethods.WICBitmapEncoder.Commit(encoderHandle));

                // Helpful for debugging stress and remote dumps
                _encodeState = EncodeState.EncoderCommitted;
            }
            finally
            {
                UnsafeNativeMethods.MILUnknown.ReleaseInterface(ref comStream);
            }

            _hasSaved = true;
        }
        private void SaveFrame(SafeMILHandle frameEncodeHandle, SafeMILHandle encoderOptions, BitmapFrame frame)
        {
            SetupFrame(frameEncodeHandle, encoderOptions);

            // Helpful for debugging stress and remote dumps
            _encodeState = EncodeState.FrameEncodeInitialized;

            // Set the size
            HRESULT.Check(UnsafeNativeMethods.WICBitmapFrameEncode.SetSize(
                              frameEncodeHandle,
                              frame.PixelWidth,
                              frame.PixelHeight
                              ));

            // Helpful for debugging stress and remote dumps
            _encodeState = EncodeState.FrameEncodeSizeSet;

            // Set the resolution
            double dpiX = frame.DpiX;
            double dpiY = frame.DpiY;

            if (dpiX <= 0)
            {
                dpiX = 96;
            }
            if (dpiY <= 0)
            {
                dpiY = 96;
            }

            HRESULT.Check(UnsafeNativeMethods.WICBitmapFrameEncode.SetResolution(
                              frameEncodeHandle,
                              dpiX,
                              dpiY
                              ));

            // Helpful for debugging stress and remote dumps
            _encodeState = EncodeState.FrameEncodeResolutionSet;

            if (_supportsFrameThumbnails)
            {
                // Set the thumbnail.
                BitmapSource thumbnail = frame.Thumbnail;

                if (thumbnail != null)
                {
                    SafeMILHandle thumbnailHandle = thumbnail.WicSourceHandle;

                    lock (thumbnail.SyncObject)
                    {
                        HRESULT.Check(UnsafeNativeMethods.WICBitmapFrameEncode.SetThumbnail(
                                          frameEncodeHandle,
                                          thumbnailHandle
                                          ));

                        // Helpful for debugging stress and remote dumps
                        _encodeState = EncodeState.FrameEncodeThumbnailSet;
                    }
                }
            }

            // if the source has been color corrected, we want to use a corresponding color profile
            if (frame._isColorCorrected)
            {
                ColorContext colorContext     = new ColorContext(frame.Format);
                IntPtr[]     colorContextPtrs = new IntPtr[1] {
                    colorContext.ColorContextHandle.DangerousGetHandle()
                };

                int hr = UnsafeNativeMethods.WICBitmapFrameEncode.SetColorContexts(
                    frameEncodeHandle,
                    1,
                    colorContextPtrs
                    );

                // It's possible that some encoders may not support color contexts so don't check hr
                if (hr == HRESULT.S_OK)
                {
                    // Helpful for debugging stress and remote dumps
                    _encodeState = EncodeState.FrameEncodeColorContextsSet;
                }
            }
            // if the caller has explicitly provided color contexts, add them to the encoder
            else
            {
                IList <ColorContext> colorContexts = frame.ColorContexts;
                if (colorContexts != null && colorContexts.Count > 0)
                {
                    int count = colorContexts.Count;

                    // Marshal can't convert SafeMILHandle[] so we must
                    {
                        IntPtr[] colorContextPtrs = new IntPtr[count];
                        for (int i = 0; i < count; ++i)
                        {
                            colorContextPtrs[i] = colorContexts[i].ColorContextHandle.DangerousGetHandle();
                        }

                        int hr = UnsafeNativeMethods.WICBitmapFrameEncode.SetColorContexts(
                            frameEncodeHandle,
                            (uint)count,
                            colorContextPtrs
                            );

                        // It's possible that some encoders may not support color contexts so don't check hr
                        if (hr == HRESULT.S_OK)
                        {
                            // Helpful for debugging stress and remote dumps
                            _encodeState = EncodeState.FrameEncodeColorContextsSet;
                        }
                    }
                }
            }

            // Set the pixel format and palette

            lock (frame.SyncObject)
            {
                SafeMILHandle outSourceHandle    = new SafeMILHandle();
                SafeMILHandle bitmapSourceHandle = frame.WicSourceHandle;
                SafeMILHandle paletteHandle      = new SafeMILHandle();

                // Set the pixel format and palette of the bitmap.
                // This could (but hopefully won't) introduce a format converter.
                HRESULT.Check(UnsafeNativeMethods.WICCodec.WICSetEncoderFormat(
                                  bitmapSourceHandle,
                                  paletteHandle,
                                  frameEncodeHandle,
                                  out outSourceHandle
                                  ));

                // Helpful for debugging stress and remote dumps
                _encodeState = EncodeState.FrameEncodeFormatSet;
                _writeSourceHandles.Add(outSourceHandle);

                // Set the metadata
                if (_supportsFrameMetadata)
                {
                    BitmapMetadata metadata = frame.Metadata as BitmapMetadata;

                    // If the frame has metadata associated with a different container format, then we ignore it.
                    if (metadata != null && metadata.GuidFormat == ContainerFormat)
                    {
                        SafeMILHandle /* IWICMetadataQueryWriter */ metadataHandle = new SafeMILHandle();

                        HRESULT.Check(UnsafeNativeMethods.WICBitmapFrameEncode.GetMetadataQueryWriter(
                                          frameEncodeHandle,
                                          out metadataHandle
                                          ));

                        PROPVARIANT propVar = new PROPVARIANT();

                        try
                        {
                            propVar.Init(metadata);

                            lock (metadata.SyncObject)
                            {
                                HRESULT.Check(UnsafeNativeMethods.WICMetadataQueryWriter.SetMetadataByName(
                                                  metadataHandle,
                                                  "/",
                                                  ref propVar
                                                  ));

                                // Helpful for debugging stress and remote dumps
                                _encodeState = EncodeState.FrameEncodeMetadataSet;
                            }
                        }
                        finally
                        {
                            propVar.Clear();
                        }
                    }
                }

                Int32Rect r = new Int32Rect();
                HRESULT.Check(UnsafeNativeMethods.WICBitmapFrameEncode.WriteSource(
                                  frameEncodeHandle,
                                  outSourceHandle,
                                  ref r
                                  ));

                // Helpful for debugging stress and remote dumps
                _encodeState = EncodeState.FrameEncodeSourceWritten;

                HRESULT.Check(UnsafeNativeMethods.WICBitmapFrameEncode.Commit(
                                  frameEncodeHandle
                                  ));

                // Helpful for debugging stress and remote dumps
                _encodeState = EncodeState.FrameEncodeCommitted;
            }
        }
        public virtual void Save(System.IO.Stream stream)
        {
            VerifyAccess();
            EnsureBuiltIn();
            EnsureUnmanagedEncoder();

            // No-op to get rid of build error
            if (_encodeState == EncodeState.None)
            {
            }

            if (_hasSaved)
            {
                throw new InvalidOperationException(SR.Get(SRID.Image_OnlyOneSave));
            }

            if (_frames == null)
            {
                throw new System.NotSupportedException(SR.Get(SRID.Image_NoFrames, null));
            }

            int count = _frames.Count;

            if (count <= 0)
            {
                throw new System.NotSupportedException(SR.Get(SRID.Image_NoFrames, null));
            }

            IntPtr        comStream     = IntPtr.Zero;
            SafeMILHandle encoderHandle = _encoderHandle;

            try
            {
                comStream = StreamAsIStream.IStreamFrom(stream);

                // does this addref the stream?
                HRESULT.Check(UnsafeNativeMethods.WICBitmapEncoder.Initialize(
                                  encoderHandle,
                                  comStream,
                                  WICBitmapEncodeCacheOption.WICBitmapEncodeNoCache
                                  ));

                // Helpful for debugging stress and remote dumps
                _encodeState = EncodeState.EncoderInitialized;

                // Save global thumbnail if any.
                if (_thumbnail != null)
                {
                    Debug.Assert(_supportsGlobalThumbnail);
                    SafeMILHandle thumbnailBitmapSource = _thumbnail.WicSourceHandle;

                    lock (_thumbnail.SyncObject)
                    {
                        HRESULT.Check(UnsafeNativeMethods.WICBitmapEncoder.SetThumbnail(
                                          encoderHandle,
                                          thumbnailBitmapSource
                                          ));

                        // Helpful for debugging stress and remote dumps
                        _encodeState = EncodeState.EncoderThumbnailSet;
                    }
                }

                // Save global palette if any.
                if (_palette != null && _palette.Colors.Count > 0)
                {
                    SafeMILHandle paletteHandle = _palette.InternalPalette;

                    HRESULT.Check(UnsafeNativeMethods.WICBitmapEncoder.SetPalette(
                                      encoderHandle,
                                      paletteHandle
                                      ));

                    // Helpful for debugging stress and remote dumps
                    _encodeState = EncodeState.EncoderPaletteSet;
                }

                // Save global metadata if any.
                if (_metadata != null && _metadata.GuidFormat == ContainerFormat)
                {
                    Debug.Assert(_supportsGlobalMetadata);

                    EnsureMetadata(false);

                    if (_metadata.InternalMetadataHandle != _metadataHandle)
                    {
                        PROPVARIANT propVar = new PROPVARIANT();

                        try
                        {
                            propVar.Init(_metadata);

                            lock (_metadata.SyncObject)
                            {
                                HRESULT.Check(UnsafeNativeMethods.WICMetadataQueryWriter.SetMetadataByName(
                                                  _metadataHandle,
                                                  "/",
                                                  ref propVar
                                                  ));
                            }
                        }
                        finally
                        {
                            propVar.Clear();
                        }
                    }
                }

                for (int i = 0; i < count; i++)
                {
                    SafeMILHandle frameEncodeHandle = new SafeMILHandle();
                    SafeMILHandle encoderOptions    = new SafeMILHandle();
                    HRESULT.Check(UnsafeNativeMethods.WICBitmapEncoder.CreateNewFrame(
                                      encoderHandle,
                                      out frameEncodeHandle,
                                      out encoderOptions
                                      ));

                    // Helpful for debugging stress and remote dumps
                    _encodeState = EncodeState.EncoderCreatedNewFrame;
                    _frameHandles.Add(frameEncodeHandle);

                    SaveFrame(frameEncodeHandle, encoderOptions, _frames[i]);

                    // If multiple frames are not supported, break out
                    if (!_supportsMultipleFrames)
                    {
                        break;
                    }
                }

                // Now let the encoder know we are done encoding the file.
                HRESULT.Check(UnsafeNativeMethods.WICBitmapEncoder.Commit(encoderHandle));

                // Helpful for debugging stress and remote dumps
                _encodeState = EncodeState.EncoderCommitted;
            }
            finally
            {
                UnsafeNativeMethods.MILUnknown.ReleaseInterface(ref comStream);
            }

            _hasSaved = true;
        }
Beispiel #9
0
        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
                ));
        }
Beispiel #10
0
        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 (_interlaceOption != c_defaultInterlaceOption)
            { 
                try
                { 
                    propBag.Init("InterlaceOption"); 
                    propValue.Init(_interlaceOption == PngInterlaceOption.On);
 
                    HRESULT.Check(UnsafeNativeMethods.IPropertyBag2.Write(
                        encoderOptions,
                        1,
                        ref propBag, 
                        ref propValue));
                } 
                finally 
                {
                    propBag.Clear(); 
                    propValue.Clear();
                }
            }
 
            HRESULT.Check(UnsafeNativeMethods.WICBitmapFrameEncode.Initialize(
                frameEncodeHandle, 
                encoderOptions 
                ));
        } 
Beispiel #11
0
        /// <summary>
        ///
        /// </summary>
        public void SetQuery(String query, object value)
        {
            WritePreamble();

            if (query == null)
            {
                throw new System.ArgumentNullException("query");
            }

            if (value == null)
            {
                throw new System.ArgumentNullException("value");
            }

            if (_readOnly)
            {
                throw new System.InvalidOperationException(SR.Get(SRID.Image_MetadataReadOnly));
            }

            // Store these for debugging stress failures.
            _setQueryString = query;
            _setQueryValue  = value;

            EnsureBitmapMetadata();

            PROPVARIANT propVar = new PROPVARIANT();

            try
            {
                propVar.Init(value);

                if (propVar.RequiresSyncObject)
                {
                    BitmapMetadata metadata = value as BitmapMetadata;
                    Invariant.Assert(metadata != null);

                    #pragma warning suppress 6506 // Invariant.Assert(metadata != null);
                    metadata.VerifyAccess();

                    #pragma warning suppress 6506 // Invariant.Assert(metadata != null);
                    lock (metadata._syncObject)
                    {
                        lock (_syncObject)
                        {
                            HRESULT.Check(UnsafeNativeMethods.WICMetadataQueryWriter.SetMetadataByName(
                                              _metadataHandle,
                                              query,
                                              ref propVar
                                              ));
                        }
                    }
                }
                else
                {
                    lock (_syncObject)
                    {
                        HRESULT.Check(UnsafeNativeMethods.WICMetadataQueryWriter.SetMetadataByName(
                                          _metadataHandle,
                                          query,
                                          ref propVar
                                          ));
                    }
                }
            }
            finally
            {
                propVar.Clear();
            }

            WritePostscript();
        }
        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
                ));
        }