diff --git a/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs b/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs
index 4eb770994..4f71d15b0 100644
--- a/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs
+++ b/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs
@@ -70,7 +70,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
private ushort resetInterval;
///
- /// Whether the image has a EXIF header
+ /// Whether the image has an EXIF marker
///
private bool isExif;
@@ -79,6 +79,16 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
///
private byte[] exifData;
+ ///
+ /// Whether the image has an ICC marker
+ ///
+ private bool isIcc;
+
+ ///
+ /// Contains ICC data
+ ///
+ private byte[] iccData;
+
///
/// Contains information about the JFIF marker
///
@@ -208,6 +218,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
{
this.ParseStream(stream);
this.InitExifProfile();
+ this.InitIccProfile();
this.InitDerivedMetaDataProperties();
return this.PostProcessIntoImage();
}
@@ -220,6 +231,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
{
this.ParseStream(stream, true);
this.InitExifProfile();
+ this.InitIccProfile();
this.InitDerivedMetaDataProperties();
return new ImageInfo(new PixelTypeInfo(this.BitsPerPixel), this.ImageWidth, this.ImageHeight, this.MetaData);
}
@@ -412,7 +424,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
}
///
- /// Initializes the exif profile.
+ /// Initializes the EXIF profile.
///
private void InitExifProfile()
{
@@ -422,6 +434,21 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
}
}
+ ///
+ /// Initializes the ICC profile.
+ ///
+ private void InitIccProfile()
+ {
+ if (this.isIcc)
+ {
+ var profile = new IccProfile(this.iccData);
+ if (profile.CheckIsValid())
+ {
+ this.MetaData.IccProfile = profile;
+ }
+ }
+ }
+
///
/// Assigns derived metadata properties to , eg. horizontal and vertical resolution if it has a JFIF header.
///
@@ -450,11 +477,19 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
this.MetaData.ResolutionUnits = UnitConverter.ExifProfileToResolutionUnit(this.MetaData.ExifProfile);
}
}
+ }
- if (this.MetaData.IccProfile?.CheckIsValid() == false)
- {
- this.MetaData.IccProfile = null;
- }
+ ///
+ /// Extends the profile with additional data.
+ ///
+ /// The profile data array.
+ /// The array containing addition profile data.
+ private void ExtendProfile(ref byte[] profile, byte[] extension)
+ {
+ int currentLength = profile.Length;
+
+ Array.Resize(ref profile, currentLength + extension.Length);
+ Buffer.BlockCopy(extension, 0, profile, currentLength, extension.Length);
}
///
@@ -488,7 +523,8 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
/// The remaining bytes in the segment block.
private void ProcessApp1Marker(int remaining)
{
- if (remaining < 6 || this.IgnoreMetadata)
+ const int Exif00 = 6;
+ if (remaining < Exif00 || this.IgnoreMetadata)
{
// Skip the application header length
this.InputStream.Skip(remaining);
@@ -503,29 +539,17 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
this.isExif = true;
if (this.exifData == null)
{
- // the first 6 bytes (Exif00) will be skipped, because this is Jpeg specific
- this.exifData = profile.Skip(6).ToArray();
+ // The first 6 bytes (Exif00) will be skipped, because this is Jpeg specific
+ this.exifData = profile.Skip(Exif00).ToArray();
}
else
{
- // if the exif information exceeds 64K, it will be split over multiple APP1 markers
- this.ExtendExif(profile.Skip(6).ToArray());
+ // If the EXIF information exceeds 64K, it will be split over multiple APP1 markers
+ this.ExtendProfile(ref this.exifData, profile.Skip(Exif00).ToArray());
}
}
}
- ///
- /// Extends the exif profile with additional data.
- ///
- /// The array containing addition profile data.
- private void ExtendExif(byte[] bytes)
- {
- int currentLength = this.exifData.Length;
-
- Array.Resize(ref this.exifData, currentLength + bytes.Length);
- Buffer.BlockCopy(bytes, 0, this.exifData, currentLength, bytes.Length);
- }
-
///
/// Processes the App2 marker retrieving any stored ICC profile information
///
@@ -546,16 +570,18 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
if (ProfileResolver.IsProfile(identifier, ProfileResolver.IccMarker))
{
+ this.isIcc = true;
byte[] profile = new byte[remaining];
this.InputStream.Read(profile, 0, remaining);
- if (this.MetaData.IccProfile == null)
+ if (this.iccData == null)
{
- this.MetaData.IccProfile = new IccProfile(profile);
+ this.iccData = profile;
}
else
{
- this.MetaData.IccProfile.Extend(profile);
+ // If the ICC information exceeds 64K, it will be split over multiple APP2 markers
+ this.ExtendProfile(ref this.iccData, profile);
}
}
else
@@ -670,7 +696,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
/// The remaining bytes in the segment block.
/// The current frame marker.
/// Whether to parse metadata only
- private void ProcessStartOfFrameMarker(int remaining, JpegFileMarker frameMarker, bool metadataOnly)
+ private void ProcessStartOfFrameMarker(int remaining, in JpegFileMarker frameMarker, bool metadataOnly)
{
if (this.Frame != null)
{
diff --git a/src/ImageSharp/MetaData/Profiles/ICC/IccProfile.cs b/src/ImageSharp/MetaData/Profiles/ICC/IccProfile.cs
index db1d96d7e..2b2fe1e4e 100644
--- a/src/ImageSharp/MetaData/Profiles/ICC/IccProfile.cs
+++ b/src/ImageSharp/MetaData/Profiles/ICC/IccProfile.cs
@@ -149,17 +149,6 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
#endif
- ///
- /// Extends the profile with additional data.
- ///
- /// The array containing addition profile data.
- public void Extend(byte[] bytes)
- {
- int currentLength = this.data.Length;
- Array.Resize(ref this.data, currentLength + bytes.Length);
- Buffer.BlockCopy(bytes, 0, this.data, currentLength, bytes.Length);
- }
-
///
/// Checks for signs of a corrupt profile.
///