Skip to content

Commit 316a839

Browse files
committed
Optimize code
1 parent 1464064 commit 316a839

2 files changed

Lines changed: 38 additions & 125 deletions

File tree

src/ImageSharp/Formats/Png/PngDecoderCore.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -671,7 +671,7 @@ private int CalculateScanlineLength(int width)
671671
/// <param name="getData">A delegate to get more data from the inner stream for <see cref="ZlibInflateStream"/>.</param>
672672
/// <param name="frameControl">The frame control</param>
673673
/// <param name="cancellationToken">The cancellation token.</param>
674-
private void ReadScanlines<TPixel>(int chunkLength, ImageFrame<TPixel> image, PngMetadata pngMetadata, Func<int> getData, FrameControl frameControl, CancellationToken cancellationToken)
674+
private void ReadScanlines<TPixel>(int chunkLength, ImageFrame<TPixel> image, PngMetadata pngMetadata, Func<int> getData, in FrameControl frameControl, CancellationToken cancellationToken)
675675
where TPixel : unmanaged, IPixel<TPixel>
676676
{
677677
using ZlibInflateStream deframeStream = new(this.currentStream, getData);
@@ -763,7 +763,7 @@ private void DecodePixelData<TPixel>(FrameControl frameControl, DeflateStream co
763763
/// <param name="image">The current image.</param>
764764
/// <param name="pngMetadata">The png metadata.</param>
765765
/// <param name="cancellationToken">The cancellation token.</param>
766-
private void DecodeInterlacedPixelData<TPixel>(FrameControl frameControl, DeflateStream compressedStream, ImageFrame<TPixel> image, PngMetadata pngMetadata, CancellationToken cancellationToken)
766+
private void DecodeInterlacedPixelData<TPixel>(in FrameControl frameControl, DeflateStream compressedStream, ImageFrame<TPixel> image, PngMetadata pngMetadata, CancellationToken cancellationToken)
767767
where TPixel : unmanaged, IPixel<TPixel>
768768
{
769769
int currentRow = Adam7.FirstRow[0] + frameControl.YOffset;
@@ -864,7 +864,7 @@ private void DecodeInterlacedPixelData<TPixel>(FrameControl frameControl, Deflat
864864
/// <param name="defilteredScanline">The de-filtered scanline</param>
865865
/// <param name="pixels">The image</param>
866866
/// <param name="pngMetadata">The png metadata.</param>
867-
private void ProcessDefilteredScanline<TPixel>(FrameControl frameControl, int currentRow, ReadOnlySpan<byte> defilteredScanline, ImageFrame<TPixel> pixels, PngMetadata pngMetadata)
867+
private void ProcessDefilteredScanline<TPixel>(in FrameControl frameControl, int currentRow, ReadOnlySpan<byte> defilteredScanline, ImageFrame<TPixel> pixels, PngMetadata pngMetadata)
868868
where TPixel : unmanaged, IPixel<TPixel>
869869
{
870870
Span<TPixel> rowSpan = pixels.PixelBuffer.DangerousGetRowSpan(currentRow);
@@ -961,7 +961,7 @@ private void ProcessDefilteredScanline<TPixel>(FrameControl frameControl, int cu
961961
/// <param name="pngMetadata">The png metadata.</param>
962962
/// <param name="pixelOffset">The column start index. Always 0 for none interlaced images.</param>
963963
/// <param name="increment">The column increment. Always 1 for none interlaced images.</param>
964-
private void ProcessInterlacedDefilteredScanline<TPixel>(FrameControl frameControl, ReadOnlySpan<byte> defilteredScanline, Span<TPixel> rowSpan, PngMetadata pngMetadata, int pixelOffset = 0, int increment = 1)
964+
private void ProcessInterlacedDefilteredScanline<TPixel>(in FrameControl frameControl, ReadOnlySpan<byte> defilteredScanline, Span<TPixel> rowSpan, PngMetadata pngMetadata, int pixelOffset = 0, int increment = 1)
965965
where TPixel : unmanaged, IPixel<TPixel>
966966
{
967967
// Trim the first marker byte from the buffer

src/ImageSharp/Formats/Png/PngScanlineProcessor.cs

Lines changed: 34 additions & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ internal static class PngScanlineProcessor
1717
{
1818
public static void ProcessGrayscaleScanline<TPixel>(
1919
int bitDepth,
20-
FrameControl frameControl,
20+
in FrameControl frameControl,
2121
ReadOnlySpan<byte> scanlineSpan,
2222
Span<TPixel> rowSpan,
2323
bool hasTrans,
@@ -37,7 +37,7 @@ public static void ProcessGrayscaleScanline<TPixel>(
3737

3838
public static void ProcessInterlacedGrayscaleScanline<TPixel>(
3939
int bitDepth,
40-
FrameControl frameControl,
40+
in FrameControl frameControl,
4141
ReadOnlySpan<byte> scanlineSpan,
4242
Span<TPixel> rowSpan,
4343
uint pixelOffset,
@@ -110,7 +110,7 @@ public static void ProcessInterlacedGrayscaleScanline<TPixel>(
110110

111111
public static void ProcessGrayscaleWithAlphaScanline<TPixel>(
112112
int bitDepth,
113-
FrameControl frameControl,
113+
in FrameControl frameControl,
114114
ReadOnlySpan<byte> scanlineSpan,
115115
Span<TPixel> rowSpan,
116116
uint bytesPerPixel,
@@ -128,7 +128,7 @@ public static void ProcessGrayscaleWithAlphaScanline<TPixel>(
128128

129129
public static void ProcessInterlacedGrayscaleWithAlphaScanline<TPixel>(
130130
int bitDepth,
131-
FrameControl frameControl,
131+
in FrameControl frameControl,
132132
ReadOnlySpan<byte> scanlineSpan,
133133
Span<TPixel> rowSpan,
134134
uint pixelOffset,
@@ -172,7 +172,7 @@ public static void ProcessInterlacedGrayscaleWithAlphaScanline<TPixel>(
172172
}
173173

174174
public static void ProcessPaletteScanline<TPixel>(
175-
FrameControl frameControl,
175+
in FrameControl frameControl,
176176
ReadOnlySpan<byte> scanlineSpan,
177177
Span<TPixel> rowSpan,
178178
ReadOnlySpan<byte> palette,
@@ -188,7 +188,7 @@ public static void ProcessPaletteScanline<TPixel>(
188188
paletteAlpha);
189189

190190
public static void ProcessInterlacedPaletteScanline<TPixel>(
191-
FrameControl frameControl,
191+
in FrameControl frameControl,
192192
ReadOnlySpan<byte> scanlineSpan,
193193
Span<TPixel> rowSpan,
194194
uint pixelOffset,
@@ -240,92 +240,31 @@ public static void ProcessInterlacedPaletteScanline<TPixel>(
240240

241241
public static void ProcessRgbScanline<TPixel>(
242242
int bitDepth,
243-
FrameControl frameControl,
243+
in FrameControl frameControl,
244244
ReadOnlySpan<byte> scanlineSpan,
245245
Span<TPixel> rowSpan,
246246
int bytesPerPixel,
247247
int bytesPerSample,
248248
bool hasTrans,
249249
Rgb48 rgb48Trans,
250250
Rgb24 rgb24Trans)
251-
where TPixel : unmanaged, IPixel<TPixel>
252-
{
253-
uint offset = (uint)frameControl.XOffset;
254-
TPixel pixel = default;
255-
ref TPixel rowSpanRef = ref MemoryMarshal.GetReference(rowSpan);
256-
257-
if (bitDepth == 16)
258-
{
259-
if (!hasTrans)
260-
{
261-
Rgb48 rgb48 = default;
262-
int o = 0;
263-
for (nuint x = offset; x < frameControl.XLimit; x++, o += bytesPerPixel)
264-
{
265-
rgb48.R = BinaryPrimitives.ReadUInt16BigEndian(scanlineSpan.Slice(o, bytesPerSample));
266-
rgb48.G = BinaryPrimitives.ReadUInt16BigEndian(scanlineSpan.Slice(o + bytesPerSample, bytesPerSample));
267-
rgb48.B = BinaryPrimitives.ReadUInt16BigEndian(scanlineSpan.Slice(o + (2 * bytesPerSample), bytesPerSample));
268-
269-
pixel.FromRgb48(rgb48);
270-
Unsafe.Add(ref rowSpanRef, x) = pixel;
271-
}
272-
}
273-
else
274-
{
275-
Rgb48 rgb48 = default;
276-
Rgba64 rgba64 = default;
277-
int o = 0;
278-
for (nuint x = offset; x < frameControl.XLimit; x++, o += bytesPerPixel)
279-
{
280-
rgb48.R = BinaryPrimitives.ReadUInt16BigEndian(scanlineSpan.Slice(o, bytesPerSample));
281-
rgb48.G = BinaryPrimitives.ReadUInt16BigEndian(scanlineSpan.Slice(o + bytesPerSample, bytesPerSample));
282-
rgb48.B = BinaryPrimitives.ReadUInt16BigEndian(scanlineSpan.Slice(o + (2 * bytesPerSample), bytesPerSample));
283-
284-
rgba64.Rgb = rgb48;
285-
rgba64.A = rgb48.Equals(rgb48Trans) ? ushort.MinValue : ushort.MaxValue;
286-
287-
pixel.FromRgba64(rgba64);
288-
Unsafe.Add(ref rowSpanRef, x) = pixel;
289-
}
290-
}
291-
292-
return;
293-
}
294-
295-
if (hasTrans)
296-
{
297-
Rgba32 rgba32 = default;
298-
ReadOnlySpan<Rgb24> rgb24Span = MemoryMarshal.Cast<byte, Rgb24>(scanlineSpan);
299-
ref Rgb24 rgb24SpanRef = ref MemoryMarshal.GetReference(rgb24Span);
300-
for (nuint x = offset; x < frameControl.XLimit; x++)
301-
{
302-
ref readonly Rgb24 rgb24 = ref Unsafe.Add(ref rgb24SpanRef, x);
303-
rgba32.Rgb = rgb24;
304-
rgba32.A = rgb24.Equals(rgb24Trans) ? byte.MinValue : byte.MaxValue;
305-
306-
pixel.FromRgba32(rgba32);
307-
Unsafe.Add(ref rowSpanRef, x) = pixel;
308-
}
309-
}
310-
else
311-
{
312-
ReadOnlySpan<Rgb24> source = MemoryMarshal.Cast<byte, Rgb24>(scanlineSpan)[..frameControl.Width];
313-
ref Rgb24 sourceBaseRef = ref MemoryMarshal.GetReference(source);
314-
ref TPixel destBaseRef = ref MemoryMarshal.GetReference(rowSpan);
315-
316-
for (nuint i = offset; i < frameControl.XLimit; i++)
317-
{
318-
ref Rgb24 sp = ref Unsafe.Add(ref sourceBaseRef, i);
319-
ref TPixel dp = ref Unsafe.Add(ref destBaseRef, i);
320-
321-
dp.FromRgb24(sp);
322-
}
323-
}
324-
}
251+
where TPixel : unmanaged, IPixel<TPixel> =>
252+
ProcessInterlacedRgbScanline(
253+
bitDepth,
254+
frameControl,
255+
scanlineSpan,
256+
rowSpan,
257+
0,
258+
1,
259+
bytesPerPixel,
260+
bytesPerSample,
261+
hasTrans,
262+
rgb48Trans,
263+
rgb24Trans);
325264

326265
public static void ProcessInterlacedRgbScanline<TPixel>(
327266
int bitDepth,
328-
FrameControl frameControl,
267+
in FrameControl frameControl,
329268
ReadOnlySpan<byte> scanlineSpan,
330269
Span<TPixel> rowSpan,
331270
uint pixelOffset,
@@ -413,51 +352,25 @@ public static void ProcessInterlacedRgbScanline<TPixel>(
413352

414353
public static void ProcessRgbaScanline<TPixel>(
415354
int bitDepth,
416-
FrameControl frameControl,
355+
in FrameControl frameControl,
417356
ReadOnlySpan<byte> scanlineSpan,
418357
Span<TPixel> rowSpan,
419358
int bytesPerPixel,
420359
int bytesPerSample)
421-
where TPixel : unmanaged, IPixel<TPixel>
422-
{
423-
uint offset = (uint)frameControl.XOffset;
424-
TPixel pixel = default;
425-
ref TPixel rowSpanRef = ref MemoryMarshal.GetReference(rowSpan);
426-
427-
if (bitDepth == 16)
428-
{
429-
Rgba64 rgba64 = default;
430-
int o = 0;
431-
for (nuint x = offset; x < frameControl.XLimit; x++, o += bytesPerPixel)
432-
{
433-
rgba64.R = BinaryPrimitives.ReadUInt16BigEndian(scanlineSpan.Slice(o, bytesPerSample));
434-
rgba64.G = BinaryPrimitives.ReadUInt16BigEndian(scanlineSpan.Slice(o + bytesPerSample, bytesPerSample));
435-
rgba64.B = BinaryPrimitives.ReadUInt16BigEndian(scanlineSpan.Slice(o + (2 * bytesPerSample), bytesPerSample));
436-
rgba64.A = BinaryPrimitives.ReadUInt16BigEndian(scanlineSpan.Slice(o + (3 * bytesPerSample), bytesPerSample));
437-
438-
pixel.FromRgba64(rgba64);
439-
Unsafe.Add(ref rowSpanRef, x) = pixel;
440-
}
441-
}
442-
else
443-
{
444-
ReadOnlySpan<Rgba32> source = MemoryMarshal.Cast<byte, Rgba32>(scanlineSpan)[..frameControl.Width];
445-
ref Rgba32 sourceBaseRef = ref MemoryMarshal.GetReference(source);
446-
ref TPixel destBaseRef = ref MemoryMarshal.GetReference(rowSpan);
447-
448-
for (nuint i = offset; i < frameControl.XLimit; i++)
449-
{
450-
ref Rgba32 sp = ref Unsafe.Add(ref sourceBaseRef, i);
451-
ref TPixel dp = ref Unsafe.Add(ref destBaseRef, i);
452-
453-
dp.FromRgba32(sp);
454-
}
455-
}
456-
}
360+
where TPixel : unmanaged, IPixel<TPixel> =>
361+
ProcessInterlacedRgbaScanline(
362+
bitDepth,
363+
frameControl,
364+
scanlineSpan,
365+
rowSpan,
366+
0,
367+
1,
368+
bytesPerPixel,
369+
bytesPerSample);
457370

458371
public static void ProcessInterlacedRgbaScanline<TPixel>(
459372
int bitDepth,
460-
FrameControl frameControl,
373+
in FrameControl frameControl,
461374
ReadOnlySpan<byte> scanlineSpan,
462375
Span<TPixel> rowSpan,
463376
uint pixelOffset,
@@ -468,7 +381,6 @@ public static void ProcessInterlacedRgbaScanline<TPixel>(
468381
{
469382
uint offset = pixelOffset + (uint)frameControl.XOffset;
470383
TPixel pixel = default;
471-
ref byte scanlineSpanRef = ref MemoryMarshal.GetReference(scanlineSpan);
472384
ref TPixel rowSpanRef = ref MemoryMarshal.GetReference(rowSpan);
473385

474386
if (bitDepth == 16)
@@ -488,6 +400,7 @@ public static void ProcessInterlacedRgbaScanline<TPixel>(
488400
}
489401
else
490402
{
403+
ref byte scanlineSpanRef = ref MemoryMarshal.GetReference(scanlineSpan);
491404
Rgba32 rgba = default;
492405
int o = 0;
493406
for (nuint x = offset; x < frameControl.XLimit; x += increment, o += bytesPerPixel)

0 commit comments

Comments
 (0)