Browse Source

Simplify metadata API

af/merge-core
James Jackson-South 8 years ago
parent
commit
06b9c54248
  1. 2
      src/ImageSharp/Common/Helpers/ImageMaths.cs
  2. 3
      src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs
  3. 2
      src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs
  4. 15
      src/ImageSharp/Formats/Gif/GifDecoderCore.cs
  5. 6
      src/ImageSharp/Formats/Gif/GifEncoderCore.cs
  6. 6
      src/ImageSharp/Formats/Png/PngDecoderCore.cs
  7. 2
      src/ImageSharp/Formats/Png/PngEncoderCore.cs
  8. 25
      src/ImageSharp/MetaData/ImageFrameMetaData.cs
  9. 21
      src/ImageSharp/MetaData/ImageMetaData.cs
  10. 2
      tests/ImageSharp.Tests/Formats/Bmp/BmpEncoderTests.cs
  11. 10
      tests/ImageSharp.Tests/Formats/Gif/GifEncoderTests.cs
  12. 4
      tests/ImageSharp.Tests/Formats/Png/PngEncoderTests.cs
  13. 14
      tests/ImageSharp.Tests/MetaData/ImageFrameMetaDataTests.cs

2
src/ImageSharp/Common/Helpers/ImageMaths.cs

@ -44,7 +44,7 @@ namespace SixLabors.ImageSharp
/// <param name="bitDepth">The bit depth.</param> /// <param name="bitDepth">The bit depth.</param>
/// <returns>The <see cref="int"/></returns> /// <returns>The <see cref="int"/></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int GetColorCountForBitDepth(int bitDepth) => (int)Math.Pow(2, bitDepth); public static int GetColorCountForBitDepth(int bitDepth) => 1 << bitDepth;
/// <summary> /// <summary>
/// Implementation of 1D Gaussian G(x) function /// Implementation of 1D Gaussian G(x) function

3
src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs

@ -537,8 +537,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp
this.metaData = meta; this.metaData = meta;
short bitsPerPixel = this.infoHeader.BitsPerPixel; short bitsPerPixel = this.infoHeader.BitsPerPixel;
var bmpMetaData = new BmpMetaData(); var bmpMetaData = this.metaData.GetFormatMetaData(BmpFormat.Instance);
this.metaData.AddOrUpdateFormatMetaData(BmpFormat.Instance, bmpMetaData);
// We can only encode at these bit rates so far. // We can only encode at these bit rates so far.
if (bitsPerPixel.Equals((short)BmpBitsPerPixel.Pixel24) if (bitsPerPixel.Equals((short)BmpBitsPerPixel.Pixel24)

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

@ -48,7 +48,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp
Guard.NotNull(image, nameof(image)); Guard.NotNull(image, nameof(image));
Guard.NotNull(stream, nameof(stream)); Guard.NotNull(stream, nameof(stream));
BmpMetaData bmpMetaData = image.MetaData.GetOrAddFormatMetaData(BmpFormat.Instance); BmpMetaData bmpMetaData = image.MetaData.GetFormatMetaData(BmpFormat.Instance);
this.bitsPerPixel = this.bitsPerPixel ?? bmpMetaData.BitsPerPixel; this.bitsPerPixel = this.bitsPerPixel ?? bmpMetaData.BitsPerPixel;
short bpp = (short)this.bitsPerPixel; short bpp = (short)this.bitsPerPixel;

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

@ -164,7 +164,6 @@ namespace SixLabors.ImageSharp.Formats.Gif
this.globalColorTable?.Dispose(); this.globalColorTable?.Dispose();
} }
image?.MetaData.AddOrUpdateFormatMetaData(GifFormat.Instance, this.gifMetaData);
return image; return image;
} }
@ -224,7 +223,6 @@ namespace SixLabors.ImageSharp.Formats.Gif
this.globalColorTable?.Dispose(); this.globalColorTable?.Dispose();
} }
this.metaData.AddOrUpdateFormatMetaData(GifFormat.Instance, this.gifMetaData);
return new ImageInfo( return new ImageInfo(
new PixelTypeInfo(this.logicalScreenDescriptor.BitsPerPixel), new PixelTypeInfo(this.logicalScreenDescriptor.BitsPerPixel),
this.logicalScreenDescriptor.Width, this.logicalScreenDescriptor.Width,
@ -542,7 +540,7 @@ namespace SixLabors.ImageSharp.Formats.Gif
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
private void SetFrameMetaData(ImageFrameMetaData meta) private void SetFrameMetaData(ImageFrameMetaData meta)
{ {
var gifMeta = new GifFrameMetaData(); GifFrameMetaData gifMeta = meta.GetFormatMetaData(GifFormat.Instance);
if (this.graphicsControlExtension.DelayTime > 0) if (this.graphicsControlExtension.DelayTime > 0)
{ {
gifMeta.FrameDelay = this.graphicsControlExtension.DelayTime; gifMeta.FrameDelay = this.graphicsControlExtension.DelayTime;
@ -561,7 +559,6 @@ namespace SixLabors.ImageSharp.Formats.Gif
} }
gifMeta.DisposalMethod = this.graphicsControlExtension.DisposalMethod; gifMeta.DisposalMethod = this.graphicsControlExtension.DisposalMethod;
meta.AddOrUpdateFormatMetaData(GifFormat.Instance, gifMeta);
} }
/// <summary> /// <summary>
@ -605,12 +602,10 @@ namespace SixLabors.ImageSharp.Formats.Gif
} }
this.metaData = meta; this.metaData = meta;
this.gifMetaData = new GifMetaData this.gifMetaData = meta.GetFormatMetaData(GifFormat.Instance);
{ this.gifMetaData.ColorTableMode = this.logicalScreenDescriptor.GlobalColorTableFlag
ColorTableMode = this.logicalScreenDescriptor.GlobalColorTableFlag ? GifColorTableMode.Global
? GifColorTableMode.Global : GifColorTableMode.Local;
: GifColorTableMode.Local
};
if (this.logicalScreenDescriptor.GlobalColorTableFlag) if (this.logicalScreenDescriptor.GlobalColorTableFlag)
{ {

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

@ -86,7 +86,7 @@ namespace SixLabors.ImageSharp.Formats.Gif
Guard.NotNull(image, nameof(image)); Guard.NotNull(image, nameof(image));
Guard.NotNull(stream, nameof(stream)); Guard.NotNull(stream, nameof(stream));
this.gifMetaData = image.MetaData.GetOrAddFormatMetaData(GifFormat.Instance); this.gifMetaData = image.MetaData.GetFormatMetaData(GifFormat.Instance);
this.colorTableMode = this.colorTableMode ?? this.gifMetaData.ColorTableMode; this.colorTableMode = this.colorTableMode ?? this.gifMetaData.ColorTableMode;
bool useGlobalTable = this.colorTableMode.Equals(GifColorTableMode.Global); 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++) 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(GifFormat.Instance); GifFrameMetaData frameMetaData = frame.MetaData.GetFormatMetaData(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(GifFormat.Instance); GifFrameMetaData meta = frame.MetaData.GetFormatMetaData(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.

6
src/ImageSharp/Formats/Png/PngDecoderCore.cs

@ -217,8 +217,7 @@ namespace SixLabors.ImageSharp.Formats.Png
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
var metaData = new ImageMetaData(); var metaData = new ImageMetaData();
var pngMetaData = new PngMetaData(); var pngMetaData = metaData.GetFormatMetaData(PngFormat.Instance);
metaData.AddOrUpdateFormatMetaData(PngFormat.Instance, pngMetaData);
this.currentStream = stream; this.currentStream = stream;
this.currentStream.Skip(8); this.currentStream.Skip(8);
Image<TPixel> image = null; Image<TPixel> image = null;
@ -308,8 +307,7 @@ namespace SixLabors.ImageSharp.Formats.Png
public IImageInfo Identify(Stream stream) public IImageInfo Identify(Stream stream)
{ {
var metaData = new ImageMetaData(); var metaData = new ImageMetaData();
var pngMetaData = new PngMetaData(); var pngMetaData = metaData.GetFormatMetaData(PngFormat.Instance);
metaData.AddOrUpdateFormatMetaData(PngFormat.Instance, pngMetaData);
this.currentStream = stream; this.currentStream = stream;
this.currentStream.Skip(8); this.currentStream.Skip(8);
try try

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

@ -181,7 +181,7 @@ namespace SixLabors.ImageSharp.Formats.Png
this.height = image.Height; this.height = image.Height;
// Always take the encoder options over the metadata values. // Always take the encoder options over the metadata values.
PngMetaData pngMetaData = image.MetaData.GetOrAddFormatMetaData(PngFormat.Instance); PngMetaData pngMetaData = image.MetaData.GetFormatMetaData(PngFormat.Instance);
this.gamma = this.gamma ?? pngMetaData.Gamma; this.gamma = this.gamma ?? pngMetaData.Gamma;
this.writeGamma = this.gamma > 0; this.writeGamma = this.gamma > 0;
this.pngColorType = this.pngColorType ?? pngMetaData.ColorType; this.pngColorType = this.pngColorType ?? pngMetaData.ColorType;

25
src/ImageSharp/MetaData/ImageFrameMetaData.cs

@ -44,27 +44,6 @@ namespace SixLabors.ImageSharp.MetaData
/// <returns>The cloned instance.</returns> /// <returns>The cloned instance.</returns>
public ImageFrameMetaData Clone() => new ImageFrameMetaData(this); public ImageFrameMetaData Clone() => new ImageFrameMetaData(this);
/// <summary>
/// Adds or updates the specified key and value to the <see cref="ImageMetaData"/>.
/// </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="value">The value of the element to add.</param>
/// <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 AddOrUpdateFormatMetaData<TFormatMetaData, TFormatFrameMetaData>(
IImageFormat<TFormatMetaData, TFormatFrameMetaData> key,
TFormatFrameMetaData value)
where TFormatMetaData : class
where TFormatFrameMetaData : class
{
// Don't think this needs to be threadsafe.
Guard.NotNull(value, nameof(value));
this.formatMetaData[key] = value;
}
/// <summary> /// <summary>
/// Gets the metadata value associated with the specified key. /// Gets the metadata value associated with the specified key.
/// </summary> /// </summary>
@ -74,7 +53,7 @@ namespace SixLabors.ImageSharp.MetaData
/// <returns> /// <returns>
/// The <typeparamref name="TFormatFrameMetaData"/>. /// The <typeparamref name="TFormatFrameMetaData"/>.
/// </returns> /// </returns>
public TFormatFrameMetaData GetOrAddFormatMetaData<TFormatMetaData, TFormatFrameMetaData>(IImageFormat<TFormatMetaData, TFormatFrameMetaData> key) public TFormatFrameMetaData GetFormatMetaData<TFormatMetaData, TFormatFrameMetaData>(IImageFormat<TFormatMetaData, TFormatFrameMetaData> key)
where TFormatMetaData : class where TFormatMetaData : class
where TFormatFrameMetaData : class where TFormatFrameMetaData : class
{ {
@ -84,7 +63,7 @@ namespace SixLabors.ImageSharp.MetaData
} }
TFormatFrameMetaData newMeta = key.CreateDefaultFormatFrameMetaData(); TFormatFrameMetaData newMeta = key.CreateDefaultFormatFrameMetaData();
this.AddOrUpdateFormatMetaData(key, newMeta); this.formatMetaData[key] = newMeta;
return newMeta; return newMeta;
} }
} }

21
src/ImageSharp/MetaData/ImageMetaData.cs

@ -131,23 +131,6 @@ namespace SixLabors.ImageSharp.MetaData
/// </summary> /// </summary>
public IList<ImageProperty> Properties { get; } = new List<ImageProperty>(); public IList<ImageProperty> Properties { get; } = new List<ImageProperty>();
/// <summary>
/// Adds or updates the specified key and value to the <see cref="ImageMetaData"/>.
/// </summary>
/// <typeparam name="TFormatMetaData">The type of format metadata.</typeparam>
/// <param name="key">The key of the metadata to add.</param>
/// <param name="value">The value of the element to add.</param>
/// <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 AddOrUpdateFormatMetaData<TFormatMetaData>(IImageFormat<TFormatMetaData> key, TFormatMetaData value)
where TFormatMetaData : class
{
// Don't think this needs to be threadsafe.
Guard.NotNull(value, nameof(value));
this.formatMetaData[key] = value;
}
/// <summary> /// <summary>
/// Gets the metadata value associated with the specified key. /// Gets the metadata value associated with the specified key.
/// </summary> /// </summary>
@ -156,7 +139,7 @@ namespace SixLabors.ImageSharp.MetaData
/// <returns> /// <returns>
/// The <typeparamref name="TFormatMetaData"/>. /// The <typeparamref name="TFormatMetaData"/>.
/// </returns> /// </returns>
public TFormatMetaData GetOrAddFormatMetaData<TFormatMetaData>(IImageFormat<TFormatMetaData> key) public TFormatMetaData GetFormatMetaData<TFormatMetaData>(IImageFormat<TFormatMetaData> key)
where TFormatMetaData : class where TFormatMetaData : class
{ {
if (this.formatMetaData.TryGetValue(key, out object meta)) if (this.formatMetaData.TryGetValue(key, out object meta))
@ -165,7 +148,7 @@ namespace SixLabors.ImageSharp.MetaData
} }
TFormatMetaData newMeta = key.CreateDefaultFormatMetaData(); TFormatMetaData newMeta = key.CreateDefaultFormatMetaData();
this.AddOrUpdateFormatMetaData(key, newMeta); this.formatMetaData[key] = newMeta;
return newMeta; return newMeta;
} }

2
tests/ImageSharp.Tests/Formats/Bmp/BmpEncoderTests.cs

@ -80,7 +80,7 @@ namespace SixLabors.ImageSharp.Tests
memStream.Position = 0; memStream.Position = 0;
using (var output = Image.Load<Rgba32>(memStream)) using (var output = Image.Load<Rgba32>(memStream))
{ {
BmpMetaData meta = output.MetaData.GetOrAddFormatMetaData(BmpFormat.Instance); BmpMetaData meta = output.MetaData.GetFormatMetaData(BmpFormat.Instance);
Assert.Equal(bmpBitsPerPixel, meta.BitsPerPixel); Assert.Equal(bmpBitsPerPixel, meta.BitsPerPixel);
} }

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

4
tests/ImageSharp.Tests/Formats/Png/PngEncoderTests.cs

@ -228,7 +228,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png
: image; : image;
float paletteToleranceHack = 80f / paletteSize; float paletteToleranceHack = 80f / paletteSize;
paletteToleranceHack = paletteToleranceHack * paletteToleranceHack; paletteToleranceHack *= paletteToleranceHack;
ImageComparer comparer = pngColorType == PngColorType.Palette ImageComparer comparer = pngColorType == PngColorType.Palette
? ImageComparer.Tolerant(ToleranceThresholdForPaletteEncoder * paletteToleranceHack) ? ImageComparer.Tolerant(ToleranceThresholdForPaletteEncoder * paletteToleranceHack)
: ImageComparer.Exact; : ImageComparer.Exact;
@ -314,7 +314,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png
memStream.Position = 0; memStream.Position = 0;
using (var output = Image.Load<Rgba32>(memStream)) using (var output = Image.Load<Rgba32>(memStream))
{ {
PngMetaData meta = output.MetaData.GetOrAddFormatMetaData(PngFormat.Instance); PngMetaData meta = output.MetaData.GetFormatMetaData(PngFormat.Instance);
Assert.Equal(pngBitDepth, meta.BitDepth); Assert.Equal(pngBitDepth, meta.BitDepth);
} }

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

@ -19,18 +19,14 @@ namespace SixLabors.ImageSharp.Tests
const int colorTableLength = 128; const int colorTableLength = 128;
const GifDisposalMethod disposalMethod = GifDisposalMethod.RestoreToBackground; const GifDisposalMethod disposalMethod = GifDisposalMethod.RestoreToBackground;
var gifFrameMetaData = new GifFrameMetaData
{
FrameDelay = frameDelay,
ColorTableLength = colorTableLength,
DisposalMethod = disposalMethod
};
var metaData = new ImageFrameMetaData(); var metaData = new ImageFrameMetaData();
metaData.AddOrUpdateFormatMetaData(GifFormat.Instance, gifFrameMetaData); GifFrameMetaData gifFrameMetaData = metaData.GetFormatMetaData(GifFormat.Instance);
gifFrameMetaData.FrameDelay = frameDelay;
gifFrameMetaData.ColorTableLength = colorTableLength;
gifFrameMetaData.DisposalMethod = disposalMethod;
var clone = new ImageFrameMetaData(metaData); var clone = new ImageFrameMetaData(metaData);
GifFrameMetaData cloneGifFrameMetaData = clone.GetOrAddFormatMetaData(GifFormat.Instance); GifFrameMetaData cloneGifFrameMetaData = clone.GetFormatMetaData(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