From 85a65ae6f92fd70fd66e92d1f1b6f35b6357af91 Mon Sep 17 00:00:00 2001 From: Brian Popow Date: Mon, 10 May 2021 12:19:49 +0200 Subject: [PATCH] Remove width and height from tiff frame metadata --- .../Formats/Tiff/TiffDecoderCore.cs | 41 ++++++- .../Formats/Tiff/TiffFrameMetadata.cs | 61 +--------- .../Formats/Tiff/TiffEncoderTests.cs | 13 ++- .../Formats/Tiff/TiffMetadataTests.cs | 107 +++++++++--------- 4 files changed, 101 insertions(+), 121 deletions(-) diff --git a/src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs b/src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs index fe6778fc23..75cd063613 100644 --- a/src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs +++ b/src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs @@ -155,7 +155,10 @@ namespace SixLabors.ImageSharp.Formats.Tiff ImageMetadata metadata = TiffDecoderMetadataCreator.Create(framesMetadata, this.ignoreMetadata, reader.ByteOrder); TiffFrameMetadata root = framesMetadata[0]; - return new ImageInfo(new PixelTypeInfo(root.BitsPerSample.BitsPerPixel()), (int)root.Width, (int)root.Height, metadata); + int width = GetImageWidth(root); + int height = GetImageHeight(root); + + return new ImageInfo(new PixelTypeInfo(root.BitsPerSample.BitsPerPixel()), width, height, metadata); } /// @@ -176,8 +179,8 @@ namespace SixLabors.ImageSharp.Formats.Tiff this.VerifyAndParse(frameMetaData); - int width = (int)frameMetaData.Width; - int height = (int)frameMetaData.Height; + int width = GetImageWidth(frameMetaData); + int height = GetImageHeight(frameMetaData); var frame = new ImageFrame(this.Configuration, width, height, coreMetadata); int rowsPerStrip = (int)frameMetaData.RowsPerStrip; @@ -312,5 +315,37 @@ namespace SixLabors.ImageSharp.Formats.Tiff colorDecoder.Decode(stripBuffer.GetSpan(), pixels, 0, top, frame.Width, stripHeight); } } + + /// + /// Gets the width of the image frame. + /// + /// The image frame. + /// The image width. + private static int GetImageWidth(TiffFrameMetadata frame) + { + IExifValue width = frame.ExifProfile.GetValue(ExifTag.ImageWidth); + if (width == null) + { + TiffThrowHelper.ThrowImageFormatException("The TIFF image frame is missing the ImageWidth"); + } + + return (int)width.Value; + } + + /// + /// Gets the height of the image frame. + /// + /// The image frame. + /// The image height. + private static int GetImageHeight(TiffFrameMetadata frame) + { + IExifValue height = frame.ExifProfile.GetValue(ExifTag.ImageLength); + if (height == null) + { + TiffThrowHelper.ThrowImageFormatException("The TIFF image frame is missing the ImageLength"); + } + + return (int)height.Value; + } } } diff --git a/src/ImageSharp/Formats/Tiff/TiffFrameMetadata.cs b/src/ImageSharp/Formats/Tiff/TiffFrameMetadata.cs index 4386f49322..119a60d92e 100644 --- a/src/ImageSharp/Formats/Tiff/TiffFrameMetadata.cs +++ b/src/ImageSharp/Formats/Tiff/TiffFrameMetadata.cs @@ -1,7 +1,6 @@ // Copyright (c) Six Labors. // Licensed under the Apache License, Version 2.0. -using System.Collections.Generic; using System.Linq; using SixLabors.ImageSharp.Common.Helpers; using SixLabors.ImageSharp.Formats.Tiff.Constants; @@ -21,13 +20,6 @@ namespace SixLabors.ImageSharp.Formats.Tiff private ExifProfile frameTags; - /// - /// Initializes a new instance of the class. - /// - public TiffFrameMetadata() - { - } - /// /// Gets the Tiff directory tags. /// @@ -47,40 +39,6 @@ namespace SixLabors.ImageSharp.Formats.Tiff /// public TiffSubfileType? OldSubfileType => (TiffSubfileType?)this.ExifProfile.GetValue(ExifTag.OldSubfileType)?.Value; - /// - /// Gets the number of columns in the image, i.e., the number of pixels per row. - /// - public Number Width - { - get - { - IExifValue width = this.ExifProfile.GetValue(ExifTag.ImageWidth); - if (width == null) - { - TiffThrowHelper.ThrowImageFormatException("The TIFF image is missing the ImageWidth"); - } - - return width.Value; - } - } - - /// - /// Gets the number of rows of pixels in the image. - /// - public Number Height - { - get - { - IExifValue height = this.ExifProfile.GetValue(ExifTag.ImageLength); - if (height == null) - { - TiffThrowHelper.ThrowImageFormatException("The TIFF image is missing the ImageLength"); - } - - return height.Value; - } - } - /// /// Gets the number of bits per component. /// @@ -88,7 +46,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff { get { - var bits = this.ExifProfile.GetValue(ExifTag.BitsPerSample)?.Value; + ushort[] bits = this.ExifProfile.GetValue(ExifTag.BitsPerSample)?.Value; if (bits == null) { if (this.PhotometricInterpretation == TiffPhotometricInterpretation.WhiteIsZero @@ -248,23 +206,6 @@ namespace SixLabors.ImageSharp.Formats.Tiff /// public TiffSampleFormat[] SampleFormat => this.ExifProfile.GetValue(ExifTag.SampleFormat)?.Value?.Select(a => (TiffSampleFormat)a).ToArray(); - /// - /// Clears the pure metadata. - /// - public void ClearMetadata() - { - var tags = new List(); - foreach (IExifValue entry in this.ExifProfile.Values) - { - if (IsFormatTag((ExifTagValue)(ushort)entry.Tag)) - { - tags.Add(entry); - } - } - - this.ExifProfile = new ExifProfile(tags, this.ExifProfile.InvalidTags); - } - /// public IDeepCloneable DeepClone() => new TiffFrameMetadata() { ExifProfile = this.ExifProfile.DeepClone() }; diff --git a/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderTests.cs b/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderTests.cs index c2edb9e1cd..4242a73412 100644 --- a/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderTests.cs @@ -39,7 +39,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff { // arrange var tiffEncoder = new TiffEncoder { Mode = mode }; - Image input = new Image(10, 10); + using Image input = new Image(10, 10); using var memStream = new MemoryStream(); // act @@ -62,7 +62,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff { // arrange var tiffEncoder = new TiffEncoder { BitsPerPixel = bitsPerPixel }; - Image input = new Image(10, 10); + using Image input = new Image(10, 10); using var memStream = new MemoryStream(); // act @@ -101,7 +101,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff { // arrange var tiffEncoder = new TiffEncoder { Mode = mode, Compression = compression }; - Image input = new Image(10, 10); + using Image input = new Image(10, 10); using var memStream = new MemoryStream(); // act @@ -331,7 +331,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff { // arrange var tiffEncoder = new TiffEncoder() { Mode = mode, Compression = compression }; - Image input = provider.GetImage(); + using Image input = provider.GetImage(); using var memStream = new MemoryStream(); TiffFrameMetadata inputMeta = input.Frames.RootFrame.Metadata.GetTiffMetadata(); @@ -340,8 +340,9 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff // assert memStream.Position = 0; - var output = Image.Load(Configuration, memStream); + using var output = Image.Load(Configuration, memStream); TiffFrameMetadata meta = output.Frames.RootFrame.Metadata.GetTiffMetadata(); + ImageFrame rootFrame = output.Frames.RootFrame; Assert.True(output.Height > (int)meta.RowsPerStrip); Assert.True(meta.StripOffsets.Length > 1); @@ -359,7 +360,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff { // The difference must be less than one row. int stripBytes = (int)meta.StripByteCounts[i]; - int widthBytes = (meta.BitsPerPixel + 7) / 8 * (int)meta.Width; + int widthBytes = (meta.BitsPerPixel + 7) / 8 * rootFrame.Width; Assert.True((TiffConstants.DefaultStripSize - stripBytes) < widthBytes); } diff --git a/tests/ImageSharp.Tests/Formats/Tiff/TiffMetadataTests.cs b/tests/ImageSharp.Tests/Formats/Tiff/TiffMetadataTests.cs index f501299fdf..5de1ce6e85 100644 --- a/tests/ImageSharp.Tests/Formats/Tiff/TiffMetadataTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tiff/TiffMetadataTests.cs @@ -182,41 +182,42 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff Assert.Equal(10, image.Metadata.HorizontalResolution); Assert.Equal(10, image.Metadata.VerticalResolution); - TiffFrameMetadata frame = image.Frames.RootFrame.Metadata.GetTiffMetadata(); - Assert.Equal(30, frame.ExifProfile.Values.Count); - - Assert.Equal(32u, frame.Width); - Assert.Equal(32u, frame.Height); - Assert.Equal(TiffBitsPerSample.Bit4, frame.BitsPerSample); - Assert.Equal(TiffCompression.Lzw, frame.Compression); - Assert.Equal(TiffPhotometricInterpretation.PaletteColor, frame.PhotometricInterpretation); - Assert.Equal("This is Название", frame.ExifProfile.GetValue(ExifTag.ImageDescription).Value); - Assert.Equal("This is Изготовитель камеры", frame.ExifProfile.GetValue(ExifTag.Make).Value); - Assert.Equal("This is Модель камеры", frame.ExifProfile.GetValue(ExifTag.Model).Value); - Assert.Equal(new Number[] { 8u }, frame.StripOffsets, new NumberComparer()); - Assert.Equal(1, frame.SamplesPerPixel); - Assert.Equal(32u, frame.RowsPerStrip); - Assert.Equal(new Number[] { 297u }, frame.StripByteCounts, new NumberComparer()); - Assert.Equal(PixelResolutionUnit.PixelsPerInch, frame.ResolutionUnit); - Assert.Equal(10, frame.HorizontalResolution); - Assert.Equal(10, frame.VerticalResolution); - Assert.Equal(TiffPlanarConfiguration.Chunky, frame.PlanarConfiguration); - Assert.Equal("IrfanView", frame.ExifProfile.GetValue(ExifTag.Software).Value); - Assert.Null(frame.ExifProfile.GetValue(ExifTag.DateTime)?.Value); - Assert.Equal("This is author1;Author2", frame.ExifProfile.GetValue(ExifTag.Artist).Value); - Assert.Null(frame.ExifProfile.GetValue(ExifTag.HostComputer)?.Value); - Assert.Equal(48, frame.ColorMap.Length); - Assert.Equal(10537, frame.ColorMap[0]); - Assert.Equal(14392, frame.ColorMap[1]); - Assert.Equal(58596, frame.ColorMap[46]); - Assert.Equal(3855, frame.ColorMap[47]); - - Assert.Null(frame.ExtraSamples); - Assert.Equal(TiffPredictor.None, frame.Predictor); - Assert.Null(frame.SampleFormat); - Assert.Equal("This is Авторские права", frame.ExifProfile.GetValue(ExifTag.Copyright).Value); - Assert.Equal(4, frame.ExifProfile.GetValue(ExifTag.Rating).Value); - Assert.Equal(75, frame.ExifProfile.GetValue(ExifTag.RatingPercent).Value); + TiffFrameMetadata frameMetadata = image.Frames.RootFrame.Metadata.GetTiffMetadata(); + ImageFrame rootFrame = image.Frames.RootFrame; + Assert.Equal(30, frameMetadata.ExifProfile.Values.Count); + + Assert.Equal(32, rootFrame.Width); + Assert.Equal(32, rootFrame.Height); + Assert.Equal(TiffBitsPerSample.Bit4, frameMetadata.BitsPerSample); + Assert.Equal(TiffCompression.Lzw, frameMetadata.Compression); + Assert.Equal(TiffPhotometricInterpretation.PaletteColor, frameMetadata.PhotometricInterpretation); + Assert.Equal("This is Название", frameMetadata.ExifProfile.GetValue(ExifTag.ImageDescription).Value); + Assert.Equal("This is Изготовитель камеры", frameMetadata.ExifProfile.GetValue(ExifTag.Make).Value); + Assert.Equal("This is Модель камеры", frameMetadata.ExifProfile.GetValue(ExifTag.Model).Value); + Assert.Equal(new Number[] { 8u }, frameMetadata.StripOffsets, new NumberComparer()); + Assert.Equal(1, frameMetadata.SamplesPerPixel); + Assert.Equal(32u, frameMetadata.RowsPerStrip); + Assert.Equal(new Number[] { 297u }, frameMetadata.StripByteCounts, new NumberComparer()); + Assert.Equal(PixelResolutionUnit.PixelsPerInch, frameMetadata.ResolutionUnit); + Assert.Equal(10, frameMetadata.HorizontalResolution); + Assert.Equal(10, frameMetadata.VerticalResolution); + Assert.Equal(TiffPlanarConfiguration.Chunky, frameMetadata.PlanarConfiguration); + Assert.Equal("IrfanView", frameMetadata.ExifProfile.GetValue(ExifTag.Software).Value); + Assert.Null(frameMetadata.ExifProfile.GetValue(ExifTag.DateTime)?.Value); + Assert.Equal("This is author1;Author2", frameMetadata.ExifProfile.GetValue(ExifTag.Artist).Value); + Assert.Null(frameMetadata.ExifProfile.GetValue(ExifTag.HostComputer)?.Value); + Assert.Equal(48, frameMetadata.ColorMap.Length); + Assert.Equal(10537, frameMetadata.ColorMap[0]); + Assert.Equal(14392, frameMetadata.ColorMap[1]); + Assert.Equal(58596, frameMetadata.ColorMap[46]); + Assert.Equal(3855, frameMetadata.ColorMap[47]); + + Assert.Null(frameMetadata.ExtraSamples); + Assert.Equal(TiffPredictor.None, frameMetadata.Predictor); + Assert.Null(frameMetadata.SampleFormat); + Assert.Equal("This is Авторские права", frameMetadata.ExifProfile.GetValue(ExifTag.Copyright).Value); + Assert.Equal(4, frameMetadata.ExifProfile.GetValue(ExifTag.Rating).Value); + Assert.Equal(75, frameMetadata.ExifProfile.GetValue(ExifTag.RatingPercent).Value); } } @@ -232,17 +233,17 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff Assert.Equal(2, image.Frames.Count); - TiffFrameMetadata frame0 = image.Frames[0].Metadata.GetTiffMetadata(); - Assert.Equal(TiffNewSubfileType.FullImage, frame0.SubfileType); - Assert.Null(frame0.OldSubfileType); - Assert.Equal(255u, frame0.Width); - Assert.Equal(255u, frame0.Height); - - TiffFrameMetadata frame1 = image.Frames[1].Metadata.GetTiffMetadata(); - Assert.Equal(TiffNewSubfileType.Preview, frame1.SubfileType); - Assert.Null(frame1.OldSubfileType); - Assert.Equal(255u, frame1.Width); - Assert.Equal(255u, frame1.Height); + TiffFrameMetadata frame0MetaData = image.Frames[0].Metadata.GetTiffMetadata(); + Assert.Equal(TiffNewSubfileType.FullImage, frame0MetaData.SubfileType); + Assert.Null(frame0MetaData.OldSubfileType); + Assert.Equal(255, image.Frames[0].Width); + Assert.Equal(255, image.Frames[0].Height); + + TiffFrameMetadata frame1MetaData = image.Frames[1].Metadata.GetTiffMetadata(); + Assert.Equal(TiffNewSubfileType.Preview, frame1MetaData.SubfileType); + Assert.Null(frame1MetaData.OldSubfileType); + Assert.Equal(255, image.Frames[1].Width); + Assert.Equal(255, image.Frames[1].Height); } } @@ -258,6 +259,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff ImageMetadata coreMeta = image.Metadata; TiffMetadata tiffMeta = image.Metadata.GetTiffMetadata(); TiffFrameMetadata frameMeta = image.Frames.RootFrame.Metadata.GetTiffMetadata(); + ImageFrame frameRoot = image.Frames.RootFrame; // Save to Tiff var tiffEncoder = new TiffEncoder() { Mode = TiffEncodingMode.Rgb }; @@ -276,6 +278,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff ImageMetadata coreMetaOut = output.Metadata; TiffMetadata tiffMetaOut = output.Metadata.GetTiffMetadata(); TiffFrameMetadata frameMetaOut = output.Frames.RootFrame.Metadata.GetTiffMetadata(); + ImageFrame rootFrameOut = output.Frames.RootFrame; Assert.Equal(TiffBitsPerPixel.Bit4, tiffMeta.BitsPerPixel); Assert.Equal(TiffBitsPerPixel.Bit24, tiffMetaOut.BitsPerPixel); @@ -286,8 +289,8 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff Assert.Equal(coreMeta.VerticalResolution, coreMetaOut.VerticalResolution); Assert.Equal(coreMeta.ResolutionUnits, coreMetaOut.ResolutionUnits); - Assert.Equal(frameMeta.Width, frameMetaOut.Width); - Assert.Equal(frameMeta.Height, frameMetaOut.Height); + Assert.Equal(frameRoot.Width, rootFrameOut.Width); + Assert.Equal(frameRoot.Height, rootFrameOut.Height); Assert.Equal(frameMeta.ResolutionUnit, frameMetaOut.ResolutionUnit); Assert.Equal(frameMeta.HorizontalResolution, frameMetaOut.HorizontalResolution); Assert.Equal(frameMeta.VerticalResolution, frameMetaOut.VerticalResolution); @@ -364,7 +367,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff // Assert ms.Position = 0; using var output = Image.Load(this.configuration, ms); - TiffMetadata meta = output.Metadata.GetTiffMetadata(); + ImageFrame rootFrameOut = output.Frames.RootFrame; ImageMetadata coreMetaOut = output.Metadata; TiffMetadata tiffMetaOut = output.Metadata.GetTiffMetadata(); @@ -377,8 +380,8 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff //// Assert.Equal(tiffEncoder.Compression, tiffMetaOut.Compression); Assert.Equal(TiffBitsPerPixel.Bit24, tiffMetaOut.BitsPerPixel); - Assert.Equal((uint)w, frameMetaOut.Width); - Assert.Equal((uint)h, frameMetaOut.Height); + Assert.Equal(w, rootFrameOut.Width); + Assert.Equal(h, rootFrameOut.Height); Assert.Equal(frameMeta.ResolutionUnit, frameMetaOut.ResolutionUnit); Assert.Equal(frameMeta.HorizontalResolution, frameMetaOut.HorizontalResolution); Assert.Equal(frameMeta.VerticalResolution, frameMetaOut.VerticalResolution); @@ -427,7 +430,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff tiffMeta.XmpProfile = null; - frameMeta.ClearMetadata(); + frameMeta.ExifProfile = null; } } }