Browse Source

Experiment with new file marker finder

pull/298/head
James Jackson-South 9 years ago
parent
commit
549e61f2f4
  1. 2
      src/ImageSharp/Formats/Jpeg/JpegDecoder.cs
  2. 50
      src/ImageSharp/Formats/Jpeg/Port/JpegDecoderCore.cs
  3. 1
      tests/ImageSharp.Benchmarks/Image/DecodeJpeg.cs

2
src/ImageSharp/Formats/Jpeg/JpegDecoder.cs

@ -21,7 +21,7 @@ namespace ImageSharp.Formats
{ {
Guard.NotNull(stream, "stream"); Guard.NotNull(stream, "stream");
// using (JpegDecoderCore decoder = new JpegDecoderCore(options, configuration)) // using (var decoder = new JpegDecoderCore(options, configuration))
// { // {
// return decoder.Decode<TPixel>(stream); // return decoder.Decode<TPixel>(stream);
// } // }

50
src/ImageSharp/Formats/Jpeg/Port/JpegDecoderCore.cs

@ -185,6 +185,45 @@ namespace ImageSharp.Formats.Jpeg.Port
return new FileMarker(newMarker, newPos, true); return new FileMarker(newMarker, newPos, true);
} }
/// <summary>
/// Finds the next file marker within the byte stream. Used for testing. Slower as it only reads on byte at a time
/// </summary>
/// <param name="stream">The input stream</param>
/// <returns>The <see cref="FileMarker"/></returns>
public static FileMarker FindNextFileMarkerNew(Stream stream)
{
while (true)
{
int value = stream.ReadByte();
if (value == -1)
{
// We've reached the end of the stream
return new FileMarker(JpegConstants.Markers.EOI, (int)stream.Length, true);
}
byte prefix = (byte)value;
byte suffix = JpegConstants.Markers.Prefix;
// According to Section B.1.1.2:
// "Any marker may optionally be preceded by any number of fill bytes, which are bytes assigned code 0xFF."
while (prefix == JpegConstants.Markers.Prefix && suffix == JpegConstants.Markers.Prefix)
{
value = stream.ReadByte();
if (value == -1)
{
// We've reached the end of the stream
return new FileMarker(JpegConstants.Markers.EOI, (int)stream.Length, true);
}
suffix = (byte)value;
}
return new FileMarker((ushort)((prefix << 8) | suffix), (int)(stream.Position - 2));
}
}
/// <summary> /// <summary>
/// Decodes the image from the specified <see cref="Stream"/> and sets /// Decodes the image from the specified <see cref="Stream"/> and sets
/// the data to image. /// the data to image.
@ -205,9 +244,9 @@ namespace ImageSharp.Formats.Jpeg.Port
/// <inheritdoc/> /// <inheritdoc/>
public void Dispose() public void Dispose()
{ {
this.frame.Dispose(); this.frame?.Dispose();
this.components.Dispose(); this.components?.Dispose();
this.quantizationTables.Dispose(); this.quantizationTables?.Dispose();
// Set large fields to null. // Set large fields to null.
this.frame = null; this.frame = null;
@ -315,13 +354,14 @@ namespace ImageSharp.Formats.Jpeg.Port
{ {
// Rewind that last bytes we read // Rewind that last bytes we read
this.InputStream.Position -= 2; this.InputStream.Position -= 2;
break;
} }
break; throw new ImageFormatException($"Unknown Marker {fileMarker.Marker} at {fileMarker.Position}");
} }
// Read on. TODO: Test this on damaged images. // Read on. TODO: Test this on damaged images.
fileMarker = FindNextFileMarker(this.InputStream); fileMarker = FindNextFileMarkerNew(this.InputStream);
} }
this.width = this.frame.SamplesPerLine; this.width = this.frame.SamplesPerLine;

1
tests/ImageSharp.Benchmarks/Image/DecodeJpeg.cs

@ -14,6 +14,7 @@ namespace ImageSharp.Benchmarks.Image
using CoreSize = ImageSharp.Size; using CoreSize = ImageSharp.Size;
[Config(typeof(Config))]
public class DecodeJpeg : BenchmarkBase public class DecodeJpeg : BenchmarkBase
{ {
private byte[] jpegBytes; private byte[] jpegBytes;

Loading…
Cancel
Save