diff --git a/src/ImageSharp/Formats/Jpeg/GolangPort/OrigJpegDecoderCore.cs b/src/ImageSharp/Formats/Jpeg/GolangPort/OrigJpegDecoderCore.cs
index f5d3e7c18..8369e9236 100644
--- a/src/ImageSharp/Formats/Jpeg/GolangPort/OrigJpegDecoderCore.cs
+++ b/src/ImageSharp/Formats/Jpeg/GolangPort/OrigJpegDecoderCore.cs
@@ -58,20 +58,25 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
private bool adobeTransformValid;
///
- /// Whether the image has a JFIF header
+ /// The horizontal resolution. Calculated if the image has a JFIF header.
///
- private bool isJfif;
+ private short horizontalResolution;
///
- /// Contains information about the JFIF marker
+ /// Whether the image has a JFIF header
///
- private JFifMarker jFif;
+ private bool isJfif;
///
/// Whether the image has a EXIF header
///
private bool isExif;
+ ///
+ /// The vertical resolution. Calculated if the image has a JFIF header.
+ ///
+ private short verticalResolution;
+
///
/// Initializes a new instance of the class.
///
@@ -356,7 +361,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
break;
case OrigJpegConstants.Markers.APP0:
- this.ProcessApplicationHeaderMarker(remaining);
+ this.ProcessApplicationHeader(remaining);
break;
case OrigJpegConstants.Markers.APP1:
this.ProcessApp1Marker(remaining);
@@ -387,76 +392,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
}
}
- this.AssignResolution();
- }
-
- ///
- /// Processes the application header containing the JFIF identifier plus extra data.
- ///
- /// The remaining bytes in the segment block.
- private void ProcessApplicationHeaderMarker(int remaining)
- {
- if (remaining < 5)
- {
- // Skip the application header length
- this.InputProcessor.Skip(remaining);
- return;
- }
-
- this.InputProcessor.ReadFull(this.Temp, 0, 13);
- remaining -= 13;
-
- this.isJfif = this.Temp[0] == OrigJpegConstants.JFif.J &&
- this.Temp[1] == OrigJpegConstants.JFif.F &&
- this.Temp[2] == OrigJpegConstants.JFif.I &&
- this.Temp[3] == OrigJpegConstants.JFif.F &&
- this.Temp[4] == OrigJpegConstants.JFif.Null;
-
- if (this.isJfif)
- {
- this.jFif = new JFifMarker
- {
- MajorVersion = this.Temp[5],
- MinorVersion = this.Temp[6],
- DensityUnits = this.Temp[7],
- XDensity = (short)((this.Temp[8] << 8) | this.Temp[9]),
- YDensity = (short)((this.Temp[10] << 8) | this.Temp[11])
- };
- }
-
- // TODO: thumbnail
- if (remaining > 0)
- {
- this.InputStream.Skip(remaining);
- }
- }
-
- ///
- /// Processes the App1 marker retrieving any stored metadata
- ///
- /// The remaining bytes in the segment block.
- private void ProcessApp1Marker(int remaining)
- {
- if (remaining < 6 || this.IgnoreMetadata)
- {
- // Skip the application header length
- this.InputProcessor.Skip(remaining);
- return;
- }
-
- byte[] profile = new byte[remaining];
- this.InputProcessor.ReadFull(profile, 0, remaining);
-
- if (profile[0] == OrigJpegConstants.Exif.E &&
- profile[1] == OrigJpegConstants.Exif.X &&
- profile[2] == OrigJpegConstants.Exif.I &&
- profile[3] == OrigJpegConstants.Exif.F &&
- profile[4] == OrigJpegConstants.Exif.Null &&
- profile[5] == OrigJpegConstants.Exif.Null)
- {
- this.isExif = true;
- this.MetaData.ExifProfile = new ExifProfile(profile);
- }
+ this.InitDerivedMetaDataProperties();
}
///
@@ -476,11 +412,16 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
}
///
- /// Assigns the horizontal and vertical resolution to the image if it has a JFIF header or EXIF metadata.
+ /// Assigns derived metadata properties to , eg. horizontal and vertical resolution if it has a JFIF header.
///
- private void AssignResolution()
+ private void InitDerivedMetaDataProperties()
{
- if (this.isExif)
+ if (this.isJfif && this.horizontalResolution > 0 && this.verticalResolution > 0)
+ {
+ this.MetaData.HorizontalResolution = this.horizontalResolution;
+ this.MetaData.VerticalResolution = this.verticalResolution;
+ }
+ else if (this.isExif)
{
ExifValue horizontal = this.MetaData.ExifProfile.GetValue(ExifTag.XResolution);
ExifValue vertical = this.MetaData.ExifProfile.GetValue(ExifTag.YResolution);
@@ -493,11 +434,6 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
this.MetaData.VerticalResolution = verticalValue;
}
}
- else if (this.jFif.XDensity > 0 && this.jFif.YDensity > 0)
- {
- this.MetaData.HorizontalResolution = this.jFif.XDensity;
- this.MetaData.VerticalResolution = this.jFif.YDensity;
- }
}
///
@@ -554,6 +490,29 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
}
}
+ ///
+ /// Processes the App1 marker retrieving any stored metadata
+ ///
+ /// The remaining bytes in the segment block.
+ private void ProcessApp1Marker(int remaining)
+ {
+ if (remaining < 6 || this.IgnoreMetadata)
+ {
+ this.InputProcessor.Skip(remaining);
+ return;
+ }
+
+ byte[] profile = new byte[remaining];
+ this.InputProcessor.ReadFull(profile, 0, remaining);
+
+ if (profile[0] == 'E' && profile[1] == 'x' && profile[2] == 'i' && profile[3] == 'f' && profile[4] == '\0'
+ && profile[5] == '\0')
+ {
+ this.isExif = true;
+ this.MetaData.ExifProfile = new ExifProfile(profile);
+ }
+ }
+
///
/// Processes the App2 marker retrieving any stored ICC profile information
///
@@ -595,6 +554,37 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
}
}
+ ///
+ /// Processes the application header containing the JFIF identifier plus extra data.
+ ///
+ /// The remaining bytes in the segment block.
+ private void ProcessApplicationHeader(int remaining)
+ {
+ if (remaining < 5)
+ {
+ this.InputProcessor.Skip(remaining);
+ return;
+ }
+
+ this.InputProcessor.ReadFull(this.Temp, 0, 13);
+ remaining -= 13;
+
+ // TODO: We should be using constants for this.
+ this.isJfif = this.Temp[0] == 'J' && this.Temp[1] == 'F' && this.Temp[2] == 'I' && this.Temp[3] == 'F'
+ && this.Temp[4] == '\x00';
+
+ if (this.isJfif)
+ {
+ this.horizontalResolution = (short)(this.Temp[9] + (this.Temp[8] << 8));
+ this.verticalResolution = (short)(this.Temp[11] + (this.Temp[10] << 8));
+ }
+
+ if (remaining > 0)
+ {
+ this.InputProcessor.Skip(remaining);
+ }
+ }
+
///
/// Processes a Define Huffman Table marker, and initializes a huffman
/// struct from its contents. Specified in section B.2.4.2.