Browse Source

universal metadata parsing methods for loading and identify

pull/2363/head
Ildar Khayrutdinov 4 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> where TPixel : unmanaged, IPixel<TPixel>
{ {
var frames = new List<ImageFrame<TPixel>>(); var frames = new List<ImageFrame<TPixel>>();
var framesMetadata = new List<ImageFrameMetadata>();
try try
{ {
this.inputStream = stream; this.inputStream = stream;
@ -179,6 +180,7 @@ internal class TiffDecoderCore : IImageDecoderInternals
cancellationToken.ThrowIfCancellationRequested(); cancellationToken.ThrowIfCancellationRequested();
ImageFrame<TPixel> frame = this.DecodeFrame<TPixel>(ifd, cancellationToken); ImageFrame<TPixel> frame = this.DecodeFrame<TPixel>(ifd, cancellationToken);
frames.Add(frame); frames.Add(frame);
framesMetadata.Add(frame.Metadata);
if (++frameCount == this.maxFrames) if (++frameCount == this.maxFrames)
{ {
@ -186,9 +188,7 @@ internal class TiffDecoderCore : IImageDecoderInternals
} }
} }
ImageMetadata metadata = TiffDecoderMetadataCreator.Create(frames, this.skipMetadata, reader.ByteOrder, reader.IsBigTiff); ImageMetadata metadata = TiffDecoderMetadataCreator.Create(framesMetadata, this.skipMetadata, reader.ByteOrder, reader.IsBigTiff);
TiffDecoderMetadataCreator.FillFrames(metadata.GetTiffMetadata(), directories);
// TODO: Tiff frames can have different sizes. // TODO: Tiff frames can have different sizes.
ImageFrame<TPixel> root = frames[0]; ImageFrame<TPixel> root = frames[0];
@ -221,17 +221,21 @@ internal class TiffDecoderCore : IImageDecoderInternals
DirectoryReader reader = new(stream, this.configuration.MemoryAllocator); DirectoryReader reader = new(stream, this.configuration.MemoryAllocator);
IList<ExifProfile> directories = reader.Read(); IList<ExifProfile> directories = reader.Read();
ExifProfile rootFrameExifProfile = directories.First(); var frames = new List<ImageFrameMetadata>();
TiffFrameMetadata rootMetadata = TiffFrameMetadata.Parse(rootFrameExifProfile); 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 width = GetImageWidth(rootFrameExifProfile);
int height = GetImageHeight(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> /// <summary>
@ -244,16 +248,8 @@ internal class TiffDecoderCore : IImageDecoderInternals
private ImageFrame<TPixel> DecodeFrame<TPixel>(ExifProfile tags, CancellationToken cancellationToken) private ImageFrame<TPixel> DecodeFrame<TPixel>(ExifProfile tags, CancellationToken cancellationToken)
where TPixel : unmanaged, IPixel<TPixel> where TPixel : unmanaged, IPixel<TPixel>
{ {
ImageFrameMetadata imageFrameMetaData = new(); var imageFrameMetaData = this.CreateFrameMetadata(tags);
if (!this.skipMetadata) bool isTiled = this.VerifyAndParse(tags, imageFrameMetaData.GetTiffMetadata());
{
imageFrameMetaData.ExifProfile = tags;
}
TiffFrameMetadata tiffFrameMetaData = imageFrameMetaData.GetTiffMetadata();
TiffFrameMetadata.Parse(tiffFrameMetaData, tags);
bool isTiled = this.VerifyAndParse(tags, tiffFrameMetaData);
int width = GetImageWidth(tags); int width = GetImageWidth(tags);
int height = GetImageHeight(tags); int height = GetImageHeight(tags);
@ -271,6 +267,19 @@ internal class TiffDecoderCore : IImageDecoderInternals
return frame; return frame;
} }
private ImageFrameMetadata CreateFrameMetadata(ExifProfile tags)
{
ImageFrameMetadata imageFrameMetaData = new();
if (!this.skipMetadata)
{
imageFrameMetaData.ExifProfile = tags;
}
TiffFrameMetadata.Parse(imageFrameMetaData.GetTiffMetadata(), tags);
return imageFrameMetaData;
}
/// <summary> /// <summary>
/// Decodes the image data for Tiff's which arrange the pixel data in stripes. /// Decodes the image data for Tiff's which arrange the pixel data in stripes.
/// </summary> /// </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.Icc;
using SixLabors.ImageSharp.Metadata.Profiles.Iptc; using SixLabors.ImageSharp.Metadata.Profiles.Iptc;
using SixLabors.ImageSharp.Metadata.Profiles.Xmp; using SixLabors.ImageSharp.Metadata.Profiles.Xmp;
using SixLabors.ImageSharp.PixelFormats;
namespace SixLabors.ImageSharp.Formats.Tiff; namespace SixLabors.ImageSharp.Formats.Tiff;
@ -17,22 +16,21 @@ namespace SixLabors.ImageSharp.Formats.Tiff;
/// </summary> /// </summary>
internal static class TiffDecoderMetadataCreator internal static class TiffDecoderMetadataCreator
{ {
public static ImageMetadata Create<TPixel>(List<ImageFrame<TPixel>> frames, bool ignoreMetadata, ByteOrder byteOrder, bool isBigTiff) public static ImageMetadata Create(List<ImageFrameMetadata> frames, bool ignoreMetadata, ByteOrder byteOrder, bool isBigTiff)
where TPixel : unmanaged, IPixel<TPixel>
{ {
if (frames.Count < 1) if (frames.Count < 1)
{ {
TiffThrowHelper.ThrowImageFormatException("Expected at least one frame."); 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) if (!ignoreMetadata)
{ {
var tiffMetadata = imageMetaData.GetTiffMetadata();
for (int i = 0; i < frames.Count; i++) for (int i = 0; i < frames.Count; i++)
{ {
ImageFrame<TPixel> frame = frames[i]; ImageFrameMetadata frameMetaData = frames[i];
ImageFrameMetadata frameMetaData = frame.Metadata;
if (TryGetIptc(frameMetaData.ExifProfile.Values, out byte[] iptcBytes)) if (TryGetIptc(frameMetaData.ExifProfile.Values, out byte[] iptcBytes))
{ {
frameMetaData.IptcProfile = new IptcProfile(iptcBytes); frameMetaData.IptcProfile = new IptcProfile(iptcBytes);
@ -47,13 +45,15 @@ internal static class TiffDecoderMetadataCreator
{ {
frameMetaData.IccProfile = new IccProfile(iccProfileBytes.Value); frameMetaData.IccProfile = new IccProfile(iccProfileBytes.Value);
} }
tiffMetadata.Frames.Add(frameMetaData.GetTiffMetadata());
} }
} }
return imageMetaData; 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(); var imageMetaData = new ImageMetadata();
SetResolution(imageMetaData, exifProfile); SetResolution(imageMetaData, exifProfile);
@ -64,16 +64,6 @@ internal static class TiffDecoderMetadataCreator
return imageMetaData; 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) private static void SetResolution(ImageMetadata imageMetaData, ExifProfile exifProfile)
{ {
imageMetaData.ResolutionUnits = exifProfile != null ? UnitConverter.ExifProfileToResolutionUnit(exifProfile) : PixelResolutionUnit.PixelsPerInch; imageMetaData.ResolutionUnits = exifProfile != null ? UnitConverter.ExifProfileToResolutionUnit(exifProfile) : PixelResolutionUnit.PixelsPerInch;

Loading…
Cancel
Save