Browse Source

Strong type meta query + format singletons

af/merge-core
James Jackson-South 8 years ago
parent
commit
dc4ec30a14
  1. 8
      src/ImageSharp/Formats/Bmp/BmpConfigurationModule.cs
  2. 14
      src/ImageSharp/Formats/Bmp/BmpFormat.cs
  3. 2
      src/ImageSharp/Formats/Bmp/BmpImageFormatDetector.cs
  4. 15
      src/ImageSharp/Formats/Bmp/BmpMetaData.cs
  5. 2
      src/ImageSharp/Formats/Bmp/ImageExtensions.cs
  6. 9
      src/ImageSharp/Formats/Gif/GifConfigurationModule.cs
  7. 5
      src/ImageSharp/Formats/Gif/GifConstants.cs
  8. 6
      src/ImageSharp/Formats/Gif/GifDecoderCore.cs
  9. 6
      src/ImageSharp/Formats/Gif/GifEncoderCore.cs
  10. 14
      src/ImageSharp/Formats/Gif/GifFormat.cs
  11. 4
      src/ImageSharp/Formats/Gif/GifFrameMetaData.cs
  12. 2
      src/ImageSharp/Formats/Gif/GifImageFormatDetector.cs
  13. 4
      src/ImageSharp/Formats/Gif/GifMetaData.cs
  14. 49
      src/ImageSharp/Formats/Gif/GifMetaDataExtensions.cs
  15. 2
      src/ImageSharp/Formats/Gif/ImageExtensions.cs
  16. 38
      src/ImageSharp/Formats/ImageFormatBase{T}.cs
  17. 2
      src/ImageSharp/Formats/Jpeg/ImageExtensions.cs
  18. 9
      src/ImageSharp/Formats/Jpeg/JpegConfigurationModule.cs
  19. 14
      src/ImageSharp/Formats/Jpeg/JpegFormat.cs
  20. 2
      src/ImageSharp/Formats/Jpeg/JpegImageFormatDetector.cs
  21. 15
      src/ImageSharp/Formats/Jpeg/JpegMetaData.cs
  22. 2
      src/ImageSharp/Formats/Png/ImageExtensions.cs
  23. 4
      src/ImageSharp/Formats/Png/PngConfigurationModule.cs
  24. 14
      src/ImageSharp/Formats/Png/PngFormat.cs
  25. 2
      src/ImageSharp/Formats/Png/PngImageFormatDetector.cs
  26. 15
      src/ImageSharp/Formats/Png/PngMetaData.cs
  27. 37
      src/ImageSharp/ImageFormats.cs
  28. 13
      src/ImageSharp/MetaData/IImageFormatFrameMetaData.cs
  29. 13
      src/ImageSharp/MetaData/IImageFormatMetaData.cs
  30. 30
      src/ImageSharp/MetaData/ImageFrameMetaData.cs
  31. 30
      src/ImageSharp/MetaData/ImageMetaData.cs
  32. 13
      tests/ImageSharp.Tests/ConfigurationTests.cs
  33. 2
      tests/ImageSharp.Tests/Formats/GeneralFormatTests.cs
  34. 10
      tests/ImageSharp.Tests/Formats/Gif/GifEncoderTests.cs
  35. 4
      tests/ImageSharp.Tests/Formats/ImageFormatManagerTests.cs
  36. 4
      tests/ImageSharp.Tests/MetaData/ImageFrameMetaDataTests.cs
  37. 4
      tests/ImageSharp.Tests/TestUtilities/TestEnvironment.Formats.cs

8
src/ImageSharp/Formats/Bmp/BmpConfigurationModule.cs

@ -9,11 +9,11 @@ namespace SixLabors.ImageSharp.Formats.Bmp
public sealed class BmpConfigurationModule : IConfigurationModule
{
/// <inheritdoc/>
public void Configure(Configuration config)
public void Configure(Configuration configuration)
{
config.ImageFormatsManager.SetEncoder(ImageFormats.Bmp, new BmpEncoder());
config.ImageFormatsManager.SetDecoder(ImageFormats.Bmp, new BmpDecoder());
config.ImageFormatsManager.AddImageFormatDetector(new BmpImageFormatDetector());
configuration.ImageFormatsManager.SetEncoder(BmpFormat.Instance, new BmpEncoder());
configuration.ImageFormatsManager.SetDecoder(BmpFormat.Instance, new BmpDecoder());
configuration.ImageFormatsManager.AddImageFormatDetector(new BmpImageFormatDetector());
}
}
}

14
src/ImageSharp/Formats/Bmp/BmpFormat.cs

@ -8,18 +8,22 @@ namespace SixLabors.ImageSharp.Formats.Bmp
/// <summary>
/// Registers the image encoders, decoders and mime type detectors for the bmp format.
/// </summary>
internal sealed class BmpFormat : IImageFormat
internal sealed class BmpFormat : ImageFormatBase<BmpFormat>
{
private BmpFormat()
{
}
/// <inheritdoc/>
public string Name => "BMP";
public override string Name => "BMP";
/// <inheritdoc/>
public string DefaultMimeType => "image/bmp";
public override string DefaultMimeType => "image/bmp";
/// <inheritdoc/>
public IEnumerable<string> MimeTypes => BmpConstants.MimeTypes;
public override IEnumerable<string> MimeTypes => BmpConstants.MimeTypes;
/// <inheritdoc/>
public IEnumerable<string> FileExtensions => BmpConstants.FileExtensions;
public override IEnumerable<string> FileExtensions => BmpConstants.FileExtensions;
}
}

2
src/ImageSharp/Formats/Bmp/BmpImageFormatDetector.cs

@ -16,7 +16,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp
/// <inheritdoc/>
public IImageFormat DetectFormat(ReadOnlySpan<byte> header)
{
return this.IsSupportedFileFormat(header) ? ImageFormats.Bmp : null;
return this.IsSupportedFileFormat(header) ? BmpFormat.Instance : null;
}
private bool IsSupportedFileFormat(ReadOnlySpan<byte> header)

15
src/ImageSharp/Formats/Bmp/BmpMetaData.cs

@ -0,0 +1,15 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using SixLabors.ImageSharp.MetaData;
namespace SixLabors.ImageSharp.Formats.Bmp
{
/// <summary>
/// Provides Bmp specific metadata information for the image.
/// </summary>
public class BmpMetaData : IImageFormatMetaData
{
// TODO: Analyse what properties we would like to preserve.
}
}

2
src/ImageSharp/Formats/Bmp/ImageExtensions.cs

@ -34,6 +34,6 @@ namespace SixLabors.ImageSharp
/// <exception cref="System.ArgumentNullException">Thrown if the stream is null.</exception>
public static void SaveAsBmp<TPixel>(this Image<TPixel> source, Stream stream, BmpEncoder encoder)
where TPixel : struct, IPixel<TPixel>
=> source.Save(stream, encoder ?? source.GetConfiguration().ImageFormatsManager.FindEncoder(ImageFormats.Bmp));
=> source.Save(stream, encoder ?? source.GetConfiguration().ImageFormatsManager.FindEncoder(BmpFormat.Instance));
}
}

9
src/ImageSharp/Formats/Gif/GifConfigurationModule.cs

@ -9,12 +9,11 @@ namespace SixLabors.ImageSharp.Formats.Gif
public sealed class GifConfigurationModule : IConfigurationModule
{
/// <inheritdoc/>
public void Configure(Configuration config)
public void Configure(Configuration configuration)
{
config.ImageFormatsManager.SetEncoder(ImageFormats.Gif, new GifEncoder());
config.ImageFormatsManager.SetDecoder(ImageFormats.Gif, new GifDecoder());
config.ImageFormatsManager.AddImageFormatDetector(new GifImageFormatDetector());
configuration.ImageFormatsManager.SetEncoder(GifFormat.Instance, new GifEncoder());
configuration.ImageFormatsManager.SetDecoder(GifFormat.Instance, new GifDecoder());
configuration.ImageFormatsManager.AddImageFormatDetector(new GifImageFormatDetector());
}
}
}

5
src/ImageSharp/Formats/Gif/GifConstants.cs

@ -26,11 +26,6 @@ namespace SixLabors.ImageSharp.Formats.Gif
/// </summary>
internal static readonly byte[] MagicNumber = Encoding.UTF8.GetBytes(FileType + FileVersion);
/// <summary>
/// Gets the key used for storing and retriving metadata.
/// </summary>
public const string MetaDataKey = FileType;
/// <summary>
/// The extension block introducer <value>!</value>.
/// </summary>

6
src/ImageSharp/Formats/Gif/GifDecoderCore.cs

@ -164,7 +164,7 @@ namespace SixLabors.ImageSharp.Formats.Gif
this.globalColorTable?.Dispose();
}
image?.MetaData.AddOrUpdateGifMetaData(this.gifMetaData);
image?.MetaData.AddOrUpdateFormatMetaData(GifFormat.Instance, this.gifMetaData);
return image;
}
@ -224,7 +224,7 @@ namespace SixLabors.ImageSharp.Formats.Gif
this.globalColorTable?.Dispose();
}
this.metaData.AddOrUpdateGifMetaData(this.gifMetaData);
this.metaData.AddOrUpdateFormatMetaData(GifFormat.Instance, this.gifMetaData);
return new ImageInfo(
new PixelTypeInfo(this.logicalScreenDescriptor.BitsPerPixel),
this.logicalScreenDescriptor.Width,
@ -561,7 +561,7 @@ namespace SixLabors.ImageSharp.Formats.Gif
}
gifMeta.DisposalMethod = this.graphicsControlExtension.DisposalMethod;
meta.AddOrUpdateGifFrameMetaData(gifMeta);
meta.AddOrUpdateFormatMetaData(GifFormat.Instance, gifMeta);
}
/// <summary>

6
src/ImageSharp/Formats/Gif/GifEncoderCore.cs

@ -86,7 +86,7 @@ namespace SixLabors.ImageSharp.Formats.Gif
Guard.NotNull(image, nameof(image));
Guard.NotNull(stream, nameof(stream));
this.gifMetaData = image.MetaData.GetGifMetaData() ?? new GifMetaData();
this.gifMetaData = image.MetaData.GetOrAddFormatMetaData<GifMetaData>(GifFormat.Instance);
this.colorTableMode = this.colorTableMode ?? this.gifMetaData.ColorTableMode;
bool useGlobalTable = this.colorTableMode.Equals(GifColorTableMode.Global);
@ -143,7 +143,7 @@ namespace SixLabors.ImageSharp.Formats.Gif
for (int i = 0; i < image.Frames.Count; i++)
{
ImageFrame<TPixel> frame = image.Frames[i];
GifFrameMetaData frameMetaData = frame.MetaData.GetGifFrameMetaData() ?? new GifFrameMetaData();
GifFrameMetaData frameMetaData = frame.MetaData.GetOrAddFormatMetaData<GifFrameMetaData>(GifFormat.Instance);
this.WriteGraphicalControlExtension(frameMetaData, transparencyIndex, stream);
this.WriteImageDescriptor(frame, false, stream);
@ -169,7 +169,7 @@ namespace SixLabors.ImageSharp.Formats.Gif
GifFrameMetaData previousMeta = null;
foreach (ImageFrame<TPixel> frame in image.Frames)
{
GifFrameMetaData meta = frame.MetaData.GetGifFrameMetaData() ?? new GifFrameMetaData();
GifFrameMetaData meta = frame.MetaData.GetOrAddFormatMetaData<GifFrameMetaData>(GifFormat.Instance);
if (quantized is null)
{
// Allow each frame to be encoded at whatever color depth the frame designates if set.

14
src/ImageSharp/Formats/Gif/GifFormat.cs

@ -8,18 +8,22 @@ namespace SixLabors.ImageSharp.Formats.Gif
/// <summary>
/// Registers the image encoders, decoders and mime type detectors for the gif format.
/// </summary>
internal sealed class GifFormat : IImageFormat
internal sealed class GifFormat : ImageFormatBase<GifFormat>
{
private GifFormat()
{
}
/// <inheritdoc/>
public string Name => "GIF";
public override string Name => "GIF";
/// <inheritdoc/>
public string DefaultMimeType => "image/gif";
public override string DefaultMimeType => "image/gif";
/// <inheritdoc/>
public IEnumerable<string> MimeTypes => GifConstants.MimeTypes;
public override IEnumerable<string> MimeTypes => GifConstants.MimeTypes;
/// <inheritdoc/>
public IEnumerable<string> FileExtensions => GifConstants.FileExtensions;
public override IEnumerable<string> FileExtensions => GifConstants.FileExtensions;
}
}

4
src/ImageSharp/Formats/Gif/GifFrameMetaData.cs

@ -1,12 +1,14 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using SixLabors.ImageSharp.MetaData;
namespace SixLabors.ImageSharp.Formats.Gif
{
/// <summary>
/// Provides Gif specific metadata information for the image frame.
/// </summary>
public class GifFrameMetaData
public class GifFrameMetaData : IImageFormatFrameMetaData
{
/// <summary>
/// Gets or sets the length of the color table for paletted images.

2
src/ImageSharp/Formats/Gif/GifImageFormatDetector.cs

@ -16,7 +16,7 @@ namespace SixLabors.ImageSharp.Formats.Gif
/// <inheritdoc/>
public IImageFormat DetectFormat(ReadOnlySpan<byte> header)
{
return this.IsSupportedFileFormat(header) ? ImageFormats.Gif : null;
return this.IsSupportedFileFormat(header) ? GifFormat.Instance : null;
}
private bool IsSupportedFileFormat(ReadOnlySpan<byte> header)

4
src/ImageSharp/Formats/Gif/GifMetaData.cs

@ -1,12 +1,14 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using SixLabors.ImageSharp.MetaData;
namespace SixLabors.ImageSharp.Formats.Gif
{
/// <summary>
/// Provides Gif specific metadata information for the image.
/// </summary>
public class GifMetaData
public class GifMetaData : IImageFormatMetaData
{
/// <summary>
/// Gets or sets the number of times any animation is repeated.

49
src/ImageSharp/Formats/Gif/GifMetaDataExtensions.cs

@ -1,49 +0,0 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using SixLabors.ImageSharp.MetaData;
namespace SixLabors.ImageSharp.Formats.Gif
{
/// <summary>
/// Extension methods for storing meta data specific to Gif images.
/// </summary>
public static class GifMetaDataExtensions
{
/// <summary>
/// Adds or updates the Gif specific meta data to the image.
/// </summary>
/// <param name="meta">The image meta data.</param>
/// <param name="value">The gif meta data.</param>
public static void AddOrUpdateGifMetaData(this ImageMetaData meta, GifMetaData value) => meta.AddOrUpdateMetaData(GifConstants.MetaDataKey, value);
/// <summary>
/// Gets the Gif format specific meta data from the image.
/// </summary>
/// <param name="meta">The image meta data.</param>
/// <returns>The <see cref="GifMetaData"/> or null.</returns>
public static GifMetaData GetGifMetaData(this ImageMetaData meta)
{
meta.TryGetMetaData(GifConstants.MetaDataKey, out GifMetaData value);
return value;
}
/// <summary>
/// Adds or updates the Gif specific meta data to the image frame.
/// </summary>
/// <param name="meta">The image meta data.</param>
/// <param name="value">The gif meta data.</param>
public static void AddOrUpdateGifFrameMetaData(this ImageFrameMetaData meta, GifFrameMetaData value) => meta.AddOrUpdateMetaData(GifConstants.MetaDataKey, value);
/// <summary>
/// Gets the Gif format specific meta data from the image frame.
/// </summary>
/// <param name="meta">The image meta data.</param>
/// <returns>The <see cref="GifMetaData"/> or null.</returns>
public static GifFrameMetaData GetGifFrameMetaData(this ImageFrameMetaData meta)
{
meta.TryGetMetaData(GifConstants.MetaDataKey, out GifFrameMetaData value);
return value;
}
}
}

2
src/ImageSharp/Formats/Gif/ImageExtensions.cs

@ -34,6 +34,6 @@ namespace SixLabors.ImageSharp
/// <exception cref="System.ArgumentNullException">Thrown if the stream is null.</exception>
public static void SaveAsGif<TPixel>(this Image<TPixel> source, Stream stream, GifEncoder encoder)
where TPixel : struct, IPixel<TPixel>
=> source.Save(stream, encoder ?? source.GetConfiguration().ImageFormatsManager.FindEncoder(ImageFormats.Gif));
=> source.Save(stream, encoder ?? source.GetConfiguration().ImageFormatsManager.FindEncoder(GifFormat.Instance));
}
}

38
src/ImageSharp/Formats/ImageFormatBase{T}.cs

@ -0,0 +1,38 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System;
using System.Collections.Generic;
namespace SixLabors.ImageSharp.Formats
{
/// <summary>
/// The base class for all image formats.
/// Inheriting classes should implement the singleton pattern by creating a private constructor.
/// </summary>
/// <typeparam name="T">The type of image format.</typeparam>
public abstract class ImageFormatBase<T> : IImageFormat
where T : class, IImageFormat
{
private static readonly Lazy<T> Lazy = new Lazy<T>(CreateInstance);
/// <summary>
/// Gets the current instance.
/// </summary>
public static T Instance => Lazy.Value;
/// <inheritdoc/>
public abstract string Name { get; }
/// <inheritdoc/>
public abstract string DefaultMimeType { get; }
/// <inheritdoc/>
public abstract IEnumerable<string> MimeTypes { get; }
/// <inheritdoc/>
public abstract IEnumerable<string> FileExtensions { get; }
private static T CreateInstance() => (T)Activator.CreateInstance(typeof(T), true);
}
}

2
src/ImageSharp/Formats/Jpeg/ImageExtensions.cs

@ -34,6 +34,6 @@ namespace SixLabors.ImageSharp
/// <exception cref="System.ArgumentNullException">Thrown if the stream is null.</exception>
public static void SaveAsJpeg<TPixel>(this Image<TPixel> source, Stream stream, JpegEncoder encoder)
where TPixel : struct, IPixel<TPixel>
=> source.Save(stream, encoder ?? source.GetConfiguration().ImageFormatsManager.FindEncoder(ImageFormats.Jpeg));
=> source.Save(stream, encoder ?? source.GetConfiguration().ImageFormatsManager.FindEncoder(JpegFormat.Instance));
}
}

9
src/ImageSharp/Formats/Jpeg/JpegConfigurationModule.cs

@ -9,12 +9,11 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
public sealed class JpegConfigurationModule : IConfigurationModule
{
/// <inheritdoc/>
public void Configure(Configuration config)
public void Configure(Configuration configuration)
{
config.ImageFormatsManager.SetEncoder(ImageFormats.Jpeg, new JpegEncoder());
config.ImageFormatsManager.SetDecoder(ImageFormats.Jpeg, new JpegDecoder());
config.ImageFormatsManager.AddImageFormatDetector(new JpegImageFormatDetector());
configuration.ImageFormatsManager.SetEncoder(JpegFormat.Instance, new JpegEncoder());
configuration.ImageFormatsManager.SetDecoder(JpegFormat.Instance, new JpegDecoder());
configuration.ImageFormatsManager.AddImageFormatDetector(new JpegImageFormatDetector());
}
}
}

14
src/ImageSharp/Formats/Jpeg/JpegFormat.cs

@ -8,18 +8,22 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
/// <summary>
/// Registers the image encoders, decoders and mime type detectors for the jpeg format.
/// </summary>
internal sealed class JpegFormat : IImageFormat
internal sealed class JpegFormat : ImageFormatBase<JpegFormat>
{
private JpegFormat()
{
}
/// <inheritdoc/>
public string Name => "JPEG";
public override string Name => "JPEG";
/// <inheritdoc/>
public string DefaultMimeType => "image/jpeg";
public override string DefaultMimeType => "image/jpeg";
/// <inheritdoc/>
public IEnumerable<string> MimeTypes => JpegConstants.MimeTypes;
public override IEnumerable<string> MimeTypes => JpegConstants.MimeTypes;
/// <inheritdoc/>
public IEnumerable<string> FileExtensions => JpegConstants.FileExtensions;
public override IEnumerable<string> FileExtensions => JpegConstants.FileExtensions;
}
}

2
src/ImageSharp/Formats/Jpeg/JpegImageFormatDetector.cs

@ -16,7 +16,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
/// <inheritdoc/>
public IImageFormat DetectFormat(ReadOnlySpan<byte> header)
{
return this.IsSupportedFileFormat(header) ? ImageFormats.Jpeg : null;
return this.IsSupportedFileFormat(header) ? JpegFormat.Instance : null;
}
private bool IsSupportedFileFormat(ReadOnlySpan<byte> header)

15
src/ImageSharp/Formats/Jpeg/JpegMetaData.cs

@ -0,0 +1,15 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using SixLabors.ImageSharp.MetaData;
namespace SixLabors.ImageSharp.Formats.Jpeg
{
/// <summary>
/// Provides Jpeg specific metadata information for the image.
/// </summary>
public class JpegMetaData : IImageFormatMetaData
{
// TODO: Analyse what properties we would like to preserve.
}
}

2
src/ImageSharp/Formats/Png/ImageExtensions.cs

@ -35,6 +35,6 @@ namespace SixLabors.ImageSharp
/// <exception cref="System.ArgumentNullException">Thrown if the stream is null.</exception>
public static void SaveAsPng<TPixel>(this Image<TPixel> source, Stream stream, PngEncoder encoder)
where TPixel : struct, IPixel<TPixel>
=> source.Save(stream, encoder ?? source.GetConfiguration().ImageFormatsManager.FindEncoder(ImageFormats.Png));
=> source.Save(stream, encoder ?? source.GetConfiguration().ImageFormatsManager.FindEncoder(PngFormat.Instance));
}
}

4
src/ImageSharp/Formats/Png/PngConfigurationModule.cs

@ -11,8 +11,8 @@ namespace SixLabors.ImageSharp.Formats.Png
/// <inheritdoc/>
public void Configure(Configuration configuration)
{
configuration.ImageFormatsManager.SetEncoder(ImageFormats.Png, new PngEncoder());
configuration.ImageFormatsManager.SetDecoder(ImageFormats.Png, new PngDecoder());
configuration.ImageFormatsManager.SetEncoder(PngFormat.Instance, new PngEncoder());
configuration.ImageFormatsManager.SetDecoder(PngFormat.Instance, new PngDecoder());
configuration.ImageFormatsManager.AddImageFormatDetector(new PngImageFormatDetector());
}
}

14
src/ImageSharp/Formats/Png/PngFormat.cs

@ -8,18 +8,22 @@ namespace SixLabors.ImageSharp.Formats.Png
/// <summary>
/// Registers the image encoders, decoders and mime type detectors for the png format.
/// </summary>
internal sealed class PngFormat : IImageFormat
internal sealed class PngFormat : ImageFormatBase<PngFormat>
{
private PngFormat()
{
}
/// <inheritdoc/>
public string Name => "PNG";
public override string Name => "PNG";
/// <inheritdoc/>
public string DefaultMimeType => "image/png";
public override string DefaultMimeType => "image/png";
/// <inheritdoc/>
public IEnumerable<string> MimeTypes => PngConstants.MimeTypes;
public override IEnumerable<string> MimeTypes => PngConstants.MimeTypes;
/// <inheritdoc/>
public IEnumerable<string> FileExtensions => PngConstants.FileExtensions;
public override IEnumerable<string> FileExtensions => PngConstants.FileExtensions;
}
}

2
src/ImageSharp/Formats/Png/PngImageFormatDetector.cs

@ -17,7 +17,7 @@ namespace SixLabors.ImageSharp.Formats.Png
/// <inheritdoc/>
public IImageFormat DetectFormat(ReadOnlySpan<byte> header)
{
return this.IsSupportedFileFormat(header) ? ImageFormats.Png : null;
return this.IsSupportedFileFormat(header) ? PngFormat.Instance : null;
}
private bool IsSupportedFileFormat(ReadOnlySpan<byte> header)

15
src/ImageSharp/Formats/Png/PngMetaData.cs

@ -0,0 +1,15 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using SixLabors.ImageSharp.MetaData;
namespace SixLabors.ImageSharp.Formats.Png
{
/// <summary>
/// Provides Png specific metadata information for the image.
/// </summary>
public class PngMetaData : IImageFormatMetaData
{
// TODO: Analyse what properties we would like to preserve.
}
}

37
src/ImageSharp/ImageFormats.cs

@ -1,37 +0,0 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using SixLabors.ImageSharp.Formats;
using SixLabors.ImageSharp.Formats.Bmp;
using SixLabors.ImageSharp.Formats.Gif;
using SixLabors.ImageSharp.Formats.Jpeg;
using SixLabors.ImageSharp.Formats.Png;
namespace SixLabors.ImageSharp
{
/// <summary>
/// The static collection of all the default image formats
/// </summary>
public static class ImageFormats
{
/// <summary>
/// The format details for the jpegs.
/// </summary>
public static readonly IImageFormat Jpeg = new JpegFormat();
/// <summary>
/// The format details for the pngs.
/// </summary>
public static readonly IImageFormat Png = new PngFormat();
/// <summary>
/// The format details for the gifs.
/// </summary>
public static readonly IImageFormat Gif = new GifFormat();
/// <summary>
/// The format details for the bitmaps.
/// </summary>
public static readonly IImageFormat Bmp = new BmpFormat();
}
}

13
src/ImageSharp/MetaData/IImageFormatFrameMetaData.cs

@ -0,0 +1,13 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
namespace SixLabors.ImageSharp.MetaData
{
/// <summary>
/// Encapsulates the format specific metadata of an image frame.
/// This interface exists to allow type saftey and avoid the performance overhead of parsing attributes.
/// </summary>
public interface IImageFormatFrameMetaData
{
}
}

13
src/ImageSharp/MetaData/IImageFormatMetaData.cs

@ -0,0 +1,13 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
namespace SixLabors.ImageSharp.MetaData
{
/// <summary>
/// Encapsulates the format specific metadata of an image.
/// This interface exists to allow type saftey and avoid the performance overhead of parsing attributes.
/// </summary>
public interface IImageFormatMetaData
{
}
}

30
src/ImageSharp/MetaData/ImageFrameMetaData.cs

@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
using SixLabors.ImageSharp.Formats;
namespace SixLabors.ImageSharp.MetaData
{
@ -11,7 +12,7 @@ namespace SixLabors.ImageSharp.MetaData
/// </summary>
public sealed class ImageFrameMetaData
{
private readonly Dictionary<string, object> metaData = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
private readonly Dictionary<IImageFormat, IImageFormatFrameMetaData> metaData = new Dictionary<IImageFormat, IImageFormatFrameMetaData>();
/// <summary>
/// Initializes a new instance of the <see cref="ImageFrameMetaData"/> class.
@ -31,7 +32,7 @@ namespace SixLabors.ImageSharp.MetaData
{
DebugGuard.NotNull(other, nameof(other));
foreach (KeyValuePair<string, object> meta in other.metaData)
foreach (KeyValuePair<IImageFormat, IImageFormatFrameMetaData> meta in other.metaData)
{
this.metaData.Add(meta.Key, meta.Value);
}
@ -51,7 +52,7 @@ namespace SixLabors.ImageSharp.MetaData
/// <exception cref="ArgumentNullException">key is null.</exception>
/// <exception cref="ArgumentNullException">value is null.</exception>
/// <exception cref="ArgumentException">An element with the same key already exists in the <see cref="ImageMetaData"/>.</exception>
public void AddOrUpdateMetaData(string key, object value)
public void AddOrUpdateFormatMetaData(IImageFormat key, IImageFormatFrameMetaData value)
{
// Don't think this needs to be threadsafe.
Guard.NotNull(value, nameof(value));
@ -61,27 +62,22 @@ namespace SixLabors.ImageSharp.MetaData
/// <summary>
/// Gets the metadata value associated with the specified key.
/// </summary>
/// <typeparam name="T">The type of value.</typeparam>
/// <typeparam name="T">The type of metadata.</typeparam>
/// <param name="key">The key of the value to get.</param>
/// <param name="value">
/// When this method returns, contains the metadata value associated with the specified key,
/// if the key is found; otherwise, the default value for the type of the value parameter.
/// This parameter is passed uninitialized.
/// </param>
/// <returns>
/// true if the <see cref="ImageMetaData"/> contains an element with
/// the specified key; otherwise, false.
/// The <typeparamref name="T"/>.
/// </returns>
public bool TryGetMetaData<T>(string key, out T value)
public T GetOrAddFormatMetaData<T>(IImageFormat key)
where T : IImageFormatFrameMetaData, new()
{
if (this.metaData.TryGetValue(key, out object meta))
if (this.metaData.TryGetValue(key, out IImageFormatFrameMetaData meta))
{
value = (T)meta;
return true;
return (T)meta;
}
value = default;
return false;
var newMeta = new T();
this.AddOrUpdateFormatMetaData(key, newMeta);
return newMeta;
}
}
}

30
src/ImageSharp/MetaData/ImageMetaData.cs

@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
using SixLabors.ImageSharp.Formats;
using SixLabors.ImageSharp.MetaData.Profiles.Exif;
using SixLabors.ImageSharp.MetaData.Profiles.Icc;
@ -25,7 +26,7 @@ namespace SixLabors.ImageSharp.MetaData
/// </summary>
public const double DefaultVerticalResolution = 96;
private readonly Dictionary<string, object> metaData = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
private readonly Dictionary<IImageFormat, IImageFormatMetaData> metaData = new Dictionary<IImageFormat, IImageFormatMetaData>();
private double horizontalResolution;
private double verticalResolution;
@ -51,7 +52,7 @@ namespace SixLabors.ImageSharp.MetaData
this.VerticalResolution = other.VerticalResolution;
this.ResolutionUnits = other.ResolutionUnits;
foreach (KeyValuePair<string, object> meta in other.metaData)
foreach (KeyValuePair<IImageFormat, IImageFormatMetaData> meta in other.metaData)
{
this.metaData.Add(meta.Key, meta.Value);
}
@ -138,7 +139,7 @@ namespace SixLabors.ImageSharp.MetaData
/// <exception cref="ArgumentNullException">key is null.</exception>
/// <exception cref="ArgumentNullException">value is null.</exception>
/// <exception cref="ArgumentException">An element with the same key already exists in the <see cref="ImageMetaData"/>.</exception>
public void AddOrUpdateMetaData(string key, object value)
public void AddOrUpdateFormatMetaData(IImageFormat key, IImageFormatMetaData value)
{
// Don't think this needs to be threadsafe.
Guard.NotNull(value, nameof(value));
@ -148,27 +149,22 @@ namespace SixLabors.ImageSharp.MetaData
/// <summary>
/// Gets the metadata value associated with the specified key.
/// </summary>
/// <typeparam name="T">The type of value.</typeparam>
/// <typeparam name="T">The type of metadata.</typeparam>
/// <param name="key">The key of the value to get.</param>
/// <param name="value">
/// When this method returns, contains the metadata value associated with the specified key,
/// if the key is found; otherwise, the default value for the type of the value parameter.
/// This parameter is passed uninitialized.
/// </param>
/// <returns>
/// true if the <see cref="ImageMetaData"/> contains an element with
/// the specified key; otherwise, false.
/// The <typeparamref name="T"/>.
/// </returns>
public bool TryGetMetaData<T>(string key, out T value)
public T GetOrAddFormatMetaData<T>(IImageFormat key)
where T : IImageFormatMetaData, new()
{
if (this.metaData.TryGetValue(key, out object meta))
if (this.metaData.TryGetValue(key, out IImageFormatMetaData meta))
{
value = (T)meta;
return true;
return (T)meta;
}
value = default;
return false;
var newMeta = new T();
this.AddOrUpdateFormatMetaData(key, newMeta);
return newMeta;
}
/// <summary>

13
tests/ImageSharp.Tests/ConfigurationTests.cs

@ -4,6 +4,7 @@
using System;
using System.Linq;
using Moq;
using SixLabors.ImageSharp.Formats.Bmp;
using SixLabors.ImageSharp.IO;
using Xunit;
// ReSharper disable InconsistentNaming
@ -37,19 +38,13 @@ namespace SixLabors.ImageSharp.Tests
/// Test that the default configuration is not null.
/// </summary>
[Fact]
public void TestDefaultConfigurationIsNotNull()
{
Assert.True(Configuration.Default != null);
}
public void TestDefaultConfigurationIsNotNull() => Assert.True(Configuration.Default != null);
/// <summary>
/// Test that the default configuration read origin options is set to begin.
/// </summary>
[Fact]
public void TestDefaultConfigurationReadOriginIsCurrent()
{
Assert.True(Configuration.Default.ReadOrigin == ReadOrigin.Current);
}
public void TestDefaultConfigurationReadOriginIsCurrent() => Assert.True(Configuration.Default.ReadOrigin == ReadOrigin.Current);
/// <summary>
/// Test that the default configuration parallel options max degrees of parallelism matches the
@ -101,7 +96,7 @@ namespace SixLabors.ImageSharp.Tests
Assert.Equal(count, config.ImageFormats.Count());
config.ImageFormatsManager.AddImageFormat(ImageFormats.Bmp);
config.ImageFormatsManager.AddImageFormat(BmpFormat.Instance);
Assert.Equal(count, config.ImageFormats.Count());
}

2
tests/ImageSharp.Tests/Formats/GeneralFormatTests.cs

@ -44,7 +44,7 @@ namespace SixLabors.ImageSharp.Tests
using (Image<Rgba32> image = file.CreateImage())
{
string filename = path + "/" + file.FileNameWithoutExtension + ".txt";
File.WriteAllText(filename, image.ToBase64String(ImageFormats.Png));
File.WriteAllText(filename, image.ToBase64String(PngFormat.Instance));
}
}
}

10
tests/ImageSharp.Tests/Formats/Gif/GifEncoderTests.cs

@ -189,8 +189,8 @@ namespace SixLabors.ImageSharp.Tests.Formats.Gif
inStream.Position = 0;
var image = Image.Load(inStream);
GifMetaData metaData = image.MetaData.GetGifMetaData();
GifFrameMetaData frameMetaData = image.Frames.RootFrame.MetaData.GetGifFrameMetaData();
GifMetaData metaData = image.MetaData.GetOrAddFormatMetaData<GifMetaData>(GifFormat.Instance);
GifFrameMetaData frameMetaData = image.Frames.RootFrame.MetaData.GetOrAddFormatMetaData<GifFrameMetaData>(GifFormat.Instance);
GifColorTableMode colorMode = metaData.ColorTableMode;
var encoder = new GifEncoder()
{
@ -204,7 +204,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Gif
outStream.Position = 0;
var clone = Image.Load(outStream);
GifMetaData cloneMetaData = clone.MetaData.GetGifMetaData();
GifMetaData cloneMetaData = clone.MetaData.GetOrAddFormatMetaData<GifMetaData>(GifFormat.Instance);
Assert.Equal(metaData.ColorTableMode, cloneMetaData.ColorTableMode);
// Gifiddle and Cyotek GifInfo say this image has 64 colors.
@ -212,8 +212,8 @@ namespace SixLabors.ImageSharp.Tests.Formats.Gif
for (int i = 0; i < image.Frames.Count; i++)
{
GifFrameMetaData ifm = image.Frames[i].MetaData.GetGifFrameMetaData();
GifFrameMetaData cifm = clone.Frames[i].MetaData.GetGifFrameMetaData();
GifFrameMetaData ifm = image.Frames[i].MetaData.GetOrAddFormatMetaData<GifFrameMetaData>(GifFormat.Instance);
GifFrameMetaData cifm = clone.Frames[i].MetaData.GetOrAddFormatMetaData<GifFrameMetaData>(GifFormat.Instance);
Assert.Equal(ifm.ColorTableLength, cifm.ColorTableLength);
Assert.Equal(ifm.FrameDelay, cifm.FrameDelay);

4
tests/ImageSharp.Tests/Formats/ImageFormatManagerTests.cs

@ -61,7 +61,7 @@ namespace SixLabors.ImageSharp.Tests
});
Assert.Throws<ArgumentNullException>(() =>
{
this.DefaultFormatsManager.SetEncoder(ImageFormats.Bmp, null);
this.DefaultFormatsManager.SetEncoder(BmpFormat.Instance, null);
});
Assert.Throws<ArgumentNullException>(() =>
{
@ -78,7 +78,7 @@ namespace SixLabors.ImageSharp.Tests
});
Assert.Throws<ArgumentNullException>(() =>
{
this.DefaultFormatsManager.SetDecoder(ImageFormats.Bmp, null);
this.DefaultFormatsManager.SetDecoder(BmpFormat.Instance, null);
});
Assert.Throws<ArgumentNullException>(() =>
{

4
tests/ImageSharp.Tests/MetaData/ImageFrameMetaDataTests.cs

@ -27,10 +27,10 @@ namespace SixLabors.ImageSharp.Tests
};
var metaData = new ImageFrameMetaData();
metaData.AddOrUpdateGifFrameMetaData(gifFrameMetaData);
metaData.AddOrUpdateFormatMetaData(GifFormat.Instance, gifFrameMetaData);
var clone = new ImageFrameMetaData(metaData);
GifFrameMetaData cloneGifFrameMetaData = clone.GetGifFrameMetaData();
GifFrameMetaData cloneGifFrameMetaData = clone.GetOrAddFormatMetaData<GifFrameMetaData>(GifFormat.Instance);
Assert.Equal(frameDelay, cloneGifFrameMetaData.FrameDelay);
Assert.Equal(colorTableLength, cloneGifFrameMetaData.ColorTableLength);

4
tests/ImageSharp.Tests/TestUtilities/TestEnvironment.Formats.cs

@ -62,13 +62,13 @@ namespace SixLabors.ImageSharp.Tests
IImageEncoder bmpEncoder = IsWindows ? (IImageEncoder)SystemDrawingReferenceEncoder.Bmp : new BmpEncoder();
cfg.ConfigureCodecs(
ImageFormats.Png,
PngFormat.Instance,
MagickReferenceDecoder.Instance,
pngEncoder,
new PngImageFormatDetector());
cfg.ConfigureCodecs(
ImageFormats.Bmp,
BmpFormat.Instance,
SystemDrawingReferenceDecoder.Instance,
bmpEncoder,
new BmpImageFormatDetector());

Loading…
Cancel
Save