Browse Source

Fix #1712

pull/1779/head
James Jackson-South 4 years ago
parent
commit
88bb74f39f
  1. 25
      src/ImageSharp/Formats/Jpeg/JpegEncoder.cs
  2. 42
      src/ImageSharp/Formats/Jpeg/JpegEncoderCore.cs

25
src/ImageSharp/Formats/Jpeg/JpegEncoder.cs

@ -29,7 +29,6 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
where TPixel : unmanaged, IPixel<TPixel> where TPixel : unmanaged, IPixel<TPixel>
{ {
var encoder = new JpegEncoderCore(this); var encoder = new JpegEncoderCore(this);
this.InitializeColorType(image);
encoder.Encode(image, stream); encoder.Encode(image, stream);
} }
@ -45,31 +44,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
where TPixel : unmanaged, IPixel<TPixel> where TPixel : unmanaged, IPixel<TPixel>
{ {
var encoder = new JpegEncoderCore(this); var encoder = new JpegEncoderCore(this);
this.InitializeColorType(image);
return encoder.EncodeAsync(image, stream, cancellationToken); return encoder.EncodeAsync(image, stream, cancellationToken);
} }
/// <summary>
/// If ColorType was not set, set it based on the given image.
/// </summary>
private void InitializeColorType<TPixel>(Image<TPixel> image)
where TPixel : unmanaged, IPixel<TPixel>
{
// First inspect the image metadata.
if (this.ColorType == null)
{
JpegMetadata metadata = image.Metadata.GetJpegMetadata();
this.ColorType = metadata.ColorType;
}
// Secondly, inspect the pixel type.
if (this.ColorType == null)
{
bool isGrayscale =
typeof(TPixel) == typeof(L8) || typeof(TPixel) == typeof(L16) ||
typeof(TPixel) == typeof(La16) || typeof(TPixel) == typeof(La32);
this.ColorType = isGrayscale ? JpegColorType.Luminance : JpegColorType.YCbCrRatio420;
}
}
} }
} }

42
src/ImageSharp/Formats/Jpeg/JpegEncoderCore.cs

@ -86,10 +86,10 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
ImageMetadata metadata = image.Metadata; ImageMetadata metadata = image.Metadata;
JpegMetadata jpegMetadata = metadata.GetJpegMetadata(); JpegMetadata jpegMetadata = metadata.GetJpegMetadata();
// If the color type was not specified by the user, preserve the color type of the input image, if it's a supported color type. // If the color type was not specified by the user, preserve the color type of the input image.
if (!this.colorType.HasValue && IsSupportedColorType(jpegMetadata.ColorType)) if (!this.colorType.HasValue)
{ {
this.colorType = jpegMetadata.ColorType; this.colorType = SetFallbackColorType(image);
} }
// Compute number of components based on color type in options. // Compute number of components based on color type in options.
@ -156,6 +156,42 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
stream.Flush(); stream.Flush();
} }
/// <summary>
/// If color type was not set, set it based on the given image.
/// Note, if there is no metadata and the image has multiple components this method
/// returns <see langword="null"/> defering the field assignment
/// to <see cref="InitQuantizationTables(int, JpegMetadata, out Block8x8F, out Block8x8F)"/>.
/// </summary>
private static JpegColorType? SetFallbackColorType<TPixel>(Image<TPixel> image)
where TPixel : unmanaged, IPixel<TPixel>
{
// First inspect the image metadata.
JpegColorType? colorType = null;
JpegMetadata metadata = image.Metadata.GetJpegMetadata();
if (IsSupportedColorType(metadata.ColorType))
{
colorType = metadata.ColorType;
}
// Secondly, inspect the pixel type.
// TODO: PixelTypeInfo should contain a component count!
if (colorType is null)
{
bool isGrayscale =
typeof(TPixel) == typeof(L8) || typeof(TPixel) == typeof(L16) ||
typeof(TPixel) == typeof(La16) || typeof(TPixel) == typeof(La32);
// We don't set multi-component color types here since we can set it based upon
// the quality in InitQuantizationTables.
if (isGrayscale)
{
colorType = JpegColorType.Luminance;
}
}
return colorType;
}
/// <summary> /// <summary>
/// Returns true, if the color type is supported by the encoder. /// Returns true, if the color type is supported by the encoder.
/// </summary> /// </summary>

Loading…
Cancel
Save