diff --git a/src/ImageSharp/Formats/Jpeg/Port/Components/ScanDecoder.cs b/src/ImageSharp/Formats/Jpeg/Port/Components/ScanDecoder.cs
index 09837aef0..b0c9979d2 100644
--- a/src/ImageSharp/Formats/Jpeg/Port/Components/ScanDecoder.cs
+++ b/src/ImageSharp/Formats/Jpeg/Port/Components/ScanDecoder.cs
@@ -49,18 +49,31 @@ namespace ImageSharp.Formats.Jpeg.Port.Components
/// The DC Huffman tables
/// The AC Huffman tables
/// The scan components
+ /// The component index within the array
+ /// The length of the components. Different to the array length
/// The reset interval
/// The spectral selection start
/// The spectral selection end
/// The successive approximation bit high end
/// The successive approximation bit low end
- public void DecodeScan(Frame frame, Stream stream, HuffmanTables dcHuffmanTables, HuffmanTables acHuffmanTables, FrameComponent[] components, ushort resetInterval, int spectralStart, int spectralEnd, int successivePrev, int successive)
+ public void DecodeScan(
+ Frame frame,
+ Stream stream,
+ HuffmanTables dcHuffmanTables,
+ HuffmanTables acHuffmanTables,
+ FrameComponent[] components,
+ int componentIndex,
+ int componentsLength,
+ ushort resetInterval,
+ int spectralStart,
+ int spectralEnd,
+ int successivePrev,
+ int successive)
{
this.specStart = spectralStart;
this.specEnd = spectralEnd;
this.successiveState = successive;
bool progressive = frame.Progressive;
- int componentsLength = components.Length;
int mcusPerLine = frame.McusPerLine;
// TODO: Delegate action will not be fast
@@ -100,14 +113,14 @@ namespace ImageSharp.Formats.Jpeg.Port.Components
int mcuExpected;
if (componentsLength == 1)
{
- mcuExpected = components[0].BlocksPerLine * components[0].BlocksPerColumn;
+ mcuExpected = components[componentIndex].BlocksPerLine * components[componentIndex].BlocksPerColumn;
}
else
{
mcuExpected = mcusPerLine * frame.McusPerColumn;
}
- FileMarker fileMarker;
+ // FileMarker fileMarker;
while (mcu < mcuExpected)
{
// Reset interval stuff
@@ -122,7 +135,7 @@ namespace ImageSharp.Formats.Jpeg.Port.Components
if (componentsLength == 1)
{
- ref FrameComponent component = ref components[0];
+ ref FrameComponent component = ref components[componentIndex];
for (int n = 0; n < mcuToRead; n++)
{
DecodeBlock(dcHuffmanTables, acHuffmanTables, ref component, decodeFn, mcu, stream);
@@ -154,45 +167,41 @@ namespace ImageSharp.Formats.Jpeg.Port.Components
// Find marker
this.bitsCount = 0;
- // TODO: We need to make sure we are not overwriting anything here.
- fileMarker = JpegDecoderCore.FindNextFileMarker(stream);
-
- // Some bad images seem to pad Scan blocks with e.g. zero bytes, skip past
- // those to attempt to find a valid marker (fixes issue4090.pdf) in original code.
- if (fileMarker.Invalid)
- {
-#if DEBUG
- Debug.WriteLine("DecodeScan - Unexpected MCU data, next marker is: " + fileMarker.Marker.ToString("X"));
-#endif
- }
-
- ushort marker = fileMarker.Marker;
- if (marker <= 0xFF00)
- {
- throw new ImageFormatException("Marker was not found");
- }
-
- if (marker >= JpegConstants.Markers.RST0 && marker <= JpegConstants.Markers.RST7)
- {
- // RSTx
- stream.Skip(2);
- }
- else
- {
- break;
- }
+ // // TODO: We need to make sure we are not overwriting anything here.
+ // fileMarker = JpegDecoderCore.FindNextFileMarker(stream);
+ // // Some bad images seem to pad Scan blocks with e.g. zero bytes, skip past
+ // // those to attempt to find a valid marker (fixes issue4090.pdf) in original code.
+ // if (fileMarker.Invalid)
+ // {
+ // #if DEBUG
+ // Debug.WriteLine("DecodeScan - Unexpected MCU data, next marker is: " + fileMarker.Marker.ToString("X"));
+ // #endif
+ // }
+ // ushort marker = fileMarker.Marker;
+ // if (marker <= 0xFF00)
+ // {
+ // throw new ImageFormatException("Marker was not found");
+ // }
+ // if (marker >= JpegConstants.Markers.RST0 && marker <= JpegConstants.Markers.RST7)
+ // {
+ // // RSTx
+ // stream.Skip(2);
+ // }
+ // else
+ // {
+ // break;
+ // }
}
- fileMarker = JpegDecoderCore.FindNextFileMarker(stream);
-
- // Some images include more Scan blocks than expected, skip past those and
- // attempt to find the next valid marker (fixes issue8182.pdf) in original code.
- if (fileMarker.Invalid)
- {
-#if DEBUG
- Debug.WriteLine("DecodeScan - Unexpected MCU data, next marker is: " + fileMarker.Marker.ToString("X"));
-#endif
- }
+ // fileMarker = JpegDecoderCore.FindNextFileMarker(stream);
+ // // Some images include more Scan blocks than expected, skip past those and
+ // // attempt to find the next valid marker (fixes issue8182.pdf) in original code.
+ // if (fileMarker.Invalid)
+ // {
+ // #if DEBUG
+ // Debug.WriteLine("DecodeScan - Unexpected MCU data, next marker is: " + fileMarker.Marker.ToString("X"));
+ // #endif
+ // }
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -231,7 +240,7 @@ namespace ImageSharp.Formats.Jpeg.Port.Components
}
this.bitsData = stream.ReadByte();
- if (this.bitsData == 0xFF)
+ if (this.bitsData == JpegConstants.Markers.Prefix)
{
int nextByte = stream.ReadByte();
if (nextByte > 0)
@@ -252,8 +261,7 @@ namespace ImageSharp.Formats.Jpeg.Port.Components
HuffmanBranch[] node = tree;
while (true)
{
- int index;
- index = this.ReadBit(stream);
+ int index = this.ReadBit(stream);
HuffmanBranch branch = node[index];
node = branch.Children;
diff --git a/src/ImageSharp/Formats/Jpeg/Port/JpegDecoderCore.cs b/src/ImageSharp/Formats/Jpeg/Port/JpegDecoderCore.cs
index 5d50ae535..abdabcd49 100644
--- a/src/ImageSharp/Formats/Jpeg/Port/JpegDecoderCore.cs
+++ b/src/ImageSharp/Formats/Jpeg/Port/JpegDecoderCore.cs
@@ -87,35 +87,33 @@ namespace ImageSharp.Formats.Jpeg.Port
///
/// The input stream
/// The
- public static FileMarker FindNextFileMarkerOld(Stream stream)
+ public static FileMarker FindNextFileMarkerNew(Stream stream)
{
- byte[] buffer = new byte[2];
- int value = stream.Read(buffer, 0, 2);
+ byte[] marker = new byte[2];
+ int value = stream.Read(marker, 0, 2);
if (value == 0)
{
return new FileMarker(JpegConstants.Markers.EOI, (int)stream.Length, true);
}
- // 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."
- if (buffer[1] != JpegConstants.Markers.Prefix)
- {
- return new FileMarker((ushort)((buffer[0] << 8) | buffer[1]), (int)(stream.Position - 2));
- }
-
- while (buffer[1] == JpegConstants.Markers.Prefix)
+ if (marker[0] == JpegConstants.Markers.Prefix)
{
- int suffix = stream.ReadByte();
- if (suffix == -1)
+ // 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 (marker[1] == JpegConstants.Markers.Prefix)
{
- return new FileMarker(JpegConstants.Markers.EOI, (int)stream.Length, true);
- }
+ int suffix = stream.ReadByte();
+ if (suffix == -1)
+ {
+ return new FileMarker(JpegConstants.Markers.EOI, (int)stream.Length, true);
+ }
- buffer[1] = (byte)value;
+ marker[1] = (byte)value;
+ }
}
- return new FileMarker((ushort)((buffer[0] << 8) | buffer[1]), (int)(stream.Position - 2));
+ return new FileMarker((ushort)((marker[0] << 8) | marker[1]), (int)(stream.Position - 2));
}
///
@@ -292,6 +290,7 @@ namespace ImageSharp.Formats.Jpeg.Port
default:
+ // TODO: Not convinced this is required
// Skip back as it could be incorrect encoding -- last 0xFF byte of the previous
// block was eaten by the encoder
this.InputStream.Position -= 3;
@@ -308,7 +307,7 @@ namespace ImageSharp.Formats.Jpeg.Port
}
// Read on. TODO: Test this on damaged images.
- fileMarker = FindNextFileMarkerOld(this.InputStream);
+ fileMarker = FindNextFileMarkerNew(this.InputStream);
}
this.width = this.frame.SamplesPerLine;
@@ -547,7 +546,7 @@ namespace ImageSharp.Formats.Jpeg.Port
component.VerticalFactor = v;
component.QuantizationIdentifier = this.temp[index + 2];
- this.frame.ComponentIds[i] = (byte)i;
+ this.frame.ComponentIds[i] = component.Id;
index += 3;
}
@@ -623,16 +622,18 @@ namespace ImageSharp.Formats.Jpeg.Port
private void ProcessStartOfScanMarker()
{
int selectorsCount = this.InputStream.ReadByte();
+ int index = -1;
for (int i = 0; i < selectorsCount; i++)
{
- int index = -1;
+ index = -1;
int selector = this.InputStream.ReadByte();
- foreach (byte id in this.frame.ComponentIds)
+ for (int j = 0; j < this.frame.ComponentIds.Length; j++)
{
+ byte id = this.frame.ComponentIds[j];
if (selector == id)
{
- index = selector;
+ index = j;
}
}
@@ -641,8 +642,7 @@ namespace ImageSharp.Formats.Jpeg.Port
throw new ImageFormatException("Unknown component selector");
}
- byte componentIndex = this.frame.ComponentIds[index];
- ref FrameComponent component = ref this.frame.Components[componentIndex];
+ ref FrameComponent component = ref this.frame.Components[index];
int tableSpec = this.InputStream.ReadByte();
component.DCHuffmanTableId = tableSpec >> 4;
component.ACHuffmanTableId = tableSpec & 15;
@@ -661,6 +661,8 @@ namespace ImageSharp.Formats.Jpeg.Port
this.dcHuffmanTables,
this.acHuffmanTables,
this.frame.Components,
+ index,
+ selectorsCount,
this.resetInterval,
spectralStart,
spectralEnd,