Browse Source

At least render something when progressive.

This allows parsing of the broken eof images. The non-progressive
renders perfectly, the progressive appears to not render the final
scan.... or something.
pull/85/head
James Jackson-South 10 years ago
parent
commit
d05b06bbbd
  1. 25
      src/ImageSharp.Formats.Jpeg/Components/Decoder/JpegScanDecoder.cs
  2. 22
      src/ImageSharp.Formats.Jpeg/JpegDecoderCore.cs
  3. 6
      tests/ImageSharp.Tests/FileTestBase.cs
  4. 1
      tests/ImageSharp.Tests/TestImages.cs
  5. BIN
      tests/ImageSharp.Tests/TestImages/Formats/Jpg/badeofprog.jpg

25
src/ImageSharp.Formats.Jpeg/Components/Decoder/JpegScanDecoder.cs

@ -356,12 +356,22 @@ namespace ImageSharp.Formats.Jpg
throw new ImageFormatException("Excessive DC component"); throw new ImageFormatException("Excessive DC component");
} }
// TODO: Handle the EOFException and piece together the final progressive scan.
try
{
int deltaDC = decoder.Bits.ReceiveExtend(value, decoder); int deltaDC = decoder.Bits.ReceiveExtend(value, decoder);
this.pointers.Dc[compIndex] += deltaDC; this.pointers.Dc[compIndex] += deltaDC;
// b[0] = dc[compIndex] << al; // b[0] = dc[compIndex] << al;
Block8x8F.SetScalarAt(b, 0, this.pointers.Dc[compIndex] << this.al); Block8x8F.SetScalarAt(b, 0, this.pointers.Dc[compIndex] << this.al);
} }
catch (JpegDecoderCore.EOFException)
{
// Do something clever here. I'm just undoing ReceiveExtend
decoder.Bits.UnreadBits += value;
decoder.Bits.Mask >>= value;
}
}
if (zig <= this.zigEnd && this.eobRun > 0) if (zig <= this.zigEnd && this.eobRun > 0)
{ {
@ -383,7 +393,20 @@ namespace ImageSharp.Formats.Jpg
break; break;
} }
int ac = decoder.Bits.ReceiveExtend(val1, decoder); int ac; // = decoder.Bits.ReceiveExtend(val1, decoder);
// TODO: Handle the EOFException and piece together the final progressive scan.
try
{
ac = decoder.Bits.ReceiveExtend(val1, decoder);
}
catch (JpegDecoderCore.EOFException)
{
// Do something clever here. I'm just undoing ReceiveExtend
decoder.Bits.UnreadBits += val1;
decoder.Bits.Mask >>= val1;
break;
}
// b[Unzig[zig]] = ac << al; // b[Unzig[zig]] = ac << al;
Block8x8F.SetScalarAt(b, this.pointers.Unzig[zig], ac << this.al); Block8x8F.SetScalarAt(b, this.pointers.Unzig[zig], ac << this.al);

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

@ -186,11 +186,9 @@ namespace ImageSharp.Formats
throw new ImageFormatException("Missing SOI marker."); throw new ImageFormatException("Missing SOI marker.");
} }
// Process the remaining segments until the End Of Image marker. while (true)
bool processBytes = true; {
try
// we can't currently short circute progressive images so don't try.
while (processBytes)
{ {
this.ReadFull(this.Temp, 0, 2); this.ReadFull(this.Temp, 0, 2);
while (this.Temp[0] != 0xff) while (this.Temp[0] != 0xff)
@ -297,14 +295,7 @@ namespace ImageSharp.Formats
return; return;
} }
// when this is a progressive image this gets called a number of times
// need to know how many times this should be called in total.
this.ProcessStartOfScan(remaining); this.ProcessStartOfScan(remaining);
if (!this.IsProgressive)
{
// if this is not a progressive image we can stop processing bytes as we now have the image data.
processBytes = false;
}
break; break;
case JpegConstants.Markers.DRI: case JpegConstants.Markers.DRI:
@ -346,6 +337,13 @@ namespace ImageSharp.Formats
break; break;
} }
} }
catch (EOFException)
{
// For non-progressive images this is a simple way to handle a missing EOI
// TODO: For progressive we still have to handle the exception within JpegScanDecoder to include last scan
break;
}
}
if (this.grayImage.IsInitialized) if (this.grayImage.IsInitialized)
{ {

6
tests/ImageSharp.Tests/FileTestBase.cs

@ -22,9 +22,11 @@ namespace ImageSharp.Tests
// TestFile.Create(TestImages.Png.Pd), // Perf: Enable for local testing only // TestFile.Create(TestImages.Png.Pd), // Perf: Enable for local testing only
// TestFile.Create(TestImages.Jpeg.Floorplan), // Perf: Enable for local testing only // TestFile.Create(TestImages.Jpeg.Floorplan), // Perf: Enable for local testing only
TestFile.Create(TestImages.Jpeg.Calliphora), TestFile.Create(TestImages.Jpeg.Calliphora),
// TestFile.Create(TestImages.Jpeg.BadEOF), // Perf: Enable for local testing only
// TestFile.Create(TestImages.Jpeg.BadEOFProgressive),
// TestFile.Create(TestImages.Jpeg.Ycck), // Perf: Enable for local testing only // TestFile.Create(TestImages.Jpeg.Ycck), // Perf: Enable for local testing only
// TestFile.Create(TestImages.Jpeg.Cmyk), // Perf: Enable for local testing only // TestFile.Create(TestImages.Jpeg.Cmyk), // Perf: Enable for local testing only
TestFile.Create(TestImages.Jpeg.Turtle), // TestFile.Create(TestImages.Jpeg.Turtle), // Perf: Enable for local testing only
// TestFile.Create(TestImages.Jpeg.Fb), // Perf: Enable for local testing only // TestFile.Create(TestImages.Jpeg.Fb), // Perf: Enable for local testing only
// TestFile.Create(TestImages.Jpeg.Progress), // Perf: Enable for local testing only // TestFile.Create(TestImages.Jpeg.Progress), // Perf: Enable for local testing only
// TestFile.Create(TestImages.Jpeg.GammaDalaiLamaGray), // Perf: Enable for local testing only // TestFile.Create(TestImages.Jpeg.GammaDalaiLamaGray), // Perf: Enable for local testing only
@ -33,7 +35,7 @@ namespace ImageSharp.Tests
// TestFile.Create(TestImages.Png.Blur), // Perf: Enable for local testing only // TestFile.Create(TestImages.Png.Blur), // Perf: Enable for local testing only
// TestFile.Create(TestImages.Png.Indexed), // Perf: Enable for local testing only // TestFile.Create(TestImages.Png.Indexed), // Perf: Enable for local testing only
TestFile.Create(TestImages.Png.Splash), TestFile.Create(TestImages.Png.Splash),
TestFile.Create(TestImages.Png.Powerpoint), // TestFile.Create(TestImages.Png.Powerpoint), // Perf: Enable for local testing only
// TestFile.Create(TestImages.Png.SplashInterlaced), // Perf: Enable for local testing only // TestFile.Create(TestImages.Png.SplashInterlaced), // Perf: Enable for local testing only
// TestFile.Create(TestImages.Png.Interlaced), // Perf: Enable for local testing only // TestFile.Create(TestImages.Png.Interlaced), // Perf: Enable for local testing only
// TestFile.Create(TestImages.Png.Filter0), // Perf: Enable for local testing only // TestFile.Create(TestImages.Png.Filter0), // Perf: Enable for local testing only

1
tests/ImageSharp.Tests/TestImages.cs

@ -52,6 +52,7 @@ namespace ImageSharp.Tests
public const string Hiyamugi = "Jpg/Hiyamugi.jpg"; public const string Hiyamugi = "Jpg/Hiyamugi.jpg";
public const string BadEOF = "Jpg/badeof.jpg"; public const string BadEOF = "Jpg/badeof.jpg";
public const string BadEOFProgressive = "Jpg/badeofprog.jpg";
public const string Snake = "Jpg/Snake.jpg"; public const string Snake = "Jpg/Snake.jpg";
public const string Lake = "Jpg/Lake.jpg"; public const string Lake = "Jpg/Lake.jpg";

BIN
tests/ImageSharp.Tests/TestImages/Formats/Jpg/badeofprog.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Loading…
Cancel
Save