diff --git a/src/ImageProcessor/Common/Exceptions/ImageProcessingException.cs b/src/ImageProcessor/Common/Exceptions/ImageProcessingException.cs
new file mode 100644
index 0000000000..fe187e077e
--- /dev/null
+++ b/src/ImageProcessor/Common/Exceptions/ImageProcessingException.cs
@@ -0,0 +1,44 @@
+//
+// Copyright (c) James Jackson-South and contributors.
+// Licensed under the Apache License, Version 2.0.
+//
+
+namespace ImageProcessor
+{
+ using System;
+
+ ///
+ /// The exception that is thrown when an error occurs when applying a process to an image.
+ ///
+ public class ImageProcessingException : Exception
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public ImageProcessingException()
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class with the name of the
+ /// parameter that causes this exception.
+ ///
+ /// The error message that explains the reason for this exception.
+ public ImageProcessingException(string errorMessage)
+ : base(errorMessage)
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class with a specified
+ /// error message and the exception that is the cause of this exception.
+ ///
+ /// The error message that explains the reason for this exception.
+ /// The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic)
+ /// if no inner exception is specified.
+ public ImageProcessingException(string errorMessage, Exception innerException)
+ : base(errorMessage, innerException)
+ {
+ }
+ }
+}
diff --git a/src/ImageProcessor/ParallelImageProcessor.cs b/src/ImageProcessor/ParallelImageProcessor.cs
index 1380ab68b3..8eb8d6c869 100644
--- a/src/ImageProcessor/ParallelImageProcessor.cs
+++ b/src/ImageProcessor/ParallelImageProcessor.cs
@@ -75,50 +75,58 @@ namespace ImageProcessor
///
public void Apply(ImageBase target, ImageBase source, int width, int height, Rectangle targetRectangle = default(Rectangle), Rectangle sourceRectangle = default(Rectangle))
{
- float[] pixels = new float[width * height * 4];
- target.SetPixels(width, height, pixels);
-
- if (sourceRectangle == Rectangle.Empty)
+ try
{
- sourceRectangle = source.Bounds;
- }
-
- // We don't want to affect the original source pixels so we make clone here.
- ImageFrame frame = source as ImageFrame;
- Image temp = frame != null ? new Image(frame) : new Image((Image)source);
- this.OnApply(temp, target, target.Bounds, sourceRectangle);
+ float[] pixels = new float[width * height * 4];
+ target.SetPixels(width, height, pixels);
- targetRectangle = target.Bounds;
- this.numRowsProcessed = 0;
- this.totalRows = targetRectangle.Bottom;
+ if (sourceRectangle == Rectangle.Empty)
+ {
+ sourceRectangle = source.Bounds;
+ }
- if (this.Parallelism > 1)
- {
- int partitionCount = this.Parallelism;
+ // We don't want to affect the original source pixels so we make clone here.
+ ImageFrame frame = source as ImageFrame;
+ Image temp = frame != null ? new Image(frame) : new Image((Image)source);
+ this.OnApply(temp, target, target.Bounds, sourceRectangle);
- Task[] tasks = new Task[partitionCount];
+ targetRectangle = target.Bounds;
+ this.numRowsProcessed = 0;
+ this.totalRows = targetRectangle.Bottom;
- for (int p = 0; p < partitionCount; p++)
+ if (this.Parallelism > 1)
{
- int current = p;
- tasks[p] = Task.Run(() =>
- {
- int batchSize = targetRectangle.Bottom / partitionCount;
- int yStart = current * batchSize;
- int yEnd = current == partitionCount - 1 ? targetRectangle.Bottom : yStart + batchSize;
+ int partitionCount = this.Parallelism;
- this.Apply(target, temp, targetRectangle, sourceRectangle, yStart, yEnd);
- });
+ Task[] tasks = new Task[partitionCount];
+
+ for (int p = 0; p < partitionCount; p++)
+ {
+ int current = p;
+ tasks[p] = Task.Run(() =>
+ {
+ int batchSize = targetRectangle.Bottom / partitionCount;
+ int yStart = current * batchSize;
+ int yEnd = current == partitionCount - 1 ? targetRectangle.Bottom : yStart + batchSize;
+
+ this.Apply(target, temp, targetRectangle, sourceRectangle, yStart, yEnd);
+ });
+ }
+
+ Task.WaitAll(tasks);
+ }
+ else
+ {
+ this.Apply(target, temp, targetRectangle, sourceRectangle, targetRectangle.Y, targetRectangle.Bottom);
}
- Task.WaitAll(tasks);
+ this.AfterApply(temp, target, target.Bounds, sourceRectangle);
}
- else
+ catch (Exception ex)
{
- this.Apply(target, temp, targetRectangle, sourceRectangle, targetRectangle.Y, targetRectangle.Bottom);
- }
- this.AfterApply(temp, target, target.Bounds, sourceRectangle);
+ throw new ImageProcessingException($"An error occured when processing the image using {this.GetType().Name}. See the inner exception for more detail.", ex);
+ }
}
///