Browse Source

Add bmp and jpeg tests

pull/649/head
James Jackson-South 8 years ago
parent
commit
b176a0ec17
  1. 11
      src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs
  2. 52
      tests/ImageSharp.Tests/Formats/Bmp/BmpDecoderTests.cs
  3. 49
      tests/ImageSharp.Tests/Formats/Bmp/BmpEncoderTests.cs
  4. 88
      tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.MetaData.cs
  5. 65
      tests/ImageSharp.Tests/Formats/Jpg/JpegEncoderTests.cs
  6. 2
      tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs
  7. 16
      tests/ImageSharp.Tests/TestImages.cs
  8. BIN
      tests/Images/Input/Jpg/baseline/ratio-1x1.jpg

11
src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs

@ -5,6 +5,7 @@ using System;
using System.Buffers.Binary;
using System.IO;
using System.Runtime.CompilerServices;
using SixLabors.ImageSharp.Common.Helpers;
using SixLabors.ImageSharp.MetaData;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.Memory;
@ -524,13 +525,19 @@ namespace SixLabors.ImageSharp.Formats.Bmp
}
// Resolution is stored in PPM.
ImageMetaData meta = new ImageMetaData();
var meta = new ImageMetaData();
meta.ResolutionUnits = PixelResolutionUnit.PixelsPerMeter;
if (this.infoHeader.XPelsPerMeter > 0 && this.infoHeader.YPelsPerMeter > 0)
{
meta.ResolutionUnits = PixelResolutionUnit.PixelsPerMeter;
meta.HorizontalResolution = this.infoHeader.XPelsPerMeter;
meta.VerticalResolution = this.infoHeader.YPelsPerMeter;
}
else
{
// Convert default metadata values to PPM.
meta.HorizontalResolution = Math.Round(UnitConverter.InchToMeter(ImageMetaData.DefaultHorizontalResolution));
meta.VerticalResolution = Math.Round(UnitConverter.InchToMeter(ImageMetaData.DefaultVerticalResolution));
}
this.metaData = meta;

52
tests/ImageSharp.Tests/Formats/Bmp/BmpDecoderTests.cs

@ -10,17 +10,25 @@ using Xunit;
namespace SixLabors.ImageSharp.Tests
{
using SixLabors.ImageSharp.MetaData;
using static TestImages.Bmp;
public class BmpDecoderTests
{
public const PixelTypes CommonNonDefaultPixelTypes =
PixelTypes.Rgba32 | PixelTypes.Bgra32 | PixelTypes.RgbaVector;
public const PixelTypes CommonNonDefaultPixelTypes = PixelTypes.Rgba32 | PixelTypes.Bgra32 | PixelTypes.RgbaVector;
public static readonly string[] AllBmpFiles =
{
Car, F, NegHeight, CoreHeader, V5Header, RLE, RLEInverted, Bit8, Bit8Inverted, Bit16, Bit16Inverted
};
{
Car, F, NegHeight, CoreHeader, V5Header, RLE, RLEInverted, Bit8, Bit8Inverted, Bit16, Bit16Inverted
};
public static readonly TheoryData<string, int, int, PixelResolutionUnit> RatioFiles =
new TheoryData<string, int, int, PixelResolutionUnit>
{
{ TestImages.Bmp.Car, 3780, 3780 , PixelResolutionUnit.PixelsPerMeter },
{ TestImages.Bmp.V5Header, 3780, 3780 , PixelResolutionUnit.PixelsPerMeter },
{ TestImages.Bmp.RLE, 2835, 2835, PixelResolutionUnit.PixelsPerMeter }
};
[Theory]
[WithFileCollection(nameof(AllBmpFiles), PixelTypes.Rgba32)]
@ -64,5 +72,39 @@ namespace SixLabors.ImageSharp.Tests
Assert.Equal(expectedPixelSize, Image.Identify(stream)?.PixelType?.BitsPerPixel);
}
}
[Theory]
[MemberData(nameof(RatioFiles))]
public void Decode_VerifyRatio(string imagePath, int xResolution, int yResolution, PixelResolutionUnit resolutionUnit)
{
var testFile = TestFile.Create(imagePath);
using (var stream = new MemoryStream(testFile.Bytes, false))
{
var decoder = new BmpDecoder();
using (Image<Rgba32> image = decoder.Decode<Rgba32>(Configuration.Default, stream))
{
ImageMetaData meta = image.MetaData;
Assert.Equal(xResolution, meta.HorizontalResolution);
Assert.Equal(yResolution, meta.VerticalResolution);
Assert.Equal(resolutionUnit, meta.ResolutionUnits);
}
}
}
[Theory]
[MemberData(nameof(RatioFiles))]
public void Identify_VerifyRatio(string imagePath, int xResolution, int yResolution, PixelResolutionUnit resolutionUnit)
{
var testFile = TestFile.Create(imagePath);
using (var stream = new MemoryStream(testFile.Bytes, false))
{
var decoder = new BmpDecoder();
IImageInfo image = decoder.Identify(Configuration.Default, stream);
ImageMetaData meta = image.MetaData;
Assert.Equal(xResolution, meta.HorizontalResolution);
Assert.Equal(yResolution, meta.VerticalResolution);
Assert.Equal(resolutionUnit, meta.ResolutionUnits);
}
}
}
}

49
tests/ImageSharp.Tests/Formats/Bmp/BmpEncoderTests.cs

@ -1,7 +1,9 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System.IO;
using SixLabors.ImageSharp.Formats.Bmp;
using SixLabors.ImageSharp.MetaData;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
using Xunit;
@ -12,11 +14,19 @@ namespace SixLabors.ImageSharp.Tests
public class BmpEncoderTests : FileTestBase
{
public static readonly TheoryData<BmpBitsPerPixel> BitsPerPixel =
new TheoryData<BmpBitsPerPixel>
{
BmpBitsPerPixel.Pixel24,
BmpBitsPerPixel.Pixel32
};
new TheoryData<BmpBitsPerPixel>
{
BmpBitsPerPixel.Pixel24,
BmpBitsPerPixel.Pixel32
};
public static readonly TheoryData<string, int, int, PixelResolutionUnit> RatioFiles =
new TheoryData<string, int, int, PixelResolutionUnit>
{
{ TestImages.Bmp.Car, 3780, 3780 , PixelResolutionUnit.PixelsPerMeter },
{ TestImages.Bmp.V5Header, 3780, 3780 , PixelResolutionUnit.PixelsPerMeter },
{ TestImages.Bmp.RLE, 2835, 2835, PixelResolutionUnit.PixelsPerMeter }
};
public BmpEncoderTests(ITestOutputHelper output)
{
@ -25,6 +35,31 @@ namespace SixLabors.ImageSharp.Tests
private ITestOutputHelper Output { get; }
[Theory]
[MemberData(nameof(RatioFiles))]
public void Encode_PreserveRatio(string imagePath, int xResolution, int yResolution, PixelResolutionUnit resolutionUnit)
{
var options = new BmpEncoder();
var testFile = TestFile.Create(imagePath);
using (Image<Rgba32> input = testFile.CreateImage())
{
using (var memStream = new MemoryStream())
{
input.Save(memStream, options);
memStream.Position = 0;
using (var output = Image.Load<Rgba32>(memStream))
{
ImageMetaData meta = output.MetaData;
Assert.Equal(xResolution, meta.HorizontalResolution);
Assert.Equal(yResolution, meta.VerticalResolution);
Assert.Equal(resolutionUnit, meta.ResolutionUnits);
}
}
}
}
[Theory]
[WithTestPatternImages(nameof(BitsPerPixel), 24, 24, PixelTypes.Rgba32 | PixelTypes.Bgra32 | PixelTypes.Rgb24)]
public void Encode_IsNotBoundToSinglePixelType<TPixel>(TestImageProvider<TPixel> provider, BmpBitsPerPixel bitsPerPixel)
@ -44,10 +79,10 @@ namespace SixLabors.ImageSharp.Tests
{
TestBmpEncoderCore(provider, bitsPerPixel);
}
private static void TestBmpEncoderCore<TPixel>(TestImageProvider<TPixel> provider, BmpBitsPerPixel bitsPerPixel)
where TPixel : struct, IPixel<TPixel>
{
{
using (Image<TPixel> image = provider.GetImage())
{
// there is no alpha in bmp!

88
tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.MetaData.cs

@ -15,30 +15,39 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
using System.Runtime.CompilerServices;
using SixLabors.ImageSharp.Formats.Jpeg;
using SixLabors.ImageSharp.MetaData;
public partial class JpegDecoderTests
{
// TODO: A JPEGsnoop & metadata expert should review if the Exif/Icc expectations are correct.
// I'm seeing several entries with Exif-related names in images where we do not decode an exif profile. (- Anton)
public static readonly TheoryData<bool, string, int, bool, bool> MetaDataTestData =
new TheoryData<bool, string, int, bool, bool>
{
{ false, TestImages.Jpeg.Progressive.Progress, 24, false, false },
{ false, TestImages.Jpeg.Progressive.Fb, 24, false, true },
{ false, TestImages.Jpeg.Baseline.Cmyk, 32, false, true },
{ false, TestImages.Jpeg.Baseline.Ycck, 32, true, true },
{ false, TestImages.Jpeg.Baseline.Jpeg400, 8, false, false },
{ false, TestImages.Jpeg.Baseline.Snake, 24, true, true },
{ false, TestImages.Jpeg.Baseline.Jpeg420Exif, 24, true, false },
{ true, TestImages.Jpeg.Progressive.Progress, 24, false, false },
{ true, TestImages.Jpeg.Progressive.Fb, 24, false, true },
{ true, TestImages.Jpeg.Baseline.Cmyk, 32, false, true },
{ true, TestImages.Jpeg.Baseline.Ycck, 32, true, true },
{ true, TestImages.Jpeg.Baseline.Jpeg400, 8, false, false },
{ true, TestImages.Jpeg.Baseline.Snake, 24, true, true },
{ true, TestImages.Jpeg.Baseline.Jpeg420Exif, 24, true, false },
};
new TheoryData<bool, string, int, bool, bool>
{
{ false, TestImages.Jpeg.Progressive.Progress, 24, false, false },
{ false, TestImages.Jpeg.Progressive.Fb, 24, false, true },
{ false, TestImages.Jpeg.Baseline.Cmyk, 32, false, true },
{ false, TestImages.Jpeg.Baseline.Ycck, 32, true, true },
{ false, TestImages.Jpeg.Baseline.Jpeg400, 8, false, false },
{ false, TestImages.Jpeg.Baseline.Snake, 24, true, true },
{ false, TestImages.Jpeg.Baseline.Jpeg420Exif, 24, true, false },
{ true, TestImages.Jpeg.Progressive.Progress, 24, false, false },
{ true, TestImages.Jpeg.Progressive.Fb, 24, false, true },
{ true, TestImages.Jpeg.Baseline.Cmyk, 32, false, true },
{ true, TestImages.Jpeg.Baseline.Ycck, 32, true, true },
{ true, TestImages.Jpeg.Baseline.Jpeg400, 8, false, false },
{ true, TestImages.Jpeg.Baseline.Snake, 24, true, true },
{ true, TestImages.Jpeg.Baseline.Jpeg420Exif, 24, true, false },
};
public static readonly TheoryData<string, int, int, PixelResolutionUnit> RatioFiles =
new TheoryData<string, int, int, PixelResolutionUnit>
{
{ TestImages.Jpeg.Baseline.Ratio1x1, 1, 1 , PixelResolutionUnit.AspectRatio},
{ TestImages.Jpeg.Baseline.Snake, 300, 300 , PixelResolutionUnit.PixelsPerInch},
{ TestImages.Jpeg.Baseline.GammaDalaiLamaGray, 72, 72, PixelResolutionUnit.PixelsPerInch }
};
[Theory]
[MemberData(nameof(MetaDataTestData))]
@ -76,14 +85,49 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
iccProfilePresent);
}
[Theory]
[MemberData(nameof(RatioFiles))]
public void Decode_VerifyRatio(string imagePath, int xResolution, int yResolution, PixelResolutionUnit resolutionUnit)
{
var testFile = TestFile.Create(imagePath);
using (var stream = new MemoryStream(testFile.Bytes, false))
{
var decoder = new JpegDecoder();
using (Image<Rgba32> image = decoder.Decode<Rgba32>(Configuration.Default, stream))
{
ImageMetaData meta = image.MetaData;
Assert.Equal(xResolution, meta.HorizontalResolution);
Assert.Equal(yResolution, meta.VerticalResolution);
Assert.Equal(resolutionUnit, meta.ResolutionUnits);
}
}
}
[Theory]
[MemberData(nameof(RatioFiles))]
public void Identify_VerifyRatio(string imagePath, int xResolution, int yResolution, PixelResolutionUnit resolutionUnit)
{
var testFile = TestFile.Create(imagePath);
using (var stream = new MemoryStream(testFile.Bytes, false))
{
var decoder = new JpegDecoder();
IImageInfo image = decoder.Identify(Configuration.Default, stream);
ImageMetaData meta = image.MetaData;
Assert.Equal(xResolution, meta.HorizontalResolution);
Assert.Equal(yResolution, meta.VerticalResolution);
Assert.Equal(resolutionUnit, meta.ResolutionUnits);
}
}
private static void TestImageInfo(string imagePath, IImageDecoder decoder, bool useIdentify, Action<IImageInfo> test)
{
var testFile = TestFile.Create(imagePath);
using (var stream = new MemoryStream(testFile.Bytes, false))
{
IImageInfo imageInfo = useIdentify
? ((IImageInfoDetector)decoder).Identify(Configuration.Default, stream)
: decoder.Decode<Rgba32>(Configuration.Default, stream);
? ((IImageInfoDetector)decoder).Identify(Configuration.Default, stream)
: decoder.Decode<Rgba32>(Configuration.Default, stream);
test(imageInfo);
}
}
@ -141,7 +185,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
}
});
}
[Theory]
[InlineData(false)]
[InlineData(true)]
@ -166,7 +210,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
}
}
}
[Theory]
[InlineData(false)]
[InlineData(true)]

65
tests/ImageSharp.Tests/Formats/Jpg/JpegEncoderTests.cs

@ -3,6 +3,7 @@
using System.IO;
using SixLabors.ImageSharp.Formats.Jpeg;
using SixLabors.ImageSharp.MetaData;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison;
@ -14,16 +15,24 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
public class JpegEncoderTests
{
public static readonly TheoryData<JpegSubsample, int> BitsPerPixel_Quality =
new TheoryData<JpegSubsample, int>
{
{ JpegSubsample.Ratio420, 40 },
{ JpegSubsample.Ratio420, 60 },
{ JpegSubsample.Ratio420, 100 },
new TheoryData<JpegSubsample, int>
{
{ JpegSubsample.Ratio420, 40 },
{ JpegSubsample.Ratio420, 60 },
{ JpegSubsample.Ratio420, 100 },
{ JpegSubsample.Ratio444, 40 },
{ JpegSubsample.Ratio444, 60 },
{ JpegSubsample.Ratio444, 100 },
};
{ JpegSubsample.Ratio444, 40 },
{ JpegSubsample.Ratio444, 60 },
{ JpegSubsample.Ratio444, 100 },
};
public static readonly TheoryData<string, int, int, PixelResolutionUnit> RatioFiles =
new TheoryData<string, int, int, PixelResolutionUnit>
{
{ TestImages.Jpeg.Baseline.Ratio1x1, 1, 1 , PixelResolutionUnit.AspectRatio},
{ TestImages.Jpeg.Baseline.Snake, 300, 300 , PixelResolutionUnit.PixelsPerInch},
{ TestImages.Jpeg.Baseline.GammaDalaiLamaGray, 72, 72, PixelResolutionUnit.PixelsPerInch }
};
[Theory]
[WithFile(TestImages.Png.CalliphoraPartial, nameof(BitsPerPixel_Quality), PixelTypes.Rgba32)]
@ -82,10 +91,10 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
image.Mutate(c => c.MakeOpaque());
var encoder = new JpegEncoder()
{
Subsample = subsample,
Quality = quality
};
{
Subsample = subsample,
Quality = quality
};
string info = $"{subsample}-Q{quality}";
ImageComparer comparer = GetComparer(quality, subsample);
@ -93,7 +102,6 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
image.VerifyEncoder(provider, "jpeg", info, encoder, comparer, referenceImageExtension: "png");
}
}
[Theory]
[InlineData(false)]
@ -104,7 +112,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
{
IgnoreMetadata = ignoreMetaData
};
using (Image<Rgba32> input = TestFile.Create(TestImages.Jpeg.Baseline.Floorplan).CreateImage())
{
using (var memStream = new MemoryStream())
@ -126,7 +134,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
}
}
}
[Fact]
public void Quality_0_And_1_Are_Identical()
{
@ -172,5 +180,30 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
Assert.NotEqual(memStream0.ToArray(), memStream1.ToArray());
}
}
[Theory]
[MemberData(nameof(RatioFiles))]
public void Encode_PreserveRatio(string imagePath, int xResolution, int yResolution, PixelResolutionUnit resolutionUnit)
{
var options = new JpegEncoder();
var testFile = TestFile.Create(imagePath);
using (Image<Rgba32> input = testFile.CreateImage())
{
using (var memStream = new MemoryStream())
{
input.Save(memStream, options);
memStream.Position = 0;
using (var output = Image.Load<Rgba32>(memStream))
{
ImageMetaData meta = output.MetaData;
Assert.Equal(xResolution, meta.HorizontalResolution);
Assert.Equal(yResolution, meta.VerticalResolution);
Assert.Equal(resolutionUnit, meta.ResolutionUnits);
}
}
}
}
}
}

2
tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs

@ -20,8 +20,6 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png
{
private const PixelTypes PixelTypes = Tests.PixelTypes.Rgba32 | Tests.PixelTypes.RgbaVector | Tests.PixelTypes.Argb32;
public static readonly string[] CommonTestImages =
{
TestImages.Png.Splash,

16
tests/ImageSharp.Tests/TestImages.cs

@ -82,7 +82,7 @@ namespace SixLabors.ImageSharp.Tests
Powerpoint, SplashInterlaced, Interlaced,
Filter0, Filter1, Filter2, Filter3, Filter4,
FilterVar, VimImage1, VimImage2, VersioningImage1,
VersioningImage2
VersioningImage2, Ratio4x1, Ratio1x4
};
}
@ -127,13 +127,14 @@ namespace SixLabors.ImageSharp.Tests
public const string Jpeg420Small = "Jpg/baseline/jpeg420small.jpg";
public const string Testorig420 = "Jpg/baseline/testorig.jpg";
public const string MultiScanBaselineCMYK = "Jpg/baseline/MultiScanBaselineCMYK.jpg";
public const string Ratio1x1 = "Jpg/baseline/ratio-1x1.jpg";
public static readonly string[] All =
{
Cmyk, Ycck, Exif, Floorplan,
Calliphora, Turtle, GammaDalaiLamaGray,
Hiyamugi, Jpeg400, Jpeg420Exif, Jpeg444,
};
{
Cmyk, Ycck, Exif, Floorplan,
Calliphora, Turtle, GammaDalaiLamaGray,
Hiyamugi, Jpeg400, Jpeg420Exif, Jpeg444, Ratio1x1
};
}
public static class Issues
@ -182,8 +183,7 @@ namespace SixLabors.ImageSharp.Tests
public const string Ratio4x1 = "Gif/base_4x1.gif";
public const string Ratio1x4 = "Gif/base_1x4.gif";
public class Issues
public static class Issues
{
public const string BadAppExtLength = "Gif/issues/issue405_badappextlength252.gif";
public const string BadAppExtLength_2 = "Gif/issues/issue405_badappextlength252-2.gif";

BIN
tests/Images/Input/Jpg/baseline/ratio-1x1.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Loading…
Cancel
Save