Browse Source

Use ExifProfile for tiff frame metadata

pull/1570/head
Ildar Khayrutdinov 5 years ago
parent
commit
34fc4e8478
  1. 14
      src/ImageSharp/Formats/Tiff/Ifd/DirectoryReader.cs
  2. 15
      src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs
  3. 2
      src/ImageSharp/Formats/Tiff/TiffEncoderEntriesCollector.cs
  4. 27
      src/ImageSharp/Formats/Tiff/TiffFrameMetadata.cs
  5. 59
      src/ImageSharp/Formats/Tiff/TiffFrameMetadataExtensions.cs
  6. 4
      src/ImageSharp/Metadata/Profiles/Exif/ExifProfile.cs

14
src/ImageSharp/Formats/Tiff/Ifd/DirectoryReader.cs

@ -26,7 +26,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff
this.tagReader = new EntryReader(stream);
}
public IEnumerable<IExifValue[]> Read()
public IEnumerable<ExifProfile> Read()
{
if (this.ReadHeader())
{
@ -55,13 +55,13 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff
return true;
}
private IEnumerable<IExifValue[]> ReadIfds()
private IEnumerable<ExifProfile> ReadIfds()
{
var list = new List<IExifValue[]>();
var list = new List<ExifProfile>();
while (this.nextIfdOffset != 0)
{
this.stream.Seek(this.nextIfdOffset);
IExifValue[] ifd = this.ReadIfd();
ExifProfile ifd = this.ReadIfd();
list.Add(ifd);
}
@ -70,7 +70,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff
return list;
}
private IExifValue[] ReadIfd()
private ExifProfile ReadIfd()
{
long pos = this.stream.Position;
@ -99,7 +99,9 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff
TiffThrowHelper.ThrowOutOfRange("IFD");
}
return entries.ToArray();
var profile = new ExifProfile();
profile.InitializeInternal(entries);
return profile;
}
}
}

15
src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs

@ -106,11 +106,11 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff
TiffStream tiffStream = CreateStream(stream);
var reader = new DirectoryReader(tiffStream);
IEnumerable<IExifValue[]> directories = reader.Read();
IEnumerable<ExifProfile> directories = reader.Read();
var frames = new List<ImageFrame<TPixel>>();
var framesMetadata = new List<TiffFrameMetadata>();
foreach (IExifValue[] ifd in directories)
foreach (ExifProfile ifd in directories)
{
ImageFrame<TPixel> frame = this.DecodeFrame<TPixel>(ifd, out TiffFrameMetadata frameMetadata);
frames.Add(frame);
@ -144,13 +144,12 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff
TiffStream tiffStream = CreateStream(stream);
var reader = new DirectoryReader(tiffStream);
IEnumerable<IExifValue[]> directories = reader.Read();
IEnumerable<ExifProfile> directories = reader.Read();
var framesMetadata = new List<TiffFrameMetadata>();
foreach (IExifValue[] ifd in directories)
foreach (ExifProfile ifd in directories)
{
var meta = new TiffFrameMetadata();
meta.FrameTags.AddRange(ifd);
var meta = new TiffFrameMetadata() { FrameTags = ifd };
framesMetadata.Add(meta);
}
@ -200,12 +199,12 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff
/// <returns>
/// The tiff frame.
/// </returns>
private ImageFrame<TPixel> DecodeFrame<TPixel>(IExifValue[] tags, out TiffFrameMetadata frameMetaData)
private ImageFrame<TPixel> DecodeFrame<TPixel>(ExifProfile tags, out TiffFrameMetadata frameMetaData)
where TPixel : unmanaged, IPixel<TPixel>
{
var coreMetadata = new ImageFrameMetadata();
frameMetaData = coreMetadata.GetTiffMetadata();
frameMetaData.FrameTags.AddRange(tags);
frameMetaData.FrameTags = tags;
this.VerifyAndParse(frameMetaData);

2
src/ImageSharp/Formats/Tiff/TiffEncoderEntriesCollector.cs

@ -134,7 +134,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff
private void ProcessMetadata(TiffFrameMetadata frameMetadata)
{
foreach (IExifValue entry in frameMetadata.FrameTags)
foreach (IExifValue entry in frameMetadata.FrameTags.Values)
{
// todo: skip subIfd
if (entry.DataType == ExifDataType.Ifd)

27
src/ImageSharp/Formats/Tiff/TiffFrameMetadata.cs

@ -21,6 +21,8 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff
private const TiffPredictor DefaultPredictor = TiffPredictor.None;
private ExifProfile frameTags;
/// <summary>
/// Initializes a new instance of the <see cref="TiffFrameMetadata"/> class.
/// </summary>
@ -29,9 +31,13 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff
}
/// <summary>
/// Gets the Tiff directory tags list.
/// Gets the Tiff directory tags.
/// </summary>
public List<IExifValue> FrameTags { get; internal set; } = new List<IExifValue>();
public ExifProfile FrameTags
{
get => this.frameTags ??= new ExifProfile();
internal set => this.frameTags = value;
}
/// <summary>Gets a general indication of the kind of data contained in this subfile.</summary>
/// <value>A general indication of the kind of data contained in this subfile.</value>
@ -241,7 +247,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff
public void ClearMetadata()
{
var tags = new List<IExifValue>();
foreach (IExifValue entry in this.FrameTags)
foreach (IExifValue entry in this.FrameTags.Values)
{
switch ((ExifTagValue)(ushort)entry.Tag)
{
@ -261,19 +267,12 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff
}
}
this.FrameTags = tags;
var profile = new ExifProfile();
profile.InitializeInternal(tags);
this.FrameTags = profile;
}
/// <inheritdoc/>
public IDeepCloneable DeepClone()
{
var tags = new List<IExifValue>();
foreach (IExifValue entry in this.FrameTags)
{
tags.Add(entry.DeepClone());
}
return new TiffFrameMetadata() { FrameTags = tags };
}
public IDeepCloneable DeepClone() => new TiffFrameMetadata() { FrameTags = this.FrameTags.DeepClone() };
}
}

59
src/ImageSharp/Formats/Tiff/TiffFrameMetadataExtensions.cs

@ -31,7 +31,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff
public static bool TryGetArray<T>(this TiffFrameMetadata meta, ExifTag tag, out T[] result)
where T : struct
{
foreach (IExifValue entry in meta.FrameTags)
foreach (IExifValue entry in meta.FrameTags.Values)
{
if (entry.Tag == tag)
{
@ -65,7 +65,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff
public static string GetString(this TiffFrameMetadata meta, ExifTag tag)
{
foreach (IExifValue entry in meta.FrameTags)
foreach (IExifValue entry in meta.FrameTags.Values)
{
if (entry.Tag == tag)
{
@ -80,13 +80,8 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff
return null;
}
public static bool SetString(this TiffFrameMetadata meta, ExifTag tag, string value)
{
IExifValue obj = FindOrCreate(meta, tag);
DebugGuard.IsTrue(obj.DataType == ExifDataType.Ascii, "Expected string entry");
return obj.TrySetValue(value);
}
public static void SetString(this TiffFrameMetadata meta, ExifTag tag, string value) =>
meta.FrameTags.SetValueInternal(tag, value);
public static TEnum? GetSingleEnumNullable<TEnum, TTagValue>(this TiffFrameMetadata meta, ExifTag tag)
where TEnum : struct
@ -105,15 +100,10 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff
where TTagValue : struct
=> meta.GetSingleEnumNullable<TEnum, TTagValue>(tag) ?? (defaultValue != null ? defaultValue.Value : throw TiffThrowHelper.TagNotFound(nameof(tag)));
public static bool SetSingleEnum<TEnum, TTagValue>(this TiffFrameMetadata meta, ExifTag tag, TEnum value)
public static void SetSingleEnum<TEnum, TTagValue>(this TiffFrameMetadata meta, ExifTag tag, TEnum value)
where TEnum : struct
where TTagValue : struct
{
IExifValue obj = FindOrCreate(meta, tag);
object val = (TTagValue)(object)value;
return obj.TrySetValue(val);
}
=> meta.FrameTags.SetValueInternal(tag, value);
public static T GetSingle<T>(this TiffFrameMetadata meta, ExifTag tag)
where T : struct
@ -129,7 +119,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff
public static bool TryGetSingle<T>(this TiffFrameMetadata meta, ExifTag tag, out T result)
where T : struct
{
foreach (IExifValue entry in meta.FrameTags)
foreach (IExifValue entry in meta.FrameTags.Values)
{
if (entry.Tag == tag)
{
@ -146,20 +136,14 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff
return false;
}
public static bool SetSingle<T>(this TiffFrameMetadata meta, ExifTag tag, T value)
public static void SetSingle<T>(this TiffFrameMetadata meta, ExifTag tag, T value)
where T : struct
{
IExifValue obj = FindOrCreate(meta, tag);
DebugGuard.IsTrue(!obj.IsArray, "Expected non array entry");
object val = value;
return obj.TrySetValue(val);
}
=> meta.FrameTags.SetValueInternal(tag, value);
public static bool Remove(this TiffFrameMetadata meta, ExifTag tag)
{
IExifValue obj = null;
foreach (IExifValue entry in meta.FrameTags)
foreach (IExifValue entry in meta.FrameTags.Values)
{
if (entry.Tag == tag)
{
@ -170,31 +154,10 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff
if (obj != null)
{
return meta.FrameTags.Remove(obj);
return meta.FrameTags.RemoveValue(obj.Tag);
}
return false;
}
private static IExifValue FindOrCreate(TiffFrameMetadata meta, ExifTag tag)
{
IExifValue obj = null;
foreach (IExifValue entry in meta.FrameTags)
{
if (entry.Tag == tag)
{
obj = entry;
break;
}
}
if (obj == null)
{
obj = ExifValues.Create(tag);
meta.FrameTags.Add(obj);
}
return obj;
}
}
}

4
src/ImageSharp/Metadata/Profiles/Exif/ExifProfile.cs

@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using SixLabors.ImageSharp.PixelFormats;
namespace SixLabors.ImageSharp.Metadata.Profiles.Exif
@ -258,6 +259,9 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif
this.SyncResolution(ExifTag.YResolution, metadata.VerticalResolution);
}
internal void InitializeInternal(List<IExifValue> values) =>
this.values = values;
private void SyncResolution(ExifTag<Rational> tag, double resolution)
{
IExifValue<Rational> value = this.GetValue(tag);

Loading…
Cancel
Save