Skip to content

Commit 271dc99

Browse files
Merge pull request #2317 from SixLabors/js/move-iimageformat
Remove ImageFormat out params and return on Metadata
2 parents f1968ba + 96a22c4 commit 271dc99

File tree

111 files changed

+1719
-2352
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

111 files changed

+1719
-2352
lines changed

src/ImageSharp/Advanced/AdvancedImageExtensions.cs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@ public static class AdvancedImageExtensions
1919
/// </summary>
2020
/// <param name="source">The source image.</param>
2121
/// <param name="filePath">The target file path to save the image to.</param>
22-
/// <exception cref="ArgumentNullException">The file path is null.</exception>
23-
/// <exception cref="NotSupportedException">No encoder available for provided path.</exception>
2422
/// <returns>The matching <see cref="IImageEncoder"/>.</returns>
23+
/// <exception cref="ArgumentNullException">The file path is null.</exception>
24+
/// <exception cref="UnknownImageFormatException">No encoder available for provided path.</exception>
2525
public static IImageEncoder DetectEncoder(this Image source, string filePath)
2626
{
2727
Guard.NotNull(filePath, nameof(filePath));
@@ -30,27 +30,27 @@ public static IImageEncoder DetectEncoder(this Image source, string filePath)
3030
if (!source.GetConfiguration().ImageFormatsManager.TryFindFormatByFileExtension(ext, out IImageFormat? format))
3131
{
3232
StringBuilder sb = new();
33-
sb.AppendLine(CultureInfo.InvariantCulture, $"No encoder was found for extension '{ext}'. Registered encoders include:");
33+
sb = sb.AppendLine(CultureInfo.InvariantCulture, $"No encoder was found for extension '{ext}'. Registered encoders include:");
3434
foreach (IImageFormat fmt in source.GetConfiguration().ImageFormats)
3535
{
36-
sb.AppendFormat(CultureInfo.InvariantCulture, " - {0} : {1}{2}", fmt.Name, string.Join(", ", fmt.FileExtensions), Environment.NewLine);
36+
sb = sb.AppendFormat(CultureInfo.InvariantCulture, " - {0} : {1}{2}", fmt.Name, string.Join(", ", fmt.FileExtensions), Environment.NewLine);
3737
}
3838

39-
throw new NotSupportedException(sb.ToString());
39+
throw new UnknownImageFormatException(sb.ToString());
4040
}
4141

42-
IImageEncoder? encoder = source.GetConfiguration().ImageFormatsManager.FindEncoder(format);
42+
IImageEncoder? encoder = source.GetConfiguration().ImageFormatsManager.GetEncoder(format);
4343

4444
if (encoder is null)
4545
{
4646
StringBuilder sb = new();
47-
sb.AppendLine(CultureInfo.InvariantCulture, $"No encoder was found for extension '{ext}' using image format '{format.Name}'. Registered encoders include:");
47+
sb = sb.AppendLine(CultureInfo.InvariantCulture, $"No encoder was found for extension '{ext}' using image format '{format.Name}'. Registered encoders include:");
4848
foreach (KeyValuePair<IImageFormat, IImageEncoder> enc in source.GetConfiguration().ImageFormatsManager.ImageEncoders)
4949
{
50-
sb.AppendFormat(CultureInfo.InvariantCulture, " - {0} : {1}{2}", enc.Key, enc.Value.GetType().Name, Environment.NewLine);
50+
sb = sb.AppendFormat(CultureInfo.InvariantCulture, " - {0} : {1}{2}", enc.Key, enc.Value.GetType().Name, Environment.NewLine);
5151
}
5252

53-
throw new NotSupportedException(sb.ToString());
53+
throw new UnknownImageFormatException(sb.ToString());
5454
}
5555

5656
return encoder;

src/ImageSharp/Formats/Bmp/BmpDecoder.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ private BmpDecoder()
2020
public static BmpDecoder Instance { get; } = new();
2121

2222
/// <inheritdoc/>
23-
protected override IImageInfo Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
23+
protected override ImageInfo Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
2424
{
2525
Guard.NotNull(options, nameof(options));
2626
Guard.NotNull(stream, nameof(stream));

src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ public Image<TPixel> Decode<TPixel>(BufferedReadStream stream, CancellationToken
209209
}
210210

211211
/// <inheritdoc />
212-
public IImageInfo Identify(BufferedReadStream stream, CancellationToken cancellationToken)
212+
public ImageInfo Identify(BufferedReadStream stream, CancellationToken cancellationToken)
213213
{
214214
this.ReadImageHeaders(stream, out _, out _);
215215
return new ImageInfo(new PixelTypeInfo(this.infoHeader.BitsPerPixel), this.infoHeader.Width, this.infoHeader.Height, this.metadata);

src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -215,15 +215,15 @@ private BmpInfoHeader CreateBmpInfoHeader(int width, int height, int infoHeaderS
215215

216216
BmpInfoHeader infoHeader = new(
217217
headerSize: infoHeaderSize,
218-
height: height,
219218
width: width,
220-
bitsPerPixel: bpp,
219+
height: height,
221220
planes: 1,
221+
bitsPerPixel: bpp,
222222
imageSize: height * bytesPerLine,
223-
clrUsed: 0,
224-
clrImportant: 0,
225223
xPelsPerMeter: hResolution,
226-
yPelsPerMeter: vResolution);
224+
yPelsPerMeter: vResolution,
225+
clrUsed: 0,
226+
clrImportant: 0);
227227

228228
if ((this.infoHeaderType is BmpInfoHeaderType.WinVersion4 or BmpInfoHeaderType.WinVersion5) && this.bitsPerPixel == BmpBitsPerPixel.Pixel32)
229229
{
@@ -470,7 +470,7 @@ private void Write8BitColor<TPixel>(Stream stream, Image<TPixel> image, Span<byt
470470
using IQuantizer<TPixel> frameQuantizer = this.quantizer.CreatePixelSpecificQuantizer<TPixel>(this.configuration);
471471

472472
frameQuantizer.BuildPalette(this.pixelSamplingStrategy, image);
473-
using IndexedImageFrame<TPixel> quantized = frameQuantizer.QuantizeFrame(image.Frames.RootFrame, image.Bounds());
473+
using IndexedImageFrame<TPixel> quantized = frameQuantizer.QuantizeFrame(image.Frames.RootFrame, image.Bounds);
474474

475475
ReadOnlySpan<TPixel> quantizedColorPalette = quantized.Palette.Span;
476476
this.WriteColorPalette(stream, quantizedColorPalette, colorPalette);
@@ -541,7 +541,7 @@ private void Write4BitPixelData<TPixel>(Stream stream, Image<TPixel> image)
541541

542542
frameQuantizer.BuildPalette(this.pixelSamplingStrategy, image);
543543

544-
using IndexedImageFrame<TPixel> quantized = frameQuantizer.QuantizeFrame(image.Frames.RootFrame, image.Bounds());
544+
using IndexedImageFrame<TPixel> quantized = frameQuantizer.QuantizeFrame(image.Frames.RootFrame, image.Bounds);
545545
using IMemoryOwner<byte> colorPaletteBuffer = this.memoryAllocator.Allocate<byte>(ColorPaletteSize4Bit, AllocationOptions.Clean);
546546

547547
Span<byte> colorPalette = colorPaletteBuffer.GetSpan();
@@ -588,7 +588,7 @@ private void Write2BitPixelData<TPixel>(Stream stream, Image<TPixel> image)
588588

589589
frameQuantizer.BuildPalette(this.pixelSamplingStrategy, image);
590590

591-
using IndexedImageFrame<TPixel> quantized = frameQuantizer.QuantizeFrame(image.Frames.RootFrame, image.Bounds());
591+
using IndexedImageFrame<TPixel> quantized = frameQuantizer.QuantizeFrame(image.Frames.RootFrame, image.Bounds);
592592
using IMemoryOwner<byte> colorPaletteBuffer = this.memoryAllocator.Allocate<byte>(ColorPaletteSize2Bit, AllocationOptions.Clean);
593593

594594
Span<byte> colorPalette = colorPaletteBuffer.GetSpan();
@@ -644,7 +644,7 @@ private void Write1BitPixelData<TPixel>(Stream stream, Image<TPixel> image)
644644

645645
frameQuantizer.BuildPalette(this.pixelSamplingStrategy, image);
646646

647-
using IndexedImageFrame<TPixel> quantized = frameQuantizer.QuantizeFrame(image.Frames.RootFrame, image.Bounds());
647+
using IndexedImageFrame<TPixel> quantized = frameQuantizer.QuantizeFrame(image.Frames.RootFrame, image.Bounds);
648648
using IMemoryOwner<byte> colorPaletteBuffer = this.memoryAllocator.Allocate<byte>(ColorPaletteSize1Bit, AllocationOptions.Clean);
649649

650650
Span<byte> colorPalette = colorPaletteBuffer.GetSpan();

src/ImageSharp/Formats/Gif/GifDecoder.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ private GifDecoder()
2020
public static GifDecoder Instance { get; } = new();
2121

2222
/// <inheritdoc/>
23-
protected override IImageInfo Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
23+
protected override ImageInfo Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken)
2424
{
2525
Guard.NotNull(options, nameof(options));
2626
Guard.NotNull(stream, nameof(stream));

src/ImageSharp/Formats/Gif/GifDecoderCore.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ public Image<TPixel> Decode<TPixel>(BufferedReadStream stream, CancellationToken
175175
}
176176

177177
/// <inheritdoc />
178-
public IImageInfo Identify(BufferedReadStream stream, CancellationToken cancellationToken)
178+
public ImageInfo Identify(BufferedReadStream stream, CancellationToken cancellationToken)
179179
{
180180
try
181181
{

src/ImageSharp/Formats/Gif/GifEncoderCore.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,12 +99,12 @@ public void Encode<TPixel>(Image<TPixel> image, Stream stream, CancellationToken
9999
if (useGlobalTable)
100100
{
101101
frameQuantizer.BuildPalette(this.pixelSamplingStrategy, image);
102-
quantized = frameQuantizer.QuantizeFrame(image.Frames.RootFrame, image.Bounds());
102+
quantized = frameQuantizer.QuantizeFrame(image.Frames.RootFrame, image.Bounds);
103103
}
104104
else
105105
{
106106
frameQuantizer.BuildPalette(this.pixelSamplingStrategy, image.Frames.RootFrame);
107-
quantized = frameQuantizer.QuantizeFrame(image.Frames.RootFrame, image.Bounds());
107+
quantized = frameQuantizer.QuantizeFrame(image.Frames.RootFrame, image.Bounds);
108108
}
109109
}
110110

src/ImageSharp/Formats/IImageDecoder.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ public interface IImageDecoder
1515
/// </summary>
1616
/// <param name="options">The general decoder options.</param>
1717
/// <param name="stream">The <see cref="Stream"/> containing image data.</param>
18-
/// <returns>The <see cref="IImageInfo"/> object.</returns>
18+
/// <returns>The <see cref="ImageInfo"/> object.</returns>
1919
/// <exception cref="ImageFormatException">Thrown if the encoded image contains errors.</exception>
20-
public IImageInfo Identify(DecoderOptions options, Stream stream);
20+
public ImageInfo Identify(DecoderOptions options, Stream stream);
2121

2222
/// <summary>
2323
/// Reads the raw image information from the specified stream.
@@ -27,7 +27,7 @@ public interface IImageDecoder
2727
/// <param name="cancellationToken">The token to monitor for cancellation requests.</param>
2828
/// <returns>The <see cref="Task{IImageInfo}"/> object.</returns>
2929
/// <exception cref="ImageFormatException">Thrown if the encoded image contains errors.</exception>
30-
public Task<IImageInfo> IdentifyAsync(DecoderOptions options, Stream stream, CancellationToken cancellationToken = default);
30+
public Task<ImageInfo> IdentifyAsync(DecoderOptions options, Stream stream, CancellationToken cancellationToken = default);
3131

3232
/// <summary>
3333
/// Decodes the image from the specified stream to an <see cref="Image{TPixel}"/> of a specific pixel type.

src/ImageSharp/Formats/IImageDecoderInternals.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,10 @@ Image<TPixel> Decode<TPixel>(BufferedReadStream stream, CancellationToken cancel
4141
/// </summary>
4242
/// <param name="stream">The <see cref="BufferedReadStream"/> containing image data.</param>
4343
/// <param name="cancellationToken">The token to monitor for cancellation requests.</param>
44-
/// <returns>The <see cref="IImageInfo"/>.</returns>
44+
/// <returns>The <see cref="ImageInfo"/>.</returns>
4545
/// <remarks>
4646
/// Cancellable synchronous method. In case of cancellation,
4747
/// an <see cref="OperationCanceledException"/> shall be thrown which will be handled on the call site.
4848
/// </remarks>
49-
IImageInfo Identify(BufferedReadStream stream, CancellationToken cancellationToken);
49+
ImageInfo Identify(BufferedReadStream stream, CancellationToken cancellationToken);
5050
}

src/ImageSharp/Formats/ImageDecoder.cs

Lines changed: 84 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
// Copyright (c) Six Labors.
22
// Licensed under the Six Labors Split License.
3-
#nullable disable
43

54
using SixLabors.ImageSharp.IO;
65
using SixLabors.ImageSharp.PixelFormats;
@@ -17,49 +16,85 @@ public abstract class ImageDecoder : IImageDecoder
1716
/// <inheritdoc/>
1817
public Image<TPixel> Decode<TPixel>(DecoderOptions options, Stream stream)
1918
where TPixel : unmanaged, IPixel<TPixel>
20-
=> WithSeekableStream(
21-
options,
22-
stream,
23-
s => this.Decode<TPixel>(options, s, default));
19+
{
20+
Image<TPixel> image = WithSeekableStream(
21+
options,
22+
stream,
23+
s => this.Decode<TPixel>(options, s, default));
24+
25+
this.SetDecoderFormat(options.Configuration, image);
26+
27+
return image;
28+
}
2429

2530
/// <inheritdoc/>
2631
public Image Decode(DecoderOptions options, Stream stream)
27-
=> WithSeekableStream(
28-
options,
29-
stream,
30-
s => this.Decode(options, s, default));
32+
{
33+
Image image = WithSeekableStream(
34+
options,
35+
stream,
36+
s => this.Decode(options, s, default));
37+
38+
this.SetDecoderFormat(options.Configuration, image);
39+
40+
return image;
41+
}
3142

3243
/// <inheritdoc/>
33-
public Task<Image<TPixel>> DecodeAsync<TPixel>(DecoderOptions options, Stream stream, CancellationToken cancellationToken = default)
44+
public async Task<Image<TPixel>> DecodeAsync<TPixel>(DecoderOptions options, Stream stream, CancellationToken cancellationToken = default)
3445
where TPixel : unmanaged, IPixel<TPixel>
35-
=> WithSeekableMemoryStreamAsync(
36-
options,
37-
stream,
38-
(s, ct) => this.Decode<TPixel>(options, s, ct),
39-
cancellationToken);
46+
{
47+
Image<TPixel> image = await WithSeekableMemoryStreamAsync(
48+
options,
49+
stream,
50+
(s, ct) => this.Decode<TPixel>(options, s, ct),
51+
cancellationToken).ConfigureAwait(false);
52+
53+
this.SetDecoderFormat(options.Configuration, image);
54+
55+
return image;
56+
}
4057

4158
/// <inheritdoc/>
42-
public Task<Image> DecodeAsync(DecoderOptions options, Stream stream, CancellationToken cancellationToken = default)
43-
=> WithSeekableMemoryStreamAsync(
59+
public async Task<Image> DecodeAsync(DecoderOptions options, Stream stream, CancellationToken cancellationToken = default)
60+
{
61+
Image image = await WithSeekableMemoryStreamAsync(
4462
options,
4563
stream,
4664
(s, ct) => this.Decode(options, s, ct),
47-
cancellationToken);
65+
cancellationToken).ConfigureAwait(false);
66+
67+
this.SetDecoderFormat(options.Configuration, image);
68+
69+
return image;
70+
}
4871

4972
/// <inheritdoc/>
50-
public IImageInfo Identify(DecoderOptions options, Stream stream)
51-
=> WithSeekableStream(
52-
options,
53-
stream,
54-
s => this.Identify(options, s, default));
73+
public ImageInfo Identify(DecoderOptions options, Stream stream)
74+
{
75+
ImageInfo info = WithSeekableStream(
76+
options,
77+
stream,
78+
s => this.Identify(options, s, default));
79+
80+
this.SetDecoderFormat(options.Configuration, info);
81+
82+
return info;
83+
}
5584

5685
/// <inheritdoc/>
57-
public Task<IImageInfo> IdentifyAsync(DecoderOptions options, Stream stream, CancellationToken cancellationToken = default)
58-
=> WithSeekableMemoryStreamAsync(
59-
options,
60-
stream,
61-
(s, ct) => this.Identify(options, s, ct),
62-
cancellationToken);
86+
public async Task<ImageInfo> IdentifyAsync(DecoderOptions options, Stream stream, CancellationToken cancellationToken = default)
87+
{
88+
ImageInfo info = await WithSeekableMemoryStreamAsync(
89+
options,
90+
stream,
91+
(s, ct) => this.Identify(options, s, ct),
92+
cancellationToken).ConfigureAwait(false);
93+
94+
this.SetDecoderFormat(options.Configuration, info);
95+
96+
return info;
97+
}
6398

6499
/// <summary>
65100
/// Decodes the image from the specified stream to an <see cref="Image{TPixel}" /> of a specific pixel type.
@@ -98,9 +133,9 @@ protected abstract Image<TPixel> Decode<TPixel>(DecoderOptions options, Stream s
98133
/// <param name="options">The general decoder options.</param>
99134
/// <param name="stream">The <see cref="Stream"/> containing image data.</param>
100135
/// <param name="cancellationToken">The token to monitor for cancellation requests.</param>
101-
/// <returns>The <see cref="IImageInfo"/> object.</returns>
136+
/// <returns>The <see cref="ImageInfo"/> object.</returns>
102137
/// <exception cref="ImageFormatException">Thrown if the encoded image contains errors.</exception>
103-
protected abstract IImageInfo Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken);
138+
protected abstract ImageInfo Identify(DecoderOptions options, Stream stream, CancellationToken cancellationToken);
104139

105140
/// <summary>
106141
/// Performs a scaling operation against the decoded image. If the target size is not set, or the image size
@@ -114,7 +149,7 @@ protected static void ScaleToTargetSize(DecoderOptions options, Image image)
114149
{
115150
ResizeOptions resizeOptions = new()
116151
{
117-
Size = options.TargetSize.Value,
152+
Size = options.TargetSize!.Value,
118153
Sampler = options.Sampler,
119154
Mode = ResizeMode.Max
120155
};
@@ -137,7 +172,7 @@ private static bool ShouldResize(DecoderOptions options, Image image)
137172
}
138173

139174
Size targetSize = options.TargetSize.Value;
140-
Size currentSize = image.Size();
175+
Size currentSize = image.Size;
141176
return currentSize.Width != targetSize.Width && currentSize.Height != targetSize.Height;
142177
}
143178

@@ -252,4 +287,20 @@ private static async Task<T> CopyToMemoryStreamAndActionAsync<T>(
252287
memoryStream.Position = 0;
253288
return await action(memoryStream, position, cancellationToken).ConfigureAwait(false);
254289
}
290+
291+
internal void SetDecoderFormat(Configuration configuration, Image image)
292+
{
293+
if (configuration.ImageFormatsManager.TryFindFormatByDecoder(this, out IImageFormat? format))
294+
{
295+
image.Metadata.DecodedImageFormat = format;
296+
}
297+
}
298+
299+
internal void SetDecoderFormat(Configuration configuration, ImageInfo info)
300+
{
301+
if (configuration.ImageFormatsManager.TryFindFormatByDecoder(this, out IImageFormat? format))
302+
{
303+
info.Metadata.DecodedImageFormat = format;
304+
}
305+
}
255306
}

0 commit comments

Comments
 (0)