Browse Source

Reduced number of stream reads in SOS marker, added check for remaining bytes

pull/1702/head
Dmitry Pentin 5 years ago
parent
commit
7c8261a51b
  1. 22
      src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs

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

@ -250,7 +250,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
case JpegConstants.Markers.SOS: case JpegConstants.Markers.SOS:
if (!metadataOnly) if (!metadataOnly)
{ {
this.ProcessStartOfScanMarker(stream, cancellationToken); this.ProcessStartOfScanMarker(stream, remaining, cancellationToken);
break; break;
} }
else else
@ -969,7 +969,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
/// <summary> /// <summary>
/// Processes the SOS (Start of scan marker). /// Processes the SOS (Start of scan marker).
/// </summary> /// </summary>
private void ProcessStartOfScanMarker(BufferedReadStream stream, CancellationToken cancellationToken) private void ProcessStartOfScanMarker(BufferedReadStream stream, int remaining, CancellationToken cancellationToken)
{ {
if (this.Frame is null) if (this.Frame is null)
{ {
@ -986,11 +986,21 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
JpegThrowHelper.ThrowInvalidImageContentException($"Invalid number of components in scan: {selectorsCount}."); JpegThrowHelper.ThrowInvalidImageContentException($"Invalid number of components in scan: {selectorsCount}.");
} }
// Validate: marker must contain exactly (4 + selectorsCount*2) bytes
int selectorsBytes = selectorsCount * 2;
if (remaining != 4 + selectorsBytes)
{
JpegThrowHelper.ThrowBadMarker("SOS", remaining);
}
// selectorsCount*2 bytes: component index + huffman tables indices
stream.Read(this.temp, 0, selectorsBytes);
this.Frame.MultiScan = this.Frame.ComponentCount != selectorsCount; this.Frame.MultiScan = this.Frame.ComponentCount != selectorsCount;
for (int i = 0; i < selectorsCount; i++) for (int i = 0; i < selectorsBytes; i += 2)
{ {
// 1 byte: Component id // 1 byte: Component id
int componentSelectorId = stream.ReadByte(); int componentSelectorId = this.temp[i];
int componentIndex = -1; int componentIndex = -1;
for (int j = 0; j < this.Frame.ComponentIds.Length; j++) for (int j = 0; j < this.Frame.ComponentIds.Length; j++)
@ -1010,14 +1020,14 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
JpegThrowHelper.ThrowInvalidImageContentException($"Unknown component id in scan: {componentSelectorId}."); JpegThrowHelper.ThrowInvalidImageContentException($"Unknown component id in scan: {componentSelectorId}.");
} }
this.Frame.ComponentOrder[i] = (byte)componentIndex; this.Frame.ComponentOrder[i / 2] = (byte)componentIndex;
JpegComponent component = this.Frame.Components[componentIndex]; JpegComponent component = this.Frame.Components[componentIndex];
// 1 byte: Huffman table selectors. // 1 byte: Huffman table selectors.
// 4 bits - dc // 4 bits - dc
// 4 bits - ac // 4 bits - ac
int tableSpec = stream.ReadByte(); int tableSpec = this.temp[i + 1];
int dcTableIndex = tableSpec >> 4; int dcTableIndex = tableSpec >> 4;
int acTableIndex = tableSpec & 15; int acTableIndex = tableSpec & 15;

Loading…
Cancel
Save