Example #1
0
        /// <summary> 
        /// Internal constructor -- Creates new frame using specified decoder 
        /// </summary>
        internal BitmapFrameDecode( 
            int frameNumber,
            BitmapCreateOptions createOptions,
            BitmapCacheOption cacheOption,
            BitmapDecoder decoder 
            ) : base(true)
        { 
            _bitmapInit.BeginInit(); 
            _frameNumber = frameNumber;
            _isThumbnailCached = false; 
            _isMetadataCached = false;
            _frameSource = null;

            Debug.Assert(decoder != null); 
            _decoder = decoder;
            _syncObject = decoder.SyncObject; 
            _createOptions = createOptions; 
            _cacheOption = cacheOption;
 
            _bitmapInit.EndInit();

            if ((createOptions & BitmapCreateOptions.DelayCreation) != 0)
            { 
                DelayCreation = true;
            } 
            else 
            {
                FinalizeCreation(); 
            }
        }
Example #2
0
        private void CheckAndUpdateSource()
        {
            Stream bmpStream = new MemoryStream(File.ReadAllBytes(imgInfo.FullName), false);
            bmpDecoder = BitmapDecoder.Create(bmpStream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.None);

            frameCount = bmpDecoder.Frames.Count;
            if (frameCount == 0)
                imgContainer.Source = main.resource.imgZeroDemension;
            // 某些图片的某些图层尺寸为0
            else if (bmpDecoder.Frames[currentFrame].PixelWidth == 0 ||
                bmpDecoder.Frames[currentFrame].PixelHeight == 0)
                imgContainer.Source = main.resource.imgZeroDemension;
            else if (frameCount == 1)
            {
                currentFrame = 0;
                imgContainer.Source = bmpDecoder.Frames[currentFrame];
            }
            else
                imgContainer.Source = bmpDecoder.Frames[currentFrame];

            bmpOriginal = imgContainer.Source as BitmapSource;
            if (indexPageModeJudge == 0)
                isHalfPage = bmpOriginal.PixelWidth < bmpOriginal.PixelHeight;	// Only divide wide page.
            else
                isHalfPage = false;

            UpdateSizeInfo();

            AutoLevels();

            UpdateInfo();
        }
        public ImageViewModel(FileInfo FileInfo, BitmapDecoder BitmapDecoder)
        {
            if (FileInfo == null)
                throw new ArgumentNullException("FileInfo");
            if (BitmapDecoder == null)
                throw new ArgumentNullException("BitmapDecoder");
            if (BitmapDecoder.Frames == null || BitmapDecoder.Frames.Count == 0)
                throw new ArgumentException("BitmapDecoder contains no frames.", "BitmapDecoder");

            this._FileInfo = FileInfo;
            this._BitmapDecoder = BitmapDecoder;
        }
 internal UnknownBitmapDecoder(
     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)
 {
 }
Example #5
0
      public void ShowGif(string _imgPath)
      {
         FileStream fsImg = new FileStream(_imgPath, FileMode.Open);
         MemoryStream gif = new MemoryStream();
         fsImg.CopyTo(gif);
         fsImg.Close();

         byte[] buffer = new byte[gif.Length];
         gif.Position = 0;
         gif.Read(buffer, 0, Convert.ToInt32(gif.Length));
         //判断图片是否为GIF格式,通过图片的前三个字节标识位来判断
         if (!ASCIIEncoding.ASCII.GetString(buffer, 0, 3).ToLower().Equals("gif"))
         {
            MessageBox.Show("无效的GIF图片!");
            return;
         }
         //清空容器
         spFrames.Children.Clear();
         spGifImage.Children.Clear();

         bd = new GifBitmapDecoder(gif, BitmapCreateOptions.None, BitmapCacheOption.Default);
         ShowGifInfo(buffer, _imgPath); //显示图片的信息
         //显示图片的所有帧
         for (int i = 0; i < bd.Frames.Count(); i++)
         {
            System.Windows.Controls.Image img = new System.Windows.Controls.Image();
            img.Source = bd.Frames[i];
            img.Width = 200;
            img.Height = 200;
            img.Margin = new Thickness(6, 0, 0, 0);
            spFrames.Children.Add(img);
         }
         GifImage gifImage = new GifImage();
         gifImage.Source = _imgPath;
         spGifImage.Children.Add(gifImage);
      }
 private ImageViewModel CreateImageViewModel(FileInfo FileInfo, BitmapDecoder Decoder)
 {
     return new ImageViewModel(FileInfo, Decoder);
 }
 private BitmapSource CreateBitmapSource(BitmapDecoder Decoder)
 {
     BitmapSource Source = null;
     try
     {
         var Frame = Decoder.Frames[0];
         if (Frame.CanFreeze && !Frame.IsFrozen)
             Frame.Freeze();
         switch (this.ZoomType)
         {
             case ZoomType.Zoom:
                 Source = new TransformedBitmap(Frame, new ScaleTransform(this.ZoomPercent, this.ZoomPercent));
                 break;
             case ZoomType.BestFit:
                 if (Frame.PixelWidth < this.ViewerWidth && Frame.PixelHeight < this.ViewerHeight)
                     Source = Frame;
                 else if (Frame.PixelWidth >= this.ViewerWidth && Frame.PixelHeight >= this.ViewerHeight)
                 {
                     var dw = this.ViewerWidth / (double)Frame.PixelWidth;
                     var dh = this.ViewerHeight / (double)Frame.PixelHeight;
                     var delta = Math.Min(dw, dh);
                     Source = new TransformedBitmap(Frame, new ScaleTransform(delta, delta));
                 }
                 else
                 {
                     double dw;
                     double dh;
                     if (Frame.PixelWidth < this.ViewerWidth)
                     {
                         dh = this.ViewerHeight / (double)Frame.PixelHeight;
                         dw = dh;
                     }
                     else
                     {
                         dw = this.ViewerWidth / (double)Frame.PixelWidth;
                         dh = dw;
                     }
                     Source = new TransformedBitmap(Frame, new ScaleTransform(dw, dh));
                 }
                 break;
             default:
                 throw new NotImplementedException(this.ZoomType.ToString());
         }
         return Source;
     }
     finally
     {
         if (Source != null)
         {
             if (Source.CanFreeze && !Source.IsFrozen)
                 Source.Freeze();
         }
     }
 }
Example #8
0
        /// <summary>
        /// Refresh Report and Data
        /// </summary>
        public void Refresh()
        {
            if (_report != null)
            {
                if (BeforeRefresh != null)
                    BeforeRefresh(this, new EventArgs());

                _report.Refresh();
                _dec = null;
            }
        }
Example #9
0
 /// <summary>
 /// Constructor
 /// </summary>
 public JpgMeta(Stream stream_, BitmapDecoder decoder_)
 {
     _stream = stream_;
     Decoder = decoder_;
 }
        internal BitmapDecoder(
            SafeMILHandle decoderHandle,
            BitmapDecoder decoder,
            Uri baseUri,
            Uri uri,
            Stream stream,
            BitmapCreateOptions createOptions,
            BitmapCacheOption cacheOption,
            bool insertInDecoderCache,
            bool isOriginalWritable,
            Stream uriStream,
            UnmanagedMemoryStream unmanagedMemoryStream,
            SafeFileHandle safeFilehandle
            )
        {
            _decoderHandle = decoderHandle;
            _baseUri = baseUri;
            _uri = uri;
            _stream = stream;
            _createOptions = createOptions;
            _cacheOption = cacheOption;
            _syncObject = decoderHandle;
            _shouldCacheDecoder = insertInDecoderCache;
            _isOriginalWritable = isOriginalWritable;
            _uriStream = uriStream;
            _unmanagedMemoryStream = unmanagedMemoryStream;
            _safeFilehandle = safeFilehandle;

            if (_uriStream == null)
            {
                GC.SuppressFinalize(this);
            }

            Initialize(decoder);
        }
        private void Initialize(BitmapDecoder decoder)
        {
            _isBuiltInDecoder = true;

            if (decoder != null)
            {
                SetupFrames(decoder, null);
                //
                // We need to keep the strong reference to the cached decoder for a few reasons:
                //
                //    The application may release the original cached decoder and then keep a
                //    reference to this decoder only, in which case, the cache can be collected.
                //    This will cause a few undesirable results:
                //    1. The application may choose to decode the same URI again in which case
                //       we will not retrieve it from the cache even though we have a copy already
                //       decoded.
                //    2. The original cached decoder holds onto the file stream indirectly which if
                //       collected can cause bad behavior if the entire decoder is not loaded into
                //       memory.
                //
                _cachedDecoder = decoder;
            }
            else if ((_createOptions & BitmapCreateOptions.DelayCreation) == 0 && _cacheOption == BitmapCacheOption.OnLoad)
            {
                SetupFrames(null, null);

                // Its ok to close the stream since the frames are not delay created and caching is immediate
                CloseStream();
            }


            if ((_uri != null) && (decoder == null) && _shouldCacheDecoder)
            {

                // Add this decoder to the decoder cache
                ImagingCache.AddToDecoderCache(
                    (_baseUri == null) ? _uri : new Uri(_baseUri, _uri),
                    new WeakReference(this)
                    );
            }
        }
        private void GetBitmapDecoderEncoder(string sourcePath, out BitmapDecoder decoder, out BitmapEncoder encoder)
        {
            using (var sourceStream = File.OpenRead(sourcePath))
            {
                // NOTE: Using BitmapCacheOption.OnLoad here will read the entire file into
                //       memory which allows us to dispose of the file stream immediately
                decoder = BitmapDecoder.Create(sourceStream, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
            }

            encoder = BitmapEncoder.Create(decoder.CodecInfo.ContainerFormat);

            try
            {
                // NOTE: This will throw if the codec does not support encoding
                var dummy = encoder.CodecInfo;
            }
            catch (NotSupportedException)
            {
                // Fallback to the default (JPEG) encoder
                encoder = (BitmapEncoder)Activator.CreateInstance(DefaultEncoderType);
            }

            // Set encoder quality if it is a jpeg encoder
            var jpegEncoder = encoder as JpegBitmapEncoder;
            if (jpegEncoder != null)
            {
                jpegEncoder.QualityLevel = _encoderQualityLevel;
            }
        }
Example #13
0
        ///
        /// Begin a download
        ///
        internal static void BeginDownload(
            BitmapDecoder decoder,
            Uri uri,
            RequestCachePolicy uriCachePolicy,
            Stream stream
            )
        {
            lock (_syncLock)
            {
                if (!_thread.IsAlive)
                {
                    _thread.IsBackground = true;
                    _thread.Start();
                }
            }

            QueueEntry entry;

            // If there is already a download for this uri, just add the decoder to the list
            if (uri != null)
            {
                lock (_syncLock)
                {
                    if (_uriTable[uri] != null)
                    {
                        entry = (QueueEntry)_uriTable[uri];
                        entry.decoders.Add(new WeakReference(decoder));

                        return;
                    }
                }
            }

            entry          = new QueueEntry();
            entry.decoders = new List <WeakReference>();

            lock (_syncLock)
            {
                entry.decoders.Add(new WeakReference(decoder));
            }

            entry.inputUri    = uri;
            entry.inputStream = stream;

            string cacheFolder = MS.Win32.WinInet.InternetCacheFolder.LocalPath;
            bool   passed      = false;

            new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Assert(); // BlessedAssert
            try
            {
                // Get the file path
                StringBuilder tmpFileName = new StringBuilder(NativeMethods.MAX_PATH);
                MS.Win32.UnsafeNativeMethods.GetTempFileName(cacheFolder, "WPF", 0, tmpFileName);

                try
                {
                    string         pathToUse  = tmpFileName.ToString();
                    SafeFileHandle fileHandle = MS.Win32.UnsafeNativeMethods.CreateFile(
                        pathToUse,
                        NativeMethods.GENERIC_READ | NativeMethods.GENERIC_WRITE, /* dwDesiredAccess */
                        0,                                                        /* dwShare */
                        null,                                                     /* lpSecurityAttributes */
                        NativeMethods.CREATE_ALWAYS,                              /* dwCreationDisposition */
                        NativeMethods.FILE_ATTRIBUTE_TEMPORARY |
                        NativeMethods.FILE_FLAG_DELETE_ON_CLOSE,                  /* dwFlagsAndAttributes */
                        IntPtr.Zero                                               /* hTemplateFile */
                        );

                    if (fileHandle.IsInvalid)
                    {
                        throw new Win32Exception();
                    }

                    entry.outputStream = new FileStream(fileHandle, FileAccess.ReadWrite);
                    entry.streamPath   = pathToUse;
                    passed             = true;
                }
                catch (Exception e)
                {
                    if (CriticalExceptions.IsCriticalException(e))
                    {
                        throw;
                    }
                }
            }
            finally
            {
                SecurityPermission.RevertAssert();
            }

            if (!passed)
            {
                throw new IOException(SR.Get(SRID.Image_CannotCreateTempFile));
            }

            entry.readBuffer    = new byte[READ_SIZE];
            entry.contentLength = -1;
            entry.contentType   = string.Empty;
            entry.lastPercent   = 0;

            // Add the entry to the table if we know the uri
            if (uri != null)
            {
                lock (_syncLock)
                {
                    _uriTable[uri] = entry;
                }
            }

            if (stream == null)
            {
                entry.webRequest = WpfWebRequestHelper.CreateRequest(uri);
                if (uriCachePolicy != null)
                {
                    entry.webRequest.CachePolicy = uriCachePolicy;
                }

                entry.webRequest.BeginGetResponse(_responseCallback, entry);
            }
            else
            {
                _workQueue.Enqueue(entry);
                // Signal
                _waitEvent.Set();
            }
        }
 public static void Deallocate(BitmapDecoder decoder)
 {
     decoder = null;
 }
Example #15
0
 private void AssignImg(BitmapDecoder bd, Image i, int key)
 {
     try
     {
         //下载完毕后再显示
         i.Source = bd.Frames[0];
         i.Width = bd.Frames[0].PixelWidth;
         i.Height = bd.Frames[0].PixelHeight;
         i.Stretch = Stretch.Uniform;
     }
     catch (Exception ex1)
     {
         Program.Log(ex1, "Read sample img failed");
         Dispatcher.Invoke(new UIdelegate(delegate(object ss) { StopLoadImg(key); }), "");
     }
 }
        private static ImageSource ExtractImage(BitmapDecoder decoder, double desiredSize)
        {
            var dpiFactor = 1.0;

            if (Application.Current != null
                && Application.Current.CheckAccess()
                && Application.Current.MainWindow != null
                && Application.Current.MainWindow.CheckAccess())
            {
                // dpi.M11 = dpiX, dpi.M22 = dpiY
                var presentationSource = PresentationSource.FromVisual(Application.Current.MainWindow);

                if (presentationSource != null)
                {
                    if (presentationSource.CompositionTarget != null)
                    {
                        var dpi = presentationSource.CompositionTarget.TransformToDevice;
                        dpiFactor = dpi.M11;
                    }
                }
            }

            var result = decoder.Frames
                .OrderBy(f => f.Width)
                .FirstOrDefault(f => f.Width >= desiredSize * dpiFactor);

            // if there is no matching frame, get the largest frame
            if (ReferenceEquals(result, default(BitmapFrame)))
            {
                result = decoder.Frames.OrderBy(f => f.Width).Last();
            }

            return result;
        }
Example #17
0
        ///
        /// Create the unmanaged resources
        ///
        internal override void FinalizeCreation()
        {
            _bitmapInit.EnsureInitializedComplete();
            Uri uri = UriSource;

            if (_baseUri != null)
            {
                uri = new Uri(_baseUri, UriSource);
            }

            if ((CreateOptions & BitmapCreateOptions.IgnoreImageCache) != 0)
            {
                ImagingCache.RemoveFromImageCache(uri);
            }

            BitmapImage bitmapImage = CheckCache(uri);

            if (bitmapImage != null &&
                bitmapImage.CheckAccess() &&
                bitmapImage.SourceRect.Equals(SourceRect) &&
                bitmapImage.DecodePixelWidth == DecodePixelWidth &&
                bitmapImage.DecodePixelHeight == DecodePixelHeight &&
                bitmapImage.Rotation == Rotation &&
                (bitmapImage.CreateOptions & BitmapCreateOptions.IgnoreColorProfile) ==
                (CreateOptions & BitmapCreateOptions.IgnoreColorProfile)
                )
            {
                _syncObject = bitmapImage.SyncObject;
                lock (_syncObject)
                {
                    WicSourceHandle   = bitmapImage.WicSourceHandle;
                    IsSourceCached    = bitmapImage.IsSourceCached;
                    _convertedDUCEPtr = bitmapImage._convertedDUCEPtr;

                    //
                    // We nee d to keep the strong reference to the cached image for a few reasons:
                    //
                    //    The application may release the original cached image and then keep a
                    //    reference to this image only, in which case, the cache can be collected.
                    //    This will cause a few undesirable results:
                    //    1. The application may choose to decode the same URI again in which case
                    //       we will not retrieve it from the cache even though we have a copy already
                    //       decoded.
                    //    2. The original cached image holds onto the file stream indirectly which if
                    //       collected can cause bad behavior if the entire image is not loaded into
                    //       memory.
                    //
                    _cachedBitmapImage = bitmapImage;
                }
                UpdateCachedSettings();
                return;
            }

            BitmapDecoder decoder = null;

            if (_decoder == null)
            {
                // Note: We do not want to insert in the cache if there is a chance that
                //       the decode pixel width/height may cause the decoder LOD to change
                decoder = BitmapDecoder.CreateFromUriOrStream(
                    _baseUri,
                    UriSource,
                    StreamSource,
                    CreateOptions & ~BitmapCreateOptions.DelayCreation,
                    BitmapCacheOption.None, // do not cache the frames since we will do that here
                    _uriCachePolicy,
                    false
                    );

                if (decoder.IsDownloading)
                {
                    _isDownloading             = true;
                    _decoder                   = decoder;
                    decoder.DownloadProgress  += OnDownloadProgress;
                    decoder.DownloadCompleted += OnDownloadCompleted;
                    decoder.DownloadFailed    += OnDownloadFailed;
                }
                else
                {
                    Debug.Assert(decoder.SyncObject != null);
                }
            }
            else
            {
                // We already had a decoder, meaning we were downloading
                Debug.Assert(!_decoder.IsDownloading);
                decoder  = _decoder;
                _decoder = null;
            }

            if (decoder.Frames.Count == 0)
            {
                throw new System.ArgumentException(SR.Get(SRID.Image_NoDecodeFrames));
            }

            BitmapFrame  frame  = decoder.Frames[0];
            BitmapSource source = frame;

            Int32Rect sourceRect = SourceRect;

            if (sourceRect.X == 0 && sourceRect.Y == 0 &&
                sourceRect.Width == source.PixelWidth &&
                sourceRect.Height == source.PixelHeight)
            {
                sourceRect = Int32Rect.Empty;
            }

            if (!sourceRect.IsEmpty)
            {
                CroppedBitmap croppedSource = new CroppedBitmap();
                croppedSource.BeginInit();
                croppedSource.Source     = source;
                croppedSource.SourceRect = sourceRect;
                croppedSource.EndInit();

                source = croppedSource;
                if (_isDownloading)
                {
                    // Unregister the download events because this is a dummy image. See comment below.
                    source.UnregisterDownloadEventSource();
                }
            }

            int finalWidth  = DecodePixelWidth;
            int finalHeight = DecodePixelHeight;

            if (finalWidth == 0 && finalHeight == 0)
            {
                finalWidth  = source.PixelWidth;
                finalHeight = source.PixelHeight;
            }
            else if (finalWidth == 0)
            {
                finalWidth = (source.PixelWidth * finalHeight) / source.PixelHeight;
            }
            else if (finalHeight == 0)
            {
                finalHeight = (source.PixelHeight * finalWidth) / source.PixelWidth;
            }

            if (finalWidth != source.PixelWidth || finalHeight != source.PixelHeight ||
                Rotation != Rotation.Rotate0)
            {
                TransformedBitmap transformedSource = new TransformedBitmap();
                transformedSource.BeginInit();
                transformedSource.Source = source;

                TransformGroup transformGroup = new TransformGroup();

                if (finalWidth != source.PixelWidth || finalHeight != source.PixelHeight)
                {
                    int oldWidth  = source.PixelWidth;
                    int oldHeight = source.PixelHeight;

                    Debug.Assert(oldWidth > 0 && oldHeight > 0);

                    transformGroup.Children.Add(
                        new ScaleTransform(
                            (1.0 * finalWidth) / oldWidth,
                            (1.0 * finalHeight) / oldHeight));
                }

                if (Rotation != Rotation.Rotate0)
                {
                    double rotation = 0.0;

                    switch (Rotation)
                    {
                    case Rotation.Rotate0:
                        rotation = 0.0;
                        break;

                    case Rotation.Rotate90:
                        rotation = 90.0;
                        break;

                    case Rotation.Rotate180:
                        rotation = 180.0;
                        break;

                    case Rotation.Rotate270:
                        rotation = 270.0;
                        break;

                    default:
                        Debug.Assert(false);
                        break;
                    }

                    transformGroup.Children.Add(new RotateTransform(rotation));
                }

                transformedSource.Transform = transformGroup;

                transformedSource.EndInit();

                source = transformedSource;
                if (_isDownloading)
                {
                    //
                    // If we're currently downloading, then the BitmapFrameDecode isn't actually
                    // the image, it's just a 1x1 placeholder. The chain we're currently building
                    // will be replaced with another chain once download completes, so there's no
                    // need to have this chain handle DownloadCompleted.
                    //
                    // Having this chain handle DownloadCompleted is actually a bad thing. Because
                    // the dummy is just 1x1, the TransformedBitmap we're building here will have
                    // a large scaling factor (to scale the image from 1x1 up to whatever
                    // DecodePixelWidth/Height specifies). When the TransformedBitmap receives
                    // DownloadCompleted from the BFD, it will call into WIC to create a new
                    // bitmap scaler using the same large scaling factor, which can produce a huge
                    // bitmap (since the BFD is now no longer 1x1). This problem is made worse if
                    // this BitmapImage has BitmapCacheOption.OnLoad, since that will put a
                    // CachedBitmap after the TransformedBitmap. When DownloadCompleted propagates
                    // from the TransformedBitmap down to the CachedBitmap, the CachedBitmap will
                    // call CreateBitmapFromSource using the TransformedBitmap, which calls
                    // CopyPixels on the huge TransformedBitmap. We want to avoid chewing up the
                    // CPU and the memory, so we unregister the download event handlers here.
                    //
                    source.UnregisterDownloadEventSource();
                }
            }

            //
            // If the original image has a color profile and IgnoreColorProfile is not one of the create options,
            // apply the profile so bits are color-corrected.
            //
            if ((CreateOptions & BitmapCreateOptions.IgnoreColorProfile) == 0 &&
                frame.ColorContexts != null &&
                frame.ColorContexts[0] != null &&
                frame.ColorContexts[0].IsValid &&
                source.Format.Format != PixelFormatEnum.Extended
                )
            {
                // NOTE: Never do this for a non-MIL pixel format, because the format converter has
                // special knowledge to deal with the profile

                PixelFormat  duceFormat   = BitmapSource.GetClosestDUCEFormat(source.Format, source.Palette);
                bool         changeFormat = (source.Format != duceFormat);
                ColorContext destinationColorContext;

                // We need to make sure, we can actually create the ColorContext for the destination duceFormat
                // If the duceFormat is gray or scRGB, the following is not supported, so we cannot
                // create the ColorConvertedBitmap
                try
                {
                    destinationColorContext = new ColorContext(duceFormat);
                }
                catch (NotSupportedException)
                {
                    destinationColorContext = null;
                }

                if (destinationColorContext != null)
                {
                    bool conversionSuccess = false;
                    bool badColorContext   = false;

                    // First try if the color converter can handle the source format directly
                    // Its possible that the color converter does not support certain pixelformats, so put a try/catch here.
                    try
                    {
                        ColorConvertedBitmap colorConvertedBitmap = new ColorConvertedBitmap(
                            source,
                            frame.ColorContexts[0],
                            destinationColorContext,
                            duceFormat
                            );

                        source = colorConvertedBitmap;
                        if (_isDownloading)
                        {
                            // Unregister the download events because this is a dummy image. See comment above.
                            source.UnregisterDownloadEventSource();
                        }
                        conversionSuccess = true;
                    }
                    catch (NotSupportedException)
                    {
                    }
                    catch (FileFormatException)
                    {
                        // If the file contains a bad color context, we catch the exception here
                        // and don't bother trying the color conversion below, since color transform isn't possible
                        // with the given color context.
                        badColorContext = true;
                    }

                    if (!conversionSuccess && !badColorContext && changeFormat)
                    {   // If the conversion failed, we first use
                        // a FormatConvertedBitmap, and then Color Convert that one...
                        FormatConvertedBitmap formatConvertedBitmap = new FormatConvertedBitmap(source, duceFormat, source.Palette, 0.0);

                        ColorConvertedBitmap colorConvertedBitmap = new ColorConvertedBitmap(
                            formatConvertedBitmap,
                            frame.ColorContexts[0],
                            destinationColorContext,
                            duceFormat
                            );

                        source = colorConvertedBitmap;
                        if (_isDownloading)
                        {
                            // Unregister the download events because this is a dummy image. See comment above.
                            source.UnregisterDownloadEventSource();
                        }
                    }
                }
            }

            if (CacheOption != BitmapCacheOption.None)
            {
                try
                {
                    // The bitmaps bits could be corrupt, and this will cause an exception if the CachedBitmap forces a decode.
                    CachedBitmap cachedSource = new CachedBitmap(source, CreateOptions & ~BitmapCreateOptions.DelayCreation, CacheOption);
                    source = cachedSource;
                    if (_isDownloading)
                    {
                        // Unregister the download events because this is a dummy image. See comment above.
                        source.UnregisterDownloadEventSource();
                    }
                }
                catch (Exception e)
                {
                    RecoverFromDecodeFailure(e);
                    CreationCompleted = true; // we're bailing out because the decode failed
                    return;
                }
            }

            // If CacheOption == OnLoad, no need to keep the stream around
            if (decoder != null && CacheOption == BitmapCacheOption.OnLoad)
            {
                decoder.CloseStream();
            }
            else if (CacheOption != BitmapCacheOption.OnLoad)
            {
                //ensure that we don't GC the source
                _finalSource = source;
            }

            WicSourceHandle = source.WicSourceHandle;
            IsSourceCached  = source.IsSourceCached;

            CreationCompleted = true;
            UpdateCachedSettings();

            // Only insert in the imaging cache if download is complete
            if (!IsDownloading)
            {
                InsertInCache(uri);
            }
        }
        internal void SetupFrames(BitmapDecoder decoder, ReadOnlyCollection<BitmapFrame> frames)
        {
            uint numFrames = 1;

            HRESULT.Check(UnsafeNativeMethods.WICBitmapDecoder.GetFrameCount(_decoderHandle, out numFrames));

            _frames = new List<BitmapFrame>((int)numFrames);

            // initialize the list of frames to null.
            // We'll fill it as it's used (pay for play).
            for (int i = 0; i < (int)numFrames; i++)
            {
                if (i > 0 && _cacheOption != BitmapCacheOption.OnLoad)
                {
                    _createOptions |= BitmapCreateOptions.DelayCreation;
                }

                BitmapFrameDecode bfd = null;

                if ((frames != null) && (frames.Count == (i + 1)))
                {
                    // If we already have a frames collection, get the BitmapFrame from it
                    bfd = frames[i] as BitmapFrameDecode;
                    bfd.UpdateDecoder(this);
                }
                else if (decoder == null)
                {
                    // All frames should be frozen.
                    bfd = new BitmapFrameDecode(
                        i,
                        _createOptions,
                        _cacheOption,
                        this
                        );
                    bfd.Freeze();
                }
                else
                {
                    // if we are creating from an existing cache, use the frames
                    // already stored in that cache
                    // All frames should be frozen.
                    bfd = new BitmapFrameDecode(
                        i,
                        _createOptions,
                        _cacheOption,
                        decoder.Frames[i] as BitmapFrameDecode
                        );
                    bfd.Freeze();
                }

                _frames.Add(bfd);
            }
        }
Example #19
0
        internal static void BeginDownload( 
            BitmapDecoder decoder,
            Uri uri, 
            RequestCachePolicy uriCachePolicy, 
            Stream stream
            ) 
        {
            lock (_syncLock)
            {
                if (!_thread.IsAlive) 
                {
                    _thread.IsBackground = true; 
                    _thread.Start(); 
                }
            } 

            QueueEntry entry;

            // If there is already a download for this uri, just add the decoder to the list 
            if (uri != null)
            { 
                lock (_syncLock) 
                {
                    if (_uriTable[uri] != null) 
                    {
                        entry = (QueueEntry)_uriTable[uri];
                        entry.decoders.Add(decoder);
 
                        return;
                    } 
                } 
            }
 
            entry = new QueueEntry();
            entry.decoders  = new List<BitmapDecoder>();

            lock (_syncLock) 
            {
                entry.decoders.Add(decoder); 
            } 

            entry.inputUri = uri; 
            entry.inputStream = stream;

            string cacheFolder = MS.Win32.WinInet.InternetCacheFolder.LocalPath;
            bool passed = false; 

            new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Assert(); // BlessedAssert 
            try 
            {
                // Get the file path 
                StringBuilder tmpFileName = new StringBuilder(NativeMethods.MAX_PATH);
                MS.Win32.UnsafeNativeMethods.GetTempFileName(cacheFolder, "WPF", 0, tmpFileName);

                try 
                {
                    string pathToUse = tmpFileName.ToString(); 
                    SafeFileHandle fileHandle = MS.Win32.UnsafeNativeMethods.CreateFile( 
                        pathToUse,
                        NativeMethods.GENERIC_READ | NativeMethods.GENERIC_WRITE, /* dwDesiredAccess */ 
                        0,                                                        /* dwShare */
                        null,                                                     /* lpSecurityAttributes */
                        NativeMethods.CREATE_ALWAYS,                              /* dwCreationDisposition */
                        NativeMethods.FILE_ATTRIBUTE_TEMPORARY | 
                        NativeMethods.FILE_FLAG_DELETE_ON_CLOSE,                  /* dwFlagsAndAttributes */
                        IntPtr.Zero                                               /* hTemplateFile */ 
                        ); 

                    if (fileHandle.IsInvalid) 
                    {
                        throw new Win32Exception();
                    }
 
                    entry.outputStream = new FileStream(fileHandle, FileAccess.ReadWrite);
                    entry.streamPath = pathToUse; 
                    passed = true; 
                }
                catch(Exception e) 
                {
                    if (CriticalExceptions.IsCriticalException(e))
                    {
                        throw; 
                    }
                } 
            } 
            finally
            { 
                SecurityPermission.RevertAssert();
            }

            if (!passed) 
            {
                throw new IOException(SR.Get(SRID.Image_CannotCreateTempFile)); 
            } 

            entry.readBuffer  = new byte[READ_SIZE]; 
            entry.contentLength = -1;
            entry.contentType = string.Empty;
            entry.lastPercent = 0;
 
            // Add the entry to the table if we know the uri
            if (uri != null) 
            { 
                lock (_syncLock)
                { 
                    _uriTable[uri] = entry;
                }
            }
 
            if (stream == null)
            { 
                bool fElevate = false; 
                if (uri.Scheme == Uri.UriSchemeHttp || uri.Scheme == Uri.UriSchemeHttps)
                { 
                    SecurityHelper.BlockCrossDomainForHttpsApps(uri);

                    // In this case we first check to see if the consumer has media permissions for
                    // safe media (Site of Origin + Cross domain), if it 
                    // does we assert and run the code that requires the assert
                    if (SecurityHelper.CallerHasMediaPermission(MediaPermissionAudio.NoAudio, 
                                                                MediaPermissionVideo.NoVideo, 
                                                                MediaPermissionImage.SafeImage))
                    { 
                        fElevate = true;
                    }
                }
 
                // This is the case where we are accessing an http image from an http site and we have media permission
                if (fElevate) 
                { 
                    (new WebPermission(NetworkAccess.Connect, BindUriHelper.UriToString(uri))).Assert(); // BlessedAssert
                } 
                try
                {
                    entry.webRequest = WpfWebRequestHelper.CreateRequest(uri);
                    if (uriCachePolicy != null) 
                    {
                        entry.webRequest.CachePolicy = uriCachePolicy; 
                    } 
                }
                finally 
                {
                    if(fElevate)
                    {
                        WebPermission.RevertAssert(); 
                    }
                } 
 
                entry.webRequest.BeginGetResponse(_responseCallback, entry);
            } 
            else
            {
                _workQueue.Enqueue(entry);
                // Signal 
                _waitEvent.Set();
            } 
        } 
        void FillFrameList(BitmapDecoder decoder)
        {
            //continue if loaded
            Progress = 1;
            var list = new List<FrameData>(decoder.Frames.Count);
            var delaySpread = new Spread<int>(0);
            var positionSpread = new Spread<Vector2D>(0);
            var sizeSpread = new Spread<Vector2D>(0);
            var disposalSpread = new Spread<GifDisposal>(0);

            Format = decoder.Frames[0].Format;

            //convert and copy frames
            foreach (var frame in decoder.Frames)
            {

                //read meta data
                if(!frame.IsFrozen)
                    frame.Freeze();

                var meta = frame.Metadata as BitmapMetadata;
                if(meta != null)
                {
                    if(meta.ContainsQuery("/grctlext/Delay"))
                        delaySpread.Add((ushort)meta.GetQuery("/grctlext/Delay"));
                    else
                        delaySpread.Add(0);

                    if(meta.ContainsQuery("/grctlext/Disposal"))
                        disposalSpread.Add((GifDisposal)((byte)meta.GetQuery("/grctlext/Disposal")));
                    else
                        disposalSpread.Add(GifDisposal.None);

                    var left = (ushort)0;
                    var top = (ushort)0;

                     if(meta.ContainsQuery("/imgdesc/Left"))
                         left = (ushort)meta.GetQuery("/imgdesc/Left");

                     if(meta.ContainsQuery("/imgdesc/Top"))
                         top = (ushort)meta.GetQuery("/imgdesc/Top");

                    positionSpread.Add(new Vector2D(left, top));
                }

                sizeSpread.Add(new Vector2D(frame.PixelWidth, frame.PixelHeight));

                var convertedBitmap = new FormatConvertedBitmap();

                convertedBitmap.BeginInit();
                convertedBitmap.Source = frame;
                convertedBitmap.DestinationFormat = PixelFormats.Bgra32;
                convertedBitmap.EndInit();

                list.Add(CopyBitmapFrameToFrameData(convertedBitmap));
            }

            FFrameDataList = list;

            //recreate texture resources
            FTextureSpread.ResizeAndDispose(FFrameDataList.Count, i => CreateTextureResource(i));
            DelaySpread = delaySpread;
            PositionSpread = positionSpread;
            SizeSpread = sizeSpread;
            DisposalSpread = disposalSpread;
            IsLoading = false;
            HasNewData = true;
        }
Example #21
0
        ///
        /// Begin a download
        ///
        internal static void BeginDownload(
            BitmapDecoder decoder,
            Uri uri,
            RequestCachePolicy uriCachePolicy,
            Stream stream
            )
        {
            lock (_syncLock)
            {
                if (!_thread.IsAlive)
                {
                    _thread.IsBackground = true;
                    _thread.Start();
                }
            }

            QueueEntry entry;

            // If there is already a download for this uri, just add the decoder to the list
            if (uri != null)
            {
                lock (_syncLock)
                {
                    if (_uriTable[uri] != null)
                    {
                        entry = (QueueEntry)_uriTable[uri];
                        entry.decoders.Add(new WeakReference(decoder));

                        return;
                    }
                }
            }

            entry          = new QueueEntry();
            entry.decoders = new List <WeakReference>();

            lock (_syncLock)
            {
                entry.decoders.Add(new WeakReference(decoder));
            }

            entry.inputUri    = uri;
            entry.inputStream = stream;

            string cacheFolder = MS.Win32.WinInet.InternetCacheFolder.LocalPath;
            bool   passed      = false;

            new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Assert(); // BlessedAssert
            try
            {
                // Get the file path
                StringBuilder tmpFileName = new StringBuilder(NativeMethods.MAX_PATH);
                MS.Win32.UnsafeNativeMethods.GetTempFileName(cacheFolder, "WPF", 0, tmpFileName);

                try
                {
                    string         pathToUse  = tmpFileName.ToString();
                    SafeFileHandle fileHandle = MS.Win32.UnsafeNativeMethods.CreateFile(
                        pathToUse,
                        NativeMethods.GENERIC_READ | NativeMethods.GENERIC_WRITE, /* dwDesiredAccess */
                        0,                                                        /* dwShare */
                        null,                                                     /* lpSecurityAttributes */
                        NativeMethods.CREATE_ALWAYS,                              /* dwCreationDisposition */
                        NativeMethods.FILE_ATTRIBUTE_TEMPORARY |
                        NativeMethods.FILE_FLAG_DELETE_ON_CLOSE,                  /* dwFlagsAndAttributes */
                        IntPtr.Zero                                               /* hTemplateFile */
                        );

                    if (fileHandle.IsInvalid)
                    {
                        throw new Win32Exception();
                    }

                    entry.outputStream = new FileStream(fileHandle, FileAccess.ReadWrite);
                    entry.streamPath   = pathToUse;
                    passed             = true;
                }
                catch (Exception e)
                {
                    if (CriticalExceptions.IsCriticalException(e))
                    {
                        throw;
                    }
                }
            }
            finally
            {
                SecurityPermission.RevertAssert();
            }

            if (!passed)
            {
                throw new IOException(SR.Get(SRID.Image_CannotCreateTempFile));
            }

            entry.readBuffer    = new byte[READ_SIZE];
            entry.contentLength = -1;
            entry.contentType   = string.Empty;
            entry.lastPercent   = 0;

            // Add the entry to the table if we know the uri
            if (uri != null)
            {
                lock (_syncLock)
                {
                    _uriTable[uri] = entry;
                }
            }

            if (stream == null)
            {
                bool fElevate = false;
                if (uri.Scheme == Uri.UriSchemeHttp || uri.Scheme == Uri.UriSchemeHttps)
                {
                    SecurityHelper.BlockCrossDomainForHttpsApps(uri);

                    // In this case we first check to see if the consumer has media permissions for
                    // safe media (Site of Origin + Cross domain), if it
                    // does we assert and run the code that requires the assert
                    if (SecurityHelper.CallerHasMediaPermission(MediaPermissionAudio.NoAudio,
                                                                MediaPermissionVideo.NoVideo,
                                                                MediaPermissionImage.SafeImage))
                    {
                        fElevate = true;
                    }
                }

                // This is the case where we are accessing an http image from an http site and we have media permission
                if (fElevate)
                {
                    (new WebPermission(NetworkAccess.Connect, BindUriHelper.UriToString(uri))).Assert(); // BlessedAssert
                }
                try
                {
                    entry.webRequest = WpfWebRequestHelper.CreateRequest(uri);
                    if (uriCachePolicy != null)
                    {
                        entry.webRequest.CachePolicy = uriCachePolicy;
                    }
                }
                finally
                {
                    if (fElevate)
                    {
                        WebPermission.RevertAssert();
                    }
                }

                entry.webRequest.BeginGetResponse(_responseCallback, entry);
            }
            else
            {
                _workQueue.Enqueue(entry);
                // Signal
                _waitEvent.Set();
            }
        }
Example #22
0
 public void CreateImageObject(string img, string filename)
 {
     _fp = new FileProperties();
     _fs = new FileStream(img, FileMode.Open);
     _decoder = BitmapDecoder.Create(_fs, BitmapCreateOptions.None, BitmapCacheOption.Default);
     _frame = _decoder.Frames[0];
     _metadata = _frame.Metadata as BitmapMetadata;
     if (_metadata != null && _metadata.DateTaken != null)
     {
         _fp.DateTaken = DateTime.Parse(_metadata.DateTaken);
         _fp.FullImagePath = img;
     }
     else
     {
         _fp.FullImagePath = img;
     }
     _fp.FileName = filename;
     _fp.FolderPath = Path.GetDirectoryName(img);
     _theImages.Add(_fp);
     _fs.Close();
 }
 static FieldInfo GetDecoderField(BitmapDecoder decoder, string fieldName) {
     FieldInfo streamField = decoder.GetType().GetField(fieldName, BindingFlags.NonPublic | BindingFlags.Instance);
     if(streamField == null)
         throw new Exception(string.Format("{0}.{1} ({2})", decoder.GetType().FullName, fieldName, decoder.GetType().AssemblyQualifiedName));
     return streamField;
 }
Example #24
0
        internal void UpdateDecoder(BitmapDecoder decoder)
        {
            Debug.Assert(_decoder != null); 
            _decoder = decoder;
            _syncObject = decoder.SyncObject; 
            WicSourceHandle = null; 
            _needsUpdate = true;
            FinalizeCreation(); 

            // Trigger a update of the UCE resource
            RegisterForAsyncUpdateResource();
        } 
Example #25
0
 /// <summary>
 /// Get a BitmapDecoder of this report 
 /// </summary>
 /// <returns>Return a BitmapDecoder of this current report. Return null on error</returns>
 public BitmapDecoder GetBitmapDecoder()
 {
     try
     {
         if (_dec == null)
         {
             Stream mStream = new MemoryStream(GetImageArray());
             _dec = BitmapDecoder.Create(mStream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
             return _dec;
         }
         else
             return _dec;
     }
     catch
     {
         return null;
     }
 }