From aed9acd6bfeef78b462113daf0bc10b8bb218bdc Mon Sep 17 00:00:00 2001 From: LuisAlfredo92 <92luisalfredo@protonmail.com> Date: Wed, 28 Jun 2023 18:12:05 -0600 Subject: [PATCH] Fixing StyleCop --- src/ImageSharp/Formats/Qoi/QoiChunkEnum.cs | 54 ++++++++++++++++--- src/ImageSharp/Formats/Qoi/QoiConstants.cs | 8 +-- src/ImageSharp/Formats/Qoi/QoiDecoderCore.cs | 41 +++++++------- src/ImageSharp/Formats/Qoi/QoiEncoder.cs | 4 +- src/ImageSharp/Formats/Qoi/QoiEncoderCore.cs | 35 ++++-------- src/ImageSharp/Formats/Qoi/QoiFormat.cs | 13 +++-- src/ImageSharp/Formats/Qoi/QoiHeader.cs | 10 ++-- src/ImageSharp/Image{TPixel}.cs | 7 +-- .../Formats/Qoi/QoiEncoderTests.cs | 4 +- 9 files changed, 100 insertions(+), 76 deletions(-) diff --git a/src/ImageSharp/Formats/Qoi/QoiChunkEnum.cs b/src/ImageSharp/Formats/Qoi/QoiChunkEnum.cs index f877a4935..7fb0de8da 100644 --- a/src/ImageSharp/Formats/Qoi/QoiChunkEnum.cs +++ b/src/ImageSharp/Formats/Qoi/QoiChunkEnum.cs @@ -3,12 +3,54 @@ namespace SixLabors.ImageSharp.Formats.Qoi; +/// +/// Enum that contains the operations that encoder and decoder must process, written +/// in binary to be easier to compare them in the reference +/// public enum QoiChunkEnum { - QOI_OP_RGB = 0b11111110, - QOI_OP_RGBA = 0b11111111, - QOI_OP_INDEX = 0b00000000, - QOI_OP_DIFF = 0b01000000, - QOI_OP_LUMA = 0b10000000, - QOI_OP_RUN = 0b11000000 + /// + /// Indicates that the operation is QOI_OP_RGB where the RGB values are written + /// in one byte each one after this marker + /// + QoiOpRgb = 0b11111110, + + /// + /// Indicates that the operation is QOI_OP_RGBA where the RGBA values are written + /// in one byte each one after this marker + /// + QoiOpRgba = 0b11111111, + + /// + /// Indicates that the operation is QOI_OP_INDEX where one byte contains a 2-bit + /// marker (0b00) followed by an index on the previously seen pixels array 0..63 + /// + QoiOpIndex = 0b00000000, + + /// + /// Indicates that the operation is QOI_OP_DIFF where one byte contains a 2-bit + /// marker (0b01) followed by 2-bit differences in red, green and blue channel + /// with the previous pixel with a bias of 2 (-2..1) + /// + QoiOpDiff = 0b01000000, + + /// + /// Indicates that the operation is QOI_OP_LUMA where one byte contains a 2-bit + /// marker (0b01) followed by a 6-bits number that indicates the difference of + /// the green channel with the previous pixel. Then another byte that contains + /// a 4-bit number that indicates the difference of the red channel minus the + /// previous difference, and another 4-bit number that indicates the difference + /// of the blue channel minus the green difference + /// Example: 0b10[6-bits diff green] 0b[6-bits dr-dg][6-bits db-dg] + /// dr_dg = (cur_px.r - prev_px.r) - (cur_px.g - prev_px.g) + /// db_dg = (cur_px.b - prev_px.b) - (cur_px.g - prev_px.g) + /// + QoiOpLuma = 0b10000000, + + /// + /// Indicates that the operation is QOI_OP_RUN where one byte contains a 2-bit + /// marker (0b11) followed by a 6-bits number that indicates the times that the + /// previous pixel is repeated + /// + QoiOpRun = 0b11000000 } diff --git a/src/ImageSharp/Formats/Qoi/QoiConstants.cs b/src/ImageSharp/Formats/Qoi/QoiConstants.cs index 62508d3be..9643ccef0 100644 --- a/src/ImageSharp/Formats/Qoi/QoiConstants.cs +++ b/src/ImageSharp/Formats/Qoi/QoiConstants.cs @@ -15,13 +15,13 @@ internal static class QoiConstants public static ReadOnlySpan Magic => SMagic; /// - /// The list of mimetypes that equate to a QOI. + /// Gets the list of mimetypes that equate to a QOI. /// See https://github.com/phoboslab/qoi/issues/167 /// - public static readonly string[] MimeTypes = { "image/qoi", "image/x-qoi", "image/vnd.qoi" }; + public static string[] MimeTypes { get; } = { "image/qoi", "image/x-qoi", "image/vnd.qoi" }; /// - /// The list of file extensions that equate to a QOI. + /// Gets the list of file extensions that equate to a QOI. /// - public static readonly string[] FileExtensions = { "qoi" }; + public static string[] FileExtensions { get; } = { "qoi" }; } diff --git a/src/ImageSharp/Formats/Qoi/QoiDecoderCore.cs b/src/ImageSharp/Formats/Qoi/QoiDecoderCore.cs index 279dbd233..844d7bc7a 100644 --- a/src/ImageSharp/Formats/Qoi/QoiDecoderCore.cs +++ b/src/ImageSharp/Formats/Qoi/QoiDecoderCore.cs @@ -61,7 +61,7 @@ internal class QoiDecoderCore : IImageDecoderInternals }; Image image = new(this.configuration, (int)this.header.Width, (int)this.header.Height, metadata); Buffer2D pixels = image.GetRootFramePixelBuffer(); - + this.ProcessPixels(stream, pixels); return image; @@ -145,11 +145,11 @@ internal class QoiDecoderCore : IImageDecoderInternals where TPixel : unmanaged, IPixel { Rgba32[] previouslySeenPixels = new Rgba32[64]; - Rgba32 previousPixel = new(0,0,0,255); + Rgba32 previousPixel = new(0, 0, 0, 255); // We save the pixel to avoid loosing the fully opaque black pixel // See https://github.com/phoboslab/qoi/issues/258 - int pixelArrayPosition = this.GetArrayPosition(previousPixel); + int pixelArrayPosition = GetArrayPosition(previousPixel); previouslySeenPixels[pixelArrayPosition] = previousPixel; for (int i = 0; i < this.header.Height; i++) @@ -159,11 +159,11 @@ internal class QoiDecoderCore : IImageDecoderInternals byte operationByte = (byte)stream.ReadByte(); byte[] pixelBytes; Rgba32 readPixel; - TPixel pixel = new(); + TPixel pixel = default; switch ((QoiChunkEnum)operationByte) { // Reading one pixel with previous alpha intact - case QoiChunkEnum.QOI_OP_RGB: + case QoiChunkEnum.QoiOpRgb: pixelBytes = new byte[3]; if (stream.Read(pixelBytes) < 3) { @@ -172,12 +172,12 @@ internal class QoiDecoderCore : IImageDecoderInternals readPixel = previousPixel with { R = pixelBytes[0], G = pixelBytes[1], B = pixelBytes[2] }; pixel.FromRgba32(readPixel); - pixelArrayPosition = this.GetArrayPosition(readPixel); + pixelArrayPosition = GetArrayPosition(readPixel); previouslySeenPixels[pixelArrayPosition] = readPixel; break; // Reading one pixel with new alpha - case QoiChunkEnum.QOI_OP_RGBA: + case QoiChunkEnum.QoiOpRgba: pixelBytes = new byte[4]; if (stream.Read(pixelBytes) < 4) { @@ -186,7 +186,7 @@ internal class QoiDecoderCore : IImageDecoderInternals readPixel = new Rgba32(pixelBytes[0], pixelBytes[1], pixelBytes[2], pixelBytes[3]); pixel.FromRgba32(readPixel); - pixelArrayPosition = this.GetArrayPosition(readPixel); + pixelArrayPosition = GetArrayPosition(readPixel); previouslySeenPixels[pixelArrayPosition] = readPixel; break; @@ -194,13 +194,13 @@ internal class QoiDecoderCore : IImageDecoderInternals switch ((QoiChunkEnum)(operationByte & 0b11000000)) { // Getting one pixel from previously seen pixels - case QoiChunkEnum.QOI_OP_INDEX: + case QoiChunkEnum.QoiOpIndex: readPixel = previouslySeenPixels[operationByte]; pixel.FromRgba32(readPixel); break; // Get one pixel from the difference (-2..1) of the previous pixel - case QoiChunkEnum.QOI_OP_DIFF: + case QoiChunkEnum.QoiOpDiff: byte redDifference = (byte)((operationByte & 0b00110000) >> 4), greenDifference = (byte)((operationByte & 0b00001100) >> 2), blueDifference = (byte)(operationByte & 0b00000011); @@ -211,30 +211,30 @@ internal class QoiDecoderCore : IImageDecoderInternals B = (byte)((previousPixel.B + (blueDifference - 2)) % 256) }; pixel.FromRgba32(readPixel); - pixelArrayPosition = this.GetArrayPosition(readPixel); + pixelArrayPosition = GetArrayPosition(readPixel); previouslySeenPixels[pixelArrayPosition] = readPixel; break; // Get green difference in 6 bits and red and blue differences // depending on the green one - case QoiChunkEnum.QOI_OP_LUMA: + case QoiChunkEnum.QoiOpLuma: byte diffGreen = (byte)(operationByte & 0b00111111), currentGreen = (byte)((previousPixel.G + (diffGreen - 32)) % 256), nextByte = (byte)stream.ReadByte(), diffRedDG = (byte)(nextByte >> 4), diffBlueDG = (byte)(nextByte & 0b00001111), - currentRed = (byte)((diffRedDG-8 + (diffGreen - 32) + previousPixel.R)%256), - currentBlue = (byte)((diffBlueDG-8 + (diffGreen - 32) + previousPixel.B)%256); + currentRed = (byte)((diffRedDG - 8 + (diffGreen - 32) + previousPixel.R) % 256), + currentBlue = (byte)((diffBlueDG - 8 + (diffGreen - 32) + previousPixel.B) % 256); readPixel = previousPixel with { R = currentRed, B = currentBlue, G = currentGreen }; pixel.FromRgba32(readPixel); - pixelArrayPosition = this.GetArrayPosition(readPixel); + pixelArrayPosition = GetArrayPosition(readPixel); previouslySeenPixels[pixelArrayPosition] = readPixel; break; // Repeating the previous pixel 1..63 times - case QoiChunkEnum.QOI_OP_RUN: + case QoiChunkEnum.QoiOpRun: byte repetitions = (byte)(operationByte & 0b00111111); - if(repetitions is 62 or 63) + if (repetitions is 62 or 63) { ThrowInvalidImageContentException(); } @@ -248,7 +248,8 @@ internal class QoiDecoderCore : IImageDecoderInternals j = 0; i++; } - pixels[j,i] = pixel; + + pixels[j, i] = pixel; } j--; @@ -262,7 +263,7 @@ internal class QoiDecoderCore : IImageDecoderInternals break; } - pixels[j,i] = pixel; + pixels[j, i] = pixel; previousPixel = readPixel; } } @@ -282,5 +283,5 @@ internal class QoiDecoderCore : IImageDecoderInternals } } - private int GetArrayPosition(Rgba32 pixel) => ((pixel.R * 3) + (pixel.G * 5) + (pixel.B * 7) + (pixel.A * 11)) % 64; + private static int GetArrayPosition(Rgba32 pixel) => ((pixel.R * 3) + (pixel.G * 5) + (pixel.B * 7) + (pixel.A * 11)) % 64; } diff --git a/src/ImageSharp/Formats/Qoi/QoiEncoder.cs b/src/ImageSharp/Formats/Qoi/QoiEncoder.cs index 526a84524..699962edb 100644 --- a/src/ImageSharp/Formats/Qoi/QoiEncoder.cs +++ b/src/ImageSharp/Formats/Qoi/QoiEncoder.cs @@ -1,8 +1,6 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -using SixLabors.ImageSharp.Advanced; - namespace SixLabors.ImageSharp.Formats.Qoi; /// @@ -13,7 +11,7 @@ public class QoiEncoder : ImageEncoder /// protected override void Encode(Image image, Stream stream, CancellationToken cancellationToken) { - QoiEncoderCore encoder = new(image.GetConfiguration(), this); + QoiEncoderCore encoder = new(); encoder.Encode(image, stream, cancellationToken); } } diff --git a/src/ImageSharp/Formats/Qoi/QoiEncoderCore.cs b/src/ImageSharp/Formats/Qoi/QoiEncoderCore.cs index 463a9be7c..2a3571336 100644 --- a/src/ImageSharp/Formats/Qoi/QoiEncoderCore.cs +++ b/src/ImageSharp/Formats/Qoi/QoiEncoderCore.cs @@ -2,7 +2,6 @@ // Licensed under the Six Labors Split License. using System.Buffers.Binary; -using System.Runtime.InteropServices.ComTypes; using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.PixelFormats; @@ -13,25 +12,11 @@ namespace SixLabors.ImageSharp.Formats.Qoi; /// public class QoiEncoderCore : IImageEncoderInternals { - /// - /// The global configuration. - /// - private Configuration configuration; - - /// - /// The encoder with options. - /// - private readonly QoiEncoder encoder; - /// /// Initializes a new instance of the class. /// - /// The configuration. - /// The encoder with options. - public QoiEncoderCore(Configuration configuration, QoiEncoder encoder) + public QoiEncoderCore() { - this.configuration = configuration; - this.encoder = encoder; } /// @@ -67,7 +52,8 @@ public class QoiEncoderCore : IImageEncoderInternals stream.WriteByte((byte)qoiColorSpace); } - private static void WritePixels(Image image, Stream stream) where TPixel : unmanaged, IPixel + private static void WritePixels(Image image, Stream stream) + where TPixel : unmanaged, IPixel { // Start image encoding Rgba32[] previouslySeenPixels = new Rgba32[64]; @@ -76,7 +62,7 @@ public class QoiEncoderCore : IImageEncoderInternals previouslySeenPixels[pixelArrayPosition] = previousPixel; Buffer2D pixels = image.Frames[0].PixelBuffer; - Rgba32 currentRgba32 = new(); + Rgba32 currentRgba32 = default; for (int i = 0; i < pixels.Height; i++) { for (int j = 0; j < pixels.Width && i < pixels.Height; j++) @@ -115,10 +101,11 @@ public class QoiEncoderCore : IImageEncoderInternals currentPixel = pixels[j, i]; currentPixel.ToRgba32(ref currentRgba32); - } while (currentRgba32.Equals(previousPixel) && repetitions < 62); + } + while (currentRgba32.Equals(previousPixel) && repetitions < 62); j--; - stream.WriteByte((byte)((byte)QoiChunkEnum.QOI_OP_RUN | (repetitions - 1))); + stream.WriteByte((byte)((byte)QoiChunkEnum.QoiOpRun | (repetitions - 1))); /* If it's a QOI_OP_RUN, we don't overwrite the previous pixel since * it will be taken and compared on the next iteration @@ -153,7 +140,7 @@ public class QoiEncoderCore : IImageEncoderInternals byte dr = (byte)(diffRed + 2), dg = (byte)(diffGreen + 2), db = (byte)(diffBlue + 2), - valueToWrite = (byte)((byte)QoiChunkEnum.QOI_OP_DIFF | (dr << 4) | (dg << 2) | db); + valueToWrite = (byte)((byte)QoiChunkEnum.QoiOpDiff | (dr << 4) | (dg << 2) | db); stream.WriteByte(valueToWrite); } else @@ -169,7 +156,7 @@ public class QoiEncoderCore : IImageEncoderInternals { byte dr_dg = (byte)(diffRedGreen + 8), db_dg = (byte)(diffBlueGreen + 8), - byteToWrite1 = (byte)((byte)QoiChunkEnum.QOI_OP_LUMA | (diffGreen + 32)), + byteToWrite1 = (byte)((byte)QoiChunkEnum.QoiOpLuma | (diffGreen + 32)), byteToWrite2 = (byte)((dr_dg << 4) | db_dg); stream.WriteByte(byteToWrite1); stream.WriteByte(byteToWrite2); @@ -180,7 +167,7 @@ public class QoiEncoderCore : IImageEncoderInternals // If so, we do a QOI_OP_RGB if (currentRgba32.A == previousPixel.A) { - stream.WriteByte((byte)QoiChunkEnum.QOI_OP_RGB); + stream.WriteByte((byte)QoiChunkEnum.QoiOpRgb); stream.WriteByte(currentRgba32.R); stream.WriteByte(currentRgba32.G); stream.WriteByte(currentRgba32.B); @@ -188,7 +175,7 @@ public class QoiEncoderCore : IImageEncoderInternals else { // else, we do a QOI_OP_RGBA - stream.WriteByte((byte)QoiChunkEnum.QOI_OP_RGBA); + stream.WriteByte((byte)QoiChunkEnum.QoiOpRgba); stream.WriteByte(currentRgba32.R); stream.WriteByte(currentRgba32.G); stream.WriteByte(currentRgba32.B); diff --git a/src/ImageSharp/Formats/Qoi/QoiFormat.cs b/src/ImageSharp/Formats/Qoi/QoiFormat.cs index e3bdbf982..ca2d7ae45 100644 --- a/src/ImageSharp/Formats/Qoi/QoiFormat.cs +++ b/src/ImageSharp/Formats/Qoi/QoiFormat.cs @@ -1,8 +1,6 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -using SixLabors.ImageSharp.Formats.Png; - namespace SixLabors.ImageSharp.Formats.Qoi; /// @@ -11,7 +9,8 @@ namespace SixLabors.ImageSharp.Formats.Qoi; public sealed class QoiFormat : IImageFormat { private QoiFormat() - { } + { + } /// /// Gets the shared instance. @@ -19,17 +18,17 @@ public sealed class QoiFormat : IImageFormat public static QoiFormat Instance { get; } = new QoiFormat(); /// - public QoiMetadata CreateDefaultFormatMetadata() => new(); + public string DefaultMimeType => "image/qoi"; /// public string Name => "QOI"; - /// - public string DefaultMimeType => "image/qoi"; - /// public IEnumerable MimeTypes => QoiConstants.MimeTypes; /// public IEnumerable FileExtensions => QoiConstants.FileExtensions; + + /// + public QoiMetadata CreateDefaultFormatMetadata() => new(); } diff --git a/src/ImageSharp/Formats/Qoi/QoiHeader.cs b/src/ImageSharp/Formats/Qoi/QoiHeader.cs index ec23d3b74..951d6701b 100644 --- a/src/ImageSharp/Formats/Qoi/QoiHeader.cs +++ b/src/ImageSharp/Formats/Qoi/QoiHeader.cs @@ -19,27 +19,27 @@ internal readonly struct QoiHeader } /// - /// Magic bytes "qoif" + /// Gets the magic bytes "qoif" /// public byte[] Magic { get; } = Encoding.UTF8.GetBytes("qoif"); /// - /// Image width in pixels (BE) + /// Gets the image width in pixels (Big Endian) /// public uint Width { get; } /// - /// Image height in pixels (BE) + /// Gets the image height in pixels (Big Endian) /// public uint Height { get; } /// - /// Color channels of the image. 3 = RGB, 4 = RGBA. + /// Gets the color channels of the image. 3 = RGB, 4 = RGBA. /// public QoiChannels Channels { get; } /// - /// Color space of the image. 0 = sRGB with linear alpha, 1 = All channels linear + /// Gets the color space of the image. 0 = sRGB with linear alpha, 1 = All channels linear /// public QoiColorSpace ColorSpace { get; } } diff --git a/src/ImageSharp/Image{TPixel}.cs b/src/ImageSharp/Image{TPixel}.cs index ed0db9b85..69654329c 100644 --- a/src/ImageSharp/Image{TPixel}.cs +++ b/src/ImageSharp/Image{TPixel}.cs @@ -418,12 +418,7 @@ public sealed class Image : Image { Guard.NotNull(frames, nameof(frames)); - ImageFrame? rootFrame = frames.FirstOrDefault(); - - if (rootFrame == null) - { - throw new ArgumentException("Must not be empty.", nameof(frames)); - } + ImageFrame? rootFrame = frames.FirstOrDefault() ?? throw new ArgumentException("Must not be empty.", nameof(frames)); Size rootSize = rootFrame.Size(); diff --git a/tests/ImageSharp.Tests/Formats/Qoi/QoiEncoderTests.cs b/tests/ImageSharp.Tests/Formats/Qoi/QoiEncoderTests.cs index 98331a8ff..4d69a1f06 100644 --- a/tests/ImageSharp.Tests/Formats/Qoi/QoiEncoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Qoi/QoiEncoderTests.cs @@ -20,7 +20,9 @@ public class QoiEncoderTests [WithFile(TestImages.Qoi.TestCard, PixelTypes.Rgba32)] [WithFile(TestImages.Qoi.TestCardRGBA, PixelTypes.Rgba32)] [WithFile(TestImages.Qoi.Wikipedia008, PixelTypes.Rgba32)] - private static void Encode(TestImageProvider provider) where TPixel : unmanaged, IPixel + [System.Diagnostics.CodeAnalysis.SuppressMessage("CodeQuality", "IDE0051:Quitar miembros privados no utilizados", Justification = "Function implicitly in tests")] + private static void Encode(TestImageProvider provider) + where TPixel : unmanaged, IPixel { using Image image = provider.GetImage(); using MemoryStream stream = new();