Browse Source

Rename Golang decoder components

pull/571/head
James Jackson-South 8 years ago
parent
commit
d610c59d5c
  1. 36
      src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/Bits.cs
  2. 54
      src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/Bytes.cs
  3. 28
      src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/DecoderThrowHelper.cs
  4. 6
      src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/GolangComponent.cs
  5. 2
      src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/GolangComponentScan.cs
  6. 2
      src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/GolangDecoderErrorCode.cs
  7. 12
      src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/GolangHuffmanTree.cs
  8. 4
      src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/GolangJpegScanDecoder.ComputationData.cs
  9. 6
      src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/GolangJpegScanDecoder.DataPointers.cs
  10. 34
      src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/GolangJpegScanDecoder.cs
  11. 68
      src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/InputProcessor.cs
  12. 26
      src/ImageSharp/Formats/Jpeg/GolangPort/GolangJpegDecoderCore.cs
  13. 5
      src/ImageSharp/Formats/Jpeg/GolangPort/JpegEncoderCore.cs
  14. 14
      tests/ImageSharp.Tests/Formats/Jpg/ParseStreamTests.cs
  15. 2
      tests/ImageSharp.Tests/Formats/Jpg/Utils/LibJpegTools.ComponentData.cs
  16. 2
      tests/ImageSharp.Tests/Formats/Jpg/Utils/LibJpegTools.SpectralData.cs

36
src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/Bits.cs

@ -38,7 +38,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void EnsureNBits(int n, ref InputProcessor inputProcessor) public void EnsureNBits(int n, ref InputProcessor inputProcessor)
{ {
OrigDecoderErrorCode errorCode = this.EnsureNBitsUnsafe(n, ref inputProcessor); GolangDecoderErrorCode errorCode = this.EnsureNBitsUnsafe(n, ref inputProcessor);
errorCode.EnsureNoError(); errorCode.EnsureNoError();
} }
@ -46,17 +46,17 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
/// Reads bytes from the byte buffer to ensure that bits.UnreadBits is at /// Reads bytes from the byte buffer to ensure that bits.UnreadBits is at
/// least n. For best performance (avoiding function calls inside hot loops), /// least n. For best performance (avoiding function calls inside hot loops),
/// the caller is the one responsible for first checking that bits.UnreadBits < n. /// the caller is the one responsible for first checking that bits.UnreadBits < n.
/// This method does not throw. Returns <see cref="OrigDecoderErrorCode"/> instead. /// This method does not throw. Returns <see cref="GolangDecoderErrorCode"/> instead.
/// </summary> /// </summary>
/// <param name="n">The number of bits to ensure.</param> /// <param name="n">The number of bits to ensure.</param>
/// <param name="inputProcessor">The <see cref="InputProcessor"/></param> /// <param name="inputProcessor">The <see cref="InputProcessor"/></param>
/// <returns>Error code</returns> /// <returns>Error code</returns>
public OrigDecoderErrorCode EnsureNBitsUnsafe(int n, ref InputProcessor inputProcessor) public GolangDecoderErrorCode EnsureNBitsUnsafe(int n, ref InputProcessor inputProcessor)
{ {
while (true) while (true)
{ {
OrigDecoderErrorCode errorCode = this.EnsureBitsStepImpl(ref inputProcessor); GolangDecoderErrorCode errorCode = this.EnsureBitsStepImpl(ref inputProcessor);
if (errorCode != OrigDecoderErrorCode.NoError || this.UnreadBits >= n) if (errorCode != GolangDecoderErrorCode.NoError || this.UnreadBits >= n)
{ {
return errorCode; return errorCode;
} }
@ -67,8 +67,8 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
/// Unrolled version of <see cref="EnsureNBitsUnsafe"/> for n==8 /// Unrolled version of <see cref="EnsureNBitsUnsafe"/> for n==8
/// </summary> /// </summary>
/// <param name="inputProcessor">The <see cref="InputProcessor"/></param> /// <param name="inputProcessor">The <see cref="InputProcessor"/></param>
/// <returns>A <see cref="OrigDecoderErrorCode"/></returns> /// <returns>A <see cref="GolangDecoderErrorCode"/></returns>
public OrigDecoderErrorCode Ensure8BitsUnsafe(ref InputProcessor inputProcessor) public GolangDecoderErrorCode Ensure8BitsUnsafe(ref InputProcessor inputProcessor)
{ {
return this.EnsureBitsStepImpl(ref inputProcessor); return this.EnsureBitsStepImpl(ref inputProcessor);
} }
@ -77,8 +77,8 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
/// Unrolled version of <see cref="EnsureNBitsUnsafe"/> for n==1 /// Unrolled version of <see cref="EnsureNBitsUnsafe"/> for n==1
/// </summary> /// </summary>
/// <param name="inputProcessor">The <see cref="InputProcessor"/></param> /// <param name="inputProcessor">The <see cref="InputProcessor"/></param>
/// <returns>A <see cref="OrigDecoderErrorCode"/></returns> /// <returns>A <see cref="GolangDecoderErrorCode"/></returns>
public OrigDecoderErrorCode Ensure1BitUnsafe(ref InputProcessor inputProcessor) public GolangDecoderErrorCode Ensure1BitUnsafe(ref InputProcessor inputProcessor)
{ {
return this.EnsureBitsStepImpl(ref inputProcessor); return this.EnsureBitsStepImpl(ref inputProcessor);
} }
@ -92,7 +92,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public int ReceiveExtend(int t, ref InputProcessor inputProcessor) public int ReceiveExtend(int t, ref InputProcessor inputProcessor)
{ {
OrigDecoderErrorCode errorCode = this.ReceiveExtendUnsafe(t, ref inputProcessor, out int x); GolangDecoderErrorCode errorCode = this.ReceiveExtendUnsafe(t, ref inputProcessor, out int x);
errorCode.EnsureNoError(); errorCode.EnsureNoError();
return x; return x;
} }
@ -103,13 +103,13 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
/// <param name="t">Byte</param> /// <param name="t">Byte</param>
/// <param name="inputProcessor">The <see cref="InputProcessor"/></param> /// <param name="inputProcessor">The <see cref="InputProcessor"/></param>
/// <param name="x">Read bits value</param> /// <param name="x">Read bits value</param>
/// <returns>The <see cref="OrigDecoderErrorCode"/></returns> /// <returns>The <see cref="GolangDecoderErrorCode"/></returns>
public OrigDecoderErrorCode ReceiveExtendUnsafe(int t, ref InputProcessor inputProcessor, out int x) public GolangDecoderErrorCode ReceiveExtendUnsafe(int t, ref InputProcessor inputProcessor, out int x)
{ {
if (this.UnreadBits < t) if (this.UnreadBits < t)
{ {
OrigDecoderErrorCode errorCode = this.EnsureNBitsUnsafe(t, ref inputProcessor); GolangDecoderErrorCode errorCode = this.EnsureNBitsUnsafe(t, ref inputProcessor);
if (errorCode != OrigDecoderErrorCode.NoError) if (errorCode != GolangDecoderErrorCode.NoError)
{ {
x = int.MaxValue; x = int.MaxValue;
return errorCode; return errorCode;
@ -126,14 +126,14 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
x += ((-1) << t) + 1; x += ((-1) << t) + 1;
} }
return OrigDecoderErrorCode.NoError; return GolangDecoderErrorCode.NoError;
} }
private OrigDecoderErrorCode EnsureBitsStepImpl(ref InputProcessor inputProcessor) private GolangDecoderErrorCode EnsureBitsStepImpl(ref InputProcessor inputProcessor)
{ {
OrigDecoderErrorCode errorCode = inputProcessor.Bytes.ReadByteStuffedByteUnsafe(inputProcessor.InputStream, out int c); GolangDecoderErrorCode errorCode = inputProcessor.Bytes.ReadByteStuffedByteUnsafe(inputProcessor.InputStream, out int c);
if (errorCode != OrigDecoderErrorCode.NoError) if (errorCode != GolangDecoderErrorCode.NoError)
{ {
return errorCode; return errorCode;
} }

54
src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/Bytes.cs

@ -79,8 +79,8 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
/// </summary> /// </summary>
/// <param name="inputStream">Input stream</param> /// <param name="inputStream">Input stream</param>
/// <param name="x">The result byte as <see cref="int"/></param> /// <param name="x">The result byte as <see cref="int"/></param>
/// <returns>The <see cref="OrigDecoderErrorCode"/></returns> /// <returns>The <see cref="GolangDecoderErrorCode"/></returns>
public OrigDecoderErrorCode ReadByteStuffedByteUnsafe(Stream inputStream, out int x) public GolangDecoderErrorCode ReadByteStuffedByteUnsafe(Stream inputStream, out int x)
{ {
// Take the fast path if bytes.buf contains at least two bytes. // Take the fast path if bytes.buf contains at least two bytes.
if (this.I + 2 <= this.J) if (this.I + 2 <= this.J)
@ -90,48 +90,48 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
this.UnreadableBytes = 1; this.UnreadableBytes = 1;
if (x != JpegConstants.Markers.XFFInt) if (x != JpegConstants.Markers.XFFInt)
{ {
return OrigDecoderErrorCode.NoError; return GolangDecoderErrorCode.NoError;
} }
if (this.BufferAsInt[this.I] != 0x00) if (this.BufferAsInt[this.I] != 0x00)
{ {
return OrigDecoderErrorCode.MissingFF00; return GolangDecoderErrorCode.MissingFF00;
} }
this.I++; this.I++;
this.UnreadableBytes = 2; this.UnreadableBytes = 2;
x = JpegConstants.Markers.XFF; x = JpegConstants.Markers.XFF;
return OrigDecoderErrorCode.NoError; return GolangDecoderErrorCode.NoError;
} }
this.UnreadableBytes = 0; this.UnreadableBytes = 0;
OrigDecoderErrorCode errorCode = this.ReadByteAsIntUnsafe(inputStream, out x); GolangDecoderErrorCode errorCode = this.ReadByteAsIntUnsafe(inputStream, out x);
this.UnreadableBytes = 1; this.UnreadableBytes = 1;
if (errorCode != OrigDecoderErrorCode.NoError) if (errorCode != GolangDecoderErrorCode.NoError)
{ {
return errorCode; return errorCode;
} }
if (x != JpegConstants.Markers.XFF) if (x != JpegConstants.Markers.XFF)
{ {
return OrigDecoderErrorCode.NoError; return GolangDecoderErrorCode.NoError;
} }
errorCode = this.ReadByteAsIntUnsafe(inputStream, out x); errorCode = this.ReadByteAsIntUnsafe(inputStream, out x);
this.UnreadableBytes = 2; this.UnreadableBytes = 2;
if (errorCode != OrigDecoderErrorCode.NoError) if (errorCode != GolangDecoderErrorCode.NoError)
{ {
return errorCode; return errorCode;
} }
if (x != 0x00) if (x != 0x00)
{ {
return OrigDecoderErrorCode.MissingFF00; return GolangDecoderErrorCode.MissingFF00;
} }
x = JpegConstants.Markers.XFF; x = JpegConstants.Markers.XFF;
return OrigDecoderErrorCode.NoError; return GolangDecoderErrorCode.NoError;
} }
/// <summary> /// <summary>
@ -142,25 +142,25 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public byte ReadByte(Stream inputStream) public byte ReadByte(Stream inputStream)
{ {
OrigDecoderErrorCode errorCode = this.ReadByteUnsafe(inputStream, out byte result); GolangDecoderErrorCode errorCode = this.ReadByteUnsafe(inputStream, out byte result);
errorCode.EnsureNoError(); errorCode.EnsureNoError();
return result; return result;
} }
/// <summary> /// <summary>
/// Extracts the next byte, whether buffered or not buffered into the result out parameter. It does not care about byte stuffing. /// Extracts the next byte, whether buffered or not buffered into the result out parameter. It does not care about byte stuffing.
/// This method does not throw on format error, it returns a <see cref="OrigDecoderErrorCode"/> instead. /// This method does not throw on format error, it returns a <see cref="GolangDecoderErrorCode"/> instead.
/// </summary> /// </summary>
/// <param name="inputStream">Input stream</param> /// <param name="inputStream">Input stream</param>
/// <param name="result">The result <see cref="byte"/> as out parameter</param> /// <param name="result">The result <see cref="byte"/> as out parameter</param>
/// <returns>The <see cref="OrigDecoderErrorCode"/></returns> /// <returns>The <see cref="GolangDecoderErrorCode"/></returns>
public OrigDecoderErrorCode ReadByteUnsafe(Stream inputStream, out byte result) public GolangDecoderErrorCode ReadByteUnsafe(Stream inputStream, out byte result)
{ {
OrigDecoderErrorCode errorCode = OrigDecoderErrorCode.NoError; GolangDecoderErrorCode errorCode = GolangDecoderErrorCode.NoError;
while (this.I == this.J) while (this.I == this.J)
{ {
errorCode = this.FillUnsafe(inputStream); errorCode = this.FillUnsafe(inputStream);
if (errorCode != OrigDecoderErrorCode.NoError) if (errorCode != GolangDecoderErrorCode.NoError)
{ {
result = 0; result = 0;
return errorCode; return errorCode;
@ -178,15 +178,15 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
/// </summary> /// </summary>
/// <param name="inputStream">The input stream</param> /// <param name="inputStream">The input stream</param>
/// <param name="result">The result <see cref="int"/></param> /// <param name="result">The result <see cref="int"/></param>
/// <returns>A <see cref="OrigDecoderErrorCode"/></returns> /// <returns>A <see cref="GolangDecoderErrorCode"/></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public OrigDecoderErrorCode ReadByteAsIntUnsafe(Stream inputStream, out int result) public GolangDecoderErrorCode ReadByteAsIntUnsafe(Stream inputStream, out int result)
{ {
OrigDecoderErrorCode errorCode = OrigDecoderErrorCode.NoError; GolangDecoderErrorCode errorCode = GolangDecoderErrorCode.NoError;
while (this.I == this.J) while (this.I == this.J)
{ {
errorCode = this.FillUnsafe(inputStream); errorCode = this.FillUnsafe(inputStream);
if (errorCode != OrigDecoderErrorCode.NoError) if (errorCode != GolangDecoderErrorCode.NoError)
{ {
result = 0; result = 0;
return errorCode; return errorCode;
@ -208,18 +208,18 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Fill(Stream inputStream) public void Fill(Stream inputStream)
{ {
OrigDecoderErrorCode errorCode = this.FillUnsafe(inputStream); GolangDecoderErrorCode errorCode = this.FillUnsafe(inputStream);
errorCode.EnsureNoError(); errorCode.EnsureNoError();
} }
/// <summary> /// <summary>
/// Fills up the bytes buffer from the underlying stream. /// Fills up the bytes buffer from the underlying stream.
/// It should only be called when there are no unread bytes in bytes. /// It should only be called when there are no unread bytes in bytes.
/// This method does not throw <see cref="EOFException"/>, returns a <see cref="OrigDecoderErrorCode"/> instead! /// This method does not throw <see cref="EOFException"/>, returns a <see cref="GolangDecoderErrorCode"/> instead!
/// </summary> /// </summary>
/// <param name="inputStream">Input stream</param> /// <param name="inputStream">Input stream</param>
/// <returns>The <see cref="OrigDecoderErrorCode"/></returns> /// <returns>The <see cref="GolangDecoderErrorCode"/></returns>
public OrigDecoderErrorCode FillUnsafe(Stream inputStream) public GolangDecoderErrorCode FillUnsafe(Stream inputStream)
{ {
if (this.I != this.J) if (this.I != this.J)
{ {
@ -241,7 +241,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
int n = inputStream.Read(this.Buffer, this.J, this.Buffer.Length - this.J); int n = inputStream.Read(this.Buffer, this.J, this.Buffer.Length - this.J);
if (n == 0) if (n == 0)
{ {
return OrigDecoderErrorCode.UnexpectedEndOfStream; return GolangDecoderErrorCode.UnexpectedEndOfStream;
} }
this.J += n; this.J += n;
@ -251,7 +251,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
this.BufferAsInt[i] = this.Buffer[i]; this.BufferAsInt[i] = this.Buffer[i];
} }
return OrigDecoderErrorCode.NoError; return GolangDecoderErrorCode.NoError;
} }
} }
} }

28
src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/DecoderThrowHelper.cs

@ -12,22 +12,22 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
internal static class DecoderThrowHelper internal static class DecoderThrowHelper
{ {
/// <summary> /// <summary>
/// Throws an exception that belongs to the given <see cref="OrigDecoderErrorCode"/> /// Throws an exception that belongs to the given <see cref="GolangDecoderErrorCode"/>
/// </summary> /// </summary>
/// <param name="errorCode">The <see cref="OrigDecoderErrorCode"/></param> /// <param name="errorCode">The <see cref="GolangDecoderErrorCode"/></param>
[MethodImpl(MethodImplOptions.NoInlining)] [MethodImpl(MethodImplOptions.NoInlining)]
public static void ThrowExceptionForErrorCode(this OrigDecoderErrorCode errorCode) public static void ThrowExceptionForErrorCode(this GolangDecoderErrorCode errorCode)
{ {
// REMARK: If this method throws for an image that is expected to be decodable, // REMARK: If this method throws for an image that is expected to be decodable,
// consider using the ***Unsafe variant of the parsing method that asks for ThrowExceptionForErrorCode() // consider using the ***Unsafe variant of the parsing method that asks for ThrowExceptionForErrorCode()
// then verify the error code + implement fallback logic manually! // then verify the error code + implement fallback logic manually!
switch (errorCode) switch (errorCode)
{ {
case OrigDecoderErrorCode.NoError: case GolangDecoderErrorCode.NoError:
throw new ArgumentException("ThrowExceptionForErrorCode() called with NoError!", nameof(errorCode)); throw new ArgumentException("ThrowExceptionForErrorCode() called with NoError!", nameof(errorCode));
case OrigDecoderErrorCode.MissingFF00: case GolangDecoderErrorCode.MissingFF00:
throw new MissingFF00Exception(); throw new MissingFF00Exception();
case OrigDecoderErrorCode.UnexpectedEndOfStream: case GolangDecoderErrorCode.UnexpectedEndOfStream:
throw new EOFException(); throw new EOFException();
default: default:
throw new ArgumentOutOfRangeException(nameof(errorCode), errorCode, null); throw new ArgumentOutOfRangeException(nameof(errorCode), errorCode, null);
@ -35,26 +35,26 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
} }
/// <summary> /// <summary>
/// Throws an exception if the given <see cref="OrigDecoderErrorCode"/> defines an error. /// Throws an exception if the given <see cref="GolangDecoderErrorCode"/> defines an error.
/// </summary> /// </summary>
/// <param name="errorCode">The <see cref="OrigDecoderErrorCode"/></param> /// <param name="errorCode">The <see cref="GolangDecoderErrorCode"/></param>
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void EnsureNoError(this OrigDecoderErrorCode errorCode) public static void EnsureNoError(this GolangDecoderErrorCode errorCode)
{ {
if (errorCode != OrigDecoderErrorCode.NoError) if (errorCode != GolangDecoderErrorCode.NoError)
{ {
ThrowExceptionForErrorCode(errorCode); ThrowExceptionForErrorCode(errorCode);
} }
} }
/// <summary> /// <summary>
/// Throws an exception if the given <see cref="OrigDecoderErrorCode"/> is <see cref="OrigDecoderErrorCode.UnexpectedEndOfStream"/>. /// Throws an exception if the given <see cref="GolangDecoderErrorCode"/> is <see cref="GolangDecoderErrorCode.UnexpectedEndOfStream"/>.
/// </summary> /// </summary>
/// <param name="errorCode">The <see cref="OrigDecoderErrorCode"/></param> /// <param name="errorCode">The <see cref="GolangDecoderErrorCode"/></param>
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void EnsureNoEOF(this OrigDecoderErrorCode errorCode) public static void EnsureNoEOF(this GolangDecoderErrorCode errorCode)
{ {
if (errorCode == OrigDecoderErrorCode.UnexpectedEndOfStream) if (errorCode == GolangDecoderErrorCode.UnexpectedEndOfStream)
{ {
errorCode.ThrowExceptionForErrorCode(); errorCode.ThrowExceptionForErrorCode();
} }

6
src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OrigComponent.cs → src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/GolangComponent.cs

@ -14,9 +14,9 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
/// <summary> /// <summary>
/// Represents a single color component /// Represents a single color component
/// </summary> /// </summary>
internal class OrigComponent : IDisposable, IJpegComponent internal class GolangComponent : IDisposable, IJpegComponent
{ {
public OrigComponent(byte identifier, int index) public GolangComponent(byte identifier, int index)
{ {
this.Identifier = identifier; this.Identifier = identifier;
this.Index = index; this.Index = index;
@ -76,7 +76,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
} }
else else
{ {
OrigComponent c0 = decoder.Components[0]; GolangComponent c0 = decoder.Components[0];
this.SubSamplingDivisors = c0.SamplingFactors.DivideBy(this.SamplingFactors); this.SubSamplingDivisors = c0.SamplingFactors.DivideBy(this.SamplingFactors);
} }

2
src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OrigComponentScan.cs → src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/GolangComponentScan.cs

@ -9,7 +9,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
/// Represents a component scan /// Represents a component scan
/// </summary> /// </summary>
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
internal struct OrigComponentScan internal struct GolangComponentScan
{ {
/// <summary> /// <summary>
/// Gets or sets the component index. /// Gets or sets the component index.

2
src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OrigDecoderErrorCode.cs → src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/GolangDecoderErrorCode.cs

@ -6,7 +6,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
/// <summary> /// <summary>
/// Represents "recoverable" decoder errors. /// Represents "recoverable" decoder errors.
/// </summary> /// </summary>
internal enum OrigDecoderErrorCode internal enum GolangDecoderErrorCode
{ {
/// <summary> /// <summary>
/// NoError /// NoError

12
src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OrigHuffmanTree.cs → src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/GolangHuffmanTree.cs

@ -1,8 +1,6 @@
// Copyright (c) Six Labors and contributors. // Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0. // Licensed under the Apache License, Version 2.0.
using System;
using System.Buffers;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
@ -12,7 +10,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
/// Represents a Huffman tree /// Represents a Huffman tree
/// </summary> /// </summary>
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
internal unsafe struct OrigHuffmanTree internal unsafe struct GolangHuffmanTree
{ {
/// <summary> /// <summary>
/// The index of the AC table row /// The index of the AC table row
@ -95,12 +93,12 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
public FixedInt32Buffer16 Indices; public FixedInt32Buffer16 Indices;
/// <summary> /// <summary>
/// Creates and initializes an array of <see cref="OrigHuffmanTree" /> instances of size <see cref="NumberOfTrees" /> /// Creates and initializes an array of <see cref="GolangHuffmanTree" /> instances of size <see cref="NumberOfTrees" />
/// </summary> /// </summary>
/// <returns>An array of <see cref="OrigHuffmanTree" /> instances representing the Huffman tables</returns> /// <returns>An array of <see cref="GolangHuffmanTree" /> instances representing the Huffman tables</returns>
public static OrigHuffmanTree[] CreateHuffmanTrees() public static GolangHuffmanTree[] CreateHuffmanTrees()
{ {
return new OrigHuffmanTree[NumberOfTrees]; return new GolangHuffmanTree[NumberOfTrees];
} }
/// <summary> /// <summary>

4
src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OrigJpegScanDecoder.ComputationData.cs → src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/GolangJpegScanDecoder.ComputationData.cs

@ -9,7 +9,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
/// <content> /// <content>
/// Conains the definition of <see cref="ComputationData"/> /// Conains the definition of <see cref="ComputationData"/>
/// </content> /// </content>
internal unsafe partial struct OrigJpegScanDecoder internal unsafe partial struct GolangJpegScanDecoder
{ {
/// <summary> /// <summary>
/// Holds the "large" data blocks needed for computations. /// Holds the "large" data blocks needed for computations.
@ -28,7 +28,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
public ZigZag Unzig; public ZigZag Unzig;
/// <summary> /// <summary>
/// The buffer storing the <see cref="OrigComponentScan"/>-s for each component /// The buffer storing the <see cref="GolangComponentScan"/>-s for each component
/// </summary> /// </summary>
public fixed byte ScanData[3 * GolangJpegDecoderCore.MaxComponents]; public fixed byte ScanData[3 * GolangJpegDecoderCore.MaxComponents];

6
src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OrigJpegScanDecoder.DataPointers.cs → src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/GolangJpegScanDecoder.DataPointers.cs

@ -8,7 +8,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
/// <content> /// <content>
/// Conains the definition of <see cref="DataPointers"/> /// Conains the definition of <see cref="DataPointers"/>
/// </content> /// </content>
internal unsafe partial struct OrigJpegScanDecoder internal unsafe partial struct GolangJpegScanDecoder
{ {
/// <summary> /// <summary>
/// Contains pointers to the memory regions of <see cref="ComputationData"/> so they can be easily passed around to pointer based utility methods of <see cref="Block8x8F"/> /// Contains pointers to the memory regions of <see cref="ComputationData"/> so they can be easily passed around to pointer based utility methods of <see cref="Block8x8F"/>
@ -28,7 +28,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
/// <summary> /// <summary>
/// Pointer to <see cref="ComputationData.ScanData"/> as Scan* /// Pointer to <see cref="ComputationData.ScanData"/> as Scan*
/// </summary> /// </summary>
public OrigComponentScan* ComponentScan; public GolangComponentScan* ComponentScan;
/// <summary> /// <summary>
/// Pointer to <see cref="ComputationData.Dc"/> /// Pointer to <see cref="ComputationData.Dc"/>
@ -43,7 +43,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
{ {
this.Block = &basePtr->Block; this.Block = &basePtr->Block;
this.Unzig = basePtr->Unzig.Data; this.Unzig = basePtr->Unzig.Data;
this.ComponentScan = (OrigComponentScan*)basePtr->ScanData; this.ComponentScan = (GolangComponentScan*)basePtr->ScanData;
this.Dc = basePtr->Dc; this.Dc = basePtr->Dc;
} }
} }

34
src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OrigJpegScanDecoder.cs → src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/GolangJpegScanDecoder.cs

@ -4,8 +4,6 @@
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using SixLabors.ImageSharp.Formats.Jpeg.Common; using SixLabors.ImageSharp.Formats.Jpeg.Common;
using SixLabors.ImageSharp.Formats.Jpeg.Common.Decoder;
using SixLabors.ImageSharp.Memory;
// ReSharper disable InconsistentNaming // ReSharper disable InconsistentNaming
namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
@ -29,7 +27,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
/// For baseline JPEGs, these parameters are hard-coded to 0/63/0/0. /// For baseline JPEGs, these parameters are hard-coded to 0/63/0/0.
/// </summary> /// </summary>
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
internal unsafe partial struct OrigJpegScanDecoder internal unsafe partial struct GolangJpegScanDecoder
{ {
// The JpegScanDecoder members should be ordered in a way that results in optimal memory layout. // The JpegScanDecoder members should be ordered in a way that results in optimal memory layout.
#pragma warning disable SA1202 // ElementsMustBeOrderedByAccess #pragma warning disable SA1202 // ElementsMustBeOrderedByAccess
@ -110,12 +108,12 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
private byte expectedRst; private byte expectedRst;
/// <summary> /// <summary>
/// Initializes a default-constructed <see cref="OrigJpegScanDecoder"/> instance for reading data from <see cref="GolangJpegDecoderCore"/>-s stream. /// Initializes a default-constructed <see cref="GolangJpegScanDecoder"/> instance for reading data from <see cref="GolangJpegDecoderCore"/>-s stream.
/// </summary> /// </summary>
/// <param name="p">Pointer to <see cref="OrigJpegScanDecoder"/> on the stack</param> /// <param name="p">Pointer to <see cref="GolangJpegScanDecoder"/> on the stack</param>
/// <param name="decoder">The <see cref="GolangJpegDecoderCore"/> instance</param> /// <param name="decoder">The <see cref="GolangJpegDecoderCore"/> instance</param>
/// <param name="remaining">The remaining bytes in the segment block.</param> /// <param name="remaining">The remaining bytes in the segment block.</param>
public static void InitStreamReading(OrigJpegScanDecoder* p, GolangJpegDecoderCore decoder, int remaining) public static void InitStreamReading(GolangJpegScanDecoder* p, GolangJpegDecoderCore decoder, int remaining)
{ {
p->data = ComputationData.Create(); p->data = ComputationData.Create();
p->pointers = new DataPointers(&p->data); p->pointers = new DataPointers(&p->data);
@ -124,7 +122,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
/// <summary> /// <summary>
/// Read Huffman data from Jpeg scans in <see cref="GolangJpegDecoderCore.InputStream"/>, /// Read Huffman data from Jpeg scans in <see cref="GolangJpegDecoderCore.InputStream"/>,
/// and decode it as <see cref="Block8x8"/> into <see cref="OrigComponent.SpectralBlocks"/>. /// and decode it as <see cref="Block8x8"/> into <see cref="GolangComponent.SpectralBlocks"/>.
/// ///
/// The blocks are traversed one MCU at a time. For 4:2:0 chroma /// The blocks are traversed one MCU at a time. For 4:2:0 chroma
/// subsampling, there are four Y 8x8 blocks in every 16x16 MCU. /// subsampling, there are four Y 8x8 blocks in every 16x16 MCU.
@ -182,7 +180,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
for (int scanIndex = 0; scanIndex < this.componentScanCount; scanIndex++) for (int scanIndex = 0; scanIndex < this.componentScanCount; scanIndex++)
{ {
this.ComponentIndex = this.pointers.ComponentScan[scanIndex].ComponentIndex; this.ComponentIndex = this.pointers.ComponentScan[scanIndex].ComponentIndex;
OrigComponent component = decoder.Components[this.ComponentIndex]; GolangComponent component = decoder.Components[this.ComponentIndex];
this.hi = component.HorizontalSamplingFactor; this.hi = component.HorizontalSamplingFactor;
int vi = component.VerticalSamplingFactor; int vi = component.VerticalSamplingFactor;
@ -285,7 +283,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
/// </summary> /// </summary>
private void ResetDcValues() private void ResetDcValues()
{ {
Unsafe.InitBlock(this.pointers.Dc, default(byte), sizeof(int) * GolangJpegDecoderCore.MaxComponents); Unsafe.InitBlock(this.pointers.Dc, default, sizeof(int) * GolangJpegDecoderCore.MaxComponents);
} }
/// <summary> /// <summary>
@ -363,7 +361,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
private void DecodeBlock(GolangJpegDecoderCore decoder, int scanIndex) private void DecodeBlock(GolangJpegDecoderCore decoder, int scanIndex)
{ {
Block8x8* b = this.pointers.Block; Block8x8* b = this.pointers.Block;
int huffmannIdx = (OrigHuffmanTree.AcTableIndex * OrigHuffmanTree.ThRowSize) + this.pointers.ComponentScan[scanIndex].AcTableSelector; int huffmannIdx = (GolangHuffmanTree.AcTableIndex * GolangHuffmanTree.ThRowSize) + this.pointers.ComponentScan[scanIndex].AcTableSelector;
if (this.ah != 0) if (this.ah != 0)
{ {
this.Refine(ref decoder.InputProcessor, ref decoder.HuffmanTrees[huffmannIdx], 1 << this.al); this.Refine(ref decoder.InputProcessor, ref decoder.HuffmanTrees[huffmannIdx], 1 << this.al);
@ -377,7 +375,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
zig++; zig++;
// Decode the DC coefficient, as specified in section F.2.2.1. // Decode the DC coefficient, as specified in section F.2.2.1.
int huffmanIndex = (OrigHuffmanTree.DcTableIndex * OrigHuffmanTree.ThRowSize) + this.pointers.ComponentScan[scanIndex].DcTableSelector; int huffmanIndex = (GolangHuffmanTree.DcTableIndex * GolangHuffmanTree.ThRowSize) + this.pointers.ComponentScan[scanIndex].DcTableSelector;
decoder.InputProcessor.DecodeHuffmanUnsafe( decoder.InputProcessor.DecodeHuffmanUnsafe(
ref decoder.HuffmanTrees[huffmanIndex], ref decoder.HuffmanTrees[huffmanIndex],
out int value); out int value);
@ -467,7 +465,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
private void DecodeEobRun(int count, ref InputProcessor processor) private void DecodeEobRun(int count, ref InputProcessor processor)
{ {
processor.DecodeBitsUnsafe(count, out int bitsResult); processor.DecodeBitsUnsafe(count, out int bitsResult);
if (processor.LastErrorCode != OrigDecoderErrorCode.NoError) if (processor.LastErrorCode != GolangDecoderErrorCode.NoError)
{ {
return; return;
} }
@ -475,7 +473,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
this.eobRun |= bitsResult; this.eobRun |= bitsResult;
} }
private void InitComponentScan(GolangJpegDecoderCore decoder, int i, ref OrigComponentScan currentComponentScan, ref int totalHv) private void InitComponentScan(GolangJpegDecoderCore decoder, int i, ref GolangComponentScan currentComponentScan, ref int totalHv)
{ {
// Component selector. // Component selector.
int cs = decoder.Temp[1 + (2 * i)]; int cs = decoder.Temp[1 + (2 * i)];
@ -502,9 +500,9 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
private void ProcessComponentImpl( private void ProcessComponentImpl(
GolangJpegDecoderCore decoder, GolangJpegDecoderCore decoder,
int i, int i,
ref OrigComponentScan currentComponentScan, ref GolangComponentScan currentComponentScan,
ref int totalHv, ref int totalHv,
OrigComponent currentComponent) GolangComponent currentComponent)
{ {
// Section B.2.3 states that "the value of Cs_j shall be different from // Section B.2.3 states that "the value of Cs_j shall be different from
// the values of Cs_1 through Cs_(j-1)". Since we have previously // the values of Cs_1 through Cs_(j-1)". Since we have previously
@ -522,13 +520,13 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
totalHv += currentComponent.HorizontalSamplingFactor * currentComponent.VerticalSamplingFactor; totalHv += currentComponent.HorizontalSamplingFactor * currentComponent.VerticalSamplingFactor;
currentComponentScan.DcTableSelector = (byte)(decoder.Temp[2 + (2 * i)] >> 4); currentComponentScan.DcTableSelector = (byte)(decoder.Temp[2 + (2 * i)] >> 4);
if (currentComponentScan.DcTableSelector > OrigHuffmanTree.MaxTh) if (currentComponentScan.DcTableSelector > GolangHuffmanTree.MaxTh)
{ {
throw new ImageFormatException("Bad DC table selector value"); throw new ImageFormatException("Bad DC table selector value");
} }
currentComponentScan.AcTableSelector = (byte)(decoder.Temp[2 + (2 * i)] & 0x0f); currentComponentScan.AcTableSelector = (byte)(decoder.Temp[2 + (2 * i)] & 0x0f);
if (currentComponentScan.AcTableSelector > OrigHuffmanTree.MaxTh) if (currentComponentScan.AcTableSelector > GolangHuffmanTree.MaxTh)
{ {
throw new ImageFormatException("Bad AC table selector value"); throw new ImageFormatException("Bad AC table selector value");
} }
@ -540,7 +538,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
/// <param name="bp">The <see cref="InputProcessor"/> instance</param> /// <param name="bp">The <see cref="InputProcessor"/> instance</param>
/// <param name="h">The Huffman tree</param> /// <param name="h">The Huffman tree</param>
/// <param name="delta">The low transform offset</param> /// <param name="delta">The low transform offset</param>
private void Refine(ref InputProcessor bp, ref OrigHuffmanTree h, int delta) private void Refine(ref InputProcessor bp, ref GolangHuffmanTree h, int delta)
{ {
Block8x8* b = this.pointers.Block; Block8x8* b = this.pointers.Block;

68
src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/InputProcessor.cs

@ -34,7 +34,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
this.Bytes = Bytes.Create(); this.Bytes = Bytes.Create();
this.InputStream = inputStream; this.InputStream = inputStream;
this.Temp = temp; this.Temp = temp;
this.LastErrorCode = OrigDecoderErrorCode.NoError; this.LastErrorCode = GolangDecoderErrorCode.NoError;
} }
/// <summary> /// <summary>
@ -50,13 +50,13 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
/// <summary> /// <summary>
/// Gets a value indicating whether an unexpected EOF reached in <see cref="InputStream"/>. /// Gets a value indicating whether an unexpected EOF reached in <see cref="InputStream"/>.
/// </summary> /// </summary>
public bool ReachedEOF => this.LastErrorCode == OrigDecoderErrorCode.UnexpectedEndOfStream; public bool ReachedEOF => this.LastErrorCode == GolangDecoderErrorCode.UnexpectedEndOfStream;
public bool HasError => this.LastErrorCode != OrigDecoderErrorCode.NoError; public bool HasError => this.LastErrorCode != GolangDecoderErrorCode.NoError;
public OrigDecoderErrorCode LastErrorCode { get; private set; } public GolangDecoderErrorCode LastErrorCode { get; private set; }
public void ResetErrorState() => this.LastErrorCode = OrigDecoderErrorCode.NoError; public void ResetErrorState() => this.LastErrorCode = GolangDecoderErrorCode.NoError;
/// <summary> /// <summary>
/// If errorCode indicates unexpected EOF, sets <see cref="ReachedEOF"/> to true and returns false. /// If errorCode indicates unexpected EOF, sets <see cref="ReachedEOF"/> to true and returns false.
@ -65,7 +65,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
/// <returns>A <see cref="bool"/> indicating whether EOF reached</returns> /// <returns>A <see cref="bool"/> indicating whether EOF reached</returns>
public bool CheckEOFEnsureNoError() public bool CheckEOFEnsureNoError()
{ {
if (this.LastErrorCode == OrigDecoderErrorCode.UnexpectedEndOfStream) if (this.LastErrorCode == GolangDecoderErrorCode.UnexpectedEndOfStream)
{ {
return false; return false;
} }
@ -81,7 +81,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
/// <returns>A <see cref="bool"/> indicating whether EOF reached</returns> /// <returns>A <see cref="bool"/> indicating whether EOF reached</returns>
public bool CheckEOF() public bool CheckEOF()
{ {
if (this.LastErrorCode == OrigDecoderErrorCode.UnexpectedEndOfStream) if (this.LastErrorCode == GolangDecoderErrorCode.UnexpectedEndOfStream)
{ {
return false; return false;
} }
@ -106,7 +106,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public OrigDecoderErrorCode ReadByteUnsafe(out byte result) public GolangDecoderErrorCode ReadByteUnsafe(out byte result)
{ {
this.LastErrorCode = this.Bytes.ReadByteUnsafe(this.InputStream, out result); this.LastErrorCode = this.Bytes.ReadByteUnsafe(this.InputStream, out result);
return this.LastErrorCode; return this.LastErrorCode;
@ -117,13 +117,13 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
/// TODO: This method (and also the usages) could be optimized by batching! /// TODO: This method (and also the usages) could be optimized by batching!
/// </summary> /// </summary>
/// <param name="result">The decoded bit as a <see cref="bool"/></param> /// <param name="result">The decoded bit as a <see cref="bool"/></param>
/// <returns>The <see cref="OrigDecoderErrorCode" /></returns> /// <returns>The <see cref="GolangDecoderErrorCode" /></returns>
public OrigDecoderErrorCode DecodeBitUnsafe(out bool result) public GolangDecoderErrorCode DecodeBitUnsafe(out bool result)
{ {
if (this.Bits.UnreadBits == 0) if (this.Bits.UnreadBits == 0)
{ {
this.LastErrorCode = this.Bits.Ensure1BitUnsafe(ref this); this.LastErrorCode = this.Bits.Ensure1BitUnsafe(ref this);
if (this.LastErrorCode != OrigDecoderErrorCode.NoError) if (this.LastErrorCode != GolangDecoderErrorCode.NoError)
{ {
result = false; result = false;
return this.LastErrorCode; return this.LastErrorCode;
@ -133,7 +133,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
result = (this.Bits.Accumulator & this.Bits.Mask) != 0; result = (this.Bits.Accumulator & this.Bits.Mask) != 0;
this.Bits.UnreadBits--; this.Bits.UnreadBits--;
this.Bits.Mask >>= 1; this.Bits.Mask >>= 1;
return this.LastErrorCode = OrigDecoderErrorCode.NoError; return this.LastErrorCode = GolangDecoderErrorCode.NoError;
} }
/// <summary> /// <summary>
@ -143,8 +143,8 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
/// <param name="data">The data to write to.</param> /// <param name="data">The data to write to.</param>
/// <param name="offset">The offset in the source buffer</param> /// <param name="offset">The offset in the source buffer</param>
/// <param name="length">The number of bytes to read</param> /// <param name="length">The number of bytes to read</param>
/// <returns>The <see cref="OrigDecoderErrorCode"/></returns> /// <returns>The <see cref="GolangDecoderErrorCode"/></returns>
public OrigDecoderErrorCode ReadFullUnsafe(byte[] data, int offset, int length) public GolangDecoderErrorCode ReadFullUnsafe(byte[] data, int offset, int length)
{ {
// Unread the overshot bytes, if any. // Unread the overshot bytes, if any.
if (this.Bytes.UnreadableBytes != 0) if (this.Bytes.UnreadableBytes != 0)
@ -157,8 +157,8 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
this.Bytes.UnreadableBytes = 0; this.Bytes.UnreadableBytes = 0;
} }
this.LastErrorCode = OrigDecoderErrorCode.NoError; this.LastErrorCode = GolangDecoderErrorCode.NoError;
while (length > 0 && this.LastErrorCode == OrigDecoderErrorCode.NoError) while (length > 0 && this.LastErrorCode == GolangDecoderErrorCode.NoError)
{ {
if (this.Bytes.J - this.Bytes.I >= length) if (this.Bytes.J - this.Bytes.I >= length)
{ {
@ -185,13 +185,13 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
/// </summary> /// </summary>
/// <param name="count">The number of bits to decode.</param> /// <param name="count">The number of bits to decode.</param>
/// <param name="result">The <see cref="uint" /> result</param> /// <param name="result">The <see cref="uint" /> result</param>
/// <returns>The <see cref="OrigDecoderErrorCode"/></returns> /// <returns>The <see cref="GolangDecoderErrorCode"/></returns>
public OrigDecoderErrorCode DecodeBitsUnsafe(int count, out int result) public GolangDecoderErrorCode DecodeBitsUnsafe(int count, out int result)
{ {
if (this.Bits.UnreadBits < count) if (this.Bits.UnreadBits < count)
{ {
this.LastErrorCode = this.Bits.EnsureNBitsUnsafe(count, ref this); this.LastErrorCode = this.Bits.EnsureNBitsUnsafe(count, ref this);
if (this.LastErrorCode != OrigDecoderErrorCode.NoError) if (this.LastErrorCode != GolangDecoderErrorCode.NoError)
{ {
result = 0; result = 0;
return this.LastErrorCode; return this.LastErrorCode;
@ -202,7 +202,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
result = result & ((1 << count) - 1); result = result & ((1 << count) - 1);
this.Bits.UnreadBits -= count; this.Bits.UnreadBits -= count;
this.Bits.Mask >>= count; this.Bits.Mask >>= count;
return this.LastErrorCode = OrigDecoderErrorCode.NoError; return this.LastErrorCode = GolangDecoderErrorCode.NoError;
} }
/// <summary> /// <summary>
@ -210,8 +210,8 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
/// </summary> /// </summary>
/// <param name="huffmanTree">The huffman value</param> /// <param name="huffmanTree">The huffman value</param>
/// <param name="result">The decoded <see cref="byte" /></param> /// <param name="result">The decoded <see cref="byte" /></param>
/// <returns>The <see cref="OrigDecoderErrorCode"/></returns> /// <returns>The <see cref="GolangDecoderErrorCode"/></returns>
public OrigDecoderErrorCode DecodeHuffmanUnsafe(ref OrigHuffmanTree huffmanTree, out int result) public GolangDecoderErrorCode DecodeHuffmanUnsafe(ref GolangHuffmanTree huffmanTree, out int result)
{ {
result = 0; result = 0;
@ -224,9 +224,9 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
{ {
this.LastErrorCode = this.Bits.Ensure8BitsUnsafe(ref this); this.LastErrorCode = this.Bits.Ensure8BitsUnsafe(ref this);
if (this.LastErrorCode == OrigDecoderErrorCode.NoError) if (this.LastErrorCode == GolangDecoderErrorCode.NoError)
{ {
int lutIndex = (this.Bits.Accumulator >> (this.Bits.UnreadBits - OrigHuffmanTree.LutSizeLog2)) & 0xFF; int lutIndex = (this.Bits.Accumulator >> (this.Bits.UnreadBits - GolangHuffmanTree.LutSizeLog2)) & 0xFF;
int v = huffmanTree.Lut[lutIndex]; int v = huffmanTree.Lut[lutIndex];
if (v != 0) if (v != 0)
@ -246,7 +246,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
} }
int code = 0; int code = 0;
for (int i = 0; i < OrigHuffmanTree.MaxCodeLength; i++) for (int i = 0; i < GolangHuffmanTree.MaxCodeLength; i++)
{ {
if (this.Bits.UnreadBits == 0) if (this.Bits.UnreadBits == 0)
{ {
@ -269,7 +269,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
if (code <= huffmanTree.MaxCodes[i]) if (code <= huffmanTree.MaxCodes[i])
{ {
result = huffmanTree.GetValue(code, i); result = huffmanTree.GetValue(code, i);
return this.LastErrorCode = OrigDecoderErrorCode.NoError; return this.LastErrorCode = GolangDecoderErrorCode.NoError;
} }
code <<= 1; code <<= 1;
@ -279,7 +279,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
DecoderThrowHelper.ThrowImageFormatException.BadHuffmanCode(); DecoderThrowHelper.ThrowImageFormatException.BadHuffmanCode();
// DUMMY RETURN! C# doesn't know we have thrown an exception! // DUMMY RETURN! C# doesn't know we have thrown an exception!
return OrigDecoderErrorCode.NoError; return GolangDecoderErrorCode.NoError;
} }
/// <summary> /// <summary>
@ -295,11 +295,11 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
/// <summary> /// <summary>
/// Skips the next n bytes. /// Skips the next n bytes.
/// Does not throw, returns <see cref="OrigDecoderErrorCode"/> instead! /// Does not throw, returns <see cref="GolangDecoderErrorCode"/> instead!
/// </summary> /// </summary>
/// <param name="count">The number of bytes to ignore.</param> /// <param name="count">The number of bytes to ignore.</param>
/// <returns>The <see cref="OrigDecoderErrorCode"/></returns> /// <returns>The <see cref="GolangDecoderErrorCode"/></returns>
public OrigDecoderErrorCode SkipUnsafe(int count) public GolangDecoderErrorCode SkipUnsafe(int count)
{ {
// Unread the overshot bytes, if any. // Unread the overshot bytes, if any.
if (this.Bytes.UnreadableBytes != 0) if (this.Bytes.UnreadableBytes != 0)
@ -328,13 +328,13 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
} }
this.LastErrorCode = this.Bytes.FillUnsafe(this.InputStream); this.LastErrorCode = this.Bytes.FillUnsafe(this.InputStream);
if (this.LastErrorCode != OrigDecoderErrorCode.NoError) if (this.LastErrorCode != GolangDecoderErrorCode.NoError)
{ {
return this.LastErrorCode; return this.LastErrorCode;
} }
} }
return this.LastErrorCode = OrigDecoderErrorCode.NoError; return this.LastErrorCode = GolangDecoderErrorCode.NoError;
} }
/// <summary> /// <summary>
@ -374,8 +374,8 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
/// </summary> /// </summary>
/// <param name="t">Byte</param> /// <param name="t">Byte</param>
/// <param name="x">Read bits value</param> /// <param name="x">Read bits value</param>
/// <returns>The <see cref="OrigDecoderErrorCode"/></returns> /// <returns>The <see cref="GolangDecoderErrorCode"/></returns>
public OrigDecoderErrorCode ReceiveExtendUnsafe(int t, out int x) public GolangDecoderErrorCode ReceiveExtendUnsafe(int t, out int x)
{ {
this.LastErrorCode = this.Bits.ReceiveExtendUnsafe(t, ref this, out x); this.LastErrorCode = this.Bits.ReceiveExtendUnsafe(t, ref this, out x);
return this.LastErrorCode; return this.LastErrorCode;

26
src/ImageSharp/Formats/Jpeg/GolangPort/GolangJpegDecoderCore.cs

@ -96,12 +96,12 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
/// <summary> /// <summary>
/// Gets the component array /// Gets the component array
/// </summary> /// </summary>
public OrigComponent[] Components { get; private set; } public GolangComponent[] Components { get; private set; }
/// <summary> /// <summary>
/// Gets the huffman trees /// Gets the huffman trees
/// </summary> /// </summary>
public OrigHuffmanTree[] HuffmanTrees { get; private set; } public GolangHuffmanTree[] HuffmanTrees { get; private set; }
/// <inheritdoc /> /// <inheritdoc />
public Block8x8F[] QuantizationTables { get; private set; } public Block8x8F[] QuantizationTables { get; private set; }
@ -209,7 +209,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
{ {
if (this.Components != null) if (this.Components != null)
{ {
foreach (OrigComponent component in this.Components) foreach (GolangComponent component in this.Components)
{ {
component?.Dispose(); component?.Dispose();
} }
@ -219,7 +219,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
} }
/// <summary> /// <summary>
/// Read metadata from stream and read the blocks in the scans into <see cref="OrigComponent.SpectralBlocks"/>. /// Read metadata from stream and read the blocks in the scans into <see cref="GolangComponent.SpectralBlocks"/>.
/// </summary> /// </summary>
/// <param name="stream">The stream</param> /// <param name="stream">The stream</param>
/// <param name="metadataOnly">Whether to decode metadata only.</param> /// <param name="metadataOnly">Whether to decode metadata only.</param>
@ -231,7 +231,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
if (!metadataOnly) if (!metadataOnly)
{ {
this.HuffmanTrees = OrigHuffmanTree.CreateHuffmanTrees(); this.HuffmanTrees = GolangHuffmanTree.CreateHuffmanTrees();
this.QuantizationTables = new Block8x8F[MaxTq + 1]; this.QuantizationTables = new Block8x8F[MaxTq + 1];
} }
@ -680,12 +680,12 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
if (!metadataOnly) if (!metadataOnly)
{ {
this.Components = new OrigComponent[this.ComponentCount]; this.Components = new GolangComponent[this.ComponentCount];
for (int i = 0; i < this.ComponentCount; i++) for (int i = 0; i < this.ComponentCount; i++)
{ {
byte componentIdentifier = this.Temp[6 + (3 * i)]; byte componentIdentifier = this.Temp[6 + (3 * i)];
var component = new OrigComponent(componentIdentifier, i); var component = new GolangComponent(componentIdentifier, i);
component.InitializeCoreData(this); component.InitializeCoreData(this);
this.Components[i] = component; this.Components[i] = component;
} }
@ -697,7 +697,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
this.ColorSpace = this.DeduceJpegColorSpace(); this.ColorSpace = this.DeduceJpegColorSpace();
foreach (OrigComponent component in this.Components) foreach (GolangComponent component in this.Components)
{ {
component.InitializeDerivedData(this.configuration.MemoryManager, this); component.InitializeDerivedData(this.configuration.MemoryManager, this);
} }
@ -721,18 +721,18 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
this.InputProcessor.ReadFull(this.Temp, 0, 17); this.InputProcessor.ReadFull(this.Temp, 0, 17);
int tc = this.Temp[0] >> 4; int tc = this.Temp[0] >> 4;
if (tc > OrigHuffmanTree.MaxTc) if (tc > GolangHuffmanTree.MaxTc)
{ {
throw new ImageFormatException("Bad Tc value"); throw new ImageFormatException("Bad Tc value");
} }
int th = this.Temp[0] & 0x0f; int th = this.Temp[0] & 0x0f;
if (th > OrigHuffmanTree.MaxTh) if (th > GolangHuffmanTree.MaxTh)
{ {
throw new ImageFormatException("Bad Th value"); throw new ImageFormatException("Bad Th value");
} }
int huffTreeIndex = (tc * OrigHuffmanTree.ThRowSize) + th; int huffTreeIndex = (tc * GolangHuffmanTree.ThRowSize) + th;
this.HuffmanTrees[huffTreeIndex].ProcessDefineHuffmanTablesMarkerLoop( this.HuffmanTrees[huffTreeIndex].ProcessDefineHuffmanTablesMarkerLoop(
ref this.InputProcessor, ref this.InputProcessor,
this.Temp, this.Temp,
@ -766,8 +766,8 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
/// </exception> /// </exception>
private void ProcessStartOfScanMarker(int remaining) private void ProcessStartOfScanMarker(int remaining)
{ {
var scan = default(OrigJpegScanDecoder); var scan = default(GolangJpegScanDecoder);
OrigJpegScanDecoder.InitStreamReading(&scan, this, remaining); GolangJpegScanDecoder.InitStreamReading(&scan, this, remaining);
this.InputProcessor.Bits = default(Bits); this.InputProcessor.Bits = default(Bits);
scan.DecodeBlocks(this); scan.DecodeBlocks(this);
} }

5
src/ImageSharp/Formats/Jpeg/GolangPort/JpegEncoderCore.cs

@ -101,11 +101,6 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
} }
}; };
/// <summary>
/// Lookup tables for converting Rgb to YCbCr
/// </summary>
private static RgbToYCbCrTables rgbToYCbCrTables = RgbToYCbCrTables.Create();
/// <summary> /// <summary>
/// A scratch buffer to reduce allocations. /// A scratch buffer to reduce allocations.
/// </summary> /// </summary>

14
tests/ImageSharp.Tests/Formats/Jpg/ParseStreamTests.cs

@ -52,7 +52,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
Assert.Equal(expectedSizeInBlocks, decoder.ImageSizeInMCU); Assert.Equal(expectedSizeInBlocks, decoder.ImageSizeInMCU);
var uniform1 = new Size(1, 1); var uniform1 = new Size(1, 1);
OrigComponent c0 = decoder.Components[0]; GolangComponent c0 = decoder.Components[0];
VerifyJpeg.VerifyComponent(c0, expectedSizeInBlocks, uniform1, uniform1); VerifyJpeg.VerifyComponent(c0, expectedSizeInBlocks, uniform1, uniform1);
} }
} }
@ -72,8 +72,8 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
{ {
sb.AppendLine(imageFile); sb.AppendLine(imageFile);
sb.AppendLine($"Size:{decoder.ImageSizeInPixels} MCU:{decoder.ImageSizeInMCU}"); sb.AppendLine($"Size:{decoder.ImageSizeInPixels} MCU:{decoder.ImageSizeInMCU}");
OrigComponent c0 = decoder.Components[0]; GolangComponent c0 = decoder.Components[0];
OrigComponent c1 = decoder.Components[1]; GolangComponent c1 = decoder.Components[1];
sb.AppendLine($"Luma: SAMP: {c0.SamplingFactors} BLOCKS: {c0.SizeInBlocks}"); sb.AppendLine($"Luma: SAMP: {c0.SamplingFactors} BLOCKS: {c0.SizeInBlocks}");
sb.AppendLine($"Chroma: {c1.SamplingFactors} BLOCKS: {c1.SizeInBlocks}"); sb.AppendLine($"Chroma: {c1.SamplingFactors} BLOCKS: {c1.SizeInBlocks}");
@ -108,9 +108,9 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
Assert.Equal(componentCount, decoder.ComponentCount); Assert.Equal(componentCount, decoder.ComponentCount);
Assert.Equal(componentCount, decoder.Components.Length); Assert.Equal(componentCount, decoder.Components.Length);
OrigComponent c0 = decoder.Components[0]; GolangComponent c0 = decoder.Components[0];
OrigComponent c1 = decoder.Components[1]; GolangComponent c1 = decoder.Components[1];
OrigComponent c2 = decoder.Components[2]; GolangComponent c2 = decoder.Components[2];
var uniform1 = new Size(1, 1); var uniform1 = new Size(1, 1);
@ -126,7 +126,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
if (componentCount == 4) if (componentCount == 4)
{ {
OrigComponent c3 = decoder.Components[2]; GolangComponent c3 = decoder.Components[2];
VerifyJpeg.VerifyComponent(c3, expectedLumaSizeInBlocks, fLuma, uniform1); VerifyJpeg.VerifyComponent(c3, expectedLumaSizeInBlocks, fLuma, uniform1);
} }
} }

2
tests/ImageSharp.Tests/Formats/Jpg/Utils/LibJpegTools.ComponentData.cs

@ -77,7 +77,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg.Utils
return result; return result;
} }
public static ComponentData Load(OrigComponent c) public static ComponentData Load(GolangComponent c)
{ {
var result = new ComponentData( var result = new ComponentData(
c.SizeInBlocks.Width, c.SizeInBlocks.Width,

2
tests/ImageSharp.Tests/Formats/Jpg/Utils/LibJpegTools.SpectralData.cs

@ -39,7 +39,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg.Utils
public static SpectralData LoadFromImageSharpDecoder(GolangJpegDecoderCore decoder) public static SpectralData LoadFromImageSharpDecoder(GolangJpegDecoderCore decoder)
{ {
OrigComponent[] srcComponents = decoder.Components; GolangComponent[] srcComponents = decoder.Components;
LibJpegTools.ComponentData[] destComponents = srcComponents.Select(LibJpegTools.ComponentData.Load).ToArray(); LibJpegTools.ComponentData[] destComponents = srcComponents.Select(LibJpegTools.ComponentData.Load).ToArray();
return new SpectralData(destComponents); return new SpectralData(destComponents);

Loading…
Cancel
Save