mirror of https://github.com/SixLabors/ImageSharp
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
286 lines
10 KiB
286 lines
10 KiB
// Copyright (c) Six Labors.
|
|
// 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.Profiles.Exif;
|
|
|
|
namespace SixLabors.ImageSharp.Formats.Experimental.Tiff
|
|
{
|
|
/// <summary>
|
|
/// Provides Tiff specific metadata information for the frame.
|
|
/// </summary>
|
|
public class TiffFrameMetadata : IDeepCloneable
|
|
{
|
|
private const TiffResolutionUnit DefaultResolutionUnit = TiffResolutionUnit.Inch;
|
|
|
|
private const TiffPlanarConfiguration DefaultPlanarConfiguration = TiffPlanarConfiguration.Chunky;
|
|
|
|
private const TiffPredictor DefaultPredictor = TiffPredictor.None;
|
|
|
|
/// <summary>
|
|
/// Initializes a new instance of the <see cref="TiffFrameMetadata"/> class.
|
|
/// </summary>
|
|
public TiffFrameMetadata()
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets or sets the Tiff directory tags list.
|
|
/// </summary>
|
|
public List<IExifValue> FrameTags { get; set; } = new List<IExifValue>();
|
|
|
|
/// <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 NewSubfileType => this.GetSingleEnum<TiffNewSubfileType, uint>(ExifTag.SubfileType, 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? SubfileType => this.GetSingleEnumNullable<TiffSubfileType, uint>(ExifTag.OldSubfileType);
|
|
|
|
/// <summary>
|
|
/// Gets the number of columns in the image, i.e., the number of pixels per row.
|
|
/// </summary>
|
|
public uint Width => this.GetSingle<uint>(ExifTag.ImageWidth);
|
|
|
|
/// <summary>
|
|
/// Gets the number of rows of pixels in the image.
|
|
/// </summary>
|
|
public uint Height => this.GetSingle<uint>(ExifTag.ImageLength);
|
|
|
|
/// <summary>
|
|
/// Gets the number of bits per component.
|
|
/// </summary>
|
|
public ushort[] BitsPerSample => this.GetArray<ushort>(ExifTag.BitsPerSample, true);
|
|
|
|
/// <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);
|
|
|
|
/// <summary>
|
|
/// Gets the color space of the image data.
|
|
/// </summary>
|
|
public TiffPhotometricInterpretation PhotometricInterpretation => this.GetSingleEnum<TiffPhotometricInterpretation, ushort>(ExifTag.PhotometricInterpretation);
|
|
|
|
/// <summary>
|
|
/// Gets the logical order of bits within a byte.
|
|
/// </summary>
|
|
internal TiffFillOrder FillOrder => this.GetSingleEnum<TiffFillOrder, ushort>(ExifTag.FillOrder, 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.SetString(ExifTag.ImageDescription, value);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets or sets the scanner manufacturer.
|
|
/// </summary>
|
|
public string Make
|
|
{
|
|
get => this.GetString(ExifTag.Make);
|
|
set => this.SetString(ExifTag.Make, value);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets or sets the scanner model name or number.
|
|
/// </summary>
|
|
public string Model
|
|
{
|
|
get => this.GetString(ExifTag.Model);
|
|
set => this.SetString(ExifTag.Model, value);
|
|
}
|
|
|
|
/// <summary>Gets for each strip, the byte offset of that strip..</summary>
|
|
public uint[] StripOffsets => this.GetArray<uint>(ExifTag.StripOffsets);
|
|
|
|
/// <summary>
|
|
/// Gets the number of components per pixel.
|
|
/// </summary>
|
|
public ushort SamplesPerPixel => this.GetSingle<ushort>(ExifTag.SamplesPerPixel);
|
|
|
|
/// <summary>
|
|
/// Gets the number of rows per strip.
|
|
/// </summary>
|
|
public uint RowsPerStrip => this.GetSingle<uint>(ExifTag.RowsPerStrip);
|
|
|
|
/// <summary>
|
|
/// Gets for each strip, the number of bytes in the strip after compression.
|
|
/// </summary>
|
|
public uint[] StripByteCounts => this.GetArray<uint>(ExifTag.StripByteCounts);
|
|
|
|
/// <summary>Gets the resolution of the image in x- direction.</summary>
|
|
/// <value>The density of the image in x- direction.</value>
|
|
public double? HorizontalResolution
|
|
{
|
|
get
|
|
{
|
|
if (this.TryGetSingle(ExifTag.XResolution, out Rational xResolution))
|
|
{
|
|
return xResolution.ToDouble() * this.ResolutionFactor;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
internal set
|
|
{
|
|
if (value == null)
|
|
{
|
|
this.Remove(ExifTag.XResolution);
|
|
}
|
|
else
|
|
{
|
|
double tag = value.Value / this.ResolutionFactor;
|
|
this.SetSingle(ExifTag.XResolution, new Rational(tag));
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the resolution of the image in y- direction.
|
|
/// </summary>
|
|
/// <value>The density of the image in y- direction.</value>
|
|
public double? VerticalResolution
|
|
{
|
|
get
|
|
{
|
|
if (this.TryGetSingle(ExifTag.YResolution, out Rational yResolution))
|
|
{
|
|
return yResolution.ToDouble() * this.ResolutionFactor;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
internal set
|
|
{
|
|
if (value == null)
|
|
{
|
|
this.Remove(ExifTag.YResolution);
|
|
}
|
|
else
|
|
{
|
|
double tag = value.Value / this.ResolutionFactor;
|
|
this.SetSingle(ExifTag.YResolution, new Rational(tag));
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets how the components of each pixel are stored.
|
|
/// </summary>
|
|
public TiffPlanarConfiguration PlanarConfiguration => this.GetSingleEnum<TiffPlanarConfiguration, ushort>(ExifTag.PlanarConfiguration, DefaultPlanarConfiguration);
|
|
|
|
/// <summary>
|
|
/// Gets the unit of measurement for XResolution and YResolution.
|
|
/// </summary>
|
|
public TiffResolutionUnit ResolutionUnit
|
|
{
|
|
get => this.GetSingleEnum<TiffResolutionUnit, ushort>(ExifTag.ResolutionUnit, DefaultResolutionUnit);
|
|
internal set => this.SetSingleEnum<TiffResolutionUnit, ushort>(ExifTag.ResolutionUnit, value);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets or sets the name and version number of the software package(s) used to create the image.
|
|
/// </summary>
|
|
public string Software
|
|
{
|
|
get => this.GetString(ExifTag.Software);
|
|
set => this.SetString(ExifTag.Software, value);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets or sets the date and time of image creation.
|
|
/// </summary>
|
|
public string DateTime
|
|
{
|
|
get => this.GetString(ExifTag.DateTime);
|
|
set => this.SetString(ExifTag.DateTime, value);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets or sets the person who created the image.
|
|
/// </summary>
|
|
public string Artist
|
|
{
|
|
get => this.GetString(ExifTag.Artist);
|
|
set => this.SetString(ExifTag.Artist, value);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets or sets the computer and/or operating system in use at the time of image creation.
|
|
/// </summary>
|
|
public string HostComputer
|
|
{
|
|
get => this.GetString(ExifTag.HostComputer);
|
|
set => this.SetString(ExifTag.HostComputer, value);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets a color map for palette color images.
|
|
/// </summary>
|
|
public ushort[] ColorMap => this.GetArray<ushort>(ExifTag.ColorMap, true);
|
|
|
|
/// <summary>
|
|
/// Gets the description of extra components.
|
|
/// </summary>
|
|
public ushort[] ExtraSamples => this.GetArray<ushort>(ExifTag.ExtraSamples, true);
|
|
|
|
/// <summary>
|
|
/// Gets or sets the copyright notice.
|
|
/// </summary>
|
|
public string Copyright
|
|
{
|
|
get => this.GetString(ExifTag.Copyright);
|
|
set => this.SetString(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);
|
|
|
|
/// <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);
|
|
|
|
private double ResolutionFactor
|
|
{
|
|
get
|
|
{
|
|
TiffResolutionUnit unit = this.ResolutionUnit;
|
|
if (unit == TiffResolutionUnit.Centimeter)
|
|
{
|
|
return 2.54;
|
|
}
|
|
else if (unit == TiffResolutionUnit.Inch)
|
|
{
|
|
return 1.0;
|
|
}
|
|
|
|
// DefaultResolutionUnit is Inch
|
|
return 1.0;
|
|
}
|
|
}
|
|
|
|
/// <inheritdoc/>
|
|
public IDeepCloneable DeepClone()
|
|
{
|
|
var tags = new List<IExifValue>();
|
|
foreach (IExifValue entry in this.FrameTags)
|
|
{
|
|
tags.Add(entry.DeepClone());
|
|
}
|
|
|
|
return new TiffFrameMetadata() { FrameTags = tags };
|
|
}
|
|
}
|
|
}
|
|
|