Browse Source

universal metadata parsing methods for loading and identify

pull/2363/head
Ildar Khayrutdinov 3 years ago
parent
commit
de71b0a85b
  1. 45
      src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs
  2. 24
      src/ImageSharp/Formats/Tiff/TiffDecoderMetadataCreator.cs

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

@ -164,6 +164,7 @@ internal class TiffDecoderCore : IImageDecoderInternals
where TPixel : unmanaged, IPixel<TPixel>
{
var frames = new List<ImageFrame<TPixel>>();
var framesMetadata = new List<ImageFrameMetadata>();
try
{
this.inputStream = stream;
@ -179,6 +180,7 @@ internal class TiffDecoderCore : IImageDecoderInternals
cancellationToken.ThrowIfCancellationRequested();
ImageFrame<TPixel> frame = this.DecodeFrame<TPixel>(ifd, cancellationToken);
frames.Add(frame);
framesMetadata.Add(frame.Metadata);
if (++frameCount == this.maxFrames)
{
@ -186,9 +188,7 @@ internal class TiffDecoderCore : IImageDecoderInternals
}
}
ImageMetadata metadata = TiffDecoderMetadataCreator.Create(frames, this.skipMetadata, reader.ByteOrder, reader.IsBigTiff);
TiffDecoderMetadataCreator.FillFrames(metadata.GetTiffMetadata(), directories);
ImageMetadata metadata = TiffDecoderMetadataCreator.Create(framesMetadata, this.skipMetadata, reader.ByteOrder, reader.IsBigTiff);
// TODO: Tiff frames can have different sizes.
ImageFrame<TPixel> root = frames[0];
@ -221,17 +221,21 @@ internal class TiffDecoderCore : IImageDecoderInternals
DirectoryReader reader = new(stream, this.configuration.MemoryAllocator);
IList<ExifProfile> directories = reader.Read();
ExifProfile rootFrameExifProfile = directories.First();
TiffFrameMetadata rootMetadata = TiffFrameMetadata.Parse(rootFrameExifProfile);
var frames = new List<ImageFrameMetadata>();
foreach (ExifProfile dir in directories)
{
var frame = this.CreateFrameMetadata(dir);
frames.Add(frame);
}
ImageMetadata metadata = TiffDecoderMetadataCreator.Create(reader.ByteOrder, reader.IsBigTiff, rootFrameExifProfile);
ExifProfile rootFrameExifProfile = directories.First();
TiffDecoderMetadataCreator.FillFrames(metadata.GetTiffMetadata(), directories);
ImageMetadata metadata = TiffDecoderMetadataCreator.Create(frames, this.skipMetadata, reader.ByteOrder, reader.IsBigTiff);
int width = GetImageWidth(rootFrameExifProfile);
int height = GetImageHeight(rootFrameExifProfile);
return new ImageInfo(new PixelTypeInfo((int)rootMetadata.BitsPerPixel), width, height, metadata);
return new ImageInfo(new PixelTypeInfo((int)frames.First().GetTiffMetadata().BitsPerPixel), width, height, metadata);
}
/// <summary>
@ -244,16 +248,8 @@ internal class TiffDecoderCore : IImageDecoderInternals
private ImageFrame<TPixel> DecodeFrame<TPixel>(ExifProfile tags, CancellationToken cancellationToken)
where TPixel : unmanaged, IPixel<TPixel>
{
ImageFrameMetadata imageFrameMetaData = new();
if (!this.skipMetadata)
{
imageFrameMetaData.ExifProfile = tags;
}
TiffFrameMetadata tiffFrameMetaData = imageFrameMetaData.GetTiffMetadata();
TiffFrameMetadata.Parse(tiffFrameMetaData, tags);
bool isTiled = this.VerifyAndParse(tags, tiffFrameMetaData);
var imageFrameMetaData = this.CreateFrameMetadata(tags);
bool isTiled = this.VerifyAndParse(tags, imageFrameMetaData.GetTiffMetadata());
int width = GetImageWidth(tags);
int height = GetImageHeight(tags);
@ -271,6 +267,19 @@ internal class TiffDecoderCore : IImageDecoderInternals
return frame;
}
private ImageFrameMetadata CreateFrameMetadata(ExifProfile tags)
{
ImageFrameMetadata imageFrameMetaData = new();
if (!this.skipMetadata)
{
imageFrameMetaData.ExifProfile = tags;
}
TiffFrameMetadata.Parse(imageFrameMetaData.GetTiffMetadata(), tags);
return imageFrameMetaData;
}
/// <summary>
/// Decodes the image data for Tiff's which arrange the pixel data in stripes.
/// </summary>

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

@ -8,7 +8,6 @@ using SixLabors.ImageSharp.Metadata.Profiles.Exif;
using SixLabors.ImageSharp.Metadata.Profiles.Icc;
using SixLabors.ImageSharp.Metadata.Profiles.Iptc;
using SixLabors.ImageSharp.Metadata.Profiles.Xmp;
using SixLabors.ImageSharp.PixelFormats;
namespace SixLabors.ImageSharp.Formats.Tiff;
@ -17,22 +16,21 @@ namespace SixLabors.ImageSharp.Formats.Tiff;
/// </summary>
internal static class TiffDecoderMetadataCreator
{
public static ImageMetadata Create<TPixel>(List<ImageFrame<TPixel>> frames, bool ignoreMetadata, ByteOrder byteOrder, bool isBigTiff)
where TPixel : unmanaged, IPixel<TPixel>
public static ImageMetadata Create(List<ImageFrameMetadata> frames, bool ignoreMetadata, ByteOrder byteOrder, bool isBigTiff)
{
if (frames.Count < 1)
{
TiffThrowHelper.ThrowImageFormatException("Expected at least one frame.");
}
ImageMetadata imageMetaData = Create(byteOrder, isBigTiff, frames[0].Metadata.ExifProfile);
ImageMetadata imageMetaData = Create(byteOrder, isBigTiff, frames[0].ExifProfile);
if (!ignoreMetadata)
{
var tiffMetadata = imageMetaData.GetTiffMetadata();
for (int i = 0; i < frames.Count; i++)
{
ImageFrame<TPixel> frame = frames[i];
ImageFrameMetadata frameMetaData = frame.Metadata;
ImageFrameMetadata frameMetaData = frames[i];
if (TryGetIptc(frameMetaData.ExifProfile.Values, out byte[] iptcBytes))
{
frameMetaData.IptcProfile = new IptcProfile(iptcBytes);
@ -47,13 +45,15 @@ internal static class TiffDecoderMetadataCreator
{
frameMetaData.IccProfile = new IccProfile(iccProfileBytes.Value);
}
tiffMetadata.Frames.Add(frameMetaData.GetTiffMetadata());
}
}
return imageMetaData;
}
public static ImageMetadata Create(ByteOrder byteOrder, bool isBigTiff, ExifProfile exifProfile)
private static ImageMetadata Create(ByteOrder byteOrder, bool isBigTiff, ExifProfile exifProfile)
{
var imageMetaData = new ImageMetadata();
SetResolution(imageMetaData, exifProfile);
@ -64,16 +64,6 @@ internal static class TiffDecoderMetadataCreator
return imageMetaData;
}
public static void FillFrames(TiffMetadata tiffMetadata, IList<ExifProfile> directories)
{
foreach (ExifProfile dir in directories)
{
TiffFrameMetadata meta = TiffFormat.Instance.CreateDefaultFormatFrameMetadata();
TiffFrameMetadata.Parse(meta, dir);
tiffMetadata.Frames.Add(meta);
}
}
private static void SetResolution(ImageMetadata imageMetaData, ExifProfile exifProfile)
{
imageMetaData.ResolutionUnits = exifProfile != null ? UnitConverter.ExifProfileToResolutionUnit(exifProfile) : PixelResolutionUnit.PixelsPerInch;

Loading…
Cancel
Save