diff --git a/src/ImageSharp/Formats/Tiff/MetadataExtensions.cs b/src/ImageSharp/Formats/Tiff/MetadataExtensions.cs index c1cd3b1533..b9da86fc44 100644 --- a/src/ImageSharp/Formats/Tiff/MetadataExtensions.cs +++ b/src/ImageSharp/Formats/Tiff/MetadataExtensions.cs @@ -17,5 +17,12 @@ namespace SixLabors.ImageSharp /// The metadata this method extends. /// The . public static TiffMetadata GetTiffMetadata(this ImageMetadata metadata) => metadata.GetFormatMetadata(TiffFormat.Instance); + + /// + /// Gets the tiff format specific metadata for the image frame. + /// + /// The metadata this method extends. + /// The . + public static TiffFrameMetadata GetTiffMetadata(this ImageFrameMetadata metadata) => metadata.GetFormatMetadata(TiffFormat.Instance); } } diff --git a/src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs b/src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs index b977c25365..b7b7640072 100644 --- a/src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs +++ b/src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs @@ -110,15 +110,13 @@ namespace SixLabors.ImageSharp.Formats.Tiff IEnumerable directories = reader.Read(); var frames = new List>(); - var tiffFramesMataData = new List(); foreach (ExifProfile ifd in directories) { - ImageFrame frame = this.DecodeFrame(ifd, out TiffFrameMetadata frameMetadata); + ImageFrame frame = this.DecodeFrame(ifd); frames.Add(frame); - tiffFramesMataData.Add(frameMetadata); } - ImageMetadata metadata = TiffDecoderMetadataCreator.Create(frames, tiffFramesMataData, this.ignoreMetadata, reader.ByteOrder); + ImageMetadata metadata = TiffDecoderMetadataCreator.Create(frames, this.ignoreMetadata, reader.ByteOrder); // TODO: Tiff frames can have different sizes ImageFrame root = frames[0]; @@ -139,24 +137,16 @@ namespace SixLabors.ImageSharp.Formats.Tiff { this.inputStream = stream; var reader = new DirectoryReader(stream); - IEnumerable directories = reader.Read(); - var framesMetadata = new List(); - foreach (ExifProfile ifd in directories) - { - var meta = new TiffFrameMetadata(ifd); - meta.Initialize(ifd); - framesMetadata.Add(meta); - } - - TiffFrameMetadata root = framesMetadata[0]; ExifProfile rootFrameExifProfile = directories.First(); - ImageMetadata metadata = TiffDecoderMetadataCreator.Create(framesMetadata, reader.ByteOrder, rootFrameExifProfile); + var rootMetadata = TiffFrameMetadata.Parse(rootFrameExifProfile); + + ImageMetadata metadata = TiffDecoderMetadataCreator.Create(reader.ByteOrder, rootFrameExifProfile); int width = GetImageWidth(rootFrameExifProfile); int height = GetImageHeight(rootFrameExifProfile); - return new ImageInfo(new PixelTypeInfo((int)root.BitsPerPixel), width, height, metadata); + return new ImageInfo(new PixelTypeInfo((int)rootMetadata.BitsPerPixel), width, height, metadata); } /// @@ -164,17 +154,18 @@ namespace SixLabors.ImageSharp.Formats.Tiff /// /// The pixel format. /// The IFD tags. - /// The tiff frame metadata. /// /// The tiff frame. /// - private ImageFrame DecodeFrame(ExifProfile tags, out TiffFrameMetadata tiffFrameMetaData) + private ImageFrame DecodeFrame(ExifProfile tags) where TPixel : unmanaged, IPixel { ImageFrameMetadata imageFrameMetaData = this.ignoreMetadata ? new ImageFrameMetadata() : new ImageFrameMetadata { ExifProfile = tags, XmpProfile = tags.GetValue(ExifTag.XMP)?.Value }; - tiffFrameMetaData = new TiffFrameMetadata(tags); + + TiffFrameMetadata tiffFrameMetaData = imageFrameMetaData.GetTiffMetadata(); + TiffFrameMetadata.Parse(tiffFrameMetaData, tags); this.VerifyAndParse(tags, tiffFrameMetaData); @@ -220,9 +211,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff } int bytesPerRow = ((width * bitsPerPixel) + 7) / 8; - int stripBytes = bytesPerRow * height; - - return stripBytes; + return bytesPerRow * height; } /// diff --git a/src/ImageSharp/Formats/Tiff/TiffDecoderMetadataCreator.cs b/src/ImageSharp/Formats/Tiff/TiffDecoderMetadataCreator.cs index 95d931b0e2..6f8a81a827 100644 --- a/src/ImageSharp/Formats/Tiff/TiffDecoderMetadataCreator.cs +++ b/src/ImageSharp/Formats/Tiff/TiffDecoderMetadataCreator.cs @@ -18,12 +18,10 @@ namespace SixLabors.ImageSharp.Formats.Tiff /// internal static class TiffDecoderMetadataCreator { - public static ImageMetadata Create(List> frames, List framesMetaData, bool ignoreMetadata, ByteOrder byteOrder) + public static ImageMetadata Create(List> frames, bool ignoreMetadata, ByteOrder byteOrder) where TPixel : unmanaged, IPixel { - DebugGuard.IsTrue(frames.Count == framesMetaData.Count, nameof(frames), "Image frames and frames metadata should be the same size."); - - if (framesMetaData.Count < 1) + if (frames.Count < 1) { TiffThrowHelper.ThrowImageFormatException("Expected at least one frame."); } @@ -58,13 +56,8 @@ namespace SixLabors.ImageSharp.Formats.Tiff return imageMetaData; } - public static ImageMetadata Create(List framesMetaData, ByteOrder byteOrder, ExifProfile exifProfile) + public static ImageMetadata Create(ByteOrder byteOrder, ExifProfile exifProfile) { - if (framesMetaData.Count < 1) - { - TiffThrowHelper.ThrowImageFormatException("Expected at least one frame."); - } - var imageMetaData = new ImageMetadata(); SetResolution(imageMetaData, exifProfile); diff --git a/src/ImageSharp/Formats/Tiff/TiffEncoderCore.cs b/src/ImageSharp/Formats/Tiff/TiffEncoderCore.cs index f930b3c9e2..055def11d5 100644 --- a/src/ImageSharp/Formats/Tiff/TiffEncoderCore.cs +++ b/src/ImageSharp/Formats/Tiff/TiffEncoderCore.cs @@ -12,7 +12,6 @@ using SixLabors.ImageSharp.Formats.Tiff.Compression; using SixLabors.ImageSharp.Formats.Tiff.Constants; using SixLabors.ImageSharp.Formats.Tiff.Writers; using SixLabors.ImageSharp.Memory; -using SixLabors.ImageSharp.Metadata; using SixLabors.ImageSharp.Metadata.Profiles.Exif; using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.Processing; @@ -110,18 +109,19 @@ namespace SixLabors.ImageSharp.Formats.Tiff Guard.NotNull(stream, nameof(stream)); this.configuration = image.GetConfiguration(); - ExifProfile rootFrameExifProfile = image.Frames.RootFrame.Metadata.ExifProfile; + TiffPhotometricInterpretation rootFramePhotometricInterpretation = GetRootFramePhotometricInterpretation(image); TiffPhotometricInterpretation photometricInterpretation = this.Mode == TiffEncodingMode.ColorPalette - ? TiffPhotometricInterpretation.PaletteColor : rootFramePhotometricInterpretation; - TiffBitsPerPixel? rootFrameBitsPerPixel = null; - if (rootFrameExifProfile != null) - { - rootFrameBitsPerPixel = new TiffFrameMetadata(rootFrameExifProfile).BitsPerPixel; - } + ? TiffPhotometricInterpretation.PaletteColor + : rootFramePhotometricInterpretation; - this.SetMode(rootFrameBitsPerPixel, photometricInterpretation); + TiffBitsPerPixel? rootFrameBitsPerPixel = image.Frames.RootFrame.Metadata.GetTiffMetadata().BitsPerPixel; + + // TODO: This isn't correct. + // We're overwriting explicit BPP based upon the Mode. It should be the other way around. + // BPP should also be nullable and based upon the current TPixel if not set. this.SetBitsPerPixel(rootFrameBitsPerPixel); + this.SetMode(photometricInterpretation); this.SetPhotometricInterpretation(); using (var writer = new TiffStreamWriter(stream)) @@ -144,9 +144,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff { writer.Write(ByteOrderMarker); writer.Write(TiffConstants.HeaderMagicNumber); - long firstIfdMarker = writer.PlaceMarker(); - - return firstIfdMarker; + return writer.PlaceMarker(); } /// @@ -206,7 +204,17 @@ namespace SixLabors.ImageSharp.Formats.Tiff int rowsPerStrip = TiffConstants.DefaultStripSize / bytesPerRow; - return rowsPerStrip > 0 ? (rowsPerStrip < height ? rowsPerStrip : height) : 1; + if (rowsPerStrip > 0) + { + if (rowsPerStrip < height) + { + return rowsPerStrip; + } + + return height; + } + + return 1; } /// @@ -219,6 +227,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff { if (entries.Count == 0) { + // TODO: Perf. Throwhelper throw new ArgumentException("There must be at least one entry per IFD.", nameof(entries)); } @@ -268,7 +277,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff return nextIfdMarker; } - private void SetMode(TiffBitsPerPixel? rootFrameBitsPerPixel, TiffPhotometricInterpretation photometricInterpretation) + private void SetMode(TiffPhotometricInterpretation photometricInterpretation) { // Make sure, that the fax compressions are only used together with the BiColor mode. if (this.CompressionType == TiffCompression.CcittGroup3Fax || this.CompressionType == TiffCompression.Ccitt1D) @@ -286,19 +295,8 @@ namespace SixLabors.ImageSharp.Formats.Tiff } } - if (this.Mode == TiffEncodingMode.Default && rootFrameBitsPerPixel.HasValue) - { - // Preserve input bits per pixel, if no encoding mode was specified and the input image has a bits per pixel set. - this.SetModeWithBitsPerPixel(rootFrameBitsPerPixel, photometricInterpretation); - - return; - } - - if (this.BitsPerPixel != null) - { - // The user has specified a bits per pixel, so use that to determine the encoding mode. - this.SetModeWithBitsPerPixel(this.BitsPerPixel, photometricInterpretation); - } + // Use the bits per pixel to determine the encoding mode. + this.SetModeWithBitsPerPixel(this.BitsPerPixel, photometricInterpretation); } private void SetModeWithBitsPerPixel(TiffBitsPerPixel? bitsPerPixel, TiffPhotometricInterpretation photometricInterpretation) @@ -383,11 +381,9 @@ namespace SixLabors.ImageSharp.Formats.Tiff private static TiffPhotometricInterpretation GetRootFramePhotometricInterpretation(Image image) { ExifProfile exifProfile = image.Frames.RootFrame.Metadata.ExifProfile; - TiffPhotometricInterpretation rootFramePhotometricInterpretation = - exifProfile?.GetValue(ExifTag.PhotometricInterpretation) != null - ? (TiffPhotometricInterpretation)exifProfile?.GetValue(ExifTag.PhotometricInterpretation).Value - : TiffPhotometricInterpretation.WhiteIsZero; - return rootFramePhotometricInterpretation; + return exifProfile?.GetValue(ExifTag.PhotometricInterpretation) != null + ? (TiffPhotometricInterpretation)exifProfile?.GetValue(ExifTag.PhotometricInterpretation).Value + : TiffPhotometricInterpretation.WhiteIsZero; } } } diff --git a/src/ImageSharp/Formats/Tiff/TiffFormat.cs b/src/ImageSharp/Formats/Tiff/TiffFormat.cs index bf0c4ebb18..2217ffb7f7 100644 --- a/src/ImageSharp/Formats/Tiff/TiffFormat.cs +++ b/src/ImageSharp/Formats/Tiff/TiffFormat.cs @@ -10,7 +10,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff /// /// Encapsulates the means to encode and decode Tiff images. /// - public class TiffFormat : IImageFormat + public sealed class TiffFormat : IImageFormat { private TiffFormat() { @@ -35,5 +35,8 @@ namespace SixLabors.ImageSharp.Formats.Tiff /// public TiffMetadata CreateDefaultFormatMetadata() => new TiffMetadata(); + + /// + public TiffFrameMetadata CreateDefaultFormatFrameMetadata() => new TiffFrameMetadata(); } } diff --git a/src/ImageSharp/Formats/Tiff/TiffFrameMetadata.cs b/src/ImageSharp/Formats/Tiff/TiffFrameMetadata.cs index 7376b114b6..3594ec388d 100644 --- a/src/ImageSharp/Formats/Tiff/TiffFrameMetadata.cs +++ b/src/ImageSharp/Formats/Tiff/TiffFrameMetadata.cs @@ -9,7 +9,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff /// /// Provides Tiff specific metadata information for the frame. /// - internal class TiffFrameMetadata : IDeepCloneable + public class TiffFrameMetadata : IDeepCloneable { /// /// Initializes a new instance of the class. @@ -18,11 +18,11 @@ namespace SixLabors.ImageSharp.Formats.Tiff { } - /// - /// Initializes a new instance of the class. - /// - /// The Tiff frame directory tags. - public TiffFrameMetadata(ExifProfile frameTags) => this.Initialize(frameTags ?? new ExifProfile()); + private TiffFrameMetadata(TiffFrameMetadata other) + { + this.BitsPerSample = other.BitsPerSample; + this.BitsPerPixel = other.BitsPerPixel; + } /// /// Gets or sets the number of bits per component. @@ -35,42 +35,54 @@ namespace SixLabors.ImageSharp.Formats.Tiff public TiffBitsPerPixel BitsPerPixel { get; set; } /// - /// Initializes a new instance of the class with a given ExifProfile. + /// Returns a new instance parsed from the given Exif profile. /// - /// The Tiff frame directory tags. - public void Initialize(ExifProfile frameTags) + /// The Exif profile containing tiff frame directory tags to parse. + /// If null, a new instance is created and parsed instead. + /// The . + internal static TiffFrameMetadata Parse(ExifProfile profile) { - TiffPhotometricInterpretation photometricInterpretation = frameTags.GetValue(ExifTag.PhotometricInterpretation) != null ? - (TiffPhotometricInterpretation)frameTags.GetValue(ExifTag.PhotometricInterpretation).Value : TiffPhotometricInterpretation.WhiteIsZero; + var meta = new TiffFrameMetadata(); + Parse(meta, profile); + return meta; + } - ushort[] bits = frameTags.GetValue(ExifTag.BitsPerSample)?.Value; + /// + /// Parses the given Exif profile to populate the properties of the tiff frame meta data.. + /// + /// The tiff frame meta data. + /// The Exif profile containing tiff frame directory tags. + internal static void Parse(TiffFrameMetadata meta, ExifProfile profile) + { + if (profile is null) + { + profile = new ExifProfile(); + } + + TiffPhotometricInterpretation photometricInterpretation = profile.GetValue(ExifTag.PhotometricInterpretation) != null + ? (TiffPhotometricInterpretation)profile.GetValue(ExifTag.PhotometricInterpretation).Value + : TiffPhotometricInterpretation.WhiteIsZero; + + ushort[] bits = profile.GetValue(ExifTag.BitsPerSample)?.Value; if (bits == null) { - if (photometricInterpretation == TiffPhotometricInterpretation.WhiteIsZero || photometricInterpretation == TiffPhotometricInterpretation.BlackIsZero) + if (photometricInterpretation == TiffPhotometricInterpretation.WhiteIsZero + || photometricInterpretation == TiffPhotometricInterpretation.BlackIsZero) { - this.BitsPerSample = TiffBitsPerSample.Bit1; + meta.BitsPerSample = TiffBitsPerSample.Bit1; } - this.BitsPerSample = null; + meta.BitsPerSample = null; } else { - this.BitsPerSample = bits.GetBitsPerSample(); + meta.BitsPerSample = bits.GetBitsPerSample(); } - this.BitsPerPixel = (TiffBitsPerPixel)this.BitsPerSample.GetValueOrDefault().BitsPerPixel(); + meta.BitsPerPixel = (TiffBitsPerPixel)meta.BitsPerSample.GetValueOrDefault().BitsPerPixel(); } /// - public IDeepCloneable DeepClone() - { - var clone = new TiffFrameMetadata - { - BitsPerSample = this.BitsPerSample, - BitsPerPixel = this.BitsPerPixel - }; - - return clone; - } + public IDeepCloneable DeepClone() => new TiffFrameMetadata(this); } } diff --git a/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderTests.cs b/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderTests.cs index 2fdc663478..619c1b5c29 100644 --- a/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderTests.cs @@ -50,7 +50,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff memStream.Position = 0; using var output = Image.Load(Configuration, memStream); ExifProfile exifProfile = output.Frames.RootFrame.Metadata.ExifProfile; - var frameMetaData = new TiffFrameMetadata(exifProfile); + var frameMetaData = TiffFrameMetadata.Parse(exifProfile); Assert.Equal(expectedBitsPerPixel, frameMetaData.BitsPerPixel); Assert.Equal(TiffCompression.None, (TiffCompression)exifProfile.GetValue(ExifTag.Compression).Value); } @@ -73,8 +73,9 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff // assert memStream.Position = 0; using var output = Image.Load(Configuration, memStream); + ExifProfile exifProfile = output.Frames.RootFrame.Metadata.ExifProfile; - var frameMetaData = new TiffFrameMetadata(exifProfile); + TiffFrameMetadata frameMetaData = output.Frames.RootFrame.Metadata.GetTiffMetadata(); Assert.Equal(bitsPerPixel, frameMetaData.BitsPerPixel); Assert.Equal(TiffCompression.None, (TiffCompression)exifProfile.GetValue(ExifTag.Compression).Value); } @@ -114,7 +115,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff memStream.Position = 0; using var output = Image.Load(Configuration, memStream); ExifProfile exifProfile = output.Frames.RootFrame.Metadata.ExifProfile; - var frameMetaData = new TiffFrameMetadata(exifProfile); + var frameMetaData = TiffFrameMetadata.Parse(exifProfile); Assert.Equal(expectedBitsPerPixel, frameMetaData.BitsPerPixel); Assert.Equal(expectedCompression, (TiffCompression)exifProfile.GetValue(ExifTag.Compression).Value); } @@ -141,7 +142,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff memStream.Position = 0; using var output = Image.Load(Configuration, memStream); ExifProfile exifProfile = output.Frames.RootFrame.Metadata.ExifProfile; - var frameMetaData = new TiffFrameMetadata(exifProfile); + var frameMetaData = TiffFrameMetadata.Parse(exifProfile); Assert.Equal(expectedBitsPerPixel, frameMetaData.BitsPerPixel); } @@ -165,7 +166,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff memStream.Position = 0; using var output = Image.Load(Configuration, memStream); ExifProfile exifProfile = output.Frames.RootFrame.Metadata.ExifProfile; - var frameMetaData = new TiffFrameMetadata(exifProfile); + var frameMetaData = TiffFrameMetadata.Parse(exifProfile); Assert.Equal(TiffBitsPerPixel.Bit1, frameMetaData.BitsPerPixel); Assert.Equal(expectedCompression, (TiffCompression)exifProfile.GetValue(ExifTag.Compression).Value); } @@ -341,7 +342,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff using var memStream = new MemoryStream(); ExifProfile exifProfileInput = input.Frames.RootFrame.Metadata.ExifProfile; var inputCompression = (TiffCompression)exifProfileInput.GetValue(ExifTag.Compression).Value; - var inputMeta = new TiffFrameMetadata(exifProfileInput); + var inputMeta = TiffFrameMetadata.Parse(exifProfileInput); // act input.Save(memStream, tiffEncoder); @@ -350,7 +351,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff memStream.Position = 0; using var output = Image.Load(Configuration, memStream); ExifProfile exifProfileOutput = output.Frames.RootFrame.Metadata.ExifProfile; - var outputMeta = new TiffFrameMetadata(exifProfileOutput); + var outputMeta = TiffFrameMetadata.Parse(exifProfileOutput); ImageFrame rootFrame = output.Frames.RootFrame; Number rowsPerStrip = exifProfileOutput.GetValue(ExifTag.RowsPerStrip) != null ? exifProfileOutput.GetValue(ExifTag.RowsPerStrip).Value : TiffConstants.RowsPerStripInfinity; diff --git a/tests/ImageSharp.Tests/Formats/Tiff/TiffMetadataTests.cs b/tests/ImageSharp.Tests/Formats/Tiff/TiffMetadataTests.cs index 3a6dea9aa5..662c7c1f33 100644 --- a/tests/ImageSharp.Tests/Formats/Tiff/TiffMetadataTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tiff/TiffMetadataTests.cs @@ -53,7 +53,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff using (Image image = provider.GetImage(TiffDecoder)) { ExifProfile exifProfile = image.Frames.RootFrame.Metadata.ExifProfile; - var meta = new TiffFrameMetadata(exifProfile); + var meta = TiffFrameMetadata.Parse(exifProfile); var cloneSameAsSampleMetaData = (TiffFrameMetadata)meta.DeepClone(); Assert.NotNull(cloneSameAsSampleMetaData); Assert.Equal(TiffBitsPerSample.Bit4, cloneSameAsSampleMetaData.BitsPerSample); @@ -196,10 +196,10 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff Assert.NotNull(tiffMetaData); Assert.Equal(ByteOrder.LittleEndian, tiffMetaData.ByteOrder); - var frameMetaData = new TiffFrameMetadata(exifProfile); + var frameMetaData = TiffFrameMetadata.Parse(exifProfile); Assert.Equal(TiffBitsPerPixel.Bit4, frameMetaData.BitsPerPixel); - var tiffFrameMetadata = new TiffFrameMetadata(exifProfile); + var tiffFrameMetadata = TiffFrameMetadata.Parse(exifProfile); Assert.NotNull(frameMetaData); Assert.Equal(TiffBitsPerSample.Bit4, frameMetaData.BitsPerSample); } @@ -238,7 +238,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff using Image image = provider.GetImage(new TiffDecoder() { IgnoreMetadata = false }); ImageMetadata inputMetaData = image.Metadata; - var frameMetaInput = new TiffFrameMetadata(image.Frames.RootFrame.Metadata.ExifProfile); + var frameMetaInput = TiffFrameMetadata.Parse(image.Frames.RootFrame.Metadata.ExifProfile); ImageFrame rootFrameInput = image.Frames.RootFrame; byte[] xmpProfileInput = rootFrameInput.Metadata.XmpProfile; ExifProfile exifProfileInput = rootFrameInput.Metadata.ExifProfile; @@ -257,7 +257,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff ImageMetadata encodedImageMetaData = encodedImage.Metadata; ImageFrame rootFrameEncodedImage = encodedImage.Frames.RootFrame; - var tiffMetaDataEncodedRootFrame = new TiffFrameMetadata(rootFrameEncodedImage.Metadata.ExifProfile); + var tiffMetaDataEncodedRootFrame = TiffFrameMetadata.Parse(rootFrameEncodedImage.Metadata.ExifProfile); ExifProfile encodedImageExifProfile = rootFrameEncodedImage.Metadata.ExifProfile; byte[] encodedImageXmpProfile = rootFrameEncodedImage.Metadata.XmpProfile;