diff --git a/src/ImageSharp/Formats/AnimatedImageFrameMetadata.cs b/src/ImageSharp/Formats/AnimatedImageFrameMetadata.cs index 75595e1f7d..8f8e187403 100644 --- a/src/ImageSharp/Formats/AnimatedImageFrameMetadata.cs +++ b/src/ImageSharp/Formats/AnimatedImageFrameMetadata.cs @@ -30,65 +30,3 @@ internal class AnimatedImageFrameMetadata /// public FrameDisposalMode DisposalMode { get; set; } } - -#pragma warning disable SA1201 // Elements should appear in the correct order -internal enum FrameBlendMode -#pragma warning restore SA1201 // Elements should appear in the correct order -{ - /// - /// Do not blend. Render the current frame on the canvas by overwriting the rectangle covered by the current frame. - /// - Source = 0, - - /// - /// Blend the current frame with the previous frame in the animation sequence within the rectangle covered - /// by the current frame. - /// If the current has any transparent areas, the corresponding areas of the previous frame will be visible - /// through these transparent regions. - /// - Over = 1 -} - -internal enum FrameDisposalMode -{ - /// - /// No disposal specified. - /// The decoder is not required to take any action. - /// - Unspecified = 0, - - /// - /// Do not dispose. The current frame is not disposed of, or in other words, not cleared or altered when moving to - /// the next frame. This means that the next frame is drawn over the current frame, and if the next frame contains - /// transparency, the previous frame will be visible through these transparent areas. - /// - DoNotDispose = 1, - - /// - /// Restore to background color. When transitioning to the next frame, the area occupied by the current frame is - /// filled with the background color specified in the image metadata. - /// This effectively erases the current frame by replacing it with the background color before the next frame is displayed. - /// - RestoreToBackground = 2, - - /// - /// Restore to previous. This method restores the area affected by the current frame to what it was before the - /// current frame was displayed. It essentially "undoes" the current frame, reverting to the state of the image - /// before the frame was displayed, then the next frame is drawn. This is useful for animations where only a small - /// part of the image changes from frame to frame. - /// - RestoreToPrevious = 3 -} - -internal enum FrameColorTableMode -{ - /// - /// The frame uses the shared color table specified by the image metadata. - /// - Global, - - /// - /// The frame uses a color table specified by the frame metadata. - /// - Local -} diff --git a/src/ImageSharp/Formats/FormatConnectingFrameMetadata.cs b/src/ImageSharp/Formats/FormatConnectingFrameMetadata.cs new file mode 100644 index 0000000000..31555afe34 --- /dev/null +++ b/src/ImageSharp/Formats/FormatConnectingFrameMetadata.cs @@ -0,0 +1,35 @@ +// Copyright (c) Six Labors. +// Licensed under the Six Labors Split License. + +namespace SixLabors.ImageSharp.Formats; + +/// +/// A metadata format designed to allow conversion between different image format frames. +/// +public class FormatConnectingFrameMetadata +{ + /// + /// Gets or sets the frame color table. + /// + public ReadOnlyMemory? ColorTable { get; set; } + + /// + /// Gets or sets the frame color table mode. + /// + public FrameColorTableMode ColorTableMode { get; set; } + + /// + /// Gets or sets the duration of the frame. + /// + public TimeSpan Duration { get; set; } + + /// + /// Gets or sets the frame alpha blending mode. + /// + public FrameBlendMode BlendMode { get; set; } + + /// + /// Gets or sets the frame disposal mode. + /// + public FrameDisposalMode DisposalMode { get; set; } +} diff --git a/src/ImageSharp/Formats/FormatConnectingMetadata.cs b/src/ImageSharp/Formats/FormatConnectingMetadata.cs new file mode 100644 index 0000000000..a7030b4642 --- /dev/null +++ b/src/ImageSharp/Formats/FormatConnectingMetadata.cs @@ -0,0 +1,65 @@ +// Copyright (c) Six Labors. +// Licensed under the Six Labors Split License. + +using SixLabors.ImageSharp.PixelFormats; + +namespace SixLabors.ImageSharp.Formats; + +/// +/// A metadata format designed to allow conversion between different image formats. +/// +public class FormatConnectingMetadata +{ + /// + /// Gets the quality. + /// + /// + /// The value is usually between 1 and 100. Defaults to 100. + /// + public int Quality { get; init; } = 100; + + /// + /// Gets information about the encoded pixel type. + /// + public PixelTypeInfo PixelTypeInfo { get; init; } + + /// + /// Gets the shared color table. + /// + public ReadOnlyMemory? ColorTable { get; init; } + + /// + /// Gets the shared color table mode. + /// + /// + /// Defaults to . + /// + public FrameColorTableMode ColorTableMode { get; init; } + + /// + /// Gets the default background color of the canvas when animating. + /// This color may be used to fill the unused space on the canvas around the frames, + /// as well as the transparent pixels of the first frame. + /// The background color is also used when the disposal mode is . + /// + /// + /// Defaults to . + /// + public Color BackgroundColor { get; init; } = Color.Transparent; + + /// + /// Gets the number of times any animation is repeated. + /// + /// + /// 0 means to repeat indefinitely, count is set as repeat n-1 times. Defaults to 1. + /// + public ushort RepeatCount { get; init; } = 1; + + /// + /// Gets a value indicating whether the root frame is shown as part of the animated sequence. + /// + /// + /// Defaults to . + /// + public bool AnimateRootFrame { get; init; } = true; +} diff --git a/src/ImageSharp/Formats/FrameBlendMode.cs b/src/ImageSharp/Formats/FrameBlendMode.cs new file mode 100644 index 0000000000..5785324e5a --- /dev/null +++ b/src/ImageSharp/Formats/FrameBlendMode.cs @@ -0,0 +1,23 @@ +// Copyright (c) Six Labors. +// Licensed under the Six Labors Split License. + +namespace SixLabors.ImageSharp.Formats; + +/// +/// Provides a way to specify how the current frame should be blended with the previous frame in the animation sequence. +/// +public enum FrameBlendMode +{ + /// + /// Do not blend. Render the current frame on the canvas by overwriting the rectangle covered by the current frame. + /// + Source = 0, + + /// + /// Blend the current frame with the previous frame in the animation sequence within the rectangle covered + /// by the current frame. + /// If the current has any transparent areas, the corresponding areas of the previous frame will be visible + /// through these transparent regions. + /// + Over = 1 +} diff --git a/src/ImageSharp/Formats/FrameColorTableMode.cs b/src/ImageSharp/Formats/FrameColorTableMode.cs new file mode 100644 index 0000000000..a45b6de0e4 --- /dev/null +++ b/src/ImageSharp/Formats/FrameColorTableMode.cs @@ -0,0 +1,20 @@ +// Copyright (c) Six Labors. +// Licensed under the Six Labors Split License. + +namespace SixLabors.ImageSharp.Formats; + +/// +/// Provides a way to specify how the color table is used by the frame. +/// +public enum FrameColorTableMode +{ + /// + /// The frame uses the shared color table specified by the image metadata. + /// + Global, + + /// + /// The frame uses a color table specified by the frame metadata. + /// + Local +} diff --git a/src/ImageSharp/Formats/FrameDisposalMode.cs b/src/ImageSharp/Formats/FrameDisposalMode.cs new file mode 100644 index 0000000000..196fdb5ad4 --- /dev/null +++ b/src/ImageSharp/Formats/FrameDisposalMode.cs @@ -0,0 +1,38 @@ +// Copyright (c) Six Labors. +// Licensed under the Six Labors Split License. + +namespace SixLabors.ImageSharp.Formats; + +/// +/// Provides a way to specify how the current frame should be disposed of before rendering the next frame. +/// +public enum FrameDisposalMode +{ + /// + /// No disposal specified. + /// The decoder is not required to take any action. + /// + Unspecified = 0, + + /// + /// Do not dispose. The current frame is not disposed of, or in other words, not cleared or altered when moving to + /// the next frame. This means that the next frame is drawn over the current frame, and if the next frame contains + /// transparency, the previous frame will be visible through these transparent areas. + /// + DoNotDispose = 1, + + /// + /// Restore to background color. When transitioning to the next frame, the area occupied by the current frame is + /// filled with the background color specified in the image metadata. + /// This effectively erases the current frame by replacing it with the background color before the next frame is displayed. + /// + RestoreToBackground = 2, + + /// + /// Restore to previous. This method restores the area affected by the current frame to what it was before the + /// current frame was displayed. It essentially "undoes" the current frame, reverting to the state of the image + /// before the frame was displayed, then the next frame is drawn. This is useful for animations where only a small + /// part of the image changes from frame to frame. + /// + RestoreToPrevious = 3 +} diff --git a/src/ImageSharp/Formats/Gif/GifMetadata.cs b/src/ImageSharp/Formats/Gif/GifMetadata.cs index 1331edee89..7c83de9305 100644 --- a/src/ImageSharp/Formats/Gif/GifMetadata.cs +++ b/src/ImageSharp/Formats/Gif/GifMetadata.cs @@ -67,7 +67,7 @@ public class GifMetadata : IDeepCloneable /// Gets or sets the collection of comments about the graphics, credits, descriptions or any /// other type of non-control and non-graphic data. /// - public IList Comments { get; set; } = new List(); + public IList Comments { get; set; } = []; /// public IDeepCloneable DeepClone() => new GifMetadata(this); diff --git a/src/ImageSharp/Formats/IFormatFrameMetadata.cs b/src/ImageSharp/Formats/IFormatFrameMetadata.cs new file mode 100644 index 0000000000..bd7c6c45b1 --- /dev/null +++ b/src/ImageSharp/Formats/IFormatFrameMetadata.cs @@ -0,0 +1,33 @@ +// Copyright (c) Six Labors. +// Licensed under the Six Labors Split License. + +namespace SixLabors.ImageSharp.Formats; + +/// +/// An interface that provides metadata for a specific image format frames. +/// +public interface IFormatFrameMetadata : IDeepCloneable +{ + /// + /// Converts the metadata to a instance. + /// + /// The . + FormatConnectingFrameMetadata ToFormatConnectingFrameMetadata(); +} + +/// +/// An interface that provides metadata for a specific image format frames. +/// +/// The metadata type implementing this interface. +public interface IFormatFrameMetadata : IFormatMetadata, IDeepCloneable + where TSelf : class, IFormatFrameMetadata, new() +{ + /// + /// Creates a new instance of the class from the given . + /// + /// The . + /// The . +#pragma warning disable CA1000 // Do not declare static members on generic types + static abstract TSelf FromFormatConnectingFrameMetadata(FormatConnectingFrameMetadata metadata); +#pragma warning restore CA1000 // Do not declare static members on generic types +} diff --git a/src/ImageSharp/Formats/IFormatMetadata.cs b/src/ImageSharp/Formats/IFormatMetadata.cs new file mode 100644 index 0000000000..f542f92db3 --- /dev/null +++ b/src/ImageSharp/Formats/IFormatMetadata.cs @@ -0,0 +1,33 @@ +// Copyright (c) Six Labors. +// Licensed under the Six Labors Split License. + +namespace SixLabors.ImageSharp.Formats; + +/// +/// An interface that provides metadata for a specific image format. +/// +public interface IFormatMetadata : IDeepCloneable +{ + /// + /// Converts the metadata to a instance. + /// + /// The . + FormatConnectingMetadata ToFormatConnectingMetadata(); +} + +/// +/// An interface that provides metadata for a specific image format. +/// +/// The metadata type implementing this interface. +public interface IFormatMetadata : IFormatMetadata, IDeepCloneable + where TSelf : class, IFormatMetadata, new() +{ + /// + /// Creates a new instance of the class from the given . + /// + /// The . + /// The . +#pragma warning disable CA1000 // Do not declare static members on generic types + static abstract TSelf FromFormatConnectingMetadata(FormatConnectingMetadata metadata); +#pragma warning restore CA1000 // Do not declare static members on generic types +} diff --git a/src/ImageSharp/Formats/Jpeg/Components/Encoder/HuffmanSpec.cs b/src/ImageSharp/Formats/Jpeg/Components/Encoder/HuffmanSpec.cs index faba3d5afc..f5666f7799 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Encoder/HuffmanSpec.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Encoder/HuffmanSpec.cs @@ -6,7 +6,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder; /// /// The Huffman encoding specifications. /// -public readonly struct HuffmanSpec +internal readonly struct HuffmanSpec { /// /// Huffman talbe specification for luminance DC. diff --git a/src/ImageSharp/Formats/Jpeg/JpegMetadata.cs b/src/ImageSharp/Formats/Jpeg/JpegMetadata.cs index fe1324a862..ce4c0758fd 100644 --- a/src/ImageSharp/Formats/Jpeg/JpegMetadata.cs +++ b/src/ImageSharp/Formats/Jpeg/JpegMetadata.cs @@ -13,10 +13,7 @@ public class JpegMetadata : IDeepCloneable /// /// Initializes a new instance of the class. /// - public JpegMetadata() - { - this.Comments = new List(); - } + public JpegMetadata() => this.Comments = new List(); /// /// Initializes a new instance of the class. @@ -36,7 +33,7 @@ public class JpegMetadata : IDeepCloneable /// /// /// This value might not be accurate if it was calculated during jpeg decoding - /// with non-complient ITU quantization tables. + /// with non-compliant ITU quantization tables. /// internal int? LuminanceQuality { get; set; } @@ -45,7 +42,7 @@ public class JpegMetadata : IDeepCloneable /// /// /// This value might not be accurate if it was calculated during jpeg decoding - /// with non-complient ITU quantization tables. + /// with non-compliant ITU quantization tables. /// internal int? ChrominanceQuality { get; set; } @@ -69,15 +66,8 @@ public class JpegMetadata : IDeepCloneable return this.LuminanceQuality.Value; } - else - { - if (this.ChrominanceQuality.HasValue) - { - return this.ChrominanceQuality.Value; - } - return Quantization.DefaultQualityFactor; - } + return this.ChrominanceQuality ?? Quantization.DefaultQualityFactor; } } diff --git a/src/ImageSharp/Formats/Png/PngMetadata.cs b/src/ImageSharp/Formats/Png/PngMetadata.cs index d9028dd807..de02e390f0 100644 --- a/src/ImageSharp/Formats/Png/PngMetadata.cs +++ b/src/ImageSharp/Formats/Png/PngMetadata.cs @@ -77,7 +77,7 @@ public class PngMetadata : IDeepCloneable /// Gets or sets the collection of text data stored within the iTXt, tEXt, and zTXt chunks. /// Used for conveying textual information associated with the image. /// - public IList TextData { get; set; } = new List(); + public IList TextData { get; set; } = []; /// /// Gets or sets the number of times to loop this APNG. 0 indicates infinite looping. @@ -96,7 +96,7 @@ public class PngMetadata : IDeepCloneable { // Should the conversion be from a format that uses a 24bit palette entries (gif) // we need to clone and adjust the color table to allow for transparency. - Color[]? colorTable = metadata.ColorTable.HasValue ? metadata.ColorTable.Value.ToArray() : null; + Color[]? colorTable = metadata.ColorTable?.ToArray(); if (colorTable != null) { for (int i = 0; i < colorTable.Length; i++) diff --git a/src/ImageSharp/PixelFormats/PixelColorType.cs b/src/ImageSharp/PixelFormats/PixelColorType.cs index 9ac2c308c2..86c3d51e97 100644 --- a/src/ImageSharp/PixelFormats/PixelColorType.cs +++ b/src/ImageSharp/PixelFormats/PixelColorType.cs @@ -9,6 +9,11 @@ namespace SixLabors.ImageSharp.PixelFormats; [Flags] public enum PixelColorType { + /// + /// No color type. + /// + None = 0, + /// /// Represents the Red component of the color. /// @@ -42,5 +47,60 @@ public enum PixelColorType /// /// Indicates that the color is in BGR (Blue, Green, Red) format. /// - BGR = Blue | Green | Red | (1 << 6) + BGR = Blue | Green | Red | (1 << 6), + + /// + /// Represents the Luminance component in YCbCr. + /// + Luminance = 1 << 7, + + /// + /// Represents the Chrominance Blue component in YCbCr. + /// + ChrominanceBlue = 1 << 8, + + /// + /// Represents the Chrominance Red component in YCbCr. + /// + ChrominanceRed = 1 << 9, + + /// + /// Indicates that the color is in YCbCr (Luminance, Chrominance Blue, Chrominance Red) format. + /// + YCbCr = Luminance | ChrominanceBlue | ChrominanceRed, + + /// + /// Represents the Cyan component in CMYK. + /// + Cyan = 1 << 10, + + /// + /// Represents the Magenta component in CMYK. + /// + Magenta = 1 << 11, + + /// + /// Represents the Yellow component in CMYK. + /// + Yellow = 1 << 12, + + /// + /// Represents the Key (black) component in CMYK and YCCK. + /// + Key = 1 << 13, + + /// + /// Indicates that the color is in CMYK (Cyan, Magenta, Yellow, Key) format. + /// + CMYK = Cyan | Magenta | Yellow | Key, + + /// + /// Indicates that the color is in YCCK (Luminance, Chrominance Blue, Chrominance Red, Key) format. + /// + YCCK = Luminance | ChrominanceBlue | ChrominanceRed | Key, + + /// + /// Indicates that the color is of a type not specified in this enum. + /// + Other = 1 << 14 } diff --git a/src/ImageSharp/PixelFormats/PixelComponentInfo.cs b/src/ImageSharp/PixelFormats/PixelComponentInfo.cs index a761054144..fca371ca92 100644 --- a/src/ImageSharp/PixelFormats/PixelComponentInfo.cs +++ b/src/ImageSharp/PixelFormats/PixelComponentInfo.cs @@ -44,7 +44,7 @@ public readonly struct PixelComponentInfo { if (precision.Length != count || precision.Length > 16) { - throw new ArgumentException($"Count must match the length of precision array and cannot exceed 16."); + throw new ArgumentOutOfRangeException(nameof(count), $"Count {count} must match the length of precision array and cannot exceed 16."); } long precisionData1 = 0; @@ -55,7 +55,7 @@ public readonly struct PixelComponentInfo int p = precision[i]; if (p is < 0 or > 255) { - throw new ArgumentException("Precision must be between 0 and 255."); + throw new ArgumentOutOfRangeException(nameof(precision), $"Precision {precision.Length} must be between 0 and 255."); } if (i < 8) diff --git a/tests/ImageSharp.Tests/PixelFormats/PixelColorTypeTests.cs b/tests/ImageSharp.Tests/PixelFormats/PixelColorTypeTests.cs new file mode 100644 index 0000000000..215fe7b876 --- /dev/null +++ b/tests/ImageSharp.Tests/PixelFormats/PixelColorTypeTests.cs @@ -0,0 +1,255 @@ +// Copyright (c) Six Labors. +// Licensed under the Six Labors Split License. + +using SixLabors.ImageSharp.PixelFormats; + +namespace SixLabors.ImageSharp.Tests.PixelFormats; + +public class PixelColorTypeTests +{ + [Fact] + public void PixelColorType_RedFlag_ShouldBeSet() + { + const PixelColorType colorType = PixelColorType.Red; + Assert.True(colorType.HasFlag(PixelColorType.Red)); + } + + [Fact] + public void PixelColorType_GreenFlag_ShouldBeSet() + { + const PixelColorType colorType = PixelColorType.Green; + Assert.True(colorType.HasFlag(PixelColorType.Green)); + } + + [Fact] + public void PixelColorType_BlueFlag_ShouldBeSet() + { + const PixelColorType colorType = PixelColorType.Blue; + Assert.True(colorType.HasFlag(PixelColorType.Blue)); + } + + [Fact] + public void PixelColorType_AlphaFlag_ShouldBeSet() + { + const PixelColorType colorType = PixelColorType.Alpha; + Assert.True(colorType.HasFlag(PixelColorType.Alpha)); + } + + [Fact] + public void PixelColorType_GrayscaleFlag_ShouldBeSet() + { + const PixelColorType colorType = PixelColorType.Grayscale; + Assert.True(colorType.HasFlag(PixelColorType.Grayscale)); + } + + [Fact] + public void PixelColorType_RGBFlags_ShouldBeSet() + { + const PixelColorType colorType = PixelColorType.RGB; + Assert.True(colorType.HasFlag(PixelColorType.Red)); + Assert.True(colorType.HasFlag(PixelColorType.Green)); + Assert.True(colorType.HasFlag(PixelColorType.Blue)); + Assert.False(colorType.HasFlag(PixelColorType.BGR)); + } + + [Fact] + public void PixelColorType_BGRFlags_ShouldBeSet() + { + const PixelColorType colorType = PixelColorType.BGR; + Assert.True(colorType.HasFlag(PixelColorType.Blue)); + Assert.True(colorType.HasFlag(PixelColorType.Green)); + Assert.True(colorType.HasFlag(PixelColorType.Red)); + Assert.False(colorType.HasFlag(PixelColorType.RGB)); + } + + [Fact] + public void PixelColorType_LuminanceFlag_ShouldBeSet() + { + const PixelColorType colorType = PixelColorType.Luminance; + Assert.True(colorType.HasFlag(PixelColorType.Luminance)); + } + + [Fact] + public void PixelColorType_ChrominanceBlueFlag_ShouldBeSet() + { + const PixelColorType colorType = PixelColorType.ChrominanceBlue; + Assert.True(colorType.HasFlag(PixelColorType.ChrominanceBlue)); + } + + [Fact] + public void PixelColorType_ChrominanceRedFlag_ShouldBeSet() + { + const PixelColorType colorType = PixelColorType.ChrominanceRed; + Assert.True(colorType.HasFlag(PixelColorType.ChrominanceRed)); + } + + [Fact] + public void PixelColorType_YCbCrFlags_ShouldBeSet() + { + const PixelColorType colorType = PixelColorType.YCbCr; + Assert.True(colorType.HasFlag(PixelColorType.Luminance)); + Assert.True(colorType.HasFlag(PixelColorType.ChrominanceBlue)); + Assert.True(colorType.HasFlag(PixelColorType.ChrominanceRed)); + } + + [Fact] + public void PixelColorType_CyanFlag_ShouldBeSet() + { + const PixelColorType colorType = PixelColorType.Cyan; + Assert.True(colorType.HasFlag(PixelColorType.Cyan)); + } + + [Fact] + public void PixelColorType_MagentaFlag_ShouldBeSet() + { + const PixelColorType colorType = PixelColorType.Magenta; + Assert.True(colorType.HasFlag(PixelColorType.Magenta)); + } + + [Fact] + public void PixelColorType_YellowFlag_ShouldBeSet() + { + const PixelColorType colorType = PixelColorType.Yellow; + Assert.True(colorType.HasFlag(PixelColorType.Yellow)); + } + + [Fact] + public void PixelColorType_KeyFlag_ShouldBeSet() + { + const PixelColorType colorType = PixelColorType.Key; + Assert.True(colorType.HasFlag(PixelColorType.Key)); + } + + [Fact] + public void PixelColorType_CMYKFlags_ShouldBeSet() + { + const PixelColorType colorType = PixelColorType.CMYK; + Assert.True(colorType.HasFlag(PixelColorType.Cyan)); + Assert.True(colorType.HasFlag(PixelColorType.Magenta)); + Assert.True(colorType.HasFlag(PixelColorType.Yellow)); + Assert.True(colorType.HasFlag(PixelColorType.Key)); + } + + [Fact] + public void PixelColorType_YCCKFlags_ShouldBeSet() + { + const PixelColorType colorType = PixelColorType.YCCK; + Assert.True(colorType.HasFlag(PixelColorType.Luminance)); + Assert.True(colorType.HasFlag(PixelColorType.ChrominanceBlue)); + Assert.True(colorType.HasFlag(PixelColorType.ChrominanceRed)); + Assert.True(colorType.HasFlag(PixelColorType.Key)); + } + + [Fact] + public void PixelColorType_Other_ShouldBeSet() + { + const PixelColorType colorType = PixelColorType.Other; + Assert.True(colorType.HasFlag(PixelColorType.Other)); + } + + [Fact] + public void PixelColorType_None_ShouldBeZero() + { + const PixelColorType colorType = PixelColorType.None; + Assert.Equal(0, (int)colorType); + } + + [Fact] + public void PixelColorType_RGB_ShouldNotContainOtherFlags() + { + const PixelColorType colorType = PixelColorType.RGB; + Assert.False(colorType.HasFlag(PixelColorType.Grayscale)); + Assert.False(colorType.HasFlag(PixelColorType.Luminance)); + Assert.False(colorType.HasFlag(PixelColorType.ChrominanceBlue)); + Assert.False(colorType.HasFlag(PixelColorType.ChrominanceRed)); + Assert.False(colorType.HasFlag(PixelColorType.Cyan)); + Assert.False(colorType.HasFlag(PixelColorType.Magenta)); + Assert.False(colorType.HasFlag(PixelColorType.Yellow)); + Assert.False(colorType.HasFlag(PixelColorType.Key)); + Assert.False(colorType.HasFlag(PixelColorType.Other)); + } + + [Fact] + public void PixelColorType_BGR_ShouldNotContainOtherFlags() + { + const PixelColorType colorType = PixelColorType.BGR; + Assert.False(colorType.HasFlag(PixelColorType.Grayscale)); + Assert.False(colorType.HasFlag(PixelColorType.Luminance)); + Assert.False(colorType.HasFlag(PixelColorType.ChrominanceBlue)); + Assert.False(colorType.HasFlag(PixelColorType.ChrominanceRed)); + Assert.False(colorType.HasFlag(PixelColorType.Cyan)); + Assert.False(colorType.HasFlag(PixelColorType.Magenta)); + Assert.False(colorType.HasFlag(PixelColorType.Yellow)); + Assert.False(colorType.HasFlag(PixelColorType.Key)); + Assert.False(colorType.HasFlag(PixelColorType.Other)); + } + + [Fact] + public void PixelColorType_YCbCr_ShouldNotContainOtherFlags() + { + const PixelColorType colorType = PixelColorType.YCbCr; + Assert.False(colorType.HasFlag(PixelColorType.Red)); + Assert.False(colorType.HasFlag(PixelColorType.Green)); + Assert.False(colorType.HasFlag(PixelColorType.Blue)); + Assert.False(colorType.HasFlag(PixelColorType.Alpha)); + Assert.False(colorType.HasFlag(PixelColorType.Grayscale)); + Assert.False(colorType.HasFlag(PixelColorType.Cyan)); + Assert.False(colorType.HasFlag(PixelColorType.Magenta)); + Assert.False(colorType.HasFlag(PixelColorType.Yellow)); + Assert.False(colorType.HasFlag(PixelColorType.Key)); + Assert.False(colorType.HasFlag(PixelColorType.Other)); + } + + [Fact] + public void PixelColorType_CMYK_ShouldNotContainOtherFlags() + { + const PixelColorType colorType = PixelColorType.CMYK; + Assert.False(colorType.HasFlag(PixelColorType.Red)); + Assert.False(colorType.HasFlag(PixelColorType.Green)); + Assert.False(colorType.HasFlag(PixelColorType.Blue)); + Assert.False(colorType.HasFlag(PixelColorType.Alpha)); + Assert.False(colorType.HasFlag(PixelColorType.Grayscale)); + Assert.False(colorType.HasFlag(PixelColorType.Luminance)); + Assert.False(colorType.HasFlag(PixelColorType.ChrominanceBlue)); + Assert.False(colorType.HasFlag(PixelColorType.ChrominanceRed)); + Assert.False(colorType.HasFlag(PixelColorType.Other)); + } + + [Fact] + public void PixelColorType_YCCK_ShouldNotContainOtherFlags() + { + const PixelColorType colorType = PixelColorType.YCCK; + Assert.False(colorType.HasFlag(PixelColorType.Red)); + Assert.False(colorType.HasFlag(PixelColorType.Green)); + Assert.False(colorType.HasFlag(PixelColorType.Blue)); + Assert.False(colorType.HasFlag(PixelColorType.Alpha)); + Assert.False(colorType.HasFlag(PixelColorType.Grayscale)); + Assert.False(colorType.HasFlag(PixelColorType.Cyan)); + Assert.False(colorType.HasFlag(PixelColorType.Magenta)); + Assert.False(colorType.HasFlag(PixelColorType.Yellow)); + Assert.False(colorType.HasFlag(PixelColorType.Other)); + } + + [Fact] + public void PixelColorType_Other_ShouldNotContainPreviousFlags() + { + const PixelColorType colorType = PixelColorType.Other; + Assert.False(colorType.HasFlag(PixelColorType.Red)); + Assert.False(colorType.HasFlag(PixelColorType.Green)); + Assert.False(colorType.HasFlag(PixelColorType.Blue)); + Assert.False(colorType.HasFlag(PixelColorType.Alpha)); + Assert.False(colorType.HasFlag(PixelColorType.Grayscale)); + Assert.False(colorType.HasFlag(PixelColorType.RGB)); + Assert.False(colorType.HasFlag(PixelColorType.BGR)); + Assert.False(colorType.HasFlag(PixelColorType.Luminance)); + Assert.False(colorType.HasFlag(PixelColorType.ChrominanceBlue)); + Assert.False(colorType.HasFlag(PixelColorType.ChrominanceRed)); + Assert.False(colorType.HasFlag(PixelColorType.YCbCr)); + Assert.False(colorType.HasFlag(PixelColorType.Cyan)); + Assert.False(colorType.HasFlag(PixelColorType.Magenta)); + Assert.False(colorType.HasFlag(PixelColorType.Yellow)); + Assert.False(colorType.HasFlag(PixelColorType.Key)); + Assert.False(colorType.HasFlag(PixelColorType.CMYK)); + Assert.False(colorType.HasFlag(PixelColorType.YCCK)); + } +}