Browse Source

Introduce InvalidImageContentException, document and guard all load methods

pull/1179/head
James Jackson-South 6 years ago
parent
commit
ad6da51a3d
  1. 22
      src/ImageSharp/Common/Exceptions/InvalidImageContentException.cs
  2. 10
      src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs
  3. 2
      src/ImageSharp/Formats/Bmp/BmpInfoHeader.cs
  4. 16
      src/ImageSharp/Formats/Bmp/BmpThrowHelper.cs
  5. 2
      src/ImageSharp/Formats/Gif/GifDecoderCore.cs
  6. 18
      src/ImageSharp/Formats/Gif/GifThrowHelper.cs
  7. 4
      src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYCbCrSimd.cs
  8. 4
      src/ImageSharp/Formats/Jpeg/Components/Decoder/JFifMarker.cs
  9. 18
      src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs
  10. 27
      src/ImageSharp/Formats/Jpeg/JpegThrowHelper.cs
  11. 10
      src/ImageSharp/Formats/Png/PngThrowHelper.cs
  12. 6
      src/ImageSharp/Formats/Tga/TgaDecoderCore.cs
  13. 14
      src/ImageSharp/Formats/Tga/TgaThrowHelper.cs
  14. 147
      src/ImageSharp/Image.FromBytes.cs
  15. 119
      src/ImageSharp/Image.FromFile.cs
  16. 131
      src/ImageSharp/Image.FromStream.cs
  17. 43
      src/ImageSharp/Image.LoadPixelData.cs
  18. 50
      src/ImageSharp/Image.WrapMemory.cs

22
src/ImageSharp/Common/Exceptions/InvalidImageContentException.cs

@ -0,0 +1,22 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
namespace SixLabors.ImageSharp
{
/// <summary>
/// The exception that is thrown when the library tries to load
/// an image which contains invalid content.
/// </summary>
public sealed class InvalidImageContentException : ImageFormatException
{
/// <summary>
/// Initializes a new instance of the <see cref="InvalidImageContentException"/> class with the name of the
/// parameter that causes this exception.
/// </summary>
/// <param name="errorMessage">The error message that explains the reason for this exception.</param>
public InvalidImageContentException(string errorMessage)
: base(errorMessage)
{
}
}
}

10
src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs

@ -462,7 +462,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp
{
if (this.stream.Read(cmd, 0, cmd.Length) != 2)
{
BmpThrowHelper.ThrowImageFormatException("Failed to read 2 bytes from the stream while uncompressing RLE4 bitmap.");
BmpThrowHelper.ThrowInvalidImageContentException("Failed to read 2 bytes from the stream while uncompressing RLE4 bitmap.");
}
if (cmd[0] == RleCommand)
@ -569,7 +569,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp
{
if (this.stream.Read(cmd, 0, cmd.Length) != 2)
{
BmpThrowHelper.ThrowImageFormatException("Failed to read 2 bytes from stream while uncompressing RLE8 bitmap.");
BmpThrowHelper.ThrowInvalidImageContentException("Failed to read 2 bytes from stream while uncompressing RLE8 bitmap.");
}
if (cmd[0] == RleCommand)
@ -648,7 +648,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp
{
if (this.stream.Read(cmd, 0, cmd.Length) != 2)
{
BmpThrowHelper.ThrowImageFormatException("Failed to read 2 bytes from stream while uncompressing RLE24 bitmap.");
BmpThrowHelper.ThrowInvalidImageContentException("Failed to read 2 bytes from stream while uncompressing RLE24 bitmap.");
}
if (cmd[0] == RleCommand)
@ -1431,7 +1431,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp
// Make sure, that we will not read pass the bitmap offset (starting position of image data).
if ((this.stream.Position + colorMapSizeBytes) > this.fileHeader.Offset)
{
BmpThrowHelper.ThrowImageFormatException(
BmpThrowHelper.ThrowInvalidImageContentException(
$"Reading the color map would read beyond the bitmap offset. Either the color map size of '{colorMapSizeBytes}' is invalid or the bitmap offset.");
}
@ -1445,7 +1445,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp
int skipAmount = this.fileHeader.Offset - (int)this.stream.Position;
if ((skipAmount + (int)this.stream.Position) > this.stream.Length)
{
BmpThrowHelper.ThrowImageFormatException("Invalid fileheader offset found. Offset is greater than the stream length.");
BmpThrowHelper.ThrowInvalidImageContentException("Invalid fileheader offset found. Offset is greater than the stream length.");
}
if (skipAmount > 0)

2
src/ImageSharp/Formats/Bmp/BmpInfoHeader.cs

@ -393,7 +393,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp
break;
default:
// Compression type 3 (1DHuffman) is not supported.
BmpThrowHelper.ThrowImageFormatException("Compression type is not supported. ImageSharp only supports uncompressed, RLE4, RLE8 and RLE24.");
BmpThrowHelper.ThrowInvalidImageContentException("Compression type is not supported. ImageSharp only supports uncompressed, RLE4, RLE8 and RLE24.");
break;
}

16
src/ImageSharp/Formats/Bmp/BmpThrowHelper.cs

@ -1,4 +1,4 @@
// Copyright (c) Six Labors and contributors.
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System;
@ -9,23 +9,19 @@ namespace SixLabors.ImageSharp.Formats.Bmp
internal static class BmpThrowHelper
{
/// <summary>
/// Cold path optimization for throwing <see cref="ImageFormatException"/>-s
/// Cold path optimization for throwing <see cref="InvalidImageContentException"/>'s
/// </summary>
/// <param name="errorMessage">The error message for the exception.</param>
[MethodImpl(MethodImplOptions.NoInlining)]
public static void ThrowImageFormatException(string errorMessage)
{
throw new ImageFormatException(errorMessage);
}
public static void ThrowInvalidImageContentException(string errorMessage)
=> throw new InvalidImageContentException(errorMessage);
/// <summary>
/// Cold path optimization for throwing <see cref="NotSupportedException"/>-s
/// Cold path optimization for throwing <see cref="NotSupportedException"/>'s
/// </summary>
/// <param name="errorMessage">The error message for the exception.</param>
[MethodImpl(MethodImplOptions.NoInlining)]
public static void ThrowNotSupportedException(string errorMessage)
{
throw new NotSupportedException(errorMessage);
}
=> throw new NotSupportedException(errorMessage);
}
}

2
src/ImageSharp/Formats/Gif/GifDecoderCore.cs

@ -318,7 +318,7 @@ namespace SixLabors.ImageSharp.Formats.Gif
{
if (length > GifConstants.MaxCommentSubBlockLength)
{
throw new ImageFormatException($"Gif comment length '{length}' exceeds max '{GifConstants.MaxCommentSubBlockLength}' of a comment data block");
GifThrowHelper.ThrowInvalidImageContentException($"Gif comment length '{length}' exceeds max '{GifConstants.MaxCommentSubBlockLength}' of a comment data block");
}
if (this.IgnoreMetadata)

18
src/ImageSharp/Formats/Gif/GifThrowHelper.cs

@ -0,0 +1,18 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System.Runtime.CompilerServices;
namespace SixLabors.ImageSharp.Formats.Gif
{
internal static class GifThrowHelper
{
/// <summary>
/// Cold path optimization for throwing <see cref="InvalidImageContentException"/>'s
/// </summary>
/// <param name="errorMessage">The error message for the exception.</param>
[MethodImpl(MethodImplOptions.NoInlining)]
public static void ThrowInvalidImageContentException(string errorMessage)
=> throw new InvalidImageContentException(errorMessage);
}
}

4
src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYCbCrSimd.cs

@ -1,4 +1,4 @@
// Copyright (c) Six Labors and contributors.
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System;
@ -104,7 +104,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
{
// TODO: Run fallback scalar code here
// However, no issues expected before someone implements this: https://github.com/dotnet/coreclr/issues/12007
throw new NotImplementedException("Your CPU architecture is too modern!");
JpegThrowHelper.ThrowNotImplementedException("Your CPU architecture is too modern!");
}
// Collect (r0,r1...r8) (g0,g1...g8) (b0,b1...b8) vector values in the expected (r0,g0,g1,1), (r1,g1,g2,1) ... order:

4
src/ImageSharp/Formats/Jpeg/Components/Decoder/JFifMarker.cs

@ -29,12 +29,12 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder
{
if (xDensity <= 0)
{
JpegThrowHelper.ThrowImageFormatException($"X-Density {xDensity} must be greater than 0.");
JpegThrowHelper.ThrowInvalidImageContentException($"X-Density {xDensity} must be greater than 0.");
}
if (yDensity <= 0)
{
JpegThrowHelper.ThrowImageFormatException($"Y-Density {yDensity} must be greater than 0.");
JpegThrowHelper.ThrowInvalidImageContentException($"Y-Density {yDensity} must be greater than 0.");
}
this.MajorVersion = majorVersion;

18
src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs

@ -259,7 +259,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
var fileMarker = new JpegFileMarker(this.markerBuffer[1], 0);
if (fileMarker.Marker != JpegConstants.Markers.SOI)
{
JpegThrowHelper.ThrowImageFormatException("Missing SOI marker.");
JpegThrowHelper.ThrowInvalidImageContentException("Missing SOI marker.");
}
this.InputStream.Read(this.markerBuffer, 0, 2);
@ -423,7 +423,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
: JpegColorSpace.Cmyk;
}
JpegThrowHelper.ThrowImageFormatException($"Unsupported color mode. Supported component counts 1, 3, and 4; found {this.ComponentCount}");
JpegThrowHelper.ThrowInvalidImageContentException($"Unsupported color mode. Supported component counts 1, 3, and 4; found {this.ComponentCount}");
return default;
}
@ -821,7 +821,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
{
if (this.Frame != null)
{
JpegThrowHelper.ThrowImageFormatException("Multiple SOF markers. Only single frame jpegs supported.");
JpegThrowHelper.ThrowInvalidImageContentException("Multiple SOF markers. Only single frame jpegs supported.");
}
// Read initial marker definitions.
@ -831,7 +831,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
// We only support 8-bit and 12-bit precision.
if (Array.IndexOf(this.supportedPrecisions, this.temp[0]) == -1)
{
JpegThrowHelper.ThrowImageFormatException("Only 8-Bit and 12-Bit precision supported.");
JpegThrowHelper.ThrowInvalidImageContentException("Only 8-Bit and 12-Bit precision supported.");
}
this.Precision = this.temp[0];
@ -928,13 +928,13 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
// Types 0..1 DC..AC
if (tableType > 1)
{
JpegThrowHelper.ThrowImageFormatException("Bad Huffman Table type.");
JpegThrowHelper.ThrowInvalidImageContentException("Bad Huffman Table type.");
}
// Max tables of each type
if (tableIndex > 3)
{
JpegThrowHelper.ThrowImageFormatException("Bad Huffman Table index.");
JpegThrowHelper.ThrowInvalidImageContentException("Bad Huffman Table index.");
}
this.InputStream.Read(huffmanData.Array, 0, 16);
@ -953,7 +953,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
if (codeLengthSum > 256 || codeLengthSum > length)
{
JpegThrowHelper.ThrowImageFormatException("Huffman table has excessive length.");
JpegThrowHelper.ThrowInvalidImageContentException("Huffman table has excessive length.");
}
using (IManagedByteBuffer huffmanValues = this.configuration.MemoryAllocator.AllocateManagedByteBuffer(256, AllocationOptions.Clean))
@ -995,7 +995,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
{
if (this.Frame is null)
{
JpegThrowHelper.ThrowImageFormatException("No readable SOFn (Start Of Frame) marker found.");
JpegThrowHelper.ThrowInvalidImageContentException("No readable SOFn (Start Of Frame) marker found.");
}
int selectorsCount = this.InputStream.ReadByte();
@ -1016,7 +1016,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
if (componentIndex < 0)
{
JpegThrowHelper.ThrowImageFormatException($"Unknown component selector {componentIndex}.");
JpegThrowHelper.ThrowInvalidImageContentException($"Unknown component selector {componentIndex}.");
}
ref JpegComponent component = ref this.Frame.Components[componentIndex];

27
src/ImageSharp/Formats/Jpeg/JpegThrowHelper.cs

@ -1,6 +1,7 @@
// Copyright (c) Six Labors and contributors.
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System;
using System.Runtime.CompilerServices;
namespace SixLabors.ImageSharp.Formats.Jpeg
@ -8,25 +9,33 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
internal static class JpegThrowHelper
{
/// <summary>
/// Cold path optimization for throwing <see cref="ImageFormatException"/>'s.
/// Cold path optimization for throwing <see cref="InvalidImageContentException"/>'s.
/// </summary>
/// <param name="errorMessage">The error message for the exception.</param>
[MethodImpl(InliningOptions.ColdPath)]
public static void ThrowImageFormatException(string errorMessage) => throw new ImageFormatException(errorMessage);
public static void ThrowInvalidImageContentException(string errorMessage) => throw new InvalidImageContentException(errorMessage);
/// <summary>
/// Cold path optimization for throwing <see cref="NotImplementedException"/>'s
/// </summary>
/// <param name="errorMessage">The error message for the exception.</param>
[MethodImpl(InliningOptions.ColdPath)]
public static void ThrowNotImplementedException(string errorMessage)
=> throw new NotImplementedException(errorMessage);
[MethodImpl(InliningOptions.ColdPath)]
public static void ThrowBadMarker(string marker, int length) => throw new ImageFormatException($"Marker {marker} has bad length {length}.");
public static void ThrowBadMarker(string marker, int length) => throw new InvalidImageContentException($"Marker {marker} has bad length {length}.");
[MethodImpl(InliningOptions.ColdPath)]
public static void ThrowBadQuantizationTable() => throw new ImageFormatException("Bad Quantization Table index.");
public static void ThrowBadQuantizationTable() => throw new InvalidImageContentException("Bad Quantization Table index.");
[MethodImpl(InliningOptions.ColdPath)]
public static void ThrowBadSampling() => throw new ImageFormatException("Bad sampling factor.");
public static void ThrowBadSampling() => throw new InvalidImageContentException("Bad sampling factor.");
[MethodImpl(InliningOptions.ColdPath)]
public static void ThrowBadProgressiveScan(int ss, int se, int ah, int al) => throw new ImageFormatException($"Invalid progressive parameters Ss={ss} Se={se} Ah={ah} Al={al}.");
public static void ThrowBadProgressiveScan(int ss, int se, int ah, int al) => throw new InvalidImageContentException($"Invalid progressive parameters Ss={ss} Se={se} Ah={ah} Al={al}.");
[MethodImpl(InliningOptions.ColdPath)]
public static void ThrowInvalidImageDimensions(int width, int height) => throw new ImageFormatException($"Invalid image dimensions: {width}x{height}.");
public static void ThrowInvalidImageDimensions(int width, int height) => throw new InvalidImageContentException($"Invalid image dimensions: {width}x{height}.");
}
}
}

10
src/ImageSharp/Formats/Png/PngThrowHelper.cs

@ -12,21 +12,21 @@ namespace SixLabors.ImageSharp.Formats.Png
internal static class PngThrowHelper
{
[MethodImpl(InliningOptions.ColdPath)]
public static void ThrowNoHeader() => throw new ImageFormatException("PNG Image does not contain a header chunk");
public static void ThrowNoHeader() => throw new InvalidImageContentException("PNG Image does not contain a header chunk");
[MethodImpl(InliningOptions.ColdPath)]
public static void ThrowNoData() => throw new ImageFormatException("PNG Image does not contain a data chunk");
public static void ThrowNoData() => throw new InvalidImageContentException("PNG Image does not contain a data chunk");
[MethodImpl(InliningOptions.ColdPath)]
public static void ThrowInvalidChunkType() => throw new ImageFormatException("Invalid PNG data.");
public static void ThrowInvalidChunkType() => throw new InvalidImageContentException("Invalid PNG data.");
[MethodImpl(InliningOptions.ColdPath)]
public static void ThrowInvalidChunkCrc(string chunkTypeName) => throw new ImageFormatException($"CRC Error. PNG {chunkTypeName} chunk is corrupt!");
public static void ThrowInvalidChunkCrc(string chunkTypeName) => throw new InvalidImageContentException($"CRC Error. PNG {chunkTypeName} chunk is corrupt!");
[MethodImpl(InliningOptions.ColdPath)]
public static void ThrowNotSupportedColor() => new NotSupportedException("Unsupported PNG color type");
[MethodImpl(InliningOptions.ColdPath)]
public static void ThrowUnknownFilter() => throw new ImageFormatException("Unknown filter type.");
public static void ThrowUnknownFilter() => throw new InvalidImageContentException("Unknown filter type.");
}
}

6
src/ImageSharp/Formats/Tga/TgaDecoderCore.cs

@ -114,12 +114,12 @@ namespace SixLabors.ImageSharp.Formats.Tga
{
if (this.fileHeader.CMapLength <= 0)
{
TgaThrowHelper.ThrowImageFormatException("Missing tga color map length");
TgaThrowHelper.ThrowInvalidImageContentException("Missing tga color map length");
}
if (this.fileHeader.CMapDepth <= 0)
{
TgaThrowHelper.ThrowImageFormatException("Missing tga color map depth");
TgaThrowHelper.ThrowInvalidImageContentException("Missing tga color map depth");
}
int colorMapPixelSizeInBytes = this.fileHeader.CMapDepth / 8;
@ -898,7 +898,7 @@ namespace SixLabors.ImageSharp.Formats.Tga
var alphaBits = this.fileHeader.ImageDescriptor & 0xf;
if (alphaBits != 0 && alphaBits != 1 && alphaBits != 8)
{
TgaThrowHelper.ThrowImageFormatException("Invalid alpha channel bits");
TgaThrowHelper.ThrowInvalidImageContentException("Invalid alpha channel bits");
}
this.tgaMetadata.AlphaChannelBits = (byte)alphaBits;

14
src/ImageSharp/Formats/Tga/TgaThrowHelper.cs

@ -9,23 +9,19 @@ namespace SixLabors.ImageSharp.Formats.Tga
internal static class TgaThrowHelper
{
/// <summary>
/// Cold path optimization for throwing <see cref="ImageFormatException"/>-s
/// Cold path optimization for throwing <see cref="ImageFormatException"/>'s
/// </summary>
/// <param name="errorMessage">The error message for the exception.</param>
[MethodImpl(MethodImplOptions.NoInlining)]
public static void ThrowImageFormatException(string errorMessage)
{
throw new ImageFormatException(errorMessage);
}
public static void ThrowInvalidImageContentException(string errorMessage)
=> throw new InvalidImageContentException(errorMessage);
/// <summary>
/// Cold path optimization for throwing <see cref="NotSupportedException"/>-s
/// Cold path optimization for throwing <see cref="NotSupportedException"/>'s
/// </summary>
/// <param name="errorMessage">The error message for the exception.</param>
[MethodImpl(MethodImplOptions.NoInlining)]
public static void ThrowNotSupportedException(string errorMessage)
{
throw new NotSupportedException(errorMessage);
}
=> throw new NotSupportedException(errorMessage);
}
}

147
src/ImageSharp/Image.FromBytes.cs

@ -17,21 +17,23 @@ namespace SixLabors.ImageSharp
/// By reading the header on the provided byte array this calculates the images format.
/// </summary>
/// <param name="data">The byte array containing encoded image data to read the header from.</param>
/// <exception cref="ArgumentNullException">The data is null.</exception>
/// <returns>The format or null if none found.</returns>
public static IImageFormat DetectFormat(byte[] data)
{
return DetectFormat(Configuration.Default, data);
}
=> DetectFormat(Configuration.Default, data);
/// <summary>
/// By reading the header on the provided byte array this calculates the images format.
/// </summary>
/// <param name="configuration">The configuration.</param>
/// <param name="data">The byte array containing encoded image data to read the header from.</param>
/// <exception cref="ArgumentNullException">The configuration is null.</exception>
/// <exception cref="ArgumentNullException">The data is null.</exception>
/// <returns>The mime type or null if none found.</returns>
public static IImageFormat DetectFormat(Configuration configuration, byte[] data)
{
Guard.NotNull(configuration, nameof(configuration));
Guard.NotNull(data, nameof(data));
using (var stream = new MemoryStream(data, 0, data.Length, false, true))
{
return DetectFormat(configuration, stream);
@ -42,7 +44,8 @@ namespace SixLabors.ImageSharp
/// Reads the raw image information from the specified stream without fully decoding it.
/// </summary>
/// <param name="data">The byte array containing encoded image data to read the header from.</param>
/// <exception cref="NotSupportedException">Thrown if the stream is not readable.</exception>
/// <exception cref="ArgumentNullException">The data is null.</exception>
/// <exception cref="NotSupportedException">The data is not readable.</exception>
/// <returns>
/// The <see cref="IImageInfo"/> or null if suitable info detector not found.
/// </returns>
@ -53,7 +56,8 @@ namespace SixLabors.ImageSharp
/// </summary>
/// <param name="data">The byte array containing encoded image data to read the header from.</param>
/// <param name="format">The format type of the decoded image.</param>
/// <exception cref="NotSupportedException">Thrown if the stream is not readable.</exception>
/// <exception cref="ArgumentNullException">The data is null.</exception>
/// <exception cref="NotSupportedException">The data is not readable.</exception>
/// <returns>
/// The <see cref="IImageInfo"/> or null if suitable info detector not found.
/// </returns>
@ -65,13 +69,16 @@ namespace SixLabors.ImageSharp
/// <param name="configuration">The configuration.</param>
/// <param name="data">The byte array containing encoded image data to read the header from.</param>
/// <param name="format">The format type of the decoded image.</param>
/// <exception cref="NotSupportedException">Thrown if the stream is not readable.</exception>
/// <exception cref="ArgumentNullException">The configuration is null.</exception>
/// <exception cref="ArgumentNullException">The data is null.</exception>
/// <exception cref="NotSupportedException">The data is not readable.</exception>
/// <returns>
/// The <see cref="IImageInfo"/> or null if suitable info detector is not found.
/// </returns>
public static IImageInfo Identify(Configuration configuration, byte[] data, out IImageFormat format)
{
Guard.NotNull(configuration, nameof(configuration));
Guard.NotNull(data, nameof(data));
using (var stream = new MemoryStream(data, 0, data.Length, false, true))
{
return Identify(configuration, stream, out format);
@ -82,14 +89,20 @@ namespace SixLabors.ImageSharp
/// Load a new instance of <see cref="Image{Rgba32}"/> from the given encoded byte array.
/// </summary>
/// <param name="data">The byte array containing image data.</param>
/// <exception cref="ArgumentNullException">The configuration is null.</exception>
/// <exception cref="ArgumentNullException">The data is null.</exception>
/// <returns>A new <see cref="Image{Rgba32}"/>.</returns>
public static Image<Rgba32> Load(byte[] data) => Load<Rgba32>(Configuration.Default, data);
public static Image<Rgba32> Load(byte[] data)
=> Load<Rgba32>(Configuration.Default, data);
/// <summary>
/// Load a new instance of <see cref="Image{TPixel}"/> from the given encoded byte array.
/// </summary>
/// <param name="data">The byte array containing encoded image data.</param>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <exception cref="ArgumentNullException">The data is null.</exception>
/// <exception cref="UnknownImageFormatException">Image format not recognised.</exception>
/// <exception cref="InvalidImageContentException">Image contains invalid content.</exception>
/// <returns>A new <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Load<TPixel>(byte[] data)
where TPixel : unmanaged, IPixel<TPixel>
@ -101,6 +114,9 @@ namespace SixLabors.ImageSharp
/// <param name="data">The byte array containing image data.</param>
/// <param name="format">The mime type of the decoded image.</param>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <exception cref="ArgumentNullException">The data is null.</exception>
/// <exception cref="UnknownImageFormatException">Image format not recognised.</exception>
/// <exception cref="InvalidImageContentException">Image contains invalid content.</exception>
/// <returns>A new <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Load<TPixel>(byte[] data, out IImageFormat format)
where TPixel : unmanaged, IPixel<TPixel>
@ -112,10 +128,16 @@ namespace SixLabors.ImageSharp
/// <param name="configuration">The configuration options.</param>
/// <param name="data">The byte array containing encoded image data.</param>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <exception cref="ArgumentNullException">The configuration is null.</exception>
/// <exception cref="ArgumentNullException">The data is null.</exception>
/// <exception cref="UnknownImageFormatException">Image format not recognised.</exception>
/// <exception cref="InvalidImageContentException">Image contains invalid content.</exception>
/// <returns>A new <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Load<TPixel>(Configuration configuration, byte[] data)
where TPixel : unmanaged, IPixel<TPixel>
{
Guard.NotNull(data, nameof(data));
using (var stream = new MemoryStream(data, 0, data.Length, false, true))
{
return Load<TPixel>(configuration, stream);
@ -129,10 +151,16 @@ namespace SixLabors.ImageSharp
/// <param name="data">The byte array containing encoded image data.</param>
/// <param name="format">The <see cref="IImageFormat"/> of the decoded image.</param>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <exception cref="ArgumentNullException">The configuration is null.</exception>
/// <exception cref="ArgumentNullException">The data is null.</exception>
/// <exception cref="UnknownImageFormatException">Image format not recognised.</exception>
/// <exception cref="InvalidImageContentException">Image contains invalid content.</exception>
/// <returns>A new <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Load<TPixel>(Configuration configuration, byte[] data, out IImageFormat format)
where TPixel : unmanaged, IPixel<TPixel>
{
Guard.NotNull(data, nameof(data));
using (var stream = new MemoryStream(data, 0, data.Length, false, true))
{
return Load<TPixel>(configuration, stream, out format);
@ -145,10 +173,15 @@ namespace SixLabors.ImageSharp
/// <param name="data">The byte array containing encoded image data.</param>
/// <param name="decoder">The decoder.</param>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <exception cref="ArgumentNullException">The data is null.</exception>
/// <exception cref="UnknownImageFormatException">Image format not recognised.</exception>
/// <exception cref="InvalidImageContentException">Image contains invalid content.</exception>
/// <returns>A new <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Load<TPixel>(byte[] data, IImageDecoder decoder)
where TPixel : unmanaged, IPixel<TPixel>
{
Guard.NotNull(data, nameof(data));
using (var stream = new MemoryStream(data, 0, data.Length, false, true))
{
return Load<TPixel>(stream, decoder);
@ -162,10 +195,16 @@ namespace SixLabors.ImageSharp
/// <param name="data">The byte array containing encoded image data.</param>
/// <param name="decoder">The decoder.</param>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <exception cref="ArgumentNullException">The configuration is null.</exception>
/// <exception cref="ArgumentNullException">The data is null.</exception>
/// <exception cref="UnknownImageFormatException">Image format not recognised.</exception>
/// <exception cref="InvalidImageContentException">Image contains invalid content.</exception>
/// <returns>A new <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Load<TPixel>(Configuration configuration, byte[] data, IImageDecoder decoder)
where TPixel : unmanaged, IPixel<TPixel>
{
Guard.NotNull(data, nameof(data));
using (var stream = new MemoryStream(data, 0, data.Length, false, true))
{
return Load<TPixel>(configuration, stream, decoder);
@ -173,9 +212,9 @@ namespace SixLabors.ImageSharp
}
/// <summary>
/// By reading the header on the provided byte array this calculates the images format.
/// By reading the header on the provided byte span this calculates the images format.
/// </summary>
/// <param name="data">The byte array containing encoded image data to read the header from.</param>
/// <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)
{
@ -183,13 +222,16 @@ namespace SixLabors.ImageSharp
}
/// <summary>
/// By reading the header on the provided byte array this calculates the images format.
/// By reading the header on the provided byte span this calculates the images format.
/// </summary>
/// <param name="configuration">The configuration.</param>
/// <param name="data">The byte array containing encoded image data to read the header from.</param>
/// <param name="data">The byte span containing encoded image data to read the header from.</param>
/// <exception cref="ArgumentNullException">The configuration is null.</exception>
/// <returns>The mime type or null if none found.</returns>
public static IImageFormat DetectFormat(Configuration configuration, ReadOnlySpan<byte> data)
{
Guard.NotNull(configuration, nameof(configuration));
int maxHeaderSize = configuration.MaxHeaderSize;
if (maxHeaderSize <= 0)
{
@ -214,28 +256,34 @@ namespace SixLabors.ImageSharp
/// </summary>
/// <param name="data">The byte span containing encoded image data.</param>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <exception cref="UnknownImageFormatException">Image format not recognised.</exception>
/// <exception cref="InvalidImageContentException">Image contains invalid content.</exception>
/// <returns>A new <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Load<TPixel>(ReadOnlySpan<byte> data)
where TPixel : unmanaged, IPixel<TPixel>
=> Load<TPixel>(Configuration.Default, data);
/// <summary>
/// Load a new instance of <see cref="Image{TPixel}"/> from the given encoded byte array.
/// Load a new instance of <see cref="Image{TPixel}"/> from the given encoded byte span.
/// </summary>
/// <param name="data">The byte span containing image data.</param>
/// <param name="format">The mime type of the decoded image.</param>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <exception cref="UnknownImageFormatException">Image format not recognised.</exception>
/// <exception cref="InvalidImageContentException">Image contains invalid content.</exception>
/// <returns>A new <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Load<TPixel>(ReadOnlySpan<byte> data, out IImageFormat format)
where TPixel : unmanaged, IPixel<TPixel>
=> Load<TPixel>(Configuration.Default, data, out format);
/// <summary>
/// Load a new instance of <see cref="Image{TPixel}"/> from the given encoded byte array.
/// Load a new instance of <see cref="Image{TPixel}"/> from the given encoded byte span.
/// </summary>
/// <param name="data">The byte span containing encoded image data.</param>
/// <param name="decoder">The decoder.</param>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <exception cref="UnknownImageFormatException">Image format not recognised.</exception>
/// <exception cref="InvalidImageContentException">Image contains invalid content.</exception>
/// <returns>A new <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Load<TPixel>(ReadOnlySpan<byte> data, IImageDecoder decoder)
where TPixel : unmanaged, IPixel<TPixel>
@ -247,6 +295,9 @@ namespace SixLabors.ImageSharp
/// <param name="configuration">The configuration options.</param>
/// <param name="data">The byte span containing encoded image data.</param>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <exception cref="ArgumentNullException">The configuration is null.</exception>
/// <exception cref="UnknownImageFormatException">Image format not recognised.</exception>
/// <exception cref="InvalidImageContentException">Image contains invalid content.</exception>
/// <returns>A new <see cref="Image{TPixel}"/>.</returns>
public static unsafe Image<TPixel> Load<TPixel>(Configuration configuration, ReadOnlySpan<byte> data)
where TPixel : unmanaged, IPixel<TPixel>
@ -267,6 +318,9 @@ namespace SixLabors.ImageSharp
/// <param name="data">The byte span containing image data.</param>
/// <param name="decoder">The decoder.</param>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <exception cref="ArgumentNullException">The configuration is null.</exception>
/// <exception cref="UnknownImageFormatException">Image format not recognised.</exception>
/// <exception cref="InvalidImageContentException">Image contains invalid content.</exception>
/// <returns>A new <see cref="Image{TPixel}"/>.</returns>
public static unsafe Image<TPixel> Load<TPixel>(
Configuration configuration,
@ -290,6 +344,9 @@ namespace SixLabors.ImageSharp
/// <param name="data">The byte span containing image data.</param>
/// <param name="format">The <see cref="IImageFormat"/> of the decoded image.</param>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <exception cref="ArgumentNullException">The configuration is null.</exception>
/// <exception cref="UnknownImageFormatException">Image format not recognised.</exception>
/// <exception cref="InvalidImageContentException">Image contains invalid content.</exception>
/// <returns>A new <see cref="Image{TPixel}"/>.</returns>
public static unsafe Image<TPixel> Load<TPixel>(
Configuration configuration,
@ -311,25 +368,38 @@ namespace SixLabors.ImageSharp
/// </summary>
/// <param name="data">The byte array containing image data.</param>
/// <param name="format">The detected format.</param>
/// <exception cref="ArgumentNullException">The configuration is null.</exception>
/// <exception cref="ArgumentNullException">The data is null.</exception>
/// <exception cref="UnknownImageFormatException">Image format not recognised.</exception>
/// <exception cref="InvalidImageContentException">Image contains invalid content.</exception>
/// <returns>The <see cref="Image"/>.</returns>
public static Image Load(byte[] data, out IImageFormat format) =>
Load(Configuration.Default, data, out format);
public static Image Load(byte[] data, out IImageFormat format)
=> Load(Configuration.Default, data, out format);
/// <summary>
/// Load a new instance of <see cref="Image"/> from the given encoded byte array.
/// </summary>
/// <param name="data">The byte array containing encoded image data.</param>
/// <param name="decoder">The decoder.</param>
/// <exception cref="ArgumentNullException">The data is null.</exception>
/// <exception cref="UnknownImageFormatException">Image format not recognised.</exception>
/// <exception cref="InvalidImageContentException">Image contains invalid content.</exception>
/// <returns>The <see cref="Image"/>.</returns>
public static Image Load(byte[] data, IImageDecoder decoder) => Load(Configuration.Default, data, decoder);
public static Image Load(byte[] data, IImageDecoder decoder)
=> Load(Configuration.Default, data, decoder);
/// <summary>
/// Load a new instance of <see cref="Image"/> from the given encoded byte array.
/// </summary>
/// <param name="configuration">The configuration for the decoder.</param>
/// <param name="data">The byte array containing encoded image data.</param>
/// <exception cref="ArgumentNullException">The configuration is null.</exception>
/// <exception cref="ArgumentNullException">The data is null.</exception>
/// <exception cref="UnknownImageFormatException">Image format not recognised.</exception>
/// <exception cref="InvalidImageContentException">Image contains invalid content.</exception>
/// <returns>The <see cref="Image"/>.</returns>
public static Image Load(Configuration configuration, byte[] data) => Load(configuration, data, out _);
public static Image Load(Configuration configuration, byte[] data)
=> Load(configuration, data, out _);
/// <summary>
/// Load a new instance of <see cref="Image"/> from the given encoded byte array.
@ -337,6 +407,10 @@ namespace SixLabors.ImageSharp
/// <param name="configuration">The configuration for the decoder.</param>
/// <param name="data">The byte array containing image data.</param>
/// <param name="decoder">The decoder.</param>
/// <exception cref="ArgumentNullException">The configuration is null.</exception>
/// <exception cref="ArgumentNullException">The data is null.</exception>
/// <exception cref="UnknownImageFormatException">Image format not recognised.</exception>
/// <exception cref="InvalidImageContentException">Image contains invalid content.</exception>
/// <returns>The <see cref="Image"/>.</returns>
public static Image Load(Configuration configuration, byte[] data, IImageDecoder decoder)
{
@ -352,6 +426,10 @@ namespace SixLabors.ImageSharp
/// <param name="configuration">The configuration for the decoder.</param>
/// <param name="data">The byte array containing image data.</param>
/// <param name="format">The mime type of the decoded image.</param>
/// <exception cref="ArgumentNullException">The configuration is null.</exception>
/// <exception cref="ArgumentNullException">The data is null.</exception>
/// <exception cref="UnknownImageFormatException">Image format not recognised.</exception>
/// <exception cref="InvalidImageContentException">Image contains invalid content.</exception>
/// <returns>The <see cref="Image"/>.</returns>
public static Image Load(Configuration configuration, byte[] data, out IImageFormat format)
{
@ -365,26 +443,36 @@ namespace SixLabors.ImageSharp
/// Load a new instance of <see cref="Image"/> from the given encoded byte span.
/// </summary>
/// <param name="data">The byte span containing image data.</param>
/// <exception cref="UnknownImageFormatException">Image format not recognised.</exception>
/// <exception cref="InvalidImageContentException">Image contains invalid content.</exception>
/// <returns>The <see cref="Image"/>.</returns>
public static Image Load(ReadOnlySpan<byte> data) => Load(Configuration.Default, data);
public static Image Load(ReadOnlySpan<byte> data)
=> Load(Configuration.Default, data);
/// <summary>
/// Load a new instance of <see cref="Image"/> from the given encoded byte span.
/// </summary>
/// <param name="data">The byte span containing image data.</param>
/// <param name="decoder">The decoder.</param>
/// <exception cref="ArgumentNullException">The data is null.</exception>
/// <exception cref="ArgumentNullException">The decoder is null.</exception>
/// <exception cref="UnknownImageFormatException">Image format not recognised.</exception>
/// <exception cref="InvalidImageContentException">Image contains invalid content.</exception>
/// <returns>The <see cref="Image"/>.</returns>
public static Image Load(ReadOnlySpan<byte> data, IImageDecoder decoder) =>
Load(Configuration.Default, data, decoder);
public static Image Load(ReadOnlySpan<byte> data, IImageDecoder decoder)
=> Load(Configuration.Default, data, decoder);
/// <summary>
/// Load a new instance of <see cref="Image"/> from the given encoded byte array.
/// </summary>
/// <param name="data">The byte span containing image data.</param>
/// <param name="format">The detected format.</param>
/// <exception cref="ArgumentNullException">The decoder is null.</exception>
/// <exception cref="UnknownImageFormatException">Image format not recognised.</exception>
/// <exception cref="InvalidImageContentException">Image contains invalid content.</exception>
/// <returns>The <see cref="Image"/>.</returns>
public static Image Load(ReadOnlySpan<byte> data, out IImageFormat format) =>
Load(Configuration.Default, data, out format);
public static Image Load(ReadOnlySpan<byte> data, out IImageFormat format)
=> Load(Configuration.Default, data, out format);
/// <summary>
/// Decodes a new instance of <see cref="Image"/> from the given encoded byte span.
@ -392,7 +480,8 @@ namespace SixLabors.ImageSharp
/// <param name="configuration">The configuration options.</param>
/// <param name="data">The byte span containing image data.</param>
/// <returns>The <see cref="Image"/>.</returns>
public static Image Load(Configuration configuration, ReadOnlySpan<byte> data) => Load(configuration, data, out _);
public static Image Load(Configuration configuration, ReadOnlySpan<byte> data)
=> Load(configuration, data, out _);
/// <summary>
/// Load a new instance of <see cref="Image"/> from the given encoded byte span.
@ -400,6 +489,11 @@ namespace SixLabors.ImageSharp
/// <param name="configuration">The Configuration.</param>
/// <param name="data">The byte span containing image data.</param>
/// <param name="decoder">The decoder.</param>
/// <exception cref="ArgumentNullException">The configuration is null.</exception>
/// <exception cref="ArgumentNullException">The decoder is null.</exception>
/// <exception cref="NotSupportedException">The stream is not readable.</exception>
/// <exception cref="UnknownImageFormatException">Image format not recognised.</exception>
/// <exception cref="InvalidImageContentException">Image contains invalid content.</exception>
/// <returns>The <see cref="Image"/>.</returns>
public static unsafe Image Load(
Configuration configuration,
@ -421,6 +515,9 @@ namespace SixLabors.ImageSharp
/// <param name="configuration">The configuration options.</param>
/// <param name="data">The byte span containing image data.</param>
/// <param name="format">The <see cref="IImageFormat"/> of the decoded image.</param>>
/// <exception cref="ArgumentNullException">The configuration is null.</exception>
/// <exception cref="UnknownImageFormatException">Image format not recognised.</exception>
/// <exception cref="InvalidImageContentException">Image contains invalid content.</exception>
/// <returns>The <see cref="Image"/>.</returns>
public static unsafe Image Load(
Configuration configuration,

119
src/ImageSharp/Image.FromFile.cs

@ -19,19 +19,19 @@ namespace SixLabors.ImageSharp
/// <param name="filePath">The image file to open and to read the header from.</param>
/// <returns>The mime type or null if none found.</returns>
public static IImageFormat DetectFormat(string filePath)
{
return DetectFormat(Configuration.Default, filePath);
}
=> DetectFormat(Configuration.Default, filePath);
/// <summary>
/// By reading the header on the provided file this calculates the images mime type.
/// </summary>
/// <param name="configuration">The configuration.</param>
/// <param name="filePath">The image file to open and to read the header from.</param>
/// <exception cref="ArgumentNullException">The configuration is null.</exception>
/// <returns>The mime type or null if none found.</returns>
public static IImageFormat DetectFormat(Configuration configuration, string filePath)
{
Guard.NotNull(configuration, nameof(configuration));
using (Stream file = configuration.FileSystem.OpenRead(filePath))
{
return DetectFormat(configuration, file);
@ -42,22 +42,22 @@ namespace SixLabors.ImageSharp
/// Reads the raw image information from the specified stream without fully decoding it.
/// </summary>
/// <param name="filePath">The image file to open and to read the header from.</param>
/// <exception cref="NotSupportedException">Thrown if the stream is not readable.</exception>
/// <returns>
/// The <see cref="IImageInfo"/> or null if suitable info detector not found.
/// </returns>
public static IImageInfo Identify(string filePath) => Identify(filePath, out IImageFormat _);
public static IImageInfo Identify(string filePath)
=> Identify(filePath, out IImageFormat _);
/// <summary>
/// Reads the raw image information from the specified stream without fully decoding it.
/// </summary>
/// <param name="filePath">The image file to open and to read the header from.</param>
/// <param name="format">The format type of the decoded image.</param>
/// <exception cref="NotSupportedException">Thrown if the stream is not readable.</exception>
/// <returns>
/// The <see cref="IImageInfo"/> or null if suitable info detector not found.
/// </returns>
public static IImageInfo Identify(string filePath, out IImageFormat format) => Identify(Configuration.Default, filePath, out format);
public static IImageInfo Identify(string filePath, out IImageFormat format)
=> Identify(Configuration.Default, filePath, out format);
/// <summary>
/// Reads the raw image information from the specified stream without fully decoding it.
@ -65,7 +65,7 @@ namespace SixLabors.ImageSharp
/// <param name="configuration">The configuration.</param>
/// <param name="filePath">The image file to open and to read the header from.</param>
/// <param name="format">The format type of the decoded image.</param>
/// <exception cref="NotSupportedException">Thrown if the stream is not readable.</exception>
/// <exception cref="ArgumentNullException">The configuration is null.</exception>
/// <returns>
/// The <see cref="IImageInfo"/> or null if suitable info detector is not found.
/// </returns>
@ -86,7 +86,8 @@ namespace SixLabors.ImageSharp
/// Thrown if the stream is not readable nor seekable.
/// </exception>
/// <returns>The <see cref="Image"/>.</returns>
public static Image Load(string path) => Load(Configuration.Default, path);
public static Image Load(string path)
=> Load(Configuration.Default, path);
/// <summary>
/// Create a new instance of the <see cref="Image"/> class from the given file.
@ -97,18 +98,21 @@ namespace SixLabors.ImageSharp
/// Thrown if the stream is not readable nor seekable.
/// </exception>
/// <returns>A new <see cref="Image{Rgba32}"/>.</returns>
public static Image Load(string path, out IImageFormat format) => Load(Configuration.Default, path, out format);
public static Image Load(string path, out IImageFormat format)
=> Load(Configuration.Default, path, out format);
/// <summary>
/// Create a new instance of the <see cref="Image"/> class from the given file.
/// </summary>
/// <param name="configuration">The configuration for the decoder.</param>
/// <param name="path">The file path to the image.</param>
/// <exception cref="NotSupportedException">
/// Thrown if the stream is not readable nor seekable.
/// </exception>
/// <exception cref="ArgumentNullException">The configuration is null.</exception>
/// <exception cref="ArgumentNullException">The path is null.</exception>
/// <exception cref="UnknownImageFormatException">Image format not recognised.</exception>
/// <exception cref="InvalidImageContentException">Image contains invalid content.</exception>
/// <returns>The <see cref="Image"/>.</returns>
public static Image Load(Configuration configuration, string path) => Load(configuration, path, out _);
public static Image Load(Configuration configuration, string path)
=> Load(configuration, path, out _);
/// <summary>
/// Create a new instance of the <see cref="Image"/> class from the given file.
@ -116,13 +120,17 @@ namespace SixLabors.ImageSharp
/// <param name="configuration">The Configuration.</param>
/// <param name="path">The file path to the image.</param>
/// <param name="decoder">The decoder.</param>
/// <exception cref="NotSupportedException">
/// Thrown if the stream is not readable nor seekable.
/// </exception>
/// <exception cref="ArgumentNullException">The configuration is null.</exception>
/// <exception cref="ArgumentNullException">The path is null.</exception>
/// <exception cref="ArgumentNullException">The decoder is null.</exception>
/// <exception cref="UnknownImageFormatException">Image format not recognised.</exception>
/// <exception cref="InvalidImageContentException">Image contains invalid content.</exception>
/// <returns>The <see cref="Image"/>.</returns>
public static Image Load(Configuration configuration, string path, IImageDecoder decoder)
{
Guard.NotNull(configuration, nameof(configuration));
Guard.NotNull(path, nameof(path));
using (Stream stream = configuration.FileSystem.OpenRead(path))
{
return Load(configuration, stream, decoder);
@ -134,57 +142,58 @@ namespace SixLabors.ImageSharp
/// </summary>
/// <param name="path">The file path to the image.</param>
/// <param name="decoder">The decoder.</param>
/// <exception cref="NotSupportedException">
/// Thrown if the stream is not readable nor seekable.
/// </exception>
/// <exception cref="ArgumentNullException">The path is null.</exception>
/// <exception cref="ArgumentNullException">The decoder is null.</exception>
/// <exception cref="UnknownImageFormatException">Image format not recognised.</exception>
/// <exception cref="InvalidImageContentException">Image contains invalid content.</exception>
/// <returns>The <see cref="Image"/>.</returns>
public static Image Load(string path, IImageDecoder decoder) => Load(Configuration.Default, path, decoder);
public static Image Load(string path, IImageDecoder decoder)
=> Load(Configuration.Default, path, decoder);
/// <summary>
/// Create a new instance of the <see cref="Image{TPixel}"/> class from the given file.
/// </summary>
/// <param name="path">The file path to the image.</param>
/// <exception cref="NotSupportedException">
/// Thrown if the stream is not readable nor seekable.
/// </exception>
/// <exception cref="ArgumentNullException">The path is null.</exception>
/// <exception cref="UnknownImageFormatException">Image format not recognised.</exception>
/// <exception cref="InvalidImageContentException">Image contains invalid content.</exception>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <returns>A new <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Load<TPixel>(string path)
where TPixel : unmanaged, IPixel<TPixel>
{
return Load<TPixel>(Configuration.Default, path);
}
=> Load<TPixel>(Configuration.Default, path);
/// <summary>
/// Create a new instance of the <see cref="Image{TPixel}"/> class from the given file.
/// </summary>
/// <param name="path">The file path to the image.</param>
/// <param name="format">The mime type of the decoded image.</param>
/// <exception cref="NotSupportedException">
/// Thrown if the stream is not readable nor seekable.
/// </exception>
/// <exception cref="ArgumentNullException">The path is null.</exception>
/// <exception cref="UnknownImageFormatException">Image format not recognised.</exception>
/// <exception cref="InvalidImageContentException">Image contains invalid content.</exception>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <returns>A new <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Load<TPixel>(string path, out IImageFormat format)
where TPixel : unmanaged, IPixel<TPixel>
{
return Load<TPixel>(Configuration.Default, path, out format);
}
=> Load<TPixel>(Configuration.Default, path, out format);
/// <summary>
/// Create a new instance of the <see cref="Image{TPixel}"/> class from the given file.
/// </summary>
/// <param name="configuration">The configuration options.</param>
/// <param name="path">The file path to the image.</param>
/// <exception cref="NotSupportedException">
/// Thrown if the stream is not readable nor seekable.
/// </exception>
/// <exception cref="ArgumentNullException">The configuration is null.</exception>
/// <exception cref="ArgumentNullException">The path is null.</exception>
/// <exception cref="UnknownImageFormatException">Image format not recognised.</exception>
/// <exception cref="InvalidImageContentException">Image contains invalid content.</exception>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <returns>A new <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Load<TPixel>(Configuration configuration, string path)
where TPixel : unmanaged, IPixel<TPixel>
{
Guard.NotNull(configuration, nameof(configuration));
Guard.NotNull(path, nameof(path));
using (Stream stream = configuration.FileSystem.OpenRead(path))
{
return Load<TPixel>(configuration, stream);
@ -197,15 +206,18 @@ namespace SixLabors.ImageSharp
/// <param name="configuration">The configuration options.</param>
/// <param name="path">The file path to the image.</param>
/// <param name="format">The mime type of the decoded image.</param>
/// <exception cref="NotSupportedException">
/// Thrown if the stream is not readable nor seekable.
/// </exception>
/// <exception cref="ArgumentNullException">The configuration is null.</exception>
/// <exception cref="ArgumentNullException">The path is null.</exception>
/// <exception cref="UnknownImageFormatException">Image format not recognised.</exception>
/// <exception cref="InvalidImageContentException">Image contains invalid content.</exception>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <returns>A new <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Load<TPixel>(Configuration configuration, string path, out IImageFormat format)
where TPixel : unmanaged, IPixel<TPixel>
{
Guard.NotNull(configuration, nameof(configuration));
Guard.NotNull(path, nameof(path));
using (Stream stream = configuration.FileSystem.OpenRead(path))
{
return Load<TPixel>(configuration, stream, out format);
@ -219,13 +231,16 @@ namespace SixLabors.ImageSharp
/// <param name="configuration">The configuration options.</param>
/// <param name="path">The file path to the image.</param>
/// <param name="format">The mime type of the decoded image.</param>
/// <exception cref="NotSupportedException">
/// Thrown if the stream is not readable nor seekable.
/// </exception>
/// <exception cref="ArgumentNullException">The configuration is null.</exception>
/// <exception cref="ArgumentNullException">The path is null.</exception>
/// <exception cref="UnknownImageFormatException">Image format not recognised.</exception>
/// <exception cref="InvalidImageContentException">Image contains invalid content.</exception>
/// <returns>A new <see cref="Image{TPixel}"/>.</returns>
public static Image Load(Configuration configuration, string path, out IImageFormat format)
{
Guard.NotNull(configuration, nameof(configuration));
Guard.NotNull(path, nameof(path));
using (Stream stream = configuration.FileSystem.OpenRead(path))
{
return Load(configuration, stream, out format);
@ -237,16 +252,14 @@ namespace SixLabors.ImageSharp
/// </summary>
/// <param name="path">The file path to the image.</param>
/// <param name="decoder">The decoder.</param>
/// <exception cref="NotSupportedException">
/// Thrown if the stream is not readable nor seekable.
/// </exception>
/// <exception cref="ArgumentNullException">The path is null.</exception>
/// <exception cref="UnknownImageFormatException">Image format not recognised.</exception>
/// <exception cref="InvalidImageContentException">Image contains invalid content.</exception>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <returns>A new <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Load<TPixel>(string path, IImageDecoder decoder)
where TPixel : unmanaged, IPixel<TPixel>
{
return Load<TPixel>(Configuration.Default, path, decoder);
}
=> Load<TPixel>(Configuration.Default, path, decoder);
/// <summary>
/// Create a new instance of the <see cref="Image{TPixel}"/> class from the given file.
@ -254,15 +267,19 @@ namespace SixLabors.ImageSharp
/// <param name="configuration">The Configuration.</param>
/// <param name="path">The file path to the image.</param>
/// <param name="decoder">The decoder.</param>
/// <exception cref="NotSupportedException">
/// Thrown if the stream is not readable nor seekable.
/// </exception>
/// <exception cref="ArgumentNullException">The configuration is null.</exception>
/// <exception cref="ArgumentNullException">The path is null.</exception>
/// <exception cref="ArgumentNullException">The decoder is null.</exception>
/// <exception cref="UnknownImageFormatException">Image format not recognised.</exception>
/// <exception cref="InvalidImageContentException">Image contains invalid content.</exception>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <returns>A new <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Load<TPixel>(Configuration configuration, string path, IImageDecoder decoder)
where TPixel : unmanaged, IPixel<TPixel>
{
Guard.NotNull(configuration, nameof(configuration));
Guard.NotNull(path, nameof(path));
using (Stream stream = configuration.FileSystem.OpenRead(path))
{
return Load<TPixel>(configuration, stream, decoder);

131
src/ImageSharp/Image.FromStream.cs

@ -19,16 +19,20 @@ namespace SixLabors.ImageSharp
/// By reading the header on the provided stream this calculates the images format type.
/// </summary>
/// <param name="stream">The image stream to read the header from.</param>
/// <exception cref="NotSupportedException">Thrown if the stream is not readable.</exception>
/// <exception cref="ArgumentNullException">The stream is null.</exception>
/// <exception cref="NotSupportedException">The stream is not readable.</exception>
/// <returns>The format type or null if none found.</returns>
public static IImageFormat DetectFormat(Stream stream) => DetectFormat(Configuration.Default, stream);
public static IImageFormat DetectFormat(Stream stream)
=> DetectFormat(Configuration.Default, stream);
/// <summary>
/// By reading the header on the provided stream this calculates the images format type.
/// </summary>
/// <param name="configuration">The configuration.</param>
/// <param name="stream">The image stream to read the header from.</param>
/// <exception cref="NotSupportedException">Thrown if the stream is not readable.</exception>
/// <exception cref="ArgumentNullException">The configuration is null.</exception>
/// <exception cref="ArgumentNullException">The stream is null.</exception>
/// <exception cref="NotSupportedException">The stream is not readable.</exception>
/// <returns>The format type or null if none found.</returns>
public static IImageFormat DetectFormat(Configuration configuration, Stream stream)
=> WithSeekableStream(configuration, stream, s => InternalDetectFormat(s, configuration));
@ -37,22 +41,28 @@ namespace SixLabors.ImageSharp
/// Reads the raw image information from the specified stream without fully decoding it.
/// </summary>
/// <param name="stream">The image stream to read the header from.</param>
/// <exception cref="NotSupportedException">Thrown if the stream is not readable.</exception>
/// <exception cref="ArgumentNullException">The stream is null.</exception>
/// <exception cref="NotSupportedException">The stream is not readable.</exception>
/// <exception cref="InvalidImageContentException">Image contains invalid content.</exception>
/// <returns>
/// The <see cref="IImageInfo"/> or null if suitable info detector not found.
/// </returns>
public static IImageInfo Identify(Stream stream) => Identify(stream, out IImageFormat _);
public static IImageInfo Identify(Stream stream)
=> Identify(stream, out IImageFormat _);
/// <summary>
/// Reads the raw image information from the specified stream without fully decoding it.
/// </summary>
/// <param name="stream">The image stream to read the header from.</param>
/// <param name="format">The format type of the decoded image.</param>
/// <exception cref="NotSupportedException">Thrown if the stream is not readable.</exception>
/// <exception cref="ArgumentNullException">The stream is null.</exception>
/// <exception cref="NotSupportedException">The stream is not readable.</exception>
/// <exception cref="InvalidImageContentException">Image contains invalid content.</exception>
/// <returns>
/// The <see cref="IImageInfo"/> or null if suitable info detector not found.
/// </returns>
public static IImageInfo Identify(Stream stream, out IImageFormat format) => Identify(Configuration.Default, stream, out format);
public static IImageInfo Identify(Stream stream, out IImageFormat format)
=> Identify(Configuration.Default, stream, out format);
/// <summary>
/// Reads the raw image information from the specified stream without fully decoding it.
@ -60,7 +70,10 @@ namespace SixLabors.ImageSharp
/// <param name="configuration">The configuration.</param>
/// <param name="stream">The image stream to read the information from.</param>
/// <param name="format">The format type of the decoded image.</param>
/// <exception cref="NotSupportedException">Thrown if the stream is not readable.</exception>
/// <exception cref="ArgumentNullException">The configuration is null.</exception>
/// <exception cref="ArgumentNullException">The stream is null.</exception>
/// <exception cref="NotSupportedException">The stream is not readable.</exception>
/// <exception cref="InvalidImageContentException">Image contains invalid content.</exception>
/// <returns>
/// The <see cref="IImageInfo"/> or null if suitable info detector is not found.
/// </returns>
@ -78,18 +91,23 @@ namespace SixLabors.ImageSharp
/// </summary>
/// <param name="stream">The stream containing image information.</param>
/// <param name="format">The format type of the decoded image.</param>
/// <exception cref="NotSupportedException">Thrown if the stream is not readable.</exception>
/// <exception cref="UnknownImageFormatException">Image cannot be loaded.</exception>
/// <exception cref="ArgumentNullException">The stream is null.</exception>
/// <exception cref="NotSupportedException">The stream is not readable.</exception>
/// <exception cref="UnknownImageFormatException">Image format not recognised.</exception>
/// <exception cref="InvalidImageContentException">Image contains invalid content.</exception>
/// <returns>The <see cref="Image"/>.</returns>
public static Image Load(Stream stream, out IImageFormat format) => Load(Configuration.Default, stream, out format);
public static Image Load(Stream stream, out IImageFormat format)
=> Load(Configuration.Default, stream, out format);
/// <summary>
/// Decode a new instance of the <see cref="Image"/> class from the given stream.
/// The pixel format is selected by the decoder.
/// </summary>
/// <param name="stream">The stream containing image information.</param>
/// <exception cref="NotSupportedException">Thrown if the stream is not readable.</exception>
/// <exception cref="UnknownImageFormatException">Image cannot be loaded.</exception>
/// <exception cref="ArgumentNullException">The stream is null.</exception>
/// <exception cref="NotSupportedException">The stream is not readable.</exception>
/// <exception cref="UnknownImageFormatException">Image format not recognised.</exception>
/// <exception cref="InvalidImageContentException">Image contains invalid content.</exception>
/// <returns>The <see cref="Image"/>.</returns>
public static Image Load(Stream stream) => Load(Configuration.Default, stream);
@ -99,10 +117,14 @@ namespace SixLabors.ImageSharp
/// </summary>
/// <param name="stream">The stream containing image information.</param>
/// <param name="decoder">The decoder.</param>
/// <exception cref="NotSupportedException">Thrown if the stream is not readable.</exception>
/// <exception cref="UnknownImageFormatException">Image cannot be loaded.</exception>
/// <exception cref="ArgumentNullException">The stream is null.</exception>
/// <exception cref="ArgumentNullException">The decoder is null.</exception>
/// <exception cref="NotSupportedException">The stream is not readable.</exception>
/// <exception cref="UnknownImageFormatException">Image format not recognised.</exception>
/// <exception cref="InvalidImageContentException">Image contains invalid content.</exception>
/// <returns>The <see cref="Image"/>.</returns>
public static Image Load(Stream stream, IImageDecoder decoder) => Load(Configuration.Default, stream, decoder);
public static Image Load(Stream stream, IImageDecoder decoder)
=> Load(Configuration.Default, stream, decoder);
/// <summary>
/// Decode a new instance of the <see cref="Image"/> class from the given stream.
@ -111,19 +133,29 @@ namespace SixLabors.ImageSharp
/// <param name="configuration">The configuration for the decoder.</param>
/// <param name="stream">The stream containing image information.</param>
/// <param name="decoder">The decoder.</param>
/// <exception cref="NotSupportedException">Thrown if the stream is not readable.</exception>
/// <exception cref="UnknownImageFormatException">Image cannot be loaded.</exception>
/// <exception cref="ArgumentNullException">The configuration is null.</exception>
/// <exception cref="ArgumentNullException">The stream is null.</exception>
/// <exception cref="ArgumentNullException">The decoder is null.</exception>
/// <exception cref="NotSupportedException">The stream is not readable.</exception>
/// <exception cref="UnknownImageFormatException">Image format not recognised.</exception>
/// <exception cref="InvalidImageContentException">Image contains invalid content.</exception>
/// <returns>A new <see cref="Image"/>.</returns>>
public static Image Load(Configuration configuration, Stream stream, IImageDecoder decoder) =>
WithSeekableStream(configuration, stream, s => decoder.Decode(configuration, s));
public static Image Load(Configuration configuration, Stream stream, IImageDecoder decoder)
{
Guard.NotNull(decoder, nameof(decoder));
return WithSeekableStream(configuration, stream, s => decoder.Decode(configuration, s));
}
/// <summary>
/// Decode a new instance of the <see cref="Image"/> class from the given stream.
/// </summary>
/// <param name="configuration">The configuration for the decoder.</param>
/// <param name="stream">The stream containing image information.</param>
/// <exception cref="NotSupportedException">Thrown if the stream is not readable.</exception>
/// <exception cref="UnknownImageFormatException">Image cannot be loaded.</exception>
/// <exception cref="ArgumentNullException">The configuration is null.</exception>
/// <exception cref="ArgumentNullException">The stream is null.</exception>
/// <exception cref="NotSupportedException">The stream is not readable.</exception>
/// <exception cref="UnknownImageFormatException">Image format not recognised.</exception>
/// <exception cref="InvalidImageContentException">Image contains invalid content.</exception>
/// <returns>A new <see cref="Image"/>.</returns>>
public static Image Load(Configuration configuration, Stream stream) => Load(configuration, stream, out _);
@ -131,8 +163,10 @@ namespace SixLabors.ImageSharp
/// Create a new instance of the <see cref="Image{TPixel}"/> class from the given stream.
/// </summary>
/// <param name="stream">The stream containing image information.</param>
/// <exception cref="NotSupportedException">Thrown if the stream is not readable.</exception>
/// <exception cref="UnknownImageFormatException">Image cannot be loaded.</exception>
/// <exception cref="ArgumentNullException">The stream is null.</exception>
/// <exception cref="NotSupportedException">The stream is not readable.</exception>
/// <exception cref="UnknownImageFormatException">Image format not recognised.</exception>
/// <exception cref="InvalidImageContentException">Image contains invalid content.</exception>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <returns>A new <see cref="Image{TPixel}"/>.</returns>>
public static Image<TPixel> Load<TPixel>(Stream stream)
@ -144,8 +178,10 @@ namespace SixLabors.ImageSharp
/// </summary>
/// <param name="stream">The stream containing image information.</param>
/// <param name="format">The format type of the decoded image.</param>
/// <exception cref="NotSupportedException">Thrown if the stream is not readable.</exception>
/// <exception cref="UnknownImageFormatException">Image cannot be loaded.</exception>
/// <exception cref="ArgumentNullException">The stream is null.</exception>
/// <exception cref="NotSupportedException">The stream is not readable.</exception>
/// <exception cref="UnknownImageFormatException">Image format not recognised.</exception>
/// <exception cref="InvalidImageContentException">Image contains invalid content.</exception>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <returns>A new <see cref="Image{TPixel}"/>.</returns>>
public static Image<TPixel> Load<TPixel>(Stream stream, out IImageFormat format)
@ -157,8 +193,10 @@ namespace SixLabors.ImageSharp
/// </summary>
/// <param name="stream">The stream containing image information.</param>
/// <param name="decoder">The decoder.</param>
/// <exception cref="NotSupportedException">Thrown if the stream is not readable.</exception>
/// <exception cref="UnknownImageFormatException">Image cannot be loaded.</exception>
/// <exception cref="ArgumentNullException">The stream is null.</exception>
/// <exception cref="NotSupportedException">The stream is not readable.</exception>
/// <exception cref="UnknownImageFormatException">Image format not recognised.</exception>
/// <exception cref="InvalidImageContentException">Image contains invalid content.</exception>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <returns>A new <see cref="Image{TPixel}"/>.</returns>>
public static Image<TPixel> Load<TPixel>(Stream stream, IImageDecoder decoder)
@ -171,8 +209,11 @@ namespace SixLabors.ImageSharp
/// <param name="configuration">The Configuration.</param>
/// <param name="stream">The stream containing image information.</param>
/// <param name="decoder">The decoder.</param>
/// <exception cref="NotSupportedException">Thrown if the stream is not readable.</exception>
/// <exception cref="UnknownImageFormatException">Image cannot be loaded.</exception>
/// <exception cref="ArgumentNullException">The configuration is null.</exception>
/// <exception cref="ArgumentNullException">The stream is null.</exception>
/// <exception cref="NotSupportedException">The stream is not readable.</exception>
/// <exception cref="UnknownImageFormatException">Image format not recognised.</exception>
/// <exception cref="InvalidImageContentException">Image contains invalid content.</exception>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <returns>A new <see cref="Image{TPixel}"/>.</returns>>
public static Image<TPixel> Load<TPixel>(Configuration configuration, Stream stream, IImageDecoder decoder)
@ -184,8 +225,11 @@ namespace SixLabors.ImageSharp
/// </summary>
/// <param name="configuration">The configuration options.</param>
/// <param name="stream">The stream containing image information.</param>
/// <exception cref="NotSupportedException">Thrown if the stream is not readable.</exception>
/// <exception cref="UnknownImageFormatException">Image cannot be loaded.</exception>
/// <exception cref="ArgumentNullException">The configuration is null.</exception>
/// <exception cref="ArgumentNullException">The stream is null.</exception>
/// <exception cref="NotSupportedException">The stream is not readable.</exception>
/// <exception cref="UnknownImageFormatException">Image format not recognised.</exception>
/// <exception cref="InvalidImageContentException">Image contains invalid content.</exception>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <returns>A new <see cref="Image{TPixel}"/>.</returns>>
public static Image<TPixel> Load<TPixel>(Configuration configuration, Stream stream)
@ -198,14 +242,16 @@ namespace SixLabors.ImageSharp
/// <param name="configuration">The configuration options.</param>
/// <param name="stream">The stream containing image information.</param>
/// <param name="format">The format type of the decoded image.</param>
/// <exception cref="NotSupportedException">Thrown if the stream is not readable.</exception>
/// <exception cref="UnknownImageFormatException">Image cannot be loaded.</exception>
/// <exception cref="ArgumentNullException">The configuration is null.</exception>
/// <exception cref="ArgumentNullException">The stream is null.</exception>
/// <exception cref="NotSupportedException">The stream is not readable.</exception>
/// <exception cref="UnknownImageFormatException">Image format not recognised.</exception>
/// <exception cref="InvalidImageContentException">Image contains invalid content.</exception>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <returns>A new <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> Load<TPixel>(Configuration configuration, Stream stream, out IImageFormat format)
where TPixel : unmanaged, IPixel<TPixel>
{
Guard.NotNull(configuration, nameof(configuration));
(Image<TPixel> img, IImageFormat format) data = WithSeekableStream(configuration, stream, s => Decode<TPixel>(s, configuration));
format = data.format;
@ -220,7 +266,7 @@ namespace SixLabors.ImageSharp
foreach (KeyValuePair<IImageFormat, IImageDecoder> val in configuration.ImageFormatsManager.ImageDecoders)
{
sb.AppendLine($" - {val.Key.Name} : {val.Value.GetType().Name}");
sb.AppendFormat(" - {0} : {1}{2}", val.Key.Name, val.Value.GetType().Name, Environment.NewLine);
}
throw new UnknownImageFormatException(sb.ToString());
@ -233,12 +279,14 @@ namespace SixLabors.ImageSharp
/// <param name="configuration">The configuration options.</param>
/// <param name="stream">The stream containing image information.</param>
/// <param name="format">The format type of the decoded image.</param>
/// <exception cref="NotSupportedException">Thrown if the stream is not readable.</exception>
/// <exception cref="UnknownImageFormatException">Image cannot be loaded.</exception>
/// <exception cref="ArgumentNullException">The configuration is null.</exception>
/// <exception cref="ArgumentNullException">The stream is null.</exception>
/// <exception cref="NotSupportedException">The stream is not readable.</exception>
/// <exception cref="UnknownImageFormatException">Image format not recognised.</exception>
/// <exception cref="InvalidImageContentException">Image contains invalid content.</exception>
/// <returns>A new <see cref="Image{TPixel}"/>.</returns>
public static Image Load(Configuration configuration, Stream stream, out IImageFormat format)
{
Guard.NotNull(configuration, nameof(configuration));
(Image img, IImageFormat format) data = WithSeekableStream(configuration, stream, s => Decode(s, configuration));
format = data.format;
@ -253,7 +301,7 @@ namespace SixLabors.ImageSharp
foreach (KeyValuePair<IImageFormat, IImageDecoder> val in configuration.ImageFormatsManager.ImageDecoders)
{
sb.AppendLine($" - {val.Key.Name} : {val.Value.GetType().Name}");
sb.AppendFormat(" - {0} : {1}{2}", val.Key.Name, val.Value.GetType().Name, Environment.NewLine);
}
throw new UnknownImageFormatException(sb.ToString());
@ -261,6 +309,9 @@ namespace SixLabors.ImageSharp
private static T WithSeekableStream<T>(Configuration configuration, Stream stream, Func<Stream, T> action)
{
Guard.NotNull(configuration, nameof(configuration));
Guard.NotNull(stream, nameof(stream));
if (!stream.CanRead)
{
throw new NotSupportedException("Cannot read from the stream.");

43
src/ImageSharp/Image.LoadPixelData.cs

@ -1,9 +1,8 @@
// Copyright (c) Six Labors and contributors.
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System;
using System.Runtime.InteropServices;
using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.PixelFormats;
@ -21,6 +20,7 @@ namespace SixLabors.ImageSharp
/// <param name="width">The width of the final image.</param>
/// <param name="height">The height of the final image.</param>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <exception cref="ArgumentException">The data length is incorrect.</exception>
/// <returns>A new <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> LoadPixelData<TPixel>(TPixel[] data, int width, int height)
where TPixel : unmanaged, IPixel<TPixel>
@ -33,6 +33,7 @@ namespace SixLabors.ImageSharp
/// <param name="width">The width of the final image.</param>
/// <param name="height">The height of the final image.</param>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <exception cref="ArgumentException">The data length is incorrect.</exception>
/// <returns>A new <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> LoadPixelData<TPixel>(ReadOnlySpan<TPixel> data, int width, int height)
where TPixel : unmanaged, IPixel<TPixel>
@ -45,6 +46,7 @@ namespace SixLabors.ImageSharp
/// <param name="width">The width of the final image.</param>
/// <param name="height">The height of the final image.</param>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <exception cref="ArgumentException">The data length is incorrect.</exception>
/// <returns>A new <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> LoadPixelData<TPixel>(byte[] data, int width, int height)
where TPixel : unmanaged, IPixel<TPixel>
@ -57,6 +59,7 @@ namespace SixLabors.ImageSharp
/// <param name="width">The width of the final image.</param>
/// <param name="height">The height of the final image.</param>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <exception cref="ArgumentException">The data length is incorrect.</exception>
/// <returns>A new <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> LoadPixelData<TPixel>(ReadOnlySpan<byte> data, int width, int height)
where TPixel : unmanaged, IPixel<TPixel>
@ -65,60 +68,68 @@ namespace SixLabors.ImageSharp
/// <summary>
/// Create a new instance of the <see cref="Image{TPixel}"/> class from the given byte array in <typeparamref name="TPixel"/> format.
/// </summary>
/// <param name="config">The config for the decoder.</param>
/// <param name="configuration">The configuration for the decoder.</param>
/// <param name="data">The byte array containing image data.</param>
/// <param name="width">The width of the final image.</param>
/// <param name="height">The height of the final image.</param>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <exception cref="ArgumentNullException">The configuration is null.</exception>
/// <exception cref="ArgumentException">The data length is incorrect.</exception>
/// <returns>A new <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> LoadPixelData<TPixel>(Configuration config, byte[] data, int width, int height)
public static Image<TPixel> LoadPixelData<TPixel>(Configuration configuration, byte[] data, int width, int height)
where TPixel : unmanaged, IPixel<TPixel>
=> LoadPixelData(config, MemoryMarshal.Cast<byte, TPixel>(new ReadOnlySpan<byte>(data)), width, height);
=> LoadPixelData(configuration, MemoryMarshal.Cast<byte, TPixel>(new ReadOnlySpan<byte>(data)), width, height);
/// <summary>
/// Create a new instance of the <see cref="Image{TPixel}"/> class from the given byte array in <typeparamref name="TPixel"/> format.
/// </summary>
/// <param name="config">The config for the decoder.</param>
/// <param name="configuration">The configuration for the decoder.</param>
/// <param name="data">The byte array containing image data.</param>
/// <param name="width">The width of the final image.</param>
/// <param name="height">The height of the final image.</param>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <exception cref="ArgumentNullException">The configuration is null.</exception>
/// <exception cref="ArgumentException">The data length is incorrect.</exception>
/// <returns>A new <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> LoadPixelData<TPixel>(Configuration config, ReadOnlySpan<byte> data, int width, int height)
public static Image<TPixel> LoadPixelData<TPixel>(Configuration configuration, ReadOnlySpan<byte> data, int width, int height)
where TPixel : unmanaged, IPixel<TPixel>
=> LoadPixelData(config, MemoryMarshal.Cast<byte, TPixel>(data), width, height);
=> LoadPixelData(configuration, MemoryMarshal.Cast<byte, TPixel>(data), width, height);
/// <summary>
/// Create a new instance of the <see cref="Image{TPixel}"/> class from the raw <typeparamref name="TPixel"/> data.
/// </summary>
/// <param name="config">The config for the decoder.</param>
/// <param name="configuration">The configuration for the decoder.</param>
/// <param name="data">The Span containing the image Pixel data.</param>
/// <param name="width">The width of the final image.</param>
/// <param name="height">The height of the final image.</param>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <exception cref="ArgumentNullException">The configuration is null.</exception>
/// <exception cref="ArgumentException">The data length is incorrect.</exception>
/// <returns>A new <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> LoadPixelData<TPixel>(Configuration config, TPixel[] data, int width, int height)
public static Image<TPixel> LoadPixelData<TPixel>(Configuration configuration, TPixel[] data, int width, int height)
where TPixel : unmanaged, IPixel<TPixel>
{
return LoadPixelData(config, new ReadOnlySpan<TPixel>(data), width, height);
}
=> LoadPixelData(configuration, new ReadOnlySpan<TPixel>(data), width, height);
/// <summary>
/// Create a new instance of the <see cref="Image{TPixel}"/> class from the raw <typeparamref name="TPixel"/> data.
/// </summary>
/// <param name="config">The config for the decoder.</param>
/// <param name="configuration">The configuration for the decoder.</param>
/// <param name="data">The Span containing the image Pixel data.</param>
/// <param name="width">The width of the final image.</param>
/// <param name="height">The height of the final image.</param>
/// <exception cref="ArgumentNullException">The configuration is null.</exception>
/// <exception cref="ArgumentException">The data length is incorrect.</exception>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <returns>A new <see cref="Image{TPixel}"/>.</returns>
public static Image<TPixel> LoadPixelData<TPixel>(Configuration config, ReadOnlySpan<TPixel> data, int width, int height)
public static Image<TPixel> LoadPixelData<TPixel>(Configuration configuration, ReadOnlySpan<TPixel> data, int width, int height)
where TPixel : unmanaged, IPixel<TPixel>
{
Guard.NotNull(configuration, nameof(configuration));
int count = width * height;
Guard.MustBeGreaterThanOrEqualTo(data.Length, count, nameof(data));
var image = new Image<TPixel>(config, width, height);
var image = new Image<TPixel>(configuration, width, height);
data = data.Slice(0, count);
data.CopyTo(image.Frames.RootFrame.PixelBuffer.FastMemoryGroup);

50
src/ImageSharp/Image.WrapMemory.cs

@ -1,4 +1,4 @@
// Copyright (c) Six Labors and contributors.
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System;
@ -20,22 +20,27 @@ namespace SixLabors.ImageSharp
/// allowing to view/manipulate it as an ImageSharp <see cref="Image{TPixel}"/> instance.
/// </summary>
/// <typeparam name="TPixel">The pixel type</typeparam>
/// <param name="config">The <see cref="ImageSharp.Configuration"/></param>
/// <param name="configuration">The <see cref="Configuration"/></param>
/// <param name="pixelMemory">The pixel memory.</param>
/// <param name="width">The width of the memory image.</param>
/// <param name="height">The height of the memory image.</param>
/// <param name="metadata">The <see cref="ImageMetadata"/>.</param>
/// <exception cref="ArgumentNullException">The configuration is null.</exception>
/// <exception cref="ArgumentNullException">The metadata is null.</exception>
/// <returns>An <see cref="Image{TPixel}"/> instance</returns>
public static Image<TPixel> WrapMemory<TPixel>(
Configuration config,
Configuration configuration,
Memory<TPixel> pixelMemory,
int width,
int height,
ImageMetadata metadata)
where TPixel : unmanaged, IPixel<TPixel>
{
Guard.NotNull(configuration, nameof(configuration));
Guard.NotNull(metadata, nameof(metadata));
var memorySource = MemoryGroup<TPixel>.Wrap(pixelMemory);
return new Image<TPixel>(config, memorySource, width, height, metadata);
return new Image<TPixel>(configuration, memorySource, width, height, metadata);
}
/// <summary>
@ -43,20 +48,19 @@ namespace SixLabors.ImageSharp
/// allowing to view/manipulate it as an ImageSharp <see cref="Image{TPixel}"/> instance.
/// </summary>
/// <typeparam name="TPixel">The pixel type</typeparam>
/// <param name="config">The <see cref="ImageSharp.Configuration"/></param>
/// <param name="configuration">The <see cref="Configuration"/></param>
/// <param name="pixelMemory">The pixel memory.</param>
/// <param name="width">The width of the memory image.</param>
/// <param name="height">The height of the memory image.</param>
/// <exception cref="ArgumentNullException">The configuration is null.</exception>
/// <returns>An <see cref="Image{TPixel}"/> instance.</returns>
public static Image<TPixel> WrapMemory<TPixel>(
Configuration config,
Configuration configuration,
Memory<TPixel> pixelMemory,
int width,
int height)
where TPixel : unmanaged, IPixel<TPixel>
{
return WrapMemory(config, pixelMemory, width, height, new ImageMetadata());
}
=> WrapMemory(configuration, pixelMemory, width, height, new ImageMetadata());
/// <summary>
/// Wraps an existing contiguous memory area of 'width' x 'height' pixels,
@ -73,9 +77,7 @@ namespace SixLabors.ImageSharp
int width,
int height)
where TPixel : unmanaged, IPixel<TPixel>
{
return WrapMemory(Configuration.Default, pixelMemory, width, height);
}
=> WrapMemory(Configuration.Default, pixelMemory, width, height);
/// <summary>
/// Wraps an existing contiguous memory area of 'width' x 'height' pixels,
@ -85,22 +87,27 @@ namespace SixLabors.ImageSharp
/// It will be disposed together with the result image.
/// </summary>
/// <typeparam name="TPixel">The pixel type</typeparam>
/// <param name="config">The <see cref="ImageSharp.Configuration"/></param>
/// <param name="configuration">The <see cref="Configuration"/></param>
/// <param name="pixelMemoryOwner">The <see cref="IMemoryOwner{T}"/> that is being transferred to the image</param>
/// <param name="width">The width of the memory image.</param>
/// <param name="height">The height of the memory image.</param>
/// <param name="metadata">The <see cref="ImageMetadata"/></param>
/// <exception cref="ArgumentNullException">The configuration is null.</exception>
/// <exception cref="ArgumentNullException">The metadata is null.</exception>
/// <returns>An <see cref="Image{TPixel}"/> instance</returns>
public static Image<TPixel> WrapMemory<TPixel>(
Configuration config,
Configuration configuration,
IMemoryOwner<TPixel> pixelMemoryOwner,
int width,
int height,
ImageMetadata metadata)
where TPixel : unmanaged, IPixel<TPixel>
{
Guard.NotNull(configuration, nameof(configuration));
Guard.NotNull(metadata, nameof(metadata));
var memorySource = MemoryGroup<TPixel>.Wrap(pixelMemoryOwner);
return new Image<TPixel>(config, memorySource, width, height, metadata);
return new Image<TPixel>(configuration, memorySource, width, height, metadata);
}
/// <summary>
@ -111,20 +118,19 @@ namespace SixLabors.ImageSharp
/// It will be disposed together with the result image.
/// </summary>
/// <typeparam name="TPixel">The pixel type.</typeparam>
/// <param name="config">The <see cref="ImageSharp.Configuration"/></param>
/// <param name="configuration">The <see cref="Configuration"/></param>
/// <param name="pixelMemoryOwner">The <see cref="IMemoryOwner{T}"/> that is being transferred to the image.</param>
/// <param name="width">The width of the memory image.</param>
/// <param name="height">The height of the memory image.</param>
/// <exception cref="ArgumentNullException">The configuration is null.</exception>
/// <returns>An <see cref="Image{TPixel}"/> instance</returns>
public static Image<TPixel> WrapMemory<TPixel>(
Configuration config,
Configuration configuration,
IMemoryOwner<TPixel> pixelMemoryOwner,
int width,
int height)
where TPixel : unmanaged, IPixel<TPixel>
{
return WrapMemory(config, pixelMemoryOwner, width, height, new ImageMetadata());
}
=> WrapMemory(configuration, pixelMemoryOwner, width, height, new ImageMetadata());
/// <summary>
/// Wraps an existing contiguous memory area of 'width' x 'height' pixels,
@ -143,8 +149,6 @@ namespace SixLabors.ImageSharp
int width,
int height)
where TPixel : unmanaged, IPixel<TPixel>
{
return WrapMemory(Configuration.Default, pixelMemoryOwner, width, height);
}
=> WrapMemory(Configuration.Default, pixelMemoryOwner, width, height);
}
}

Loading…
Cancel
Save