From b5d7d12717aea795285a9efcf82a1f24771ea852 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Wed, 27 Jan 2016 16:12:26 +1100 Subject: [PATCH] Add better exception handling. Former-commit-id: f6ba09bdf9b16351b639490de55c5a0402acd7cc Former-commit-id: 676fecf193f635d19f74ca3de41b8ced7e667352 Former-commit-id: 00484e51faae841544bdc27a2f59d227c664012c --- .../Exceptions/ImageProcessingException.cs | 44 ++++++++++++ src/ImageProcessor/ParallelImageProcessor.cs | 72 ++++++++++--------- 2 files changed, 84 insertions(+), 32 deletions(-) create mode 100644 src/ImageProcessor/Common/Exceptions/ImageProcessingException.cs 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); + } } ///