Browse Source

Use directly ExifProfile methods instead TiffFrameMetadataExtensions

pull/1570/head
Ildar Khayrutdinov 5 years ago
parent
commit
ef068e6a77
  1. 15
      src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs
  2. 18
      src/ImageSharp/Formats/Tiff/TiffDecoderMetadataCreator.cs
  3. 2
      src/ImageSharp/Formats/Tiff/TiffDecoderOptionsParser.cs
  4. 14
      src/ImageSharp/Formats/Tiff/TiffEncoderEntriesCollector.cs
  5. 68
      src/ImageSharp/Formats/Tiff/TiffFrameMetadata.cs
  6. 136
      src/ImageSharp/Formats/Tiff/TiffFrameMetadataExtensions.cs
  7. 26
      src/ImageSharp/Formats/Tiff/TiffFrameMetadataResolutionExtensions.cs

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

@ -19,11 +19,6 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff
/// </summary>
internal class TiffDecoderCore : IImageDecoderInternals
{
/// <summary>
/// The global configuration
/// </summary>
private readonly Configuration configuration;
/// <summary>
/// Used for allocating memory during processing operations.
/// </summary>
@ -48,9 +43,9 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff
{
options ??= new TiffDecoder();
this.configuration = configuration ?? Configuration.Default;
this.Configuration = configuration ?? Configuration.Default;
this.ignoreMetadata = options.IgnoreMetadata;
this.memoryAllocator = this.configuration.MemoryAllocator;
this.memoryAllocator = this.Configuration.MemoryAllocator;
}
/// <summary>
@ -91,7 +86,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff
public TiffPredictor Predictor { get; set; }
/// <inheritdoc/>
public Configuration Configuration => this.configuration;
public Configuration Configuration { get; }
/// <inheritdoc/>
public Size Dimensions { get; private set; }
@ -129,7 +124,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff
}
}
var image = new Image<TPixel>(this.configuration, metadata, frames);
var image = new Image<TPixel>(this.Configuration, metadata, frames);
return image;
}
@ -175,7 +170,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff
int width = (int)frameMetaData.Width;
int height = (int)frameMetaData.Height;
var frame = new ImageFrame<TPixel>(this.configuration, width, height, coreMetadata);
var frame = new ImageFrame<TPixel>(this.Configuration, width, height, coreMetadata);
int rowsPerStrip = (int)frameMetaData.RowsPerStrip;
Number[] stripOffsets = frameMetaData.StripOffsets;

18
src/ImageSharp/Formats/Tiff/TiffDecoderMetadataCreator.cs

@ -47,28 +47,28 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff
{
if (tiffMetadata.XmpProfile == null)
{
byte[] buf = frame.GetArray<byte>(ExifTag.XMP, true);
if (buf != null)
IExifValue<byte[]> val = frame.ExifProfile.GetValue<byte[]>(ExifTag.XMP);
if (val != null)
{
tiffMetadata.XmpProfile = buf;
tiffMetadata.XmpProfile = val.Value;
}
}
if (coreMetadata.IptcProfile == null)
{
byte[] buf = frame.GetArray<byte>(ExifTag.IPTC, true);
if (buf != null)
IExifValue<byte[]> val = frame.ExifProfile.GetValue<byte[]>(ExifTag.IPTC);
if (val != null)
{
coreMetadata.IptcProfile = new IptcProfile(buf);
coreMetadata.IptcProfile = new IptcProfile(val.Value);
}
}
if (coreMetadata.IccProfile == null)
{
byte[] buf = frame.GetArray<byte>(ExifTag.IccProfile, true);
if (buf != null)
IExifValue<byte[]> val = frame.ExifProfile.GetValue<byte[]>(ExifTag.IccProfile);
if (val != null)
{
coreMetadata.IccProfile = new IccProfile(buf);
coreMetadata.IccProfile = new IccProfile(val.Value);
}
}
}

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

@ -29,7 +29,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff
TiffThrowHelper.ThrowNotSupported("The lower-order bits of the byte FillOrder is not supported.");
}
if (entries.GetArray<uint>(ExifTag.TileOffsets, true) != null)
if (entries.ExifProfile.GetValue<uint[]>(ExifTag.TileOffsets) != null)
{
TiffThrowHelper.ThrowNotSupported("The Tile images is not supported.");
}

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

@ -114,17 +114,17 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff
var xResolution = new ExifRational(ExifTagValue.XResolution)
{
Value = frameMetadata.GetSingle<Rational>(ExifTag.XResolution)
Value = frameMetadata.ExifProfile.GetValue<Rational>(ExifTag.XResolution).Value
};
var yResolution = new ExifRational(ExifTagValue.YResolution)
{
Value = frameMetadata.GetSingle<Rational>(ExifTag.YResolution)
Value = frameMetadata.ExifProfile.GetValue<Rational>(ExifTag.YResolution).Value
};
var resolutionUnit = new ExifShort(ExifTagValue.ResolutionUnit)
{
Value = frameMetadata.GetSingle<ushort>(ExifTag.ResolutionUnit)
Value = frameMetadata.ExifProfile.GetValue<ushort>(ExifTag.ResolutionUnit).Value
};
this.collector.AddInternal(xResolution);
@ -183,7 +183,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff
}
else
{
tiffFrameMetadata.Remove(ExifTag.SubIFDOffset);
tiffFrameMetadata.ExifProfile.RemoveValue(ExifTag.SubIFDOffset);
}
if (imageMetadata.IptcProfile != null)
@ -198,7 +198,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff
}
else
{
tiffFrameMetadata.Remove(ExifTag.IPTC);
tiffFrameMetadata.ExifProfile.RemoveValue(ExifTag.IPTC);
}
if (imageMetadata.IccProfile != null)
@ -212,7 +212,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff
}
else
{
tiffFrameMetadata.Remove(ExifTag.IccProfile);
tiffFrameMetadata.ExifProfile.RemoveValue(ExifTag.IccProfile);
}
TiffMetadata tiffMetadata = imageMetadata.GetTiffMetadata();
@ -227,7 +227,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff
}
else
{
tiffFrameMetadata.Remove(ExifTag.XMP);
tiffFrameMetadata.ExifProfile.RemoveValue(ExifTag.XMP);
}
}
}

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

@ -2,7 +2,7 @@
// Licensed under the Apache License, Version 2.0.
using System.Collections.Generic;
using System.Linq;
using SixLabors.ImageSharp.Formats.Experimental.Tiff.Constants;
using SixLabors.ImageSharp.Metadata;
using SixLabors.ImageSharp.Metadata.Profiles.Exif;
@ -41,21 +41,21 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff
/// <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>
public TiffNewSubfileType SubfileType => this.GetSingleEnum<TiffNewSubfileType, uint>(ExifTag.SubfileType, TiffNewSubfileType.FullImage);
public TiffNewSubfileType SubfileType => (TiffNewSubfileType?)this.ExifProfile.GetValue<uint>(ExifTag.SubfileType)?.Value ?? TiffNewSubfileType.FullImage;
/// <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>
public TiffSubfileType? OldSubfileType => this.GetSingleEnumNullable<TiffSubfileType, ushort>(ExifTag.OldSubfileType);
public TiffSubfileType? OldSubfileType => (TiffSubfileType?)this.ExifProfile.GetValue<ushort>(ExifTag.OldSubfileType)?.Value;
/// <summary>
/// Gets the number of columns in the image, i.e., the number of pixels per row.
/// </summary>
public Number Width => this.GetSingle<Number>(ExifTag.ImageWidth);
public Number Width => this.ExifProfile.GetValue<Number>(ExifTag.ImageWidth).Value;
/// <summary>
/// Gets the number of rows of pixels in the image.
/// </summary>
public Number Height => this.GetSingle<Number>(ExifTag.ImageLength);
public Number Height => this.ExifProfile.GetValue<Number>(ExifTag.ImageLength).Value;
/// <summary>
/// Gets the number of bits per component.
@ -64,7 +64,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff
{
get
{
var bits = this.GetArray<ushort>(ExifTag.BitsPerSample, true);
var bits = this.ExifProfile.GetValue<ushort[]>(ExifTag.BitsPerSample)?.Value;
if (bits == null)
{
if (this.PhotometricInterpretation == TiffPhotometricInterpretation.WhiteIsZero
@ -98,25 +98,25 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff
/// <summary>Gets the compression scheme used on the image data.</summary>
/// <value>The compression scheme used on the image data.</value>
public TiffCompression Compression => this.GetSingleEnum<TiffCompression, ushort>(ExifTag.Compression);
public TiffCompression Compression => (TiffCompression)this.ExifProfile.GetValue<ushort>(ExifTag.Compression).Value;
/// <summary>
/// Gets the color space of the image data.
/// </summary>
public TiffPhotometricInterpretation PhotometricInterpretation => this.GetSingleEnum<TiffPhotometricInterpretation, ushort>(ExifTag.PhotometricInterpretation);
public TiffPhotometricInterpretation PhotometricInterpretation => (TiffPhotometricInterpretation)this.ExifProfile.GetValue<ushort>(ExifTag.PhotometricInterpretation).Value;
/// <summary>
/// Gets the logical order of bits within a byte.
/// </summary>
internal TiffFillOrder FillOrder => this.GetSingleEnum<TiffFillOrder, ushort>(ExifTag.FillOrder, TiffFillOrder.MostSignificantBitFirst);
internal TiffFillOrder FillOrder => (TiffFillOrder?)this.ExifProfile.GetValue<ushort>(ExifTag.FillOrder)?.Value ?? TiffFillOrder.MostSignificantBitFirst;
/// <summary>
/// Gets or sets the a string that describes the subject of the image.
/// </summary>
public string ImageDescription
{
get => this.GetString(ExifTag.ImageDescription);
set => this.Set(ExifTag.ImageDescription, value);
get => this.ExifProfile.GetValue(ExifTag.ImageDescription)?.Value;
set => this.ExifProfile.SetValue(ExifTag.ImageDescription, value);
}
/// <summary>
@ -124,8 +124,8 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff
/// </summary>
public string Make
{
get => this.GetString(ExifTag.Make);
set => this.Set(ExifTag.Make, value);
get => this.ExifProfile.GetValue(ExifTag.Make)?.Value;
set => this.ExifProfile.SetValue(ExifTag.Make, value);
}
/// <summary>
@ -133,27 +133,27 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff
/// </summary>
public string Model
{
get => this.GetString(ExifTag.Model);
set => this.Set(ExifTag.Model, value);
get => this.ExifProfile.GetValue(ExifTag.Model)?.Value;
set => this.ExifProfile.SetValue(ExifTag.Model, value);
}
/// <summary>Gets for each strip, the byte offset of that strip..</summary>
public Number[] StripOffsets => this.GetArray<Number>(ExifTag.StripOffsets);
public Number[] StripOffsets => this.ExifProfile.GetValue<Number[]>(ExifTag.StripOffsets).Value;
/// <summary>
/// Gets the number of components per pixel.
/// </summary>
public ushort SamplesPerPixel => this.GetSingle<ushort>(ExifTag.SamplesPerPixel);
public ushort SamplesPerPixel => this.ExifProfile.GetValue<ushort>(ExifTag.SamplesPerPixel).Value;
/// <summary>
/// Gets the number of rows per strip.
/// </summary>
public Number RowsPerStrip => this.GetSingle<Number>(ExifTag.RowsPerStrip);
public Number RowsPerStrip => this.ExifProfile.GetValue<Number>(ExifTag.RowsPerStrip).Value;
/// <summary>
/// Gets for each strip, the number of bytes in the strip after compression.
/// </summary>
public Number[] StripByteCounts => this.GetArray<Number>(ExifTag.StripByteCounts);
public Number[] StripByteCounts => this.ExifProfile.GetValue<Number[]>(ExifTag.StripByteCounts).Value;
/// <summary>Gets the resolution of the image in x- direction.</summary>
/// <value>The density of the image in x- direction.</value>
@ -168,7 +168,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff
/// <summary>
/// Gets how the components of each pixel are stored.
/// </summary>
public TiffPlanarConfiguration PlanarConfiguration => this.GetSingleEnum<TiffPlanarConfiguration, ushort>(ExifTag.PlanarConfiguration, DefaultPlanarConfiguration);
public TiffPlanarConfiguration PlanarConfiguration => (TiffPlanarConfiguration?)this.ExifProfile.GetValue<ushort>(ExifTag.PlanarConfiguration)?.Value ?? DefaultPlanarConfiguration;
/// <summary>
/// Gets the unit of measurement for XResolution and YResolution.
@ -180,8 +180,8 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff
/// </summary>
public string Software
{
get => this.GetString(ExifTag.Software);
set => this.Set(ExifTag.Software, value);
get => this.ExifProfile.GetValue(ExifTag.Software)?.Value;
set => this.ExifProfile.SetValue(ExifTag.Software, value);
}
/// <summary>
@ -189,8 +189,8 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff
/// </summary>
public string DateTime
{
get => this.GetString(ExifTag.DateTime);
set => this.Set(ExifTag.DateTime, value);
get => this.ExifProfile.GetValue(ExifTag.DateTime)?.Value;
set => this.ExifProfile.SetValue(ExifTag.DateTime, value);
}
/// <summary>
@ -198,8 +198,8 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff
/// </summary>
public string Artist
{
get => this.GetString(ExifTag.Artist);
set => this.Set(ExifTag.Artist, value);
get => this.ExifProfile.GetValue(ExifTag.Artist)?.Value;
set => this.ExifProfile.SetValue(ExifTag.Artist, value);
}
/// <summary>
@ -207,39 +207,39 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff
/// </summary>
public string HostComputer
{
get => this.GetString(ExifTag.HostComputer);
set => this.Set(ExifTag.HostComputer, value);
get => this.ExifProfile.GetValue(ExifTag.HostComputer)?.Value;
set => this.ExifProfile.SetValue(ExifTag.HostComputer, value);
}
/// <summary>
/// Gets a color map for palette color images.
/// </summary>
public ushort[] ColorMap => this.GetArray<ushort>(ExifTag.ColorMap, true);
public ushort[] ColorMap => this.ExifProfile.GetValue<ushort[]>(ExifTag.ColorMap)?.Value;
/// <summary>
/// Gets the description of extra components.
/// </summary>
public ushort[] ExtraSamples => this.GetArray<ushort>(ExifTag.ExtraSamples, true);
public ushort[] ExtraSamples => this.ExifProfile.GetValue<ushort[]>(ExifTag.ExtraSamples)?.Value;
/// <summary>
/// Gets or sets the copyright notice.
/// </summary>
public string Copyright
{
get => this.GetString(ExifTag.Copyright);
set => this.Set(ExifTag.Copyright, value);
get => this.ExifProfile.GetValue(ExifTag.Copyright)?.Value;
set => this.ExifProfile.SetValue(ExifTag.Copyright, value);
}
/// <summary>
/// Gets a mathematical operator that is applied to the image data before an encoding scheme is applied.
/// </summary>
public TiffPredictor Predictor => this.GetSingleEnum<TiffPredictor, ushort>(ExifTag.Predictor, DefaultPredictor);
public TiffPredictor Predictor => (TiffPredictor?)this.ExifProfile.GetValue<ushort>(ExifTag.Predictor)?.Value ?? DefaultPredictor;
/// <summary>
/// Gets the specifies how to interpret each data sample in a pixel.
/// <see cref="SamplesPerPixel"/>
/// </summary>
public TiffSampleFormat[] SampleFormat => this.GetEnumArray<TiffSampleFormat, ushort>(ExifTag.SampleFormat, true);
public TiffSampleFormat[] SampleFormat => this.ExifProfile.GetValue<ushort[]>(ExifTag.SampleFormat)?.Value?.Select(a => (TiffSampleFormat)a).ToArray();
/// <summary>
/// Clears the metadata.

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

@ -1,136 +0,0 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
using System.Linq;
using SixLabors.ImageSharp.Metadata.Profiles.Exif;
namespace SixLabors.ImageSharp.Formats.Experimental.Tiff
{
/// <summary>
/// The tiff metadata extensions
/// </summary>
internal static class TiffFrameMetadataExtensions
{
public static T[] GetArray<T>(this TiffFrameMetadata meta, ExifTag tag, bool optional = false)
where T : struct
{
if (meta.TryGetArray(tag, out T[] result))
{
return result;
}
if (!optional)
{
TiffThrowHelper.ThrowTagNotFound(nameof(tag));
}
return null;
}
public static bool TryGetArray<T>(this TiffFrameMetadata meta, ExifTag tag, out T[] result)
where T : struct
{
IExifValue obj = meta.ExifProfile.GetValueInternal(tag);
if (obj != null)
{
DebugGuard.IsTrue(obj.IsArray, "Expected array entry");
object value = obj.GetValue();
result = (T[])value;
return true;
}
result = null;
return false;
}
public static TEnum[] GetEnumArray<TEnum, TTagValue>(this TiffFrameMetadata meta, ExifTag tag, bool optional = false)
where TEnum : struct
where TTagValue : struct
{
if (meta.TryGetArray(tag, out TTagValue[] result))
{
return result.Select(a => (TEnum)(object)a).ToArray();
}
if (!optional)
{
TiffThrowHelper.ThrowTagNotFound(nameof(tag));
}
return null;
}
public static string GetString(this TiffFrameMetadata meta, ExifTag tag)
{
IExifValue obj = meta.ExifProfile.GetValueInternal(tag);
if (obj != null)
{
DebugGuard.IsTrue(obj.DataType == ExifDataType.Ascii, "Expected string entry");
object value = obj.GetValue();
DebugGuard.IsTrue(value is string, "Expected string entry");
return (string)value;
}
return null;
}
public static void Set(this TiffFrameMetadata meta, ExifTag tag, object value) =>
meta.ExifProfile.SetValueInternal(tag, value);
public static TEnum? GetSingleEnumNullable<TEnum, TTagValue>(this TiffFrameMetadata meta, ExifTag tag)
where TEnum : struct
where TTagValue : struct
{
if (!meta.TryGetSingle(tag, out TTagValue value))
{
return null;
}
return (TEnum)(object)value;
}
public static TEnum GetSingleEnum<TEnum, TTagValue>(this TiffFrameMetadata meta, ExifTag tag, TEnum? defaultValue = null)
where TEnum : struct
where TTagValue : struct
=> meta.GetSingleEnumNullable<TEnum, TTagValue>(tag) ?? (defaultValue != null ? defaultValue.Value : throw TiffThrowHelper.TagNotFound(nameof(tag)));
public static T GetSingle<T>(this TiffFrameMetadata meta, ExifTag tag)
where T : struct
{
if (meta.TryGetSingle(tag, out T result))
{
return result;
}
throw TiffThrowHelper.TagNotFound(nameof(tag));
}
public static bool TryGetSingle<T>(this TiffFrameMetadata meta, ExifTag tag, out T result)
where T : struct
{
IExifValue obj = meta.ExifProfile.GetValueInternal(tag);
if (obj != null)
{
DebugGuard.IsTrue(!obj.IsArray, "Expected non array entry");
object value = obj.GetValue();
result = (T)value;
return true;
}
result = default;
return false;
}
public static bool Remove(this TiffFrameMetadata meta, ExifTag tag)
{
IExifValue obj = meta.ExifProfile.GetValueInternal(tag);
if (obj != null)
{
return meta.ExifProfile.RemoveValue(obj.Tag);
}
return false;
}
}
}

26
src/ImageSharp/Formats/Tiff/TiffFrameMetadataResolutionExtensions.cs

@ -19,9 +19,9 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff
break;
case PixelResolutionUnit.PixelsPerMeter:
{
unit = PixelResolutionUnit.PixelsPerCentimeter;
horizontal = UnitConverter.MeterToCm(horizontal);
vertical = UnitConverter.MeterToCm(vertical);
unit = PixelResolutionUnit.PixelsPerCentimeter;
horizontal = UnitConverter.MeterToCm(horizontal);
vertical = UnitConverter.MeterToCm(vertical);
}
break;
@ -30,29 +30,27 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff
break;
}
meta.Set(ExifTag.ResolutionUnit, (ushort)unit + 1);
meta.ExifProfile.SetValue(ExifTag.ResolutionUnit, (ushort)(unit + 1));
meta.SetResolution(ExifTag.XResolution, horizontal);
meta.SetResolution(ExifTag.YResolution, vertical);
}
public static PixelResolutionUnit GetResolutionUnit(this TiffFrameMetadata meta)
{
if (!meta.TryGetSingle(ExifTag.ResolutionUnit, out ushort res))
{
res = TiffFrameMetadata.DefaultResolutionUnit;
}
ushort res = meta.ExifProfile.GetValue<ushort>(ExifTag.ResolutionUnit)?.Value ?? TiffFrameMetadata.DefaultResolutionUnit;
return (PixelResolutionUnit)(res - 1);
}
public static double? GetResolution(this TiffFrameMetadata meta, ExifTag tag)
public static double? GetResolution(this TiffFrameMetadata meta, ExifTag<Rational> tag)
{
if (!meta.TryGetSingle(tag, out Rational resolution))
IExifValue<Rational> resolution = meta.ExifProfile.GetValue<Rational>(tag);
if (resolution == null)
{
return null;
}
double res = resolution.ToDouble();
double res = resolution.Value.ToDouble();
switch (meta.ResolutionUnit)
{
case PixelResolutionUnit.AspectRatio:
@ -68,11 +66,11 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff
}
}
private static void SetResolution(this TiffFrameMetadata meta, ExifTag tag, double? value)
private static void SetResolution(this TiffFrameMetadata meta, ExifTag<Rational> tag, double? value)
{
if (value == null)
{
meta.Remove(tag);
meta.ExifProfile.RemoveValue(tag);
return;
}
else
@ -94,7 +92,7 @@ namespace SixLabors.ImageSharp.Formats.Experimental.Tiff
break;
}
meta.Set(tag, new Rational(res));
meta.ExifProfile.SetValue(tag, new Rational(res));
}
}
}

Loading…
Cancel
Save