diff --git a/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsHuffmanTable.cs b/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsHuffmanTable.cs
index 80cf7d5498..c3faa9d1ee 100644
--- a/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsHuffmanTable.cs
+++ b/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsHuffmanTable.cs
@@ -10,6 +10,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components
///
/// Represents a Huffman Table
///
+ [StructLayout(LayoutKind.Sequential)]
internal unsafe struct PdfJsHuffmanTable
{
///
diff --git a/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsIDCT.cs b/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsIDCT.cs
index d07ddf846b..b0b4c0d713 100644
--- a/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsIDCT.cs
+++ b/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsIDCT.cs
@@ -1,7 +1,6 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
-using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using SixLabors.ImageSharp.Memory;
@@ -23,38 +22,6 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components
private const int DctSqrt1D2 = 2896; // sqrt(2) / 2
private const int MaxJSample = 255;
private const int CenterJSample = 128;
- private const int RangeCenter = (MaxJSample * 2) + 2;
-
- // First segment of range limit table: limit[x] = 0 for x < 0
- // allow negative subscripts of simple table
- private const int TableOffset = 2 * (MaxJSample + 1);
- private const int LimitOffset = TableOffset - (RangeCenter - CenterJSample);
-
- // Each IDCT routine is responsible for range-limiting its results and
- // converting them to unsigned form (0..MaxJSample). The raw outputs could
- // be quite far out of range if the input data is corrupt, so a bulletproof
- // range-limiting step is required. We use a mask-and-table-lookup method
- // to do the combined operations quickly, assuming that MaxJSample+1
- // is a power of 2.
- private const int RangeMask = (MaxJSample * 4) + 3; // 2 bits wider than legal samples
-
- private static readonly byte[] Limit = new byte[5 * (MaxJSample + 1)];
-
- static PdfJsIDCT()
- {
- // Main part of range limit table: limit[x] = x
- int i;
- for (i = 0; i <= MaxJSample; i++)
- {
- Limit[TableOffset + i] = (byte)i;
- }
-
- // End of range limit table: Limit[x] = MaxJSample for x > MaxJSample
- for (; i < 3 * (MaxJSample + 1); i++)
- {
- Limit[TableOffset + i] = MaxJSample;
- }
- }
///
/// A port of Poppler's IDCT method which in turn is taken from:
@@ -64,9 +31,9 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components
///
/// The frame component
/// The block buffer offset
- /// The computational buffer for holding temp values
- /// The quantization table
- public static void QuantizeAndInverse(PdfJsFrameComponent component, int blockBufferOffset, ref short computationBuffer, ref short quantizationTable)
+ /// The computational buffer for holding temp values ref
+ /// The quantization table ref
+ public static void QuantizeAndInverse(PdfJsFrameComponent component, int blockBufferOffset, ref short computationBufferRef, ref short quantizationTableRef)
{
ref short blockDataRef = ref MemoryMarshal.GetReference(component.BlockData.Slice(blockBufferOffset));
int v0, v1, v2, v3, v4, v5, v6, v7;
@@ -87,48 +54,48 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components
p7 = Unsafe.Add(ref blockDataRef, row + 7);
// dequant p0
- p0 *= Unsafe.Add(ref quantizationTable, row);
+ p0 *= Unsafe.Add(ref quantizationTableRef, row);
// check for all-zero AC coefficients
if ((p1 | p2 | p3 | p4 | p5 | p6 | p7) == 0)
{
t = ((DctSqrt2 * p0) + 512) >> 10;
short st = (short)t;
- Unsafe.Add(ref computationBuffer, row) = st;
- Unsafe.Add(ref computationBuffer, row + 1) = st;
- Unsafe.Add(ref computationBuffer, row + 2) = st;
- Unsafe.Add(ref computationBuffer, row + 3) = st;
- Unsafe.Add(ref computationBuffer, row + 4) = st;
- Unsafe.Add(ref computationBuffer, row + 5) = st;
- Unsafe.Add(ref computationBuffer, row + 6) = st;
- Unsafe.Add(ref computationBuffer, row + 7) = st;
+ Unsafe.Add(ref computationBufferRef, row) = st;
+ Unsafe.Add(ref computationBufferRef, row + 1) = st;
+ Unsafe.Add(ref computationBufferRef, row + 2) = st;
+ Unsafe.Add(ref computationBufferRef, row + 3) = st;
+ Unsafe.Add(ref computationBufferRef, row + 4) = st;
+ Unsafe.Add(ref computationBufferRef, row + 5) = st;
+ Unsafe.Add(ref computationBufferRef, row + 6) = st;
+ Unsafe.Add(ref computationBufferRef, row + 7) = st;
continue;
}
// dequant p1 ... p7
- p1 *= Unsafe.Add(ref quantizationTable, row + 1);
- p2 *= Unsafe.Add(ref quantizationTable, row + 2);
- p3 *= Unsafe.Add(ref quantizationTable, row + 3);
- p4 *= Unsafe.Add(ref quantizationTable, row + 4);
- p5 *= Unsafe.Add(ref quantizationTable, row + 5);
- p6 *= Unsafe.Add(ref quantizationTable, row + 6);
- p7 *= Unsafe.Add(ref quantizationTable, row + 7);
+ p1 *= Unsafe.Add(ref quantizationTableRef, row + 1);
+ p2 *= Unsafe.Add(ref quantizationTableRef, row + 2);
+ p3 *= Unsafe.Add(ref quantizationTableRef, row + 3);
+ p4 *= Unsafe.Add(ref quantizationTableRef, row + 4);
+ p5 *= Unsafe.Add(ref quantizationTableRef, row + 5);
+ p6 *= Unsafe.Add(ref quantizationTableRef, row + 6);
+ p7 *= Unsafe.Add(ref quantizationTableRef, row + 7);
// stage 4
- v0 = ((DctSqrt2 * p0) + 128) >> 8;
- v1 = ((DctSqrt2 * p4) + 128) >> 8;
+ v0 = ((DctSqrt2 * p0) + CenterJSample) >> 8;
+ v1 = ((DctSqrt2 * p4) + CenterJSample) >> 8;
v2 = p2;
v3 = p6;
- v4 = ((DctSqrt1D2 * (p1 - p7)) + 128) >> 8;
- v7 = ((DctSqrt1D2 * (p1 + p7)) + 128) >> 8;
+ v4 = ((DctSqrt1D2 * (p1 - p7)) + CenterJSample) >> 8;
+ v7 = ((DctSqrt1D2 * (p1 + p7)) + CenterJSample) >> 8;
v5 = p3 << 4;
v6 = p5 << 4;
// stage 3
v0 = (v0 + v1 + 1) >> 1;
v1 = v0 - v1;
- t = ((v2 * DctSin6) + (v3 * DctCos6) + 128) >> 8;
- v2 = ((v2 * DctCos6) - (v3 * DctSin6) + 128) >> 8;
+ t = ((v2 * DctSin6) + (v3 * DctCos6) + CenterJSample) >> 8;
+ v2 = ((v2 * DctCos6) - (v3 * DctSin6) + CenterJSample) >> 8;
v3 = t;
v4 = (v4 + v6 + 1) >> 1;
v6 = v4 - v6;
@@ -148,27 +115,27 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components
v6 = t;
// stage 1
- Unsafe.Add(ref computationBuffer, row) = (short)(v0 + v7);
- Unsafe.Add(ref computationBuffer, row + 7) = (short)(v0 - v7);
- Unsafe.Add(ref computationBuffer, row + 1) = (short)(v1 + v6);
- Unsafe.Add(ref computationBuffer, row + 6) = (short)(v1 - v6);
- Unsafe.Add(ref computationBuffer, row + 2) = (short)(v2 + v5);
- Unsafe.Add(ref computationBuffer, row + 5) = (short)(v2 - v5);
- Unsafe.Add(ref computationBuffer, row + 3) = (short)(v3 + v4);
- Unsafe.Add(ref computationBuffer, row + 4) = (short)(v3 - v4);
+ Unsafe.Add(ref computationBufferRef, row) = (short)(v0 + v7);
+ Unsafe.Add(ref computationBufferRef, row + 7) = (short)(v0 - v7);
+ Unsafe.Add(ref computationBufferRef, row + 1) = (short)(v1 + v6);
+ Unsafe.Add(ref computationBufferRef, row + 6) = (short)(v1 - v6);
+ Unsafe.Add(ref computationBufferRef, row + 2) = (short)(v2 + v5);
+ Unsafe.Add(ref computationBufferRef, row + 5) = (short)(v2 - v5);
+ Unsafe.Add(ref computationBufferRef, row + 3) = (short)(v3 + v4);
+ Unsafe.Add(ref computationBufferRef, row + 4) = (short)(v3 - v4);
}
// inverse DCT on columns
for (int col = 0; col < 8; ++col)
{
- p0 = Unsafe.Add(ref computationBuffer, col);
- p1 = Unsafe.Add(ref computationBuffer, col + 8);
- p2 = Unsafe.Add(ref computationBuffer, col + 16);
- p3 = Unsafe.Add(ref computationBuffer, col + 24);
- p4 = Unsafe.Add(ref computationBuffer, col + 32);
- p5 = Unsafe.Add(ref computationBuffer, col + 40);
- p6 = Unsafe.Add(ref computationBuffer, col + 48);
- p7 = Unsafe.Add(ref computationBuffer, col + 56);
+ p0 = Unsafe.Add(ref computationBufferRef, col);
+ p1 = Unsafe.Add(ref computationBufferRef, col + 8);
+ p2 = Unsafe.Add(ref computationBufferRef, col + 16);
+ p3 = Unsafe.Add(ref computationBufferRef, col + 24);
+ p4 = Unsafe.Add(ref computationBufferRef, col + 32);
+ p5 = Unsafe.Add(ref computationBufferRef, col + 40);
+ p6 = Unsafe.Add(ref computationBufferRef, col + 48);
+ p7 = Unsafe.Add(ref computationBufferRef, col + 56);
// check for all-zero AC coefficients
if ((p1 | p2 | p3 | p4 | p5 | p6 | p7) == 0)
diff --git a/src/ImageSharp/Formats/Jpeg/PdfJsPort/PdfJsJpegDecoderCore.cs b/src/ImageSharp/Formats/Jpeg/PdfJsPort/PdfJsJpegDecoderCore.cs
index c1e89dc0e5..9572b7b0e3 100644
--- a/src/ImageSharp/Formats/Jpeg/PdfJsPort/PdfJsJpegDecoderCore.cs
+++ b/src/ImageSharp/Formats/Jpeg/PdfJsPort/PdfJsJpegDecoderCore.cs
@@ -358,12 +358,6 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort
this.acHuffmanTables = null;
}
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- private static int GetBlockBufferOffset(ref PdfJsComponent component, int row, int col)
- {
- return 64 * (((component.BlocksPerLine + 1) * row) + col);
- }
-
internal void QuantizeAndInverseAllComponents()
{
for (int i = 0; i < this.components.Components.Length; i++)
@@ -692,8 +686,9 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort
for (int i = 0; i < this.Frame.Components.Length; i++)
{
- int h = this.temp[index + 1] >> 4;
- int v = this.temp[index + 1] & 15;
+ byte hv = this.temp[index + 1];
+ int h = hv >> 4;
+ int v = hv & 15;
if (maxH < h)
{
@@ -852,7 +847,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort
{
for (int blockCol = 0; blockCol < blocksPerLine; blockCol++)
{
- int offset = GetBlockBufferOffset(ref component, blockRow, blockCol);
+ int offset = 64 * (((blocksPerLine + 1) * blockRow) + blockCol);
PdfJsIDCT.QuantizeAndInverse(frameComponent, offset, ref computationBufferSpan, ref quantizationTableRef);
}
}