Browse Source

Much better type safety.

pull/693/head
James Jackson-South 8 years ago
parent
commit
25e5d48dca
  1. 18
      src/ImageSharp/Formats/Bmp/BmpFormat.cs
  2. 4
      src/ImageSharp/Formats/Bmp/BmpMetaData.cs
  3. 4
      src/ImageSharp/Formats/Gif/GifEncoderCore.cs
  4. 21
      src/ImageSharp/Formats/Gif/GifFormat.cs
  5. 4
      src/ImageSharp/Formats/Gif/GifFrameMetaData.cs
  6. 4
      src/ImageSharp/Formats/Gif/GifMetaData.cs
  7. 32
      src/ImageSharp/Formats/IImageFormat.cs
  8. 38
      src/ImageSharp/Formats/ImageFormatBase{T}.cs
  9. 18
      src/ImageSharp/Formats/Jpeg/JpegFormat.cs
  10. 4
      src/ImageSharp/Formats/Jpeg/JpegMetaData.cs
  11. 18
      src/ImageSharp/Formats/Png/PngFormat.cs
  12. 4
      src/ImageSharp/Formats/Png/PngMetaData.cs
  13. 13
      src/ImageSharp/MetaData/IImageFormatFrameMetaData.cs
  14. 13
      src/ImageSharp/MetaData/IImageFormatMetaData.cs
  15. 26
      src/ImageSharp/MetaData/ImageFrameMetaData.cs
  16. 22
      src/ImageSharp/MetaData/ImageMetaData.cs
  17. 8
      tests/ImageSharp.Tests/Formats/Gif/GifEncoderTests.cs
  18. 2
      tests/ImageSharp.Tests/MetaData/ImageFrameMetaDataTests.cs

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

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

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

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

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

@ -143,7 +143,7 @@ namespace SixLabors.ImageSharp.Formats.Gif
for (int i = 0; i < image.Frames.Count; i++) for (int i = 0; i < image.Frames.Count; i++)
{ {
ImageFrame<TPixel> frame = image.Frames[i]; ImageFrame<TPixel> frame = image.Frames[i];
GifFrameMetaData frameMetaData = frame.MetaData.GetOrAddFormatMetaData<GifFrameMetaData>(GifFormat.Instance); GifFrameMetaData frameMetaData = frame.MetaData.GetOrAddFormatMetaData(GifFormat.Instance);
this.WriteGraphicalControlExtension(frameMetaData, transparencyIndex, stream); this.WriteGraphicalControlExtension(frameMetaData, transparencyIndex, stream);
this.WriteImageDescriptor(frame, false, stream); this.WriteImageDescriptor(frame, false, stream);
@ -169,7 +169,7 @@ namespace SixLabors.ImageSharp.Formats.Gif
GifFrameMetaData previousMeta = null; GifFrameMetaData previousMeta = null;
foreach (ImageFrame<TPixel> frame in image.Frames) foreach (ImageFrame<TPixel> frame in image.Frames)
{ {
GifFrameMetaData meta = frame.MetaData.GetOrAddFormatMetaData<GifFrameMetaData>(GifFormat.Instance); GifFrameMetaData meta = frame.MetaData.GetOrAddFormatMetaData(GifFormat.Instance);
if (quantized is null) if (quantized is null)
{ {
// Allow each frame to be encoded at whatever color depth the frame designates if set. // Allow each frame to be encoded at whatever color depth the frame designates if set.

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

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

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

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

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

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

32
src/ImageSharp/Formats/IImageFormat.cs

@ -6,7 +6,37 @@ using System.Collections.Generic;
namespace SixLabors.ImageSharp.Formats namespace SixLabors.ImageSharp.Formats
{ {
/// <summary> /// <summary>
/// Describes an image format. /// Defines the contract for an image format containing metadata with multiple frames.
/// </summary>
/// <typeparam name="TFormatMetaData">The type of format metadata.</typeparam>
/// <typeparam name="TFormatFrameMetaData">The type of format frame metadata.</typeparam>
public interface IImageFormat<TFormatMetaData, TFormatFrameMetaData> : IImageFormat<TFormatMetaData>
where TFormatMetaData : class
where TFormatFrameMetaData : class
{
/// <summary>
/// Creates a default instance of the format frame metadata.
/// </summary>
/// <returns>The <typeparamref name="TFormatFrameMetaData"/>.</returns>
TFormatFrameMetaData CreateDefaultFormatFrameMetaData();
}
/// <summary>
/// Defines the contract for an image format containing metadata.
/// </summary>
/// <typeparam name="TFormatMetaData">The type of format metadata.</typeparam>
public interface IImageFormat<TFormatMetaData> : IImageFormat
where TFormatMetaData : class
{
/// <summary>
/// Creates a default instance of the format metadata.
/// </summary>
/// <returns>The <typeparamref name="TFormatMetaData"/>.</returns>
TFormatMetaData CreateDefaultFormatMetaData();
}
/// <summary>
/// Defines the contract for an image format.
/// </summary> /// </summary>
public interface IImageFormat public interface IImageFormat
{ {

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

@ -1,38 +0,0 @@
// 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);
}
}

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

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

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

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

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

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

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

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

13
src/ImageSharp/MetaData/IImageFormatFrameMetaData.cs

@ -1,13 +0,0 @@
// 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

@ -1,13 +0,0 @@
// 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
{
}
}

26
src/ImageSharp/MetaData/ImageFrameMetaData.cs

@ -12,7 +12,7 @@ namespace SixLabors.ImageSharp.MetaData
/// </summary> /// </summary>
public sealed class ImageFrameMetaData public sealed class ImageFrameMetaData
{ {
private readonly Dictionary<IImageFormat, IImageFormatFrameMetaData> metaData = new Dictionary<IImageFormat, IImageFormatFrameMetaData>(); private readonly Dictionary<IImageFormat, object> metaData = new Dictionary<IImageFormat, object>();
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="ImageFrameMetaData"/> class. /// Initializes a new instance of the <see cref="ImageFrameMetaData"/> class.
@ -32,7 +32,7 @@ namespace SixLabors.ImageSharp.MetaData
{ {
DebugGuard.NotNull(other, nameof(other)); DebugGuard.NotNull(other, nameof(other));
foreach (KeyValuePair<IImageFormat, IImageFormatFrameMetaData> meta in other.metaData) foreach (KeyValuePair<IImageFormat, object> meta in other.metaData)
{ {
this.metaData.Add(meta.Key, meta.Value); this.metaData.Add(meta.Key, meta.Value);
} }
@ -47,12 +47,16 @@ namespace SixLabors.ImageSharp.MetaData
/// <summary> /// <summary>
/// Adds or updates the specified key and value to the <see cref="ImageMetaData"/>. /// Adds or updates the specified key and value to the <see cref="ImageMetaData"/>.
/// </summary> /// </summary>
/// <typeparam name="TFormatMetaData">The type of format metadata.</typeparam>
/// <typeparam name="TFormatFrameMetaData">The type of format frame metadata.</typeparam>
/// <param name="key">The key of the metadata to add.</param> /// <param name="key">The key of the metadata to add.</param>
/// <param name="value">The value of the element to add.</param> /// <param name="value">The value of the element to add.</param>
/// <exception cref="ArgumentNullException">key is null.</exception> /// <exception cref="ArgumentNullException">key is null.</exception>
/// <exception cref="ArgumentNullException">value 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> /// <exception cref="ArgumentException">An element with the same key already exists in the <see cref="ImageMetaData"/>.</exception>
public void AddOrUpdateFormatMetaData(IImageFormat key, IImageFormatFrameMetaData value) public void AddOrUpdateFormatMetaData<TFormatMetaData, TFormatFrameMetaData>(IImageFormat<TFormatMetaData, TFormatFrameMetaData> key, TFormatFrameMetaData value)
where TFormatMetaData : class
where TFormatFrameMetaData : class
{ {
// Don't think this needs to be threadsafe. // Don't think this needs to be threadsafe.
Guard.NotNull(value, nameof(value)); Guard.NotNull(value, nameof(value));
@ -62,20 +66,22 @@ namespace SixLabors.ImageSharp.MetaData
/// <summary> /// <summary>
/// Gets the metadata value associated with the specified key. /// Gets the metadata value associated with the specified key.
/// </summary> /// </summary>
/// <typeparam name="T">The type of metadata.</typeparam> /// <typeparam name="TFormatMetaData">The type of format metadata.</typeparam>
/// <typeparam name="TFormatFrameMetaData">The type of format frame metadata.</typeparam>
/// <param name="key">The key of the value to get.</param> /// <param name="key">The key of the value to get.</param>
/// <returns> /// <returns>
/// The <typeparamref name="T"/>. /// The <typeparamref name="TFormatFrameMetaData"/>.
/// </returns> /// </returns>
public T GetOrAddFormatMetaData<T>(IImageFormat key) public TFormatFrameMetaData GetOrAddFormatMetaData<TFormatMetaData, TFormatFrameMetaData>(IImageFormat<TFormatMetaData, TFormatFrameMetaData> key)
where T : IImageFormatFrameMetaData, new() where TFormatMetaData : class
where TFormatFrameMetaData : class
{ {
if (this.metaData.TryGetValue(key, out IImageFormatFrameMetaData meta)) if (this.metaData.TryGetValue(key, out object meta))
{ {
return (T)meta; return (TFormatFrameMetaData)meta;
} }
var newMeta = new T(); TFormatFrameMetaData newMeta = key.CreateDefaultFormatFrameMetaData();
this.AddOrUpdateFormatMetaData(key, newMeta); this.AddOrUpdateFormatMetaData(key, newMeta);
return newMeta; return newMeta;
} }

22
src/ImageSharp/MetaData/ImageMetaData.cs

@ -26,7 +26,7 @@ namespace SixLabors.ImageSharp.MetaData
/// </summary> /// </summary>
public const double DefaultVerticalResolution = 96; public const double DefaultVerticalResolution = 96;
private readonly Dictionary<IImageFormat, IImageFormatMetaData> metaData = new Dictionary<IImageFormat, IImageFormatMetaData>(); private readonly Dictionary<IImageFormat, object> metaData = new Dictionary<IImageFormat, object>();
private double horizontalResolution; private double horizontalResolution;
private double verticalResolution; private double verticalResolution;
@ -52,7 +52,7 @@ namespace SixLabors.ImageSharp.MetaData
this.VerticalResolution = other.VerticalResolution; this.VerticalResolution = other.VerticalResolution;
this.ResolutionUnits = other.ResolutionUnits; this.ResolutionUnits = other.ResolutionUnits;
foreach (KeyValuePair<IImageFormat, IImageFormatMetaData> meta in other.metaData) foreach (KeyValuePair<IImageFormat, object> meta in other.metaData)
{ {
this.metaData.Add(meta.Key, meta.Value); this.metaData.Add(meta.Key, meta.Value);
} }
@ -134,12 +134,14 @@ namespace SixLabors.ImageSharp.MetaData
/// <summary> /// <summary>
/// Adds or updates the specified key and value to the <see cref="ImageMetaData"/>. /// Adds or updates the specified key and value to the <see cref="ImageMetaData"/>.
/// </summary> /// </summary>
/// <typeparam name="TFormatMetaData">The type of format metadata.</typeparam>
/// <param name="key">The key of the metadata to add.</param> /// <param name="key">The key of the metadata to add.</param>
/// <param name="value">The value of the element to add.</param> /// <param name="value">The value of the element to add.</param>
/// <exception cref="ArgumentNullException">key is null.</exception> /// <exception cref="ArgumentNullException">key is null.</exception>
/// <exception cref="ArgumentNullException">value 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> /// <exception cref="ArgumentException">An element with the same key already exists in the <see cref="ImageMetaData"/>.</exception>
public void AddOrUpdateFormatMetaData(IImageFormat key, IImageFormatMetaData value) public void AddOrUpdateFormatMetaData<TFormatMetaData>(IImageFormat<TFormatMetaData> key, TFormatMetaData value)
where TFormatMetaData : class
{ {
// Don't think this needs to be threadsafe. // Don't think this needs to be threadsafe.
Guard.NotNull(value, nameof(value)); Guard.NotNull(value, nameof(value));
@ -149,20 +151,20 @@ namespace SixLabors.ImageSharp.MetaData
/// <summary> /// <summary>
/// Gets the metadata value associated with the specified key. /// Gets the metadata value associated with the specified key.
/// </summary> /// </summary>
/// <typeparam name="T">The type of metadata.</typeparam> /// <typeparam name="TFormatMetaData">The type of metadata.</typeparam>
/// <param name="key">The key of the value to get.</param> /// <param name="key">The key of the value to get.</param>
/// <returns> /// <returns>
/// The <typeparamref name="T"/>. /// The <typeparamref name="TFormatMetaData"/>.
/// </returns> /// </returns>
public T GetOrAddFormatMetaData<T>(IImageFormat key) public TFormatMetaData GetOrAddFormatMetaData<TFormatMetaData>(IImageFormat<TFormatMetaData> key)
where T : IImageFormatMetaData, new() where TFormatMetaData : class
{ {
if (this.metaData.TryGetValue(key, out IImageFormatMetaData meta)) if (this.metaData.TryGetValue(key, out object meta))
{ {
return (T)meta; return (TFormatMetaData)meta;
} }
var newMeta = new T(); TFormatMetaData newMeta = key.CreateDefaultFormatMetaData();
this.AddOrUpdateFormatMetaData(key, newMeta); this.AddOrUpdateFormatMetaData(key, newMeta);
return newMeta; return newMeta;
} }

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

@ -189,8 +189,8 @@ namespace SixLabors.ImageSharp.Tests.Formats.Gif
inStream.Position = 0; inStream.Position = 0;
var image = Image.Load(inStream); var image = Image.Load(inStream);
GifMetaData metaData = image.MetaData.GetOrAddFormatMetaData<GifMetaData>(GifFormat.Instance); GifMetaData metaData = image.MetaData.GetOrAddFormatMetaData(GifFormat.Instance);
GifFrameMetaData frameMetaData = image.Frames.RootFrame.MetaData.GetOrAddFormatMetaData<GifFrameMetaData>(GifFormat.Instance); GifFrameMetaData frameMetaData = image.Frames.RootFrame.MetaData.GetOrAddFormatMetaData(GifFormat.Instance);
GifColorTableMode colorMode = metaData.ColorTableMode; GifColorTableMode colorMode = metaData.ColorTableMode;
var encoder = new GifEncoder() var encoder = new GifEncoder()
{ {
@ -212,8 +212,8 @@ namespace SixLabors.ImageSharp.Tests.Formats.Gif
for (int i = 0; i < image.Frames.Count; i++) for (int i = 0; i < image.Frames.Count; i++)
{ {
GifFrameMetaData ifm = image.Frames[i].MetaData.GetOrAddFormatMetaData<GifFrameMetaData>(GifFormat.Instance); GifFrameMetaData ifm = image.Frames[i].MetaData.GetOrAddFormatMetaData(GifFormat.Instance);
GifFrameMetaData cifm = clone.Frames[i].MetaData.GetOrAddFormatMetaData<GifFrameMetaData>(GifFormat.Instance); GifFrameMetaData cifm = clone.Frames[i].MetaData.GetOrAddFormatMetaData(GifFormat.Instance);
Assert.Equal(ifm.ColorTableLength, cifm.ColorTableLength); Assert.Equal(ifm.ColorTableLength, cifm.ColorTableLength);
Assert.Equal(ifm.FrameDelay, cifm.FrameDelay); Assert.Equal(ifm.FrameDelay, cifm.FrameDelay);

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

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

Loading…
Cancel
Save