Browse Source

Greatly reduced operations per emit call

pull/1761/head
Dmitry Pentin 5 years ago
parent
commit
4c14c57d09
  1. 3
      src/ImageSharp/Formats/Jpeg/Components/Encoder/HuffmanLut.cs
  2. 23
      src/ImageSharp/Formats/Jpeg/Components/Encoder/HuffmanScanEncoder.cs

3
src/ImageSharp/Formats/Jpeg/Components/Encoder/HuffmanLut.cs

@ -4,6 +4,7 @@
namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder
{ {
/// <summary> /// <summary>
/// TODO: THIS IS NO LONGER TRUE, INTERNAL REPRESENTATION WAS CHANGED AND THIS DOC SHOULD BE CHANGED TOO!!!
/// A compiled look-up table representation of a huffmanSpec. /// A compiled look-up table representation of a huffmanSpec.
/// Each value maps to a int32 of which the 24 most significant bits hold the /// Each value maps to a int32 of which the 24 most significant bits hold the
/// codeword in bits and the 8 least significant bits hold the codeword size. /// codeword in bits and the 8 least significant bits hold the codeword size.
@ -54,7 +55,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder
int len = i + 1; int len = i + 1;
for (int j = 0; j < spec.Count[i]; j++) for (int j = 0; j < spec.Count[i]; j++)
{ {
this.Values[spec.Values[k]] = len | (code << 8); this.Values[spec.Values[k]] = len | (code << (32 - len));
code++; code++;
k++; k++;
} }

23
src/ImageSharp/Formats/Jpeg/Components/Encoder/HuffmanScanEncoder.cs

@ -349,16 +349,14 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder
[MethodImpl(InliningOptions.ShortMethod)] [MethodImpl(InliningOptions.ShortMethod)]
private void Emit(uint bits, int count) private void Emit(uint bits, int count)
{ {
uint correctedBits = bits << (32 - count); this.accumulatedBits |= bits >> this.bitCount;
this.accumulatedBits |= correctedBits >> this.bitCount;
count += this.bitCount; count += this.bitCount;
if (count >= 32) if (count >= 32)
{ {
this.emitBuffer[--this.emitWriteIndex] = this.accumulatedBits; this.emitBuffer[--this.emitWriteIndex] = this.accumulatedBits;
this.accumulatedBits = correctedBits << (32 - this.bitCount); this.accumulatedBits = bits << (32 - this.bitCount);
count -= 32; count -= 32;
} }
@ -375,7 +373,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder
private void EmitHuff(int[] table, int value) private void EmitHuff(int[] table, int value)
{ {
int x = table[value]; int x = table[value];
this.Emit((uint)x >> 8, x & 0xff); this.Emit((uint)x & 0xffff_ff00u, x & 0xff);
} }
[MethodImpl(InliningOptions.ShortMethod)] [MethodImpl(InliningOptions.ShortMethod)]
@ -389,13 +387,10 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder
b = value - 1; b = value - 1;
} }
int bt = GetHuffmanEncodingLength((uint)a); int valueLen = GetHuffmanEncodingLength((uint)a);
this.EmitHuff(table, bt); this.EmitHuff(table, valueLen);
if (bt > 0) this.Emit((uint)b << (32 - valueLen), valueLen);
{
this.Emit((uint)(b & ((1 << bt) - 1)), bt);
}
} }
/// <summary> /// <summary>
@ -415,10 +410,10 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder
b = value - 1; b = value - 1;
} }
int bt = GetHuffmanEncodingLength((uint)a); int valueLen = GetHuffmanEncodingLength((uint)a);
this.EmitHuff(table, (runLength << 4) | bt); this.EmitHuff(table, (runLength << 4) | valueLen);
this.Emit((uint)(b & ((1 << bt) - 1)), bt); this.Emit((uint)b << (32 - valueLen), valueLen);
} }
/// <summary> /// <summary>

Loading…
Cancel
Save