Browse Source

Cleanup

pull/2364/head
James Jackson-South 3 years ago
parent
commit
992361f967
  1. 5
      .gitattributes
  2. 63
      src/ImageSharp/Formats/Webp/AlphaDecoder.cs
  3. 25
      src/ImageSharp/Formats/Webp/AlphaEncoder.cs
  4. 10
      src/ImageSharp/Formats/Webp/BitReader/BitReaderBase.cs
  5. 7
      src/ImageSharp/Formats/Webp/Lossless/ColorCache.cs
  6. 10
      src/ImageSharp/Formats/Webp/Lossy/Vp8Encoder.cs
  7. 98
      src/ImageSharp/Formats/Webp/WebpDecoderCore.cs
  8. 2
      src/ImageSharp/Formats/Webp/WebpEncoder.cs
  9. 11
      src/ImageSharp/Formats/Webp/WebpEncoderCore.cs

5
.gitattributes

@ -64,18 +64,19 @@
# Set explicit file behavior to:
# treat as text
# normalize to Unix-style line endings and
# use a union merge when resoling conflicts
# use a union merge when resolving conflicts
###############################################################################
*.csproj text eol=lf merge=union
*.dbproj text eol=lf merge=union
*.fsproj text eol=lf merge=union
*.ncrunchproject text eol=lf merge=union
*.vbproj text eol=lf merge=union
*.shproj text eol=lf merge=union
###############################################################################
# Set explicit file behavior to:
# treat as text
# normalize to Windows-style line endings and
# use a union merge when resoling conflicts
# use a union merge when resolving conflicts
###############################################################################
*.sln text eol=crlf merge=union
###############################################################################

63
src/ImageSharp/Formats/Webp/AlphaDecoder.cs

@ -38,7 +38,7 @@ internal class AlphaDecoder : IDisposable
this.LastRow = 0;
int totalPixels = width * height;
var compression = (WebpAlphaCompressionMethod)(alphaChunkHeader & 0x03);
WebpAlphaCompressionMethod compression = (WebpAlphaCompressionMethod)(alphaChunkHeader & 0x03);
if (compression is not WebpAlphaCompressionMethod.NoCompression and not WebpAlphaCompressionMethod.WebpLosslessCompression)
{
WebpThrowHelper.ThrowImageFormatException($"unexpected alpha compression method {compression} found");
@ -59,7 +59,7 @@ internal class AlphaDecoder : IDisposable
if (this.Compressed)
{
var bitReader = new Vp8LBitReader(data);
Vp8LBitReader bitReader = new(data);
this.LosslessDecoder = new WebpLosslessDecoder(bitReader, memoryAllocator, configuration);
this.LosslessDecoder.DecodeImageStream(this.Vp8LDec, width, height, true);
@ -174,17 +174,14 @@ internal class AlphaDecoder : IDisposable
dst = dst[this.Width..];
}
}
else if (this.Use8BDecode)
{
this.LosslessDecoder.DecodeAlphaData(this);
}
else
{
if (this.Use8BDecode)
{
this.LosslessDecoder.DecodeAlphaData(this);
}
else
{
this.LosslessDecoder.DecodeImageData(this.Vp8LDec, this.Vp8LDec.Pixels.Memory.Span);
this.ExtractAlphaRows(this.Vp8LDec);
}
this.LosslessDecoder.DecodeImageData(this.Vp8LDec, this.Vp8LDec.Pixels.Memory.Span);
this.ExtractAlphaRows(this.Vp8LDec);
}
}
@ -262,8 +259,7 @@ internal class AlphaDecoder : IDisposable
{
int numRowsToProcess = dec.Height;
int width = dec.Width;
Span<uint> pixels = dec.Pixels.Memory.Span;
Span<uint> input = pixels;
Span<uint> input = dec.Pixels.Memory.Span;
Span<byte> output = this.Alpha.Memory.Span;
// Extract alpha (which is stored in the green plane).
@ -328,7 +324,7 @@ internal class AlphaDecoder : IDisposable
ref byte srcRef = ref MemoryMarshal.GetReference(input);
for (i = 1; i + 8 <= width; i += 8)
{
var a0 = Vector128.Create(Unsafe.As<byte, long>(ref Unsafe.Add(ref srcRef, i)), 0);
Vector128<long> a0 = Vector128.Create(Unsafe.As<byte, long>(ref Unsafe.Add(ref srcRef, i)), 0);
Vector128<byte> a1 = Sse2.Add(a0.AsByte(), last.AsByte());
Vector128<byte> a2 = Sse2.ShiftLeftLogical128BitLane(a1, 1);
Vector128<byte> a3 = Sse2.Add(a1, a2);
@ -366,32 +362,29 @@ internal class AlphaDecoder : IDisposable
{
HorizontalUnfilter(null, input, dst, width);
}
else
else if (Avx2.IsSupported)
{
if (Avx2.IsSupported)
nint i;
int maxPos = width & ~31;
for (i = 0; i < maxPos; i += 32)
{
nint i;
int maxPos = width & ~31;
for (i = 0; i < maxPos; i += 32)
{
Vector256<int> a0 = Unsafe.As<byte, Vector256<int>>(ref Unsafe.Add(ref MemoryMarshal.GetReference(input), i));
Vector256<int> b0 = Unsafe.As<byte, Vector256<int>>(ref Unsafe.Add(ref MemoryMarshal.GetReference(prev), i));
Vector256<byte> c0 = Avx2.Add(a0.AsByte(), b0.AsByte());
ref byte outputRef = ref Unsafe.Add(ref MemoryMarshal.GetReference(dst), i);
Unsafe.As<byte, Vector256<byte>>(ref outputRef) = c0;
}
Vector256<int> a0 = Unsafe.As<byte, Vector256<int>>(ref Unsafe.Add(ref MemoryMarshal.GetReference(input), i));
Vector256<int> b0 = Unsafe.As<byte, Vector256<int>>(ref Unsafe.Add(ref MemoryMarshal.GetReference(prev), i));
Vector256<byte> c0 = Avx2.Add(a0.AsByte(), b0.AsByte());
ref byte outputRef = ref Unsafe.Add(ref MemoryMarshal.GetReference(dst), i);
Unsafe.As<byte, Vector256<byte>>(ref outputRef) = c0;
}
for (; i < width; i++)
{
dst[(int)i] = (byte)(prev[(int)i] + input[(int)i]);
}
for (; i < width; i++)
{
dst[(int)i] = (byte)(prev[(int)i] + input[(int)i]);
}
else
}
else
{
for (int i = 0; i < width; i++)
{
for (int i = 0; i < width; i++)
{
dst[i] = (byte)(prev[i] + input[i]);
}
dst[i] = (byte)(prev[i] + input[i]);
}
}
}

25
src/ImageSharp/Formats/Webp/AlphaEncoder.cs

@ -12,10 +12,8 @@ namespace SixLabors.ImageSharp.Formats.Webp;
/// <summary>
/// Methods for encoding the alpha data of a VP8 image.
/// </summary>
internal class AlphaEncoder : IDisposable
internal static class AlphaEncoder
{
private IMemoryOwner<byte>? alphaData;
/// <summary>
/// Encodes the alpha channel data.
/// Data is either compressed as lossless webp image or uncompressed.
@ -28,12 +26,18 @@ internal class AlphaEncoder : IDisposable
/// <param name="compress">Indicates, if the data should be compressed with the lossless webp compression.</param>
/// <param name="size">The size in bytes of the alpha data.</param>
/// <returns>The encoded alpha data.</returns>
public IMemoryOwner<byte> EncodeAlpha<TPixel>(Image<TPixel> image, Configuration configuration, MemoryAllocator memoryAllocator, bool skipMetadata, bool compress, out int size)
public static IMemoryOwner<byte> EncodeAlpha<TPixel>(
Image<TPixel> image,
Configuration configuration,
MemoryAllocator memoryAllocator,
bool skipMetadata,
bool compress,
out int size)
where TPixel : unmanaged, IPixel<TPixel>
{
int width = image.Width;
int height = image.Height;
this.alphaData = ExtractAlphaChannel(image, configuration, memoryAllocator);
IMemoryOwner<byte> alphaData = ExtractAlphaChannel(image, configuration, memoryAllocator);
if (compress)
{
@ -54,15 +58,15 @@ internal class AlphaEncoder : IDisposable
// The transparency information will be stored in the green channel of the ARGB quadruplet.
// The green channel is allowed extra transformation steps in the specification -- unlike the other channels,
// that can improve compression.
using Image<Rgba32> alphaAsImage = DispatchAlphaToGreen(image, this.alphaData.GetSpan());
using Image<Rgba32> alphaAsImage = DispatchAlphaToGreen(image, alphaData.GetSpan());
size = lossLessEncoder.EncodeAlphaImageData(alphaAsImage, this.alphaData);
size = lossLessEncoder.EncodeAlphaImageData(alphaAsImage, alphaData);
return this.alphaData;
return alphaData;
}
size = width * height;
return this.alphaData;
return alphaData;
}
/// <summary>
@ -127,7 +131,4 @@ internal class AlphaEncoder : IDisposable
return alphaDataBuffer;
}
/// <inheritdoc/>
public void Dispose() => this.alphaData?.Dispose();
}

10
src/ImageSharp/Formats/Webp/BitReader/BitReaderBase.cs

@ -13,14 +13,16 @@ internal abstract class BitReaderBase : IDisposable
{
private bool isDisposed;
protected BitReaderBase(IMemoryOwner<byte> data) => this.Data = data;
protected BitReaderBase(IMemoryOwner<byte> data)
=> this.Data = data;
protected BitReaderBase(Stream inputStream, int imageDataSize, MemoryAllocator memoryAllocator) => this.Data = ReadImageDataFromStream(inputStream, imageDataSize, memoryAllocator);
protected BitReaderBase(Stream inputStream, int imageDataSize, MemoryAllocator memoryAllocator)
=> this.Data = ReadImageDataFromStream(inputStream, imageDataSize, memoryAllocator);
/// <summary>
/// Gets or sets the raw encoded image data.
/// Gets the raw encoded image data.
/// </summary>
public IMemoryOwner<byte> Data { get; set; }
public IMemoryOwner<byte> Data { get; }
/// <summary>
/// Copies the raw encoded image data from the stream into a byte array.

7
src/ImageSharp/Formats/Webp/Lossless/ColorCache.cs

@ -1,7 +1,6 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
namespace SixLabors.ImageSharp.Formats.Webp.Lossless;
@ -28,17 +27,17 @@ internal class ColorCache
/// <summary>
/// Gets the color entries.
/// </summary>
public uint[] Colors { get; private set; }
public uint[] Colors { get; }
/// <summary>
/// Gets the hash shift: 32 - hashBits.
/// </summary>
public int HashShift { get; private set; }
public int HashShift { get; }
/// <summary>
/// Gets the hash bits.
/// </summary>
public int HashBits { get; private set; }
public int HashBits { get; }
/// <summary>
/// Inserts a new color into the cache.

10
src/ImageSharp/Formats/Webp/Lossy/Vp8Encoder.cs

@ -348,12 +348,18 @@ internal class Vp8Encoder : IDisposable
// Extract and encode alpha channel data, if present.
int alphaDataSize = 0;
bool alphaCompressionSucceeded = false;
using AlphaEncoder alphaEncoder = new();
Span<byte> alphaData = Span<byte>.Empty;
if (hasAlpha)
{
// TODO: This can potentially run in an separate task.
IMemoryOwner<byte> encodedAlphaData = alphaEncoder.EncodeAlpha(image, this.configuration, this.memoryAllocator, this.skipMetadata, this.alphaCompression, out alphaDataSize);
using IMemoryOwner<byte> encodedAlphaData = AlphaEncoder.EncodeAlpha(
image,
this.configuration,
this.memoryAllocator,
this.skipMetadata,
this.alphaCompression,
out alphaDataSize);
alphaData = encodedAlphaData.GetSpan();
if (alphaDataSize < pixelCount)
{

98
src/ImageSharp/Formats/Webp/WebpDecoderCore.cs

@ -8,9 +8,7 @@ using SixLabors.ImageSharp.Formats.Webp.Lossy;
using SixLabors.ImageSharp.IO;
using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.Metadata;
using SixLabors.ImageSharp.Metadata.Profiles.Exif;
using SixLabors.ImageSharp.Metadata.Profiles.Icc;
using SixLabors.ImageSharp.Metadata.Profiles.Xmp;
using SixLabors.ImageSharp.PixelFormats;
namespace SixLabors.ImageSharp.Formats.Webp;
@ -40,11 +38,6 @@ internal sealed class WebpDecoderCore : IImageDecoderInternals, IDisposable
/// </summary>
private readonly uint maxFrames;
/// <summary>
/// Gets the <see cref="ImageMetadata"/> decoded by this decoder instance.
/// </summary>
private ImageMetadata? metadata;
/// <summary>
/// Gets or sets the alpha data, if an ALPH chunk is present.
/// </summary>
@ -55,11 +48,6 @@ internal sealed class WebpDecoderCore : IImageDecoderInternals, IDisposable
/// </summary>
private readonly MemoryAllocator memoryAllocator;
/// <summary>
/// The webp specific metadata.
/// </summary>
private WebpMetadata? webpMetadata;
/// <summary>
/// Information about the webp image.
/// </summary>
@ -91,15 +79,15 @@ internal sealed class WebpDecoderCore : IImageDecoderInternals, IDisposable
Image<TPixel>? image = null;
try
{
this.metadata = new ImageMetadata();
ImageMetadata metadata = new();
uint fileSize = this.ReadImageHeader(stream);
using (this.webImageInfo = this.ReadVp8Info(stream))
using (this.webImageInfo = this.ReadVp8Info(stream, metadata))
{
if (this.webImageInfo.Features is { Animation: true })
{
using var animationDecoder = new WebpAnimationDecoder(this.memoryAllocator, this.configuration, this.maxFrames);
using WebpAnimationDecoder animationDecoder = new(this.memoryAllocator, this.configuration, this.maxFrames);
return animationDecoder.Decode<TPixel>(stream, this.webImageInfo.Features, this.webImageInfo.Width, this.webImageInfo.Height, fileSize);
}
@ -108,23 +96,23 @@ internal sealed class WebpDecoderCore : IImageDecoderInternals, IDisposable
WebpThrowHelper.ThrowNotSupportedException("Animations are not supported");
}
image = new Image<TPixel>(this.configuration, (int)this.webImageInfo.Width, (int)this.webImageInfo.Height, this.metadata);
image = new Image<TPixel>(this.configuration, (int)this.webImageInfo.Width, (int)this.webImageInfo.Height, metadata);
Buffer2D<TPixel> pixels = image.GetRootFramePixelBuffer();
if (this.webImageInfo.IsLossless)
{
var losslessDecoder = new WebpLosslessDecoder(this.webImageInfo.Vp8LBitReader, this.memoryAllocator, this.configuration);
WebpLosslessDecoder losslessDecoder = new(this.webImageInfo.Vp8LBitReader, this.memoryAllocator, this.configuration);
losslessDecoder.Decode(pixels, image.Width, image.Height);
}
else
{
var lossyDecoder = new WebpLossyDecoder(this.webImageInfo.Vp8BitReader, this.memoryAllocator, this.configuration);
WebpLossyDecoder lossyDecoder = new(this.webImageInfo.Vp8BitReader, this.memoryAllocator, this.configuration);
lossyDecoder.Decode(pixels, image.Width, image.Height, this.webImageInfo, this.alphaData);
}
// There can be optional chunks after the image data, like EXIF and XMP.
if (this.webImageInfo.Features != null)
{
this.ParseOptionalChunks(stream, this.webImageInfo.Features);
this.ParseOptionalChunks(stream, metadata, this.webImageInfo.Features);
}
return image;
@ -141,9 +129,11 @@ internal sealed class WebpDecoderCore : IImageDecoderInternals, IDisposable
public ImageInfo Identify(BufferedReadStream stream, CancellationToken cancellationToken)
{
this.ReadImageHeader(stream);
using (this.webImageInfo = this.ReadVp8Info(stream, true))
ImageMetadata metadata = new();
using (this.webImageInfo = this.ReadVp8Info(stream, metadata, true))
{
return new ImageInfo(new PixelTypeInfo((int)this.webImageInfo.BitsPerPixel), (int)this.webImageInfo.Width, (int)this.webImageInfo.Height, this.metadata);
return new ImageInfo(new PixelTypeInfo((int)this.webImageInfo.BitsPerPixel), (int)this.webImageInfo.Width, (int)this.webImageInfo.Height, metadata);
}
}
@ -172,23 +162,23 @@ internal sealed class WebpDecoderCore : IImageDecoderInternals, IDisposable
/// Reads information present in the image header, about the image content and how to decode the image.
/// </summary>
/// <param name="stream">The stream to decode from.</param>
/// <param name="metadata">The image metadata.</param>
/// <param name="ignoreAlpha">For identify, the alpha data should not be read.</param>
/// <returns>Information about the webp image.</returns>
private WebpImageInfo ReadVp8Info(BufferedReadStream stream, bool ignoreAlpha = false)
private WebpImageInfo ReadVp8Info(BufferedReadStream stream, ImageMetadata metadata, bool ignoreAlpha = false)
{
this.metadata = new ImageMetadata();
this.webpMetadata = this.metadata.GetFormatMetadata(WebpFormat.Instance);
WebpMetadata webpMetadata = metadata.GetFormatMetadata(WebpFormat.Instance);
WebpChunkType chunkType = WebpChunkParsingUtils.ReadChunkType(stream, this.buffer);
var features = new WebpFeatures();
WebpFeatures features = new();
switch (chunkType)
{
case WebpChunkType.Vp8:
this.webpMetadata.FileFormat = WebpFileFormatType.Lossy;
webpMetadata.FileFormat = WebpFileFormatType.Lossy;
return WebpChunkParsingUtils.ReadVp8Header(this.memoryAllocator, stream, this.buffer, features);
case WebpChunkType.Vp8L:
this.webpMetadata.FileFormat = WebpFileFormatType.Lossless;
webpMetadata.FileFormat = WebpFileFormatType.Lossless;
return WebpChunkParsingUtils.ReadVp8LHeader(this.memoryAllocator, stream, this.buffer, features);
case WebpChunkType.Vp8X:
WebpImageInfo webpInfos = WebpChunkParsingUtils.ReadVp8XHeader(stream, this.buffer, features);
@ -197,17 +187,17 @@ internal sealed class WebpDecoderCore : IImageDecoderInternals, IDisposable
chunkType = WebpChunkParsingUtils.ReadChunkType(stream, this.buffer);
if (chunkType == WebpChunkType.Vp8)
{
this.webpMetadata.FileFormat = WebpFileFormatType.Lossy;
webpMetadata.FileFormat = WebpFileFormatType.Lossy;
webpInfos = WebpChunkParsingUtils.ReadVp8Header(this.memoryAllocator, stream, this.buffer, features);
}
else if (chunkType == WebpChunkType.Vp8L)
{
this.webpMetadata.FileFormat = WebpFileFormatType.Lossless;
webpMetadata.FileFormat = WebpFileFormatType.Lossless;
webpInfos = WebpChunkParsingUtils.ReadVp8LHeader(this.memoryAllocator, stream, this.buffer, features);
}
else if (WebpChunkParsingUtils.IsOptionalVp8XChunk(chunkType))
{
bool isAnimationChunk = this.ParseOptionalExtendedChunks(stream, chunkType, features, ignoreAlpha);
bool isAnimationChunk = this.ParseOptionalExtendedChunks(stream, metadata, chunkType, features, ignoreAlpha);
if (isAnimationChunk)
{
return webpInfos;
@ -233,24 +223,30 @@ internal sealed class WebpDecoderCore : IImageDecoderInternals, IDisposable
/// Parses optional VP8X chunks, which can be ICCP, XMP, ANIM or ALPH chunks.
/// </summary>
/// <param name="stream">The stream to decode from.</param>
/// <param name="metadata">The image metadata.</param>
/// <param name="chunkType">The chunk type.</param>
/// <param name="features">The webp image features.</param>
/// <param name="ignoreAlpha">For identify, the alpha data should not be read.</param>
/// <returns>true, if its a alpha chunk.</returns>
private bool ParseOptionalExtendedChunks(BufferedReadStream stream, WebpChunkType chunkType, WebpFeatures features, bool ignoreAlpha)
private bool ParseOptionalExtendedChunks(
BufferedReadStream stream,
ImageMetadata metadata,
WebpChunkType chunkType,
WebpFeatures features,
bool ignoreAlpha)
{
switch (chunkType)
{
case WebpChunkType.Iccp:
this.ReadIccProfile(stream);
this.ReadIccProfile(stream, metadata);
break;
case WebpChunkType.Exif:
this.ReadExifProfile(stream);
this.ReadExifProfile(stream, metadata);
break;
case WebpChunkType.Xmp:
this.ReadXmpProfile(stream);
this.ReadXmpProfile(stream, metadata);
break;
case WebpChunkType.AnimationParameter:
@ -272,8 +268,9 @@ internal sealed class WebpDecoderCore : IImageDecoderInternals, IDisposable
/// Reads the optional metadata EXIF of XMP profiles, which can follow the image data.
/// </summary>
/// <param name="stream">The stream to decode from.</param>
/// <param name="metadata">The image metadata.</param>
/// <param name="features">The webp features.</param>
private void ParseOptionalChunks(BufferedReadStream stream, WebpFeatures features)
private void ParseOptionalChunks(BufferedReadStream stream, ImageMetadata metadata, WebpFeatures features)
{
if (this.skipMetadata || (!features.ExifProfile && !features.XmpMetaData))
{
@ -285,13 +282,13 @@ internal sealed class WebpDecoderCore : IImageDecoderInternals, IDisposable
{
// Read chunk header.
WebpChunkType chunkType = this.ReadChunkType(stream);
if (chunkType == WebpChunkType.Exif && this.metadata!.ExifProfile == null)
if (chunkType == WebpChunkType.Exif && metadata.ExifProfile == null)
{
this.ReadExifProfile(stream);
this.ReadExifProfile(stream, metadata);
}
else if (chunkType == WebpChunkType.Xmp && this.metadata!.XmpProfile == null)
else if (chunkType == WebpChunkType.Xmp && metadata.XmpProfile == null)
{
this.ReadXmpProfile(stream);
this.ReadXmpProfile(stream, metadata);
}
else
{
@ -306,7 +303,8 @@ internal sealed class WebpDecoderCore : IImageDecoderInternals, IDisposable
/// Reads the EXIF profile from the stream.
/// </summary>
/// <param name="stream">The stream to decode from.</param>
private void ReadExifProfile(BufferedReadStream stream)
/// <param name="metadata">The image metadata.</param>
private void ReadExifProfile(BufferedReadStream stream, ImageMetadata metadata)
{
uint exifChunkSize = this.ReadChunkSize(stream);
if (this.skipMetadata)
@ -323,8 +321,7 @@ internal sealed class WebpDecoderCore : IImageDecoderInternals, IDisposable
return;
}
var profile = new ExifProfile(exifData);
this.metadata!.ExifProfile = profile;
metadata.ExifProfile = new(exifData);
}
}
@ -332,7 +329,8 @@ internal sealed class WebpDecoderCore : IImageDecoderInternals, IDisposable
/// Reads the XMP profile the stream.
/// </summary>
/// <param name="stream">The stream to decode from.</param>
private void ReadXmpProfile(BufferedReadStream stream)
/// <param name="metadata">The image metadata.</param>
private void ReadXmpProfile(BufferedReadStream stream, ImageMetadata metadata)
{
uint xmpChunkSize = this.ReadChunkSize(stream);
if (this.skipMetadata)
@ -349,8 +347,7 @@ internal sealed class WebpDecoderCore : IImageDecoderInternals, IDisposable
return;
}
var profile = new XmpProfile(xmpData);
this.metadata!.XmpProfile = profile;
metadata.XmpProfile = new(xmpData);
}
}
@ -358,7 +355,8 @@ internal sealed class WebpDecoderCore : IImageDecoderInternals, IDisposable
/// Reads the ICCP chunk from the stream.
/// </summary>
/// <param name="stream">The stream to decode from.</param>
private void ReadIccProfile(BufferedReadStream stream)
/// <param name="metadata">The image metadata.</param>
private void ReadIccProfile(BufferedReadStream stream, ImageMetadata metadata)
{
uint iccpChunkSize = this.ReadChunkSize(stream);
if (this.skipMetadata)
@ -374,10 +372,10 @@ internal sealed class WebpDecoderCore : IImageDecoderInternals, IDisposable
WebpThrowHelper.ThrowInvalidImageContentException("Not enough data to read the iccp chunk");
}
var profile = new IccProfile(iccpData);
IccProfile profile = new(iccpData);
if (profile.CheckIsValid())
{
this.metadata!.IccProfile = profile;
metadata.IccProfile = profile;
}
}
}
@ -442,8 +440,7 @@ internal sealed class WebpDecoderCore : IImageDecoderInternals, IDisposable
{
if (stream.Read(this.buffer, 0, 4) == 4)
{
var chunkType = (WebpChunkType)BinaryPrimitives.ReadUInt32BigEndian(this.buffer);
return chunkType;
return (WebpChunkType)BinaryPrimitives.ReadUInt32BigEndian(this.buffer);
}
throw new ImageFormatException("Invalid Webp data.");
@ -455,6 +452,7 @@ internal sealed class WebpDecoderCore : IImageDecoderInternals, IDisposable
/// </summary>
/// <param name="stream">The stream to decode from.</param>
/// <returns>The chunk size in bytes.</returns>
/// <exception cref="ImageFormatException">Invalid data.</exception>
private uint ReadChunkSize(BufferedReadStream stream)
{
if (stream.Read(this.buffer, 0, 4) == 4)

2
src/ImageSharp/Formats/Webp/WebpEncoder.cs

@ -82,7 +82,7 @@ public sealed class WebpEncoder : ImageEncoder
/// <inheritdoc/>
protected override void Encode<TPixel>(Image<TPixel> image, Stream stream, CancellationToken cancellationToken)
{
WebpEncoderCore encoder = new(this, image.GetMemoryAllocator());
WebpEncoderCore encoder = new(this, image.GetConfiguration());
encoder.Encode(image, stream, cancellationToken);
}
}

11
src/ImageSharp/Formats/Webp/WebpEncoderCore.cs

@ -1,7 +1,6 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.Formats.Webp.Lossless;
using SixLabors.ImageSharp.Formats.Webp.Lossy;
using SixLabors.ImageSharp.Memory;
@ -80,16 +79,17 @@ internal sealed class WebpEncoderCore : IImageEncoderInternals
/// <summary>
/// The global configuration.
/// </summary>
private Configuration? configuration;
private readonly Configuration configuration;
/// <summary>
/// Initializes a new instance of the <see cref="WebpEncoderCore"/> class.
/// </summary>
/// <param name="encoder">The encoder with options.</param>
/// <param name="memoryAllocator">The memory manager.</param>
public WebpEncoderCore(WebpEncoder encoder, MemoryAllocator memoryAllocator)
/// <param name="configuration">The global configuration.</param>
public WebpEncoderCore(WebpEncoder encoder, Configuration configuration)
{
this.memoryAllocator = memoryAllocator;
this.configuration = configuration;
this.memoryAllocator = configuration.MemoryAllocator;
this.alphaCompression = encoder.UseAlphaCompression;
this.fileFormat = encoder.FileFormat;
this.quality = encoder.Quality;
@ -116,7 +116,6 @@ internal sealed class WebpEncoderCore : IImageEncoderInternals
Guard.NotNull(image, nameof(image));
Guard.NotNull(stream, nameof(stream));
this.configuration = image.GetConfiguration();
bool lossless;
if (this.fileFormat is not null)
{

Loading…
Cancel
Save