Browse Source

Replace AppHead and App1

af/merge-core
James Jackson-South 9 years ago
parent
commit
fcf373cefb
  1. 156
      src/ImageSharp/Formats/Jpeg/GolangPort/OrigJpegDecoderCore.cs

156
src/ImageSharp/Formats/Jpeg/GolangPort/OrigJpegDecoderCore.cs

@ -57,25 +57,20 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
/// </summary>
private bool adobeTransformValid;
/// <summary>
/// The horizontal resolution. Calculated if the image has a JFIF header.
/// </summary>
private short horizontalResolution;
/// <summary>
/// Whether the image has a JFIF header
/// </summary>
private bool isJfif;
/// <summary>
/// Whether the image has a EXIF header
/// Contains information about the JFIF marker
/// </summary>
private bool isExif;
private JFifMarker jFif;
/// <summary>
/// The vertical resolution. Calculated if the image has a JFIF header.
/// Whether the image has a EXIF header
/// </summary>
private short verticalResolution;
private bool isExif;
/// <summary>
/// Initializes a new instance of the <see cref="OrigJpegDecoderCore" /> 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();
}
/// <summary>
/// Processes the application header containing the JFIF identifier plus extra data.
/// </summary>
/// <param name="remaining">The remaining bytes in the segment block.</param>
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);
}
}
/// <summary>
/// Processes the App1 marker retrieving any stored metadata
/// </summary>
/// <param name="remaining">The remaining bytes in the segment block.</param>
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);
}
}
/// <summary>
@ -412,16 +476,11 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
}
/// <summary>
/// Assigns derived metadata properties to <see cref="MetaData"/>, 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.
/// </summary>
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;
}
}
/// <summary>
@ -490,29 +554,6 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
}
}
/// <summary>
/// Processes the App1 marker retrieving any stored metadata
/// </summary>
/// <param name="remaining">The remaining bytes in the segment block.</param>
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);
}
}
/// <summary>
/// Processes the App2 marker retrieving any stored ICC profile information
/// </summary>
@ -554,37 +595,6 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
}
}
/// <summary>
/// Processes the application header containing the JFIF identifier plus extra data.
/// </summary>
/// <param name="remaining">The remaining bytes in the segment block.</param>
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);
}
}
/// <summary>
/// Processes a Define Huffman Table marker, and initializes a huffman
/// struct from its contents. Specified in section B.2.4.2.

Loading…
Cancel
Save