diff --git a/src/ImageSharp/Formats/Jpeg/Components/Decoder/HuffmanScanDecoder.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/HuffmanScanDecoder.cs index bc9a53ea0..71f1689f5 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/Decoder/HuffmanScanDecoder.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/HuffmanScanDecoder.cs @@ -501,7 +501,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder { i += r; s = buffer.Receive(s); - Unsafe.Add(ref blockDataRef, ZigZag.ZigZagOrder[i++]) = (short)s; + Unsafe.Add(ref blockDataRef, ZigZag.TransposingOrder[i++]) = (short)s; } else { @@ -570,7 +570,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder if (s != 0) { s = buffer.Receive(s); - Unsafe.Add(ref blockDataRef, ZigZag.ZigZagOrder[i]) = (short)(s << low); + Unsafe.Add(ref blockDataRef, ZigZag.TransposingOrder[i]) = (short)(s << low); } else { @@ -646,7 +646,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder do { - ref short coef = ref Unsafe.Add(ref blockDataRef, ZigZag.ZigZagOrder[k]); + ref short coef = ref Unsafe.Add(ref blockDataRef, ZigZag.TransposingOrder[k]); if (coef != 0) { buffer.CheckBits(); @@ -672,7 +672,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder if ((s != 0) && (k < 64)) { - Unsafe.Add(ref blockDataRef, ZigZag.ZigZagOrder[k]) = (short)s; + Unsafe.Add(ref blockDataRef, ZigZag.TransposingOrder[k]) = (short)s; } } } @@ -681,7 +681,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder { for (; k <= end; k++) { - ref short coef = ref Unsafe.Add(ref blockDataRef, ZigZag.ZigZagOrder[k]); + ref short coef = ref Unsafe.Add(ref blockDataRef, ZigZag.TransposingOrder[k]); if (coef != 0) { diff --git a/src/ImageSharp/Formats/Jpeg/Components/ZigZag.cs b/src/ImageSharp/Formats/Jpeg/Components/ZigZag.cs index e519a8a1d..f52cb6c10 100644 --- a/src/ImageSharp/Formats/Jpeg/Components/ZigZag.cs +++ b/src/ImageSharp/Formats/Jpeg/Components/ZigZag.cs @@ -35,5 +35,21 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63 }; + + public static ReadOnlySpan TransposingOrder => new byte[] + { + 0, 8, 1, 2, 9, 16, 24, 17, + 10, 3, 4, 11, 18, 25, 32, 40, + 33, 26, 19, 12, 5, 6, 13, 20, + 27, 34, 41, 48, 56, 49, 42, 35, + 28, 21, 14, 7, 15, 22, 29, 36, + 43, 50, 57, 58, 51, 44, 37, 30, + 23, 31, 38, 45, 52, 59, 60, 53, + 46, 39, 47, 54, 61, 62, 55, 63, + + // Extra entries for safety in decoder + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63 + }; } } diff --git a/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs b/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs index 9a9e5eb79..73763f4ab 100644 --- a/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs +++ b/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs @@ -942,6 +942,9 @@ namespace SixLabors.ImageSharp.Formats.Jpeg break; } } + + // Adjusting table for IDCT step during decompression + FastFloatingPointDCT.AdjustToIDCT(ref table); } } diff --git a/tests/ImageSharp.Tests/Formats/Jpg/ZigZagTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/ZigZagTests.cs index 39046438a..b67ad85ee 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/ZigZagTests.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/ZigZagTests.cs @@ -1,6 +1,7 @@ // Copyright (c) Six Labors. // Licensed under the Apache License, Version 2.0. +using System; using SixLabors.ImageSharp.Formats.Jpeg.Components; using Xunit; @@ -9,8 +10,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg [Trait("Format", "Jpg")] public class ZigZagTests { - [Fact] - public void ZigZagCanHandleAllPossibleCoefficients() + private static void CanHandleAllPossibleCoefficients(ReadOnlySpan order) { // Mimic the behaviour of the huffman scan decoder using all possible byte values short[] block = new short[64]; @@ -26,7 +26,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg if (s != 0) { i += r; - block[ZigZag.ZigZagOrder[i++]] = (short)s; + block[order[i++]] = (short)s; } else { @@ -40,5 +40,13 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg } } } + + [Fact] + public static void ZigZagCanHandleAllPossibleCoefficients() => + CanHandleAllPossibleCoefficients(ZigZag.ZigZagOrder); + + [Fact] + public static void TrasposingZigZagCanHandleAllPossibleCoefficients() => + CanHandleAllPossibleCoefficients(ZigZag.TransposingOrder); } }