diff --git a/src/ImageSharp/Formats/Jpeg/GolangPort/OrigJpegDecoderCore.cs b/src/ImageSharp/Formats/Jpeg/GolangPort/OrigJpegDecoderCore.cs
index 8369e9236..f5d3e7c18 100644
--- a/src/ImageSharp/Formats/Jpeg/GolangPort/OrigJpegDecoderCore.cs
+++ b/src/ImageSharp/Formats/Jpeg/GolangPort/OrigJpegDecoderCore.cs
@@ -57,25 +57,20 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
///
private bool adobeTransformValid;
- ///
- /// The horizontal resolution. Calculated if the image has a JFIF header.
- ///
- private short horizontalResolution;
-
///
/// Whether the image has a JFIF header
///
private bool isJfif;
///
- /// Whether the image has a EXIF header
+ /// Contains information about the JFIF marker
///
- private bool isExif;
+ private JFifMarker jFif;
///
- /// The vertical resolution. Calculated if the image has a JFIF header.
+ /// Whether the image has a EXIF header
///
- private short verticalResolution;
+ private bool isExif;
///
/// Initializes a new instance of the class.
@@ -361,7 +356,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
break;
case OrigJpegConstants.Markers.APP0:
- this.ProcessApplicationHeader(remaining);
+ this.ProcessApplicationHeaderMarker(remaining);
break;
case OrigJpegConstants.Markers.APP1:
this.ProcessApp1Marker(remaining);
@@ -392,7 +387,76 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
}
}
- this.InitDerivedMetaDataProperties();
+ 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);
+ }
}
///
@@ -412,16 +476,11 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
}
///
- /// Assigns derived metadata properties to , eg. horizontal and vertical resolution if it has a JFIF header.
+ /// Assigns the horizontal and vertical resolution to the image if it has a JFIF header or EXIF metadata.
///
- private void InitDerivedMetaDataProperties()
+ private void AssignResolution()
{
- if (this.isJfif && this.horizontalResolution > 0 && this.verticalResolution > 0)
- {
- this.MetaData.HorizontalResolution = this.horizontalResolution;
- this.MetaData.VerticalResolution = this.verticalResolution;
- }
- else if (this.isExif)
+ if (this.isExif)
{
ExifValue horizontal = this.MetaData.ExifProfile.GetValue(ExifTag.XResolution);
ExifValue vertical = this.MetaData.ExifProfile.GetValue(ExifTag.YResolution);
@@ -434,6 +493,11 @@ 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;
+ }
}
///
@@ -490,29 +554,6 @@ 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
///
@@ -554,37 +595,6 @@ 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.