Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
update write block in huffman encoder, add test
  • Loading branch information
ardabada committed May 22, 2024
commit 490c0d3a314edc2c91c720b5ff204ddc25628dd1
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,6 @@ public void EncodeDcScan(Component component, CancellationToken cancellationToke
ref Unsafe.Add(ref blockRef, k),
ref dcHuffmanTable);


if (this.IsStreamFlushNeeded)
{
this.FlushToStream();
Expand Down Expand Up @@ -492,6 +491,7 @@ private void WriteAcBlock(
}
}

// if mcu block contains trailing zeros - we must write end of block (EOB) value indicating that current block is over
if (runLength > 0)
{
this.EmitHuff(acHuffTable, 0x00);
Expand All @@ -505,44 +505,7 @@ private void WriteBlock(
ref HuffmanLut acTable)
{
this.WriteDc(component, ref block, ref dcTable);

// Emit the AC components.
int[] acHuffTable = acTable.Values;

nint lastValuableIndex = block.GetLastNonZeroIndex();

int runLength = 0;
ref short blockRef = ref Unsafe.As<Block8x8, short>(ref block);
for (nint zig = 1; zig <= lastValuableIndex; zig++)
{
const int zeroRun1 = 1 << 4;
const int zeroRun16 = 16 << 4;

int ac = Unsafe.Add(ref blockRef, zig);
if (ac == 0)
{
runLength += zeroRun1;
}
else
{
while (runLength >= zeroRun16)
{
this.EmitHuff(acHuffTable, 0xf0);
runLength -= zeroRun16;
}

this.EmitHuffRLE(acHuffTable, runLength, ac);
runLength = 0;
}
}

// if mcu block contains trailing zeros - we must write end of block (EOB) value indicating that current block is over
// this can be done for any number of trailing zeros, even when all 63 ac values are zero
// (Block8x8F.Size - 1) == 63 - last index of the mcu elements
if (lastValuableIndex != Block8x8F.Size - 1)
{
this.EmitHuff(acHuffTable, 0x00);
}
this.WriteAcBlock(ref block, 1, 64, ref acTable);
}

/// <summary>
Expand Down
32 changes: 25 additions & 7 deletions tests/ImageSharp.Tests/Formats/Jpg/JpegEncoderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,6 @@ public partial class JpegEncoderTests
{
private static JpegEncoder JpegEncoder => new();

private static readonly TheoryData<int> TestQualities = new()
{
40,
80,
100,
};

public static readonly TheoryData<JpegEncodingColor, int, float> NonSubsampledEncodingSetups = new()
{
{ JpegEncodingColor.Rgb, 100, 0.0238f / 100 },
Expand Down Expand Up @@ -160,6 +153,31 @@ public void EncodeBaseline_WorksWithDiscontiguousBuffers<TPixel>(TestImageProvid
TestJpegEncoderCore(provider, colorType, 100, comparer);
}

[Theory]
[WithFile(TestImages.Png.CalliphoraPartial, nameof(NonSubsampledEncodingSetups), PixelTypes.Rgb24)]
[WithFile(TestImages.Png.CalliphoraPartial, nameof(SubsampledEncodingSetups), PixelTypes.Rgb24)]
[WithFile(TestImages.Png.BikeGrayscale, nameof(LuminanceEncodingSetups), PixelTypes.L8)]
[WithFile(TestImages.Jpeg.Baseline.Cmyk, nameof(CmykEncodingSetups), PixelTypes.Rgb24)]
[WithFile(TestImages.Jpeg.Baseline.Ycck, nameof(YcckEncodingSetups), PixelTypes.Rgb24)]
public void EncodeProgressive_DefaultNumberOfScans<TPixel>(TestImageProvider<TPixel> provider, JpegEncodingColor colorType, int quality, float tolerance)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you can add an additional test setting the restart interval this would be good to merge! 👍

where TPixel : unmanaged, IPixel<TPixel>
{
using Image<TPixel> image = provider.GetImage();

JpegEncoder encoder = new()
{
Quality = quality,
ColorType = colorType,
Progressive = true
};
string info = $"{colorType}-Q{quality}";

ImageComparer comparer = new TolerantImageComparer(tolerance);

// Does DebugSave & load reference CompareToReferenceInput():
image.VerifyEncoder(provider, "jpeg", info, encoder, comparer, referenceImageExtension: "jpg");
}

[Theory]
[InlineData(JpegEncodingColor.YCbCrRatio420)]
[InlineData(JpegEncodingColor.YCbCrRatio444)]
Expand Down