diff --git a/src/ImageProcessor.Web/NET4/ImageProcessor.Web_NET4.csproj b/src/ImageProcessor.Web/NET4/ImageProcessor.Web_NET4.csproj
index 2a149236a..d830257ae 100644
--- a/src/ImageProcessor.Web/NET4/ImageProcessor.Web_NET4.csproj
+++ b/src/ImageProcessor.Web/NET4/ImageProcessor.Web_NET4.csproj
@@ -95,6 +95,9 @@
ImageSecuritySection.cs
+
+ DirectoryInfoExtensions.cs
+
CommonParameterParserUtility.cs
diff --git a/src/ImageProcessor.Web/NET45/Caching/DiskCache.cs b/src/ImageProcessor.Web/NET45/Caching/DiskCache.cs
index f1cefc657..6a23d48ad 100644
--- a/src/ImageProcessor.Web/NET45/Caching/DiskCache.cs
+++ b/src/ImageProcessor.Web/NET45/Caching/DiskCache.cs
@@ -22,6 +22,7 @@ namespace ImageProcessor.Web.Caching
using ImageProcessor.Common.Extensions;
using ImageProcessor.Web.Configuration;
+ using ImageProcessor.Web.Extensions;
using ImageProcessor.Web.Helpers;
#endregion
@@ -212,37 +213,44 @@ namespace ImageProcessor.Web.Caching
///
private void TrimCachedFolders(string path)
{
- // ReSharper disable once AssignNullToNotNullAttribute
- DirectoryInfo directoryInfo = new DirectoryInfo(Path.GetDirectoryName(path));
- DirectoryInfo parentDirectoryInfo = directoryInfo.Parent;
+ string directory = Path.GetDirectoryName(path);
- // ReSharper disable once PossibleNullReferenceException
- foreach (DirectoryInfo enumerateDirectory in parentDirectoryInfo.EnumerateDirectories())
+ if (directory != null)
{
- IEnumerable files = enumerateDirectory.EnumerateFiles().OrderBy(f => f.CreationTimeUtc);
- int count = files.Count();
+ DirectoryInfo directoryInfo = new DirectoryInfo(directory);
+ DirectoryInfo parentDirectoryInfo = directoryInfo.Parent;
- foreach (FileInfo fileInfo in files)
+ if (parentDirectoryInfo != null)
{
- try
+ // UNC folders can throw exceptions if the file doesn't exist.
+ foreach (DirectoryInfo enumerateDirectory in parentDirectoryInfo.SafeEnumerateDirectories())
{
- // If the group count is equal to the max count minus 1 then we know we
- // have reduced the number of items below the maximum allowed.
- // We'll cleanup any orphaned expired files though.
- if (!this.IsExpired(fileInfo.CreationTimeUtc) && count <= MaxFilesCount - 1)
+ IEnumerable files = enumerateDirectory.EnumerateFiles().OrderBy(f => f.CreationTimeUtc);
+ int count = files.Count();
+
+ foreach (FileInfo fileInfo in files)
{
- break;
+ try
+ {
+ // If the group count is equal to the max count minus 1 then we know we
+ // have reduced the number of items below the maximum allowed.
+ // We'll cleanup any orphaned expired files though.
+ if (!this.IsExpired(fileInfo.CreationTimeUtc) && count <= MaxFilesCount - 1)
+ {
+ break;
+ }
+
+ // Remove from the cache and delete each CachedImage.
+ CacheIndexer.Remove(fileInfo.Name);
+ fileInfo.Delete();
+ count -= 1;
+ }
+ // ReSharper disable once EmptyGeneralCatchClause
+ catch
+ {
+ // Do nothing; skip to the next file.
+ }
}
-
- // Remove from the cache and delete each CachedImage.
- CacheIndexer.Remove(fileInfo.Name);
- fileInfo.Delete();
- count -= 1;
- }
- // ReSharper disable once EmptyGeneralCatchClause
- catch
- {
- // Do nothing; skip to the next file.
}
}
}
diff --git a/src/ImageProcessor.Web/NET45/Configuration/ImageProcessorConfiguration.cs b/src/ImageProcessor.Web/NET45/Configuration/ImageProcessorConfiguration.cs
index b0977a962..9d3ea6be9 100644
--- a/src/ImageProcessor.Web/NET45/Configuration/ImageProcessorConfiguration.cs
+++ b/src/ImageProcessor.Web/NET45/Configuration/ImageProcessorConfiguration.cs
@@ -22,8 +22,8 @@ namespace ImageProcessor.Web.Configuration
using ImageProcessor.Common.Extensions;
using ImageProcessor.Processors;
- using ImageProcessor.Web.Processors;
using ImageProcessor.Web.Helpers;
+ using ImageProcessor.Web.Processors;
///
/// Encapsulates methods to allow the retrieval of ImageProcessor settings.
diff --git a/src/ImageProcessor.Web/NET45/HttpModules/ImageProcessingModule.cs b/src/ImageProcessor.Web/NET45/HttpModules/ImageProcessingModule.cs
index 33877e15b..d70e71867 100644
--- a/src/ImageProcessor.Web/NET45/HttpModules/ImageProcessingModule.cs
+++ b/src/ImageProcessor.Web/NET45/HttpModules/ImageProcessingModule.cs
@@ -359,7 +359,7 @@ namespace ImageProcessor.Web.HttpModules
IPrincipal user = context.User ?? new GenericPrincipal(new GenericIdentity(string.Empty, string.Empty), new string[0]);
// Do we have permission to call UrlAuthorizationModule.CheckUrlAccessForPrincipal?
- PermissionSet permission = new PermissionSet(PermissionState.Unrestricted);
+ PermissionSet permission = new PermissionSet(PermissionState.None);
permission.AddPermission(new AspNetHostingPermission(AspNetHostingPermissionLevel.Unrestricted));
bool hasPermission = permission.IsSubsetOf(AppDomain.CurrentDomain.PermissionSet);
diff --git a/src/ImageProcessor.Web/NET45/ImageProcessor.Web_NET45.csproj b/src/ImageProcessor.Web/NET45/ImageProcessor.Web_NET45.csproj
index ac434afe5..2f5e77f23 100644
--- a/src/ImageProcessor.Web/NET45/ImageProcessor.Web_NET45.csproj
+++ b/src/ImageProcessor.Web/NET45/ImageProcessor.Web_NET45.csproj
@@ -53,6 +53,7 @@
+
diff --git a/src/ImageProcessor/Imaging/Formats/FormatUtilities.cs b/src/ImageProcessor/Imaging/Formats/FormatUtilities.cs
index a72485a19..53025bf42 100644
--- a/src/ImageProcessor/Imaging/Formats/FormatUtilities.cs
+++ b/src/ImageProcessor/Imaging/Formats/FormatUtilities.cs
@@ -131,40 +131,42 @@ namespace ImageProcessor.Imaging.Formats
if (fetchFrames)
{
- FrameDimension frameDimension = new FrameDimension(image.FrameDimensionsList[0]);
- int frameCount = image.GetFrameCount(frameDimension);
+ int frameCount = image.GetFrameCount(FrameDimension.Time);
int last = frameCount - 1;
- int delay = 0;
+ int length = 0;
+
List gifFrames = new List();
+ // Get the times stored in the gif.
+ byte[] times = image.GetPropertyItem((int)ExifPropertyTag.FrameDelay).Value;
+
for (int i = 0; i < frameCount; i++)
{
+ // Convert each 4-byte chunk into an integer.
// GDI returns a single array with all delays, while Mono returns a different array for each frame.
- image.SelectActiveFrame(frameDimension, i);
- byte[] times = image.GetPropertyItem(20736).Value;
- int thisDelay = BitConverter.ToInt32(times, (4 * i) % times.Length);
- int toAddDelay = thisDelay * 10 < 20 ? 20 : thisDelay * 10; // Minimum delay is 20 ms
+ int delay = BitConverter.ToInt32(times, (4 * i) % times.Length);
+ delay = delay * 10 < 20 ? 20 : delay * 10; // Minimum delay is 20 ms
// Find the frame
- image.SelectActiveFrame(frameDimension, i);
+ image.SelectActiveFrame(FrameDimension.Time, i);
// TODO: Get positions.
- gifFrames.Add(new GifFrame { Delay = toAddDelay, Image = (Image)image.Clone() });
+ gifFrames.Add(new GifFrame { Delay = delay, Image = (Image)image.Clone() });
// Reset the position.
if (i == last)
{
- image.SelectActiveFrame(frameDimension, 0);
+ image.SelectActiveFrame(FrameDimension.Time, 0);
}
- delay += toAddDelay;
+ length += delay;
}
info.GifFrames = gifFrames;
- info.AnimationLength = delay;
+ info.AnimationLength = length;
// Loop info is stored at byte 20737.
- info.LoopCount = BitConverter.ToInt16(image.GetPropertyItem(20737).Value, 0);
+ info.LoopCount = BitConverter.ToInt16(image.GetPropertyItem((int)ExifPropertyTag.LoopCount).Value, 0);
info.IsLooped = info.LoopCount != 1;
}
}
diff --git a/src/ImageProcessor/Imaging/Formats/GifEncoder.cs b/src/ImageProcessor/Imaging/Formats/GifEncoder.cs
index 612a453bf..662ad314c 100644
--- a/src/ImageProcessor/Imaging/Formats/GifEncoder.cs
+++ b/src/ImageProcessor/Imaging/Formats/GifEncoder.cs
@@ -193,13 +193,6 @@ namespace ImageProcessor.Imaging.Formats
}
#endregion
- #region Properties
- ///
- /// Gets or sets the frame delay.
- ///
- public TimeSpan FrameDelay { get; set; }
- #endregion
-
#region Public Methods and Operators
///
/// Adds a frame to the gif.
@@ -289,13 +282,18 @@ namespace ImageProcessor.Imaging.Formats
{
int count = this.repeatCount.GetValueOrDefault(0);
- // File Header
+ // File Header sinature and version.
this.WriteString(FileType);
this.WriteString(FileVersion);
+
+ // Write the logical screen descriptor.
this.WriteShort(this.width.GetValueOrDefault(w)); // Initial Logical Width
this.WriteShort(this.height.GetValueOrDefault(h)); // Initial Logical Height
+
+ // Read the global color table info.
sourceGif.Position = SourceGlobalColorInfoPosition;
- this.WriteByte(sourceGif.ReadByte()); // Global Color Table Info
+ this.WriteByte(sourceGif.ReadByte());
+
this.WriteByte(0); // Background Color Index
this.WriteByte(0); // Pixel aspect ratio
this.WriteColorTable(sourceGif);
@@ -387,6 +385,7 @@ namespace ImageProcessor.Imaging.Formats
///
private void WriteImageBlock(Stream sourceGif, bool includeColorTable, int x, int y, int h, int w)
{
+ // Local Image Descriptor
sourceGif.Position = SourceImageBlockPosition; // Locating the image block
byte[] header = new byte[SourceImageBlockHeaderLength];
sourceGif.Read(header, 0, header.Length);
@@ -435,6 +434,7 @@ namespace ImageProcessor.Imaging.Formats
///
private void WriteShort(int value)
{
+ // Leave only one significant byte.
this.inputStream.WriteByte(Convert.ToByte(value & 0xff));
this.inputStream.WriteByte(Convert.ToByte((value >> 8) & 0xff));
}
diff --git a/src/ImageProcessorConsole/Program.cs b/src/ImageProcessorConsole/Program.cs
index b08b9440b..248fe1d7f 100644
--- a/src/ImageProcessorConsole/Program.cs
+++ b/src/ImageProcessorConsole/Program.cs
@@ -1,6 +1,7 @@
// --------------------------------------------------------------------------------------------------------------------
//
-// Copyright James South
+// Copyright (c) James South.
+// Licensed under the Apache License, Version 2.0.
//
//
// The program.
@@ -58,7 +59,7 @@ namespace ImageProcessorConsole
// Load, resize, set the format and quality and save an image.
imageFactory.Load(inStream)
- .AutoRotate()
+ //.AutoRotate()
.Constrain(size)
//.Format(new WebPFormat())
//.Quality(5)