diff --git a/src/ImageSharp/Formats/Jpg/Components/Bits.cs b/src/ImageSharp/Formats/Jpg/Components/Bits.cs
index 975c92aee..b273b2702 100644
--- a/src/ImageSharp/Formats/Jpg/Components/Bits.cs
+++ b/src/ImageSharp/Formats/Jpg/Components/Bits.cs
@@ -44,7 +44,7 @@ namespace ImageSharp.Formats
{
JpegDecoderCore.ErrorCodes errorCode;
- byte c = decoder.bytes.ReadByteStuffedByte(decoder.inputStream, out errorCode);
+ byte c = decoder.Bytes.ReadByteStuffedByte(decoder.InputStream, out errorCode);
if (errorCode != JpegDecoderCore.ErrorCodes.NoError)
{
diff --git a/src/ImageSharp/Formats/Jpg/Components/Block8x8F.cs b/src/ImageSharp/Formats/Jpg/Components/Block8x8F.cs
index a3f62fcef..c27de4ca9 100644
--- a/src/ImageSharp/Formats/Jpg/Components/Block8x8F.cs
+++ b/src/ImageSharp/Formats/Jpg/Components/Block8x8F.cs
@@ -15,6 +15,9 @@ namespace ImageSharp.Formats
///
internal partial struct Block8x8F
{
+ public const int VectorCount = 16;
+ public const int ScalarCount = VectorCount * 4;
+
public Vector4 V0L;
public Vector4 V0R;
@@ -39,18 +42,43 @@ namespace ImageSharp.Formats
public Vector4 V7L;
public Vector4 V7R;
- public const int VectorCount = 16;
- public const int ScalarCount = VectorCount * 4;
+#pragma warning disable SA1310 // FieldNamesMustNotContainUnderscore
+ private static readonly Vector4 C_1_175876 = new Vector4(1.175876f);
+ private static readonly Vector4 C_1_961571 = new Vector4(-1.961571f);
+ private static readonly Vector4 C_0_390181 = new Vector4(-0.390181f);
+ private static readonly Vector4 C_0_899976 = new Vector4(-0.899976f);
+ private static readonly Vector4 C_2_562915 = new Vector4(-2.562915f);
+ private static readonly Vector4 C_0_298631 = new Vector4(0.298631f);
+ private static readonly Vector4 C_2_053120 = new Vector4(2.053120f);
+ private static readonly Vector4 C_3_072711 = new Vector4(3.072711f);
+ private static readonly Vector4 C_1_501321 = new Vector4(1.501321f);
+ private static readonly Vector4 C_0_541196 = new Vector4(0.541196f);
+ private static readonly Vector4 C_1_847759 = new Vector4(-1.847759f);
+ private static readonly Vector4 C_0_765367 = new Vector4(0.765367f);
+
+ private static readonly Vector4 C_0_125 = new Vector4(0.1250f);
+#pragma warning restore SA1310 // FieldNamesMustNotContainUnderscore
- ///
- /// Load raw 32bit floating point data from source
- ///
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public unsafe void LoadFrom(MutableSpan source)
+ public unsafe float this[int idx]
{
- fixed (void* ptr = &this.V0L)
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ get
{
- Marshal.Copy(source.Data, source.Offset, (IntPtr)ptr, ScalarCount);
+ fixed (Block8x8F* p = &this)
+ {
+ float* fp = (float*)p;
+ return fp[idx];
+ }
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ set
+ {
+ fixed (Block8x8F* p = &this)
+ {
+ float* fp = (float*)p;
+ fp[idx] = value;
+ }
}
}
@@ -64,29 +92,23 @@ namespace ImageSharp.Formats
}
///
- /// Load raw 32bit floating point data from source
+ /// Copy raw 32bit floating point data to dest
///
- internal unsafe void LoadFrom(MutableSpan source)
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static unsafe void CopyTo(Block8x8F* blockPtr, MutableSpan dest)
{
- fixed (Vector4* ptr = &this.V0L)
- {
- float* fp = (float*)ptr;
- for (int i = 0; i < ScalarCount; i++)
- {
- fp[i] = source[i];
- }
- }
+ Marshal.Copy((IntPtr)blockPtr, dest.Data, dest.Offset, ScalarCount);
}
///
- /// Copy raw 32bit floating point data to dest
+ /// Load raw 32bit floating point data from source
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public unsafe void CopyTo(MutableSpan dest)
+ public unsafe void LoadFrom(MutableSpan source)
{
fixed (void* ptr = &this.V0L)
{
- Marshal.Copy((IntPtr)ptr, dest.Data, dest.Offset, ScalarCount);
+ Marshal.Copy(source.Data, source.Offset, (IntPtr)ptr, ScalarCount);
}
}
@@ -94,11 +116,11 @@ namespace ImageSharp.Formats
/// Copy raw 32bit floating point data to dest
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public unsafe void CopyTo(float[] dest)
+ public unsafe void CopyTo(MutableSpan dest)
{
fixed (void* ptr = &this.V0L)
{
- Marshal.Copy((IntPtr)ptr, dest, 0, ScalarCount);
+ Marshal.Copy((IntPtr)ptr, dest.Data, dest.Offset, ScalarCount);
}
}
@@ -106,23 +128,11 @@ namespace ImageSharp.Formats
/// Copy raw 32bit floating point data to dest
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static unsafe void CopyTo(Block8x8F* blockPtr, MutableSpan dest)
- {
- Marshal.Copy((IntPtr)blockPtr, dest.Data, dest.Offset, ScalarCount);
- }
-
- ///
- /// Copy raw 32bit floating point data to dest
- ///
- internal unsafe void CopyTo(MutableSpan dest)
+ public unsafe void CopyTo(float[] dest)
{
- fixed (Vector4* ptr = &this.V0L)
+ fixed (void* ptr = &this.V0L)
{
- float* fp = (float*)ptr;
- for (int i = 0; i < ScalarCount; i++)
- {
- dest[i] = (int)fp[i];
- }
+ Marshal.Copy((IntPtr)ptr, dest, 0, ScalarCount);
}
}
@@ -163,23 +173,72 @@ namespace ImageSharp.Formats
temp.IDCT8x4_LeftPart(ref dest);
temp.IDCT8x4_RightPart(ref dest);
- dest.MultiplyAllInplace(c_0_125);
+ dest.MultiplyAllInplace(C_0_125);
+ }
+
+ ///
+ /// Pointer-based "Indexer" (getter part)
+ ///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ internal static unsafe float GetScalarAt(Block8x8F* blockPtr, int idx)
+ {
+ float* fp = (float*)blockPtr;
+ return fp[idx];
+ }
+
+ ///
+ /// Pointer-based "Indexer" (setter part)
+ ///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ internal static unsafe void SetScalarAt(Block8x8F* blockPtr, int idx, float value)
+ {
+ float* fp = (float*)blockPtr;
+ fp[idx] = value;
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ internal static unsafe void UnZig(Block8x8F* block, Block8x8F* qt, int* unzigPtr)
+ {
+ float* b = (float*)block;
+ float* qtp = (float*)qt;
+ for (int zig = 0; zig < BlockF.BlockSize; zig++)
+ {
+ float* unzigPos = b + unzigPtr[zig];
+ float val = *unzigPos;
+ val *= qtp[zig];
+ *unzigPos = val;
+ }
+ }
+
+ ///
+ /// Copy raw 32bit floating point data to dest
+ ///
+ internal unsafe void CopyTo(MutableSpan dest)
+ {
+ fixed (Vector4* ptr = &this.V0L)
+ {
+ float* fp = (float*)ptr;
+ for (int i = 0; i < ScalarCount; i++)
+ {
+ dest[i] = (int)fp[i];
+ }
+ }
}
- private static readonly Vector4 c_1_175876 = new Vector4(1.175876f);
- private static readonly Vector4 c_1_961571 = new Vector4(-1.961571f);
- private static readonly Vector4 c_0_390181 = new Vector4(-0.390181f);
- private static readonly Vector4 c_0_899976 = new Vector4(-0.899976f);
- private static readonly Vector4 c_2_562915 = new Vector4(-2.562915f);
- private static readonly Vector4 c_0_298631 = new Vector4(0.298631f);
- private static readonly Vector4 c_2_053120 = new Vector4(2.053120f);
- private static readonly Vector4 c_3_072711 = new Vector4(3.072711f);
- private static readonly Vector4 c_1_501321 = new Vector4(1.501321f);
- private static readonly Vector4 c_0_541196 = new Vector4(0.541196f);
- private static readonly Vector4 c_1_847759 = new Vector4(-1.847759f);
- private static readonly Vector4 c_0_765367 = new Vector4(0.765367f);
-
- private static readonly Vector4 c_0_125 = new Vector4(0.1250f);
+ ///
+ /// Load raw 32bit floating point data from source
+ ///
+ internal unsafe void LoadFrom(MutableSpan source)
+ {
+ fixed (Vector4* ptr = &this.V0L)
+ {
+ float* fp = (float*)ptr;
+ for (int i = 0; i < ScalarCount; i++)
+ {
+ fp[i] = source[i];
+ }
+ }
+ }
///
/// Do IDCT internal operations on the left part of the block. Original source:
@@ -199,28 +258,28 @@ namespace ImageSharp.Formats
Vector4 mz1 = my3 + my5;
Vector4 mz3 = my1 + my5;
- Vector4 mz4 = ((mz0 + mz1) * c_1_175876);
+ Vector4 mz4 = (mz0 + mz1) * C_1_175876;
- mz2 = (mz2 * c_1_961571) + mz4;
- mz3 = (mz3 * c_0_390181) + mz4;
- mz0 = mz0 * c_0_899976;
- mz1 = mz1 * c_2_562915;
+ mz2 = (mz2 * C_1_961571) + mz4;
+ mz3 = (mz3 * C_0_390181) + mz4;
+ mz0 = mz0 * C_0_899976;
+ mz1 = mz1 * C_2_562915;
- Vector4 mb3 = (my7 * c_0_298631) + mz0 + mz2;
- Vector4 mb2 = (my5 * c_2_053120) + mz1 + mz3;
- Vector4 mb1 = (my3 * c_3_072711) + mz1 + mz2;
- Vector4 mb0 = (my1 * c_1_501321) + mz0 + mz3;
+ Vector4 mb3 = (my7 * C_0_298631) + mz0 + mz2;
+ Vector4 mb2 = (my5 * C_2_053120) + mz1 + mz3;
+ Vector4 mb1 = (my3 * C_3_072711) + mz1 + mz2;
+ Vector4 mb0 = (my1 * C_1_501321) + mz0 + mz3;
Vector4 my2 = this.V2L;
Vector4 my6 = this.V6L;
- mz4 = (my2 + my6) * c_0_541196;
+ mz4 = (my2 + my6) * C_0_541196;
Vector4 my0 = this.V0L;
Vector4 my4 = this.V4L;
mz0 = my0 + my4;
mz1 = my0 - my4;
- mz2 = mz4 + (my6 * c_1_847759);
- mz3 = mz4 + (my2 * c_0_765367);
+ mz2 = mz4 + (my6 * C_1_847759);
+ mz3 = mz4 + (my2 * C_0_765367);
my0 = mz0 + mz3;
my3 = mz0 - mz3;
@@ -255,28 +314,28 @@ namespace ImageSharp.Formats
Vector4 mz1 = my3 + my5;
Vector4 mz3 = my1 + my5;
- Vector4 mz4 = (mz0 + mz1) * c_1_175876;
+ Vector4 mz4 = (mz0 + mz1) * C_1_175876;
- mz2 = (mz2 * c_1_961571) + mz4;
- mz3 = (mz3 * c_0_390181) + mz4;
- mz0 = mz0 * c_0_899976;
- mz1 = mz1 * c_2_562915;
+ mz2 = (mz2 * C_1_961571) + mz4;
+ mz3 = (mz3 * C_0_390181) + mz4;
+ mz0 = mz0 * C_0_899976;
+ mz1 = mz1 * C_2_562915;
- Vector4 mb3 = (my7 * c_0_298631) + mz0 + mz2;
- Vector4 mb2 = (my5 * c_2_053120) + mz1 + mz3;
- Vector4 mb1 = (my3 * c_3_072711) + mz1 + mz2;
- Vector4 mb0 = (my1 * c_1_501321) + mz0 + mz3;
+ Vector4 mb3 = (my7 * C_0_298631) + mz0 + mz2;
+ Vector4 mb2 = (my5 * C_2_053120) + mz1 + mz3;
+ Vector4 mb1 = (my3 * C_3_072711) + mz1 + mz2;
+ Vector4 mb0 = (my1 * C_1_501321) + mz0 + mz3;
Vector4 my2 = this.V2R;
Vector4 my6 = this.V6R;
- mz4 = (my2 + my6) * c_0_541196;
+ mz4 = (my2 + my6) * C_0_541196;
Vector4 my0 = this.V0R;
Vector4 my4 = this.V4R;
mz0 = my0 + my4;
mz1 = my0 - my4;
- mz2 = mz4 + (my6 * c_1_847759);
- mz3 = mz4 + (my2 * c_0_765367);
+ mz2 = mz4 + (my6 * C_1_847759);
+ mz3 = mz4 + (my2 * C_0_765367);
my0 = mz0 + mz3;
my3 = mz0 - mz3;
@@ -293,49 +352,6 @@ namespace ImageSharp.Formats
d.V4R = my3 - mb3;
}
- public unsafe float this[int idx]
- {
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- get
- {
- fixed (Block8x8F* p = &this)
- {
- float* fp = (float*)p;
- return fp[idx];
- }
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- set
- {
- fixed (Block8x8F* p = &this)
- {
- float* fp = (float*)p;
- fp[idx] = value;
- }
- }
- }
-
- ///
- /// Pointer-based "Indexer" (getter part)
- ///
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- internal static unsafe float GetScalarAt(Block8x8F* blockPtr, int idx)
- {
- float* fp = (float*)blockPtr;
- return fp[idx];
- }
-
- ///
- /// Pointer-based "Indexer" (setter part)
- ///
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- internal static unsafe void SetScalarAt(Block8x8F* blockPtr, int idx, float value)
- {
- float* fp = (float*)blockPtr;
- fp[idx] = value;
- }
-
///
/// Fill the block with defaults (zeroes)
///
@@ -387,19 +403,5 @@ namespace ImageSharp.Formats
src += 8;
}
}
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- internal static unsafe void UnZig(Block8x8F* block, Block8x8F* qt, int* unzigPtr)
- {
- float* b = (float*)block;
- float* qtp = (float*)qt;
- for (int zig = 0; zig < BlockF.BlockSize; zig++)
- {
- float* unzigPos = b + unzigPtr[zig];
- float val = *unzigPos;
- val *= qtp[zig];
- *unzigPos = val;
- }
- }
}
}
\ No newline at end of file
diff --git a/src/ImageSharp/Formats/Jpg/Components/Bytes.cs b/src/ImageSharp/Formats/Jpg/Components/Bytes.cs
index 32a767d58..9a49665d2 100644
--- a/src/ImageSharp/Formats/Jpg/Components/Bytes.cs
+++ b/src/ImageSharp/Formats/Jpg/Components/Bytes.cs
@@ -16,16 +16,6 @@ namespace ImageSharp.Formats
///
internal struct Bytes : IDisposable
{
- private static readonly ArrayPool ArrayPool = ArrayPool.Create(4096, 50);
-
- ///
- /// Creates a new instance of the , and initializes it's buffer.
- ///
- public static Bytes Create()
- {
- return new Bytes { Buffer = ArrayPool.Rent(4096) };
- }
-
///
/// Gets or sets the buffer.
/// buffer[i:j] are the buffered bytes read from the underlying
@@ -43,9 +33,22 @@ namespace ImageSharp.Formats
///
public int UnreadableBytes;
+ private static readonly ArrayPool ArrayPool = ArrayPool.Create(4096, 50);
+
+ ///
+ /// Creates a new instance of the , and initializes it's buffer.
+ ///
+ public static Bytes Create()
+ {
+ return new Bytes { Buffer = ArrayPool.Rent(4096) };
+ }
+
public void Dispose()
{
- if (this.Buffer != null) ArrayPool.Return(this.Buffer);
+ if (this.Buffer != null)
+ {
+ ArrayPool.Return(this.Buffer);
+ }
this.Buffer = null;
}
diff --git a/src/ImageSharp/Formats/Jpg/Components/FDCT.cs b/src/ImageSharp/Formats/Jpg/Components/FDCT.cs
index 13ce80f55..650656ab2 100644
--- a/src/ImageSharp/Formats/Jpg/Components/FDCT.cs
+++ b/src/ImageSharp/Formats/Jpg/Components/FDCT.cs
@@ -13,18 +13,20 @@ namespace ImageSharp.Formats
{
// Trigonometric constants in 13-bit fixed point format.
// TODO: Rename and describe these.
- private const int fix_0_298631336 = 2446;
- private const int fix_0_390180644 = 3196;
- private const int fix_0_541196100 = 4433;
- private const int fix_0_765366865 = 6270;
- private const int fix_0_899976223 = 7373;
- private const int fix_1_175875602 = 9633;
- private const int fix_1_501321110 = 12299;
- private const int fix_1_847759065 = 15137;
- private const int fix_1_961570560 = 16069;
- private const int fix_2_053119869 = 16819;
- private const int fix_2_562915447 = 20995;
- private const int fix_3_072711026 = 25172;
+#pragma warning disable SA1310 // FieldNamesMustNotContainUnderscore
+ private const int Fix_0_298631336 = 2446;
+ private const int Fix_0_390180644 = 3196;
+ private const int Fix_0_541196100 = 4433;
+ private const int Fix_0_765366865 = 6270;
+ private const int Fix_0_899976223 = 7373;
+ private const int Fix_1_175875602 = 9633;
+ private const int Fix_1_501321110 = 12299;
+ private const int Fix_1_847759065 = 15137;
+ private const int Fix_1_961570560 = 16069;
+ private const int Fix_2_053119869 = 16819;
+ private const int Fix_2_562915447 = 20995;
+ private const int Fix_3_072711026 = 25172;
+#pragma warning restore SA1310 // FieldNamesMustNotContainUnderscore
///
/// The number of bits
@@ -78,25 +80,25 @@ namespace ImageSharp.Formats
block[y8] = (tmp10 + tmp11 - (8 * CenterJSample)) << Pass1Bits;
block[y8 + 4] = (tmp10 - tmp11) << Pass1Bits;
- int z1 = (tmp12 + tmp13) * fix_0_541196100;
+ int z1 = (tmp12 + tmp13) * Fix_0_541196100;
z1 += 1 << (Bits - Pass1Bits - 1);
- block[y8 + 2] = (z1 + (tmp12 * fix_0_765366865)) >> (Bits - Pass1Bits);
- block[y8 + 6] = (z1 - (tmp13 * fix_1_847759065)) >> (Bits - Pass1Bits);
+ block[y8 + 2] = (z1 + (tmp12 * Fix_0_765366865)) >> (Bits - Pass1Bits);
+ block[y8 + 6] = (z1 - (tmp13 * Fix_1_847759065)) >> (Bits - Pass1Bits);
tmp10 = tmp0 + tmp3;
tmp11 = tmp1 + tmp2;
tmp12 = tmp0 + tmp2;
tmp13 = tmp1 + tmp3;
- z1 = (tmp12 + tmp13) * fix_1_175875602;
+ z1 = (tmp12 + tmp13) * Fix_1_175875602;
z1 += 1 << (Bits - Pass1Bits - 1);
- tmp0 = tmp0 * fix_1_501321110;
- tmp1 = tmp1 * fix_3_072711026;
- tmp2 = tmp2 * fix_2_053119869;
- tmp3 = tmp3 * fix_0_298631336;
- tmp10 = tmp10 * -fix_0_899976223;
- tmp11 = tmp11 * -fix_2_562915447;
- tmp12 = tmp12 * -fix_0_390180644;
- tmp13 = tmp13 * -fix_1_961570560;
+ tmp0 = tmp0 * Fix_1_501321110;
+ tmp1 = tmp1 * Fix_3_072711026;
+ tmp2 = tmp2 * Fix_2_053119869;
+ tmp3 = tmp3 * Fix_0_298631336;
+ tmp10 = tmp10 * -Fix_0_899976223;
+ tmp11 = tmp11 * -Fix_2_562915447;
+ tmp12 = tmp12 * -Fix_0_390180644;
+ tmp13 = tmp13 * -Fix_1_961570560;
tmp12 += z1;
tmp13 += z1;
@@ -128,25 +130,25 @@ namespace ImageSharp.Formats
block[x] = (tmp10 + tmp11) >> Pass1Bits;
block[32 + x] = (tmp10 - tmp11) >> Pass1Bits;
- int z1 = (tmp12 + tmp13) * fix_0_541196100;
+ int z1 = (tmp12 + tmp13) * Fix_0_541196100;
z1 += 1 << (Bits + Pass1Bits - 1);
- block[16 + x] = (z1 + (tmp12 * fix_0_765366865)) >> (Bits + Pass1Bits);
- block[48 + x] = (z1 - (tmp13 * fix_1_847759065)) >> (Bits + Pass1Bits);
+ block[16 + x] = (z1 + (tmp12 * Fix_0_765366865)) >> (Bits + Pass1Bits);
+ block[48 + x] = (z1 - (tmp13 * Fix_1_847759065)) >> (Bits + Pass1Bits);
tmp10 = tmp0 + tmp3;
tmp11 = tmp1 + tmp2;
tmp12 = tmp0 + tmp2;
tmp13 = tmp1 + tmp3;
- z1 = (tmp12 + tmp13) * fix_1_175875602;
+ z1 = (tmp12 + tmp13) * Fix_1_175875602;
z1 += 1 << (Bits + Pass1Bits - 1);
- tmp0 = tmp0 * fix_1_501321110;
- tmp1 = tmp1 * fix_3_072711026;
- tmp2 = tmp2 * fix_2_053119869;
- tmp3 = tmp3 * fix_0_298631336;
- tmp10 = tmp10 * -fix_0_899976223;
- tmp11 = tmp11 * -fix_2_562915447;
- tmp12 = tmp12 * -fix_0_390180644;
- tmp13 = tmp13 * -fix_1_961570560;
+ tmp0 = tmp0 * Fix_1_501321110;
+ tmp1 = tmp1 * Fix_3_072711026;
+ tmp2 = tmp2 * Fix_2_053119869;
+ tmp3 = tmp3 * Fix_0_298631336;
+ tmp10 = tmp10 * -Fix_0_899976223;
+ tmp11 = tmp11 * -Fix_2_562915447;
+ tmp12 = tmp12 * -Fix_0_390180644;
+ tmp13 = tmp13 * -Fix_1_961570560;
tmp12 += z1;
tmp13 += z1;
diff --git a/src/ImageSharp/Formats/Jpg/Components/Huffman.cs b/src/ImageSharp/Formats/Jpg/Components/Huffman.cs
index 30b80d4f8..74f77f303 100644
--- a/src/ImageSharp/Formats/Jpg/Components/Huffman.cs
+++ b/src/ImageSharp/Formats/Jpg/Components/Huffman.cs
@@ -12,21 +12,6 @@ namespace ImageSharp.Formats
///
internal struct Huffman : IDisposable
{
- private static ArrayPool UshortBuffer = ArrayPool.Create(1 << JpegDecoderCore.LutSize, 50);
-
- private static ArrayPool ByteBuffer = ArrayPool.Create(JpegDecoderCore.MaxNCodes, 50);
-
- private static readonly ArrayPool IntBuffer = ArrayPool.Create(JpegDecoderCore.MaxCodeLength, 50);
-
- public void Init(int lutSize, int maxNCodes, int maxCodeLength)
- {
- this.Lut = UshortBuffer.Rent(1 << lutSize);
- this.Values = ByteBuffer.Rent(maxNCodes);
- this.MinCodes = IntBuffer.Rent(maxCodeLength);
- this.MaxCodes = IntBuffer.Rent(maxCodeLength);
- this.Indices = IntBuffer.Rent(maxCodeLength);
- }
-
///
/// Gets or sets the number of codes in the tree.
///
@@ -62,6 +47,21 @@ namespace ImageSharp.Formats
///
public int[] Indices;
+ private static readonly ArrayPool UshortBuffer = ArrayPool.Create(1 << JpegDecoderCore.LutSize, 50);
+
+ private static readonly ArrayPool ByteBuffer = ArrayPool.Create(JpegDecoderCore.MaxNCodes, 50);
+
+ private static readonly ArrayPool IntBuffer = ArrayPool.Create(JpegDecoderCore.MaxCodeLength, 50);
+
+ public void Init(int lutSize, int maxNCodes, int maxCodeLength)
+ {
+ this.Lut = UshortBuffer.Rent(1 << lutSize);
+ this.Values = ByteBuffer.Rent(maxNCodes);
+ this.MinCodes = IntBuffer.Rent(maxCodeLength);
+ this.MaxCodes = IntBuffer.Rent(maxCodeLength);
+ this.Indices = IntBuffer.Rent(maxCodeLength);
+ }
+
public void Dispose()
{
UshortBuffer.Return(this.Lut, true);
diff --git a/src/ImageSharp/Formats/Jpg/Components/IDCT.cs b/src/ImageSharp/Formats/Jpg/Components/IDCT.cs
index b3277e027..8c3a5a238 100644
--- a/src/ImageSharp/Formats/Jpg/Components/IDCT.cs
+++ b/src/ImageSharp/Formats/Jpg/Components/IDCT.cs
@@ -10,21 +10,21 @@ namespace ImageSharp.Formats
///
internal class IDCT
{
- private const int w1 = 2841; // 2048*sqrt(2)*cos(1*pi/16)
- private const int w2 = 2676; // 2048*sqrt(2)*cos(2*pi/16)
- private const int w3 = 2408; // 2048*sqrt(2)*cos(3*pi/16)
- private const int w5 = 1609; // 2048*sqrt(2)*cos(5*pi/16)
- private const int w6 = 1108; // 2048*sqrt(2)*cos(6*pi/16)
- private const int w7 = 565; // 2048*sqrt(2)*cos(7*pi/16)
-
- private const int w1pw7 = w1 + w7;
- private const int w1mw7 = w1 - w7;
- private const int w2pw6 = w2 + w6;
- private const int w2mw6 = w2 - w6;
- private const int w3pw5 = w3 + w5;
- private const int w3mw5 = w3 - w5;
-
- private const int r2 = 181; // 256/sqrt(2)
+ private const int W1 = 2841; // 2048*sqrt(2)*cos(1*pi/16)
+ private const int W2 = 2676; // 2048*sqrt(2)*cos(2*pi/16)
+ private const int W3 = 2408; // 2048*sqrt(2)*cos(3*pi/16)
+ private const int W5 = 1609; // 2048*sqrt(2)*cos(5*pi/16)
+ private const int W6 = 1108; // 2048*sqrt(2)*cos(6*pi/16)
+ private const int W7 = 565; // 2048*sqrt(2)*cos(7*pi/16)
+
+ private const int W1pw7 = W1 + W7;
+ private const int W1mw7 = W1 - W7;
+ private const int W2pw6 = W2 + W6;
+ private const int W2mw6 = W2 - W6;
+ private const int W3pw5 = W3 + W5;
+ private const int W3mw5 = W3 - W5;
+
+ private const int R2 = 181; // 256/sqrt(2)
///
/// Performs a 2-D Inverse Discrete Cosine Transformation.
@@ -73,19 +73,19 @@ namespace ImageSharp.Formats
int x7 = src[y8 + 3];
// Stage 1.
- int x8 = w7 * (x4 + x5);
- x4 = x8 + (w1mw7 * x4);
- x5 = x8 - (w1pw7 * x5);
- x8 = w3 * (x6 + x7);
- x6 = x8 - (w3mw5 * x6);
- x7 = x8 - (w3pw5 * x7);
+ int x8 = W7 * (x4 + x5);
+ x4 = x8 + (W1mw7 * x4);
+ x5 = x8 - (W1pw7 * x5);
+ x8 = W3 * (x6 + x7);
+ x6 = x8 - (W3mw5 * x6);
+ x7 = x8 - (W3pw5 * x7);
// Stage 2.
x8 = x0 + x1;
x0 -= x1;
- x1 = w6 * (x3 + x2);
- x2 = x1 - (w2pw6 * x2);
- x3 = x1 + (w2mw6 * x3);
+ x1 = W6 * (x3 + x2);
+ x2 = x1 - (W2pw6 * x2);
+ x3 = x1 + (W2mw6 * x3);
x1 = x4 + x6;
x4 -= x6;
x6 = x5 + x7;
@@ -96,8 +96,8 @@ namespace ImageSharp.Formats
x8 -= x3;
x3 = x0 + x2;
x0 -= x2;
- x2 = ((r2 * (x4 + x5)) + 128) >> 8;
- x4 = ((r2 * (x4 - x5)) + 128) >> 8;
+ x2 = ((R2 * (x4 + x5)) + 128) >> 8;
+ x4 = ((R2 * (x4 - x5)) + 128) >> 8;
// Stage 4.
src[y8 + 0] = (x7 + x1) >> 8;
@@ -128,19 +128,19 @@ namespace ImageSharp.Formats
int y7 = src[24 + x];
// Stage 1.
- int y8 = (w7 * (y4 + y5)) + 4;
- y4 = (y8 + (w1mw7 * y4)) >> 3;
- y5 = (y8 - (w1pw7 * y5)) >> 3;
- y8 = (w3 * (y6 + y7)) + 4;
- y6 = (y8 - (w3mw5 * y6)) >> 3;
- y7 = (y8 - (w3pw5 * y7)) >> 3;
+ int y8 = (W7 * (y4 + y5)) + 4;
+ y4 = (y8 + (W1mw7 * y4)) >> 3;
+ y5 = (y8 - (W1pw7 * y5)) >> 3;
+ y8 = (W3 * (y6 + y7)) + 4;
+ y6 = (y8 - (W3mw5 * y6)) >> 3;
+ y7 = (y8 - (W3pw5 * y7)) >> 3;
// Stage 2.
y8 = y0 + y1;
y0 -= y1;
- y1 = (w6 * (y3 + y2)) + 4;
- y2 = (y1 - (w2pw6 * y2)) >> 3;
- y3 = (y1 + (w2mw6 * y3)) >> 3;
+ y1 = (W6 * (y3 + y2)) + 4;
+ y2 = (y1 - (W2pw6 * y2)) >> 3;
+ y3 = (y1 + (W2mw6 * y3)) >> 3;
y1 = y4 + y6;
y4 -= y6;
y6 = y5 + y7;
@@ -151,8 +151,8 @@ namespace ImageSharp.Formats
y8 -= y3;
y3 = y0 + y2;
y0 -= y2;
- y2 = ((r2 * (y4 + y5)) + 128) >> 8;
- y4 = ((r2 * (y4 - y5)) + 128) >> 8;
+ y2 = ((R2 * (y4 + y5)) + 128) >> 8;
+ y4 = ((R2 * (y4 - y5)) + 128) >> 8;
// Stage 4.
src[x] = (y7 + y1) >> 14;
@@ -165,6 +165,5 @@ namespace ImageSharp.Formats
src[56 + x] = (y7 - y1) >> 14;
}
}
-
}
}
diff --git a/src/ImageSharp/Formats/Jpg/Components/MutableSpan.cs b/src/ImageSharp/Formats/Jpg/Components/MutableSpan.cs
index 2d762fdfa..4b4899849 100644
--- a/src/ImageSharp/Formats/Jpg/Components/MutableSpan.cs
+++ b/src/ImageSharp/Formats/Jpg/Components/MutableSpan.cs
@@ -22,8 +22,6 @@ namespace ImageSharp.Formats
public int Offset;
- public int TotalCount => this.Data.Length - this.Offset;
-
public MutableSpan(int size, int offset = 0)
{
this.Data = new T[size];
@@ -36,6 +34,8 @@ namespace ImageSharp.Formats
this.Offset = offset;
}
+ public int TotalCount => this.Data.Length - this.Offset;
+
public T this[int idx]
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -51,14 +51,14 @@ namespace ImageSharp.Formats
}
}
+ public static implicit operator MutableSpan(T[] data) => new MutableSpan(data, 0);
+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public MutableSpan Slice(int offset)
{
return new MutableSpan(this.Data, this.Offset + offset);
}
- public static implicit operator MutableSpan(T[] data) => new MutableSpan(data, 0);
-
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void AddOffset(int offset)
{
diff --git a/src/ImageSharp/Formats/Jpg/JpegDecoderCore.cs b/src/ImageSharp/Formats/Jpg/JpegDecoderCore.cs
index d9983eb29..3362b332d 100644
--- a/src/ImageSharp/Formats/Jpg/JpegDecoderCore.cs
+++ b/src/ImageSharp/Formats/Jpg/JpegDecoderCore.cs
@@ -31,6 +31,21 @@ namespace ImageSharp.Formats
///
internal const int LutSize = 8;
+ ///
+ /// The byte buffer.
+ ///
+ internal Bytes Bytes;
+
+ ///
+ /// The input stream.
+ ///
+ internal Stream InputStream;
+
+ ///
+ /// Holds the unprocessed bits that have been taken from the byte-stream.
+ ///
+ internal Bits Bits;
+
///
/// The maximum number of color components
///
@@ -101,11 +116,6 @@ namespace ImageSharp.Formats
///
private readonly byte[] temp;
- ///
- /// The byte buffer.
- ///
- internal Bytes bytes;
-
///
/// The image width
///
@@ -131,16 +141,6 @@ namespace ImageSharp.Formats
///
private YCbCrImage ycbcrImage;
- ///
- /// The input stream.
- ///
- internal Stream inputStream;
-
- ///
- /// Holds the unprocessed bits that have been taken from the byte-stream.
- ///
- internal Bits bits;
-
///
/// The array of keyline pixels in a CMYK image
///
@@ -198,26 +198,37 @@ namespace ImageSharp.Formats
///
public JpegDecoderCore()
{
- //this.huffmanTrees = new Huffman[MaxTc + 1, MaxTh + 1];
+ // this.huffmanTrees = new Huffman[MaxTc + 1, MaxTh + 1];
this.huffmanTrees = new Huffman[(MaxTc + 1) * (MaxTh + 1)];
this.quantizationTables = new Block8x8F[MaxTq + 1];
this.temp = new byte[2 * BlockF.BlockSize];
this.componentArray = new Component[MaxComponents];
this.progCoeffs = new Block8x8F[MaxComponents][];
- this.bits = new Bits();
- this.bytes = Bytes.Create();
+ this.Bits = default(Bits);
+ this.Bytes = Bytes.Create();
// TODO: This looks like it could be static.
for (int i = 0; i < MaxTc + 1; i++)
{
for (int j = 0; j < MaxTh + 1; j++)
{
- this.huffmanTrees[i * ThRowSize + j].Init(LutSize, MaxNCodes, MaxCodeLength);
+ this.huffmanTrees[(i * ThRowSize) + j].Init(LutSize, MaxNCodes, MaxCodeLength);
}
}
}
+ ///
+ /// ReadByteStuffedByte was throwing exceptions on normal execution path (very inefficent)
+ /// It's better tho have an error code for this!
+ ///
+ internal enum ErrorCodes
+ {
+ NoError,
+ // ReSharper disable once InconsistentNaming
+ MissingFF00
+ }
+
///
/// Decodes the image from the specified this._stream and sets
/// the data to image.
@@ -231,7 +242,7 @@ namespace ImageSharp.Formats
where TColor : struct, IPackedPixel
where TPacked : struct
{
- this.inputStream = stream;
+ this.InputStream = stream;
// Check for the Start Of Image marker.
this.ReadFull(this.temp, 0, 2);
@@ -422,6 +433,51 @@ namespace ImageSharp.Formats
}
}
+ public void Dispose()
+ {
+ for (int i = 0; i < this.huffmanTrees.Length; i++)
+ {
+ this.huffmanTrees[i].Dispose();
+ }
+
+ this.Bytes.Dispose();
+ }
+
+ ///
+ /// Returns the next byte, whether buffered or not buffered. It does not care about byte stuffing.
+ ///
+ /// The
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ internal byte ReadByte()
+ {
+ return this.Bytes.ReadByte(this.InputStream);
+ }
+
+ ///
+ /// Optimized method to pack bytes to the image from the YCbCr color space.
+ /// This is faster than implicit casting as it avoids double packing.
+ ///
+ /// The pixel format.
+ /// The packed format. uint, long, float.
+ /// The packed pixel.
+ /// The y luminance component.
+ /// The cb chroma component.
+ /// The cr chroma component.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private static void PackYcbCr(ref TColor packed, byte y, byte cb, byte cr)
+ where TColor : struct, IPackedPixel
+ where TPacked : struct
+ {
+ int ccb = cb - 128;
+ int ccr = cr - 128;
+
+ byte r = (byte)(y + (1.402F * ccr)).Clamp(0, 255);
+ byte g = (byte)(y - (0.34414F * ccb) - (0.71414F * ccr)).Clamp(0, 255);
+ byte b = (byte)(y + (1.772F * ccb)).Clamp(0, 255);
+
+ packed.PackFromBytes(r, g, b, 255);
+ }
+
///
/// Processes a Define Huffman Table marker, and initializes a huffman
/// struct from its contents. Specified in section B.2.4.2.
@@ -450,7 +506,7 @@ namespace ImageSharp.Formats
throw new ImageFormatException("Bad Th value");
}
- this.ProcessDefineHuffmanTablesMarkerLoop(ref this.huffmanTrees[tc * ThRowSize + th], ref remaining);
+ this.ProcessDefineHuffmanTablesMarkerLoop(ref this.huffmanTrees[(tc * ThRowSize) + th], ref remaining);
}
}
@@ -550,25 +606,24 @@ namespace ImageSharp.Formats
private byte DecodeHuffman(ref Huffman huffman)
{
// Copy stuff to the stack:
-
if (huffman.Length == 0)
{
throw new ImageFormatException("Uninitialized Huffman table");
}
- if (this.bits.UnreadBits < 8)
+ if (this.Bits.UnreadBits < 8)
{
- var errorCode = this.bits.EnsureNBits(8, this);
+ var errorCode = this.Bits.EnsureNBits(8, this);
if (errorCode == ErrorCodes.NoError)
{
- ushort v = huffman.Lut[(this.bits.Accumulator >> (this.bits.UnreadBits - LutSize)) & 0xff];
+ ushort v = huffman.Lut[(this.Bits.Accumulator >> (this.Bits.UnreadBits - LutSize)) & 0xff];
if (v != 0)
{
byte n = (byte)((v & 0xff) - 1);
- this.bits.UnreadBits -= n;
- this.bits.Mask >>= n;
+ this.Bits.UnreadBits -= n;
+ this.Bits.Mask >>= n;
return (byte)(v >> 8);
}
}
@@ -581,22 +636,22 @@ namespace ImageSharp.Formats
int code = 0;
for (int i = 0; i < MaxCodeLength; i++)
{
- if (this.bits.UnreadBits == 0)
+ if (this.Bits.UnreadBits == 0)
{
- var errorCode = this.bits.EnsureNBits(1, this);
+ var errorCode = this.Bits.EnsureNBits(1, this);
if (errorCode != ErrorCodes.NoError)
{
throw new MissingFF00Exception();
}
}
- if ((this.bits.Accumulator & this.bits.Mask) != 0)
+ if ((this.Bits.Accumulator & this.Bits.Mask) != 0)
{
code |= 1;
}
- this.bits.UnreadBits--;
- this.bits.Mask >>= 1;
+ this.Bits.UnreadBits--;
+ this.Bits.Mask >>= 1;
if (code <= huffman.MaxCodes[i])
{
@@ -615,18 +670,18 @@ namespace ImageSharp.Formats
/// The
private bool DecodeBit()
{
- if (this.bits.UnreadBits == 0)
+ if (this.Bits.UnreadBits == 0)
{
- var errorCode = this.bits.EnsureNBits(1, this);
+ var errorCode = this.Bits.EnsureNBits(1, this);
if (errorCode != ErrorCodes.NoError)
{
throw new MissingFF00Exception();
}
}
- bool ret = (this.bits.Accumulator & this.bits.Mask) != 0;
- this.bits.UnreadBits--;
- this.bits.Mask >>= 1;
+ bool ret = (this.Bits.Accumulator & this.Bits.Mask) != 0;
+ this.Bits.UnreadBits--;
+ this.Bits.Mask >>= 1;
return ret;
}
@@ -637,19 +692,19 @@ namespace ImageSharp.Formats
/// The
private uint DecodeBits(int count)
{
- if (this.bits.UnreadBits < count)
+ if (this.Bits.UnreadBits < count)
{
- var errorCode = this.bits.EnsureNBits(count, this);
+ var errorCode = this.Bits.EnsureNBits(count, this);
if (errorCode != ErrorCodes.NoError)
{
throw new MissingFF00Exception();
}
}
- uint ret = this.bits.Accumulator >> (this.bits.UnreadBits - count);
+ uint ret = this.Bits.Accumulator >> (this.Bits.UnreadBits - count);
ret = (uint)(ret & ((1 << count) - 1));
- this.bits.UnreadBits -= count;
- this.bits.Mask >>= count;
+ this.Bits.UnreadBits -= count;
+ this.Bits.Mask >>= count;
return ret;
}
@@ -662,26 +717,16 @@ namespace ImageSharp.Formats
///
private void UnreadByteStuffedByte()
{
- this.bytes.I -= this.bytes.UnreadableBytes;
- this.bytes.UnreadableBytes = 0;
- if (this.bits.UnreadBits >= 8)
+ this.Bytes.I -= this.Bytes.UnreadableBytes;
+ this.Bytes.UnreadableBytes = 0;
+ if (this.Bits.UnreadBits >= 8)
{
- this.bits.Accumulator >>= 8;
- this.bits.UnreadBits -= 8;
- this.bits.Mask >>= 8;
+ this.Bits.Accumulator >>= 8;
+ this.Bits.UnreadBits -= 8;
+ this.Bits.Mask >>= 8;
}
}
- ///
- /// Returns the next byte, whether buffered or not buffered. It does not care about byte stuffing.
- ///
- /// The
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- internal byte ReadByte()
- {
- return this.bytes.ReadByte(this.inputStream);
- }
-
///
/// Reads exactly length bytes into data. It does not care about byte stuffing.
///
@@ -691,32 +736,32 @@ namespace ImageSharp.Formats
private void ReadFull(byte[] data, int offset, int length)
{
// Unread the overshot bytes, if any.
- if (this.bytes.UnreadableBytes != 0)
+ if (this.Bytes.UnreadableBytes != 0)
{
- if (this.bits.UnreadBits >= 8)
+ if (this.Bits.UnreadBits >= 8)
{
this.UnreadByteStuffedByte();
}
- this.bytes.UnreadableBytes = 0;
+ this.Bytes.UnreadableBytes = 0;
}
while (length > 0)
{
- if (this.bytes.J - this.bytes.I >= length)
+ if (this.Bytes.J - this.Bytes.I >= length)
{
- Array.Copy(this.bytes.Buffer, this.bytes.I, data, offset, length);
- this.bytes.I += length;
+ Array.Copy(this.Bytes.Buffer, this.Bytes.I, data, offset, length);
+ this.Bytes.I += length;
length -= length;
}
else
{
- Array.Copy(this.bytes.Buffer, this.bytes.I, data, offset, this.bytes.J - this.bytes.I);
- offset += this.bytes.J - this.bytes.I;
- length -= this.bytes.J - this.bytes.I;
- this.bytes.I += this.bytes.J - this.bytes.I;
+ Array.Copy(this.Bytes.Buffer, this.Bytes.I, data, offset, this.Bytes.J - this.Bytes.I);
+ offset += this.Bytes.J - this.Bytes.I;
+ length -= this.Bytes.J - this.Bytes.I;
+ this.Bytes.I += this.Bytes.J - this.Bytes.I;
- this.bytes.Fill(this.inputStream);
+ this.Bytes.Fill(this.InputStream);
}
}
}
@@ -728,32 +773,32 @@ namespace ImageSharp.Formats
private void Skip(int count)
{
// Unread the overshot bytes, if any.
- if (this.bytes.UnreadableBytes != 0)
+ if (this.Bytes.UnreadableBytes != 0)
{
- if (this.bits.UnreadBits >= 8)
+ if (this.Bits.UnreadBits >= 8)
{
this.UnreadByteStuffedByte();
}
- this.bytes.UnreadableBytes = 0;
+ this.Bytes.UnreadableBytes = 0;
}
while (true)
{
- int m = this.bytes.J - this.bytes.I;
+ int m = this.Bytes.J - this.Bytes.I;
if (m > count)
{
m = count;
}
- this.bytes.I += m;
+ this.Bytes.I += m;
count -= m;
if (count == 0)
{
break;
}
- this.bytes.Fill(this.inputStream);
+ this.Bytes.Fill(this.InputStream);
}
}
@@ -1073,7 +1118,8 @@ namespace ImageSharp.Formats
/// The remaining bytes in the segment block.
/// The image.
private void ProcessApp1Marker(int remaining, Image image)
- where TColor : struct, IPackedPixel where TPacked : struct
+ where TColor : struct, IPackedPixel
+ where TPacked : struct
{
if (remaining < 6)
{
@@ -1130,7 +1176,8 @@ namespace ImageSharp.Formats
/// The image height.
/// The image.
private void ConvertFromCmyk(int width, int height, Image image)
- where TColor : struct, IPackedPixel where TPacked : struct
+ where TColor : struct, IPackedPixel
+ where TPacked : struct
{
if (!this.adobeTransformValid)
{
@@ -1186,7 +1233,8 @@ namespace ImageSharp.Formats
/// The image height.
/// The image.
private void ConvertFromGrayScale(int width, int height, Image image)
- where TColor : struct, IPackedPixel where TPacked : struct
+ where TColor : struct, IPackedPixel
+ where TPacked : struct
{
image.InitPixels(width, height);
@@ -1222,7 +1270,8 @@ namespace ImageSharp.Formats
/// The image height.
/// The image.
private void ConvertFromYCbCr(int width, int height, Image image)
- where TColor : struct, IPackedPixel where TPacked : struct
+ where TColor : struct, IPackedPixel
+ where TPacked : struct
{
int scale = this.componentArray[0].HorizontalFactor / this.componentArray[1].HorizontalFactor;
image.InitPixels(width, height);
@@ -1263,7 +1312,8 @@ namespace ImageSharp.Formats
/// The height.
/// The image.
private void ConvertFromRGB(int width, int height, Image image)
- where TColor : struct, IPackedPixel where TPacked : struct
+ where TColor : struct, IPackedPixel
+ where TPacked : struct
{
int scale = this.componentArray[0].HorizontalFactor / this.componentArray[1].HorizontalFactor;
image.InitPixels(width, height);
@@ -1302,7 +1352,8 @@ namespace ImageSharp.Formats
/// The packed format. uint, long, float.
/// The image to assign the resolution to.
private void AssignResolution(Image image)
- where TColor : struct, IPackedPixel where TPacked : struct
+ where TColor : struct, IPackedPixel
+ where TPacked : struct
{
if (this.isJfif && this.horizontalResolution > 0 && this.verticalResolution > 0)
{
@@ -1311,11 +1362,6 @@ namespace ImageSharp.Formats
}
}
- struct StackallocUnzigData
- {
- internal fixed int Data[64];
- }
-
///
/// Processes the SOS (Start of scan marker).
///
@@ -1431,13 +1477,13 @@ namespace ImageSharp.Formats
}
}
- this.bits = new Bits();
+ this.Bits = default(Bits);
int mcu = 0;
byte expectedRst = JpegConstants.Markers.RST0;
// b is the decoded coefficients block, in natural (not zig-zag) order.
- //Block b;
+ // Block b;
int[] dc = new int[MaxComponents];
// bx and by are the location of the current block, in units of 8x8
@@ -1510,8 +1556,8 @@ namespace ImageSharp.Formats
fixed (Block8x8F* qtp = &this.quantizationTables[qtIndex])
{
- if (this.isProgressive)
// Load the previous partially decoded coefficients, if applicable.
+ if (this.isProgressive)
{
this.blockIndex = ((@by * mxx) * hi) + bx;
@@ -1585,7 +1631,7 @@ namespace ImageSharp.Formats
}
// Reset the Huffman decoder.
- this.bits = new Bits();
+ this.Bits = default(Bits);
// Reset the DC components, as per section F.2.1.3.1.
dc = new int[MaxComponents];
@@ -1620,7 +1666,7 @@ namespace ImageSharp.Formats
int bx,
Block8x8F* qt)
{
- var huffmannIdx = AcTable * ThRowSize + scan[i].AcTableSelector;
+ var huffmannIdx = (AcTable * ThRowSize) + scan[i].AcTableSelector;
if (ah != 0)
{
this.Refine(b, ref this.huffmanTrees[huffmannIdx], unzigPtr, zigStart, zigEnd, 1 << al);
@@ -1634,13 +1680,13 @@ namespace ImageSharp.Formats
// Decode the DC coefficient, as specified in section F.2.2.1.
byte value = this.DecodeHuffman(
- ref this.huffmanTrees[DcTable * ThRowSize + scan[i].DcTableSelector]);
+ ref this.huffmanTrees[(DcTable * ThRowSize) + scan[i].DcTableSelector]);
if (value > 16)
{
throw new ImageFormatException("Excessive DC component");
}
- int deltaDC = this.bits.ReceiveExtend(value, this);
+ int deltaDC = this.Bits.ReceiveExtend(value, this);
dc[compIndex] += deltaDC;
// b[0] = dc[compIndex] << al;
@@ -1668,7 +1714,7 @@ namespace ImageSharp.Formats
break;
}
- int ac = this.bits.ReceiveExtend(val1, this);
+ int ac = this.Bits.ReceiveExtend(val1, this);
// b[Unzig[zig]] = ac << al;
Block8x8F.SetScalarAt(b, unzigPtr[zig], ac << al);
@@ -1700,8 +1746,8 @@ namespace ImageSharp.Formats
// We haven't completely decoded this 8x8 block. Save the coefficients.
// TODO!!!
- //throw new NotImplementedException();
- //this.progCoeffs[compIndex][((@by * mxx) * hi) + bx] = b.Clone();
+ // throw new NotImplementedException();
+ // this.progCoeffs[compIndex][((@by * mxx) * hi) + bx] = b.Clone();
this.progCoeffs[compIndex][((@by * mxx) * hi) + bx] = *b;
// At this point, we could execute the rest of the loop body to dequantize and
@@ -1774,7 +1820,7 @@ namespace ImageSharp.Formats
int compIndex = -1;
for (int j = 0; j < this.componentCount; j++)
{
- //Component compv = ;
+ // Component compv = ;
if (cs == this.componentArray[j].Identifier)
{
compIndex = j;
@@ -1914,7 +1960,7 @@ namespace ImageSharp.Formats
if (z != 0)
{
- //b[Unzig[zig]] = z;
+ // b[Unzig[zig]] = z;
Block8x8F.SetScalarAt(b, unzigPtr[zig], z);
}
}
@@ -1964,12 +2010,12 @@ namespace ImageSharp.Formats
if (bu >= 0)
{
- //b[u] += delta;
+ // b[u] += delta;
Block8x8F.SetScalarAt(b, u, bu + delta);
}
else
{
- //b[u] -= delta;
+ // b[u] -= delta;
Block8x8F.SetScalarAt(b, u, bu - delta);
}
}
@@ -2056,30 +2102,6 @@ namespace ImageSharp.Formats
&& this.componentArray[2].Identifier == 'B';
}
- ///
- /// Optimized method to pack bytes to the image from the YCbCr color space.
- /// This is faster than implicit casting as it avoids double packing.
- ///
- /// The pixel format.
- /// The packed format. uint, long, float.
- /// The packed pixel.
- /// The y luminance component.
- /// The cb chroma component.
- /// The cr chroma component.
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- private static void PackYcbCr(ref TColor packed, byte y, byte cb, byte cr)
- where TColor : struct, IPackedPixel where TPacked : struct
- {
- int ccb = cb - 128;
- int ccr = cr - 128;
-
- byte r = (byte)(y + (1.402F * ccr)).Clamp(0, 255);
- byte g = (byte)(y - (0.34414F * ccb) - (0.71414F * ccr)).Clamp(0, 255);
- byte b = (byte)(y + (1.772F * ccb)).Clamp(0, 255);
-
- packed.PackFromBytes(r, g, b, 255);
- }
-
///
/// Optimized method to pack bytes to the image from the CMYK color space.
/// This is faster than implicit casting as it avoids double packing.
@@ -2093,7 +2115,8 @@ namespace ImageSharp.Formats
/// The x-position within the image.
/// The y-position within the image.
private void PackCmyk(ref TColor packed, byte y, byte cb, byte cr, int xx, int yy)
- where TColor : struct, IPackedPixel where TPacked : struct
+ where TColor : struct, IPackedPixel
+ where TPacked : struct
{
// TODO: We can speed this up further with Vector4
int ccb = cb - 128;
@@ -2136,15 +2159,9 @@ namespace ImageSharp.Formats
public byte AcTableSelector { get; set; }
}
- ///
- /// ReadByteStuffedByte was throwing exceptions on normal execution path (very inefficent)
- /// It's better tho have an error code for this!
- ///
- internal enum ErrorCodes
+ private struct StackallocUnzigData
{
- NoError,
- // ReSharper disable once InconsistentNaming
- MissingFF00
+ internal fixed int Data[64];
}
///
@@ -2154,13 +2171,6 @@ namespace ImageSharp.Formats
{
}
- ///
- /// The short huffman data exception.
- ///
- private class ShortHuffmanDataException : Exception
- {
- }
-
///
/// The EOF (End of File exception).
/// Thrown when the decoder encounters an EOF marker without a proceeding EOI (End Of Image) marker
@@ -2169,14 +2179,11 @@ namespace ImageSharp.Formats
{
}
- public void Dispose()
+ ///
+ /// The short huffman data exception.
+ ///
+ private class ShortHuffmanDataException : Exception
{
- for (int i = 0; i < this.huffmanTrees.Length; i++)
- {
- this.huffmanTrees[i].Dispose();
- }
-
- this.bytes.Dispose();
}
}
}
diff --git a/src/ImageSharp/Formats/Jpg/JpegEncoderCore.cs b/src/ImageSharp/Formats/Jpg/JpegEncoderCore.cs
index c813c2cb7..c0a6a765b 100644
--- a/src/ImageSharp/Formats/Jpg/JpegEncoderCore.cs
+++ b/src/ImageSharp/Formats/Jpg/JpegEncoderCore.cs
@@ -540,13 +540,10 @@ namespace ImageSharp.Formats
/// The luminance block.
/// The red chroma block.
/// The blue chroma block.
- // ReSharper disable StyleCop.SA1305
private void ToYCbCr(PixelAccessor pixels, int x, int y, ref Block yBlock, ref Block cbBlock, ref Block crBlock)
where TColor : struct, IPackedPixel
where TPacked : struct
{
-
- // ReSharper restore StyleCop.SA1305
int xmax = pixels.Width - 1;
int ymax = pixels.Height - 1;
byte[] color = new byte[3];