Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/ImageSharp/Formats/Bmp/BmpImageFormatDetector.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.

#nullable enable
using System.Buffers.Binary;

namespace SixLabors.ImageSharp.Formats.Bmp;
Expand All @@ -14,7 +15,7 @@ public sealed class BmpImageFormatDetector : IImageFormatDetector
public int HeaderSize => 2;

/// <inheritdoc/>
public IImageFormat DetectFormat(ReadOnlySpan<byte> header)
public IImageFormat? DetectFormat(ReadOnlySpan<byte> header)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I cannot decide what the best pattern for nullable return types should be. I feel like anything that returns a nullable type should probably use a TryXX(in, out..) pattern (though I still haven't found a nice async pattern for that)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like anything that returns a nullable type should probably use a TryXX(in, out..)

yeah. i was trying to do this in the least intrusive way

though I still haven't found a nice async pattern for that

neither have I

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

happy to add some TryXX overloads. but i would prefer to do those in a new PR

{
return this.IsSupportedFileFormat(header) ? BmpFormat.Instance : null;
}
Expand Down
3 changes: 2 additions & 1 deletion src/ImageSharp/Formats/Gif/GifImageFormatDetector.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.

#nullable enable
namespace SixLabors.ImageSharp.Formats.Gif;

/// <summary>
Expand All @@ -12,7 +13,7 @@ public sealed class GifImageFormatDetector : IImageFormatDetector
public int HeaderSize => 6;

/// <inheritdoc/>
public IImageFormat DetectFormat(ReadOnlySpan<byte> header)
public IImageFormat? DetectFormat(ReadOnlySpan<byte> header)
{
return this.IsSupportedFileFormat(header) ? GifFormat.Instance : null;
}
Expand Down
3 changes: 2 additions & 1 deletion src/ImageSharp/Formats/IImageFormatDetector.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.

#nullable enable
namespace SixLabors.ImageSharp.Formats;

/// <summary>
Expand All @@ -19,5 +20,5 @@ public interface IImageFormatDetector
/// </summary>
/// <param name="header">The <see cref="T:byte[]"/> containing the file header.</param>
/// <returns>returns the mime type of detected otherwise returns null</returns>
IImageFormat DetectFormat(ReadOnlySpan<byte> header);
IImageFormat? DetectFormat(ReadOnlySpan<byte> header);
}
13 changes: 7 additions & 6 deletions src/ImageSharp/Formats/ImageFormatManager.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.

#nullable enable
using System.Collections.Concurrent;

namespace SixLabors.ImageSharp.Formats;
Expand Down Expand Up @@ -92,7 +93,7 @@ public void AddImageFormat(IImageFormat format)
/// </summary>
/// <param name="extension">The extension to discover</param>
/// <returns>The <see cref="IImageFormat"/> if found otherwise null</returns>
public IImageFormat FindFormatByFileExtension(string extension)
public IImageFormat? FindFormatByFileExtension(string extension)
{
Guard.NotNullOrWhiteSpace(extension, nameof(extension));

Expand All @@ -109,7 +110,7 @@ public IImageFormat FindFormatByFileExtension(string extension)
/// </summary>
/// <param name="mimeType">The mime-type to discover</param>
/// <returns>The <see cref="IImageFormat"/> if found; otherwise null</returns>
public IImageFormat FindFormatByMimeType(string mimeType)
public IImageFormat? FindFormatByMimeType(string mimeType)
=> this.imageFormats.FirstOrDefault(x => x.MimeTypes.Contains(mimeType, StringComparer.OrdinalIgnoreCase));

/// <summary>
Expand Down Expand Up @@ -159,11 +160,11 @@ public void AddImageFormatDetector(IImageFormatDetector detector)
/// </summary>
/// <param name="format">The format to discover</param>
/// <returns>The <see cref="IImageDecoder"/> if found otherwise null</returns>
public IImageDecoder FindDecoder(IImageFormat format)
public IImageDecoder? FindDecoder(IImageFormat format)
{
Guard.NotNull(format, nameof(format));

return this.mimeTypeDecoders.TryGetValue(format, out IImageDecoder decoder)
return this.mimeTypeDecoders.TryGetValue(format, out IImageDecoder? decoder)
? decoder
: null;
}
Expand All @@ -173,11 +174,11 @@ public IImageDecoder FindDecoder(IImageFormat format)
/// </summary>
/// <param name="format">The format to discover</param>
/// <returns>The <see cref="IImageEncoder"/> if found otherwise null</returns>
public IImageEncoder FindEncoder(IImageFormat format)
public IImageEncoder? FindEncoder(IImageFormat format)
{
Guard.NotNull(format, nameof(format));

return this.mimeTypeEncoders.TryGetValue(format, out IImageEncoder encoder)
return this.mimeTypeEncoders.TryGetValue(format, out IImageEncoder? encoder)
? encoder
: null;
}
Expand Down
3 changes: 2 additions & 1 deletion src/ImageSharp/Formats/Jpeg/JpegImageFormatDetector.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.

#nullable enable
namespace SixLabors.ImageSharp.Formats.Jpeg;

/// <summary>
Expand All @@ -12,7 +13,7 @@ public sealed class JpegImageFormatDetector : IImageFormatDetector
public int HeaderSize => 11;

/// <inheritdoc/>
public IImageFormat DetectFormat(ReadOnlySpan<byte> header)
public IImageFormat? DetectFormat(ReadOnlySpan<byte> header)
=> this.IsSupportedFileFormat(header) ? JpegFormat.Instance : null;

private bool IsSupportedFileFormat(ReadOnlySpan<byte> header)
Expand Down
3 changes: 2 additions & 1 deletion src/ImageSharp/Formats/Pbm/PbmImageFormatDetector.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.

#nullable enable
namespace SixLabors.ImageSharp.Formats.Pbm;

/// <summary>
Expand All @@ -16,7 +17,7 @@ public sealed class PbmImageFormatDetector : IImageFormatDetector
public int HeaderSize => 2;

/// <inheritdoc/>
public IImageFormat DetectFormat(ReadOnlySpan<byte> header) => IsSupportedFileFormat(header) ? PbmFormat.Instance : null;
public IImageFormat? DetectFormat(ReadOnlySpan<byte> header) => IsSupportedFileFormat(header) ? PbmFormat.Instance : null;

private static bool IsSupportedFileFormat(ReadOnlySpan<byte> header)
{
Expand Down
3 changes: 2 additions & 1 deletion src/ImageSharp/Formats/Png/PngImageFormatDetector.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.

#nullable enable
using System.Buffers.Binary;

namespace SixLabors.ImageSharp.Formats.Png;
Expand All @@ -14,7 +15,7 @@ public sealed class PngImageFormatDetector : IImageFormatDetector
public int HeaderSize => 8;

/// <inheritdoc/>
public IImageFormat DetectFormat(ReadOnlySpan<byte> header)
public IImageFormat? DetectFormat(ReadOnlySpan<byte> header)
{
return this.IsSupportedFileFormat(header) ? PngFormat.Instance : null;
}
Expand Down
3 changes: 2 additions & 1 deletion src/ImageSharp/Formats/Tga/TgaImageFormatDetector.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.

#nullable enable
namespace SixLabors.ImageSharp.Formats.Tga;

/// <summary>
Expand All @@ -12,7 +13,7 @@ public sealed class TgaImageFormatDetector : IImageFormatDetector
public int HeaderSize => 16;

/// <inheritdoc/>
public IImageFormat DetectFormat(ReadOnlySpan<byte> header)
public IImageFormat? DetectFormat(ReadOnlySpan<byte> header)
{
return this.IsSupportedFileFormat(header) ? TgaFormat.Instance : null;
}
Expand Down
3 changes: 2 additions & 1 deletion src/ImageSharp/Formats/Tiff/TiffImageFormatDetector.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.

#nullable enable
namespace SixLabors.ImageSharp.Formats.Tiff;

/// <summary>
Expand All @@ -12,7 +13,7 @@ public sealed class TiffImageFormatDetector : IImageFormatDetector
public int HeaderSize => 8;

/// <inheritdoc/>
public IImageFormat DetectFormat(ReadOnlySpan<byte> header)
public IImageFormat? DetectFormat(ReadOnlySpan<byte> header)
{
if (this.IsSupportedFileFormat(header))
{
Expand Down
3 changes: 2 additions & 1 deletion src/ImageSharp/Formats/Webp/WebpImageFormatDetector.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.

#nullable enable
namespace SixLabors.ImageSharp.Formats.Webp;

/// <summary>
Expand All @@ -12,7 +13,7 @@ public sealed class WebpImageFormatDetector : IImageFormatDetector
public int HeaderSize => 12;

/// <inheritdoc />
public IImageFormat DetectFormat(ReadOnlySpan<byte> header)
public IImageFormat? DetectFormat(ReadOnlySpan<byte> header)
=> this.IsSupportedFileFormat(header) ? WebpFormat.Instance : null;

private bool IsSupportedFileFormat(ReadOnlySpan<byte> header)
Expand Down
23 changes: 12 additions & 11 deletions src/ImageSharp/Image.Decode.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.

#nullable enable
using SixLabors.ImageSharp.Formats;
using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.Metadata;
Expand Down Expand Up @@ -44,7 +45,7 @@ internal static Image<TPixel> CreateUninitialized<TPixel>(
/// <param name="configuration">The general configuration.</param>
/// <param name="stream">The image stream to read the header from.</param>
/// <returns>The mime type or null if none found.</returns>
private static IImageFormat InternalDetectFormat(Configuration configuration, Stream stream)
private static IImageFormat? InternalDetectFormat(Configuration configuration, Stream stream)
{
// We take a minimum of the stream length vs the max header size and always check below
// to ensure that only formats that headers fit within the given buffer length are tested.
Expand Down Expand Up @@ -76,12 +77,12 @@ private static IImageFormat InternalDetectFormat(Configuration configuration, St
// Does the given stream contain enough data to fit in the header for the format
// and does that data match the format specification?
// Individual formats should still check since they are public.
IImageFormat format = null;
IImageFormat? format = null;
foreach (IImageFormatDetector formatDetector in configuration.ImageFormatsManager.FormatDetectors)
{
if (formatDetector.HeaderSize <= headerSize)
{
IImageFormat attemptFormat = formatDetector.DetectFormat(headersBuffer);
IImageFormat? attemptFormat = formatDetector.DetectFormat(headersBuffer);
if (attemptFormat != null)
{
format = attemptFormat;
Expand All @@ -99,7 +100,7 @@ private static IImageFormat InternalDetectFormat(Configuration configuration, St
/// <param name="stream">The image stream to read the header from.</param>
/// <param name="format">The IImageFormat.</param>
/// <returns>The image format or null if none found.</returns>
private static IImageDecoder DiscoverDecoder(DecoderOptions options, Stream stream, out IImageFormat format)
private static IImageDecoder? DiscoverDecoder(DecoderOptions options, Stream stream, out IImageFormat? format)
{
format = InternalDetectFormat(options.Configuration, stream);

Expand All @@ -118,10 +119,10 @@ private static IImageDecoder DiscoverDecoder(DecoderOptions options, Stream stre
/// <returns>
/// A new <see cref="Image{TPixel}"/>.
/// </returns>
private static (Image<TPixel> Image, IImageFormat Format) Decode<TPixel>(DecoderOptions options, Stream stream, CancellationToken cancellationToken = default)
private static (Image<TPixel>? Image, IImageFormat? Format) Decode<TPixel>(DecoderOptions options, Stream stream, CancellationToken cancellationToken = default)
where TPixel : unmanaged, IPixel<TPixel>
{
IImageDecoder decoder = DiscoverDecoder(options, stream, out IImageFormat format);
IImageDecoder? decoder = DiscoverDecoder(options, stream, out IImageFormat? format);
if (decoder is null)
{
return (null, null);
Expand All @@ -131,9 +132,9 @@ private static (Image<TPixel> Image, IImageFormat Format) Decode<TPixel>(Decoder
return (img, format);
}

private static (Image Image, IImageFormat Format) Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken = default)
private static (Image? Image, IImageFormat? Format) Decode(DecoderOptions options, Stream stream, CancellationToken cancellationToken = default)
{
IImageDecoder decoder = DiscoverDecoder(options, stream, out IImageFormat format);
IImageDecoder? decoder = DiscoverDecoder(options, stream, out IImageFormat? format);
if (decoder is null)
{
return (null, null);
Expand All @@ -152,16 +153,16 @@ private static (Image Image, IImageFormat Format) Decode(DecoderOptions options,
/// <returns>
/// The <see cref="IImageInfo"/> or null if a suitable info detector is not found.
/// </returns>
private static (IImageInfo ImageInfo, IImageFormat Format) InternalIdentity(DecoderOptions options, Stream stream, CancellationToken cancellationToken = default)
private static (IImageInfo? ImageInfo, IImageFormat? Format) InternalIdentity(DecoderOptions options, Stream stream, CancellationToken cancellationToken = default)
{
IImageDecoder decoder = DiscoverDecoder(options, stream, out IImageFormat format);
IImageDecoder? decoder = DiscoverDecoder(options, stream, out IImageFormat? format);

if (decoder is not IImageInfoDetector detector)
{
return (null, null);
}

IImageInfo info = detector?.Identify(options, stream, cancellationToken);
IImageInfo? info = detector.Identify(options, stream, cancellationToken);
return (info, format);
}
}
21 changes: 11 additions & 10 deletions src/ImageSharp/Image.FromBytes.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.

#nullable enable
using SixLabors.ImageSharp.Formats;
using SixLabors.ImageSharp.PixelFormats;

Expand All @@ -16,7 +17,7 @@ public abstract partial class Image
/// </summary>
/// <param name="data">The byte span containing encoded image data to read the header from.</param>
/// <returns>The format or null if none found.</returns>
public static IImageFormat DetectFormat(ReadOnlySpan<byte> data)
public static IImageFormat? DetectFormat(ReadOnlySpan<byte> data)
=> DetectFormat(DecoderOptions.Default, data);

/// <summary>
Expand All @@ -26,7 +27,7 @@ public static IImageFormat DetectFormat(ReadOnlySpan<byte> data)
/// <param name="data">The byte span containing encoded image data to read the header from.</param>
/// <exception cref="ArgumentNullException">The options are null.</exception>
/// <returns>The mime type or null if none found.</returns>
public static IImageFormat DetectFormat(DecoderOptions options, ReadOnlySpan<byte> data)
public static IImageFormat? DetectFormat(DecoderOptions options, ReadOnlySpan<byte> data)
{
Guard.NotNull(options, nameof(options.Configuration));

Expand All @@ -39,7 +40,7 @@ public static IImageFormat DetectFormat(DecoderOptions options, ReadOnlySpan<byt

foreach (IImageFormatDetector detector in configuration.ImageFormatsManager.FormatDetectors)
{
IImageFormat f = detector.DetectFormat(data);
IImageFormat? f = detector.DetectFormat(data);

if (f != null)
{
Expand All @@ -59,7 +60,7 @@ public static IImageFormat DetectFormat(DecoderOptions options, ReadOnlySpan<byt
/// <returns>
/// The <see cref="IImageInfo"/> or null if suitable info detector not found.
/// </returns>
public static IImageInfo Identify(ReadOnlySpan<byte> data) => Identify(data, out IImageFormat _);
public static IImageInfo? Identify(ReadOnlySpan<byte> data) => Identify(data, out IImageFormat? _);

/// <summary>
/// Reads the raw image information from the specified stream without fully decoding it.
Expand All @@ -71,7 +72,7 @@ public static IImageFormat DetectFormat(DecoderOptions options, ReadOnlySpan<byt
/// <returns>
/// The <see cref="IImageInfo"/> or null if suitable info detector not found.
/// </returns>
public static IImageInfo Identify(ReadOnlySpan<byte> data, out IImageFormat format)
public static IImageInfo? Identify(ReadOnlySpan<byte> data, out IImageFormat? format)
=> Identify(DecoderOptions.Default, data, out format);

/// <summary>
Expand All @@ -86,7 +87,7 @@ public static IImageInfo Identify(ReadOnlySpan<byte> data, out IImageFormat form
/// <returns>
/// The <see cref="IImageInfo"/> or null if suitable info detector is not found.
/// </returns>
public static unsafe IImageInfo Identify(DecoderOptions options, ReadOnlySpan<byte> data, out IImageFormat format)
public static unsafe IImageInfo? Identify(DecoderOptions options, ReadOnlySpan<byte> data, out IImageFormat? format)
{
fixed (byte* ptr = data)
{
Expand Down Expand Up @@ -118,7 +119,7 @@ public static Image<TPixel> Load<TPixel>(ReadOnlySpan<byte> data)
/// <exception cref="InvalidImageContentException">Image contains invalid content.</exception>
/// <exception cref="NotSupportedException">Image format is not supported.</exception>
/// <returns>A new <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Load<TPixel>(ReadOnlySpan<byte> data, out IImageFormat format)
public static Image<TPixel> Load<TPixel>(ReadOnlySpan<byte> data, out IImageFormat? format)
where TPixel : unmanaged, IPixel<TPixel>
=> Load<TPixel>(DecoderOptions.Default, data, out format);

Expand Down Expand Up @@ -158,7 +159,7 @@ public static unsafe Image<TPixel> Load<TPixel>(DecoderOptions options, ReadOnly
public static unsafe Image<TPixel> Load<TPixel>(
DecoderOptions options,
ReadOnlySpan<byte> data,
out IImageFormat format)
out IImageFormat? format)
where TPixel : unmanaged, IPixel<TPixel>
{
fixed (byte* ptr = data)
Expand Down Expand Up @@ -189,7 +190,7 @@ public static Image Load(ReadOnlySpan<byte> data)
/// <exception cref="InvalidImageContentException">Image contains invalid content.</exception>
/// <exception cref="NotSupportedException">Image format is not supported.</exception>
/// <returns>The <see cref="Image"/>.</returns>
public static Image Load(ReadOnlySpan<byte> data, out IImageFormat format)
public static Image Load(ReadOnlySpan<byte> data, out IImageFormat? format)
=> Load(DecoderOptions.Default, data, out format);

/// <summary>
Expand All @@ -215,7 +216,7 @@ public static Image Load(DecoderOptions options, ReadOnlySpan<byte> data)
public static unsafe Image Load(
DecoderOptions options,
ReadOnlySpan<byte> data,
out IImageFormat format)
out IImageFormat? format)
{
fixed (byte* ptr = data)
{
Expand Down
Loading