Skip to content
Merged
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
22 changes: 22 additions & 0 deletions src/ImageSharp/Common/Exceptions/InvalidImageContentException.cs
Original file line number Diff line number Diff line change
@@ -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 changes: 5 additions & 5 deletions src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -462,7 +462,7 @@ private void UncompressRle4(int w, Span<byte> buffer, Span<bool> undefinedPixels
{
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)
Expand Down Expand Up @@ -569,7 +569,7 @@ private void UncompressRle8(int w, Span<byte> buffer, Span<bool> undefinedPixels
{
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)
Expand Down Expand Up @@ -648,7 +648,7 @@ private void UncompressRle24(int w, Span<byte> buffer, Span<bool> undefinedPixel
{
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)
Expand Down Expand Up @@ -1431,7 +1431,7 @@ private int ReadImageHeaders(Stream stream, out bool inverted, out byte[] palett
// 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.");
}

Expand All @@ -1445,7 +1445,7 @@ private int ReadImageHeaders(Stream stream, out bool inverted, out byte[] palett
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)
Expand Down
2 changes: 1 addition & 1 deletion src/ImageSharp/Formats/Bmp/BmpInfoHeader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,7 @@ public static BmpInfoHeader ParseOs2Version2(ReadOnlySpan<byte> data)
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;
}

Expand Down
16 changes: 6 additions & 10 deletions src/ImageSharp/Formats/Bmp/BmpThrowHelper.cs
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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 changes: 1 addition & 1 deletion src/ImageSharp/Formats/Gif/GifDecoderCore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ private void ReadComments()
{
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)
Expand Down
18 changes: 18 additions & 0 deletions src/ImageSharp/Formats/Gif/GifThrowHelper.cs
Original file line number Diff line number Diff line change
@@ -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);
}
}
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -104,7 +104,7 @@ internal static void ConvertCore(in ComponentValues values, Span<Vector4> result
{
// 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:
Expand Down
4 changes: 2 additions & 2 deletions src/ImageSharp/Formats/Jpeg/Components/Decoder/JFifMarker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,12 @@ private JFifMarker(byte majorVersion, byte minorVersion, byte densityUnits, shor
{
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;
Expand Down
18 changes: 9 additions & 9 deletions src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ public void ParseStream(Stream stream, bool metadataOnly = false)
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);
Expand Down Expand Up @@ -423,7 +423,7 @@ private JpegColorSpace DeduceJpegColorSpace()
: 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;
}

Expand Down Expand Up @@ -821,7 +821,7 @@ private void ProcessStartOfFrameMarker(int remaining, in JpegFileMarker frameMar
{
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.
Expand All @@ -831,7 +831,7 @@ private void ProcessStartOfFrameMarker(int remaining, in JpegFileMarker frameMar
// 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];
Expand Down Expand Up @@ -928,13 +928,13 @@ private void ProcessDefineHuffmanTablesMarker(int remaining)
// 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);
Expand All @@ -953,7 +953,7 @@ private void ProcessDefineHuffmanTablesMarker(int remaining)

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))
Expand Down Expand Up @@ -995,7 +995,7 @@ private void ProcessStartOfScanMarker()
{
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();
Expand All @@ -1016,7 +1016,7 @@ private void ProcessStartOfScanMarker()

if (componentIndex < 0)
{
JpegThrowHelper.ThrowImageFormatException($"Unknown component selector {componentIndex}.");
JpegThrowHelper.ThrowInvalidImageContentException($"Unknown component selector {componentIndex}.");
}

ref JpegComponent component = ref this.Frame.Components[componentIndex];
Expand Down
27 changes: 18 additions & 9 deletions src/ImageSharp/Formats/Jpeg/JpegThrowHelper.cs
Original file line number Diff line number Diff line change
@@ -1,32 +1,41 @@
// 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
{
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 changes: 5 additions & 5 deletions src/ImageSharp/Formats/Png/PngThrowHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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 changes: 3 additions & 3 deletions src/ImageSharp/Formats/Tga/TgaDecoderCore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -114,12 +114,12 @@ public Image<TPixel> Decode<TPixel>(Stream stream)
{
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;
Expand Down Expand Up @@ -898,7 +898,7 @@ private TgaImageOrigin ReadFileHeader(Stream stream)
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;
Expand Down
Loading