Browse Source

Restore JPEG and PNG implementations to upstream main

Remove unrelated codec changes introduced during the HEIF work. Restore all
three changed JPEG production files and the PNG cICP writer to upstream/main.

The restored files match upstream/main exactly and were included in the
successful Release net11.0 build. HEIF region and ICC changes remain uncommitted.
pull/2633/head
James Jackson-South 4 weeks ago
parent
commit
e38989d630
  1. 1
      src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.Operator.cs
  2. 22
      src/ImageSharp/Formats/Jpeg/Components/Decoder/SpectralConverter{TPixel}.cs
  3. 8
      src/ImageSharp/Formats/Jpeg/JpegEncoderCore.cs
  4. 2
      src/ImageSharp/Formats/Png/PngEncoderCore.cs

1
src/ImageSharp/Formats/Jpeg/Components/ColorConverters/JpegColorConverter.Operator.cs

@ -4,6 +4,7 @@
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Runtime.Intrinsics; using System.Runtime.Intrinsics;
using SixLabors.ImageSharp.Common.Helpers;
namespace SixLabors.ImageSharp.Formats.Jpeg.Components; namespace SixLabors.ImageSharp.Formats.Jpeg.Components;

22
src/ImageSharp/Formats/Jpeg/Components/Decoder/SpectralConverter{TPixel}.cs

@ -42,6 +42,11 @@ internal class SpectralConverter<TPixel> : SpectralConverter, IDisposable
/// </summary> /// </summary>
private IMemoryOwner<byte> rgbBuffer; private IMemoryOwner<byte> rgbBuffer;
/// <summary>
/// Proxy buffer used in packing from RGB to target TPixel pixels.
/// </summary>
private IMemoryOwner<TPixel> paddedProxyPixelRow;
/// <summary> /// <summary>
/// Resulting 2D pixel buffer. /// Resulting 2D pixel buffer.
/// </summary> /// </summary>
@ -158,8 +163,19 @@ internal class SpectralConverter<TPixel> : SpectralConverter, IDisposable
SimdUtils.NormalizedFloatToByteSaturate(values.Component1, g); SimdUtils.NormalizedFloatToByteSaturate(values.Component1, g);
SimdUtils.NormalizedFloatToByteSaturate(values.Component2, b); SimdUtils.NormalizedFloatToByteSaturate(values.Component2, b);
Span<TPixel> destination = this.pixelBuffer.DangerousGetRowSpan(yy); // PackFromRgbPlanes expects the destination to be padded, so try to get padded span containing extra elements from the next row.
PixelOperations<TPixel>.Instance.PackFromRgbPlanes(r, g, b, destination); // If we can't get such a padded row because we are on a MemoryGroup boundary or at the last row,
// pack pixels to a temporary, padded proxy buffer, then copy the relevant values to the destination row.
if (this.pixelBuffer.DangerousTryGetPaddedRowSpan(yy, 3, out Span<TPixel> destRow))
{
PixelOperations<TPixel>.Instance.PackFromRgbPlanes(r, g, b, destRow);
}
else
{
Span<TPixel> proxyRow = this.paddedProxyPixelRow.GetSpan();
PixelOperations<TPixel>.Instance.PackFromRgbPlanes(r, g, b, proxyRow);
proxyRow[..width].CopyTo(this.pixelBuffer.DangerousGetRowSpan(yy));
}
} }
this.pixelRowCounter += this.pixelRowsPerStep; this.pixelRowCounter += this.pixelRowsPerStep;
@ -198,6 +214,7 @@ internal class SpectralConverter<TPixel> : SpectralConverter, IDisposable
pixelSize.Height, pixelSize.Height,
this.Configuration.PreferContiguousImageBuffers, this.Configuration.PreferContiguousImageBuffers,
AllocationOptions.Clean); AllocationOptions.Clean);
this.paddedProxyPixelRow = allocator.Allocate<TPixel>(pixelSize.Width + 3);
// Component processors from spectral to RGB // Component processors from spectral to RGB
int bufferWidth = majorBlockWidth * blockPixelSize; int bufferWidth = majorBlockWidth * blockPixelSize;
@ -258,6 +275,7 @@ internal class SpectralConverter<TPixel> : SpectralConverter, IDisposable
} }
this.rgbBuffer?.Dispose(); this.rgbBuffer?.Dispose();
this.paddedProxyPixelRow?.Dispose();
this.pixelBuffer?.Dispose(); this.pixelBuffer?.Dispose();
} }
} }

8
src/ImageSharp/Formats/Jpeg/JpegEncoderCore.cs

@ -90,13 +90,11 @@ internal sealed unsafe partial class JpegEncoderCore
this.WriteApp14Marker(frameConfig.AdobeColorTransformMarkerFlag.Value, buffer); this.WriteApp14Marker(frameConfig.AdobeColorTransformMarkerFlag.Value, buffer);
} }
if (!this.encoder.SkipMetadata) // Write Exif, XMP, ICC and IPTC profiles
{
// Profiles and comments are optional application metadata and must not leak into a containing format
// when the containing encoder has requested a metadata-free embedded JPEG payload.
this.WriteProfiles(metadata, buffer); this.WriteProfiles(metadata, buffer);
// Write comments
this.WriteComments(image.Configuration, jpegMetadata); this.WriteComments(image.Configuration, jpegMetadata);
}
// Write the image dimensions. // Write the image dimensions.
this.WriteStartOfFrame(image.Width, image.Height, frameConfig, buffer); this.WriteStartOfFrame(image.Width, image.Height, frameConfig, buffer);

2
src/ImageSharp/Formats/Png/PngEncoderCore.cs

@ -1057,7 +1057,7 @@ internal sealed class PngEncoderCore : IDisposable
/// <exception cref="NotSupportedException">CICP matrix coefficients other than Identity are not supported in PNG.</exception> /// <exception cref="NotSupportedException">CICP matrix coefficients other than Identity are not supported in PNG.</exception>
private void WriteCicpChunk(Stream stream, ImageMetadata metaData) private void WriteCicpChunk(Stream stream, ImageMetadata metaData)
{ {
if (this.chunkFilter == PngChunkFilter.ExcludeAll || metaData.CicpProfile is null) if (metaData.CicpProfile is null)
{ {
return; return;
} }

Loading…
Cancel
Save