Skip to content

Commit 490c0d3

Browse files
committed
update write block in huffman encoder, add test
1 parent 602504e commit 490c0d3

File tree

2 files changed

+27
-46
lines changed

2 files changed

+27
-46
lines changed

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

Lines changed: 2 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,6 @@ public void EncodeDcScan(Component component, CancellationToken cancellationToke
263263
ref Unsafe.Add(ref blockRef, k),
264264
ref dcHuffmanTable);
265265

266-
267266
if (this.IsStreamFlushNeeded)
268267
{
269268
this.FlushToStream();
@@ -492,6 +491,7 @@ private void WriteAcBlock(
492491
}
493492
}
494493

494+
// if mcu block contains trailing zeros - we must write end of block (EOB) value indicating that current block is over
495495
if (runLength > 0)
496496
{
497497
this.EmitHuff(acHuffTable, 0x00);
@@ -505,44 +505,7 @@ private void WriteBlock(
505505
ref HuffmanLut acTable)
506506
{
507507
this.WriteDc(component, ref block, ref dcTable);
508-
509-
// Emit the AC components.
510-
int[] acHuffTable = acTable.Values;
511-
512-
nint lastValuableIndex = block.GetLastNonZeroIndex();
513-
514-
int runLength = 0;
515-
ref short blockRef = ref Unsafe.As<Block8x8, short>(ref block);
516-
for (nint zig = 1; zig <= lastValuableIndex; zig++)
517-
{
518-
const int zeroRun1 = 1 << 4;
519-
const int zeroRun16 = 16 << 4;
520-
521-
int ac = Unsafe.Add(ref blockRef, zig);
522-
if (ac == 0)
523-
{
524-
runLength += zeroRun1;
525-
}
526-
else
527-
{
528-
while (runLength >= zeroRun16)
529-
{
530-
this.EmitHuff(acHuffTable, 0xf0);
531-
runLength -= zeroRun16;
532-
}
533-
534-
this.EmitHuffRLE(acHuffTable, runLength, ac);
535-
runLength = 0;
536-
}
537-
}
538-
539-
// if mcu block contains trailing zeros - we must write end of block (EOB) value indicating that current block is over
540-
// this can be done for any number of trailing zeros, even when all 63 ac values are zero
541-
// (Block8x8F.Size - 1) == 63 - last index of the mcu elements
542-
if (lastValuableIndex != Block8x8F.Size - 1)
543-
{
544-
this.EmitHuff(acHuffTable, 0x00);
545-
}
508+
this.WriteAcBlock(ref block, 1, 64, ref acTable);
546509
}
547510

548511
/// <summary>

tests/ImageSharp.Tests/Formats/Jpg/JpegEncoderTests.cs

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,6 @@ public partial class JpegEncoderTests
1414
{
1515
private static JpegEncoder JpegEncoder => new();
1616

17-
private static readonly TheoryData<int> TestQualities = new()
18-
{
19-
40,
20-
80,
21-
100,
22-
};
23-
2417
public static readonly TheoryData<JpegEncodingColor, int, float> NonSubsampledEncodingSetups = new()
2518
{
2619
{ JpegEncodingColor.Rgb, 100, 0.0238f / 100 },
@@ -160,6 +153,31 @@ public void EncodeBaseline_WorksWithDiscontiguousBuffers<TPixel>(TestImageProvid
160153
TestJpegEncoderCore(provider, colorType, 100, comparer);
161154
}
162155

156+
[Theory]
157+
[WithFile(TestImages.Png.CalliphoraPartial, nameof(NonSubsampledEncodingSetups), PixelTypes.Rgb24)]
158+
[WithFile(TestImages.Png.CalliphoraPartial, nameof(SubsampledEncodingSetups), PixelTypes.Rgb24)]
159+
[WithFile(TestImages.Png.BikeGrayscale, nameof(LuminanceEncodingSetups), PixelTypes.L8)]
160+
[WithFile(TestImages.Jpeg.Baseline.Cmyk, nameof(CmykEncodingSetups), PixelTypes.Rgb24)]
161+
[WithFile(TestImages.Jpeg.Baseline.Ycck, nameof(YcckEncodingSetups), PixelTypes.Rgb24)]
162+
public void EncodeProgressive_DefaultNumberOfScans<TPixel>(TestImageProvider<TPixel> provider, JpegEncodingColor colorType, int quality, float tolerance)
163+
where TPixel : unmanaged, IPixel<TPixel>
164+
{
165+
using Image<TPixel> image = provider.GetImage();
166+
167+
JpegEncoder encoder = new()
168+
{
169+
Quality = quality,
170+
ColorType = colorType,
171+
Progressive = true
172+
};
173+
string info = $"{colorType}-Q{quality}";
174+
175+
ImageComparer comparer = new TolerantImageComparer(tolerance);
176+
177+
// Does DebugSave & load reference CompareToReferenceInput():
178+
image.VerifyEncoder(provider, "jpeg", info, encoder, comparer, referenceImageExtension: "jpg");
179+
}
180+
163181
[Theory]
164182
[InlineData(JpegEncodingColor.YCbCrRatio420)]
165183
[InlineData(JpegEncodingColor.YCbCrRatio444)]

0 commit comments

Comments
 (0)