From de71b0a85b0bac37832347c4bb9462e587ca5711 Mon Sep 17 00:00:00 2001 From: Ildar Khayrutdinov Date: Mon, 20 Feb 2023 13:51:27 +0300 Subject: [PATCH] universal metadata parsing methods for loading and identify --- .../Formats/Tiff/TiffDecoderCore.cs | 45 +++++++++++-------- .../Tiff/TiffDecoderMetadataCreator.cs | 24 +++------- 2 files changed, 34 insertions(+), 35 deletions(-) diff --git a/src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs b/src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs index 0579a5dd10..456518e11a 100644 --- a/src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs +++ b/src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs @@ -164,6 +164,7 @@ internal class TiffDecoderCore : IImageDecoderInternals where TPixel : unmanaged, IPixel { var frames = new List>(); + var framesMetadata = new List(); try { this.inputStream = stream; @@ -179,6 +180,7 @@ internal class TiffDecoderCore : IImageDecoderInternals cancellationToken.ThrowIfCancellationRequested(); ImageFrame frame = this.DecodeFrame(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 root = frames[0]; @@ -221,17 +221,21 @@ internal class TiffDecoderCore : IImageDecoderInternals DirectoryReader reader = new(stream, this.configuration.MemoryAllocator); IList directories = reader.Read(); - ExifProfile rootFrameExifProfile = directories.First(); - TiffFrameMetadata rootMetadata = TiffFrameMetadata.Parse(rootFrameExifProfile); + var frames = new List(); + 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); } /// @@ -244,16 +248,8 @@ internal class TiffDecoderCore : IImageDecoderInternals private ImageFrame DecodeFrame(ExifProfile tags, CancellationToken cancellationToken) where TPixel : unmanaged, IPixel { - 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; + } + /// /// Decodes the image data for Tiff's which arrange the pixel data in stripes. /// diff --git a/src/ImageSharp/Formats/Tiff/TiffDecoderMetadataCreator.cs b/src/ImageSharp/Formats/Tiff/TiffDecoderMetadataCreator.cs index c2a12c93cf..f17b928829 100644 --- a/src/ImageSharp/Formats/Tiff/TiffDecoderMetadataCreator.cs +++ b/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; /// internal static class TiffDecoderMetadataCreator { - public static ImageMetadata Create(List> frames, bool ignoreMetadata, ByteOrder byteOrder, bool isBigTiff) - where TPixel : unmanaged, IPixel + public static ImageMetadata Create(List 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 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 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;