diff --git a/appveyor.yml b/appveyor.yml index 821fd427c..2cc5182d3 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -12,10 +12,10 @@ environment: - target_framework: netcoreapp2.1 is_32bit: True - - target_framework: net471 + - target_framework: net472 is_32bit: False - - target_framework: net471 + - target_framework: net472 is_32bit: True - target_framework: net462 diff --git a/src/ImageSharp/Common/Helpers/SimdUtils.ExtendedIntrinsics.cs b/src/ImageSharp/Common/Helpers/SimdUtils.ExtendedIntrinsics.cs index e0d6187dc..2ac577264 100644 --- a/src/ImageSharp/Common/Helpers/SimdUtils.ExtendedIntrinsics.cs +++ b/src/ImageSharp/Common/Helpers/SimdUtils.ExtendedIntrinsics.cs @@ -1,5 +1,4 @@ using System; -using System.Diagnostics; using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -20,8 +19,7 @@ namespace SixLabors.ImageSharp public static class ExtendedIntrinsics { public static bool IsAvailable { get; } = -#if NETCOREAPP2_1 - // TODO: Also available in .NET 4.7.2, we need to add a build target! +#if SUPPORTS_EXTENDED_INTRINSICS Vector.IsHardwareAccelerated; #else false; diff --git a/src/ImageSharp/Common/Helpers/SimdUtils.cs b/src/ImageSharp/Common/Helpers/SimdUtils.cs index 71eb88b1d..a989cc875 100644 --- a/src/ImageSharp/Common/Helpers/SimdUtils.cs +++ b/src/ImageSharp/Common/Helpers/SimdUtils.cs @@ -67,7 +67,7 @@ namespace SixLabors.ImageSharp { DebugGuard.IsTrue(source.Length == dest.Length, nameof(source), "Input spans must be of same length!"); -#if NETCOREAPP2_1 +#if SUPPORTS_EXTENDED_INTRINSICS ExtendedIntrinsics.BulkConvertByteToNormalizedFloatReduce(ref source, ref dest); #else BasicIntrinsics256.BulkConvertByteToNormalizedFloatReduce(ref source, ref dest); @@ -94,7 +94,7 @@ namespace SixLabors.ImageSharp { DebugGuard.IsTrue(source.Length == dest.Length, nameof(source), "Input spans must be of same length!"); -#if NETCOREAPP2_1 +#if SUPPORTS_EXTENDED_INTRINSICS ExtendedIntrinsics.BulkConvertNormalizedFloatToByteClampOverflowsReduce(ref source, ref dest); #else BasicIntrinsics256.BulkConvertNormalizedFloatToByteClampOverflowsReduce(ref source, ref dest); diff --git a/src/ImageSharp/Common/Helpers/TestHelpers.cs b/src/ImageSharp/Common/Helpers/TestHelpers.cs index 45ef7706d..fd16a577a 100644 --- a/src/ImageSharp/Common/Helpers/TestHelpers.cs +++ b/src/ImageSharp/Common/Helpers/TestHelpers.cs @@ -13,8 +13,12 @@ namespace SixLabors.ImageSharp.Common.Helpers /// Only intended to be used in tests! /// internal const string ImageSharpBuiltAgainst = -#if NETCOREAPP2_1 +#if NET472 + "netfx4.7.2"; +#elif NETCOREAPP2_1 "netcoreapp2.1"; +#elif NETSTANDARD1_3 + "netstandard1.3"; #else "netstandard2.0"; #endif diff --git a/src/ImageSharp/ImageSharp.csproj b/src/ImageSharp/ImageSharp.csproj index 8d2ad2abe..29d29d50d 100644 --- a/src/ImageSharp/ImageSharp.csproj +++ b/src/ImageSharp/ImageSharp.csproj @@ -5,7 +5,7 @@ $(packageversion) 0.0.1 Six Labors and contributors - netstandard1.3;netstandard2.0;netcoreapp2.1 + netstandard1.3;netstandard2.0;netcoreapp2.1;net472 true true SixLabors.ImageSharp @@ -31,9 +31,15 @@ IOperation Latest + + + $(DefineConstants);SUPPORTS_EXTENDED_INTRINSICS + + + @@ -43,15 +49,14 @@ - - - + + ..\..\ImageSharp.ruleset SixLabors.ImageSharp diff --git a/src/ImageSharp/MetaData/Profiles/Exif/ExifProfile.cs b/src/ImageSharp/MetaData/Profiles/Exif/ExifProfile.cs index b48b146f1..37ceaf10f 100644 --- a/src/ImageSharp/MetaData/Profiles/Exif/ExifProfile.cs +++ b/src/ImageSharp/MetaData/Profiles/Exif/ExifProfile.cs @@ -50,7 +50,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Exif { this.Parts = ExifParts.All; this.data = data; - this.InvalidTags = new List(); + this.InvalidTags = Array.Empty(); } /// @@ -63,7 +63,11 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Exif this.Parts = other.Parts; this.thumbnailLength = other.thumbnailLength; this.thumbnailOffset = other.thumbnailOffset; - this.InvalidTags = new List(other.InvalidTags); + + this.InvalidTags = other.InvalidTags.Count > 0 + ? new List(other.InvalidTags) + : (IReadOnlyList)Array.Empty(); + if (other.values != null) { this.values = new List(other.Values.Count); @@ -289,7 +293,10 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Exif this.values = reader.ReadValues(); - this.InvalidTags = new List(reader.InvalidTags); + this.InvalidTags = reader.InvalidTags.Count > 0 + ? new List(reader.InvalidTags) + : (IReadOnlyList)Array.Empty(); + this.thumbnailOffset = (int)reader.ThumbnailOffset; this.thumbnailLength = (int)reader.ThumbnailLength; } diff --git a/src/ImageSharp/MetaData/Profiles/Exif/ExifReader.cs b/src/ImageSharp/MetaData/Profiles/Exif/ExifReader.cs index 5f9549908..3326c3217 100644 --- a/src/ImageSharp/MetaData/Profiles/Exif/ExifReader.cs +++ b/src/ImageSharp/MetaData/Profiles/Exif/ExifReader.cs @@ -7,7 +7,6 @@ using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; using System.Text; using SixLabors.ImageSharp.IO; using SixLabors.ImageSharp.Primitives; @@ -19,7 +18,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Exif /// internal sealed class ExifReader { - private readonly List invalidTags = new List(); + private List invalidTags; private readonly byte[] exifData; private int position; private Endianness endianness = Endianness.BigEndian; @@ -38,7 +37,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Exif /// /// Gets the invalid tags. /// - public IReadOnlyList InvalidTags => this.invalidTags; + public IReadOnlyList InvalidTags => this.invalidTags ?? (IReadOnlyList)Array.Empty(); /// /// Gets the thumbnail length in the byte stream @@ -338,7 +337,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Exif // Ensure that the new index does not overrun the data if (newIndex > int.MaxValue) { - this.invalidTags.Add(tag); + this.AddInvalidTag(tag); exifValue = default; @@ -349,7 +348,8 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Exif if (this.RemainingLength < size) { - this.invalidTags.Add(tag); + this.AddInvalidTag(tag); + this.position = oldIndex; exifValue = default; @@ -372,6 +372,16 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Exif return true; } + private void AddInvalidTag(ExifTag tag) + { + if (this.invalidTags == null) + { + this.invalidTags = new List(); + } + + this.invalidTags.Add(tag); + } + private TEnum ToEnum(int value, TEnum defaultValue) where TEnum : struct { diff --git a/src/ImageSharp/MetaData/Profiles/Exif/ExifWriter.cs b/src/ImageSharp/MetaData/Profiles/Exif/ExifWriter.cs index ade373341..9079526d5 100644 --- a/src/ImageSharp/MetaData/Profiles/Exif/ExifWriter.cs +++ b/src/ImageSharp/MetaData/Profiles/Exif/ExifWriter.cs @@ -17,8 +17,8 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Exif /// /// Which parts will be written. /// - private ExifParts allowedParts; - private IList values; + private readonly ExifParts allowedParts; + private readonly IList values; private List dataOffsets; private readonly List ifdIndexes; private readonly List exifIndexes; diff --git a/src/ImageSharp/MetaData/Profiles/ICC/IccProfile.cs b/src/ImageSharp/MetaData/Profiles/ICC/IccProfile.cs index 72665bc69..5d75a6df9 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/IccProfile.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/IccProfile.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. using System; -using System.Collections.Generic; using System.Security.Cryptography; namespace SixLabors.ImageSharp.MetaData.Profiles.Icc @@ -20,7 +19,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// /// The backing file for the property /// - private List entries; + private IccTagDataEntry[] entries; /// /// ICC profile header @@ -46,13 +45,10 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// /// The profile header /// The actual profile data - internal IccProfile(IccProfileHeader header, IEnumerable entries) + internal IccProfile(IccProfileHeader header, IccTagDataEntry[] entries) { - Guard.NotNull(header, nameof(header)); - Guard.NotNull(entries, nameof(entries)); - - this.header = header; - this.entries = new List(entries); + this.header = header ?? throw new ArgumentNullException(nameof(header)); + this.entries = entries ?? throw new ArgumentNullException(nameof(entries)); } /// @@ -85,7 +81,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// /// Gets the actual profile data /// - public List Entries + public IccTagDataEntry[] Entries { get { @@ -212,12 +208,12 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc if (this.data is null) { - this.entries = new List(); + this.entries = Array.Empty(); return; } var reader = new IccReader(); - this.entries = new List(reader.ReadTagData(this.data)); + this.entries = reader.ReadTagData(this.data); } } } \ No newline at end of file diff --git a/src/ImageSharp/MetaData/Profiles/ICC/IccReader.cs b/src/ImageSharp/MetaData/Profiles/ICC/IccReader.cs index da47b565e..9f9d373ae 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/IccReader.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/IccReader.cs @@ -1,6 +1,7 @@ // Copyright (c) Six Labors and contributors. // Licensed under the Apache License, Version 2.0. +using System; using System.Collections.Generic; namespace SixLabors.ImageSharp.MetaData.Profiles.Icc @@ -126,7 +127,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc // A normal profile usually has 5-15 entries if (tagCount > 100) { - return new IccTagTableEntry[0]; + return Array.Empty(); } var table = new List((int)tagCount); diff --git a/src/ImageSharp/MetaData/Profiles/ICC/IccWriter.cs b/src/ImageSharp/MetaData/Profiles/ICC/IccWriter.cs index b476e3195..91a3bba54 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/IccWriter.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/IccWriter.cs @@ -68,12 +68,12 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc } } - private IccTagTableEntry[] WriteTagData(IccDataWriter writer, List entries) + private IccTagTableEntry[] WriteTagData(IccDataWriter writer, IccTagDataEntry[] entries) { IEnumerable> grouped = entries.GroupBy(t => t); // (Header size) + (entry count) + (nr of entries) * (size of table entry) - writer.SetIndex(128 + 4 + (entries.Count * 12)); + writer.SetIndex(128 + 4 + (entries.Length * 12)); var table = new List(); foreach (IGrouping group in grouped) diff --git a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccCurveTagDataEntry.cs b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccCurveTagDataEntry.cs index 38a2f4522..77a913b14 100644 --- a/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccCurveTagDataEntry.cs +++ b/src/ImageSharp/MetaData/Profiles/ICC/TagDataEntries/IccCurveTagDataEntry.cs @@ -14,7 +14,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// Initializes a new instance of the class. /// public IccCurveTagDataEntry() - : this(new float[0], IccProfileTag.Unknown) + : this(Array.Empty(), IccProfileTag.Unknown) { } @@ -41,7 +41,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc /// /// Tag Signature public IccCurveTagDataEntry(IccProfileTag tagSignature) - : this(new float[0], tagSignature) + : this(Array.Empty(), tagSignature) { } @@ -63,7 +63,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc public IccCurveTagDataEntry(float[] curveData, IccProfileTag tagSignature) : base(IccTypeSignature.Curve, tagSignature) { - this.CurveData = curveData ?? new float[0]; + this.CurveData = curveData ?? Array.Empty(); } /// diff --git a/tests/ImageSharp.Tests/ImageSharp.Tests.csproj b/tests/ImageSharp.Tests/ImageSharp.Tests.csproj index 5d163917c..04a680200 100644 --- a/tests/ImageSharp.Tests/ImageSharp.Tests.csproj +++ b/tests/ImageSharp.Tests/ImageSharp.Tests.csproj @@ -1,6 +1,6 @@  - net462;net471;netcoreapp2.1 + net462;net472;netcoreapp2.1 True latest full diff --git a/tests/ImageSharp.Tests/MetaData/Profiles/ICC/DataWriter/IccDataWriter.PrimitivesTests.cs b/tests/ImageSharp.Tests/MetaData/Profiles/ICC/DataWriter/IccDataWriter.PrimitivesTests.cs index 56a4f8c0c..845a149b5 100644 --- a/tests/ImageSharp.Tests/MetaData/Profiles/ICC/DataWriter/IccDataWriter.PrimitivesTests.cs +++ b/tests/ImageSharp.Tests/MetaData/Profiles/ICC/DataWriter/IccDataWriter.PrimitivesTests.cs @@ -42,7 +42,7 @@ namespace SixLabors.ImageSharp.Tests.Icc byte[] output = writer.GetData(); Assert.Equal(0, count); - Assert.Equal(new byte[0], output); + Assert.Equal(Array.Empty(), output); } [Fact] @@ -62,7 +62,7 @@ namespace SixLabors.ImageSharp.Tests.Icc byte[] output = writer.GetData(); Assert.Equal(0, count); - Assert.Equal(new byte[0], output); + Assert.Equal(Array.Empty(), output); } [Theory] diff --git a/tests/ImageSharp.Tests/MetaData/Profiles/ICC/IccReaderTests.cs b/tests/ImageSharp.Tests/MetaData/Profiles/ICC/IccReaderTests.cs index b3215ee7a..c91076afc 100644 --- a/tests/ImageSharp.Tests/MetaData/Profiles/ICC/IccReaderTests.cs +++ b/tests/ImageSharp.Tests/MetaData/Profiles/ICC/IccReaderTests.cs @@ -15,7 +15,7 @@ namespace SixLabors.ImageSharp.Tests.Icc IccProfile output = reader.Read(IccTestDataProfiles.Header_Random_Array); - Assert.Equal(0, output.Entries.Count); + Assert.Equal(0, output.Entries.Length); Assert.NotNull(output.Header); IccProfileHeader header = output.Header; @@ -46,7 +46,7 @@ namespace SixLabors.ImageSharp.Tests.Icc IccProfile output = reader.Read(IccTestDataProfiles.Profile_Random_Array); - Assert.Equal(2, output.Entries.Count); + Assert.Equal(2, output.Entries.Length); Assert.True(ReferenceEquals(output.Entries[0], output.Entries[1])); } diff --git a/tests/ImageSharp.Tests/RunExtendedTests.cmd b/tests/ImageSharp.Tests/RunExtendedTests.cmd index 481e5fb3d..c2f4b9f53 100644 --- a/tests/ImageSharp.Tests/RunExtendedTests.cmd +++ b/tests/ImageSharp.Tests/RunExtendedTests.cmd @@ -5,3 +5,5 @@ dotnet xunit -nobuild -c Release -f net47 dotnet xunit -nobuild -c Release -f net47 -x86 dotnet xunit -nobuild -c Release -f net471 dotnet xunit -nobuild -c Release -f net471 -x86 +dotnet xunit -nobuild -c Release -f net472 +dotnet xunit -nobuild -c Release -f net472 -x86