From c79dd773ca3974e08683faa4439195c486da8ccf Mon Sep 17 00:00:00 2001 From: LuisAlfredo92 <92luisalfredo@protonmail.com> Date: Wed, 3 May 2023 14:06:49 -0600 Subject: [PATCH] Adding qoi identification I'm going to do some tests before the pull request and add all the functions --- .../Formats/Qoi/MetadataExtensions.cs | 20 ++++ src/ImageSharp/Formats/Qoi/QoiDecoder.cs | 27 ++++++ src/ImageSharp/Formats/Qoi/QoiDecoderCore.cs | 93 +++++++++++++++++++ src/ImageSharp/Formats/Qoi/QoiFormat.cs | 35 +++++++ src/ImageSharp/Formats/Qoi/QoiMetadata.cs | 3 - 5 files changed, 175 insertions(+), 3 deletions(-) create mode 100644 src/ImageSharp/Formats/Qoi/MetadataExtensions.cs create mode 100644 src/ImageSharp/Formats/Qoi/QoiDecoder.cs create mode 100644 src/ImageSharp/Formats/Qoi/QoiDecoderCore.cs create mode 100644 src/ImageSharp/Formats/Qoi/QoiFormat.cs diff --git a/src/ImageSharp/Formats/Qoi/MetadataExtensions.cs b/src/ImageSharp/Formats/Qoi/MetadataExtensions.cs new file mode 100644 index 000000000..1e0fa8899 --- /dev/null +++ b/src/ImageSharp/Formats/Qoi/MetadataExtensions.cs @@ -0,0 +1,20 @@ +// Copyright (c) Six Labors. +// Licensed under the Six Labors Split License. + +using SixLabors.ImageSharp.Formats.Qoi; +using SixLabors.ImageSharp.Metadata; + +namespace SixLabors.ImageSharp; + +/// +/// Extension methods for the type. +/// +public static partial class MetadataExtensions +{ + /// + /// Gets the qoi format specific metadata for the image. + /// + /// The metadata this method extends. + /// The . + public static QoiMetadata GetQoiMetadata(this ImageMetadata metadata) => metadata.GetFormatMetadata(QoiFormat.Instance); +} diff --git a/src/ImageSharp/Formats/Qoi/QoiDecoder.cs b/src/ImageSharp/Formats/Qoi/QoiDecoder.cs new file mode 100644 index 000000000..b36ca77f8 --- /dev/null +++ b/src/ImageSharp/Formats/Qoi/QoiDecoder.cs @@ -0,0 +1,27 @@ +// Copyright (c) Six Labors. +// Licensed under the Six Labors Split License. + +namespace SixLabors.ImageSharp.Formats.Qoi; +internal class QoiDecoder : ImageDecoder +{ + protected override Image Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken) + { + Guard.NotNull(options, nameof(options)); + Guard.NotNull(stream, nameof(stream)); + throw new NotImplementedException(); + } + + protected override Image Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken) + { + Guard.NotNull(options, nameof(options)); + Guard.NotNull(stream, nameof(stream)); + throw new NotImplementedException(); + } + + protected override ImageInfo Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken) + { + Guard.NotNull(options, nameof(options)); + Guard.NotNull(stream, nameof(stream)); + throw new NotImplementedException(); + } +} diff --git a/src/ImageSharp/Formats/Qoi/QoiDecoderCore.cs b/src/ImageSharp/Formats/Qoi/QoiDecoderCore.cs new file mode 100644 index 000000000..717ea5165 --- /dev/null +++ b/src/ImageSharp/Formats/Qoi/QoiDecoderCore.cs @@ -0,0 +1,93 @@ +// Copyright (c) Six Labors. +// Licensed under the Six Labors Split License. + +using SixLabors.ImageSharp.IO; +using SixLabors.ImageSharp.Memory; +using SixLabors.ImageSharp.Metadata; +using SixLabors.ImageSharp.PixelFormats; + +namespace SixLabors.ImageSharp.Formats.Qoi; + +internal class QoiDecoderCore : IImageDecoderInternals +{ + /// + /// The global configuration. + /// + private readonly Configuration configuration; + + /// + /// Used the manage memory allocations. + /// + private readonly MemoryAllocator memoryAllocator; + + /// + /// Gets or sets a value indicating whether the metadata should be ignored when the image is being decoded. + /// + private readonly bool skipMetadata; + + /// + /// The QOI header. + /// + private QoiHeader header; + + public QoiDecoderCore(DecoderOptions options) + { + this.Options = options; + this.configuration = options.Configuration; + this.skipMetadata = options.SkipMetadata; + this.memoryAllocator = this.configuration.MemoryAllocator; + } + + public DecoderOptions Options { get; } + + public Size Dimensions { get; } + + public Image Decode(BufferedReadStream stream, CancellationToken cancellationToken) + where TPixel : unmanaged, IPixel => throw new NotImplementedException(); + + public ImageInfo Identify(BufferedReadStream stream, CancellationToken cancellationToken) + { + ImageMetadata metadata = new(); + + byte[] widthBytes, heightBytes; + byte[] magicBytes = widthBytes = heightBytes = Array.Empty(); + + // Read magic bytes + int read = stream.Read(magicBytes, 0, 4); + if (read != 4 || !magicBytes.Equals(QoiConstants.Magic.ToArray())) + { + throw new InvalidImageContentException("The image is not a QOI image"); + } + + // If it's a qoi image, read the rest of properties + read = stream.Read(widthBytes, 0, 4); + if (read != 4) + { + throw new InvalidImageContentException("The image is not a QOI image"); + } + + read = stream.Read(heightBytes, 0, 4); + if (read != 4) + { + throw new InvalidImageContentException("The image is not a QOI image"); + } + + Size size = new(BitConverter.ToInt32(widthBytes), BitConverter.ToInt32(heightBytes)); + + int channels = stream.ReadByte(); + if (channels == -1) + { + throw new InvalidImageContentException("The image is not a QOI image"); + } + + PixelTypeInfo pixelType = new(8 * channels); + + int colorSpace = stream.ReadByte(); + if (colorSpace == -1) + { + throw new InvalidImageContentException("The image is not a QOI image"); + } + + return new ImageInfo(pixelType, size, metadata); + } +} diff --git a/src/ImageSharp/Formats/Qoi/QoiFormat.cs b/src/ImageSharp/Formats/Qoi/QoiFormat.cs new file mode 100644 index 000000000..e3bdbf982 --- /dev/null +++ b/src/ImageSharp/Formats/Qoi/QoiFormat.cs @@ -0,0 +1,35 @@ +// Copyright (c) Six Labors. +// Licensed under the Six Labors Split License. + +using SixLabors.ImageSharp.Formats.Png; + +namespace SixLabors.ImageSharp.Formats.Qoi; + +/// +/// Registers the image encoders, decoders and mime type detectors for the qoi format. +/// +public sealed class QoiFormat : IImageFormat +{ + private QoiFormat() + { } + + /// + /// Gets the shared instance. + /// + public static QoiFormat Instance { get; } = new QoiFormat(); + + /// + public QoiMetadata CreateDefaultFormatMetadata() => new(); + + /// + public string Name => "QOI"; + + /// + public string DefaultMimeType => "image/qoi"; + + /// + public IEnumerable MimeTypes => QoiConstants.MimeTypes; + + /// + public IEnumerable FileExtensions => QoiConstants.FileExtensions; +} diff --git a/src/ImageSharp/Formats/Qoi/QoiMetadata.cs b/src/ImageSharp/Formats/Qoi/QoiMetadata.cs index de6b0a7a6..11ab314a8 100644 --- a/src/ImageSharp/Formats/Qoi/QoiMetadata.cs +++ b/src/ImageSharp/Formats/Qoi/QoiMetadata.cs @@ -1,9 +1,6 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -using System.Text; -using SixLabors.ImageSharp.PixelFormats; - namespace SixLabors.ImageSharp.Formats.Qoi; ///