Skip to content

Commit 043ee2b

Browse files
Merge pull request #3105 from SixLabors/js/fix-3104
Fix JPEG SIMD slicing and padding length handling.
2 parents b10a7ed + e06a015 commit 043ee2b

File tree

2 files changed

+11
-9
lines changed

2 files changed

+11
-9
lines changed

src/ImageSharp/Common/Helpers/SimdUtils.HwIntrinsics.cs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -752,7 +752,7 @@ internal static void ByteToNormalizedFloatReduce(
752752
/// Implementation is based on MagicScaler code:
753753
/// https://github.com/saucecontrol/PhotoSauce/blob/b5811908041200488aa18fdfd17df5fc457415dc/src/MagicScaler/Magic/Processors/ConvertersFloat.cs#L80-L182
754754
/// </remarks>
755-
internal static unsafe void ByteToNormalizedFloat(
755+
internal static void ByteToNormalizedFloat(
756756
ReadOnlySpan<byte> source,
757757
Span<float> destination)
758758
{
@@ -1172,8 +1172,10 @@ internal static void UnpackToRgbPlanesAvx2Reduce(
11721172
Vector256<byte> rgb, rg, bx;
11731173
Vector256<float> r, g, b;
11741174

1175+
// Each iteration consumes 8 Rgb24 pixels (24 bytes) but starts with a 32-byte load,
1176+
// so we need 3 extra pixels of addressable slack beyond the vectorized chunk.
11751177
const int bytesPerRgbStride = 24;
1176-
nuint count = (uint)source.Length / 8;
1178+
nuint count = source.Length > 3 ? (uint)(source.Length - 3) / 8 : 0;
11771179
for (nuint i = 0; i < count; i++)
11781180
{
11791181
rgb = Avx2.PermuteVar8x32(Unsafe.AddByteOffset(ref rgbByteSpan, (uint)(bytesPerRgbStride * i)).AsUInt32(), extractToLanesMask).AsByte();
@@ -1193,10 +1195,10 @@ internal static void UnpackToRgbPlanesAvx2Reduce(
11931195
}
11941196

11951197
int sliceCount = (int)(count * 8);
1196-
redChannel = redChannel.Slice(sliceCount);
1197-
greenChannel = greenChannel.Slice(sliceCount);
1198-
blueChannel = blueChannel.Slice(sliceCount);
1199-
source = source.Slice(sliceCount);
1198+
redChannel = redChannel[sliceCount..];
1199+
greenChannel = greenChannel[sliceCount..];
1200+
blueChannel = blueChannel[sliceCount..];
1201+
source = source[sliceCount..];
12001202
}
12011203
}
12021204
}

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,9 +114,9 @@ private void ConvertStride(int spectralStep)
114114
Span<TPixel> sourceRow = this.pixelBuffer.DangerousGetRowSpan(srcIndex);
115115
PixelOperations<TPixel>.Instance.UnpackIntoRgbPlanes(rLane, gLane, bLane, sourceRow);
116116

117-
rLane.Slice(paddingStartIndex).Fill(rLane[paddingStartIndex - 1]);
118-
gLane.Slice(paddingStartIndex).Fill(gLane[paddingStartIndex - 1]);
119-
bLane.Slice(paddingStartIndex).Fill(bLane[paddingStartIndex - 1]);
117+
rLane.Slice(paddingStartIndex, paddedPixelsCount).Fill(rLane[paddingStartIndex - 1]);
118+
gLane.Slice(paddingStartIndex, paddedPixelsCount).Fill(gLane[paddingStartIndex - 1]);
119+
bLane.Slice(paddingStartIndex, paddedPixelsCount).Fill(bLane[paddingStartIndex - 1]);
120120

121121
// Convert from rgb24 to target pixel type
122122
JpegColorConverterBase.ComponentValues values = new(this.componentProcessors, y);

0 commit comments

Comments
 (0)