Browse Source

Added comments to DQT marker parser, DQT exceptions now provide better info messages

pull/1706/head
Dmitry Pentin 5 years ago
parent
commit
1d781da193
  1. 2
      src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegComponent.cs
  2. 45
      src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs
  3. 5
      src/ImageSharp/Formats/Jpeg/JpegThrowHelper.cs

2
src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegComponent.cs

@ -32,7 +32,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder
if (quantizationTableIndex > 3)
{
JpegThrowHelper.ThrowBadQuantizationTable();
JpegThrowHelper.ThrowBadQuantizationTableIndex(quantizationTableIndex);
}
this.QuantizationTableIndex = quantizationTableIndex;

45
src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs

@ -755,26 +755,29 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
{
while (remaining > 0)
{
bool done = false;
remaining--;
// 1 byte: quantization table spec
// bit 0..3: table index (0..3)
// bit 4..7: table precision (0 = 8 bit, 1 = 16 bit)
int quantizationTableSpec = stream.ReadByte();
int tableIndex = quantizationTableSpec & 15;
int tablePrecision = quantizationTableSpec >> 4;
// Max index. 4 Tables max.
// Validate:
if (tableIndex > 3)
{
JpegThrowHelper.ThrowBadQuantizationTable();
JpegThrowHelper.ThrowBadQuantizationTableIndex(tableIndex);
}
switch (quantizationTableSpec >> 4)
remaining--;
switch (tablePrecision)
{
// 8 bit values
case 0:
{
// 8 bit values
// Validate: 8 bit table needs exactly 64 bytes
if (remaining < 64)
{
done = true;
break;
JpegThrowHelper.ThrowBadMarker(nameof(JpegConstants.Markers.DQT), remaining);
}
stream.Read(this.temp, 0, 64);
@ -785,16 +788,17 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
{
table[j] = this.temp[j];
}
break;
}
break;
// 16 bit values
case 1:
{
// 16 bit values
// Validate: 16 bit table needs exactly 128 bytes
if (remaining < 128)
{
done = true;
break;
JpegThrowHelper.ThrowBadMarker(nameof(JpegConstants.Markers.DQT), remaining);
}
stream.Read(this.temp, 0, 128);
@ -805,26 +809,17 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
{
table[j] = (this.temp[2 * j] << 8) | this.temp[(2 * j) + 1];
}
}
break;
break;
}
// Unknown precision - error
default:
{
JpegThrowHelper.ThrowBadQuantizationTable();
JpegThrowHelper.ThrowBadQuantizationTablePrecision(tablePrecision);
break;
}
}
if (done)
{
break;
}
}
if (remaining != 0)
{
JpegThrowHelper.ThrowBadMarker(nameof(JpegConstants.Markers.DQT), remaining);
}
this.Metadata.GetFormatMetadata(JpegFormat.Instance).Quality = QualityEvaluator.EstimateQuality(this.QuantizationTables);

5
src/ImageSharp/Formats/Jpeg/JpegThrowHelper.cs

@ -36,7 +36,10 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
public static void ThrowBadMarker(string marker, int length) => throw new InvalidImageContentException($"Marker {marker} has bad length {length}.");
[MethodImpl(InliningOptions.ColdPath)]
public static void ThrowBadQuantizationTable() => throw new InvalidImageContentException("Bad Quantization Table index.");
public static void ThrowBadQuantizationTableIndex(int index) => throw new InvalidImageContentException($"Bad Quantization Table index {index}.");
[MethodImpl(InliningOptions.ColdPath)]
public static void ThrowBadQuantizationTablePrecision(int precision) => throw new InvalidImageContentException($"Unknown Quantization Table precision {precision}.");
[MethodImpl(InliningOptions.ColdPath)]
public static void ThrowBadSampling() => throw new InvalidImageContentException("Bad sampling factor.");

Loading…
Cancel
Save