Browse Source

Add test for ICCP

pull/2109/head
Brian Popow 4 years ago
parent
commit
5bac8b36bf
  1. 8
      src/ImageSharp/Formats/Webp/BitWriter/BitWriterBase.cs
  2. 10
      src/ImageSharp/Formats/Webp/BitWriter/Vp8BitWriter.cs
  3. 10
      src/ImageSharp/Formats/Webp/BitWriter/Vp8LBitWriter.cs
  4. 31
      tests/ImageSharp.Tests/Formats/WebP/WebpMetaDataTests.cs

8
src/ImageSharp/Formats/Webp/BitWriter/BitWriterBase.cs

@ -98,7 +98,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.BitWriter
}
/// <summary>
/// Calculates the chunk size of EXIF or XMP metadata.
/// Calculates the chunk size of EXIF, XMP or ICCP metadata.
/// </summary>
/// <param name="metadataBytes">The metadata profile bytes.</param>
/// <returns>The metadata chunk size in bytes.</returns>
@ -209,11 +209,11 @@ namespace SixLabors.ImageSharp.Formats.Webp.BitWriter
/// <param name="stream">The stream to write to.</param>
/// <param name="exifProfile">A exif profile or null, if it does not exist.</param>
/// <param name="xmpProfile">A XMP profile or null, if it does not exist.</param>
/// <param name="iccProfile">The color profile.</param>
/// <param name="iccProfileBytes">The color profile bytes.</param>
/// <param name="width">The width of the image.</param>
/// <param name="height">The height of the image.</param>
/// <param name="hasAlpha">Flag indicating, if a alpha channel is present.</param>
protected void WriteVp8XHeader(Stream stream, ExifProfile exifProfile, XmpProfile xmpProfile, IccProfile iccProfile, uint width, uint height, bool hasAlpha)
protected void WriteVp8XHeader(Stream stream, ExifProfile exifProfile, XmpProfile xmpProfile, byte[] iccProfileBytes, uint width, uint height, bool hasAlpha)
{
if (width > MaxDimension || height > MaxDimension)
{
@ -245,7 +245,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.BitWriter
flags |= 16;
}
if (iccProfile != null)
if (iccProfileBytes != null)
{
// Set iccp flag.
flags |= 32;

10
src/ImageSharp/Formats/Webp/BitWriter/Vp8BitWriter.cs

@ -481,7 +481,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.BitWriter
riffSize += WebpConstants.TagSize + WebpConstants.ChunkHeaderSize + vp8Size;
// Emit headers and partition #0
this.WriteWebpHeaders(stream, size0, vp8Size, riffSize, isVp8X, width, height, exifProfile, xmpProfile, iccProfile, hasAlpha, alphaData, alphaDataIsCompressed);
this.WriteWebpHeaders(stream, size0, vp8Size, riffSize, isVp8X, width, height, exifProfile, xmpProfile, iccProfileBytes, hasAlpha, alphaData, alphaDataIsCompressed);
bitWriterPartZero.WriteToStream(stream);
// Write the encoded image to the stream.
@ -679,7 +679,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.BitWriter
uint height,
ExifProfile exifProfile,
XmpProfile xmpProfile,
IccProfile iccProfile,
byte[] iccProfileBytes,
bool hasAlpha,
Span<byte> alphaData,
bool alphaDataIsCompressed)
@ -689,11 +689,11 @@ namespace SixLabors.ImageSharp.Formats.Webp.BitWriter
// Write VP8X, header if necessary.
if (isVp8X)
{
this.WriteVp8XHeader(stream, exifProfile, xmpProfile, iccProfile, width, height, hasAlpha);
this.WriteVp8XHeader(stream, exifProfile, xmpProfile, iccProfileBytes, width, height, hasAlpha);
if (iccProfile != null)
if (iccProfileBytes != null)
{
this.WriteColorProfile(stream, iccProfile.ToByteArray());
this.WriteColorProfile(stream, iccProfileBytes);
}
if (hasAlpha)

10
src/ImageSharp/Formats/Webp/BitWriter/Vp8LBitWriter.cs

@ -149,7 +149,6 @@ namespace SixLabors.ImageSharp.Formats.Webp.BitWriter
if (exifProfile != null)
{
isVp8X = true;
riffSize += ExtendedFileChunkSize;
exifBytes = exifProfile.ToByteArray();
riffSize += this.MetadataChunkSize(exifBytes);
}
@ -157,7 +156,6 @@ namespace SixLabors.ImageSharp.Formats.Webp.BitWriter
if (xmpProfile != null)
{
isVp8X = true;
riffSize += ExtendedFileChunkSize;
xmpBytes = xmpProfile.Data;
riffSize += this.MetadataChunkSize(xmpBytes);
}
@ -165,11 +163,15 @@ namespace SixLabors.ImageSharp.Formats.Webp.BitWriter
if (iccProfile != null)
{
isVp8X = true;
riffSize += ExtendedFileChunkSize;
iccBytes = iccProfile.ToByteArray();
riffSize += this.MetadataChunkSize(iccBytes);
}
if (isVp8X)
{
riffSize += ExtendedFileChunkSize;
}
this.Finish();
uint size = (uint)this.NumBytes();
size++; // One byte extra for the VP8L signature.
@ -182,7 +184,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.BitWriter
// Write VP8X, header if necessary.
if (isVp8X)
{
this.WriteVp8XHeader(stream, exifProfile, xmpProfile, iccProfile, width, height, hasAlpha);
this.WriteVp8XHeader(stream, exifProfile, xmpProfile, iccBytes, width, height, hasAlpha);
if (iccBytes != null)
{

31
tests/ImageSharp.Tests/Formats/WebP/WebpMetaDataTests.cs

@ -152,6 +152,37 @@ namespace SixLabors.ImageSharp.Tests.Formats.Webp
Assert.Equal(expectedExif.Values.Count, actualExif.Values.Count);
}
[Theory]
[WithFile(TestImages.Webp.Lossy.WithIccp, PixelTypes.Rgba32, WebpFileFormatType.Lossless)]
[WithFile(TestImages.Webp.Lossy.WithIccp, PixelTypes.Rgba32, WebpFileFormatType.Lossy)]
public void Encode_PreservesColorProfile<TPixel>(TestImageProvider<TPixel> provider, WebpFileFormatType fileFormat)
where TPixel : unmanaged, IPixel<TPixel>
{
using (Image<TPixel> input = provider.GetImage(new WebpDecoder()))
{
ImageSharp.Metadata.Profiles.Icc.IccProfile expectedProfile = input.Metadata.IccProfile;
byte[] expectedProfileBytes = expectedProfile.ToByteArray();
using (var memStream = new MemoryStream())
{
input.Save(memStream, new WebpEncoder()
{
FileFormat = fileFormat
});
memStream.Position = 0;
using (var output = Image.Load<Rgba32>(memStream))
{
ImageSharp.Metadata.Profiles.Icc.IccProfile actualProfile = output.Metadata.IccProfile;
byte[] actualProfileBytes = actualProfile.ToByteArray();
Assert.NotNull(actualProfile);
Assert.Equal(expectedProfileBytes, actualProfileBytes);
}
}
}
}
[Theory]
[WithFile(TestImages.Webp.Lossy.WithExifNotEnoughData, PixelTypes.Rgba32)]
public void WebpDecoder_IgnoresInvalidExifChunk<TPixel>(TestImageProvider<TPixel> provider)

Loading…
Cancel
Save