diff --git a/src/ImageSharp/Formats/Jpeg/Common/Block8x8.cs b/src/ImageSharp/Formats/Jpeg/Common/Block8x8.cs
index c04ba1f83..d686a5e25 100644
--- a/src/ImageSharp/Formats/Jpeg/Common/Block8x8.cs
+++ b/src/ImageSharp/Formats/Jpeg/Common/Block8x8.cs
@@ -9,7 +9,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Common
/// Represents a Jpeg block with coefficiens.
///
// ReSharper disable once InconsistentNaming
- internal unsafe struct Block8x8
+ internal unsafe struct Block8x8 : IEquatable
{
///
/// A number of scalar coefficients in a
@@ -44,6 +44,16 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Common
}
}
+ public static bool operator ==(Block8x8 left, Block8x8 right)
+ {
+ return left.Equals(right);
+ }
+
+ public static bool operator !=(Block8x8 left, Block8x8 right)
+ {
+ return !left.Equals(right);
+ }
+
///
/// Pointer-based "Indexer" (getter part)
///
@@ -74,6 +84,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Common
fp[idx] = value;
}
+ public short GetValueAt(int x, int y) => this[(y * 8) + x];
public Block8x8F AsFloatBlock()
{
@@ -124,5 +135,34 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Common
bld.Append(']');
return bld.ToString();
}
+
+ public bool Equals(Block8x8 other)
+ {
+ for (int i = 0; i < Size; i++)
+ {
+ if (this[i] != other[i])
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ public override bool Equals(object obj)
+ {
+ if (ReferenceEquals(null, obj))
+ {
+ return false;
+ }
+
+ return obj is Block8x8 && this.Equals((Block8x8)obj);
+ }
+
+ public override int GetHashCode()
+ {
+ return (this[0] * 31) + this[1];
+ }
+
}
}
\ No newline at end of file
diff --git a/src/ImageSharp/Formats/Jpeg/GolangPort/OldJpegDecoderCore.cs b/src/ImageSharp/Formats/Jpeg/GolangPort/OldJpegDecoderCore.cs
index a028215ba..856e31b33 100644
--- a/src/ImageSharp/Formats/Jpeg/GolangPort/OldJpegDecoderCore.cs
+++ b/src/ImageSharp/Formats/Jpeg/GolangPort/OldJpegDecoderCore.cs
@@ -120,7 +120,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
/// Gets the huffman trees
///
public OldHuffmanTree[] HuffmanTrees { get; }
-
+
///
/// Gets the quantization tables, in zigzag order.
///
@@ -182,6 +182,11 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
///
public bool IgnoreMetadata { get; private set; }
+ ///
+ /// Gets the decoded by this decoder instance.
+ ///
+ public ImageMetaData MetaData { get; private set; }
+
///
/// Decodes the image from the specified and sets
/// the data to image.
@@ -192,10 +197,9 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
public Image Decode(Stream stream)
where TPixel : struct, IPixel
{
- ImageMetaData metadata = new ImageMetaData();
- this.ProcessStream(metadata, stream, false);
+ this.ParseStream(stream, false);
this.ProcessBlocksIntoJpegImageChannels();
- Image image = this.ConvertJpegPixelsToImagePixels(metadata);
+ Image image = this.ConvertJpegPixelsToImagePixels();
return image;
}
@@ -254,11 +258,11 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
///
/// Read metadata from stream and read the blocks in the scans into .
///
- /// The metadata
/// The stream
/// Whether to decode metadata only.
- private void ProcessStream(ImageMetaData metadata, Stream stream, bool metadataOnly)
+ public void ParseStream(Stream stream, bool metadataOnly)
{
+ this.MetaData = new ImageMetaData();
this.InputStream = stream;
this.InputProcessor = new InputProcessor(stream, this.Temp);
@@ -405,10 +409,10 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
this.ProcessApplicationHeader(remaining);
break;
case OldJpegConstants.Markers.APP1:
- this.ProcessApp1Marker(remaining, metadata);
+ this.ProcessApp1Marker(remaining);
break;
case OldJpegConstants.Markers.APP2:
- this.ProcessApp2Marker(remaining, metadata);
+ this.ProcessApp2Marker(remaining);
break;
case OldJpegConstants.Markers.APP14:
this.ProcessApp14Marker(remaining);
@@ -475,12 +479,11 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
/// Convert the pixel data in and/or into pixels of
///
/// The pixel type
- /// The metadata for the image.
/// The decoded image.
- private Image ConvertJpegPixelsToImagePixels(ImageMetaData metadata)
+ private Image ConvertJpegPixelsToImagePixels()
where TPixel : struct, IPixel
{
- Image image = new Image(this.configuration, this.ImageWidth, this.ImageHeight, metadata);
+ var image = new Image(this.configuration, this.ImageWidth, this.ImageHeight, this.MetaData);
if (this.grayImage.IsInitialized)
{
@@ -929,7 +932,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
///
/// The remaining bytes in the segment block.
/// The image.
- private void ProcessApp1Marker(int remaining, ImageMetaData metadata)
+ private void ProcessApp1Marker(int remaining)
{
if (remaining < 6 || this.IgnoreMetadata)
{
@@ -948,7 +951,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
profile[5] == '\0')
{
this.isExif = true;
- metadata.ExifProfile = new ExifProfile(profile);
+ this.MetaData.ExifProfile = new ExifProfile(profile);
}
}
@@ -956,8 +959,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
/// Processes the App2 marker retrieving any stored ICC profile information
///
/// The remaining bytes in the segment block.
- /// The image.
- private void ProcessApp2Marker(int remaining, ImageMetaData metadata)
+ private void ProcessApp2Marker(int remaining)
{
// Length is 14 though we only need to check 12.
const int Icclength = 14;
@@ -987,13 +989,13 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
byte[] profile = new byte[remaining];
this.InputProcessor.ReadFull(profile, 0, remaining);
- if (metadata.IccProfile == null)
+ if (this.MetaData.IccProfile == null)
{
- metadata.IccProfile = new IccProfile(profile);
+ this.MetaData.IccProfile = new IccProfile(profile);
}
else
{
- metadata.IccProfile.Extend(profile);
+ this.MetaData.IccProfile.Extend(profile);
}
}
else
diff --git a/tests/ImageSharp.Tests/Formats/Jpg/Block8x8Tests.cs b/tests/ImageSharp.Tests/Formats/Jpg/Block8x8Tests.cs
index fafe56ee7..d77a46887 100644
--- a/tests/ImageSharp.Tests/Formats/Jpg/Block8x8Tests.cs
+++ b/tests/ImageSharp.Tests/Formats/Jpg/Block8x8Tests.cs
@@ -87,5 +87,43 @@ namespace SixLabors.ImageSharp.Tests
Assert.Equal(data, result);
}
+
+ [Fact]
+ public void Equality_WhenTrue()
+ {
+ short[] data = Create8x8ShortData();
+ var block1 = new Block8x8(data);
+ var block2 = new Block8x8(data);
+
+ block1[0] = 42;
+ block2[0] = 42;
+
+ Assert.Equal(block1, block2);
+ Assert.Equal(block1.GetHashCode(), block2.GetHashCode());
+ }
+
+ [Fact]
+ public void Equality_WhenFalse()
+ {
+ short[] data = Create8x8ShortData();
+ var block1 = new Block8x8(data);
+ var block2 = new Block8x8(data);
+
+ block1[0] = 42;
+ block2[0] = 666;
+
+ Assert.NotEqual(block1, block2);
+ }
+
+ [Fact]
+ public void GetValueAt()
+ {
+ var block = default(Block8x8);
+ block[8 * 3 + 5] = 42;
+
+ short value = block.GetValueAt(5, 3);
+
+ Assert.Equal(42, value);
+ }
}
}
\ No newline at end of file
diff --git a/tests/ImageSharp.Tests/Formats/Jpg/LibJpegTools.cs b/tests/ImageSharp.Tests/Formats/Jpg/LibJpegTools.cs
index 04e755310..11b769103 100644
--- a/tests/ImageSharp.Tests/Formats/Jpg/LibJpegTools.cs
+++ b/tests/ImageSharp.Tests/Formats/Jpg/LibJpegTools.cs
@@ -8,6 +8,7 @@ namespace SixLabors.ImageSharp.Tests
using BitMiracle.LibJpeg.Classic;
+ using SixLabors.ImageSharp.Formats.Jpeg.Common;
using SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort;
using SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components;
using SixLabors.ImageSharp.PixelFormats;
@@ -17,52 +18,6 @@ namespace SixLabors.ImageSharp.Tests
internal static class LibJpegTools
{
- public unsafe struct Block : IEquatable
- {
- public Block(short[] data)
- {
- this.Data = data;
- }
-
- public short[] Data { get; }
-
- public short this[int x, int y]
- {
- get => this.Data[y * 8 + x];
- set => this.Data[y * 8 + x] = value;
- }
-
- public bool Equals(Block other)
- {
- for (int i = 0; i < 64; i++)
- {
- if (this.Data[i] != other.Data[i]) return false;
- }
- return true;
- }
-
- public override bool Equals(object obj)
- {
- if (ReferenceEquals(null, obj)) return false;
- return obj is Block && Equals((Block)obj);
- }
-
- public override int GetHashCode()
- {
- return (this.Data != null ? this.Data.GetHashCode() : 0);
- }
-
- public static bool operator ==(Block left, Block right)
- {
- return left.Equals(right);
- }
-
- public static bool operator !=(Block left, Block right)
- {
- return !left.Equals(right);
- }
- }
-
public class SpectralData : IEquatable
{
public int ComponentCount { get; private set; }
@@ -187,9 +142,9 @@ namespace SixLabors.ImageSharp.Tests
ComponentData c1 = this.Components[1];
ComponentData c2 = this.Components[2];
- Block block0 = c0.Blocks[by, bx];
- Block block1 = c1.Blocks[by, bx];
- Block block2 = c2.Blocks[by, bx];
+ Block8x8 block0 = c0.Blocks[by, bx];
+ Block8x8 block1 = c1.Blocks[by, bx];
+ Block8x8 block2 = c2.Blocks[by, bx];
float d0 = (c0.MaxVal - c0.MinVal);
float d1 = (c1.MaxVal - c1.MinVal);
@@ -266,7 +221,7 @@ namespace SixLabors.ImageSharp.Tests
this.YCount = yCount;
this.XCount = xCount;
this.Index = index;
- this.Blocks = new Block[this.YCount, this.XCount];
+ this.Blocks = new Block8x8[this.YCount, this.XCount];
}
public Size Size => new Size(this.XCount, this.YCount);
@@ -277,7 +232,7 @@ namespace SixLabors.ImageSharp.Tests
public int XCount { get; }
- public Block[,] Blocks { get; private set; }
+ public Block8x8[,] Blocks { get; private set; }
public short MinVal { get; private set; } = short.MaxValue;
@@ -311,7 +266,7 @@ namespace SixLabors.ImageSharp.Tests
{
this.MinVal = Math.Min(this.MinVal, data.Min());
this.MaxVal = Math.Max(this.MaxVal, data.Max());
- this.Blocks[y, x] = new Block(data);
+ this.Blocks[y, x] = new Block8x8(data);
}
public static ComponentData Load(FrameComponent sc, int index)
@@ -353,7 +308,7 @@ namespace SixLabors.ImageSharp.Tests
internal void WriteToImage(int bx, int by, Image image)
{
- Block block = this.Blocks[by, bx];
+ Block8x8 block = this.Blocks[by, bx];
for (int y = 0; y < 8; y++)
{
@@ -372,10 +327,10 @@ namespace SixLabors.ImageSharp.Tests
}
}
- internal float GetBlockValue(Block block, int x, int y)
+ internal float GetBlockValue(Block8x8 block, int x, int y)
{
float d = (this.MaxVal - this.MinVal);
- float val = block[x, y];
+ float val = block.GetValueAt(x, y);
val -= this.MinVal;
val /= d;
return val;
@@ -394,8 +349,8 @@ namespace SixLabors.ImageSharp.Tests
{
for (int j = 0; j < this.XCount; j++)
{
- Block a = this.Blocks[i, j];
- Block b = other.Blocks[i, j];
+ Block8x8 a = this.Blocks[i, j];
+ Block8x8 b = other.Blocks[i, j];
if (!a.Equals(b)) return false;
}
}
diff --git a/tests/ImageSharp.Tests/Formats/Jpg/SpectralJpegTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/SpectralJpegTests.cs
index 4a2d4939e..84a900f32 100644
--- a/tests/ImageSharp.Tests/Formats/Jpg/SpectralJpegTests.cs
+++ b/tests/ImageSharp.Tests/Formats/Jpg/SpectralJpegTests.cs
@@ -59,7 +59,7 @@ namespace SixLabors.ImageSharp.Tests
[Theory]
[WithFileCollection(nameof(BaselineTestJpegs), PixelTypes.Rgba32)]
- public void JpegDecoderCore_ParseStream_SaveSpectralResult(TestImageProvider provider)
+ public void PdfJsDecoder_ParseStream_SaveSpectralResult(TestImageProvider provider)
where TPixel : struct, IPixel
{
JpegDecoderCore decoder = new JpegDecoderCore(Configuration.Default, new JpegDecoder());
@@ -77,7 +77,7 @@ namespace SixLabors.ImageSharp.Tests
[Theory]
[WithFileCollection(nameof(AllTestJpegs), PixelTypes.Rgba32)]
- public void CompareSpectralResults(TestImageProvider provider)
+ public void CompareSpectralResults_PdfJs(TestImageProvider provider)
where TPixel : struct, IPixel
{
JpegDecoderCore decoder = new JpegDecoderCore(Configuration.Default, new JpegDecoder());
@@ -95,7 +95,7 @@ namespace SixLabors.ImageSharp.Tests
bool equality = libJpegData.Equals(imageSharpData);
this.Output.WriteLine("Spectral data equality: " + equality);
- // Assert.Equal(libJpegData, imageSharpData);
+ Assert.Equal(libJpegData, imageSharpData);
}
}