Skip to content

Commit 5388489

Browse files
committed
Add color profile tests
1 parent 106f6c0 commit 5388489

File tree

6 files changed

+55
-9
lines changed

6 files changed

+55
-9
lines changed

Diff for: src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs

+7-6
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ public void Encode<TPixel>(Image<TPixel> image, Stream stream, CancellationToken
163163
this.WriteBitmapFileHeader(stream, infoHeaderSize, colorPaletteSize, iccProfileSize, infoHeader, buffer);
164164
this.WriteBitmapInfoHeader(stream, infoHeader, buffer, infoHeaderSize);
165165
this.WriteImage(stream, image.Frames.RootFrame);
166-
this.WriteColorProfile(stream, metadata, buffer);
166+
this.WriteColorProfile(stream, iccProfileData, buffer);
167167

168168
stream.Flush();
169169
}
@@ -246,14 +246,15 @@ private BmpInfoHeader CreateBmpInfoHeader(int width, int height, int infoHeaderS
246246
/// Writes the color profile to the stream.
247247
/// </summary>
248248
/// <param name="stream">The stream to write to.</param>
249-
/// <param name="metadata">The metadata.</param>
249+
/// <param name="iccProfileData">The color profile data.</param>
250250
/// <param name="buffer">The buffer.</param>
251-
private void WriteColorProfile(Stream stream, ImageMetadata metadata, Span<byte> buffer)
251+
private void WriteColorProfile(Stream stream, byte[] iccProfileData, Span<byte> buffer)
252252
{
253-
if (metadata.IccProfile != null)
253+
if (iccProfileData != null)
254254
{
255-
int streamPositionAfterImageData = (int)stream.Position;
256-
stream.Write(metadata.IccProfile.ToByteArray());
255+
// The offset, in bytes, from the beginning of the BITMAPV5HEADER structure to the start of the profile data.
256+
int streamPositionAfterImageData = (int)stream.Position - BmpFileHeader.Size;
257+
stream.Write(iccProfileData);
257258
BinaryPrimitives.WriteInt32LittleEndian(buffer, streamPositionAfterImageData);
258259
stream.Position = BmpFileHeader.Size + 112;
259260
stream.Write(buffer.Slice(0, 4));

Diff for: tests/ImageSharp.Tests/Formats/Bmp/BmpDecoderTests.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,10 @@ public class BmpDecoderTests
2929

3030
public static readonly string[] BitfieldsBmpFiles = BitFields;
3131

32-
private static BmpDecoder BmpDecoder => new BmpDecoder();
32+
private static BmpDecoder BmpDecoder => new();
3333

3434
public static readonly TheoryData<string, int, int, PixelResolutionUnit> RatioFiles =
35-
new TheoryData<string, int, int, PixelResolutionUnit>
35+
new()
3636
{
3737
{ Car, 3780, 3780, PixelResolutionUnit.PixelsPerMeter },
3838
{ V5Header, 3780, 3780, PixelResolutionUnit.PixelsPerMeter },

Diff for: tests/ImageSharp.Tests/Formats/Bmp/BmpEncoderTests.cs

+27
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,33 @@ public void Encode_8BitColor_WithOctreeQuantizer<TPixel>(TestImageProvider<TPixe
301301
public void Encode_PreservesAlpha<TPixel>(TestImageProvider<TPixel> provider, BmpBitsPerPixel bitsPerPixel)
302302
where TPixel : unmanaged, IPixel<TPixel> => TestBmpEncoderCore(provider, bitsPerPixel, supportTransparency: true);
303303

304+
[Theory]
305+
[WithFile(IccProfile, PixelTypes.Rgba32)]
306+
public void Encode_PreservesColorProfile<TPixel>(TestImageProvider<TPixel> provider)
307+
where TPixel : unmanaged, IPixel<TPixel>
308+
{
309+
using (Image<TPixel> input = provider.GetImage(new BmpDecoder()))
310+
{
311+
ImageSharp.Metadata.Profiles.Icc.IccProfile expectedProfile = input.Metadata.IccProfile;
312+
byte[] expectedProfileBytes = expectedProfile.ToByteArray();
313+
314+
using (var memStream = new MemoryStream())
315+
{
316+
input.Save(memStream, new BmpEncoder());
317+
318+
memStream.Position = 0;
319+
using (var output = Image.Load<Rgba32>(memStream))
320+
{
321+
ImageSharp.Metadata.Profiles.Icc.IccProfile actualProfile = output.Metadata.IccProfile;
322+
byte[] actualProfileBytes = actualProfile.ToByteArray();
323+
324+
Assert.NotNull(actualProfile);
325+
Assert.Equal(expectedProfileBytes, actualProfileBytes);
326+
}
327+
}
328+
}
329+
}
330+
304331
[Theory]
305332
[WithFile(Car, PixelTypes.Rgba32, BmpBitsPerPixel.Pixel32)]
306333
[WithFile(V5Header, PixelTypes.Rgba32, BmpBitsPerPixel.Pixel32)]

Diff for: tests/ImageSharp.Tests/Formats/Bmp/BmpMetadataTests.cs

+15-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
using System.IO;
55
using SixLabors.ImageSharp.Formats.Bmp;
6-
6+
using SixLabors.ImageSharp.PixelFormats;
77
using Xunit;
88
using static SixLabors.ImageSharp.Tests.TestImages.Bmp;
99

@@ -47,5 +47,19 @@ public void Identify_DetectsCorrectBitmapInfoHeaderType(string imagePath, BmpInf
4747
Assert.Equal(expectedInfoHeaderType, bitmapMetadata.InfoHeaderType);
4848
}
4949
}
50+
51+
[Theory]
52+
[WithFile(IccProfile, PixelTypes.Rgba32)]
53+
public void Decoder_CanReadColorProfile<TPixel>(TestImageProvider<TPixel> provider)
54+
where TPixel : unmanaged, IPixel<TPixel>
55+
{
56+
using (Image<TPixel> image = provider.GetImage(new BmpDecoder()))
57+
{
58+
ImageSharp.Metadata.ImageMetadata metaData = image.Metadata;
59+
Assert.NotNull(metaData);
60+
Assert.NotNull(metaData.IccProfile);
61+
Assert.Equal(16, metaData.IccProfile.Entries.Length);
62+
}
63+
}
5064
}
5165
}

Diff for: tests/ImageSharp.Tests/TestImages.cs

+1
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,7 @@ public static class Bmp
379379
public const string Rgb24jpeg = "Bmp/rgb24jpeg.bmp";
380380
public const string Rgb24png = "Bmp/rgb24png.bmp";
381381
public const string Rgba32v4 = "Bmp/rgba32v4.bmp";
382+
public const string IccProfile = "Bmp/BMP_v5_with_ICC_2.bmp";
382383

383384
// Bitmap images with compression type BITFIELDS.
384385
public const string Rgb32bfdef = "Bmp/rgb32bfdef.bmp";

Diff for: tests/Images/Input/Bmp/BMP_v5_with_ICC_2.bmp

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
version https://git-lfs.github.com/spec/v1
2+
oid sha256:b5b483e9a9d3f3ebdeada2eff70800002c27c046bf971206af0ecc73fa1416e6
3+
size 27782

0 commit comments

Comments
 (0)