/// <summary>
        /// Resizes the current image to the given dimensions using Content Aware Resizing.
        /// </summary>
        /// <param name="factory">
        /// The current instance of the <see cref="T:ImageProcessor.ImageFactory"/> class
        /// that this method extends.
        /// </param>
        /// <param name="size">
        /// The <see cref="T:System.Drawing.Size"/> containing the width and height to set the image to.
        /// </param>
        /// <returns>
        /// The current instance of the <see cref="T:ImageProcessor.ImageFactory"/> class.
        /// </returns>
        public static ImageFactory ContentAwareResize(this ImageFactory factory, Size size)
        {
            if (factory.ShouldProcess)
            {
                int width  = size.Width;
                int height = size.Height;

                ContentAwareResizeLayer resizeLayer = new ContentAwareResizeLayer(new Size(width, height));
                return(factory.ContentAwareResize(resizeLayer));
            }

            return(factory);
        }
        /// <summary>
        /// Resizes the current image to the given dimensions using Content Aware Resizing.
        /// </summary>
        /// <param name="factory">
        /// The current instance of the <see cref="T:ImageProcessor.ImageFactory"/> class
        /// that this method extends.
        /// </param>
        /// <param name="layer">
        /// The <see cref="ContentAwareResizeLayer"/> containing the properties required to resize the image.
        /// </param>
        /// <returns>
        /// The current instance of the <see cref="T:ImageProcessor.ImageFactory"/> class.
        /// </returns>
        public static ImageFactory ContentAwareResize(this ImageFactory factory, ContentAwareResizeLayer layer)
        {
            if (factory.ShouldProcess)
            {
                Dictionary <string, string> resizeSettings = new Dictionary <string, string> {
                    { "MaxWidth", layer.Size.Width.ToString("G") }, { "MaxHeight", layer.Size.Height.ToString("G") }
                };

                ContentAwareResize resize = new ContentAwareResize {
                    DynamicParameter = layer, Settings = resizeSettings
                };
                factory.CurrentImageFormat.ApplyProcessor(resize.ProcessImage, factory);
            }

            return(factory);
        }
        /// <summary>
        /// Processes the image.
        /// </summary>
        /// <param name="factory">
        /// The current instance of the <see cref="T:ImageProcessor.ImageFactory"/> class containing
        /// the image to process.
        /// </param>
        /// <returns>
        /// The processed image from the current instance of the <see cref="T:ImageProcessor.ImageFactory"/> class.
        /// </returns>
        public Image ProcessImage(ImageFactory factory)
        {
            string fileName = Guid.NewGuid().ToString();

            // Use bmp's as the temporary files since they are lossless and support transparency.
            string sourcePath  = Path.Combine(CairBootstrapper.CairPath, fileName + ".bmp");
            string resizedPath = Path.Combine(CairBootstrapper.CairPath, fileName + "-r.bmp");

            // Gather the parameters.
            ContentAwareResizeLayer layer = (ContentAwareResizeLayer)this.DynamicParameter;
            int width   = layer.Size.Width;
            int height  = layer.Size.Height;
            int timeout = layer.Timeout > 0 ? layer.Timeout : 60000;

            int defaultMaxWidth;
            int defaultMaxHeight;

            int.TryParse(this.Settings["MaxWidth"], NumberStyles.Any, CultureInfo.InvariantCulture, out defaultMaxWidth);
            int.TryParse(this.Settings["MaxHeight"], NumberStyles.Any, CultureInfo.InvariantCulture, out defaultMaxHeight);

            Bitmap newImage = null;
            Image  image    = factory.Image;

            try
            {
                int sourceWidth  = image.Width;
                int sourceHeight = image.Height;

                // Fractional variants for preserving aspect ratio.
                double percentHeight = Math.Abs(height / (double)sourceHeight);
                double percentWidth  = Math.Abs(width / (double)sourceWidth);

                int maxWidth  = defaultMaxWidth > 0 ? defaultMaxWidth : int.MaxValue;
                int maxHeight = defaultMaxHeight > 0 ? defaultMaxHeight : int.MaxValue;

                // If height or width is not passed we assume that the standard ratio is to be kept.
                if (height == 0)
                {
                    height = (int)Math.Ceiling(sourceHeight * percentWidth);
                }

                if (width == 0)
                {
                    width = (int)Math.Ceiling(sourceWidth * percentHeight);
                }

                if (width > 0 && height > 0 && width <= maxWidth && height <= maxHeight)
                {
                    // Save the temporary bitmap.
                    image.Save(sourcePath, ImageFormat.Bmp);

                    // Process the image using the CAIR executable.
                    string arguments = string.Format(
                        " -I \"{0}\" -O \"{1}\" -C {2} -X {3} -Y {4} -E {5} -T {6} -R {7}",
                        sourcePath,
                        resizedPath,
                        (int)layer.ConvolutionType,
                        width,
                        height,
                        (int)layer.EnergyFunction,
                        layer.Parallelize ? Math.Min(4, Environment.ProcessorCount) : 1,
                        (int)layer.OutputType);

                    if (!string.IsNullOrWhiteSpace(layer.WeightPath))
                    {
                        arguments = string.Format("{0} -W {1}", arguments, layer.WeightPath);
                    }

                    this.ProcessCairImage(arguments, timeout);

                    // Assign the new image.
                    newImage = new Bitmap(resizedPath);
                    newImage.MakeTransparent();

                    // Reassign the image.
                    image.Dispose();
                    image = newImage;
                }
            }
            catch (Exception ex)
            {
                if (newImage != null)
                {
                    newImage.Dispose();
                }

                throw new ImageProcessingException("Error processing image with " + this.GetType().Name, ex);
            }
            finally
            {
                FileInfo sourceFileInfo = new FileInfo(sourcePath);
                if (sourceFileInfo.Exists)
                {
                    sourceFileInfo.Delete();
                }

                FileInfo resizedFileInfo = new FileInfo(resizedPath);
                if (resizedFileInfo.Exists)
                {
                    resizedFileInfo.Delete();
                }
            }

            return(image);
        }