diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index 4828f4f21..5189f0435 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -1,19 +1,37 @@ name: Build on: - push: - branches: - - master - tags: - - "v*" - pull_request: - branches: - - master + push: + branches: + - master + tags: + - "v*" + pull_request: + branches: + - master jobs: Build: strategy: matrix: options: + - os: ubuntu-latest + framework: net6.0 + sdk: 6.0.x + sdk-preview: true + runtime: -x64 + codecov: false + - os: macos-latest + framework: net6.0 + sdk: 6.0.x + sdk-preview: true + runtime: -x64 + codecov: false + - os: windows-latest + framework: net6.0 + sdk: 6.0.x + sdk-preview: true + runtime: -x64 + codecov: false - os: ubuntu-latest framework: net5.0 runtime: -x64 @@ -52,37 +70,38 @@ jobs: codecov: false runs-on: ${{matrix.options.os}} - if: "!contains(github.event.head_commit.message, '[skip ci]')" steps: - - uses: actions/checkout@v2 + - name: Git Config + shell: bash + run: | + git config --global core.autocrlf false + git config --global core.longpaths true + + - name: Git Checkout + uses: actions/checkout@v2 + with: + fetch-depth: 0 + submodules: recursive # See https://github.com/actions/checkout/issues/165#issuecomment-657673315 - - name: Create LFS file list + - name: Git Create LFS FileList run: git lfs ls-files -l | cut -d' ' -f1 | sort > .lfs-assets-id - - name: Restore LFS cache + - name: Git Setup LFS Cache uses: actions/cache@v2 id: lfs-cache with: path: .git/lfs key: ${{ runner.os }}-lfs-${{ hashFiles('.lfs-assets-id') }}-v1 - - name: Git LFS Pull + - name: Git Pull LFS run: git lfs pull - - name: Install NuGet + - name: NuGet Install uses: NuGet/setup-nuget@v1 - - name: Setup Git - shell: bash - run: | - git config --global core.autocrlf false - git config --global core.longpaths true - git fetch --prune --unshallow - git submodule -q update --init --recursive - - - name: Setup NuGet Cache + - name: NuGet Setup Cache uses: actions/cache@v2 id: nuget-cache with: @@ -90,60 +109,94 @@ jobs: key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj', '**/*.props', '**/*.targets') }} restore-keys: ${{ runner.os }}-nuget- - - name: Build + - name: DotNet Setup Preview + if: ${{ matrix.options.sdk-preview == true }} + uses: actions/setup-dotnet@v1 + with: + dotnet-version: ${{ matrix.options.sdk }} + include-prerelease: true + + - name: DotNet Build + if: ${{ matrix.options.sdk-preview != true }} shell: pwsh run: ./ci-build.ps1 "${{matrix.options.framework}}" env: SIXLABORS_TESTING: True - - name: Test + - name: DotNet Build Preview + if: ${{ matrix.options.sdk-preview == true }} + shell: pwsh + run: ./ci-build.ps1 "${{matrix.options.framework}}" + env: + SIXLABORS_TESTING_PREVIEW: True + + - name: DotNet Test + if: ${{ matrix.options.sdk-preview != true }} shell: pwsh run: ./ci-test.ps1 "${{matrix.options.os}}" "${{matrix.options.framework}}" "${{matrix.options.runtime}}" "${{matrix.options.codecov}}" env: - SIXLABORS_TESTING: True - XUNIT_PATH: .\tests\ImageSharp.Tests # Required for xunit + SIXLABORS_TESTING: True + XUNIT_PATH: .\tests\ImageSharp.Tests # Required for xunit + + - name: DotNet Test Preview + if: ${{ matrix.options.sdk-preview == true }} + shell: pwsh + run: ./ci-test.ps1 "${{matrix.options.os}}" "${{matrix.options.framework}}" "${{matrix.options.runtime}}" "${{matrix.options.codecov}}" + env: + SIXLABORS_TESTING_PREVIEW: True + XUNIT_PATH: .\tests\ImageSharp.Tests # Required for xunit - name: Export Failed Output uses: actions/upload-artifact@v2 if: failure() with: - name: actual_output_${{ runner.os }}_${{ matrix.options.framework }}${{ matrix.options.runtime }}.zip - path: tests/Images/ActualOutput/ + name: actual_output_${{ runner.os }}_${{ matrix.options.framework }}${{ matrix.options.runtime }}.zip + path: tests/Images/ActualOutput/ - - name: Update Codecov + - name: Codecov Update uses: codecov/codecov-action@v1 if: matrix.options.codecov == true && startsWith(github.repository, 'SixLabors') with: - flags: unittests + flags: unittests Publish: needs: [Build] - runs-on: windows-latest + runs-on: ubuntu-latest if: (github.event_name == 'push') steps: - - uses: actions/checkout@v2 - - - name: Install NuGet - uses: NuGet/setup-nuget@v1 - - - name: Setup Git + - name: Git Config shell: bash run: | git config --global core.autocrlf false git config --global core.longpaths true - git fetch --prune --unshallow - git submodule -q update --init --recursive - - name: Pack + - name: Git Checkout + uses: actions/checkout@v2 + with: + fetch-depth: 0 + submodules: recursive + + - name: NuGet Install + uses: NuGet/setup-nuget@v1 + + - name: NuGet Setup Cache + uses: actions/cache@v2 + id: nuget-cache + with: + path: ~/.nuget + key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj', '**/*.props', '**/*.targets') }} + restore-keys: ${{ runner.os }}-nuget- + + - name: DotNet Pack shell: pwsh run: ./ci-pack.ps1 - - name: Publish to MyGet + - name: MyGet Publish shell: pwsh run: | - nuget.exe push .\artifacts\*.nupkg ${{secrets.MYGET_TOKEN}} -Source https://www.myget.org/F/sixlabors/api/v2/package - nuget.exe push .\artifacts\*.snupkg ${{secrets.MYGET_TOKEN}} -Source https://www.myget.org/F/sixlabors/api/v3/index.json + dotnet nuget push .\artifacts\*.nupkg -k ${{secrets.MYGET_TOKEN}} -s https://www.myget.org/F/sixlabors/api/v2/package + dotnet nuget push .\artifacts\*.snupkg -k ${{secrets.MYGET_TOKEN}} -s https://www.myget.org/F/sixlabors/api/v3/index.json # TODO: If github.ref starts with 'refs/tags' then it was tag push and we can optionally push out package to nuget.org diff --git a/.gitignore b/.gitignore index 769a40c6c..fadf36964 100644 --- a/.gitignore +++ b/.gitignore @@ -223,3 +223,7 @@ artifacts/ **/Images/ReferenceOutput **/Images/Input/MemoryStress .DS_Store + +#lfs +hooks/** +lfs/** diff --git a/Directory.Build.props b/Directory.Build.props index b3e18e5a5..3899ce939 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -18,6 +18,11 @@ + + + preview + + + 2.0 + + + + + net6.0;net5.0;netcoreapp3.1;netcoreapp2.1;netstandard2.1;netstandard2.0;netstandard1.3;net472 + + net5.0;netcoreapp3.1;netcoreapp2.1;netstandard2.1;netstandard2.0;netstandard1.3;net472 diff --git a/src/ImageSharp/Image{TPixel}.cs b/src/ImageSharp/Image{TPixel}.cs index b43ff0422..2aa9c5394 100644 --- a/src/ImageSharp/Image{TPixel}.cs +++ b/src/ImageSharp/Image{TPixel}.cs @@ -87,6 +87,21 @@ namespace SixLabors.ImageSharp this.frames = new ImageFrameCollection(this, width, height, default(TPixel)); } + /// + /// Initializes a new instance of the class + /// wrapping an external pixel bufferx. + /// + /// The configuration providing initialization code which allows extending the library. + /// Pixel buffer. + /// The images metadata. + internal Image( + Configuration configuration, + Buffer2D pixelBuffer, + ImageMetadata metadata) + : this(configuration, pixelBuffer.FastMemoryGroup, pixelBuffer.Width, pixelBuffer.Height, metadata) + { + } + /// /// Initializes a new instance of the class /// wrapping an external . diff --git a/src/ImageSharp/Memory/Allocators/IManagedByteBuffer.cs b/src/ImageSharp/Memory/Allocators/IManagedByteBuffer.cs index 8088a2c47..b8298edcd 100644 --- a/src/ImageSharp/Memory/Allocators/IManagedByteBuffer.cs +++ b/src/ImageSharp/Memory/Allocators/IManagedByteBuffer.cs @@ -15,4 +15,4 @@ namespace SixLabors.ImageSharp.Memory /// byte[] Array { get; } } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Memory/Allocators/Internals/BasicArrayBuffer.cs b/src/ImageSharp/Memory/Allocators/Internals/BasicArrayBuffer.cs index 3a3c695b2..d70811600 100644 --- a/src/ImageSharp/Memory/Allocators/Internals/BasicArrayBuffer.cs +++ b/src/ImageSharp/Memory/Allocators/Internals/BasicArrayBuffer.cs @@ -57,4 +57,4 @@ namespace SixLabors.ImageSharp.Memory.Internals return this.Array; } } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Memory/Allocators/Internals/BasicByteBuffer.cs b/src/ImageSharp/Memory/Allocators/Internals/BasicByteBuffer.cs index 499a9228c..e21592a12 100644 --- a/src/ImageSharp/Memory/Allocators/Internals/BasicByteBuffer.cs +++ b/src/ImageSharp/Memory/Allocators/Internals/BasicByteBuffer.cs @@ -17,4 +17,4 @@ namespace SixLabors.ImageSharp.Memory.Internals { } } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Memory/Allocators/Internals/ManagedBufferBase.cs b/src/ImageSharp/Memory/Allocators/Internals/ManagedBufferBase.cs index 3f54e335e..296a8bd3a 100644 --- a/src/ImageSharp/Memory/Allocators/Internals/ManagedBufferBase.cs +++ b/src/ImageSharp/Memory/Allocators/Internals/ManagedBufferBase.cs @@ -24,7 +24,9 @@ namespace SixLabors.ImageSharp.Memory.Internals } void* ptr = (void*)this.pinHandle.AddrOfPinnedObject(); - return new MemoryHandle(ptr, this.pinHandle); + + // We should only pass pinnable:this, when GCHandle lifetime is managed by the MemoryManager instance. + return new MemoryHandle(ptr, pinnable: this); } /// @@ -42,4 +44,4 @@ namespace SixLabors.ImageSharp.Memory.Internals /// The pinnable . protected abstract object GetPinnableObject(); } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Memory/Buffer2D{T}.cs b/src/ImageSharp/Memory/Buffer2D{T}.cs index 21c19f5d5..b62c9beb5 100644 --- a/src/ImageSharp/Memory/Buffer2D{T}.cs +++ b/src/ImageSharp/Memory/Buffer2D{T}.cs @@ -116,6 +116,36 @@ namespace SixLabors.ImageSharp.Memory : this.GetRowMemorySlow(y).Span; } + internal bool TryGetPaddedRowSpan(int y, int padding, out Span paddedSpan) + { + DebugGuard.MustBeGreaterThanOrEqualTo(y, 0, nameof(y)); + DebugGuard.MustBeLessThan(y, this.Height, nameof(y)); + + int stride = this.Width + padding; + if (this.cachedMemory.Length > 0) + { + paddedSpan = this.cachedMemory.Span.Slice(y * this.Width); + if (paddedSpan.Length < stride) + { + return false; + } + + paddedSpan = paddedSpan.Slice(0, stride); + return true; + } + + Memory memory = this.FastMemoryGroup.GetRemainingSliceOfBuffer(y * (long)this.Width); + + if (memory.Length < stride) + { + paddedSpan = default; + return false; + } + + paddedSpan = memory.Span.Slice(0, stride); + return true; + } + [MethodImpl(InliningOptions.ShortMethod)] internal ref T GetElementUnsafe(int x, int y) { diff --git a/src/ImageSharp/Memory/DiscontiguousBuffers/MemoryGroupExtensions.cs b/src/ImageSharp/Memory/DiscontiguousBuffers/MemoryGroupExtensions.cs index da42b30ad..8e6f38d14 100644 --- a/src/ImageSharp/Memory/DiscontiguousBuffers/MemoryGroupExtensions.cs +++ b/src/ImageSharp/Memory/DiscontiguousBuffers/MemoryGroupExtensions.cs @@ -39,12 +39,8 @@ namespace SixLabors.ImageSharp.Memory int bufferIdx = (int)(start / group.BufferLength); - if (bufferIdx < 0) - { - throw new ArgumentOutOfRangeException(nameof(start)); - } - - if (bufferIdx >= group.Count) + // if (bufferIdx < 0 || bufferIdx >= group.Count) + if ((uint)bufferIdx >= group.Count) { throw new ArgumentOutOfRangeException(nameof(start)); } @@ -61,6 +57,31 @@ namespace SixLabors.ImageSharp.Memory return memory.Slice(bufferStart, length); } + /// + /// Returns the slice of the buffer starting at global index that goes until the end of the buffer. + /// + internal static Memory GetRemainingSliceOfBuffer(this IMemoryGroup group, long start) + where T : struct + { + Guard.NotNull(group, nameof(group)); + Guard.IsTrue(group.IsValid, nameof(group), "Group must be valid!"); + Guard.MustBeLessThan(start, group.TotalLength, nameof(start)); + + int bufferIdx = (int)(start / group.BufferLength); + + // if (bufferIdx < 0 || bufferIdx >= group.Count) + if ((uint)bufferIdx >= group.Count) + { + throw new ArgumentOutOfRangeException(nameof(start)); + } + + int bufferStart = (int)(start % group.BufferLength); + + Memory memory = group[bufferIdx]; + + return memory.Slice(bufferStart); + } + internal static void CopyTo(this IMemoryGroup source, Span target) where T : struct { diff --git a/src/ImageSharp/Memory/TransformItemsDelegate{T}.cs b/src/ImageSharp/Memory/TransformItemsDelegate{TSource, TTarget}.cs similarity index 56% rename from src/ImageSharp/Memory/TransformItemsDelegate{T}.cs rename to src/ImageSharp/Memory/TransformItemsDelegate{TSource, TTarget}.cs index 722dde19a..3bf8cb1b8 100644 --- a/src/ImageSharp/Memory/TransformItemsDelegate{T}.cs +++ b/src/ImageSharp/Memory/TransformItemsDelegate{TSource, TTarget}.cs @@ -1,9 +1,11 @@ -// Copyright (c) Six Labors. +// Copyright (c) Six Labors. // Licensed under the Apache License, Version 2.0. using System; namespace SixLabors.ImageSharp.Memory { +#pragma warning disable SA1649 // File name should match first type name internal delegate void TransformItemsDelegate(ReadOnlySpan source, Span target); +#pragma warning restore SA1649 // File name should match first type name } diff --git a/src/ImageSharp/Metadata/FrameDecodingMode.cs b/src/ImageSharp/Metadata/FrameDecodingMode.cs index e03af18bd..6164f939b 100644 --- a/src/ImageSharp/Metadata/FrameDecodingMode.cs +++ b/src/ImageSharp/Metadata/FrameDecodingMode.cs @@ -18,4 +18,4 @@ namespace SixLabors.ImageSharp.Metadata /// First } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Metadata/Profiles/Exif/ExifProfile.cs b/src/ImageSharp/Metadata/Profiles/Exif/ExifProfile.cs index 9265314ed..e0ab8ecf9 100644 --- a/src/ImageSharp/Metadata/Profiles/Exif/ExifProfile.cs +++ b/src/ImageSharp/Metadata/Profiles/Exif/ExifProfile.cs @@ -4,7 +4,6 @@ using System; using System.Collections.Generic; using System.IO; - using SixLabors.ImageSharp.PixelFormats; namespace SixLabors.ImageSharp.Metadata.Profiles.Exif diff --git a/src/ImageSharp/Metadata/Profiles/ICC/Curves/IccCurveSegment.cs b/src/ImageSharp/Metadata/Profiles/ICC/Curves/IccCurveSegment.cs index c68283914..8f2598a9a 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/Curves/IccCurveSegment.cs +++ b/src/ImageSharp/Metadata/Profiles/ICC/Curves/IccCurveSegment.cs @@ -40,4 +40,4 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc return this.Signature == other.Signature; } } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Metadata/Profiles/ICC/Curves/IccFormulaCurveElement.cs b/src/ImageSharp/Metadata/Profiles/ICC/Curves/IccFormulaCurveElement.cs index 1ba521f1a..b756e1b09 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/Curves/IccFormulaCurveElement.cs +++ b/src/ImageSharp/Metadata/Profiles/ICC/Curves/IccFormulaCurveElement.cs @@ -90,4 +90,4 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc return this.Equals((IccCurveSegment)other); } } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Metadata/Profiles/ICC/Enums/IccDataType.cs b/src/ImageSharp/Metadata/Profiles/ICC/Enums/IccDataType.cs index a0c1c3b2a..97a27a557 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/Enums/IccDataType.cs +++ b/src/ImageSharp/Metadata/Profiles/ICC/Enums/IccDataType.cs @@ -81,4 +81,4 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc /// Ascii } -} \ 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 dd1c72c8b..5d8b450f0 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/IccReader.cs +++ b/src/ImageSharp/Metadata/Profiles/ICC/IccReader.cs @@ -147,4 +147,4 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc return table.ToArray(); } } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Metadata/Profiles/ICC/IccTagDataEntry.cs b/src/ImageSharp/Metadata/Profiles/ICC/IccTagDataEntry.cs index b1783cfe4..77a647482 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/IccTagDataEntry.cs +++ b/src/ImageSharp/Metadata/Profiles/ICC/IccTagDataEntry.cs @@ -66,4 +66,4 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc /// public override int GetHashCode() => this.Signature.GetHashCode(); } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Metadata/Profiles/ICC/IccWriter.cs b/src/ImageSharp/Metadata/Profiles/ICC/IccWriter.cs index 9cd0c1793..50ece5056 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/IccWriter.cs +++ b/src/ImageSharp/Metadata/Profiles/ICC/IccWriter.cs @@ -89,4 +89,4 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc return table.ToArray(); } } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Metadata/Profiles/ICC/MultiProcessElements/IccCurveSetProcessElement.cs b/src/ImageSharp/Metadata/Profiles/ICC/MultiProcessElements/IccCurveSetProcessElement.cs index 8270786ed..c21d7f001 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/MultiProcessElements/IccCurveSetProcessElement.cs +++ b/src/ImageSharp/Metadata/Profiles/ICC/MultiProcessElements/IccCurveSetProcessElement.cs @@ -37,4 +37,4 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc /// public bool Equals(IccCurveSetProcessElement other) => this.Equals((IccMultiProcessElement)other); } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccChromaticityTagDataEntry.cs b/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccChromaticityTagDataEntry.cs index 508b3f9ad..cdadea77c 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccChromaticityTagDataEntry.cs +++ b/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccChromaticityTagDataEntry.cs @@ -165,4 +165,4 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc return true; } } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccColorantOrderTagDataEntry.cs b/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccColorantOrderTagDataEntry.cs index df7c6b8e8..091aee367 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccColorantOrderTagDataEntry.cs +++ b/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccColorantOrderTagDataEntry.cs @@ -73,4 +73,4 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc return HashCode.Combine(this.Signature, this.ColorantNumber); } } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccColorantTableTagDataEntry.cs b/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccColorantTableTagDataEntry.cs index 0e096f0cb..3c07372ae 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccColorantTableTagDataEntry.cs +++ b/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccColorantTableTagDataEntry.cs @@ -65,4 +65,4 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc /// public override int GetHashCode() => HashCode.Combine(this.Signature, this.ColorantData); } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccCurveTagDataEntry.cs b/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccCurveTagDataEntry.cs index 24e57ec8e..5a9691622 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccCurveTagDataEntry.cs +++ b/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccCurveTagDataEntry.cs @@ -118,4 +118,4 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc /// public override int GetHashCode() => HashCode.Combine(this.Signature, this.CurveData); } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccDataTagDataEntry.cs b/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccDataTagDataEntry.cs index 1b885c590..7d18faede 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccDataTagDataEntry.cs +++ b/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccDataTagDataEntry.cs @@ -97,4 +97,4 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc this.IsAscii); } } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccDateTimeTagDataEntry.cs b/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccDateTimeTagDataEntry.cs index af837237e..55d445ef1 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccDateTimeTagDataEntry.cs +++ b/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccDateTimeTagDataEntry.cs @@ -69,4 +69,4 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc return HashCode.Combine(this.Signature, this.Value); } } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccFix16ArrayTagDataEntry.cs b/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccFix16ArrayTagDataEntry.cs index 45d6865c3..005ab6753 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccFix16ArrayTagDataEntry.cs +++ b/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccFix16ArrayTagDataEntry.cs @@ -66,4 +66,4 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc /// public override int GetHashCode() => HashCode.Combine(this.Signature, this.Data); } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccMultiLocalizedUnicodeTagDataEntry.cs b/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccMultiLocalizedUnicodeTagDataEntry.cs index ca713b4ed..3f2dab80b 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccMultiLocalizedUnicodeTagDataEntry.cs +++ b/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccMultiLocalizedUnicodeTagDataEntry.cs @@ -67,4 +67,4 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc /// public override int GetHashCode() => HashCode.Combine(this.Signature, this.Texts); } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccMultiProcessElementsTagDataEntry.cs b/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccMultiProcessElementsTagDataEntry.cs index 3dd05ca42..5077b74cc 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccMultiProcessElementsTagDataEntry.cs +++ b/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccMultiProcessElementsTagDataEntry.cs @@ -91,4 +91,4 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc this.Data); } } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccResponseCurveSet16TagDataEntry.cs b/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccResponseCurveSet16TagDataEntry.cs index 625566140..13ba0bbea 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccResponseCurveSet16TagDataEntry.cs +++ b/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccResponseCurveSet16TagDataEntry.cs @@ -83,4 +83,4 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc this.Curves); } } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccTextTagDataEntry.cs b/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccTextTagDataEntry.cs index 2ee339a5f..b6f7edec1 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccTextTagDataEntry.cs +++ b/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccTextTagDataEntry.cs @@ -66,4 +66,4 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc /// public override int GetHashCode() => HashCode.Combine(this.Signature, this.Text); } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccUFix16ArrayTagDataEntry.cs b/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccUFix16ArrayTagDataEntry.cs index 2b8ec2c7e..b084787f7 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccUFix16ArrayTagDataEntry.cs +++ b/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccUFix16ArrayTagDataEntry.cs @@ -66,4 +66,4 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc /// public override int GetHashCode() => HashCode.Combine(this.Signature, this.Data); } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccUInt16ArrayTagDataEntry.cs b/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccUInt16ArrayTagDataEntry.cs index 9396bbc35..4a0ff8108 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccUInt16ArrayTagDataEntry.cs +++ b/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccUInt16ArrayTagDataEntry.cs @@ -66,4 +66,4 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc /// public override int GetHashCode() => HashCode.Combine(this.Signature, this.Data); } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccUInt32ArrayTagDataEntry.cs b/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccUInt32ArrayTagDataEntry.cs index 38b76fd34..6741bd538 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccUInt32ArrayTagDataEntry.cs +++ b/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccUInt32ArrayTagDataEntry.cs @@ -66,4 +66,4 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc /// public override int GetHashCode() => HashCode.Combine(this.Signature, this.Data); } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccUInt64ArrayTagDataEntry.cs b/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccUInt64ArrayTagDataEntry.cs index f1eb93c46..63f7ec4a5 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccUInt64ArrayTagDataEntry.cs +++ b/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccUInt64ArrayTagDataEntry.cs @@ -57,4 +57,4 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc /// public override int GetHashCode() => HashCode.Combine(this.Signature, this.Data); } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccUInt8ArrayTagDataEntry.cs b/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccUInt8ArrayTagDataEntry.cs index 1640999a3..eee1c2bd3 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccUInt8ArrayTagDataEntry.cs +++ b/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccUInt8ArrayTagDataEntry.cs @@ -66,4 +66,4 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc /// public override int GetHashCode() => HashCode.Combine(this.Signature, this.Data); } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccUcrBgTagDataEntry.cs b/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccUcrBgTagDataEntry.cs index 763425554..4a5989bf1 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccUcrBgTagDataEntry.cs +++ b/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccUcrBgTagDataEntry.cs @@ -93,4 +93,4 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc this.Description); } } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccUnknownTagDataEntry.cs b/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccUnknownTagDataEntry.cs index f811af298..7a9d06e05 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccUnknownTagDataEntry.cs +++ b/src/ImageSharp/Metadata/Profiles/ICC/TagDataEntries/IccUnknownTagDataEntry.cs @@ -66,4 +66,4 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc /// public override int GetHashCode() => HashCode.Combine(this.Signature, this.Data); } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Metadata/Profiles/ICC/Various/IccClut.cs b/src/ImageSharp/Metadata/Profiles/ICC/Various/IccClut.cs index 0e37b0e2d..edee7a4c7 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/Various/IccClut.cs +++ b/src/ImageSharp/Metadata/Profiles/ICC/Various/IccClut.cs @@ -184,4 +184,4 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc Guard.IsTrue(this.Values.Length == length, nameof(this.Values), "Length of values array does not match the grid points"); } } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Metadata/Profiles/ICC/Various/IccProfileId.cs b/src/ImageSharp/Metadata/Profiles/ICC/Various/IccProfileId.cs index dcac6fa48..0bea1b9e1 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/Various/IccProfileId.cs +++ b/src/ImageSharp/Metadata/Profiles/ICC/Various/IccProfileId.cs @@ -110,4 +110,4 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc private static string ToHex(uint value) => value.ToString("X").PadLeft(8, '0'); } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Metadata/Profiles/ICC/Various/IccScreeningChannel.cs b/src/ImageSharp/Metadata/Profiles/ICC/Various/IccScreeningChannel.cs index d8e360512..94d6b7662 100644 --- a/src/ImageSharp/Metadata/Profiles/ICC/Various/IccScreeningChannel.cs +++ b/src/ImageSharp/Metadata/Profiles/ICC/Various/IccScreeningChannel.cs @@ -91,4 +91,4 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Icc /// public override string ToString() => $"{this.Frequency}Hz; {this.Angle}°; {this.SpotShape}"; } -} \ No newline at end of file +} diff --git a/src/ImageSharp/PixelFormats/HalfTypeHelper.cs b/src/ImageSharp/PixelFormats/HalfTypeHelper.cs index 534f60999..69f4d7813 100644 --- a/src/ImageSharp/PixelFormats/HalfTypeHelper.cs +++ b/src/ImageSharp/PixelFormats/HalfTypeHelper.cs @@ -142,4 +142,4 @@ namespace SixLabors.ImageSharp.PixelFormats public uint U; } } -} \ No newline at end of file +} diff --git a/src/ImageSharp/PixelFormats/IPackedVector{TPacked}.cs b/src/ImageSharp/PixelFormats/IPackedVector{TPacked}.cs index 64560a572..f9dcbed71 100644 --- a/src/ImageSharp/PixelFormats/IPackedVector{TPacked}.cs +++ b/src/ImageSharp/PixelFormats/IPackedVector{TPacked}.cs @@ -18,4 +18,4 @@ namespace SixLabors.ImageSharp.PixelFormats /// TPacked PackedValue { get; set; } } -} \ No newline at end of file +} diff --git a/src/ImageSharp/PixelFormats/PixelConversionModifiers.cs b/src/ImageSharp/PixelFormats/PixelConversionModifiers.cs index 7a5a3dad6..51c223113 100644 --- a/src/ImageSharp/PixelFormats/PixelConversionModifiers.cs +++ b/src/ImageSharp/PixelFormats/PixelConversionModifiers.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. using System; - using SixLabors.ImageSharp.ColorSpaces.Companding; namespace SixLabors.ImageSharp.PixelFormats diff --git a/src/ImageSharp/PixelFormats/PixelConversionModifiersExtensions.cs b/src/ImageSharp/PixelFormats/PixelConversionModifiersExtensions.cs index 9e8c97f81..5b1b44dd2 100644 --- a/src/ImageSharp/PixelFormats/PixelConversionModifiersExtensions.cs +++ b/src/ImageSharp/PixelFormats/PixelConversionModifiersExtensions.cs @@ -35,4 +35,4 @@ namespace SixLabors.ImageSharp.PixelFormats ? originalModifiers | PixelConversionModifiers.Scale | PixelConversionModifiers.SRgbCompand : originalModifiers; } -} \ No newline at end of file +} diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/A8.cs b/src/ImageSharp/PixelFormats/PixelImplementations/A8.cs index 77df2bc80..cca7ff7db 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/A8.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/A8.cs @@ -73,7 +73,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public readonly Vector4 ToVector4() => new Vector4(0, 0, 0, this.PackedValue / 255F); + public readonly Vector4 ToVector4() => new(0, 0, 0, this.PackedValue / 255F); /// [MethodImpl(InliningOptions.ShortMethod)] diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Argb32.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Argb32.cs index 3ac9b523f..8c1b04ff1 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Argb32.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Argb32.cs @@ -44,12 +44,12 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// The maximum byte value. /// - private static readonly Vector4 MaxBytes = new Vector4(255); + private static readonly Vector4 MaxBytes = new(255); /// /// The half vector value. /// - private static readonly Vector4 Half = new Vector4(0.5F); + private static readonly Vector4 Half = new(0.5F); /// /// Initializes a new instance of the struct. @@ -151,7 +151,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// The . /// The . [MethodImpl(InliningOptions.ShortMethod)] - public static implicit operator Color(Argb32 source) => new Color(source); + public static implicit operator Color(Argb32 source) => new(source); /// /// Converts a to . diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Bgr24.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Bgr24.cs index 6cff5fd77..22e983a65 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Bgr24.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Bgr24.cs @@ -56,7 +56,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// The . /// The . [MethodImpl(InliningOptions.ShortMethod)] - public static implicit operator Color(Bgr24 source) => new Color(source); + public static implicit operator Color(Bgr24 source) => new(source); /// /// Converts a to . @@ -225,7 +225,7 @@ namespace SixLabors.ImageSharp.PixelFormats public override readonly bool Equals(object obj) => obj is Bgr24 other && this.Equals(other); /// - public override readonly string ToString() => $"Bgra({this.B}, {this.G}, {this.R})"; + public override readonly string ToString() => $"Bgr24({this.B}, {this.G}, {this.R})"; /// [MethodImpl(InliningOptions.ShortMethod)] diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Bgr565.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Bgr565.cs index fd12b6837..5585310b9 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Bgr565.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Bgr565.cs @@ -81,7 +81,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public readonly Vector4 ToVector4() => new Vector4(this.ToVector3(), 1F); + public readonly Vector4 ToVector4() => new(this.ToVector3(), 1F); /// [MethodImpl(InliningOptions.ShortMethod)] @@ -125,10 +125,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void ToRgba32(ref Rgba32 dest) - { - dest.FromScaledVector4(this.ToScaledVector4()); - } + public void ToRgba32(ref Rgba32 dest) => dest.FromScaledVector4(this.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] @@ -144,13 +141,10 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// The . [MethodImpl(InliningOptions.ShortMethod)] - public readonly Vector3 ToVector3() - { - return new Vector3( + public readonly Vector3 ToVector3() => new( ((this.PackedValue >> 11) & 0x1F) * (1F / 31F), ((this.PackedValue >> 5) & 0x3F) * (1F / 63F), (this.PackedValue & 0x1F) * (1F / 31F)); - } /// public override readonly bool Equals(object obj) => obj is Bgr565 other && this.Equals(other); diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Bgra32.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Bgra32.cs index 190345dda..be4e178c2 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Bgra32.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Bgra32.cs @@ -41,12 +41,12 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// The maximum byte value. /// - private static readonly Vector4 MaxBytes = new Vector4(255); + private static readonly Vector4 MaxBytes = new(255); /// /// The half vector value. /// - private static readonly Vector4 Half = new Vector4(0.5F); + private static readonly Vector4 Half = new(0.5F); /// /// Initializes a new instance of the struct. @@ -104,7 +104,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// The . /// The . [MethodImpl(InliningOptions.ShortMethod)] - public static implicit operator Color(Bgra32 source) => new Color(source); + public static implicit operator Color(Bgra32 source) => new(source); /// /// Converts a to . diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Bgra4444.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Bgra4444.cs index 8fa5219d5..3578f1dd3 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Bgra4444.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Bgra4444.cs @@ -128,10 +128,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void ToRgba32(ref Rgba32 dest) - { - dest.FromScaledVector4(this.ToScaledVector4()); - } + public void ToRgba32(ref Rgba32 dest) => dest.FromScaledVector4(this.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Bgra5551.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Bgra5551.cs index b3a0d0896..0254397c3 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Bgra5551.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Bgra5551.cs @@ -78,14 +78,11 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public readonly Vector4 ToVector4() - { - return new Vector4( + public readonly Vector4 ToVector4() => new( ((this.PackedValue >> 10) & 0x1F) / 31F, ((this.PackedValue >> 5) & 0x1F) / 31F, ((this.PackedValue >> 0) & 0x1F) / 31F, (this.PackedValue >> 15) & 0x01); - } /// [MethodImpl(InliningOptions.ShortMethod)] @@ -129,10 +126,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void ToRgba32(ref Rgba32 dest) - { - dest.FromScaledVector4(this.ToScaledVector4()); - } + public void ToRgba32(ref Rgba32 dest) => dest.FromScaledVector4(this.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Byte4.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Byte4.cs index e26121291..0995f8417 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Byte4.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Byte4.cs @@ -78,14 +78,11 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public readonly Vector4 ToVector4() - { - return new Vector4( + public readonly Vector4 ToVector4() => new( this.PackedValue & 0xFF, (this.PackedValue >> 0x8) & 0xFF, (this.PackedValue >> 0x10) & 0xFF, (this.PackedValue >> 0x18) & 0xFF); - } /// [MethodImpl(InliningOptions.ShortMethod)] @@ -129,10 +126,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void ToRgba32(ref Rgba32 dest) - { - dest.FromScaledVector4(this.ToScaledVector4()); - } + public void ToRgba32(ref Rgba32 dest) => dest.FromScaledVector4(this.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/HalfSingle.cs b/src/ImageSharp/PixelFormats/PixelImplementations/HalfSingle.cs index 5c4aa1cfb..b0ef0f6a9 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/HalfSingle.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/HalfSingle.cs @@ -74,7 +74,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public readonly Vector4 ToVector4() => new Vector4(this.ToSingle(), 0, 0, 1F); + public readonly Vector4 ToVector4() => new(this.ToSingle(), 0, 0, 1F); /// [MethodImpl(InliningOptions.ShortMethod)] @@ -118,10 +118,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void ToRgba32(ref Rgba32 dest) - { - dest.FromScaledVector4(this.ToScaledVector4()); - } + public void ToRgba32(ref Rgba32 dest) => dest.FromScaledVector4(this.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/HalfVector2.cs b/src/ImageSharp/PixelFormats/PixelImplementations/HalfVector2.cs index 39cb6f799..8be826130 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/HalfVector2.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/HalfVector2.cs @@ -129,10 +129,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void ToRgba32(ref Rgba32 dest) - { - dest.FromScaledVector4(this.ToScaledVector4()); - } + public void ToRgba32(ref Rgba32 dest) => dest.FromScaledVector4(this.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/HalfVector4.cs b/src/ImageSharp/PixelFormats/PixelImplementations/HalfVector4.cs index 9826d61a2..955b274ac 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/HalfVector4.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/HalfVector4.cs @@ -86,14 +86,11 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public readonly Vector4 ToVector4() - { - return new Vector4( + public readonly Vector4 ToVector4() => new( HalfTypeHelper.Unpack((ushort)this.PackedValue), HalfTypeHelper.Unpack((ushort)(this.PackedValue >> 0x10)), HalfTypeHelper.Unpack((ushort)(this.PackedValue >> 0x20)), HalfTypeHelper.Unpack((ushort)(this.PackedValue >> 0x30))); - } /// [MethodImpl(InliningOptions.ShortMethod)] @@ -137,10 +134,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void ToRgba32(ref Rgba32 dest) - { - dest.FromScaledVector4(this.ToScaledVector4()); - } + public void ToRgba32(ref Rgba32 dest) => dest.FromScaledVector4(this.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/L16.cs b/src/ImageSharp/PixelFormats/PixelImplementations/L16.cs index dd31aae2f..6d1128dd2 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/L16.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/L16.cs @@ -72,33 +72,24 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void FromArgb32(Argb32 source) - { - this.PackedValue = ColorNumerics.Get16BitBT709Luminance( + public void FromArgb32(Argb32 source) => this.PackedValue = ColorNumerics.Get16BitBT709Luminance( ColorNumerics.UpscaleFrom8BitTo16Bit(source.R), ColorNumerics.UpscaleFrom8BitTo16Bit(source.G), ColorNumerics.UpscaleFrom8BitTo16Bit(source.B)); - } /// [MethodImpl(InliningOptions.ShortMethod)] - public void FromBgr24(Bgr24 source) - { - this.PackedValue = ColorNumerics.Get16BitBT709Luminance( + public void FromBgr24(Bgr24 source) => this.PackedValue = ColorNumerics.Get16BitBT709Luminance( ColorNumerics.UpscaleFrom8BitTo16Bit(source.R), ColorNumerics.UpscaleFrom8BitTo16Bit(source.G), ColorNumerics.UpscaleFrom8BitTo16Bit(source.B)); - } /// [MethodImpl(InliningOptions.ShortMethod)] - public void FromBgra32(Bgra32 source) - { - this.PackedValue = ColorNumerics.Get16BitBT709Luminance( + public void FromBgra32(Bgra32 source) => this.PackedValue = ColorNumerics.Get16BitBT709Luminance( ColorNumerics.UpscaleFrom8BitTo16Bit(source.R), ColorNumerics.UpscaleFrom8BitTo16Bit(source.G), ColorNumerics.UpscaleFrom8BitTo16Bit(source.B)); - } /// [MethodImpl(InliningOptions.ShortMethod)] @@ -122,23 +113,17 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void FromRgb24(Rgb24 source) - { - this.PackedValue = ColorNumerics.Get16BitBT709Luminance( + public void FromRgb24(Rgb24 source) => this.PackedValue = ColorNumerics.Get16BitBT709Luminance( ColorNumerics.UpscaleFrom8BitTo16Bit(source.R), ColorNumerics.UpscaleFrom8BitTo16Bit(source.G), ColorNumerics.UpscaleFrom8BitTo16Bit(source.B)); - } /// [MethodImpl(InliningOptions.ShortMethod)] - public void FromRgba32(Rgba32 source) - { - this.PackedValue = ColorNumerics.Get16BitBT709Luminance( + public void FromRgba32(Rgba32 source) => this.PackedValue = ColorNumerics.Get16BitBT709Luminance( ColorNumerics.UpscaleFrom8BitTo16Bit(source.R), ColorNumerics.UpscaleFrom8BitTo16Bit(source.G), ColorNumerics.UpscaleFrom8BitTo16Bit(source.B)); - } /// [MethodImpl(InliningOptions.ShortMethod)] diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/L8.cs b/src/ImageSharp/PixelFormats/PixelImplementations/L8.cs index c570c33a1..ffff60be5 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/L8.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/L8.cs @@ -14,8 +14,8 @@ namespace SixLabors.ImageSharp.PixelFormats /// public partial struct L8 : IPixel, IPackedVector { - private static readonly Vector4 MaxBytes = new Vector4(255F); - private static readonly Vector4 Half = new Vector4(0.5F); + private static readonly Vector4 MaxBytes = new(255F); + private static readonly Vector4 Half = new(0.5F); /// /// Initializes a new instance of the struct. diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/La16.cs b/src/ImageSharp/PixelFormats/PixelImplementations/La16.cs index 5a69431a1..877aaed81 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/La16.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/La16.cs @@ -16,8 +16,8 @@ namespace SixLabors.ImageSharp.PixelFormats [StructLayout(LayoutKind.Explicit)] public partial struct La16 : IPixel, IPackedVector { - private static readonly Vector4 MaxBytes = new Vector4(255F); - private static readonly Vector4 Half = new Vector4(0.5F); + private static readonly Vector4 MaxBytes = new(255F); + private static readonly Vector4 Half = new(0.5F); /// /// Gets or sets the luminance component. @@ -35,7 +35,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// Initializes a new instance of the struct. /// /// The luminance component. - /// The alpha componant. + /// The alpha component. public La16(byte l, byte a) { this.L = l; diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/La32.cs b/src/ImageSharp/PixelFormats/PixelImplementations/La32.cs index 66d0e38c7..f19f22813 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/La32.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/La32.cs @@ -35,7 +35,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// Initializes a new instance of the struct. /// /// The luminance component. - /// The alpha componant. + /// The alpha component. public La32(ushort l, ushort a) { this.L = l; diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/NormalizedByte2.cs b/src/ImageSharp/PixelFormats/PixelImplementations/NormalizedByte2.cs index 8b244d391..62eaf949d 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/NormalizedByte2.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/NormalizedByte2.cs @@ -15,8 +15,10 @@ namespace SixLabors.ImageSharp.PixelFormats /// public partial struct NormalizedByte2 : IPixel, IPackedVector { - private static readonly Vector2 Half = new Vector2(127); - private static readonly Vector2 MinusOne = new Vector2(-1F); + private const float MaxPos = 127F; + + private static readonly Vector2 Half = new(MaxPos); + private static readonly Vector2 MinusOne = new(-1F); /// /// Initializes a new instance of the struct. @@ -91,7 +93,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public readonly Vector4 ToVector4() => new Vector4(this.ToVector2(), 0F, 1F); + public readonly Vector4 ToVector4() => new(this.ToVector2(), 0F, 1F); /// [MethodImpl(InliningOptions.ShortMethod)] @@ -151,12 +153,9 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// The . [MethodImpl(InliningOptions.ShortMethod)] - public readonly Vector2 ToVector2() - { - return new Vector2( - (sbyte)((this.PackedValue >> 0) & 0xFF) / 127F, - (sbyte)((this.PackedValue >> 8) & 0xFF) / 127F); - } + public readonly Vector2 ToVector2() => new( + (sbyte)((this.PackedValue >> 0) & 0xFF) / MaxPos, + (sbyte)((this.PackedValue >> 8) & 0xFF) / MaxPos); /// public override readonly bool Equals(object obj) => obj is NormalizedByte2 other && this.Equals(other); @@ -181,8 +180,8 @@ namespace SixLabors.ImageSharp.PixelFormats { vector = Vector2.Clamp(vector, MinusOne, Vector2.One) * Half; - int byte2 = ((ushort)Math.Round(vector.X) & 0xFF) << 0; - int byte1 = ((ushort)Math.Round(vector.Y) & 0xFF) << 8; + int byte2 = ((ushort)Convert.ToInt16(Math.Round(vector.X)) & 0xFF) << 0; + int byte1 = ((ushort)Convert.ToInt16(Math.Round(vector.Y)) & 0xFF) << 8; return (ushort)(byte2 | byte1); } diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/NormalizedByte4.cs b/src/ImageSharp/PixelFormats/PixelImplementations/NormalizedByte4.cs index 84f0bb022..2e81b3e2d 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/NormalizedByte4.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/NormalizedByte4.cs @@ -15,8 +15,10 @@ namespace SixLabors.ImageSharp.PixelFormats /// public partial struct NormalizedByte4 : IPixel, IPackedVector { - private static readonly Vector4 Half = new Vector4(127); - private static readonly Vector4 MinusOne = new Vector4(-1F); + private const float MaxPos = 127F; + + private static readonly Vector4 Half = new(MaxPos); + private static readonly Vector4 MinusOne = new(-1F); /// /// Initializes a new instance of the struct. @@ -89,14 +91,11 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public readonly Vector4 ToVector4() - { - return new Vector4( - (sbyte)((this.PackedValue >> 0) & 0xFF) / 127F, - (sbyte)((this.PackedValue >> 8) & 0xFF) / 127F, - (sbyte)((this.PackedValue >> 16) & 0xFF) / 127F, - (sbyte)((this.PackedValue >> 24) & 0xFF) / 127F); - } + public readonly Vector4 ToVector4() => new( + (sbyte)((this.PackedValue >> 0) & 0xFF) / MaxPos, + (sbyte)((this.PackedValue >> 8) & 0xFF) / MaxPos, + (sbyte)((this.PackedValue >> 16) & 0xFF) / MaxPos, + (sbyte)((this.PackedValue >> 24) & 0xFF) / MaxPos); /// [MethodImpl(InliningOptions.ShortMethod)] @@ -140,10 +139,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void ToRgba32(ref Rgba32 dest) - { - dest.FromScaledVector4(this.ToScaledVector4()); - } + public void ToRgba32(ref Rgba32 dest) => dest.FromScaledVector4(this.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] @@ -176,10 +172,10 @@ namespace SixLabors.ImageSharp.PixelFormats { vector = Numerics.Clamp(vector, MinusOne, Vector4.One) * Half; - uint byte4 = ((uint)MathF.Round(vector.X) & 0xFF) << 0; - uint byte3 = ((uint)MathF.Round(vector.Y) & 0xFF) << 8; - uint byte2 = ((uint)MathF.Round(vector.Z) & 0xFF) << 16; - uint byte1 = ((uint)MathF.Round(vector.W) & 0xFF) << 24; + uint byte4 = ((uint)Convert.ToInt16(MathF.Round(vector.X)) & 0xFF) << 0; + uint byte3 = ((uint)Convert.ToInt16(MathF.Round(vector.Y)) & 0xFF) << 8; + uint byte2 = ((uint)Convert.ToInt16(MathF.Round(vector.Z)) & 0xFF) << 16; + uint byte1 = ((uint)Convert.ToInt16(MathF.Round(vector.W)) & 0xFF) << 24; return byte4 | byte3 | byte2 | byte1; } diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/NormalizedShort2.cs b/src/ImageSharp/PixelFormats/PixelImplementations/NormalizedShort2.cs index 97bbc1206..b97aaacec 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/NormalizedShort2.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/NormalizedShort2.cs @@ -15,7 +15,10 @@ namespace SixLabors.ImageSharp.PixelFormats /// public partial struct NormalizedShort2 : IPixel, IPackedVector { - private static readonly Vector2 Max = new Vector2(0x7FFF); + // Largest two byte positive number 0xFFFF >> 1; + private const float MaxPos = 0x7FFF; + + private static readonly Vector2 Max = new(MaxPos); private static readonly Vector2 Min = Vector2.Negate(Max); /// @@ -135,10 +138,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void ToRgba32(ref Rgba32 dest) - { - dest.FromScaledVector4(this.ToScaledVector4()); - } + public void ToRgba32(ref Rgba32 dest) => dest.FromScaledVector4(this.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] @@ -154,14 +154,9 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// The . [MethodImpl(InliningOptions.ShortMethod)] - public readonly Vector2 ToVector2() - { - const float MaxVal = 0x7FFF; - - return new Vector2( - (short)(this.PackedValue & 0xFFFF) / MaxVal, - (short)(this.PackedValue >> 0x10) / MaxVal); - } + public readonly Vector2 ToVector2() => new( + (short)(this.PackedValue & 0xFFFF) / MaxPos, + (short)(this.PackedValue >> 0x10) / MaxPos); /// public override readonly bool Equals(object obj) => obj is NormalizedShort2 other && this.Equals(other); diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/NormalizedShort4.cs b/src/ImageSharp/PixelFormats/PixelImplementations/NormalizedShort4.cs index a3fd8989c..f2e8aedd8 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/NormalizedShort4.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/NormalizedShort4.cs @@ -15,7 +15,10 @@ namespace SixLabors.ImageSharp.PixelFormats /// public partial struct NormalizedShort4 : IPixel, IPackedVector { - private static readonly Vector4 Max = new Vector4(0x7FFF); + // Largest two byte positive number 0xFFFF >> 1; + private const float MaxPos = 0x7FFF; + + private static readonly Vector4 Max = new(MaxPos); private static readonly Vector4 Min = Vector4.Negate(Max); /// @@ -89,16 +92,11 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public readonly Vector4 ToVector4() - { - const float MaxVal = 0x7FFF; - - return new Vector4( - (short)((this.PackedValue >> 0x00) & 0xFFFF) / MaxVal, - (short)((this.PackedValue >> 0x10) & 0xFFFF) / MaxVal, - (short)((this.PackedValue >> 0x20) & 0xFFFF) / MaxVal, - (short)((this.PackedValue >> 0x30) & 0xFFFF) / MaxVal); - } + public readonly Vector4 ToVector4() => new( + (short)((this.PackedValue >> 0x00) & 0xFFFF) / MaxPos, + (short)((this.PackedValue >> 0x10) & 0xFFFF) / MaxPos, + (short)((this.PackedValue >> 0x20) & 0xFFFF) / MaxPos, + (short)((this.PackedValue >> 0x30) & 0xFFFF) / MaxPos); /// [MethodImpl(InliningOptions.ShortMethod)] @@ -142,10 +140,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void ToRgba32(ref Rgba32 dest) - { - dest.FromScaledVector4(this.ToScaledVector4()); - } + public void ToRgba32(ref Rgba32 dest) => dest.FromScaledVector4(this.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] @@ -180,10 +175,10 @@ namespace SixLabors.ImageSharp.PixelFormats vector = Numerics.Clamp(vector, Min, Max); // Round rather than truncate. - ulong word4 = ((ulong)MathF.Round(vector.X) & 0xFFFF) << 0x00; - ulong word3 = ((ulong)MathF.Round(vector.Y) & 0xFFFF) << 0x10; - ulong word2 = ((ulong)MathF.Round(vector.Z) & 0xFFFF) << 0x20; - ulong word1 = ((ulong)MathF.Round(vector.W) & 0xFFFF) << 0x30; + ulong word4 = ((ulong)Convert.ToInt32(MathF.Round(vector.X)) & 0xFFFF) << 0x00; + ulong word3 = ((ulong)Convert.ToInt32(MathF.Round(vector.Y)) & 0xFFFF) << 0x10; + ulong word2 = ((ulong)Convert.ToInt32(MathF.Round(vector.Z)) & 0xFFFF) << 0x20; + ulong word1 = ((ulong)Convert.ToInt32(MathF.Round(vector.W)) & 0xFFFF) << 0x30; return word4 | word3 | word2 | word1; } diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/PixelOperations/Rgb24.PixelOperations.cs b/src/ImageSharp/PixelFormats/PixelImplementations/PixelOperations/Rgb24.PixelOperations.cs index f345f58bc..0f1ea6b81 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/PixelOperations/Rgb24.PixelOperations.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/PixelOperations/Rgb24.PixelOperations.cs @@ -32,9 +32,7 @@ namespace SixLabors.ImageSharp.PixelFormats { Guard.NotNull(configuration, nameof(configuration)); int count = redChannel.Length; - Guard.IsTrue(greenChannel.Length == count, nameof(greenChannel), "Channels must be of same size!"); - Guard.IsTrue(blueChannel.Length == count, nameof(blueChannel), "Channels must be of same size!"); - Guard.IsTrue(destination.Length > count + 2, nameof(destination), "'destination' must contain a padding of 3 elements!"); + GuardPackFromRgbPlanes(greenChannel, blueChannel, destination, count); SimdUtils.PackFromRgbPlanes(configuration, redChannel, greenChannel, blueChannel, destination); } diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/PixelOperations/Rgba32.PixelOperations.cs b/src/ImageSharp/PixelFormats/PixelImplementations/PixelOperations/Rgba32.PixelOperations.cs index 963305977..d937da98f 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/PixelOperations/Rgba32.PixelOperations.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/PixelOperations/Rgba32.PixelOperations.cs @@ -67,9 +67,7 @@ namespace SixLabors.ImageSharp.PixelFormats { Guard.NotNull(configuration, nameof(configuration)); int count = redChannel.Length; - Guard.IsTrue(greenChannel.Length == count, nameof(greenChannel), "Channels must be of same size!"); - Guard.IsTrue(blueChannel.Length == count, nameof(blueChannel), "Channels must be of same size!"); - Guard.IsTrue(destination.Length > count, nameof(destination), "'destination' span should not be shorter than the source channels!"); + GuardPackFromRgbPlanes(greenChannel, blueChannel, destination, count); SimdUtils.PackFromRgbPlanes(configuration, redChannel, greenChannel, blueChannel, destination); } diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Rg32.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Rg32.cs index d7e6f53cf..12b6e153f 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Rg32.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Rg32.cs @@ -15,7 +15,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// public partial struct Rg32 : IPixel, IPackedVector { - private static readonly Vector2 Max = new Vector2(ushort.MaxValue); + private static readonly Vector2 Max = new(ushort.MaxValue); /// /// Initializes a new instance of the struct. @@ -79,7 +79,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public readonly Vector4 ToVector4() => new Vector4(this.ToVector2(), 0F, 1F); + public readonly Vector4 ToVector4() => new(this.ToVector2(), 0F, 1F); /// [MethodImpl(InliningOptions.ShortMethod)] @@ -123,10 +123,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void ToRgba32(ref Rgba32 dest) - { - dest.FromScaledVector4(this.ToScaledVector4()); - } + public void ToRgba32(ref Rgba32 dest) => dest.FromScaledVector4(this.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Rgb24.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Rgb24.cs index 7fd63c676..3b5bdb3d5 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Rgb24.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Rgb24.cs @@ -36,8 +36,8 @@ namespace SixLabors.ImageSharp.PixelFormats [FieldOffset(2)] public byte B; - private static readonly Vector4 MaxBytes = new Vector4(byte.MaxValue); - private static readonly Vector4 Half = new Vector4(0.5F); + private static readonly Vector4 MaxBytes = new(byte.MaxValue); + private static readonly Vector4 Half = new(0.5F); /// /// Initializes a new instance of the struct. diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Rgb48.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Rgb48.cs index e3738b70c..d16b7db7a 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Rgb48.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Rgb48.cs @@ -93,7 +93,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public readonly Vector4 ToVector4() => new Vector4(this.R / Max, this.G / Max, this.B / Max, 1F); + public readonly Vector4 ToVector4() => new(this.R / Max, this.G / Max, this.B / Max, 1F); /// [MethodImpl(InliningOptions.ShortMethod)] diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Rgba1010102.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Rgba1010102.cs index dee2f9fcb..e68726018 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Rgba1010102.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Rgba1010102.cs @@ -16,7 +16,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// public partial struct Rgba1010102 : IPixel, IPackedVector { - private static readonly Vector4 Multiplier = new Vector4(1023F, 1023F, 1023F, 3F); + private static readonly Vector4 Multiplier = new(1023F, 1023F, 1023F, 3F); /// /// Initializes a new instance of the struct. @@ -78,14 +78,11 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public readonly Vector4 ToVector4() - { - return new Vector4( + public readonly Vector4 ToVector4() => new Vector4( (this.PackedValue >> 0) & 0x03FF, (this.PackedValue >> 10) & 0x03FF, (this.PackedValue >> 20) & 0x03FF, (this.PackedValue >> 30) & 0x03) / Multiplier; - } /// [MethodImpl(InliningOptions.ShortMethod)] @@ -129,10 +126,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void ToRgba32(ref Rgba32 dest) - { - dest.FromScaledVector4(this.ToScaledVector4()); - } + public void ToRgba32(ref Rgba32 dest) => dest.FromScaledVector4(this.ToScaledVector4()); /// [MethodImpl(InliningOptions.ShortMethod)] diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Rgba32.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Rgba32.cs index 868165e9c..3dc6490f1 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Rgba32.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Rgba32.cs @@ -44,8 +44,8 @@ namespace SixLabors.ImageSharp.PixelFormats /// public byte A; - private static readonly Vector4 MaxBytes = new Vector4(byte.MaxValue); - private static readonly Vector4 Half = new Vector4(0.5F); + private static readonly Vector4 MaxBytes = new(byte.MaxValue); + private static readonly Vector4 Half = new(0.5F); /// /// Initializes a new instance of the struct. @@ -137,7 +137,7 @@ namespace SixLabors.ImageSharp.PixelFormats public Rgb24 Rgb { [MethodImpl(InliningOptions.ShortMethod)] - readonly get => new Rgb24(this.R, this.G, this.B); + readonly get => new(this.R, this.G, this.B); [MethodImpl(InliningOptions.ShortMethod)] set @@ -154,7 +154,7 @@ namespace SixLabors.ImageSharp.PixelFormats public Bgr24 Bgr { [MethodImpl(InliningOptions.ShortMethod)] - readonly get => new Bgr24(this.R, this.G, this.B); + readonly get => new(this.R, this.G, this.B); [MethodImpl(InliningOptions.ShortMethod)] set @@ -181,7 +181,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// The . /// The . [MethodImpl(InliningOptions.ShortMethod)] - public static implicit operator Color(Rgba32 source) => new Color(source); + public static implicit operator Color(Rgba32 source) => new(source); /// /// Converts a to . @@ -393,10 +393,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public void ToRgba32(ref Rgba32 dest) - { - dest = this; - } + public void ToRgba32(ref Rgba32 dest) => dest = this; /// [MethodImpl(InliningOptions.ShortMethod)] @@ -424,7 +421,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// A hexadecimal string representation of the value. public readonly string ToHex() { - uint hexOrder = (uint)(this.A << 0 | this.B << 8 | this.G << 16 | this.R << 24); + uint hexOrder = (uint)((this.A << 0) | (this.B << 8) | (this.G << 16) | (this.R << 24)); return hexOrder.ToString("X8"); } @@ -523,7 +520,7 @@ namespace SixLabors.ImageSharp.PixelFormats return hex + "FF"; } - if (hex.Length < 3 || hex.Length > 4) + if (hex.Length is < 3 or > 4) { return null; } diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Rgba64.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Rgba64.cs index 9add3d718..4cfa0bf97 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Rgba64.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Rgba64.cs @@ -162,7 +162,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// The . /// The . [MethodImpl(InliningOptions.ShortMethod)] - public static implicit operator Color(Rgba64 source) => new Color(source); + public static implicit operator Color(Rgba64 source) => new(source); /// /// Converts a to . diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/RgbaVector.cs b/src/ImageSharp/PixelFormats/PixelImplementations/RgbaVector.cs index 97e103d0f..cd6f53c4e 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/RgbaVector.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/RgbaVector.cs @@ -43,8 +43,8 @@ namespace SixLabors.ImageSharp.PixelFormats public float A; private const float MaxBytes = byte.MaxValue; - private static readonly Vector4 Max = new Vector4(MaxBytes); - private static readonly Vector4 Half = new Vector4(0.5F); + private static readonly Vector4 Max = new(MaxBytes); + private static readonly Vector4 Half = new(0.5F); /// /// Initializes a new instance of the struct. @@ -120,7 +120,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public readonly Vector4 ToVector4() => new Vector4(this.R, this.G, this.B, this.A); + public readonly Vector4 ToVector4() => new(this.R, this.G, this.B, this.A); /// [MethodImpl(InliningOptions.ShortMethod)] @@ -183,7 +183,7 @@ namespace SixLabors.ImageSharp.PixelFormats // Hex is RRGGBBAA Vector4 vector = this.ToVector4() * Max; vector += Half; - uint hexOrder = (uint)((byte)vector.W | (byte)vector.Z << 8 | (byte)vector.Y << 16 | (byte)vector.X << 24); + uint hexOrder = (uint)((byte)vector.W | ((byte)vector.Z << 8) | ((byte)vector.Y << 16) | ((byte)vector.X << 24)); return hexOrder.ToString("X8"); } @@ -199,10 +199,7 @@ namespace SixLabors.ImageSharp.PixelFormats && this.A.Equals(other.A); /// - public override readonly string ToString() - { - return FormattableString.Invariant($"RgbaVector({this.R:#0.##}, {this.G:#0.##}, {this.B:#0.##}, {this.A:#0.##})"); - } + public override readonly string ToString() => FormattableString.Invariant($"RgbaVector({this.R:#0.##}, {this.G:#0.##}, {this.B:#0.##}, {this.A:#0.##})"); /// public override readonly int GetHashCode() => HashCode.Combine(this.R, this.G, this.B, this.A); diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Short2.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Short2.cs index f7a4f9994..24f6b4d1d 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Short2.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Short2.cs @@ -21,8 +21,8 @@ namespace SixLabors.ImageSharp.PixelFormats // Two's complement private const float MinNeg = ~(int)MaxPos; - private static readonly Vector2 Max = new Vector2(MaxPos); - private static readonly Vector2 Min = new Vector2(MinNeg); + private static readonly Vector2 Max = new(MaxPos); + private static readonly Vector2 Min = new(MinNeg); /// /// Initializes a new instance of the struct. @@ -97,7 +97,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// [MethodImpl(InliningOptions.ShortMethod)] - public readonly Vector4 ToVector4() => new Vector4((short)(this.PackedValue & 0xFFFF), (short)(this.PackedValue >> 0x10), 0, 1); + public readonly Vector4 ToVector4() => new((short)(this.PackedValue & 0xFFFF), (short)(this.PackedValue >> 0x10), 0, 1); /// [MethodImpl(InliningOptions.ShortMethod)] @@ -157,7 +157,7 @@ namespace SixLabors.ImageSharp.PixelFormats /// /// The . [MethodImpl(InliningOptions.ShortMethod)] - public readonly Vector2 ToVector2() => new Vector2((short)(this.PackedValue & 0xFFFF), (short)(this.PackedValue >> 0x10)); + public readonly Vector2 ToVector2() => new((short)(this.PackedValue & 0xFFFF), (short)(this.PackedValue >> 0x10)); /// public override readonly bool Equals(object obj) => obj is Short2 other && this.Equals(other); @@ -181,8 +181,8 @@ namespace SixLabors.ImageSharp.PixelFormats private static uint Pack(Vector2 vector) { vector = Vector2.Clamp(vector, Min, Max); - uint word2 = (uint)Math.Round(vector.X) & 0xFFFF; - uint word1 = ((uint)Math.Round(vector.Y) & 0xFFFF) << 0x10; + uint word2 = (uint)Convert.ToInt32(Math.Round(vector.X)) & 0xFFFF; + uint word1 = ((uint)Convert.ToInt32(Math.Round(vector.Y)) & 0xFFFF) << 0x10; return word2 | word1; } diff --git a/src/ImageSharp/PixelFormats/PixelImplementations/Short4.cs b/src/ImageSharp/PixelFormats/PixelImplementations/Short4.cs index 409f46c72..86a519297 100644 --- a/src/ImageSharp/PixelFormats/PixelImplementations/Short4.cs +++ b/src/ImageSharp/PixelFormats/PixelImplementations/Short4.cs @@ -186,10 +186,10 @@ namespace SixLabors.ImageSharp.PixelFormats vector = Numerics.Clamp(vector, Min, Max); // Clamp the value between min and max values - ulong word4 = ((ulong)Math.Round(vector.X) & 0xFFFF) << 0x00; - ulong word3 = ((ulong)Math.Round(vector.Y) & 0xFFFF) << 0x10; - ulong word2 = ((ulong)Math.Round(vector.Z) & 0xFFFF) << 0x20; - ulong word1 = ((ulong)Math.Round(vector.W) & 0xFFFF) << 0x30; + ulong word4 = ((ulong)Convert.ToInt32(Math.Round(vector.X)) & 0xFFFF) << 0x00; + ulong word3 = ((ulong)Convert.ToInt32(Math.Round(vector.Y)) & 0xFFFF) << 0x10; + ulong word2 = ((ulong)Convert.ToInt32(Math.Round(vector.Z)) & 0xFFFF) << 0x20; + ulong word1 = ((ulong)Convert.ToInt32(Math.Round(vector.W)) & 0xFFFF) << 0x30; return word4 | word3 | word2 | word1; } diff --git a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs index c5450538e..f748a4b57 100644 --- a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs +++ b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs @@ -181,11 +181,7 @@ namespace SixLabors.ImageSharp.PixelFormats Guard.NotNull(configuration, nameof(configuration)); int count = redChannel.Length; - Guard.IsTrue(greenChannel.Length == count, nameof(greenChannel), "Channels must be of same size!"); - Guard.IsTrue(blueChannel.Length == count, nameof(blueChannel), "Channels must be of same size!"); - Guard.IsTrue(destination.Length > count + 2, nameof(destination), "'destination' must contain a padding of 3 elements!"); - - Guard.DestinationShouldNotBeTooShort(redChannel, destination, nameof(destination)); + GuardPackFromRgbPlanes(greenChannel, blueChannel, destination, count); Rgb24 rgb24 = default; ref byte r = ref MemoryMarshal.GetReference(redChannel); @@ -201,5 +197,13 @@ namespace SixLabors.ImageSharp.PixelFormats Unsafe.Add(ref d, i).FromRgb24(rgb24); } } + + [MethodImpl(InliningOptions.ShortMethod)] + internal static void GuardPackFromRgbPlanes(ReadOnlySpan greenChannel, ReadOnlySpan blueChannel, Span destination, int count) + { + Guard.IsTrue(greenChannel.Length == count, nameof(greenChannel), "Channels must be of same size!"); + Guard.IsTrue(blueChannel.Length == count, nameof(blueChannel), "Channels must be of same size!"); + Guard.IsTrue(destination.Length > count + 2, nameof(destination), "'destination' must contain a padding of 3 elements!"); + } } } diff --git a/src/ImageSharp/PixelFormats/Utils/Vector4Converters.cs b/src/ImageSharp/PixelFormats/Utils/Vector4Converters.cs index 7af266276..8df7f2c03 100644 --- a/src/ImageSharp/PixelFormats/Utils/Vector4Converters.cs +++ b/src/ImageSharp/PixelFormats/Utils/Vector4Converters.cs @@ -4,7 +4,6 @@ using System; using System.Numerics; using System.Runtime.CompilerServices; - using SixLabors.ImageSharp.ColorSpaces.Companding; namespace SixLabors.ImageSharp.PixelFormats.Utils @@ -14,7 +13,7 @@ namespace SixLabors.ImageSharp.PixelFormats.Utils /// /// Apply modifiers used requested by ToVector4() conversion. /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] internal static void ApplyForwardConversionModifiers(Span vectors, PixelConversionModifiers modifiers) { if (modifiers.IsDefined(PixelConversionModifiers.SRgbCompand)) @@ -31,7 +30,7 @@ namespace SixLabors.ImageSharp.PixelFormats.Utils /// /// Apply modifiers used requested by FromVector4() conversion. /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] + [MethodImpl(InliningOptions.ShortMethod)] internal static void ApplyBackwardConversionModifiers(Span vectors, PixelConversionModifiers modifiers) { if (modifiers.IsDefined(PixelConversionModifiers.Premultiply)) diff --git a/src/ImageSharp/Primitives/LongRational.cs b/src/ImageSharp/Primitives/LongRational.cs index 9f8eb9a1a..ec49a5b0f 100644 --- a/src/ImageSharp/Primitives/LongRational.cs +++ b/src/ImageSharp/Primitives/LongRational.cs @@ -223,4 +223,4 @@ namespace SixLabors.ImageSharp return this; } } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Primitives/Point.cs b/src/ImageSharp/Primitives/Point.cs index 653ec1fe3..3e097d5fa 100644 --- a/src/ImageSharp/Primitives/Point.cs +++ b/src/ImageSharp/Primitives/Point.cs @@ -285,4 +285,4 @@ namespace SixLabors.ImageSharp private static short LowInt16(int n) => unchecked((short)(n & 0xffff)); } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Primitives/PointF.cs b/src/ImageSharp/Primitives/PointF.cs index 848bfce4a..7c5703696 100644 --- a/src/ImageSharp/Primitives/PointF.cs +++ b/src/ImageSharp/Primitives/PointF.cs @@ -290,4 +290,4 @@ namespace SixLabors.ImageSharp [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool Equals(PointF other) => this.X.Equals(other.X) && this.Y.Equals(other.Y); } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Primitives/Rational.cs b/src/ImageSharp/Primitives/Rational.cs index b6f83e277..b14681c69 100644 --- a/src/ImageSharp/Primitives/Rational.cs +++ b/src/ImageSharp/Primitives/Rational.cs @@ -43,7 +43,7 @@ namespace SixLabors.ImageSharp { if (simplify) { - var rational = new LongRational(numerator, denominator).Simplify(); + LongRational rational = new LongRational(numerator, denominator).Simplify(); this.Numerator = (uint)rational.Numerator; this.Denominator = (uint)rational.Denominator; @@ -93,10 +93,7 @@ namespace SixLabors.ImageSharp /// The first to compare. /// The second to compare. /// The - public static bool operator ==(Rational left, Rational right) - { - return left.Equals(right); - } + public static bool operator ==(Rational left, Rational right) => left.Equals(right); /// /// Determines whether the specified instances are not considered equal. @@ -104,10 +101,7 @@ namespace SixLabors.ImageSharp /// The first to compare. /// The second to compare. /// The - public static bool operator !=(Rational left, Rational right) - { - return !left.Equals(right); - } + public static bool operator !=(Rational left, Rational right) => !left.Equals(right); /// /// Converts the specified to an instance of this type. @@ -116,10 +110,7 @@ namespace SixLabors.ImageSharp /// /// The . /// - public static Rational FromDouble(double value) - { - return new Rational(value, false); - } + public static Rational FromDouble(double value) => new Rational(value, false); /// /// Converts the specified to an instance of this type. @@ -129,16 +120,10 @@ namespace SixLabors.ImageSharp /// /// The . /// - public static Rational FromDouble(double value, bool bestPrecision) - { - return new Rational(value, bestPrecision); - } + public static Rational FromDouble(double value, bool bestPrecision) => new Rational(value, bestPrecision); /// - public override bool Equals(object obj) - { - return obj is Rational other && this.Equals(other); - } + public override bool Equals(object obj) => obj is Rational other && this.Equals(other); /// public bool Equals(Rational other) @@ -162,16 +147,18 @@ namespace SixLabors.ImageSharp /// /// The . /// - public double ToDouble() - { - return this.Numerator / (double)this.Denominator; - } + public double ToDouble() => this.Numerator / (double)this.Denominator; + + /// + /// Converts a rational number to the nearest . + /// + /// + /// The . + /// + public float ToSingle() => this.Numerator / (float)this.Denominator; /// - public override string ToString() - { - return this.ToString(CultureInfo.InvariantCulture); - } + public override string ToString() => this.ToString(CultureInfo.InvariantCulture); /// /// Converts the numeric value of this instance to its equivalent string representation using diff --git a/src/ImageSharp/Primitives/RectangleF.cs b/src/ImageSharp/Primitives/RectangleF.cs index d050c5139..6cda81423 100644 --- a/src/ImageSharp/Primitives/RectangleF.cs +++ b/src/ImageSharp/Primitives/RectangleF.cs @@ -393,4 +393,4 @@ namespace SixLabors.ImageSharp this.Width.Equals(other.Width) && this.Height.Equals(other.Height); } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Primitives/Size.cs b/src/ImageSharp/Primitives/Size.cs index 0790a3dbd..adc78ca10 100644 --- a/src/ImageSharp/Primitives/Size.cs +++ b/src/ImageSharp/Primitives/Size.cs @@ -293,4 +293,4 @@ namespace SixLabors.ImageSharp private static SizeF Multiply(Size size, float multiplier) => new SizeF(size.Width * multiplier, size.Height * multiplier); } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Primitives/SizeF.cs b/src/ImageSharp/Primitives/SizeF.cs index b62aa8b0d..a35b6eea6 100644 --- a/src/ImageSharp/Primitives/SizeF.cs +++ b/src/ImageSharp/Primitives/SizeF.cs @@ -230,4 +230,4 @@ namespace SixLabors.ImageSharp private static SizeF Multiply(SizeF size, float multiplier) => new SizeF(size.Width * multiplier, size.Height * multiplier); } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Primitives/ValueSize.cs b/src/ImageSharp/Primitives/ValueSize.cs index 86d54e26d..ee173aba3 100644 --- a/src/ImageSharp/Primitives/ValueSize.cs +++ b/src/ImageSharp/Primitives/ValueSize.cs @@ -130,4 +130,4 @@ namespace SixLabors.ImageSharp /// public override int GetHashCode() => HashCode.Combine(this.Value, this.Type); } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Processing/Extensions/Convolution/BoxBlurExtensions.cs b/src/ImageSharp/Processing/Extensions/Convolution/BoxBlurExtensions.cs index 1f75838ab..f891ffa97 100644 --- a/src/ImageSharp/Processing/Extensions/Convolution/BoxBlurExtensions.cs +++ b/src/ImageSharp/Processing/Extensions/Convolution/BoxBlurExtensions.cs @@ -40,4 +40,4 @@ namespace SixLabors.ImageSharp.Processing public static IImageProcessingContext BoxBlur(this IImageProcessingContext source, int radius, Rectangle rectangle) => source.ApplyProcessor(new BoxBlurProcessor(radius), rectangle); } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Processing/Extensions/Convolution/GaussianBlurExtensions.cs b/src/ImageSharp/Processing/Extensions/Convolution/GaussianBlurExtensions.cs index 824094935..bd4fb716d 100644 --- a/src/ImageSharp/Processing/Extensions/Convolution/GaussianBlurExtensions.cs +++ b/src/ImageSharp/Processing/Extensions/Convolution/GaussianBlurExtensions.cs @@ -40,4 +40,4 @@ namespace SixLabors.ImageSharp.Processing public static IImageProcessingContext GaussianBlur(this IImageProcessingContext source, float sigma, Rectangle rectangle) => source.ApplyProcessor(new GaussianBlurProcessor(sigma), rectangle); } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Processing/Extensions/Convolution/GaussianSharpenExtensions.cs b/src/ImageSharp/Processing/Extensions/Convolution/GaussianSharpenExtensions.cs index 78044e958..f5b8798f4 100644 --- a/src/ImageSharp/Processing/Extensions/Convolution/GaussianSharpenExtensions.cs +++ b/src/ImageSharp/Processing/Extensions/Convolution/GaussianSharpenExtensions.cs @@ -43,4 +43,4 @@ namespace SixLabors.ImageSharp.Processing Rectangle rectangle) => source.ApplyProcessor(new GaussianSharpenProcessor(sigma), rectangle); } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Processing/Extensions/Effects/OilPaintExtensions.cs b/src/ImageSharp/Processing/Extensions/Effects/OilPaintExtensions.cs index 13d9bc349..3e2b744de 100644 --- a/src/ImageSharp/Processing/Extensions/Effects/OilPaintExtensions.cs +++ b/src/ImageSharp/Processing/Extensions/Effects/OilPaintExtensions.cs @@ -59,4 +59,4 @@ namespace SixLabors.ImageSharp.Processing Rectangle rectangle) => source.ApplyProcessor(new OilPaintingProcessor(levels, brushSize), rectangle); } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Processing/Extensions/Effects/PixelateExtensions.cs b/src/ImageSharp/Processing/Extensions/Effects/PixelateExtensions.cs index 5316c46cf..f00203382 100644 --- a/src/ImageSharp/Processing/Extensions/Effects/PixelateExtensions.cs +++ b/src/ImageSharp/Processing/Extensions/Effects/PixelateExtensions.cs @@ -42,4 +42,4 @@ namespace SixLabors.ImageSharp.Processing Rectangle rectangle) => source.ApplyProcessor(new PixelateProcessor(size), rectangle); } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Processing/Extensions/Filters/BlackWhiteExtensions.cs b/src/ImageSharp/Processing/Extensions/Filters/BlackWhiteExtensions.cs index 76861af1a..7fe784fde 100644 --- a/src/ImageSharp/Processing/Extensions/Filters/BlackWhiteExtensions.cs +++ b/src/ImageSharp/Processing/Extensions/Filters/BlackWhiteExtensions.cs @@ -30,4 +30,4 @@ namespace SixLabors.ImageSharp.Processing public static IImageProcessingContext BlackWhite(this IImageProcessingContext source, Rectangle rectangle) => source.ApplyProcessor(new BlackWhiteProcessor(), rectangle); } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Processing/Extensions/Filters/ColorBlindnessExtensions.cs b/src/ImageSharp/Processing/Extensions/Filters/ColorBlindnessExtensions.cs index d46e3b284..ccbc2d9ef 100644 --- a/src/ImageSharp/Processing/Extensions/Filters/ColorBlindnessExtensions.cs +++ b/src/ImageSharp/Processing/Extensions/Filters/ColorBlindnessExtensions.cs @@ -56,4 +56,4 @@ namespace SixLabors.ImageSharp.Processing } } } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Processing/Extensions/Filters/ContrastExtensions.cs b/src/ImageSharp/Processing/Extensions/Filters/ContrastExtensions.cs index 01a346aac..a3896df67 100644 --- a/src/ImageSharp/Processing/Extensions/Filters/ContrastExtensions.cs +++ b/src/ImageSharp/Processing/Extensions/Filters/ContrastExtensions.cs @@ -40,4 +40,4 @@ namespace SixLabors.ImageSharp.Processing public static IImageProcessingContext Contrast(this IImageProcessingContext source, float amount, Rectangle rectangle) => source.ApplyProcessor(new ContrastProcessor(amount), rectangle); } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Processing/Extensions/Filters/HueExtensions.cs b/src/ImageSharp/Processing/Extensions/Filters/HueExtensions.cs index 59a46852d..9e62c3610 100644 --- a/src/ImageSharp/Processing/Extensions/Filters/HueExtensions.cs +++ b/src/ImageSharp/Processing/Extensions/Filters/HueExtensions.cs @@ -32,4 +32,4 @@ namespace SixLabors.ImageSharp.Processing public static IImageProcessingContext Hue(this IImageProcessingContext source, float degrees, Rectangle rectangle) => source.ApplyProcessor(new HueProcessor(degrees), rectangle); } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Processing/Extensions/Filters/InvertExtensions.cs b/src/ImageSharp/Processing/Extensions/Filters/InvertExtensions.cs index 03bfb2fa8..be7beea18 100644 --- a/src/ImageSharp/Processing/Extensions/Filters/InvertExtensions.cs +++ b/src/ImageSharp/Processing/Extensions/Filters/InvertExtensions.cs @@ -30,4 +30,4 @@ namespace SixLabors.ImageSharp.Processing public static IImageProcessingContext Invert(this IImageProcessingContext source, Rectangle rectangle) => source.ApplyProcessor(new InvertProcessor(1F), rectangle); } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Processing/Extensions/Filters/OpacityExtensions.cs b/src/ImageSharp/Processing/Extensions/Filters/OpacityExtensions.cs index 80d7d0c8a..44440e9c0 100644 --- a/src/ImageSharp/Processing/Extensions/Filters/OpacityExtensions.cs +++ b/src/ImageSharp/Processing/Extensions/Filters/OpacityExtensions.cs @@ -32,4 +32,4 @@ namespace SixLabors.ImageSharp.Processing public static IImageProcessingContext Opacity(this IImageProcessingContext source, float amount, Rectangle rectangle) => source.ApplyProcessor(new OpacityProcessor(amount), rectangle); } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Processing/Extensions/Filters/SaturateExtensions.cs b/src/ImageSharp/Processing/Extensions/Filters/SaturateExtensions.cs index b7d520be8..98eaf0d2f 100644 --- a/src/ImageSharp/Processing/Extensions/Filters/SaturateExtensions.cs +++ b/src/ImageSharp/Processing/Extensions/Filters/SaturateExtensions.cs @@ -40,4 +40,4 @@ namespace SixLabors.ImageSharp.Processing public static IImageProcessingContext Saturate(this IImageProcessingContext source, float amount, Rectangle rectangle) => source.ApplyProcessor(new SaturateProcessor(amount), rectangle); } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Processing/Extensions/Filters/SepiaExtensions.cs b/src/ImageSharp/Processing/Extensions/Filters/SepiaExtensions.cs index 8d818cb0b..759373cc0 100644 --- a/src/ImageSharp/Processing/Extensions/Filters/SepiaExtensions.cs +++ b/src/ImageSharp/Processing/Extensions/Filters/SepiaExtensions.cs @@ -51,4 +51,4 @@ namespace SixLabors.ImageSharp.Processing public static IImageProcessingContext Sepia(this IImageProcessingContext source, float amount, Rectangle rectangle) => source.ApplyProcessor(new SepiaProcessor(amount), rectangle); } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Processing/Extensions/Normalization/HistogramEqualizationExtensions.cs b/src/ImageSharp/Processing/Extensions/Normalization/HistogramEqualizationExtensions.cs index 175c7648a..a8ac3376a 100644 --- a/src/ImageSharp/Processing/Extensions/Normalization/HistogramEqualizationExtensions.cs +++ b/src/ImageSharp/Processing/Extensions/Normalization/HistogramEqualizationExtensions.cs @@ -29,4 +29,4 @@ namespace SixLabors.ImageSharp.Processing HistogramEqualizationOptions options) => source.ApplyProcessor(HistogramEqualizationProcessor.FromOptions(options)); } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Processing/Extensions/ProcessingExtensions.cs b/src/ImageSharp/Processing/Extensions/ProcessingExtensions.cs index ac14d8423..1a005368e 100644 --- a/src/ImageSharp/Processing/Extensions/ProcessingExtensions.cs +++ b/src/ImageSharp/Processing/Extensions/ProcessingExtensions.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. using System; - using SixLabors.ImageSharp.Advanced; using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.Processing.Processors; diff --git a/src/ImageSharp/Processing/Extensions/Transforms/AutoOrientExtensions.cs b/src/ImageSharp/Processing/Extensions/Transforms/AutoOrientExtensions.cs index 0011101e6..e67cb5617 100644 --- a/src/ImageSharp/Processing/Extensions/Transforms/AutoOrientExtensions.cs +++ b/src/ImageSharp/Processing/Extensions/Transforms/AutoOrientExtensions.cs @@ -19,4 +19,4 @@ namespace SixLabors.ImageSharp.Processing public static IImageProcessingContext AutoOrient(this IImageProcessingContext source) => source.ApplyProcessor(new AutoOrientProcessor()); } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Processing/Extensions/Transforms/CropExtensions.cs b/src/ImageSharp/Processing/Extensions/Transforms/CropExtensions.cs index 5b62b226d..28f37308f 100644 --- a/src/ImageSharp/Processing/Extensions/Transforms/CropExtensions.cs +++ b/src/ImageSharp/Processing/Extensions/Transforms/CropExtensions.cs @@ -32,4 +32,4 @@ namespace SixLabors.ImageSharp.Processing public static IImageProcessingContext Crop(this IImageProcessingContext source, Rectangle cropRectangle) => source.ApplyProcessor(new CropProcessor(cropRectangle, source.GetCurrentSize())); } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Processing/Extensions/Transforms/EntropyCropExtensions.cs b/src/ImageSharp/Processing/Extensions/Transforms/EntropyCropExtensions.cs index 9324a6977..476a09f58 100644 --- a/src/ImageSharp/Processing/Extensions/Transforms/EntropyCropExtensions.cs +++ b/src/ImageSharp/Processing/Extensions/Transforms/EntropyCropExtensions.cs @@ -28,4 +28,4 @@ namespace SixLabors.ImageSharp.Processing public static IImageProcessingContext EntropyCrop(this IImageProcessingContext source, float threshold) => source.ApplyProcessor(new EntropyCropProcessor(threshold)); } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Processing/Extensions/Transforms/FlipExtensions.cs b/src/ImageSharp/Processing/Extensions/Transforms/FlipExtensions.cs index 9f08ecaaf..6ab758120 100644 --- a/src/ImageSharp/Processing/Extensions/Transforms/FlipExtensions.cs +++ b/src/ImageSharp/Processing/Extensions/Transforms/FlipExtensions.cs @@ -20,4 +20,4 @@ namespace SixLabors.ImageSharp.Processing public static IImageProcessingContext Flip(this IImageProcessingContext source, FlipMode flipMode) => source.ApplyProcessor(new FlipProcessor(flipMode)); } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Processing/Extensions/Transforms/PadExtensions.cs b/src/ImageSharp/Processing/Extensions/Transforms/PadExtensions.cs index 5b0614e79..8c3edcadf 100644 --- a/src/ImageSharp/Processing/Extensions/Transforms/PadExtensions.cs +++ b/src/ImageSharp/Processing/Extensions/Transforms/PadExtensions.cs @@ -39,4 +39,4 @@ namespace SixLabors.ImageSharp.Processing return color.Equals(default) ? source.Resize(options) : source.Resize(options).BackgroundColor(color); } } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Processing/Extensions/Transforms/RotateExtensions.cs b/src/ImageSharp/Processing/Extensions/Transforms/RotateExtensions.cs index 4b2ee8144..359aadd82 100644 --- a/src/ImageSharp/Processing/Extensions/Transforms/RotateExtensions.cs +++ b/src/ImageSharp/Processing/Extensions/Transforms/RotateExtensions.cs @@ -42,4 +42,4 @@ namespace SixLabors.ImageSharp.Processing IResampler sampler) => source.ApplyProcessor(new RotateProcessor(degrees, sampler, source.GetCurrentSize())); } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Processing/Extensions/Transforms/RotateFlipExtensions.cs b/src/ImageSharp/Processing/Extensions/Transforms/RotateFlipExtensions.cs index f1e3823a0..4259a7578 100644 --- a/src/ImageSharp/Processing/Extensions/Transforms/RotateFlipExtensions.cs +++ b/src/ImageSharp/Processing/Extensions/Transforms/RotateFlipExtensions.cs @@ -19,4 +19,4 @@ namespace SixLabors.ImageSharp.Processing public static IImageProcessingContext RotateFlip(this IImageProcessingContext source, RotateMode rotateMode, FlipMode flipMode) => source.Rotate(rotateMode).Flip(flipMode); } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Processing/Extensions/Transforms/SkewExtensions.cs b/src/ImageSharp/Processing/Extensions/Transforms/SkewExtensions.cs index b3fc43dde..3a7df8d6c 100644 --- a/src/ImageSharp/Processing/Extensions/Transforms/SkewExtensions.cs +++ b/src/ImageSharp/Processing/Extensions/Transforms/SkewExtensions.cs @@ -37,4 +37,4 @@ namespace SixLabors.ImageSharp.Processing IResampler sampler) => source.ApplyProcessor(new SkewProcessor(degreesX, degreesY, sampler, source.GetCurrentSize())); } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Processing/Extensions/Transforms/TransformExtensions.cs b/src/ImageSharp/Processing/Extensions/Transforms/TransformExtensions.cs index 57acf78ee..56036edd0 100644 --- a/src/ImageSharp/Processing/Extensions/Transforms/TransformExtensions.cs +++ b/src/ImageSharp/Processing/Extensions/Transforms/TransformExtensions.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. using System.Numerics; - using SixLabors.ImageSharp.Processing.Processors.Transforms; namespace SixLabors.ImageSharp.Processing @@ -141,4 +140,4 @@ namespace SixLabors.ImageSharp.Processing sourceRectangle); } } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Processing/FlipMode.cs b/src/ImageSharp/Processing/FlipMode.cs index 59e7e8a9c..2803d1b4d 100644 --- a/src/ImageSharp/Processing/FlipMode.cs +++ b/src/ImageSharp/Processing/FlipMode.cs @@ -23,4 +23,4 @@ namespace SixLabors.ImageSharp.Processing /// Vertical, } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Processing/GrayscaleMode.cs b/src/ImageSharp/Processing/GrayscaleMode.cs index 27b190d23..1a73afc82 100644 --- a/src/ImageSharp/Processing/GrayscaleMode.cs +++ b/src/ImageSharp/Processing/GrayscaleMode.cs @@ -18,4 +18,4 @@ namespace SixLabors.ImageSharp.Processing /// Bt601 } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Processing/KnownQuantizers.cs b/src/ImageSharp/Processing/KnownQuantizers.cs index 9fc8cf543..28b77a455 100644 --- a/src/ImageSharp/Processing/KnownQuantizers.cs +++ b/src/ImageSharp/Processing/KnownQuantizers.cs @@ -31,4 +31,4 @@ namespace SixLabors.ImageSharp.Processing /// public static IQuantizer Werner { get; } = new WernerPaletteQuantizer(); } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Processing/Processors/Binarization/AdaptiveThresholdProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/Binarization/AdaptiveThresholdProcessor{TPixel}.cs index 6d95d51b3..254ba5a7e 100644 --- a/src/ImageSharp/Processing/Processors/Binarization/AdaptiveThresholdProcessor{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Binarization/AdaptiveThresholdProcessor{TPixel}.cs @@ -4,7 +4,6 @@ using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; - using SixLabors.ImageSharp.Advanced; using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.PixelFormats; diff --git a/src/ImageSharp/Processing/Processors/Convolution/Kernels/Implementation/LaplacianKernelFactory.cs b/src/ImageSharp/Processing/Processors/Convolution/Kernels/Implementation/LaplacianKernelFactory.cs index 960ff30eb..286dcb326 100644 --- a/src/ImageSharp/Processing/Processors/Convolution/Kernels/Implementation/LaplacianKernelFactory.cs +++ b/src/ImageSharp/Processing/Processors/Convolution/Kernels/Implementation/LaplacianKernelFactory.cs @@ -28,4 +28,4 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution return kernel; } } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Processing/Processors/Convolution/Kernels/Implementation/PrewittKernels.cs b/src/ImageSharp/Processing/Processors/Convolution/Kernels/Implementation/PrewittKernels.cs index 67e52a8f1..108c66543 100644 --- a/src/ImageSharp/Processing/Processors/Convolution/Kernels/Implementation/PrewittKernels.cs +++ b/src/ImageSharp/Processing/Processors/Convolution/Kernels/Implementation/PrewittKernels.cs @@ -30,4 +30,4 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution { -1, -1, -1 } }; } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Processing/Processors/Convolution/Kernels/Implementation/RobertsCrossKernels.cs b/src/ImageSharp/Processing/Processors/Convolution/Kernels/Implementation/RobertsCrossKernels.cs index 40c811ca6..2fcdd31de 100644 --- a/src/ImageSharp/Processing/Processors/Convolution/Kernels/Implementation/RobertsCrossKernels.cs +++ b/src/ImageSharp/Processing/Processors/Convolution/Kernels/Implementation/RobertsCrossKernels.cs @@ -28,4 +28,4 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution { -1, 0 } }; } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Processing/Processors/Convolution/Kernels/Implementation/ScharrKernels.cs b/src/ImageSharp/Processing/Processors/Convolution/Kernels/Implementation/ScharrKernels.cs index 72c48b273..ff4f5902c 100644 --- a/src/ImageSharp/Processing/Processors/Convolution/Kernels/Implementation/ScharrKernels.cs +++ b/src/ImageSharp/Processing/Processors/Convolution/Kernels/Implementation/ScharrKernels.cs @@ -30,4 +30,4 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution { -3, -10, -3 } }; } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Processing/Processors/Convolution/Kernels/Implementation/SobelKernels.cs b/src/ImageSharp/Processing/Processors/Convolution/Kernels/Implementation/SobelKernels.cs index 333b275ba..6810a2ee3 100644 --- a/src/ImageSharp/Processing/Processors/Convolution/Kernels/Implementation/SobelKernels.cs +++ b/src/ImageSharp/Processing/Processors/Convolution/Kernels/Implementation/SobelKernels.cs @@ -30,4 +30,4 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution { 1, 2, 1 } }; } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Processing/Processors/Dithering/ErrorDither.cs b/src/ImageSharp/Processing/Processors/Dithering/ErrorDither.cs index 1a107c2cf..0fe2d4b2c 100644 --- a/src/ImageSharp/Processing/Processors/Dithering/ErrorDither.cs +++ b/src/ImageSharp/Processing/Processors/Dithering/ErrorDither.cs @@ -27,6 +27,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Dithering [MethodImpl(InliningOptions.ShortMethod)] public ErrorDither(in DenseMatrix matrix, int offset) { + Guard.MustBeGreaterThan(offset, 0, nameof(offset)); + this.matrix = matrix; this.offset = offset; } @@ -95,6 +97,11 @@ namespace SixLabors.ImageSharp.Processing.Processors.Dithering where TFrameQuantizer : struct, IQuantizer where TPixel : unmanaged, IPixel { + if (this == default) + { + ThrowDefaultInstance(); + } + int offsetY = bounds.Top; int offsetX = bounds.Left; float scale = quantizer.Options.DitherScale; @@ -122,6 +129,11 @@ namespace SixLabors.ImageSharp.Processing.Processors.Dithering where TPaletteDitherImageProcessor : struct, IPaletteDitherImageProcessor where TPixel : unmanaged, IPixel { + if (this == default) + { + ThrowDefaultInstance(); + } + float scale = processor.DitherScale; for (int y = bounds.Top; y < bounds.Bottom; y++) { @@ -210,5 +222,9 @@ namespace SixLabors.ImageSharp.Processing.Processors.Dithering /// public override int GetHashCode() => HashCode.Combine(this.offset, this.matrix); + + [MethodImpl(InliningOptions.ColdPath)] + private static void ThrowDefaultInstance() + => throw new ImageProcessingException("Cannot use the default value type instance to dither."); } } diff --git a/src/ImageSharp/Processing/Processors/Dithering/OrderedDither.cs b/src/ImageSharp/Processing/Processors/Dithering/OrderedDither.cs index c317ddf02..2f5a5cf85 100644 --- a/src/ImageSharp/Processing/Processors/Dithering/OrderedDither.cs +++ b/src/ImageSharp/Processing/Processors/Dithering/OrderedDither.cs @@ -24,6 +24,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Dithering [MethodImpl(InliningOptions.ShortMethod)] public OrderedDither(uint length) { + Guard.MustBeGreaterThan(length, 0, nameof(length)); + DenseMatrix ditherMatrix = OrderedDitherFactory.CreateDitherMatrix(length); // Create a new matrix to run against, that pre-thresholds the values. @@ -109,6 +111,11 @@ namespace SixLabors.ImageSharp.Processing.Processors.Dithering where TFrameQuantizer : struct, IQuantizer where TPixel : unmanaged, IPixel { + if (this == default) + { + ThrowDefaultInstance(); + } + int spread = CalculatePaletteSpread(destination.Palette.Length); float scale = quantizer.Options.DitherScale; @@ -134,6 +141,11 @@ namespace SixLabors.ImageSharp.Processing.Processors.Dithering where TPaletteDitherImageProcessor : struct, IPaletteDitherImageProcessor where TPixel : unmanaged, IPixel { + if (this == default) + { + ThrowDefaultInstance(); + } + int spread = CalculatePaletteSpread(processor.Palette.Length); float scale = processor.DitherScale; @@ -201,5 +213,9 @@ namespace SixLabors.ImageSharp.Processing.Processors.Dithering [MethodImpl(InliningOptions.ShortMethod)] public override int GetHashCode() => HashCode.Combine(this.thresholdMatrix, this.modulusX, this.modulusY); + + [MethodImpl(InliningOptions.ColdPath)] + private static void ThrowDefaultInstance() + => throw new ImageProcessingException("Cannot use the default value type instance to dither."); } } diff --git a/src/ImageSharp/Processing/Processors/Filters/AchromatomalyProcessor.cs b/src/ImageSharp/Processing/Processors/Filters/AchromatomalyProcessor.cs index 63326d299..74d926eac 100644 --- a/src/ImageSharp/Processing/Processors/Filters/AchromatomalyProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Filters/AchromatomalyProcessor.cs @@ -16,4 +16,4 @@ namespace SixLabors.ImageSharp.Processing.Processors.Filters { } } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Processing/Processors/Filters/BlackWhiteProcessor.cs b/src/ImageSharp/Processing/Processors/Filters/BlackWhiteProcessor.cs index e5e556dc2..c3cc4ac50 100644 --- a/src/ImageSharp/Processing/Processors/Filters/BlackWhiteProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Filters/BlackWhiteProcessor.cs @@ -16,4 +16,4 @@ namespace SixLabors.ImageSharp.Processing.Processors.Filters { } } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Processing/Processors/Filters/BrightnessProcessor.cs b/src/ImageSharp/Processing/Processors/Filters/BrightnessProcessor.cs index bc424e462..1bc1acc8e 100644 --- a/src/ImageSharp/Processing/Processors/Filters/BrightnessProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Filters/BrightnessProcessor.cs @@ -27,4 +27,4 @@ namespace SixLabors.ImageSharp.Processing.Processors.Filters /// public float Amount { get; } } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Processing/Processors/Filters/ContrastProcessor.cs b/src/ImageSharp/Processing/Processors/Filters/ContrastProcessor.cs index cc7385d4b..150cd35a4 100644 --- a/src/ImageSharp/Processing/Processors/Filters/ContrastProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Filters/ContrastProcessor.cs @@ -27,4 +27,4 @@ namespace SixLabors.ImageSharp.Processing.Processors.Filters /// public float Amount { get; } } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Processing/Processors/Filters/DeuteranomalyProcessor.cs b/src/ImageSharp/Processing/Processors/Filters/DeuteranomalyProcessor.cs index 3afef7b7e..5c1928484 100644 --- a/src/ImageSharp/Processing/Processors/Filters/DeuteranomalyProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Filters/DeuteranomalyProcessor.cs @@ -16,4 +16,4 @@ namespace SixLabors.ImageSharp.Processing.Processors.Filters { } } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Processing/Processors/Filters/DeuteranopiaProcessor.cs b/src/ImageSharp/Processing/Processors/Filters/DeuteranopiaProcessor.cs index 9bd7f449b..eb25cfe8c 100644 --- a/src/ImageSharp/Processing/Processors/Filters/DeuteranopiaProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Filters/DeuteranopiaProcessor.cs @@ -16,4 +16,4 @@ namespace SixLabors.ImageSharp.Processing.Processors.Filters { } } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Processing/Processors/Filters/GrayscaleBt601Processor.cs b/src/ImageSharp/Processing/Processors/Filters/GrayscaleBt601Processor.cs index f2c5e023d..b4b601cfc 100644 --- a/src/ImageSharp/Processing/Processors/Filters/GrayscaleBt601Processor.cs +++ b/src/ImageSharp/Processing/Processors/Filters/GrayscaleBt601Processor.cs @@ -23,4 +23,4 @@ namespace SixLabors.ImageSharp.Processing.Processors.Filters /// public float Amount { get; } } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Processing/Processors/Filters/GrayscaleBt709Processor.cs b/src/ImageSharp/Processing/Processors/Filters/GrayscaleBt709Processor.cs index ace25f1fb..8ef5219f3 100644 --- a/src/ImageSharp/Processing/Processors/Filters/GrayscaleBt709Processor.cs +++ b/src/ImageSharp/Processing/Processors/Filters/GrayscaleBt709Processor.cs @@ -23,4 +23,4 @@ namespace SixLabors.ImageSharp.Processing.Processors.Filters /// public float Amount { get; } } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Processing/Processors/Filters/HueProcessor.cs b/src/ImageSharp/Processing/Processors/Filters/HueProcessor.cs index 2ff99009a..d8bc2a2d8 100644 --- a/src/ImageSharp/Processing/Processors/Filters/HueProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Filters/HueProcessor.cs @@ -23,4 +23,4 @@ namespace SixLabors.ImageSharp.Processing.Processors.Filters /// public float Degrees { get; } } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Processing/Processors/Filters/InvertProcessor.cs b/src/ImageSharp/Processing/Processors/Filters/InvertProcessor.cs index 95937e5b3..a47be636c 100644 --- a/src/ImageSharp/Processing/Processors/Filters/InvertProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Filters/InvertProcessor.cs @@ -23,4 +23,4 @@ namespace SixLabors.ImageSharp.Processing.Processors.Filters /// public float Amount { get; } } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Processing/Processors/Filters/KodachromeProcessor.cs b/src/ImageSharp/Processing/Processors/Filters/KodachromeProcessor.cs index fa9cc0874..c5be144c7 100644 --- a/src/ImageSharp/Processing/Processors/Filters/KodachromeProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Filters/KodachromeProcessor.cs @@ -16,4 +16,4 @@ namespace SixLabors.ImageSharp.Processing.Processors.Filters { } } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Processing/Processors/Filters/OpacityProcessor.cs b/src/ImageSharp/Processing/Processors/Filters/OpacityProcessor.cs index 0ccdfafbd..260699bc2 100644 --- a/src/ImageSharp/Processing/Processors/Filters/OpacityProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Filters/OpacityProcessor.cs @@ -23,4 +23,4 @@ namespace SixLabors.ImageSharp.Processing.Processors.Filters /// public float Amount { get; } } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Processing/Processors/Filters/ProtanomalyProcessor.cs b/src/ImageSharp/Processing/Processors/Filters/ProtanomalyProcessor.cs index 0e8f571f5..e2faf9433 100644 --- a/src/ImageSharp/Processing/Processors/Filters/ProtanomalyProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Filters/ProtanomalyProcessor.cs @@ -16,4 +16,4 @@ namespace SixLabors.ImageSharp.Processing.Processors.Filters { } } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Processing/Processors/Filters/ProtanopiaProcessor.cs b/src/ImageSharp/Processing/Processors/Filters/ProtanopiaProcessor.cs index 59735a28c..2d63f6626 100644 --- a/src/ImageSharp/Processing/Processors/Filters/ProtanopiaProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Filters/ProtanopiaProcessor.cs @@ -16,4 +16,4 @@ namespace SixLabors.ImageSharp.Processing.Processors.Filters { } } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Processing/Processors/Filters/SaturateProcessor.cs b/src/ImageSharp/Processing/Processors/Filters/SaturateProcessor.cs index 051c4ca6b..1ac381884 100644 --- a/src/ImageSharp/Processing/Processors/Filters/SaturateProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Filters/SaturateProcessor.cs @@ -27,4 +27,4 @@ namespace SixLabors.ImageSharp.Processing.Processors.Filters /// public float Amount { get; } } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Processing/Processors/Filters/SepiaProcessor.cs b/src/ImageSharp/Processing/Processors/Filters/SepiaProcessor.cs index 8a0780e46..dec0b8dfe 100644 --- a/src/ImageSharp/Processing/Processors/Filters/SepiaProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Filters/SepiaProcessor.cs @@ -23,4 +23,4 @@ namespace SixLabors.ImageSharp.Processing.Processors.Filters /// public float Amount { get; } } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Processing/Processors/Filters/TritanomalyProcessor.cs b/src/ImageSharp/Processing/Processors/Filters/TritanomalyProcessor.cs index bb031d0ef..22c274ac3 100644 --- a/src/ImageSharp/Processing/Processors/Filters/TritanomalyProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Filters/TritanomalyProcessor.cs @@ -16,4 +16,4 @@ namespace SixLabors.ImageSharp.Processing.Processors.Filters { } } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Processing/Processors/Filters/TritanopiaProcessor.cs b/src/ImageSharp/Processing/Processors/Filters/TritanopiaProcessor.cs index 926fd70c5..1dbc3d3f4 100644 --- a/src/ImageSharp/Processing/Processors/Filters/TritanopiaProcessor.cs +++ b/src/ImageSharp/Processing/Processors/Filters/TritanopiaProcessor.cs @@ -16,4 +16,4 @@ namespace SixLabors.ImageSharp.Processing.Processors.Filters { } } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Processing/Processors/Normalization/AdaptiveHistogramEqualizationProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/Normalization/AdaptiveHistogramEqualizationProcessor{TPixel}.cs index 91ed9f5de..883f85be3 100644 --- a/src/ImageSharp/Processing/Processors/Normalization/AdaptiveHistogramEqualizationProcessor{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Normalization/AdaptiveHistogramEqualizationProcessor{TPixel}.cs @@ -70,7 +70,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization { cdfData.CalculateLookupTables(source, this); - var tileYStartPositions = new List<(int y, int cdfY)>(); + var tileYStartPositions = new List<(int Y, int CdfY)>(); int cdfY = 0; int yStart = halfTileHeight; for (int tile = 0; tile < tileCount - 1; tile++) @@ -367,7 +367,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization private readonly struct RowIntervalOperation : IRowIntervalOperation { private readonly CdfTileData cdfData; - private readonly List<(int y, int cdfY)> tileYStartPositions; + private readonly List<(int Y, int CdfY)> tileYStartPositions; private readonly int tileWidth; private readonly int tileHeight; private readonly int tileCount; @@ -380,7 +380,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization [MethodImpl(InliningOptions.ShortMethod)] public RowIntervalOperation( CdfTileData cdfData, - List<(int y, int cdfY)> tileYStartPositions, + List<(int Y, int CdfY)> tileYStartPositions, int tileWidth, int tileHeight, int tileCount, @@ -406,9 +406,9 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization { for (int index = rows.Min; index < rows.Max; index++) { - (int y, int cdfY) tileYStartPosition = this.tileYStartPositions[index]; - int y = tileYStartPosition.y; - int cdfYY = tileYStartPosition.cdfY; + (int Y, int CdfY) tileYStartPosition = this.tileYStartPositions[index]; + int y = tileYStartPosition.Y; + int cdfYY = tileYStartPosition.CdfY; int cdfX = 0; int x = this.halfTileWidth; @@ -473,7 +473,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization private readonly int tileWidth; private readonly int tileHeight; private readonly int luminanceLevels; - private readonly List<(int y, int cdfY)> tileYStartPositions; + private readonly List<(int Y, int CdfY)> tileYStartPositions; public CdfTileData( Configuration configuration, @@ -496,7 +496,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization this.pixelsInTile = tileWidth * tileHeight; // Calculate the start positions and rent buffers. - this.tileYStartPositions = new List<(int y, int cdfY)>(); + this.tileYStartPositions = new List<(int Y, int CdfY)>(); int cdfY = 0; for (int y = 0; y < sourceHeight; y += tileHeight) { @@ -556,7 +556,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization private readonly MemoryAllocator allocator; private readonly Buffer2D cdfMinBuffer2D; private readonly Buffer2D cdfLutBuffer2D; - private readonly List<(int y, int cdfY)> tileYStartPositions; + private readonly List<(int Y, int CdfY)> tileYStartPositions; private readonly int tileWidth; private readonly int tileHeight; private readonly int luminanceLevels; @@ -570,7 +570,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization MemoryAllocator allocator, Buffer2D cdfMinBuffer2D, Buffer2D cdfLutBuffer2D, - List<(int y, int cdfY)> tileYStartPositions, + List<(int Y, int CdfY)> tileYStartPositions, int tileWidth, int tileHeight, int luminanceLevels, @@ -596,8 +596,8 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization for (int index = rows.Min; index < rows.Max; index++) { int cdfX = 0; - int cdfY = this.tileYStartPositions[index].cdfY; - int y = this.tileYStartPositions[index].y; + int cdfY = this.tileYStartPositions[index].CdfY; + int y = this.tileYStartPositions[index].Y; int endY = Math.Min(y + this.tileHeight, this.sourceHeight); Span cdfMinSpan = this.cdfMinBuffer2D.GetRowSpan(cdfY); cdfMinSpan.Clear(); diff --git a/src/ImageSharp/Processing/Processors/Normalization/AdaptiveHistogramEqualizationSlidingWindowProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/Normalization/AdaptiveHistogramEqualizationSlidingWindowProcessor{TPixel}.cs index b9383e331..f17e0d1e4 100644 --- a/src/ImageSharp/Processing/Processors/Normalization/AdaptiveHistogramEqualizationSlidingWindowProcessor{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Normalization/AdaptiveHistogramEqualizationSlidingWindowProcessor{TPixel}.cs @@ -7,7 +7,6 @@ using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Threading.Tasks; - using SixLabors.ImageSharp.Advanced; using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.PixelFormats; @@ -257,7 +256,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization [MethodImpl(InliningOptions.ShortMethod)] private void AddPixelsToHistogram(ref Vector4 greyValuesBase, ref int histogramBase, int luminanceLevels, int length) { - for (int idx = 0; idx < length; idx++) + for (nint idx = 0; idx < length; idx++) { int luminance = ColorNumerics.GetBT709Luminance(ref Unsafe.Add(ref greyValuesBase, idx), luminanceLevels); Unsafe.Add(ref histogramBase, luminance)++; diff --git a/src/ImageSharp/Processing/Processors/Normalization/HistogramEqualizationProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/Normalization/HistogramEqualizationProcessor{TPixel}.cs index 9227cb0c0..92d36b412 100644 --- a/src/ImageSharp/Processing/Processors/Normalization/HistogramEqualizationProcessor{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Normalization/HistogramEqualizationProcessor{TPixel}.cs @@ -4,7 +4,6 @@ using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; - using SixLabors.ImageSharp.PixelFormats; namespace SixLabors.ImageSharp.Processing.Processors.Normalization diff --git a/src/ImageSharp/Processing/Processors/Quantization/OctreeQuantizer.cs b/src/ImageSharp/Processing/Processors/Quantization/OctreeQuantizer.cs index 861697594..c1b695f65 100644 --- a/src/ImageSharp/Processing/Processors/Quantization/OctreeQuantizer.cs +++ b/src/ImageSharp/Processing/Processors/Quantization/OctreeQuantizer.cs @@ -11,14 +11,12 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization /// public class OctreeQuantizer : IQuantizer { - private static readonly QuantizerOptions DefaultOptions = new QuantizerOptions(); - /// /// Initializes a new instance of the class /// using the default . /// public OctreeQuantizer() - : this(DefaultOptions) + : this(new QuantizerOptions()) { } diff --git a/src/ImageSharp/Processing/Processors/Quantization/PaletteQuantizer.cs b/src/ImageSharp/Processing/Processors/Quantization/PaletteQuantizer.cs index 4f73f4ac8..5da674cc9 100644 --- a/src/ImageSharp/Processing/Processors/Quantization/PaletteQuantizer.cs +++ b/src/ImageSharp/Processing/Processors/Quantization/PaletteQuantizer.cs @@ -11,7 +11,6 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization /// public class PaletteQuantizer : IQuantizer { - private static readonly QuantizerOptions DefaultOptions = new QuantizerOptions(); private readonly ReadOnlyMemory colorPalette; /// @@ -19,7 +18,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization /// /// The color palette. public PaletteQuantizer(ReadOnlyMemory palette) - : this(palette, DefaultOptions) + : this(palette, new QuantizerOptions()) { } diff --git a/src/ImageSharp/Processing/Processors/Quantization/WebSafePaletteQuantizer.cs b/src/ImageSharp/Processing/Processors/Quantization/WebSafePaletteQuantizer.cs index 5dda17dc6..e717152f9 100644 --- a/src/ImageSharp/Processing/Processors/Quantization/WebSafePaletteQuantizer.cs +++ b/src/ImageSharp/Processing/Processors/Quantization/WebSafePaletteQuantizer.cs @@ -1,8 +1,6 @@ // Copyright (c) Six Labors. // Licensed under the Apache License, Version 2.0. -using SixLabors.ImageSharp.Processing.Processors.Dithering; - namespace SixLabors.ImageSharp.Processing.Processors.Quantization { /// @@ -10,13 +8,11 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization /// public class WebSafePaletteQuantizer : PaletteQuantizer { - private static readonly QuantizerOptions DefaultOptions = new QuantizerOptions(); - /// /// Initializes a new instance of the class. /// public WebSafePaletteQuantizer() - : this(DefaultOptions) + : this(new QuantizerOptions()) { } diff --git a/src/ImageSharp/Processing/Processors/Quantization/WernerPaletteQuantizer.cs b/src/ImageSharp/Processing/Processors/Quantization/WernerPaletteQuantizer.cs index 6675263df..8a96f8ecc 100644 --- a/src/ImageSharp/Processing/Processors/Quantization/WernerPaletteQuantizer.cs +++ b/src/ImageSharp/Processing/Processors/Quantization/WernerPaletteQuantizer.cs @@ -9,13 +9,11 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization /// public class WernerPaletteQuantizer : PaletteQuantizer { - private static readonly QuantizerOptions DefaultOptions = new QuantizerOptions(); - /// /// Initializes a new instance of the class. /// public WernerPaletteQuantizer() - : this(DefaultOptions) + : this(new QuantizerOptions()) { } diff --git a/src/ImageSharp/Processing/Processors/Quantization/WuQuantizer.cs b/src/ImageSharp/Processing/Processors/Quantization/WuQuantizer.cs index 95adb7e5d..337948bef 100644 --- a/src/ImageSharp/Processing/Processors/Quantization/WuQuantizer.cs +++ b/src/ImageSharp/Processing/Processors/Quantization/WuQuantizer.cs @@ -10,14 +10,12 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization /// public class WuQuantizer : IQuantizer { - private static readonly QuantizerOptions DefaultOptions = new QuantizerOptions(); - /// /// Initializes a new instance of the class /// using the default . /// public WuQuantizer() - : this(DefaultOptions) + : this(new QuantizerOptions()) { } diff --git a/src/ImageSharp/Processing/Processors/Transforms/Linear/AutoOrientProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/Transforms/Linear/AutoOrientProcessor{TPixel}.cs index 3a06f5c2c..6c5219b3a 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/Linear/AutoOrientProcessor{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/Linear/AutoOrientProcessor{TPixel}.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. using System; - using SixLabors.ImageSharp.Metadata.Profiles.Exif; using SixLabors.ImageSharp.PixelFormats; diff --git a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeHelper.cs b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeHelper.cs index 5ff82a096..9a540559f 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeHelper.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeHelper.cs @@ -30,7 +30,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms /// /// The tuple representing the location and the bounds /// - public static (Size, Rectangle) CalculateTargetLocationAndBounds(Size sourceSize, ResizeOptions options) + public static (Size Size, Rectangle Rectangle) CalculateTargetLocationAndBounds(Size sourceSize, ResizeOptions options) { int width = options.Size.Width; int height = options.Size.Height; @@ -76,7 +76,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms } } - private static (Size, Rectangle) CalculateBoxPadRectangle( + private static (Size Size, Rectangle Rectangle) CalculateBoxPadRectangle( Size source, ResizeOptions options, int width, @@ -150,7 +150,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms return CalculatePadRectangle(source, options, width, height); } - private static (Size, Rectangle) CalculateCropRectangle( + private static (Size Size, Rectangle Rectangle) CalculateCropRectangle( Size source, ResizeOptions options, int width, @@ -256,7 +256,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms return (new Size(Sanitize(width), Sanitize(height)), new Rectangle(targetX, targetY, Sanitize(targetWidth), Sanitize(targetHeight))); } - private static (Size, Rectangle) CalculateMaxRectangle( + private static (Size Size, Rectangle Rectangle) CalculateMaxRectangle( Size source, int width, int height) @@ -285,7 +285,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms return (new Size(Sanitize(targetWidth), Sanitize(targetHeight)), new Rectangle(0, 0, Sanitize(targetWidth), Sanitize(targetHeight))); } - private static (Size, Rectangle) CalculateMinRectangle( + private static (Size Size, Rectangle Rectangle) CalculateMinRectangle( Size source, int width, int height) @@ -333,7 +333,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms return (new Size(Sanitize(targetWidth), Sanitize(targetHeight)), new Rectangle(0, 0, Sanitize(targetWidth), Sanitize(targetHeight))); } - private static (Size, Rectangle) CalculatePadRectangle( + private static (Size Size, Rectangle Rectangle) CalculatePadRectangle( Size sourceSize, ResizeOptions options, int width, @@ -401,7 +401,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms return (new Size(Sanitize(width), Sanitize(height)), new Rectangle(targetX, targetY, Sanitize(targetWidth), Sanitize(targetHeight))); } - private static (Size, Rectangle) CalculateManualRectangle( + private static (Size Size, Rectangle Rectangle) CalculateManualRectangle( ResizeOptions options, int width, int height) diff --git a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.cs b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.cs index a58c20f68..9cc468060 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeKernelMap.cs @@ -216,7 +216,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms ResizeKernel kernel = this.CreateKernel(dataRowIndex, left, right); - Span kernelValues = this.tempValues.AsSpan().Slice(0, kernel.Length); + Span kernelValues = this.tempValues.AsSpan(0, kernel.Length); double sum = 0; for (int j = left; j <= right; j++) diff --git a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeProcessor{TPixel}.cs b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeProcessor{TPixel}.cs index ec238608e..1b93d01a1 100644 --- a/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeProcessor{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Transforms/Resize/ResizeProcessor{TPixel}.cs @@ -4,6 +4,7 @@ using System; using System.Runtime.CompilerServices; using SixLabors.ImageSharp.Advanced; +using SixLabors.ImageSharp.Formats; using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.PixelFormats; @@ -187,6 +188,11 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms bool compand, bool premultiplyAlpha) { + PixelAlphaRepresentation? alphaRepresentation = PixelOperations.Instance.GetPixelTypeInfo()?.AlphaRepresentation; + + // Premultiply only if alpha representation is unknown or Unassociated: + bool needsPremultiplication = alphaRepresentation == null || alphaRepresentation.Value == PixelAlphaRepresentation.Unassociated; + premultiplyAlpha &= needsPremultiplication; PixelConversionModifiers conversionModifiers = GetModifiers(compand, premultiplyAlpha); Buffer2DRegion sourceRegion = source.PixelBuffer.GetRegion(sourceRectangle); diff --git a/src/ImageSharp/Processing/RotateMode.cs b/src/ImageSharp/Processing/RotateMode.cs index 9a738d990..66fbc1a85 100644 --- a/src/ImageSharp/Processing/RotateMode.cs +++ b/src/ImageSharp/Processing/RotateMode.cs @@ -28,4 +28,4 @@ namespace SixLabors.ImageSharp.Processing /// Rotate270 = 270 } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Processing/TaperCorner.cs b/src/ImageSharp/Processing/TaperCorner.cs index b44fcadbe..07e4957d4 100644 --- a/src/ImageSharp/Processing/TaperCorner.cs +++ b/src/ImageSharp/Processing/TaperCorner.cs @@ -23,4 +23,4 @@ namespace SixLabors.ImageSharp.Processing /// Both } -} \ No newline at end of file +} diff --git a/src/ImageSharp/Processing/TaperSide.cs b/src/ImageSharp/Processing/TaperSide.cs index 209f5bf6d..47fe9858e 100644 --- a/src/ImageSharp/Processing/TaperSide.cs +++ b/src/ImageSharp/Processing/TaperSide.cs @@ -28,4 +28,4 @@ namespace SixLabors.ImageSharp.Processing /// Bottom } -} \ No newline at end of file +} diff --git a/tests/ImageSharp.Benchmarks/Codecs/DecodeTiff.cs b/tests/ImageSharp.Benchmarks/Codecs/DecodeTiff.cs index e77bb8b3e..db94fb121 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/DecodeTiff.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/DecodeTiff.cs @@ -6,12 +6,9 @@ //// #define BIG_TESTS using System.IO; - using BenchmarkDotNet.Attributes; - using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.Tests; - using SDImage = System.Drawing.Image; using SDSize = System.Drawing.Size; @@ -26,8 +23,6 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs private byte[] data; - private Configuration configuration; - #if BIG_TESTS private static readonly int BufferSize = 1024 * 68; @@ -61,16 +56,6 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs public string TestImage { get; set; } #endif - [GlobalSetup] - public void Config() - { - if (this.configuration == null) - { - this.configuration = new Configuration(); - this.configuration.StreamProcessingBufferSize = BufferSize; - } - } - [IterationSetup] public void ReadImages() { @@ -95,7 +80,7 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs public Size TiffCore() { using (var ms = new MemoryStream(this.data)) - using (var image = Image.Load(this.configuration, ms)) + using (var image = Image.Load(ms)) { return image.Size(); } diff --git a/tests/ImageSharp.Benchmarks/Codecs/DecodeWebp.cs b/tests/ImageSharp.Benchmarks/Codecs/DecodeWebp.cs new file mode 100644 index 000000000..878929823 --- /dev/null +++ b/tests/ImageSharp.Benchmarks/Codecs/DecodeWebp.cs @@ -0,0 +1,104 @@ +// Copyright (c) Six Labors. +// Licensed under the Apache License, Version 2.0. + +using System.IO; +using BenchmarkDotNet.Attributes; + +using ImageMagick; +using SixLabors.ImageSharp.Formats.Webp; +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Tests; + +namespace SixLabors.ImageSharp.Benchmarks.Codecs +{ + [MarkdownExporter] + [HtmlExporter] + [Config(typeof(Config.ShortMultiFramework))] + public class DecodeWebp + { + private Configuration configuration; + + private byte[] webpLossyBytes; + + private byte[] webpLosslessBytes; + + private string TestImageLossyFullPath => Path.Combine(TestEnvironment.InputImagesDirectoryFullPath, this.TestImageLossy); + + private string TestImageLosslessFullPath => Path.Combine(TestEnvironment.InputImagesDirectoryFullPath, this.TestImageLossless); + + [Params(TestImages.Webp.Lossy.Earth)] + public string TestImageLossy { get; set; } + + [Params(TestImages.Webp.Lossless.Earth)] + public string TestImageLossless { get; set; } + + [GlobalSetup] + public void ReadImages() + { + this.configuration = Configuration.CreateDefaultInstance(); + new WebpConfigurationModule().Configure(this.configuration); + + this.webpLossyBytes ??= File.ReadAllBytes(this.TestImageLossyFullPath); + this.webpLosslessBytes ??= File.ReadAllBytes(this.TestImageLosslessFullPath); + } + + [Benchmark(Description = "Magick Lossy Webp")] + public int WebpLossyMagick() + { + var settings = new MagickReadSettings { Format = MagickFormat.WebP }; + using var memoryStream = new MemoryStream(this.webpLossyBytes); + using var image = new MagickImage(memoryStream, settings); + return image.Width; + } + + [Benchmark(Description = "ImageSharp Lossy Webp")] + public int WebpLossy() + { + using var memoryStream = new MemoryStream(this.webpLossyBytes); + using var image = Image.Load(this.configuration, memoryStream); + return image.Height; + } + + [Benchmark(Description = "Magick Lossless Webp")] + public int WebpLosslessMagick() + { + var settings = new MagickReadSettings { Format = MagickFormat.WebP }; + using var memoryStream = new MemoryStream(this.webpLossyBytes); + using var image = new MagickImage(memoryStream, settings); + return image.Width; + } + + [Benchmark(Description = "ImageSharp Lossless Webp")] + public int WebpLossless() + { + using var memoryStream = new MemoryStream(this.webpLosslessBytes); + using var image = Image.Load(this.configuration, memoryStream); + return image.Height; + } + + /* Results 04.11.2021 + * BenchmarkDotNet=v0.13.0, OS=Windows 10.0.19043.1320 (21H1/May2021Update) + Intel Core i7-6700K CPU 4.00GHz (Skylake), 1 CPU, 8 logical and 4 physical cores + .NET SDK=6.0.100-rc.2.21505.57 + [Host] : .NET 5.0.11 (5.0.1121.47308), X64 RyuJIT + Job-WQLXJO : .NET 5.0.11 (5.0.1121.47308), X64 RyuJIT + Job-OJJAMD : .NET Core 3.1.20 (CoreCLR 4.700.21.47003, CoreFX 4.700.21.47101), X64 RyuJIT + Job-OMFOAS : .NET Framework 4.8 (4.8.4420.0), X64 RyuJIT + + | Method | Job | Runtime | Arguments | TestImageLossy | TestImageLossless | Mean | Error | StdDev | Gen 0 | Gen 1 | Gen 2 | Allocated | + |--------------------------- |----------- |--------------------- |---------------------- |---------------------- |------------------------- |-----------:|----------:|--------:|---------:|------:|------:|----------:| + | 'Magick Lossy Webp' | Job-HLWZLL | .NET 5.0 | /p:DebugType=portable | Webp/earth_lossy.webp | Webp/earth_lossless.webp | 107.9 ms | 28.91 ms | 1.58 ms | - | - | - | 25 KB | + | 'ImageSharp Lossy Webp' | Job-HLWZLL | .NET 5.0 | /p:DebugType=portable | Webp/earth_lossy.webp | Webp/earth_lossless.webp | 282.3 ms | 25.40 ms | 1.39 ms | 500.0000 | - | - | 2,428 KB | + | 'Magick Lossless Webp' | Job-HLWZLL | .NET 5.0 | /p:DebugType=portable | Webp/earth_lossy.webp | Webp/earth_lossless.webp | 106.3 ms | 11.99 ms | 0.66 ms | - | - | - | 16 KB | + | 'ImageSharp Lossless Webp' | Job-HLWZLL | .NET 5.0 | /p:DebugType=portable | Webp/earth_lossy.webp | Webp/earth_lossless.webp | 280.2 ms | 6.21 ms | 0.34 ms | - | - | - | 2,092 KB | + | 'Magick Lossy Webp' | Job-ALQPDS | .NET Core 3.1 | Default | Webp/earth_lossy.webp | Webp/earth_lossless.webp | 106.2 ms | 9.32 ms | 0.51 ms | - | - | - | 15 KB | + | 'ImageSharp Lossy Webp' | Job-ALQPDS | .NET Core 3.1 | Default | Webp/earth_lossy.webp | Webp/earth_lossless.webp | 295.8 ms | 21.25 ms | 1.16 ms | 500.0000 | - | - | 2,427 KB | + | 'Magick Lossless Webp' | Job-ALQPDS | .NET Core 3.1 | Default | Webp/earth_lossy.webp | Webp/earth_lossless.webp | 106.5 ms | 4.07 ms | 0.22 ms | - | - | - | 15 KB | + | 'ImageSharp Lossless Webp' | Job-ALQPDS | .NET Core 3.1 | Default | Webp/earth_lossy.webp | Webp/earth_lossless.webp | 464.0 ms | 55.70 ms | 3.05 ms | - | - | - | 2,090 KB | + | 'Magick Lossy Webp' | Job-RYVVNN | .NET Framework 4.7.2 | Default | Webp/earth_lossy.webp | Webp/earth_lossless.webp | 108.0 ms | 29.60 ms | 1.62 ms | - | - | - | 32 KB | + | 'ImageSharp Lossy Webp' | Job-RYVVNN | .NET Framework 4.7.2 | Default | Webp/earth_lossy.webp | Webp/earth_lossless.webp | 564.9 ms | 29.69 ms | 1.63 ms | - | - | - | 2,436 KB | + | 'Magick Lossless Webp' | Job-RYVVNN | .NET Framework 4.7.2 | Default | Webp/earth_lossy.webp | Webp/earth_lossless.webp | 106.2 ms | 4.74 ms | 0.26 ms | - | - | - | 18 KB | + | 'ImageSharp Lossless Webp' | Job-RYVVNN | .NET Framework 4.7.2 | Default | Webp/earth_lossy.webp | Webp/earth_lossless.webp | 1,767.5 ms | 106.33 ms | 5.83 ms | - | - | - | 9,729 KB | + */ + } +} diff --git a/tests/ImageSharp.Benchmarks/Codecs/EncodeTga.cs b/tests/ImageSharp.Benchmarks/Codecs/EncodeTga.cs index 0e320e4a7..e7b102547 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/EncodeTga.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/EncodeTga.cs @@ -13,7 +13,7 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs public class EncodeTga { private MagickImage tgaMagick; - private Image tgaCore; + private Image tga; private string TestImageFullPath => Path.Combine(TestEnvironment.InputImagesDirectoryFullPath, this.TestImage); @@ -24,9 +24,9 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs [GlobalSetup] public void ReadImages() { - if (this.tgaCore == null) + if (this.tga == null) { - this.tgaCore = Image.Load(this.TestImageFullPath); + this.tga = Image.Load(this.TestImageFullPath); this.tgaMagick = new MagickImage(this.TestImageFullPath); } } @@ -34,23 +34,23 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs [GlobalCleanup] public void Cleanup() { - this.tgaCore.Dispose(); - this.tgaCore = null; + this.tga.Dispose(); + this.tga = null; this.tgaMagick.Dispose(); } [Benchmark(Baseline = true, Description = "Magick Tga")] - public void TgaMagick() + public void MagickTga() { using var memoryStream = new MemoryStream(); this.tgaMagick.Write(memoryStream, MagickFormat.Tga); } [Benchmark(Description = "ImageSharp Tga")] - public void TgaImageSharp() + public void ImageSharpTga() { using var memoryStream = new MemoryStream(); - this.tgaCore.SaveAsTga(memoryStream); + this.tga.SaveAsTga(memoryStream); } } } diff --git a/tests/ImageSharp.Benchmarks/Codecs/EncodeTiff.cs b/tests/ImageSharp.Benchmarks/Codecs/EncodeTiff.cs index 025412adc..e9c61e729 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/EncodeTiff.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/EncodeTiff.cs @@ -3,7 +3,6 @@ using System.Drawing.Imaging; using System.IO; - using BenchmarkDotNet.Attributes; using SixLabors.ImageSharp.Formats.Tiff; @@ -73,12 +72,6 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs { TiffPhotometricInterpretation photometricInterpretation = TiffPhotometricInterpretation.Rgb; - // Workaround for 1-bit bug - if (this.Compression == TiffCompression.CcittGroup3Fax || this.Compression == TiffCompression.Ccitt1D) - { - photometricInterpretation = TiffPhotometricInterpretation.WhiteIsZero; - } - var encoder = new TiffEncoder() { Compression = this.Compression, PhotometricInterpretation = photometricInterpretation }; using var memoryStream = new MemoryStream(); this.core.SaveAsTiff(memoryStream, encoder); diff --git a/tests/ImageSharp.Benchmarks/Codecs/EncodeWebp.cs b/tests/ImageSharp.Benchmarks/Codecs/EncodeWebp.cs new file mode 100644 index 000000000..43d8c464c --- /dev/null +++ b/tests/ImageSharp.Benchmarks/Codecs/EncodeWebp.cs @@ -0,0 +1,143 @@ +// Copyright (c) Six Labors. +// Licensed under the Apache License, Version 2.0. + +using System.IO; +using BenchmarkDotNet.Attributes; +using ImageMagick; +using ImageMagick.Formats; +using SixLabors.ImageSharp.Formats.Webp; +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Tests; + +namespace SixLabors.ImageSharp.Benchmarks.Codecs +{ + [MarkdownExporter] + [HtmlExporter] + [Config(typeof(Config.ShortMultiFramework))] + public class EncodeWebp + { + private MagickImage webpMagick; + private Image webp; + + private string TestImageFullPath => Path.Combine(TestEnvironment.InputImagesDirectoryFullPath, this.TestImage); + + [Params(TestImages.Png.Bike)] // The bike image will have all 3 transforms as lossless webp. + public string TestImage { get; set; } + + [GlobalSetup] + public void ReadImages() + { + if (this.webp == null) + { + this.webp = Image.Load(this.TestImageFullPath); + this.webpMagick = new MagickImage(this.TestImageFullPath); + } + } + + [GlobalCleanup] + public void Cleanup() + { + this.webp.Dispose(); + this.webpMagick.Dispose(); + } + + [Benchmark(Description = "Magick Webp Lossy")] + public void MagickWebpLossy() + { + using var memoryStream = new MemoryStream(); + + var defines = new WebPWriteDefines + { + Lossless = false, + Method = 4, + AlphaCompression = WebPAlphaCompression.None, + FilterStrength = 60, + SnsStrength = 50, + Pass = 1, + + // 100 means off. + NearLossless = 100 + }; + + this.webpMagick.Quality = 75; + this.webpMagick.Write(memoryStream, defines); + } + + [Benchmark(Description = "ImageSharp Webp Lossy")] + public void ImageSharpWebpLossy() + { + using var memoryStream = new MemoryStream(); + this.webp.Save(memoryStream, new WebpEncoder() + { + FileFormat = WebpFileFormatType.Lossy, + Method = WebpEncodingMethod.Level4, + UseAlphaCompression = false, + FilterStrength = 60, + SpatialNoiseShaping = 50, + EntropyPasses = 1 + }); + } + + [Benchmark(Baseline = true, Description = "Magick Webp Lossless")] + public void MagickWebpLossless() + { + using var memoryStream = new MemoryStream(); + var defines = new WebPWriteDefines + { + Lossless = true, + Method = 4, + + // 100 means off. + NearLossless = 100 + }; + + this.webpMagick.Quality = 75; + this.webpMagick.Write(memoryStream, defines); + } + + [Benchmark(Description = "ImageSharp Webp Lossless")] + public void ImageSharpWebpLossless() + { + using var memoryStream = new MemoryStream(); + this.webp.Save(memoryStream, new WebpEncoder() + { + FileFormat = WebpFileFormatType.Lossless, + Method = WebpEncodingMethod.Level4, + NearLossless = false, + + // This is equal to exact = false in libwebp, which is the default. + TransparentColorMode = WebpTransparentColorMode.Clear + }); + } + + /* Results 04.11.2021 + * Summary * + BenchmarkDotNet=v0.13.0, OS=Windows 10.0.19043.1320 (21H1/May2021Update) + Intel Core i7-6700K CPU 4.00GHz (Skylake), 1 CPU, 8 logical and 4 physical cores + .NET SDK=6.0.100-rc.2.21505.57 + [Host] : .NET 5.0.11 (5.0.1121.47308), X64 RyuJIT + Job-WQLXJO : .NET 5.0.11 (5.0.1121.47308), X64 RyuJIT + Job-OJJAMD : .NET Core 3.1.20 (CoreCLR 4.700.21.47003, CoreFX 4.700.21.47101), X64 RyuJIT + Job-OMFOAS : .NET Framework 4.8 (4.8.4420.0), X64 RyuJIT + + IterationCount=3 LaunchCount=1 WarmupCount=3 + + | Method | Job | Runtime | Arguments | TestImage | Mean | Error | StdDev | Ratio | RatioSD | Gen 0 | Gen 1 | Gen 2 | Allocated | + |--------------------------- |----------- |--------------------- |---------------------- |------------- |----------:|----------:|---------:|------:|--------:|------------:|----------:|----------:|-----------:| + | 'Magick Webp Lossy' | Job-WQLXJO | .NET 5.0 | /p:DebugType=portable | Png/Bike.png | 23.33 ms | 1.491 ms | 0.082 ms | 0.15 | 0.00 | - | - | - | 67 KB | + | 'ImageSharp Webp Lossy' | Job-WQLXJO | .NET 5.0 | /p:DebugType=portable | Png/Bike.png | 245.80 ms | 24.288 ms | 1.331 ms | 1.53 | 0.01 | 135000.0000 | - | - | 552,713 KB | + | 'Magick Webp Lossless' | Job-WQLXJO | .NET 5.0 | /p:DebugType=portable | Png/Bike.png | 160.36 ms | 11.131 ms | 0.610 ms | 1.00 | 0.00 | - | - | - | 518 KB | + | 'ImageSharp Webp Lossless' | Job-WQLXJO | .NET 5.0 | /p:DebugType=portable | Png/Bike.png | 313.93 ms | 45.605 ms | 2.500 ms | 1.96 | 0.01 | 34000.0000 | 5000.0000 | 2000.0000 | 161,670 KB | + | | | | | | | | | | | | | | | + | 'Magick Webp Lossy' | Job-OJJAMD | .NET Core 3.1 | Default | Png/Bike.png | 23.36 ms | 2.289 ms | 0.125 ms | 0.15 | 0.00 | - | - | - | 67 KB | + | 'ImageSharp Webp Lossy' | Job-OJJAMD | .NET Core 3.1 | Default | Png/Bike.png | 254.64 ms | 19.620 ms | 1.075 ms | 1.59 | 0.00 | 135000.0000 | - | - | 552,713 KB | + | 'Magick Webp Lossless' | Job-OJJAMD | .NET Core 3.1 | Default | Png/Bike.png | 160.30 ms | 9.549 ms | 0.523 ms | 1.00 | 0.00 | - | - | - | 518 KB | + | 'ImageSharp Webp Lossless' | Job-OJJAMD | .NET Core 3.1 | Default | Png/Bike.png | 320.35 ms | 22.924 ms | 1.257 ms | 2.00 | 0.01 | 34000.0000 | 5000.0000 | 2000.0000 | 161,669 KB | + | | | | | | | | | | | | | | | + | 'Magick Webp Lossy' | Job-OMFOAS | .NET Framework 4.7.2 | Default | Png/Bike.png | 23.37 ms | 0.908 ms | 0.050 ms | 0.15 | 0.00 | - | - | - | 68 KB | + | 'ImageSharp Webp Lossy' | Job-OMFOAS | .NET Framework 4.7.2 | Default | Png/Bike.png | 378.67 ms | 25.540 ms | 1.400 ms | 2.36 | 0.01 | 135000.0000 | - | - | 554,351 KB | + | 'Magick Webp Lossless' | Job-OMFOAS | .NET Framework 4.7.2 | Default | Png/Bike.png | 160.13 ms | 5.115 ms | 0.280 ms | 1.00 | 0.00 | - | - | - | 520 KB | + | 'ImageSharp Webp Lossless' | Job-OMFOAS | .NET Framework 4.7.2 | Default | Png/Bike.png | 379.01 ms | 71.192 ms | 3.902 ms | 2.37 | 0.02 | 34000.0000 | 5000.0000 | 2000.0000 | 162,119 KB | + */ + } +} diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_CopyTo1x1.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_CopyTo1x1.cs index bb7d08e22..1bd7329f6 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_CopyTo1x1.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_CopyTo1x1.cs @@ -5,14 +5,11 @@ using System; using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; - #if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; #endif - using BenchmarkDotNet.Attributes; - using SixLabors.ImageSharp.Formats.Jpeg.Components; // ReSharper disable InconsistentNaming @@ -319,26 +316,28 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg.BlockOperations { int stride = Width; fixed (float* d = this.unpinnedBuffer) - fixed (Block8x8F* ss = &this.block) { - var s = (float*)ss; - Vector256 v0 = Avx.LoadVector256(s); - Vector256 v1 = Avx.LoadVector256(s + 8); - Vector256 v2 = Avx.LoadVector256(s + (8 * 2)); - Vector256 v3 = Avx.LoadVector256(s + (8 * 3)); - Avx.Store(d, v0); - Avx.Store(d + stride, v1); - Avx.Store(d + (stride * 2), v2); - Avx.Store(d + (stride * 3), v3); - - v0 = Avx.LoadVector256(s + (8 * 4)); - v1 = Avx.LoadVector256(s + (8 * 5)); - v2 = Avx.LoadVector256(s + (8 * 6)); - v3 = Avx.LoadVector256(s + (8 * 7)); - Avx.Store(d + (stride * 4), v0); - Avx.Store(d + (stride * 5), v1); - Avx.Store(d + (stride * 6), v2); - Avx.Store(d + (stride * 7), v3); + fixed (Block8x8F* ss = &this.block) + { + var s = (float*)ss; + Vector256 v0 = Avx.LoadVector256(s); + Vector256 v1 = Avx.LoadVector256(s + 8); + Vector256 v2 = Avx.LoadVector256(s + (8 * 2)); + Vector256 v3 = Avx.LoadVector256(s + (8 * 3)); + Avx.Store(d, v0); + Avx.Store(d + stride, v1); + Avx.Store(d + (stride * 2), v2); + Avx.Store(d + (stride * 3), v3); + + v0 = Avx.LoadVector256(s + (8 * 4)); + v1 = Avx.LoadVector256(s + (8 * 5)); + v2 = Avx.LoadVector256(s + (8 * 6)); + v3 = Avx.LoadVector256(s + (8 * 7)); + Avx.Store(d + (stride * 4), v0); + Avx.Store(d + (stride * 5), v1); + Avx.Store(d + (stride * 6), v2); + Avx.Store(d + (stride * 7), v3); + } } } diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_CopyTo2x2.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_CopyTo2x2.cs index d915cbef0..5398eb6ac 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_CopyTo2x2.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_CopyTo2x2.cs @@ -3,7 +3,6 @@ using System.Numerics; using System.Runtime.CompilerServices; - using BenchmarkDotNet.Attributes; using SixLabors.ImageSharp.Formats.Jpeg.Components; diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_DivideRound.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_DivideRound.cs index 574a08000..80388069f 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_DivideRound.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_DivideRound.cs @@ -3,7 +3,6 @@ using System.Numerics; using System.Runtime.CompilerServices; - using BenchmarkDotNet.Attributes; using SixLabors.ImageSharp.Formats.Jpeg.Components; diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_LoadFromInt16.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_LoadFromInt16.cs index 167e93691..3ee63cdcf 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_LoadFromInt16.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_LoadFromInt16.cs @@ -3,7 +3,6 @@ using System; using System.Numerics; - using BenchmarkDotNet.Attributes; using SixLabors.ImageSharp.Formats.Jpeg.Components; diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_Quantize.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_Quantize.cs new file mode 100644 index 000000000..898bbdb45 --- /dev/null +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_Quantize.cs @@ -0,0 +1,50 @@ +// Copyright (c) Six Labors. +// Licensed under the Apache License, Version 2.0. + +using BenchmarkDotNet.Attributes; +using SixLabors.ImageSharp.Formats.Jpeg.Components; + +namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg.BlockOperations +{ + [Config(typeof(Config.HwIntrinsics_SSE_AVX))] + public class Block8x8F_Quantize + { + private Block8x8F block = CreateFromScalar(1); + private Block8x8F quant = CreateFromScalar(1); + private Block8x8 result = default; + + [Benchmark] + public short Quantize() + { + Block8x8F.Quantize(ref this.block, ref this.result, ref this.quant); + return this.result[0]; + } + + private static Block8x8F CreateFromScalar(float scalar) + { + Block8x8F block = default; + for (int i = 0; i < 64; i++) + { + block[i] = scalar; + } + + return block; + } + } +} + +/* +BenchmarkDotNet=v0.13.0, OS=Windows 10.0.19042.1165 (20H2/October2020Update) +Intel Core i7-6700K CPU 4.00GHz (Skylake), 1 CPU, 8 logical and 4 physical cores +.NET SDK=6.0.100-preview.3.21202.5 + [Host] : .NET Core 3.1.18 (CoreCLR 4.700.21.35901, CoreFX 4.700.21.36305), X64 RyuJIT + 1. No HwIntrinsics : .NET Core 3.1.18 (CoreCLR 4.700.21.35901, CoreFX 4.700.21.36305), X64 RyuJIT + 2. SSE : .NET Core 3.1.18 (CoreCLR 4.700.21.35901, CoreFX 4.700.21.36305), X64 RyuJIT + 3. AVX : .NET Core 3.1.18 (CoreCLR 4.700.21.35901, CoreFX 4.700.21.36305), X64 RyuJIT + +| Method | Job | Mean | Error | StdDev | Ratio | +|--------- |-----------------|---------:|---------:|---------:|------:| +| Quantize | No HwIntrinsics | 73.34 ns | 1.081 ns | 1.011 ns | 1.00 | +| Quantize | SSE | 24.11 ns | 0.298 ns | 0.279 ns | 0.33 | +| Quantize | AVX | 15.90 ns | 0.074 ns | 0.065 ns | 0.22 | + */ diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_Round.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_Round.cs index 0a6a1d97e..6ce1242a5 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_Round.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_Round.cs @@ -5,12 +5,10 @@ using System; using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; - #if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; #endif - using BenchmarkDotNet.Attributes; using SixLabors.ImageSharp.Formats.Jpeg.Components; diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_Transpose.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_Transpose.cs index 1d103cd1a..c2efb517a 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_Transpose.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_Transpose.cs @@ -9,29 +9,44 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg.BlockOperations [Config(typeof(Config.HwIntrinsics_SSE_AVX))] public class Block8x8F_Transpose { - private static readonly Block8x8F Source = Create8x8FloatData(); + private Block8x8F source = Create8x8FloatData(); [Benchmark] - public void TransposeInto() + public float TransposeInplace() { - var dest = default(Block8x8F); - Source.TransposeInto(ref dest); + this.source.TransposeInplace(); + return this.source[0]; } private static Block8x8F Create8x8FloatData() { - var result = new float[64]; + Block8x8F block = default; for (int i = 0; i < 8; i++) { for (int j = 0; j < 8; j++) { - result[(i * 8) + j] = (i * 10) + j; + block[(i * 8) + j] = (i * 10) + j; } } - var source = default(Block8x8F); - source.LoadFrom(result); - return source; + return block; } } } + +/* +BenchmarkDotNet=v0.13.0, OS=Windows 10.0.19042.1237 (20H2/October2020Update) +Intel Core i7-6700K CPU 4.00GHz (Skylake), 1 CPU, 8 logical and 4 physical cores +.NET SDK=6.0.100-preview.3.21202.5 + [Host] : .NET Core 3.1.18 (CoreCLR 4.700.21.35901, CoreFX 4.700.21.36305), X64 RyuJIT + 1. No HwIntrinsics : .NET Core 3.1.18 (CoreCLR 4.700.21.35901, CoreFX 4.700.21.36305), X64 RyuJIT + 2. SSE : .NET Core 3.1.18 (CoreCLR 4.700.21.35901, CoreFX 4.700.21.36305), X64 RyuJIT + 3. AVX : .NET Core 3.1.18 (CoreCLR 4.700.21.35901, CoreFX 4.700.21.36305), X64 RyuJIT + +Runtime=.NET Core 3.1 + +| Method | Job | Mean | Error | StdDev | Ratio | +|----------------- |----------------:|----------:|----------:|----------:|------:| +| TransposeInplace | No HwIntrinsics | 12.531 ns | 0.0637 ns | 0.0565 ns | 1.00 | +| TransposeInplace | AVX | 5.767 ns | 0.0529 ns | 0.0495 ns | 0.46 | +*/ diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/CmykColorConversion.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/CmykColorConversion.cs index d17882adf..490beec6f 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/CmykColorConversion.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/CmykColorConversion.cs @@ -19,7 +19,7 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg { var values = new JpegColorConverter.ComponentValues(this.Input, 0); - new JpegColorConverter.FromCmykBasic(8).ConvertToRgba(values, this.Output); + new JpegColorConverter.FromCmykBasic(8).ConvertToRgbInplace(values); } [Benchmark] @@ -27,7 +27,7 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg { var values = new JpegColorConverter.ComponentValues(this.Input, 0); - new JpegColorConverter.FromCmykVector8(8).ConvertToRgba(values, this.Output); + new JpegColorConverter.FromCmykVector8(8).ConvertToRgbInplace(values); } [Benchmark] @@ -35,7 +35,7 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg { var values = new JpegColorConverter.ComponentValues(this.Input, 0); - new JpegColorConverter.FromCmykAvx2(8).ConvertToRgba(values, this.Output); + new JpegColorConverter.FromCmykAvx2(8).ConvertToRgbInplace(values); } } } diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversionBenchmark.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversionBenchmark.cs index e93ad474b..caed0e4e5 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversionBenchmark.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversionBenchmark.cs @@ -19,13 +19,10 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg protected Buffer2D[] Input { get; private set; } - protected Vector4[] Output { get; private set; } - [GlobalSetup] public void Setup() { this.Input = CreateRandomValues(this.componentCount, Count); - this.Output = new Vector4[Count]; } [GlobalCleanup] diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpegParseStreamOnly.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpegParseStreamOnly.cs index 68a102e3c..9db666c37 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpegParseStreamOnly.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpegParseStreamOnly.cs @@ -4,6 +4,7 @@ using System.IO; using BenchmarkDotNet.Attributes; using SixLabors.ImageSharp.Formats.Jpeg; +using SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder; using SixLabors.ImageSharp.IO; using SixLabors.ImageSharp.Tests; using SDSize = System.Drawing.Size; @@ -39,21 +40,46 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg using var bufferedStream = new BufferedReadStream(Configuration.Default, memoryStream); var decoder = new JpegDecoderCore(Configuration.Default, new JpegDecoder { IgnoreMetadata = true }); - decoder.ParseStream(bufferedStream); + var scanDecoder = new HuffmanScanDecoder(bufferedStream, new NoopSpectralConverter(), cancellationToken: default); + decoder.ParseStream(bufferedStream, scanDecoder, cancellationToken: default); decoder.Dispose(); } - } - /* - | Method | Job | Runtime | TestImage | Mean | Error | StdDev | Ratio | Gen 0 | Gen 1 | Gen 2 | Allocated | - |---------------------------- |----------- |-------------- |--------------------- |---------:|----------:|----------:|------:|--------:|------:|------:|----------:| - | 'System.Drawing FULL' | Job-HITJFX | .NET 4.7.2 | Jpg/b(...)e.jpg [21] | 5.828 ms | 0.9885 ms | 0.0542 ms | 1.00 | 46.8750 | - | - | 211566 B | - | JpegDecoderCore.ParseStream | Job-HITJFX | .NET 4.7.2 | Jpg/b(...)e.jpg [21] | 5.833 ms | 0.2923 ms | 0.0160 ms | 1.00 | - | - | - | 12416 B | - | | | | | | | | | | | | | - | 'System.Drawing FULL' | Job-WPSKZD | .NET Core 2.1 | Jpg/b(...)e.jpg [21] | 6.018 ms | 2.1374 ms | 0.1172 ms | 1.00 | 46.8750 | - | - | 210768 B | - | JpegDecoderCore.ParseStream | Job-WPSKZD | .NET Core 2.1 | Jpg/b(...)e.jpg [21] | 4.382 ms | 0.9009 ms | 0.0494 ms | 0.73 | - | - | - | 12360 B | - | | | | | | | | | | | | | - | 'System.Drawing FULL' | Job-ZLSNRP | .NET Core 3.1 | Jpg/b(...)e.jpg [21] | 5.714 ms | 0.4078 ms | 0.0224 ms | 1.00 | - | - | - | 176 B | - | JpegDecoderCore.ParseStream | Job-ZLSNRP | .NET Core 3.1 | Jpg/b(...)e.jpg [21] | 4.239 ms | 1.0943 ms | 0.0600 ms | 0.74 | - | - | - | 12406 B | - */ + // We want to test only stream parsing and scan decoding, we don't need to convert spectral data to actual pixels + // Nor we need to allocate final pixel buffer + // Note: this still introduces virtual method call overhead for baseline interleaved images + // There's no way to eliminate it as spectral conversion is built into the scan decoding loop for memory footprint reduction + private class NoopSpectralConverter : SpectralConverter + { + public override void ConvertStrideBaseline() + { + } + + public override void InjectFrameData(JpegFrame frame, IRawJpegData jpegData) + { + } + } + } } + +/* +BenchmarkDotNet=v0.13.0, OS=Windows 10.0.19042.1083 (20H2/October2020Update) +Intel Core i7-6700K CPU 4.00GHz (Skylake), 1 CPU, 8 logical and 4 physical cores +.NET SDK=6.0.100-preview.3.21202.5 + [Host] : .NET Core 3.1.13 (CoreCLR 4.700.21.11102, CoreFX 4.700.21.11602), X64 RyuJIT + Job-VAJCIU : .NET Core 2.1.26 (CoreCLR 4.6.29812.02, CoreFX 4.6.29812.01), X64 RyuJIT + Job-INPXCR : .NET Core 3.1.13 (CoreCLR 4.700.21.11102, CoreFX 4.700.21.11602), X64 RyuJIT + Job-JRCLOJ : .NET Framework 4.8 (4.8.4390.0), X64 RyuJIT + +IterationCount=3 LaunchCount=1 WarmupCount=3 +| Method | Job | Runtime | TestImage | Mean | Error | StdDev | Ratio | Gen 0 | Gen 1 | Gen 2 | Allocated | +|---------------------------- |----------- |--------------------- |---------------------- |---------:|----------:|----------:|------:|--------:|------:|------:|----------:| +| 'System.Drawing FULL' | Job-VAJCIU | .NET Core 2.1 | Jpg/baseline/Lake.jpg | 5.196 ms | 0.7520 ms | 0.0412 ms | 1.00 | 46.8750 | - | - | 210,768 B | +| JpegDecoderCore.ParseStream | Job-VAJCIU | .NET Core 2.1 | Jpg/baseline/Lake.jpg | 3.467 ms | 0.0784 ms | 0.0043 ms | 0.67 | - | - | - | 12,416 B | +| | | | | | | | | | | | | +| 'System.Drawing FULL' | Job-INPXCR | .NET Core 3.1 | Jpg/baseline/Lake.jpg | 5.201 ms | 0.4105 ms | 0.0225 ms | 1.00 | - | - | - | 183 B | +| JpegDecoderCore.ParseStream | Job-INPXCR | .NET Core 3.1 | Jpg/baseline/Lake.jpg | 3.349 ms | 0.0468 ms | 0.0026 ms | 0.64 | - | - | - | 12,408 B | +| | | | | | | | | | | | | +| 'System.Drawing FULL' | Job-JRCLOJ | .NET Framework 4.7.2 | Jpg/baseline/Lake.jpg | 5.164 ms | 0.6524 ms | 0.0358 ms | 1.00 | 46.8750 | - | - | 211,571 B | +| JpegDecoderCore.ParseStream | Job-JRCLOJ | .NET Framework 4.7.2 | Jpg/baseline/Lake.jpg | 4.548 ms | 0.3357 ms | 0.0184 ms | 0.88 | - | - | - | 12,480 B | +*/ diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpeg_ImageSpecific.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpeg_ImageSpecific.cs index b0ac1c0fc..da2c81f86 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpeg_ImageSpecific.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpeg_ImageSpecific.cs @@ -44,8 +44,8 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg } } - [Benchmark(Baseline = true, Description = "Decode Jpeg - System.Drawing")] - public SDSize JpegSystemDrawing() + [Benchmark(Baseline = true)] + public SDSize SystemDrawing() { using (var memoryStream = new MemoryStream(this.jpegBytes)) { @@ -56,12 +56,12 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg } } - [Benchmark(Description = "Decode Jpeg - ImageSharp")] - public Size JpegImageSharp() + [Benchmark] + public Size ImageSharp() { using (var memoryStream = new MemoryStream(this.jpegBytes)) { - using (var image = Image.Load(memoryStream, new JpegDecoder { IgnoreMetadata = true })) + using (var image = Image.Load(memoryStream, new JpegDecoder { IgnoreMetadata = true })) { return new Size(image.Width, image.Height); } diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/EncodeJpeg.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/EncodeJpeg.cs index 87170e8d2..0e9bed1d9 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/EncodeJpeg.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/EncodeJpeg.cs @@ -40,8 +40,8 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg this.bmpCore = Image.Load(this.bmpStream); this.bmpCore.Metadata.ExifProfile = null; - this.encoder420 = new JpegEncoder { Quality = this.Quality, Subsample = JpegSubsample.Ratio420 }; - this.encoder444 = new JpegEncoder { Quality = this.Quality, Subsample = JpegSubsample.Ratio444 }; + this.encoder420 = new JpegEncoder { Quality = this.Quality, ColorType = JpegColorType.YCbCrRatio420 }; + this.encoder444 = new JpegEncoder { Quality = this.Quality, ColorType = JpegColorType.YCbCrRatio444 }; this.bmpStream.Position = 0; this.bmpDrawing = SDImage.FromStream(this.bmpStream); @@ -111,24 +111,24 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg } /* -BenchmarkDotNet=v0.12.1, OS=Windows 10.0.19042 +BenchmarkDotNet=v0.13.0, OS=Windows 10.0.19042 Intel Core i7-6700K CPU 4.00GHz (Skylake), 1 CPU, 8 logical and 4 physical cores -.NET Core SDK=6.0.100-preview.3.21202.5 - [Host] : .NET Core 3.1.13 (CoreCLR 4.700.21.11102, CoreFX 4.700.21.11602), X64 RyuJIT - DefaultJob : .NET Core 3.1.13 (CoreCLR 4.700.21.11102, CoreFX 4.700.21.11602), X64 RyuJIT +.NET SDK=6.0.100-preview.3.21202.5 + [Host] : .NET Core 3.1.18 (CoreCLR 4.700.21.35901, CoreFX 4.700.21.36305), X64 RyuJIT + DefaultJob : .NET Core 3.1.18 (CoreCLR 4.700.21.35901, CoreFX 4.700.21.36305), X64 RyuJIT | Method | Quality | Mean | Error | StdDev | Ratio | |---------------------------- |-------- |---------:|---------:|---------:|------:| -| 'System.Drawing Jpeg 4:2:0' | 75 | 29.41 ms | 0.108 ms | 0.096 ms | 1.00 | -| 'ImageSharp Jpeg 4:2:0' | 75 | 26.30 ms | 0.131 ms | 0.109 ms | 0.89 | -| 'ImageSharp Jpeg 4:4:4' | 75 | 36.70 ms | 0.303 ms | 0.269 ms | 1.25 | +| 'System.Drawing Jpeg 4:2:0' | 75 | 30.04 ms | 0.540 ms | 0.479 ms | 1.00 | +| 'ImageSharp Jpeg 4:2:0' | 75 | 19.32 ms | 0.290 ms | 0.257 ms | 0.64 | +| 'ImageSharp Jpeg 4:4:4' | 75 | 26.76 ms | 0.332 ms | 0.294 ms | 0.89 | | | | | | | | -| 'System.Drawing Jpeg 4:2:0' | 90 | 32.67 ms | 0.226 ms | 0.211 ms | 1.00 | -| 'ImageSharp Jpeg 4:2:0' | 90 | 33.56 ms | 0.237 ms | 0.222 ms | 1.03 | -| 'ImageSharp Jpeg 4:4:4' | 90 | 44.82 ms | 0.250 ms | 0.234 ms | 1.37 | +| 'System.Drawing Jpeg 4:2:0' | 90 | 32.82 ms | 0.184 ms | 0.163 ms | 1.00 | +| 'ImageSharp Jpeg 4:2:0' | 90 | 25.00 ms | 0.408 ms | 0.361 ms | 0.76 | +| 'ImageSharp Jpeg 4:4:4' | 90 | 31.83 ms | 0.636 ms | 0.595 ms | 0.97 | | | | | | | | -| 'System.Drawing Jpeg 4:2:0' | 100 | 39.06 ms | 0.233 ms | 0.218 ms | 1.00 | -| 'ImageSharp Jpeg 4:2:0' | 100 | 40.23 ms | 0.225 ms | 0.277 ms | 1.03 | -| 'ImageSharp Jpeg 4:4:4' | 100 | 63.35 ms | 0.486 ms | 0.431 ms | 1.62 | +| 'System.Drawing Jpeg 4:2:0' | 100 | 39.30 ms | 0.359 ms | 0.318 ms | 1.00 | +| 'ImageSharp Jpeg 4:2:0' | 100 | 34.49 ms | 0.265 ms | 0.235 ms | 0.88 | +| 'ImageSharp Jpeg 4:4:4' | 100 | 56.40 ms | 0.565 ms | 0.501 ms | 1.44 | */ diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/GrayscaleColorConversion.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/GrayscaleColorConversion.cs index 1eba1571d..7b62e1434 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/GrayscaleColorConversion.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/GrayscaleColorConversion.cs @@ -19,7 +19,7 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg { var values = new JpegColorConverter.ComponentValues(this.Input, 0); - new JpegColorConverter.FromGrayscaleBasic(8).ConvertToRgba(values, this.Output); + new JpegColorConverter.FromGrayscaleBasic(8).ConvertToRgbInplace(values); } [Benchmark] @@ -27,7 +27,7 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg { var values = new JpegColorConverter.ComponentValues(this.Input, 0); - new JpegColorConverter.FromGrayscaleAvx2(8).ConvertToRgba(values, this.Output); + new JpegColorConverter.FromGrayscaleAvx2(8).ConvertToRgbInplace(values); } } } diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/RgbColorConversion.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/RgbColorConversion.cs index c1598be04..af03b31e5 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/RgbColorConversion.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/RgbColorConversion.cs @@ -19,7 +19,7 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg { var values = new JpegColorConverter.ComponentValues(this.Input, 0); - new JpegColorConverter.FromRgbBasic(8).ConvertToRgba(values, this.Output); + new JpegColorConverter.FromRgbBasic(8).ConvertToRgbInplace(values); } [Benchmark] @@ -27,7 +27,7 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg { var values = new JpegColorConverter.ComponentValues(this.Input, 0); - new JpegColorConverter.FromRgbVector8(8).ConvertToRgba(values, this.Output); + new JpegColorConverter.FromRgbVector8(8).ConvertToRgbInplace(values); } [Benchmark] @@ -35,7 +35,7 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg { var values = new JpegColorConverter.ComponentValues(this.Input, 0); - new JpegColorConverter.FromRgbAvx2(8).ConvertToRgba(values, this.Output); + new JpegColorConverter.FromRgbAvx2(8).ConvertToRgbInplace(values); } } } diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/YCbCrColorConversion.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/YCbCrColorConversion.cs index 6c5732c99..18daa364c 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/YCbCrColorConversion.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/YCbCrColorConversion.cs @@ -19,7 +19,7 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg { var values = new JpegColorConverter.ComponentValues(this.Input, 0); - new JpegColorConverter.FromYCbCrBasic(8).ConvertToRgba(values, this.Output); + new JpegColorConverter.FromYCbCrBasic(8).ConvertToRgbInplace(values); } [Benchmark(Baseline = true)] @@ -27,7 +27,7 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg { var values = new JpegColorConverter.ComponentValues(this.Input, 0); - new JpegColorConverter.FromYCbCrVector4(8).ConvertToRgba(values, this.Output); + new JpegColorConverter.FromYCbCrVector4(8).ConvertToRgbInplace(values); } [Benchmark] @@ -35,7 +35,7 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg { var values = new JpegColorConverter.ComponentValues(this.Input, 0); - new JpegColorConverter.FromYCbCrVector8(8).ConvertToRgba(values, this.Output); + new JpegColorConverter.FromYCbCrVector8(8).ConvertToRgbInplace(values); } [Benchmark] @@ -43,7 +43,7 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg { var values = new JpegColorConverter.ComponentValues(this.Input, 0); - new JpegColorConverter.FromYCbCrAvx2(8).ConvertToRgba(values, this.Output); + new JpegColorConverter.FromYCbCrAvx2(8).ConvertToRgbInplace(values); } } } diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/YccKColorConverter.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/YccKColorConverter.cs index 0a9bdb8fd..08e5e50d1 100644 --- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/YccKColorConverter.cs +++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/YccKColorConverter.cs @@ -19,7 +19,7 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg { var values = new JpegColorConverter.ComponentValues(this.Input, 0); - new JpegColorConverter.FromYccKBasic(8).ConvertToRgba(values, this.Output); + new JpegColorConverter.FromYccKBasic(8).ConvertToRgbInplace(values); } [Benchmark] @@ -27,7 +27,7 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg { var values = new JpegColorConverter.ComponentValues(this.Input, 0); - new JpegColorConverter.FromYccKVector8(8).ConvertToRgba(values, this.Output); + new JpegColorConverter.FromYccKVector8(8).ConvertToRgbInplace(values); } [Benchmark] @@ -35,7 +35,7 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg { var values = new JpegColorConverter.ComponentValues(this.Input, 0); - new JpegColorConverter.FromYccKAvx2(8).ConvertToRgba(values, this.Output); + new JpegColorConverter.FromYccKAvx2(8).ConvertToRgbInplace(values); } } } diff --git a/tests/ImageSharp.Benchmarks/Color/Bulk/FromVector4.cs b/tests/ImageSharp.Benchmarks/Color/Bulk/FromVector4.cs index 04ca8cd65..03e29b8e8 100644 --- a/tests/ImageSharp.Benchmarks/Color/Bulk/FromVector4.cs +++ b/tests/ImageSharp.Benchmarks/Color/Bulk/FromVector4.cs @@ -6,12 +6,10 @@ using System.Buffers; using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; - #if SUPPORTS_RUNTIME_INTRINSICS using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; #endif - using BenchmarkDotNet.Attributes; using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.PixelFormats; diff --git a/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4_Rgba32.cs b/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4_Rgba32.cs index 9ae3b073d..ddeae5c2a 100644 --- a/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4_Rgba32.cs +++ b/tests/ImageSharp.Benchmarks/Color/Bulk/ToVector4_Rgba32.cs @@ -5,7 +5,6 @@ using System; using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; - using BenchmarkDotNet.Attributes; using SixLabors.ImageSharp.Memory; diff --git a/tests/ImageSharp.Benchmarks/Color/RgbToYCbCr.cs b/tests/ImageSharp.Benchmarks/Color/RgbToYCbCr.cs index f4f944333..d231b706b 100644 --- a/tests/ImageSharp.Benchmarks/Color/RgbToYCbCr.cs +++ b/tests/ImageSharp.Benchmarks/Color/RgbToYCbCr.cs @@ -3,7 +3,6 @@ using System.Numerics; using System.Runtime.CompilerServices; - using BenchmarkDotNet.Attributes; using SixLabors.ImageSharp.Formats.Jpeg.Components; diff --git a/tests/ImageSharp.Benchmarks/Config.HwIntrinsics.cs b/tests/ImageSharp.Benchmarks/Config.HwIntrinsics.cs index 5ceb4c8a0..ffe0f4c02 100644 --- a/tests/ImageSharp.Benchmarks/Config.HwIntrinsics.cs +++ b/tests/ImageSharp.Benchmarks/Config.HwIntrinsics.cs @@ -65,17 +65,17 @@ namespace SixLabors.ImageSharp.Benchmarks .WithId("1. No HwIntrinsics").AsBaseline()); #if SUPPORTS_RUNTIME_INTRINSICS - if (Avx.IsSupported) + if (Sse.IsSupported) { this.AddJob(Job.Default.WithRuntime(CoreRuntime.Core31) - .WithId("2. AVX")); + .WithEnvironmentVariables(new EnvironmentVariable(EnableAVX, Off)) + .WithId("2. SSE")); } - if (Sse.IsSupported) + if (Avx.IsSupported) { this.AddJob(Job.Default.WithRuntime(CoreRuntime.Core31) - .WithEnvironmentVariables(new EnvironmentVariable(EnableAVX, Off)) - .WithId("3. SSE")); + .WithId("3. AVX")); } #endif } diff --git a/tests/ImageSharp.Benchmarks/Config.cs b/tests/ImageSharp.Benchmarks/Config.cs index 63064eec5..299784821 100644 --- a/tests/ImageSharp.Benchmarks/Config.cs +++ b/tests/ImageSharp.Benchmarks/Config.cs @@ -33,16 +33,16 @@ namespace SixLabors.ImageSharp.Benchmarks { public MultiFramework() => this.AddJob( Job.Default.WithRuntime(ClrRuntime.Net472), - Job.Default.WithRuntime(CoreRuntime.Core21), - Job.Default.WithRuntime(CoreRuntime.Core31)); + Job.Default.WithRuntime(CoreRuntime.Core31), + Job.Default.WithRuntime(CoreRuntime.Core50).With(new Argument[] { new MsBuildArgument("/p:DebugType=portable") })); } public class ShortMultiFramework : Config { public ShortMultiFramework() => this.AddJob( Job.Default.WithRuntime(ClrRuntime.Net472).WithLaunchCount(1).WithWarmupCount(3).WithIterationCount(3), - Job.Default.WithRuntime(CoreRuntime.Core21).WithLaunchCount(1).WithWarmupCount(3).WithIterationCount(3), - Job.Default.WithRuntime(CoreRuntime.Core31).WithLaunchCount(1).WithWarmupCount(3).WithIterationCount(3)); + Job.Default.WithRuntime(CoreRuntime.Core31).WithLaunchCount(1).WithWarmupCount(3).WithIterationCount(3), + Job.Default.WithRuntime(CoreRuntime.Core50).WithLaunchCount(1).WithWarmupCount(3).WithIterationCount(3).With(new Argument[] { new MsBuildArgument("/p:DebugType=portable") })); } public class ShortCore31 : Config diff --git a/tests/ImageSharp.Benchmarks/General/Array2D.cs b/tests/ImageSharp.Benchmarks/General/Array2D.cs index 16cbb5991..cd4eec0d4 100644 --- a/tests/ImageSharp.Benchmarks/General/Array2D.cs +++ b/tests/ImageSharp.Benchmarks/General/Array2D.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. using System; - using BenchmarkDotNet.Attributes; using SixLabors.ImageSharp; diff --git a/tests/ImageSharp.Benchmarks/General/ArrayReverse.cs b/tests/ImageSharp.Benchmarks/General/ArrayReverse.cs index cd3fc5a06..b9ba80c15 100644 --- a/tests/ImageSharp.Benchmarks/General/ArrayReverse.cs +++ b/tests/ImageSharp.Benchmarks/General/ArrayReverse.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. using System; - using BenchmarkDotNet.Attributes; namespace SixLabors.ImageSharp.Benchmarks.General diff --git a/tests/ImageSharp.Benchmarks/General/BasicMath/Abs.cs b/tests/ImageSharp.Benchmarks/General/BasicMath/Abs.cs index b6cdcf5f5..0abaac207 100644 --- a/tests/ImageSharp.Benchmarks/General/BasicMath/Abs.cs +++ b/tests/ImageSharp.Benchmarks/General/BasicMath/Abs.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. using System; - using BenchmarkDotNet.Attributes; namespace SixLabors.ImageSharp.Benchmarks.General.BasicMath diff --git a/tests/ImageSharp.Benchmarks/General/BasicMath/ClampFloat.cs b/tests/ImageSharp.Benchmarks/General/BasicMath/ClampFloat.cs index 516c187e3..2f4120bb3 100644 --- a/tests/ImageSharp.Benchmarks/General/BasicMath/ClampFloat.cs +++ b/tests/ImageSharp.Benchmarks/General/BasicMath/ClampFloat.cs @@ -3,7 +3,6 @@ using System; using System.Runtime.CompilerServices; - using BenchmarkDotNet.Attributes; namespace SixLabors.ImageSharp.Benchmarks.General.BasicMath diff --git a/tests/ImageSharp.Benchmarks/General/BasicMath/ClampInt32IntoByte.cs b/tests/ImageSharp.Benchmarks/General/BasicMath/ClampInt32IntoByte.cs index 1c58636df..bfa468f13 100644 --- a/tests/ImageSharp.Benchmarks/General/BasicMath/ClampInt32IntoByte.cs +++ b/tests/ImageSharp.Benchmarks/General/BasicMath/ClampInt32IntoByte.cs @@ -3,7 +3,6 @@ using System; using System.Runtime.CompilerServices; - using BenchmarkDotNet.Attributes; namespace SixLabors.ImageSharp.Benchmarks.General.BasicMath diff --git a/tests/ImageSharp.Benchmarks/General/BasicMath/ClampVector4.cs b/tests/ImageSharp.Benchmarks/General/BasicMath/ClampVector4.cs index 0b5f31ee4..c1dab7024 100644 --- a/tests/ImageSharp.Benchmarks/General/BasicMath/ClampVector4.cs +++ b/tests/ImageSharp.Benchmarks/General/BasicMath/ClampVector4.cs @@ -3,7 +3,6 @@ using System.Numerics; using System.Runtime.CompilerServices; - using BenchmarkDotNet.Attributes; namespace SixLabors.ImageSharp.Benchmarks.General.BasicMath diff --git a/tests/ImageSharp.Benchmarks/General/BasicMath/Pow.cs b/tests/ImageSharp.Benchmarks/General/BasicMath/Pow.cs index ad8f8746c..899a21cc1 100644 --- a/tests/ImageSharp.Benchmarks/General/BasicMath/Pow.cs +++ b/tests/ImageSharp.Benchmarks/General/BasicMath/Pow.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. using System; - using BenchmarkDotNet.Attributes; namespace SixLabors.ImageSharp.Benchmarks.General.BasicMath diff --git a/tests/ImageSharp.Benchmarks/General/CopyBuffers.cs b/tests/ImageSharp.Benchmarks/General/CopyBuffers.cs index d21e44a1c..db8887580 100644 --- a/tests/ImageSharp.Benchmarks/General/CopyBuffers.cs +++ b/tests/ImageSharp.Benchmarks/General/CopyBuffers.cs @@ -5,7 +5,6 @@ using System; using System.Buffers; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; - using BenchmarkDotNet.Attributes; namespace SixLabors.ImageSharp.Benchmarks.General diff --git a/tests/ImageSharp.Benchmarks/General/PixelConversion/ITestPixel.cs b/tests/ImageSharp.Benchmarks/General/PixelConversion/ITestPixel.cs index 12ebbcf4b..c10000f0a 100644 --- a/tests/ImageSharp.Benchmarks/General/PixelConversion/ITestPixel.cs +++ b/tests/ImageSharp.Benchmarks/General/PixelConversion/ITestPixel.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. using System.Numerics; - using SixLabors.ImageSharp.PixelFormats; namespace SixLabors.ImageSharp.Benchmarks.General.PixelConversion diff --git a/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertFromRgba32.cs b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertFromRgba32.cs index a933f890f..e0aa7023c 100644 --- a/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertFromRgba32.cs +++ b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertFromRgba32.cs @@ -4,7 +4,6 @@ using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; - using BenchmarkDotNet.Attributes; using SixLabors.ImageSharp.PixelFormats; diff --git a/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertFromVector4.cs b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertFromVector4.cs index 6bb3f38be..5a9421fe7 100644 --- a/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertFromVector4.cs +++ b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertFromVector4.cs @@ -4,7 +4,6 @@ using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; - using BenchmarkDotNet.Attributes; using SixLabors.ImageSharp.PixelFormats; diff --git a/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertToRgba32.cs b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertToRgba32.cs index f922559f7..07f697e91 100644 --- a/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertToRgba32.cs +++ b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertToRgba32.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. using System.Runtime.CompilerServices; - using BenchmarkDotNet.Attributes; using SixLabors.ImageSharp.PixelFormats; diff --git a/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertToRgba32_AsPartOfCompositeOperation.cs b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertToRgba32_AsPartOfCompositeOperation.cs index 1a228e3bf..5df8daa04 100644 --- a/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertToRgba32_AsPartOfCompositeOperation.cs +++ b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertToRgba32_AsPartOfCompositeOperation.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. using System.Runtime.CompilerServices; - using BenchmarkDotNet.Attributes; using SixLabors.ImageSharp.PixelFormats; diff --git a/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertToVector4.cs b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertToVector4.cs index dc7dea504..798995c3d 100644 --- a/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertToVector4.cs +++ b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertToVector4.cs @@ -3,7 +3,6 @@ using System.Numerics; using System.Runtime.CompilerServices; - using BenchmarkDotNet.Attributes; namespace SixLabors.ImageSharp.Benchmarks.General.PixelConversion diff --git a/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertToVector4_AsPartOfCompositeOperation.cs b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertToVector4_AsPartOfCompositeOperation.cs index c1c4d6e0d..d029cd90d 100644 --- a/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertToVector4_AsPartOfCompositeOperation.cs +++ b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_ConvertToVector4_AsPartOfCompositeOperation.cs @@ -3,7 +3,6 @@ using System.Numerics; using System.Runtime.CompilerServices; - using BenchmarkDotNet.Attributes; namespace SixLabors.ImageSharp.Benchmarks.General.PixelConversion diff --git a/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_PackFromRgbPlanes.cs b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_PackFromRgbPlanes.cs index eade8e0c4..8900894b4 100644 --- a/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_PackFromRgbPlanes.cs +++ b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_PackFromRgbPlanes.cs @@ -50,16 +50,22 @@ namespace SixLabors.ImageSharp.Benchmarks.General.PixelConversion public void Rgb24_Scalar_PerElement_Pinned() { fixed (byte* r = &this.rBuf[0]) - fixed (byte* g = &this.gBuf[0]) - fixed (byte* b = &this.bBuf[0]) - fixed (Rgb24* rgb = &this.rgbBuf[0]) { - for (int i = 0; i < this.Count; i++) + fixed (byte* g = &this.gBuf[0]) { - Rgb24* d = rgb + i; - d->R = r[i]; - d->G = g[i]; - d->B = b[i]; + fixed (byte* b = &this.bBuf[0]) + { + fixed (Rgb24* rgb = &this.rgbBuf[0]) + { + for (int i = 0; i < this.Count; i++) + { + Rgb24* d = rgb + i; + d->R = r[i]; + d->G = g[i]; + d->B = b[i]; + } + } + } } } } @@ -283,4 +289,4 @@ namespace SixLabors.ImageSharp.Benchmarks.General.PixelConversion // | Rgb24_Avx2_Bytes | 1024 | 243.3 ns | 1.56 ns | 1.30 ns | 0.47 | 0.00 | // | Rgba32_Avx2_Bytes | 1024 | 146.0 ns | 2.48 ns | 2.32 ns | 0.28 | 0.01 | } -} \ No newline at end of file +} diff --git a/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_Rgba32_To_Argb32.cs b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_Rgba32_To_Argb32.cs index 7c51e0547..6ab1982aa 100644 --- a/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_Rgba32_To_Argb32.cs +++ b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_Rgba32_To_Argb32.cs @@ -4,7 +4,6 @@ using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; - using BenchmarkDotNet.Attributes; using SixLabors.ImageSharp.PixelFormats; diff --git a/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_Rgba32_To_Bgra32.cs b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_Rgba32_To_Bgra32.cs index 8cb9fb984..580ae7afb 100644 --- a/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_Rgba32_To_Bgra32.cs +++ b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_Rgba32_To_Bgra32.cs @@ -5,7 +5,6 @@ using System; using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; - using BenchmarkDotNet.Attributes; using SixLabors.ImageSharp.PixelFormats; diff --git a/tests/ImageSharp.Benchmarks/General/PixelConversion/TestArgb.cs b/tests/ImageSharp.Benchmarks/General/PixelConversion/TestArgb.cs index 958495c3c..6c74fc3bc 100644 --- a/tests/ImageSharp.Benchmarks/General/PixelConversion/TestArgb.cs +++ b/tests/ImageSharp.Benchmarks/General/PixelConversion/TestArgb.cs @@ -4,7 +4,6 @@ using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; - using SixLabors.ImageSharp.PixelFormats; namespace SixLabors.ImageSharp.Benchmarks.General.PixelConversion diff --git a/tests/ImageSharp.Benchmarks/General/PixelConversion/TestRgba.cs b/tests/ImageSharp.Benchmarks/General/PixelConversion/TestRgba.cs index ff11585e7..e01bfa011 100644 --- a/tests/ImageSharp.Benchmarks/General/PixelConversion/TestRgba.cs +++ b/tests/ImageSharp.Benchmarks/General/PixelConversion/TestRgba.cs @@ -4,7 +4,6 @@ using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; - using SixLabors.ImageSharp.PixelFormats; namespace SixLabors.ImageSharp.Benchmarks.General.PixelConversion diff --git a/tests/ImageSharp.Benchmarks/General/Vector4Constants.cs b/tests/ImageSharp.Benchmarks/General/Vector4Constants.cs index ef1b3c98d..fa3f1e9dd 100644 --- a/tests/ImageSharp.Benchmarks/General/Vector4Constants.cs +++ b/tests/ImageSharp.Benchmarks/General/Vector4Constants.cs @@ -3,7 +3,6 @@ using System; using System.Numerics; - using BenchmarkDotNet.Attributes; namespace SixLabors.ImageSharp.Benchmarks.General diff --git a/tests/ImageSharp.Benchmarks/General/Vectorization/BitwiseOrUint32.cs b/tests/ImageSharp.Benchmarks/General/Vectorization/BitwiseOrUint32.cs index 651ca51ba..3cf9f0555 100644 --- a/tests/ImageSharp.Benchmarks/General/Vectorization/BitwiseOrUint32.cs +++ b/tests/ImageSharp.Benchmarks/General/Vectorization/BitwiseOrUint32.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. using System.Numerics; - using BenchmarkDotNet.Attributes; namespace SixLabors.ImageSharp.Benchmarks.General.Vectorization diff --git a/tests/ImageSharp.Benchmarks/General/Vectorization/DivFloat.cs b/tests/ImageSharp.Benchmarks/General/Vectorization/DivFloat.cs index 4c981bf5c..85d4a93a3 100644 --- a/tests/ImageSharp.Benchmarks/General/Vectorization/DivFloat.cs +++ b/tests/ImageSharp.Benchmarks/General/Vectorization/DivFloat.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. using System.Numerics; - using BenchmarkDotNet.Attributes; namespace SixLabors.ImageSharp.Benchmarks.General.Vectorization diff --git a/tests/ImageSharp.Benchmarks/General/Vectorization/DivUInt32.cs b/tests/ImageSharp.Benchmarks/General/Vectorization/DivUInt32.cs index 36a45a482..2555d7b8f 100644 --- a/tests/ImageSharp.Benchmarks/General/Vectorization/DivUInt32.cs +++ b/tests/ImageSharp.Benchmarks/General/Vectorization/DivUInt32.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. using System.Numerics; - using BenchmarkDotNet.Attributes; namespace SixLabors.ImageSharp.Benchmarks.General.Vectorization diff --git a/tests/ImageSharp.Benchmarks/General/Vectorization/Divide.cs b/tests/ImageSharp.Benchmarks/General/Vectorization/Divide.cs index 09d14963b..11889127c 100644 --- a/tests/ImageSharp.Benchmarks/General/Vectorization/Divide.cs +++ b/tests/ImageSharp.Benchmarks/General/Vectorization/Divide.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. using System.Numerics; - using BenchmarkDotNet.Attributes; namespace ImageSharp.Benchmarks.General.Vectorization diff --git a/tests/ImageSharp.Benchmarks/General/Vectorization/MulFloat.cs b/tests/ImageSharp.Benchmarks/General/Vectorization/MulFloat.cs index 595df8a59..99afc90de 100644 --- a/tests/ImageSharp.Benchmarks/General/Vectorization/MulFloat.cs +++ b/tests/ImageSharp.Benchmarks/General/Vectorization/MulFloat.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. using System.Numerics; - using BenchmarkDotNet.Attributes; namespace SixLabors.ImageSharp.Benchmarks.General.Vectorization diff --git a/tests/ImageSharp.Benchmarks/General/Vectorization/MulUInt32.cs b/tests/ImageSharp.Benchmarks/General/Vectorization/MulUInt32.cs index a405f0953..2b41904f8 100644 --- a/tests/ImageSharp.Benchmarks/General/Vectorization/MulUInt32.cs +++ b/tests/ImageSharp.Benchmarks/General/Vectorization/MulUInt32.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. using System.Numerics; - using BenchmarkDotNet.Attributes; namespace SixLabors.ImageSharp.Benchmarks.General.Vectorization diff --git a/tests/ImageSharp.Benchmarks/General/Vectorization/ReinterpretUInt32AsFloat.cs b/tests/ImageSharp.Benchmarks/General/Vectorization/ReinterpretUInt32AsFloat.cs index cdf8ad04f..d4da75cdf 100644 --- a/tests/ImageSharp.Benchmarks/General/Vectorization/ReinterpretUInt32AsFloat.cs +++ b/tests/ImageSharp.Benchmarks/General/Vectorization/ReinterpretUInt32AsFloat.cs @@ -3,7 +3,6 @@ using System.Numerics; using System.Runtime.InteropServices; - using BenchmarkDotNet.Attributes; namespace SixLabors.ImageSharp.Benchmarks.General.Vectorization diff --git a/tests/ImageSharp.Benchmarks/General/Vectorization/SIMDBenchmarkBase.cs b/tests/ImageSharp.Benchmarks/General/Vectorization/SIMDBenchmarkBase.cs index 8a61f49c4..0a666d0c6 100644 --- a/tests/ImageSharp.Benchmarks/General/Vectorization/SIMDBenchmarkBase.cs +++ b/tests/ImageSharp.Benchmarks/General/Vectorization/SIMDBenchmarkBase.cs @@ -3,7 +3,6 @@ using System.Numerics; using System.Runtime.CompilerServices; - using BenchmarkDotNet.Attributes; namespace ImageSharp.Benchmarks.General.Vectorization diff --git a/tests/ImageSharp.Benchmarks/General/Vectorization/UInt32ToSingle.cs b/tests/ImageSharp.Benchmarks/General/Vectorization/UInt32ToSingle.cs index 5ec5f1d18..21114c510 100644 --- a/tests/ImageSharp.Benchmarks/General/Vectorization/UInt32ToSingle.cs +++ b/tests/ImageSharp.Benchmarks/General/Vectorization/UInt32ToSingle.cs @@ -3,7 +3,6 @@ using System.Numerics; using System.Runtime.CompilerServices; - using BenchmarkDotNet.Attributes; namespace SixLabors.ImageSharp.Benchmarks.General.Vectorization diff --git a/tests/ImageSharp.Benchmarks/General/Vectorization/WidenBytesToUInt32.cs b/tests/ImageSharp.Benchmarks/General/Vectorization/WidenBytesToUInt32.cs index 20d3bd9d6..661eb844e 100644 --- a/tests/ImageSharp.Benchmarks/General/Vectorization/WidenBytesToUInt32.cs +++ b/tests/ImageSharp.Benchmarks/General/Vectorization/WidenBytesToUInt32.cs @@ -3,7 +3,6 @@ using System.Numerics; using System.Runtime.CompilerServices; - using BenchmarkDotNet.Attributes; using SixLabors.ImageSharp.Tuples; diff --git a/tests/ImageSharp.Benchmarks/ImageSharp.Benchmarks.csproj b/tests/ImageSharp.Benchmarks/ImageSharp.Benchmarks.csproj index 84b83ee14..8f0b4a86f 100644 --- a/tests/ImageSharp.Benchmarks/ImageSharp.Benchmarks.csproj +++ b/tests/ImageSharp.Benchmarks/ImageSharp.Benchmarks.csproj @@ -6,15 +6,20 @@ Exe SixLabors.ImageSharp.Benchmarks false + portable false Debug;Release;Debug-InnerLoop;Release-InnerLoop - 9 + + + net6.0;net5.0;netcoreapp3.1;netcoreapp2.1;net472 + + netcoreapp3.1 diff --git a/tests/ImageSharp.Benchmarks/LoadResizeSave/LoadResizeSaveStressBenchmarks.cs b/tests/ImageSharp.Benchmarks/LoadResizeSave/LoadResizeSaveStressBenchmarks.cs index f1f7de3dc..b7ec95c4b 100644 --- a/tests/ImageSharp.Benchmarks/LoadResizeSave/LoadResizeSaveStressBenchmarks.cs +++ b/tests/ImageSharp.Benchmarks/LoadResizeSave/LoadResizeSaveStressBenchmarks.cs @@ -42,11 +42,11 @@ namespace SixLabors.ImageSharp.Benchmarks.LoadResizeSave 1 }; - [Benchmark(Baseline = true)] + [Benchmark] [ArgumentsSource(nameof(ParallelismValues))] public void SystemDrawing(int maxDegreeOfParallelism) => this.ForEachImage(this.runner.SystemDrawingResize, maxDegreeOfParallelism); - [Benchmark] + [Benchmark(Baseline = true)] [ArgumentsSource(nameof(ParallelismValues))] public void ImageSharp(int maxDegreeOfParallelism) => this.ForEachImage(this.runner.ImageSharpResize, maxDegreeOfParallelism); @@ -62,6 +62,10 @@ namespace SixLabors.ImageSharp.Benchmarks.LoadResizeSave [ArgumentsSource(nameof(ParallelismValues))] public void SkiaBitmap(int maxDegreeOfParallelism) => this.ForEachImage(this.runner.SkiaBitmapResize, maxDegreeOfParallelism); + [Benchmark] + [ArgumentsSource(nameof(ParallelismValues))] + public void SkiaBitmapDecodeToTargetSize(int maxDegreeOfParallelism) => this.ForEachImage(this.runner.SkiaBitmapDecodeToTargetSize, maxDegreeOfParallelism); + [Benchmark] [ArgumentsSource(nameof(ParallelismValues))] public void NetVips(int maxDegreeOfParallelism) => this.ForEachImage(this.runner.NetVipsResize, maxDegreeOfParallelism); diff --git a/tests/ImageSharp.Benchmarks/LoadResizeSave/LoadResizeSaveStressRunner.cs b/tests/ImageSharp.Benchmarks/LoadResizeSave/LoadResizeSaveStressRunner.cs index c15f641b4..7c57d691a 100644 --- a/tests/ImageSharp.Benchmarks/LoadResizeSave/LoadResizeSaveStressRunner.cs +++ b/tests/ImageSharp.Benchmarks/LoadResizeSave/LoadResizeSaveStressRunner.cs @@ -7,6 +7,7 @@ using System.Drawing.Drawing2D; using System.Drawing.Imaging; using System.IO; using System.Linq; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Threading.Tasks; using ImageMagick; @@ -31,18 +32,10 @@ namespace SixLabors.ImageSharp.Benchmarks.LoadResizeSave public class LoadResizeSaveStressRunner { - private const int ThumbnailSize = 150; private const int Quality = 75; - private const string ImageSharp = nameof(ImageSharp); - private const string SystemDrawing = nameof(SystemDrawing); - private const string MagickNET = nameof(MagickNET); - private const string NetVips = nameof(NetVips); - private const string MagicScaler = nameof(MagicScaler); - private const string SkiaSharpCanvas = nameof(SkiaSharpCanvas); - private const string SkiaSharpBitmap = nameof(SkiaSharpBitmap); // Set the quality for ImagSharp - private readonly JpegEncoder imageSharpJpegEncoder = new () { Quality = Quality }; + private readonly JpegEncoder imageSharpJpegEncoder = new() { Quality = Quality }; private readonly ImageCodecInfo systemDrawingJpegCodec = ImageCodecInfo.GetImageEncoders().First(codec => codec.FormatID == ImageFormat.Jpeg.Guid); @@ -58,6 +51,8 @@ namespace SixLabors.ImageSharp.Benchmarks.LoadResizeSave public JpegKind Filter { get; set; } + public int ThumbnailSize { get; set; } = 150; + private static readonly string[] ProgressiveFiles = { "ancyloscelis-apiformis-m-paraguay-face_2014-08-08-095255-zs-pmax_15046500892_o.jpg", @@ -132,12 +127,12 @@ namespace SixLabors.ImageSharp.Benchmarks.LoadResizeSave this.TotalProcessedMegapixels += pixels / 1_000_000.0; } - private string OutputPath(string inputPath, string postfix) => + private string OutputPath(string inputPath, [CallerMemberName]string postfix = null) => Path.Combine( this.outputDirectory, Path.GetFileNameWithoutExtension(inputPath) + "-" + postfix + Path.GetExtension(inputPath)); - private (int width, int height) ScaledSize(int inWidth, int inHeight, int outSize) + private (int Width, int Height) ScaledSize(int inWidth, int inHeight, int outSize) { int width, height; if (inWidth > inHeight) @@ -159,8 +154,8 @@ namespace SixLabors.ImageSharp.Benchmarks.LoadResizeSave using var image = SystemDrawingImage.FromFile(input, true); this.IncreaseTotalMegapixels(image.Width, image.Height); - (int width, int height) scaled = this.ScaledSize(image.Width, image.Height, ThumbnailSize); - var resized = new Bitmap(scaled.width, scaled.height); + (int Width, int Height) scaled = this.ScaledSize(image.Width, image.Height, this.ThumbnailSize); + var resized = new Bitmap(scaled.Width, scaled.Height); using var graphics = Graphics.FromImage(resized); using var attributes = new ImageAttributes(); attributes.SetWrapMode(WrapMode.TileFlipXY); @@ -174,12 +169,12 @@ namespace SixLabors.ImageSharp.Benchmarks.LoadResizeSave using var encoderParams = new EncoderParameters(1); using var qualityParam = new EncoderParameter(Encoder.Quality, (long)Quality); encoderParams.Param[0] = qualityParam; - resized.Save(this.OutputPath(input, SystemDrawing), this.systemDrawingJpegCodec, encoderParams); + resized.Save(this.OutputPath(input), this.systemDrawingJpegCodec, encoderParams); } public void ImageSharpResize(string input) { - using FileStream output = File.Open(this.OutputPath(input, ImageSharp), FileMode.Create); + using FileStream output = File.Open(this.OutputPath(input), FileMode.Create); // Resize it to fit a 150x150 square using var image = ImageSharpImage.Load(input); @@ -187,7 +182,7 @@ namespace SixLabors.ImageSharp.Benchmarks.LoadResizeSave image.Mutate(i => i.Resize(new ResizeOptions { - Size = new ImageSharpSize(ThumbnailSize, ThumbnailSize), + Size = new ImageSharpSize(this.ThumbnailSize, this.ThumbnailSize), Mode = ResizeMode.Max })); @@ -204,7 +199,7 @@ namespace SixLabors.ImageSharp.Benchmarks.LoadResizeSave this.IncreaseTotalMegapixels(image.Width, image.Height); // Resize it to fit a 150x150 square - image.Resize(ThumbnailSize, ThumbnailSize); + image.Resize(this.ThumbnailSize, this.ThumbnailSize); // Reduce the size of the file image.Strip(); @@ -213,15 +208,15 @@ namespace SixLabors.ImageSharp.Benchmarks.LoadResizeSave image.Quality = Quality; // Save the results - image.Write(this.OutputPath(input, MagickNET)); + image.Write(this.OutputPath(input)); } public void MagicScalerResize(string input) { var settings = new ProcessImageSettings() { - Width = ThumbnailSize, - Height = ThumbnailSize, + Width = this.ThumbnailSize, + Height = this.ThumbnailSize, ResizeMode = CropScaleMode.Max, SaveFormat = FileFormat.Jpeg, JpegQuality = Quality, @@ -229,7 +224,7 @@ namespace SixLabors.ImageSharp.Benchmarks.LoadResizeSave }; // TODO: Is there a way to capture input dimensions for IncreaseTotalMegapixels? - using var output = new FileStream(this.OutputPath(input, MagicScaler), FileMode.Create); + using var output = new FileStream(this.OutputPath(input), FileMode.Create); MagicImageProcessor.ProcessImage(input, output, settings); } @@ -237,15 +232,15 @@ namespace SixLabors.ImageSharp.Benchmarks.LoadResizeSave { using var original = SKBitmap.Decode(input); this.IncreaseTotalMegapixels(original.Width, original.Height); - (int width, int height) scaled = this.ScaledSize(original.Width, original.Height, ThumbnailSize); - using var surface = SKSurface.Create(new SKImageInfo(scaled.width, scaled.height, original.ColorType, original.AlphaType)); + (int Width, int Height) scaled = this.ScaledSize(original.Width, original.Height, this.ThumbnailSize); + using var surface = SKSurface.Create(new SKImageInfo(scaled.Width, scaled.Height, original.ColorType, original.AlphaType)); using var paint = new SKPaint() { FilterQuality = SKFilterQuality.High }; SKCanvas canvas = surface.Canvas; - canvas.Scale((float)scaled.width / original.Width); + canvas.Scale((float)scaled.Width / original.Width); canvas.DrawBitmap(original, 0, 0, paint); canvas.Flush(); - using FileStream output = File.OpenWrite(this.OutputPath(input, SkiaSharpCanvas)); + using FileStream output = File.OpenWrite(this.OutputPath(input)); surface.Snapshot() .Encode(SKEncodedImageFormat.Jpeg, Quality) .SaveTo(output); @@ -255,15 +250,38 @@ namespace SixLabors.ImageSharp.Benchmarks.LoadResizeSave { using var original = SKBitmap.Decode(input); this.IncreaseTotalMegapixels(original.Width, original.Height); - (int width, int height) scaled = this.ScaledSize(original.Width, original.Height, ThumbnailSize); - using var resized = original.Resize(new SKImageInfo(scaled.width, scaled.height), SKFilterQuality.High); + (int Width, int Height) scaled = this.ScaledSize(original.Width, original.Height, this.ThumbnailSize); + using var resized = original.Resize(new SKImageInfo(scaled.Width, scaled.Height), SKFilterQuality.High); if (resized == null) { return; } using var image = SKImage.FromBitmap(resized); - using FileStream output = File.OpenWrite(this.OutputPath(input, SkiaSharpBitmap)); + using FileStream output = File.OpenWrite(this.OutputPath(input)); + image.Encode(SKEncodedImageFormat.Jpeg, Quality) + .SaveTo(output); + } + + public void SkiaBitmapDecodeToTargetSize(string input) + { + using var codec = SKCodec.Create(input); + + SKImageInfo info = codec.Info; + this.IncreaseTotalMegapixels(info.Width, info.Height); + (int Width, int Height) scaled = this.ScaledSize(info.Width, info.Height, this.ThumbnailSize); + SKSizeI supportedScale = codec.GetScaledDimensions((float)scaled.Width / info.Width); + + using var original = SKBitmap.Decode(codec, new SKImageInfo(supportedScale.Width, supportedScale.Height)); + using SKBitmap resized = original.Resize(new SKImageInfo(scaled.Width, scaled.Height), SKFilterQuality.High); + if (resized == null) + { + return; + } + + using var image = SKImage.FromBitmap(resized); + + using FileStream output = File.OpenWrite(this.OutputPath(input, nameof(this.SkiaBitmapDecodeToTargetSize))); image.Encode(SKEncodedImageFormat.Jpeg, Quality) .SaveTo(output); } @@ -271,10 +289,10 @@ namespace SixLabors.ImageSharp.Benchmarks.LoadResizeSave public void NetVipsResize(string input) { // Thumbnail to fit a 150x150 square - using var thumb = NetVipsImage.Thumbnail(input, ThumbnailSize, ThumbnailSize); + using var thumb = NetVipsImage.Thumbnail(input, this.ThumbnailSize, this.ThumbnailSize); // Save the results - thumb.Jpegsave(this.OutputPath(input, NetVips), q: Quality, strip: true); + thumb.Jpegsave(this.OutputPath(input), q: Quality, strip: true); } } } diff --git a/tests/ImageSharp.Benchmarks/Processing/Resize.cs b/tests/ImageSharp.Benchmarks/Processing/Resize.cs index 571c92cc8..81fdbfb31 100644 --- a/tests/ImageSharp.Benchmarks/Processing/Resize.cs +++ b/tests/ImageSharp.Benchmarks/Processing/Resize.cs @@ -215,4 +215,35 @@ namespace SixLabors.ImageSharp.Benchmarks // SystemDrawing | Core | Core | 3032 | 400 | 118.3 ms | 6.899 ms | 0.3781 ms | 1.00 | 0.00 | - | - | - | 96 B | // 'ImageSharp, MaxDegreeOfParallelism = 1' | Core | Core | 3032 | 400 | 122.4 ms | 15.069 ms | 0.8260 ms | 1.03 | 0.01 | - | - | - | 15712 B | } + + public class Resize_Bicubic_Compare_Rgba32_Rgb24 + { + private Resize_Bicubic_Rgb24 rgb24; + private Resize_Bicubic_Rgba32 rgba32; + + [GlobalSetup] + public void Setup() + { + this.rgb24 = new Resize_Bicubic_Rgb24(); + this.rgb24.Setup(); + this.rgba32 = new Resize_Bicubic_Rgba32(); + this.rgba32.Setup(); + } + + [GlobalCleanup] + public void Cleanup() + { + this.rgb24.Cleanup(); + this.rgba32.Cleanup(); + } + + [Benchmark] + public void SystemDrawing() => this.rgba32.SystemDrawing(); + + [Benchmark(Baseline = true)] + public void Rgba32() => this.rgba32.ImageSharp_P1(); + + [Benchmark] + public void Rgb24() => this.rgb24.ImageSharp_P1(); + } } diff --git a/tests/ImageSharp.Benchmarks/Program.cs b/tests/ImageSharp.Benchmarks/Program.cs index 8080825d9..f6ffa6f80 100644 --- a/tests/ImageSharp.Benchmarks/Program.cs +++ b/tests/ImageSharp.Benchmarks/Program.cs @@ -1,8 +1,6 @@ -// Copyright (c) Six Labors. +// Copyright (c) Six Labors. // Licensed under the Apache License, Version 2.0. -using System.Reflection; - using BenchmarkDotNet.Running; namespace SixLabors.ImageSharp.Benchmarks @@ -15,9 +13,8 @@ namespace SixLabors.ImageSharp.Benchmarks /// /// The arguments to pass to the program. /// - public static void Main(string[] args) - { - new BenchmarkSwitcher(typeof(Program).GetTypeInfo().Assembly).Run(args); - } + public static void Main(string[] args) => BenchmarkSwitcher + .FromAssembly(typeof(Program).Assembly) + .Run(args); } } diff --git a/tests/ImageSharp.Tests.ProfilingSandbox/ImageSharp.Tests.ProfilingSandbox.csproj b/tests/ImageSharp.Tests.ProfilingSandbox/ImageSharp.Tests.ProfilingSandbox.csproj index 10deb24c6..1a470fa31 100644 --- a/tests/ImageSharp.Tests.ProfilingSandbox/ImageSharp.Tests.ProfilingSandbox.csproj +++ b/tests/ImageSharp.Tests.ProfilingSandbox/ImageSharp.Tests.ProfilingSandbox.csproj @@ -14,10 +14,14 @@ false Debug;Release;Debug-InnerLoop;Release-InnerLoop false - 9 + + + net6.0;net5.0;netcoreapp3.1;netcoreapp2.1;net472 + + netcoreapp3.1 diff --git a/tests/ImageSharp.Tests.ProfilingSandbox/LoadResizeSaveParallelMemoryStress.cs b/tests/ImageSharp.Tests.ProfilingSandbox/LoadResizeSaveParallelMemoryStress.cs index 2aadf02eb..7fe91fe5f 100644 --- a/tests/ImageSharp.Tests.ProfilingSandbox/LoadResizeSaveParallelMemoryStress.cs +++ b/tests/ImageSharp.Tests.ProfilingSandbox/LoadResizeSaveParallelMemoryStress.cs @@ -1,4 +1,4 @@ -// Copyright (c) Six Labors. +// Copyright (c) Six Labors. // Licensed under the Apache License, Version 2.0. using System; @@ -18,7 +18,7 @@ namespace SixLabors.ImageSharp.Tests.ProfilingSandbox this.benchmarks = new LoadResizeSaveStressRunner() { // MaxDegreeOfParallelism = 10, - // Filter = JpegKind.Baseline + Filter = JpegKind.Baseline, }; this.benchmarks.Init(); } @@ -58,6 +58,7 @@ namespace SixLabors.ImageSharp.Tests.ProfilingSandbox lrs.SystemDrawingBenchmarkParallel(); break; case ConsoleKey.D2: + Console.WriteLine($"Images: {lrs.benchmarks.Images.Length}"); lrs.ImageSharpBenchmarkParallel(); break; case ConsoleKey.D3: @@ -120,7 +121,7 @@ namespace SixLabors.ImageSharp.Tests.ProfilingSandbox return bld.ToString(); - static string L(string header) => new ('-', header.Length); + static string L(string header) => new('-', header.Length); static string F(string column) => $"{{0,{column.Length}:f3}}"; } } diff --git a/tests/ImageSharp.Tests.ProfilingSandbox/Program.cs b/tests/ImageSharp.Tests.ProfilingSandbox/Program.cs index 9dd7e4c82..e6e82b981 100644 --- a/tests/ImageSharp.Tests.ProfilingSandbox/Program.cs +++ b/tests/ImageSharp.Tests.ProfilingSandbox/Program.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. using System; -using System.Diagnostics; using SixLabors.ImageSharp.Tests.Formats.Jpg; using SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations; using SixLabors.ImageSharp.Tests.ProfilingBenchmarks; diff --git a/tests/ImageSharp.Tests/Color/ColorTests.CastTo.cs b/tests/ImageSharp.Tests/Color/ColorTests.CastTo.cs index ee1820de7..3003265ca 100644 --- a/tests/ImageSharp.Tests/Color/ColorTests.CastTo.cs +++ b/tests/ImageSharp.Tests/Color/ColorTests.CastTo.cs @@ -66,7 +66,7 @@ namespace SixLabors.ImageSharp.Tests [Fact] public void Rgb24() { - var source = new Rgb24(1, 22, 231); + var source = new Rgb24(1, 22, 231); // Act: var color = new Color(source); @@ -79,7 +79,7 @@ namespace SixLabors.ImageSharp.Tests [Fact] public void Bgr24() { - var source = new Bgr24(1, 22, 231); + var source = new Bgr24(1, 22, 231); // Act: var color = new Color(source); @@ -88,6 +88,28 @@ namespace SixLabors.ImageSharp.Tests Bgr24 data = color; Assert.Equal(source, data); } + + [Fact] + public void GenericPixel() + { + AssertGenericPixel(new RgbaVector(float.Epsilon, 2 * float.Epsilon, float.MaxValue, float.MinValue)); + AssertGenericPixel(new Rgba64(1, 2, ushort.MaxValue, ushort.MaxValue - 1)); + AssertGenericPixel(new Rgb48(1, 2, ushort.MaxValue - 1)); + AssertGenericPixel(new La32(1, ushort.MaxValue - 1)); + AssertGenericPixel(new L16(ushort.MaxValue - 1)); + AssertGenericPixel(new Rgba32(1, 2, 255, 254)); + } + + private static void AssertGenericPixel(TPixel source) + where TPixel : unmanaged, IPixel + { + // Act: + var color = Color.FromPixel(source); + + // Assert: + TPixel actual = color.ToPixel(); + Assert.Equal(source, actual); + } } } } diff --git a/tests/ImageSharp.Tests/Common/ConstantsTests.cs b/tests/ImageSharp.Tests/Common/ConstantsTests.cs index 8180814cd..40a531413 100644 --- a/tests/ImageSharp.Tests/Common/ConstantsTests.cs +++ b/tests/ImageSharp.Tests/Common/ConstantsTests.cs @@ -13,4 +13,4 @@ namespace SixLabors.ImageSharp.Tests.Common Assert.Equal(0.001f, Constants.Epsilon); } } -} \ No newline at end of file +} diff --git a/tests/ImageSharp.Tests/Common/NumericsTests.cs b/tests/ImageSharp.Tests/Common/NumericsTests.cs index 29eae6d48..62819af49 100644 --- a/tests/ImageSharp.Tests/Common/NumericsTests.cs +++ b/tests/ImageSharp.Tests/Common/NumericsTests.cs @@ -34,7 +34,7 @@ namespace SixLabors.ImageSharp.Tests.Common int expected = 0; int actual = Numerics.Log2(value); - Assert.True(expected == actual, $"Expected: {expected}, Actual: {actual}"); + Assert.Equal(expected, actual); } [Fact] @@ -47,7 +47,7 @@ namespace SixLabors.ImageSharp.Tests.Common int expected = i; int actual = Numerics.Log2(value); - Assert.True(expected == actual, $"Expected: {expected}, Actual: {actual}"); + Assert.Equal(expected, actual); } } @@ -66,7 +66,35 @@ namespace SixLabors.ImageSharp.Tests.Common int expected = Log2_ReferenceImplementation(value); int actual = Numerics.Log2(value); - Assert.True(expected == actual, $"Expected: {expected}, Actual: {actual}"); + Assert.Equal(expected, actual); + } + } + + private static uint DivideCeil_ReferenceImplementation(uint value, uint divisor) => (uint)MathF.Ceiling((float)value / divisor); + + [Fact] + public void DivideCeil_DivideZero() + { + uint expected = 0; + uint actual = Numerics.DivideCeil(0, 100); + + Assert.Equal(expected, actual); + } + + [Theory] + [InlineData(1, 100)] + public void DivideCeil_RandomValues(int seed, int count) + { + var rng = new Random(seed); + for (int i = 0; i < count; i++) + { + uint value = (uint)rng.Next(); + uint divisor = (uint)rng.Next(); + + uint expected = DivideCeil_ReferenceImplementation(value, divisor); + uint actual = Numerics.DivideCeil(value, divisor); + + Assert.True(expected == actual, $"Expected: {expected}\nActual: {actual}\n{value} / {divisor} = {expected}"); } } } diff --git a/tests/ImageSharp.Tests/Common/SimdUtilsTests.cs b/tests/ImageSharp.Tests/Common/SimdUtilsTests.cs index 1f680aa6c..f61e2dc8e 100644 --- a/tests/ImageSharp.Tests/Common/SimdUtilsTests.cs +++ b/tests/ImageSharp.Tests/Common/SimdUtilsTests.cs @@ -19,10 +19,7 @@ namespace SixLabors.ImageSharp.Tests.Common { private ITestOutputHelper Output { get; } - public SimdUtilsTests(ITestOutputHelper output) - { - this.Output = output; - } + public SimdUtilsTests(ITestOutputHelper output) => this.Output = output; private static int R(float f) => (int)Math.Round(f, MidpointRounding.AwayFromZero); @@ -63,7 +60,7 @@ namespace SixLabors.ImageSharp.Tests.Common private static Vector CreateRandomTestVector(int seed, float min, float max) { - var data = new float[Vector.Count]; + float[] data = new float[Vector.Count]; var rnd = new Random(seed); @@ -154,7 +151,7 @@ namespace SixLabors.ImageSharp.Tests.Common float[] source = new Random(seed).GenerateRandomFloatArray(count, 0, 1f); - var dest = new byte[count]; + byte[] dest = new byte[count]; SimdUtils.BasicIntrinsics256.BulkConvertNormalizedFloatToByte(source, dest); @@ -163,25 +160,18 @@ namespace SixLabors.ImageSharp.Tests.Common Assert.Equal(expected, dest); } - public static readonly TheoryData ArraySizesDivisibleBy8 = new TheoryData { 0, 8, 16, 1024 }; - public static readonly TheoryData ArraySizesDivisibleBy4 = new TheoryData { 0, 4, 8, 28, 1020 }; - public static readonly TheoryData ArraySizesDivisibleBy3 = new TheoryData { 0, 3, 9, 36, 957 }; - public static readonly TheoryData ArraySizesDivisibleBy32 = new TheoryData { 0, 32, 512 }; + public static readonly TheoryData ArraySizesDivisibleBy8 = new() { 0, 8, 16, 1024 }; + public static readonly TheoryData ArraySizesDivisibleBy4 = new() { 0, 4, 8, 28, 1020 }; + public static readonly TheoryData ArraySizesDivisibleBy3 = new() { 0, 3, 9, 36, 957 }; + public static readonly TheoryData ArraySizesDivisibleBy32 = new() { 0, 32, 512 }; - public static readonly TheoryData ArbitraryArraySizes = - new TheoryData - { - 0, 1, 2, 3, 4, 7, 8, 9, 15, 16, 17, 63, 64, 255, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, - }; + public static readonly TheoryData ArbitraryArraySizes = new() { 0, 1, 2, 3, 4, 7, 8, 9, 15, 16, 17, 63, 64, 255, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520 }; [Theory] [MemberData(nameof(ArraySizesDivisibleBy4))] - public void FallbackIntrinsics128_BulkConvertByteToNormalizedFloat(int count) - { - TestImpl_BulkConvertByteToNormalizedFloat( + public void FallbackIntrinsics128_BulkConvertByteToNormalizedFloat(int count) => TestImpl_BulkConvertByteToNormalizedFloat( count, (s, d) => SimdUtils.FallbackIntrinsics128.ByteToNormalizedFloat(s.Span, d.Span)); - } [Theory] [MemberData(nameof(ArraySizesDivisibleBy8))] @@ -199,24 +189,23 @@ namespace SixLabors.ImageSharp.Tests.Common [Theory] [MemberData(nameof(ArraySizesDivisibleBy32))] - public void ExtendedIntrinsics_BulkConvertByteToNormalizedFloat(int count) - { - TestImpl_BulkConvertByteToNormalizedFloat( + public void ExtendedIntrinsics_BulkConvertByteToNormalizedFloat(int count) => TestImpl_BulkConvertByteToNormalizedFloat( count, (s, d) => SimdUtils.ExtendedIntrinsics.ByteToNormalizedFloat(s.Span, d.Span)); - } #if SUPPORTS_RUNTIME_INTRINSICS [Theory] [MemberData(nameof(ArraySizesDivisibleBy32))] public void HwIntrinsics_BulkConvertByteToNormalizedFloat(int count) { - static void RunTest(string serialized) + if (!Sse2.IsSupported) { - TestImpl_BulkConvertByteToNormalizedFloat( + return; + } + + static void RunTest(string serialized) => TestImpl_BulkConvertByteToNormalizedFloat( FeatureTestRunner.Deserialize(serialized), (s, d) => SimdUtils.HwIntrinsics.ByteToNormalizedFloat(s.Span, d.Span)); - } FeatureTestRunner.RunWithHwIntrinsicsFeature( RunTest, @@ -227,20 +216,17 @@ namespace SixLabors.ImageSharp.Tests.Common [Theory] [MemberData(nameof(ArbitraryArraySizes))] - public void BulkConvertByteToNormalizedFloat(int count) - { - TestImpl_BulkConvertByteToNormalizedFloat( + public void BulkConvertByteToNormalizedFloat(int count) => TestImpl_BulkConvertByteToNormalizedFloat( count, (s, d) => SimdUtils.ByteToNormalizedFloat(s.Span, d.Span)); - } private static void TestImpl_BulkConvertByteToNormalizedFloat( int count, Action, Memory> convert) { byte[] source = new Random(count).GenerateRandomByteArray(count); - var result = new float[count]; - float[] expected = source.Select(b => (float)b / 255f).ToArray(); + float[] result = new float[count]; + float[] expected = source.Select(b => b / 255f).ToArray(); convert(source, result); @@ -249,12 +235,9 @@ namespace SixLabors.ImageSharp.Tests.Common [Theory] [MemberData(nameof(ArraySizesDivisibleBy4))] - public void FallbackIntrinsics128_BulkConvertNormalizedFloatToByteClampOverflows(int count) - { - TestImpl_BulkConvertNormalizedFloatToByteClampOverflows( + public void FallbackIntrinsics128_BulkConvertNormalizedFloatToByteClampOverflows(int count) => TestImpl_BulkConvertNormalizedFloatToByteClampOverflows( count, (s, d) => SimdUtils.FallbackIntrinsics128.NormalizedFloatToByteSaturate(s.Span, d.Span)); - } [Theory] [MemberData(nameof(ArraySizesDivisibleBy8))] @@ -270,12 +253,9 @@ namespace SixLabors.ImageSharp.Tests.Common [Theory] [MemberData(nameof(ArraySizesDivisibleBy32))] - public void ExtendedIntrinsics_BulkConvertNormalizedFloatToByteClampOverflows(int count) - { - TestImpl_BulkConvertNormalizedFloatToByteClampOverflows( + public void ExtendedIntrinsics_BulkConvertNormalizedFloatToByteClampOverflows(int count) => TestImpl_BulkConvertNormalizedFloatToByteClampOverflows( count, (s, d) => SimdUtils.ExtendedIntrinsics.NormalizedFloatToByteSaturate(s.Span, d.Span)); - } [Theory] [InlineData(1234)] @@ -304,12 +284,14 @@ namespace SixLabors.ImageSharp.Tests.Common [MemberData(nameof(ArraySizesDivisibleBy32))] public void HwIntrinsics_BulkConvertNormalizedFloatToByteClampOverflows(int count) { - static void RunTest(string serialized) + if (!Sse2.IsSupported) { - TestImpl_BulkConvertNormalizedFloatToByteClampOverflows( + return; + } + + static void RunTest(string serialized) => TestImpl_BulkConvertNormalizedFloatToByteClampOverflows( FeatureTestRunner.Deserialize(serialized), (s, d) => SimdUtils.HwIntrinsics.NormalizedFloatToByteSaturate(s.Span, d.Span)); - } FeatureTestRunner.RunWithHwIntrinsicsFeature( RunTest, @@ -326,7 +308,7 @@ namespace SixLabors.ImageSharp.Tests.Common TestImpl_BulkConvertNormalizedFloatToByteClampOverflows(count, (s, d) => SimdUtils.NormalizedFloatToByteSaturate(s.Span, d.Span)); // For small values, let's stress test the implementation a bit: - if (count > 0 && count < 10) + if (count is > 0 and < 10) { for (int i = 0; i < 20; i++) { @@ -340,23 +322,17 @@ namespace SixLabors.ImageSharp.Tests.Common [Theory] [MemberData(nameof(ArbitraryArraySizes))] - public void PackFromRgbPlanes_Rgb24(int count) - { - TestPackFromRgbPlanes( + public void PackFromRgbPlanes_Rgb24(int count) => TestPackFromRgbPlanes( count, (r, g, b, actual) => SimdUtils.PackFromRgbPlanes(Configuration.Default, r, g, b, actual)); - } [Theory] [MemberData(nameof(ArbitraryArraySizes))] - public void PackFromRgbPlanes_Rgba32(int count) - { - TestPackFromRgbPlanes( + public void PackFromRgbPlanes_Rgba32(int count) => TestPackFromRgbPlanes( count, (r, g, b, actual) => SimdUtils.PackFromRgbPlanes(Configuration.Default, r, g, b, actual)); - } #if SUPPORTS_RUNTIME_INTRINSICS [Fact] @@ -371,7 +347,7 @@ namespace SixLabors.ImageSharp.Tests.Common byte[] g = Enumerable.Range(100, 32).Select(x => (byte)x).ToArray(); byte[] b = Enumerable.Range(200, 32).Select(x => (byte)x).ToArray(); const int padding = 4; - Rgb24[] d = new Rgb24[32 + padding]; + var d = new Rgb24[32 + padding]; ReadOnlySpan rr = r.AsSpan(); ReadOnlySpan gg = g.AsSpan(); @@ -405,7 +381,7 @@ namespace SixLabors.ImageSharp.Tests.Common byte[] g = Enumerable.Range(100, 32).Select(x => (byte)x).ToArray(); byte[] b = Enumerable.Range(200, 32).Select(x => (byte)x).ToArray(); - Rgba32[] d = new Rgba32[32]; + var d = new Rgba32[32]; ReadOnlySpan rr = r.AsSpan(); ReadOnlySpan gg = g.AsSpan(); @@ -432,18 +408,18 @@ namespace SixLabors.ImageSharp.Tests.Common internal static void TestPackFromRgbPlanes(int count, Action packMethod) where TPixel : unmanaged, IPixel { - Random rnd = new Random(42); + var rnd = new Random(42); byte[] r = rnd.GenerateRandomByteArray(count); byte[] g = rnd.GenerateRandomByteArray(count); byte[] b = rnd.GenerateRandomByteArray(count); - TPixel[] expected = new TPixel[count]; + var expected = new TPixel[count]; for (int i = 0; i < count; i++) { expected[i].FromRgb24(new Rgb24(r[i], g[i], b[i])); } - TPixel[] actual = new TPixel[count + 3]; // padding for Rgb24 AVX2 + var actual = new TPixel[count + 3]; // padding for Rgb24 AVX2 packMethod(r, g, b, actual); Assert.True(expected.AsSpan().SequenceEqual(actual.AsSpan().Slice(0, count))); diff --git a/tests/ImageSharp.Tests/ConfigurationTests.cs b/tests/ImageSharp.Tests/ConfigurationTests.cs index 3ad8ef2f8..803babdfa 100644 --- a/tests/ImageSharp.Tests/ConfigurationTests.cs +++ b/tests/ImageSharp.Tests/ConfigurationTests.cs @@ -21,7 +21,7 @@ namespace SixLabors.ImageSharp.Tests public Configuration DefaultConfiguration { get; } - private readonly int expectedDefaultConfigurationCount = 6; + private readonly int expectedDefaultConfigurationCount = 7; public ConfigurationTests() { diff --git a/tests/ImageSharp.Tests/Formats/Bmp/BmpDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Bmp/BmpDecoderTests.cs index e64d8452f..4e6dc36dc 100644 --- a/tests/ImageSharp.Tests/Formats/Bmp/BmpDecoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Bmp/BmpDecoderTests.cs @@ -14,7 +14,6 @@ using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison; using SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs; using Xunit; - using static SixLabors.ImageSharp.Tests.TestImages.Bmp; // ReSharper disable InconsistentNaming @@ -55,7 +54,8 @@ namespace SixLabors.ImageSharp.Tests.Formats.Bmp } [Theory] - [WithFileCollection(nameof(MiscBmpFiles), PixelTypes.Rgba32)] + [WithFile(Car, PixelTypes.Rgba32)] + [WithFile(F, PixelTypes.Rgba32)] public void BmpDecoder_CanDecode_MiscellaneousBitmaps_WithLimitedAllocatorBufferCapacity( TestImageProvider provider) { diff --git a/tests/ImageSharp.Tests/Formats/Bmp/BmpEncoderTests.cs b/tests/ImageSharp.Tests/Formats/Bmp/BmpEncoderTests.cs index f338c1aff..d645f0b60 100644 --- a/tests/ImageSharp.Tests/Formats/Bmp/BmpEncoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Bmp/BmpEncoderTests.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. using System.IO; - using SixLabors.ImageSharp.Formats; using SixLabors.ImageSharp.Formats.Bmp; using SixLabors.ImageSharp.Metadata; @@ -13,7 +12,6 @@ using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison; using SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs; using Xunit; - using static SixLabors.ImageSharp.Tests.TestImages.Bmp; // ReSharper disable InconsistentNaming diff --git a/tests/ImageSharp.Tests/Formats/Bmp/BmpMetadataTests.cs b/tests/ImageSharp.Tests/Formats/Bmp/BmpMetadataTests.cs index ea5e8b087..8931c242e 100644 --- a/tests/ImageSharp.Tests/Formats/Bmp/BmpMetadataTests.cs +++ b/tests/ImageSharp.Tests/Formats/Bmp/BmpMetadataTests.cs @@ -2,11 +2,9 @@ // Licensed under the Apache License, Version 2.0. using System.IO; - using SixLabors.ImageSharp.Formats.Bmp; using Xunit; - using static SixLabors.ImageSharp.Tests.TestImages.Bmp; // ReSharper disable InconsistentNaming diff --git a/tests/ImageSharp.Tests/Formats/GeneralFormatTests.cs b/tests/ImageSharp.Tests/Formats/GeneralFormatTests.cs index c0843a51b..bf13a9097 100644 --- a/tests/ImageSharp.Tests/Formats/GeneralFormatTests.cs +++ b/tests/ImageSharp.Tests/Formats/GeneralFormatTests.cs @@ -16,6 +16,7 @@ using Xunit; namespace SixLabors.ImageSharp.Tests.Formats { + [Collection("RunSerial")] public class GeneralFormatTests { /// @@ -152,7 +153,7 @@ namespace SixLabors.ImageSharp.Tests.Formats using (FileStream output = File.OpenWrite(Path.Combine(path, $"{file.FileNameWithoutExtension}.tiff"))) { - image.SaveAsTga(output); + image.SaveAsTiff(output); } } } diff --git a/tests/ImageSharp.Tests/Formats/Gif/GifEncoderTests.cs b/tests/ImageSharp.Tests/Formats/Gif/GifEncoderTests.cs index bd24e1a8d..cb0b1521d 100644 --- a/tests/ImageSharp.Tests/Formats/Gif/GifEncoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Gif/GifEncoderTests.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. using System.IO; - using SixLabors.ImageSharp.Formats.Gif; using SixLabors.ImageSharp.Metadata; using SixLabors.ImageSharp.PixelFormats; diff --git a/tests/ImageSharp.Tests/Formats/Gif/GifMetadataTests.cs b/tests/ImageSharp.Tests/Formats/Gif/GifMetadataTests.cs index e209586f5..59f7ebb74 100644 --- a/tests/ImageSharp.Tests/Formats/Gif/GifMetadataTests.cs +++ b/tests/ImageSharp.Tests/Formats/Gif/GifMetadataTests.cs @@ -4,7 +4,6 @@ using System.Collections.Generic; using System.IO; using System.Linq; - using SixLabors.ImageSharp.Formats.Gif; using SixLabors.ImageSharp.Metadata; using SixLabors.ImageSharp.PixelFormats; @@ -13,6 +12,7 @@ using Xunit; namespace SixLabors.ImageSharp.Tests.Formats.Gif { + [Collection("RunSerial")] [Trait("Format", "Gif")] public class GifMetadataTests { diff --git a/tests/ImageSharp.Tests/Formats/ImageFormatManagerTests.cs b/tests/ImageSharp.Tests/Formats/ImageFormatManagerTests.cs index 1e00bfff8..5cd70b100 100644 --- a/tests/ImageSharp.Tests/Formats/ImageFormatManagerTests.cs +++ b/tests/ImageSharp.Tests/Formats/ImageFormatManagerTests.cs @@ -12,6 +12,7 @@ using SixLabors.ImageSharp.Formats.Jpeg; using SixLabors.ImageSharp.Formats.Png; using SixLabors.ImageSharp.Formats.Tga; using SixLabors.ImageSharp.Formats.Tiff; +using SixLabors.ImageSharp.Formats.Webp; using SixLabors.ImageSharp.PixelFormats; using Xunit; @@ -38,6 +39,7 @@ namespace SixLabors.ImageSharp.Tests.Formats Assert.Equal(1, this.DefaultFormatsManager.ImageEncoders.Select(item => item.Value).OfType().Count()); Assert.Equal(1, this.DefaultFormatsManager.ImageEncoders.Select(item => item.Value).OfType().Count()); Assert.Equal(1, this.DefaultFormatsManager.ImageEncoders.Select(item => item.Value).OfType().Count()); + Assert.Equal(1, this.DefaultFormatsManager.ImageEncoders.Select(item => item.Value).OfType().Count()); Assert.Equal(1, this.DefaultFormatsManager.ImageDecoders.Select(item => item.Value).OfType().Count()); Assert.Equal(1, this.DefaultFormatsManager.ImageDecoders.Select(item => item.Value).OfType().Count()); @@ -45,6 +47,7 @@ namespace SixLabors.ImageSharp.Tests.Formats Assert.Equal(1, this.DefaultFormatsManager.ImageDecoders.Select(item => item.Value).OfType().Count()); Assert.Equal(1, this.DefaultFormatsManager.ImageDecoders.Select(item => item.Value).OfType().Count()); Assert.Equal(1, this.DefaultFormatsManager.ImageDecoders.Select(item => item.Value).OfType().Count()); + Assert.Equal(1, this.DefaultFormatsManager.ImageDecoders.Select(item => item.Value).OfType().Count()); } [Fact] diff --git a/tests/ImageSharp.Tests/Formats/Jpg/Block8x8FTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/Block8x8FTests.cs index 4effc52b2..e5dc0ba01 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/Block8x8FTests.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/Block8x8FTests.cs @@ -4,8 +4,9 @@ // Uncomment this to turn unit tests into benchmarks: // #define BENCHMARKING using System; -using System.Diagnostics; - +#if SUPPORTS_RUNTIME_INTRINSICS +using System.Runtime.Intrinsics.X86; +#endif using SixLabors.ImageSharp.Formats.Jpeg.Components; using SixLabors.ImageSharp.Tests.Formats.Jpg.Utils; using SixLabors.ImageSharp.Tests.TestUtilities; @@ -164,52 +165,27 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg } [Fact] - public void TransposeInto() + public void TransposeInplace() { static void RunTest() { float[] expected = Create8x8FloatData(); ReferenceImplementations.Transpose8x8(expected); - var source = default(Block8x8F); - source.LoadFrom(Create8x8FloatData()); + var block8x8 = default(Block8x8F); + block8x8.LoadFrom(Create8x8FloatData()); - var dest = default(Block8x8F); - source.TransposeInto(ref dest); + block8x8.TransposeInplace(); float[] actual = new float[64]; - dest.ScaledCopyTo(actual); + block8x8.ScaledCopyTo(actual); Assert.Equal(expected, actual); } FeatureTestRunner.RunWithHwIntrinsicsFeature( RunTest, - HwIntrinsics.AllowAll | HwIntrinsics.DisableAVX); - } - - private class BufferHolder - { - public Block8x8F Buffer; - } - - [Fact] - public void TransposeInto_Benchmark() - { - var source = new BufferHolder(); - source.Buffer.LoadFrom(Create8x8FloatData()); - var dest = new BufferHolder(); - - this.Output.WriteLine($"TransposeInto_PinningImpl_Benchmark X {Times} ..."); - var sw = Stopwatch.StartNew(); - - for (int i = 0; i < Times; i++) - { - source.Buffer.TransposeInto(ref dest.Buffer); - } - - sw.Stop(); - this.Output.WriteLine($"TransposeInto_PinningImpl_Benchmark finished in {sw.ElapsedMilliseconds} ms"); + HwIntrinsics.AllowAll | HwIntrinsics.DisableAVX | HwIntrinsics.DisableHWIntrinsic); } private static float[] Create8x8ColorCropTestData() @@ -273,32 +249,44 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg } [Theory] - [InlineData(1)] - [InlineData(2)] - public unsafe void Quantize(int seed) + [InlineData(1, 2)] + [InlineData(2, 1)] + public void Quantize(int srcSeed, int qtSeed) { - var block = default(Block8x8F); - block.LoadFrom(Create8x8RoundedRandomFloatData(-2000, 2000, seed)); - - var qt = default(Block8x8F); - qt.LoadFrom(Create8x8RoundedRandomFloatData(-2000, 2000, seed)); + static void RunTest(string srcSeedSerialized, string qtSeedSerialized) + { + int srcSeed = FeatureTestRunner.Deserialize(srcSeedSerialized); + int qtSeed = FeatureTestRunner.Deserialize(qtSeedSerialized); - var unzig = ZigZag.CreateUnzigTable(); + Block8x8F source = CreateRandomFloatBlock(-2000, 2000, srcSeed); - int* expectedResults = stackalloc int[Block8x8F.Size]; - ReferenceImplementations.QuantizeRational(&block, expectedResults, &qt, unzig.Data); + // Quantization code is used only in jpeg where it's guaranteed that + // qunatization valus are greater than 1 + // Quantize method supports negative numbers by very small numbers can cause troubles + Block8x8F quant = CreateRandomFloatBlock(1, 2000, qtSeed); - var actualResults = default(Block8x8F); + // Reference implementation quantizes given block via division + Block8x8 expected = default; + ReferenceImplementations.Quantize(ref source, ref expected, ref quant, ZigZag.ZigZagOrder); - Block8x8F.Quantize(ref block, ref actualResults, ref qt, ref unzig); + // Actual current implementation quantizes given block via multiplication + // With quantization table reciprocal + for (int i = 0; i < Block8x8F.Size; i++) + { + quant[i] = 1f / quant[i]; + } - for (int i = 0; i < Block8x8F.Size; i++) - { - int expected = expectedResults[i]; - int actual = (int)actualResults[i]; + Block8x8 actual = default; + Block8x8F.Quantize(ref source, ref actual, ref quant); - Assert.Equal(expected, actual); + Assert.True(CompareBlocks(expected, actual, 1, out int diff), $"Blocks are not equal, diff={diff}"); } + + FeatureTestRunner.RunWithHwIntrinsicsFeature( + RunTest, + srcSeed, + qtSeed, + HwIntrinsics.AllowAll | HwIntrinsics.DisableAVX | HwIntrinsics.DisableSSE); } [Fact] @@ -368,48 +356,6 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg HwIntrinsics.AllowAll | HwIntrinsics.DisableAVX); } - [Theory] - [InlineData(1)] - [InlineData(2)] - [InlineData(3)] - public unsafe void DequantizeBlock(int seed) - { - Block8x8F original = CreateRandomFloatBlock(-500, 500, seed); - Block8x8F qt = CreateRandomFloatBlock(0, 10, seed + 42); - - var unzig = ZigZag.CreateUnzigTable(); - - Block8x8F expected = original; - Block8x8F actual = original; - - ReferenceImplementations.DequantizeBlock(&expected, &qt, unzig.Data); - Block8x8F.DequantizeBlock(&actual, &qt, unzig.Data); - - this.CompareBlocks(expected, actual, 0); - } - - [Theory] - [InlineData(1)] - [InlineData(2)] - [InlineData(3)] - public unsafe void ZigZag_CreateDequantizationTable_MultiplicationShouldQuantize(int seed) - { - Block8x8F original = CreateRandomFloatBlock(-500, 500, seed); - Block8x8F qt = CreateRandomFloatBlock(0, 10, seed + 42); - - var unzig = ZigZag.CreateUnzigTable(); - Block8x8F zigQt = ZigZag.CreateDequantizationTable(ref qt); - - Block8x8F expected = original; - Block8x8F actual = original; - - ReferenceImplementations.DequantizeBlock(&expected, &qt, unzig.Data); - - actual.MultiplyInPlace(ref zigQt); - - this.CompareBlocks(expected, actual, 0); - } - [Fact] public void AddToAllInPlace() { @@ -462,7 +408,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg short[] data = Create8x8ShortData(); - var source = new Block8x8(data); + var source = Block8x8.Load(data); Block8x8F dest = default; dest.LoadFromInt16Scalar(ref source); @@ -483,7 +429,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg short[] data = Create8x8ShortData(); - var source = new Block8x8(data); + var source = Block8x8.Load(data); Block8x8F dest = default; dest.LoadFromInt16ExtendedAvx2(ref source); @@ -493,5 +439,96 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg Assert.Equal(data[i], dest[i]); } } + + [Fact] + public void EqualsToScalar_AllOne() + { + static void RunTest() + { + // Fill matrix with valid value + Block8x8F block = default; + for (int i = 0; i < Block8x8F.Size; i++) + { + block[i] = 1; + } + + bool isEqual = block.EqualsToScalar(1); + Assert.True(isEqual); + } + + // 2 paths: + // 1. DisableFMA - call avx implementation + // 3. DisableAvx2 - call fallback code of float implementation + FeatureTestRunner.RunWithHwIntrinsicsFeature( + RunTest, + HwIntrinsics.AllowAll | HwIntrinsics.DisableAVX2); + } + + [Theory] + [InlineData(10)] + public void EqualsToScalar_OneOffEachPosition(int equalsTo) + { + static void RunTest(string serializedEqualsTo) + { + int equalsTo = FeatureTestRunner.Deserialize(serializedEqualsTo); + int offValue = 0; + + // Fill matrix with valid value + Block8x8F block = default; + for (int i = 0; i < Block8x8F.Size; i++) + { + block[i] = equalsTo; + } + + // Assert with invalid values at different positions + for (int i = 0; i < Block8x8F.Size; i++) + { + block[i] = offValue; + + bool isEqual = block.EqualsToScalar(equalsTo); + Assert.False(isEqual, $"False equality:\n{block}"); + + // restore valid value for next iteration assertion + block[i] = equalsTo; + } + } + + // 2 paths: + // 1. DisableFMA - call avx implementation + // 3. DisableAvx2 - call fallback code of float implementation + FeatureTestRunner.RunWithHwIntrinsicsFeature( + RunTest, + equalsTo, + HwIntrinsics.AllowAll | HwIntrinsics.DisableAVX2); + } + + [Theory] + [InlineData(39)] + public void EqualsToScalar_Valid(int equalsTo) + { + static void RunTest(string serializedEqualsTo) + { + int equalsTo = FeatureTestRunner.Deserialize(serializedEqualsTo); + + // Fill matrix with valid value + Block8x8F block = default; + for (int i = 0; i < Block8x8F.Size; i++) + { + block[i] = equalsTo; + } + + // Assert + bool isEqual = block.EqualsToScalar(equalsTo); + Assert.True(isEqual); + } + + // 2 paths: + // 1. DisableFMA - call avx implementation + // 3. DisableAvx2 - call fallback code of float implementation + FeatureTestRunner.RunWithHwIntrinsicsFeature( + RunTest, + equalsTo, + HwIntrinsics.AllowAll | HwIntrinsics.DisableAVX2); + } } } diff --git a/tests/ImageSharp.Tests/Formats/Jpg/Block8x8Tests.cs b/tests/ImageSharp.Tests/Formats/Jpg/Block8x8Tests.cs index 9195f0915..3737cce80 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/Block8x8Tests.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/Block8x8Tests.cs @@ -1,9 +1,10 @@ // Copyright (c) Six Labors. // Licensed under the Apache License, Version 2.0. +using System; using SixLabors.ImageSharp.Formats.Jpeg.Components; using SixLabors.ImageSharp.Tests.Formats.Jpg.Utils; - +using SixLabors.ImageSharp.Tests.TestUtilities; using Xunit; using Xunit.Abstractions; @@ -22,7 +23,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg { short[] data = Create8x8ShortData(); - var block = new Block8x8(data); + var block = Block8x8.Load(data); for (int i = 0; i < Block8x8.Size; i++) { @@ -43,32 +44,12 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg Assert.Equal(42, block[42]); } - [Fact] - public unsafe void Indexer_GetScalarAt_SetScalarAt() - { - int sum; - var block = default(Block8x8); - - for (int i = 0; i < Block8x8.Size; i++) - { - Block8x8.SetScalarAt(&block, i, (short)i); - } - - sum = 0; - for (int i = 0; i < Block8x8.Size; i++) - { - sum += Block8x8.GetScalarAt(&block, i); - } - - Assert.Equal(sum, 64 * 63 / 2); - } - [Fact] public void AsFloatBlock() { short[] data = Create8x8ShortData(); - var source = new Block8x8(data); + var source = Block8x8.Load(data); Block8x8F dest = source.AsFloatBlock(); @@ -82,7 +63,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg public void ToArray() { short[] data = Create8x8ShortData(); - var block = new Block8x8(data); + var block = Block8x8.Load(data); short[] result = block.ToArray(); @@ -93,8 +74,8 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg public void Equality_WhenTrue() { short[] data = Create8x8ShortData(); - var block1 = new Block8x8(data); - var block2 = new Block8x8(data); + var block1 = Block8x8.Load(data); + var block2 = Block8x8.Load(data); block1[0] = 42; block2[0] = 42; @@ -107,8 +88,8 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg public void Equality_WhenFalse() { short[] data = Create8x8ShortData(); - var block1 = new Block8x8(data); - var block2 = new Block8x8(data); + var block1 = Block8x8.Load(data); + var block2 = Block8x8.Load(data); block1[0] = 42; block2[0] = 666; @@ -131,8 +112,8 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg public void TotalDifference() { short[] data = Create8x8ShortData(); - var block1 = new Block8x8(data); - var block2 = new Block8x8(data); + var block1 = Block8x8.Load(data); + var block2 = Block8x8.Load(data); block2[10] += 7; block2[63] += 8; @@ -141,5 +122,159 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg Assert.Equal(15, d); } + + [Fact] + public void GetLastNonZeroIndex_AllZero() + { + static void RunTest() + { + Block8x8 data = default; + + nint expected = -1; + + nint actual = data.GetLastNonZeroIndex(); + + Assert.Equal(expected, actual); + } + + FeatureTestRunner.RunWithHwIntrinsicsFeature( + RunTest, + HwIntrinsics.AllowAll | HwIntrinsics.DisableAVX2); + } + + [Fact] + public void GetLastNonZeroIndex_AllNonZero() + { + static void RunTest() + { + Block8x8 data = default; + for (int i = 0; i < Block8x8.Size; i++) + { + data[i] = 10; + } + + nint expected = Block8x8.Size - 1; + + nint actual = data.GetLastNonZeroIndex(); + + Assert.Equal(expected, actual); + } + + FeatureTestRunner.RunWithHwIntrinsicsFeature( + RunTest, + HwIntrinsics.AllowAll | HwIntrinsics.DisableAVX2); + } + + [Theory] + [InlineData(1)] + [InlineData(2)] + public void GetLastNonZeroIndex_RandomFilledSingle(int seed) + { + static void RunTest(string seedSerialized) + { + int seed = FeatureTestRunner.Deserialize(seedSerialized); + var rng = new Random(seed); + + for (int i = 0; i < 1000; i++) + { + Block8x8 data = default; + + int setIndex = rng.Next(1, Block8x8.Size); + data[setIndex] = (short)rng.Next(-2000, 2000); + + nint expected = setIndex; + + nint actual = data.GetLastNonZeroIndex(); + + Assert.Equal(expected, actual); + } + } + + FeatureTestRunner.RunWithHwIntrinsicsFeature( + RunTest, + seed, + HwIntrinsics.AllowAll | HwIntrinsics.DisableAVX2); + } + + [Theory] + [InlineData(1)] + [InlineData(2)] + public void GetLastNonZeroIndex_RandomFilledPartially(int seed) + { + static void RunTest(string seedSerialized) + { + int seed = FeatureTestRunner.Deserialize(seedSerialized); + var rng = new Random(seed); + + for (int i = 0; i < 1000; i++) + { + Block8x8 data = default; + + int lastIndex = rng.Next(1, Block8x8.Size); + short fillValue = (short)rng.Next(-2000, 2000); + for (int dataIndex = 0; dataIndex <= lastIndex; dataIndex++) + { + data[dataIndex] = fillValue; + } + + int expected = lastIndex; + + nint actual = data.GetLastNonZeroIndex(); + + Assert.Equal(expected, actual); + } + } + + FeatureTestRunner.RunWithHwIntrinsicsFeature( + RunTest, + seed, + HwIntrinsics.AllowAll | HwIntrinsics.DisableAVX2); + } + + [Theory] + [InlineData(1)] + [InlineData(2)] + public void GetLastNonZeroIndex_RandomFilledFragmented(int seed) + { + static void RunTest(string seedSerialized) + { + int seed = FeatureTestRunner.Deserialize(seedSerialized); + var rng = new Random(seed); + + for (int i = 0; i < 1000; i++) + { + Block8x8 data = default; + + short fillValue = (short)rng.Next(-2000, 2000); + + // first filled chunk + int firstChunkStart = rng.Next(0, Block8x8.Size / 2); + int firstChunkEnd = rng.Next(firstChunkStart, Block8x8.Size / 2); + for (int dataIdx = firstChunkStart; dataIdx <= firstChunkEnd; dataIdx++) + { + data[dataIdx] = fillValue; + } + + // second filled chunk, there might be a spot with zero(s) between first and second chunk + int secondChunkStart = rng.Next(firstChunkEnd, Block8x8.Size); + int secondChunkEnd = rng.Next(secondChunkStart, Block8x8.Size); + for (int dataIdx = secondChunkStart; dataIdx <= secondChunkEnd; dataIdx++) + { + data[dataIdx] = fillValue; + } + + int expected = secondChunkEnd; + + nint actual = data.GetLastNonZeroIndex(); + + Assert.True(expected == actual, $"Expected: {expected}\nActual: {actual}\nInput matrix: {data}"); + } + } + + FeatureTestRunner.RunWithHwIntrinsicsFeature( + RunTest, + seed, + HwIntrinsics.AllowAll | HwIntrinsics.DisableAVX2); + } } } diff --git a/tests/ImageSharp.Tests/Formats/Jpg/DCTTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/DCTTests.cs index d49a6498c..0a49d20cd 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/DCTTests.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/DCTTests.cs @@ -33,15 +33,14 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg { float[] sourceArray = Create8x8RoundedRandomFloatData(-1000, 1000, seed); - var source = Block8x8F.Load(sourceArray); + var srcBlock = Block8x8F.Load(sourceArray); - Block8x8F expected = ReferenceImplementations.LLM_FloatingPoint_DCT.TransformIDCT(ref source); + Block8x8F expected = ReferenceImplementations.LLM_FloatingPoint_DCT.TransformIDCT(ref srcBlock); var temp = default(Block8x8F); - var actual = default(Block8x8F); - FastFloatingPointDCT.TransformIDCT(ref source, ref actual, ref temp); + FastFloatingPointDCT.TransformIDCT(ref srcBlock, ref temp); - this.CompareBlocks(expected, actual, 1f); + this.CompareBlocks(expected, srcBlock, 1f); } [Theory] @@ -52,15 +51,14 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg { float[] sourceArray = Create8x8RoundedRandomFloatData(-1000, 1000, seed); - var source = Block8x8F.Load(sourceArray); + var srcBlock = Block8x8F.Load(sourceArray); - Block8x8F expected = ReferenceImplementations.AccurateDCT.TransformIDCT(ref source); + Block8x8F expected = ReferenceImplementations.AccurateDCT.TransformIDCT(ref srcBlock); var temp = default(Block8x8F); - var actual = default(Block8x8F); - FastFloatingPointDCT.TransformIDCT(ref source, ref actual, ref temp); + FastFloatingPointDCT.TransformIDCT(ref srcBlock, ref temp); - this.CompareBlocks(expected, actual, 1f); + this.CompareBlocks(expected, srcBlock, 1f); } // Inverse transform @@ -120,24 +118,19 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg public void IDCT8x8_Avx(int seed) { #if SUPPORTS_RUNTIME_INTRINSICS - var skip = !Avx.IsSupported; -#else - var skip = true; -#endif - - if (skip) + if (!Avx.IsSupported) { this.Output.WriteLine("No AVX present, skipping test!"); return; } Span src = Create8x8RoundedRandomFloatData(-200, 200, seed); - var srcBlock = default(Block8x8F); + Block8x8F srcBlock = default; srcBlock.LoadFrom(src); - var destBlock = default(Block8x8F); + Block8x8F destBlock = default; - var expectedDest = new float[64]; + float[] expectedDest = new float[64]; // reference, left part ReferenceImplementations.LLM_FloatingPoint_DCT.IDCT2D8x4_32f(src, expectedDest); @@ -148,10 +141,11 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg // testee, whole 8x8 FastFloatingPointDCT.IDCT8x8_Avx(ref srcBlock, ref destBlock); - var actualDest = new float[64]; + float[] actualDest = new float[64]; destBlock.ScaledCopyTo(actualDest); Assert.Equal(actualDest, expectedDest, new ApproximateFloatComparer(1f)); +#endif } [Theory] @@ -167,8 +161,6 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg var srcBlock = default(Block8x8F); srcBlock.LoadFrom(src); - var destBlock = default(Block8x8F); - var expectedDest = new float[64]; var temp1 = new float[64]; var temp2 = default(Block8x8F); @@ -177,10 +169,10 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg ReferenceImplementations.LLM_FloatingPoint_DCT.IDCT2D_llm(src, expectedDest, temp1); // testee - FastFloatingPointDCT.TransformIDCT(ref srcBlock, ref destBlock, ref temp2); + FastFloatingPointDCT.TransformIDCT(ref srcBlock, ref temp2); var actualDest = new float[64]; - destBlock.ScaledCopyTo(actualDest); + srcBlock.ScaledCopyTo(actualDest); Assert.Equal(actualDest, expectedDest, new ApproximateFloatComparer(1f)); } @@ -198,95 +190,8 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg } // Forward transform - [Theory] - [InlineData(1)] - [InlineData(2)] - public void FDCT8x4_LeftPart(int seed) - { - Span src = Create8x8RoundedRandomFloatData(-200, 200, seed); - var srcBlock = default(Block8x8F); - srcBlock.LoadFrom(src); - - var destBlock = default(Block8x8F); - - var expectedDest = new float[64]; - - // reference - ReferenceImplementations.LLM_FloatingPoint_DCT.FDCT2D8x4_32f(src, expectedDest); - - // testee - FastFloatingPointDCT.FDCT8x4_LeftPart(ref srcBlock, ref destBlock); - - var actualDest = new float[64]; - destBlock.ScaledCopyTo(actualDest); - - Assert.Equal(actualDest, expectedDest, new ApproximateFloatComparer(1f)); - } - - [Theory] - [InlineData(1)] - [InlineData(2)] - public void FDCT8x4_RightPart(int seed) - { - Span src = Create8x8RoundedRandomFloatData(-200, 200, seed); - var srcBlock = default(Block8x8F); - srcBlock.LoadFrom(src); - - var destBlock = default(Block8x8F); - - var expectedDest = new float[64]; - - // reference - ReferenceImplementations.LLM_FloatingPoint_DCT.FDCT2D8x4_32f(src.Slice(4), expectedDest.AsSpan(4)); - - // testee - FastFloatingPointDCT.FDCT8x4_RightPart(ref srcBlock, ref destBlock); - - var actualDest = new float[64]; - destBlock.ScaledCopyTo(actualDest); - - Assert.Equal(actualDest, expectedDest, new ApproximateFloatComparer(1f)); - } - - [Theory] - [InlineData(1)] - [InlineData(2)] - public void FDCT8x8_Avx(int seed) - { -#if SUPPORTS_RUNTIME_INTRINSICS - var skip = !Avx.IsSupported; -#else - var skip = true; -#endif - if (skip) - { - this.Output.WriteLine("No AVX present, skipping test!"); - return; - } - - Span src = Create8x8RoundedRandomFloatData(-200, 200, seed); - var srcBlock = default(Block8x8F); - srcBlock.LoadFrom(src); - - var destBlock = default(Block8x8F); - - var expectedDest = new float[64]; - - // reference, left part - ReferenceImplementations.LLM_FloatingPoint_DCT.FDCT2D8x4_32f(src, expectedDest); - - // reference, right part - ReferenceImplementations.LLM_FloatingPoint_DCT.FDCT2D8x4_32f(src.Slice(4), expectedDest.AsSpan(4)); - - // testee, whole 8x8 - FastFloatingPointDCT.FDCT8x8_Avx(ref srcBlock, ref destBlock); - - var actualDest = new float[64]; - destBlock.ScaledCopyTo(actualDest); - - Assert.Equal(actualDest, expectedDest, new ApproximateFloatComparer(1f)); - } - + // This test covers entire FDCT conversions chain + // This test checks all implementations: intrinsic and scalar fallback [Theory] [InlineData(1)] [InlineData(2)] @@ -297,37 +202,38 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg int seed = FeatureTestRunner.Deserialize(serialized); Span src = Create8x8RoundedRandomFloatData(-200, 200, seed); - var srcBlock = default(Block8x8F); - srcBlock.LoadFrom(src); - - var destBlock = default(Block8x8F); + var block = default(Block8x8F); + block.LoadFrom(src); - var expectedDest = new float[64]; - var temp1 = new float[64]; - var temp2 = default(Block8x8F); + float[] expectedDest = new float[64]; + float[] temp1 = new float[64]; // reference ReferenceImplementations.LLM_FloatingPoint_DCT.FDCT2D_llm(src, expectedDest, temp1, downscaleBy8: true); // testee - FastFloatingPointDCT.TransformFDCT(ref srcBlock, ref destBlock, ref temp2, false); + // Part of the FDCT calculations is fused into the quantization step + // We must multiply transformed block with reciprocal values from FastFloatingPointDCT.ANN_DCT_reciprocalAdjustmen + FastFloatingPointDCT.TransformFDCT(ref block); + for (int i = 0; i < 64; i++) + { + block[i] = block[i] * FastFloatingPointDCT.DctReciprocalAdjustmentCoefficients[i]; + } - var actualDest = new float[64]; - destBlock.ScaledCopyTo(actualDest); + float[] actualDest = block.ToArray(); - Assert.Equal(actualDest, expectedDest, new ApproximateFloatComparer(1f)); + Assert.Equal(expectedDest, actualDest, new ApproximateFloatComparer(1f)); } // 3 paths: // 1. AllowAll - call avx/fma implementation // 2. DisableFMA - call avx implementation without fma acceleration - // 3. DisableAvx - call fallback code of Vector4 implementation - // - // DisableSSE isn't needed because fallback Vector4 code will compile to either sse or fallback code with same result + // 3. DisableAvx - call sse implementation + // 4. DisableHWIntrinsic - call scalar fallback implementation FeatureTestRunner.RunWithHwIntrinsicsFeature( RunTest, seed, - HwIntrinsics.AllowAll | HwIntrinsics.DisableFMA | HwIntrinsics.DisableAVX); + HwIntrinsics.AllowAll | HwIntrinsics.DisableFMA | HwIntrinsics.DisableAVX | HwIntrinsics.DisableHWIntrinsic); } } } diff --git a/tests/ImageSharp.Tests/Formats/Jpg/GenericBlock8x8Tests.cs b/tests/ImageSharp.Tests/Formats/Jpg/GenericBlock8x8Tests.cs index c0f3b6a6a..d5ee2a2b8 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/GenericBlock8x8Tests.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/GenericBlock8x8Tests.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. using System; - using SixLabors.ImageSharp.Formats.Jpeg.Components; using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.PixelFormats; diff --git a/tests/ImageSharp.Tests/Formats/Jpg/HuffmanScanEncoderTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/HuffmanScanEncoderTests.cs index b953e80b8..42f2fa0d5 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/HuffmanScanEncoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/HuffmanScanEncoderTests.cs @@ -85,157 +85,5 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg Assert.Equal(expected, actual); } } - - [Fact] - public void GetLastValuableElementIndex_AllZero() - { - static void RunTest() - { - Block8x8F data = default; - - int expectedLessThan = 1; - - int actual = HuffmanScanEncoder.GetLastValuableElementIndex(ref data); - - Assert.True(actual < expectedLessThan); - } - - FeatureTestRunner.RunWithHwIntrinsicsFeature( - RunTest, - HwIntrinsics.AllowAll | HwIntrinsics.DisableAVX2); - } - - [Fact] - public void GetLastValuableElementIndex_AllNonZero() - { - static void RunTest() - { - Block8x8F data = default; - for (int i = 0; i < Block8x8F.Size; i++) - { - data[i] = 10; - } - - int expected = Block8x8F.Size - 1; - - int actual = HuffmanScanEncoder.GetLastValuableElementIndex(ref data); - - Assert.Equal(expected, actual); - } - - FeatureTestRunner.RunWithHwIntrinsicsFeature( - RunTest, - HwIntrinsics.AllowAll | HwIntrinsics.DisableAVX2); - } - - [Theory] - [InlineData(1)] - [InlineData(2)] - public void GetLastValuableElementIndex_RandomFilledSingle(int seed) - { - static void RunTest(string seedSerialized) - { - int seed = FeatureTestRunner.Deserialize(seedSerialized); - var rng = new Random(seed); - - for (int i = 0; i < 1000; i++) - { - Block8x8F data = default; - - int setIndex = rng.Next(1, Block8x8F.Size); - data[setIndex] = rng.Next(); - - int expected = setIndex; - - int actual = HuffmanScanEncoder.GetLastValuableElementIndex(ref data); - - Assert.Equal(expected, actual); - } - } - - FeatureTestRunner.RunWithHwIntrinsicsFeature( - RunTest, - seed, - HwIntrinsics.AllowAll | HwIntrinsics.DisableAVX2); - } - - [Theory] - [InlineData(1)] - [InlineData(2)] - public void GetLastValuableElementIndex_RandomFilledPartially(int seed) - { - static void RunTest(string seedSerialized) - { - int seed = FeatureTestRunner.Deserialize(seedSerialized); - var rng = new Random(seed); - - for (int i = 0; i < 1000; i++) - { - Block8x8F data = default; - - int lastIndex = rng.Next(1, Block8x8F.Size); - int fillValue = rng.Next(); - for (int dataIndex = 0; dataIndex <= lastIndex; dataIndex++) - { - data[dataIndex] = fillValue; - } - - int expected = lastIndex; - - int actual = HuffmanScanEncoder.GetLastValuableElementIndex(ref data); - - Assert.Equal(expected, actual); - } - } - - FeatureTestRunner.RunWithHwIntrinsicsFeature( - RunTest, - seed, - HwIntrinsics.AllowAll | HwIntrinsics.DisableAVX2); - } - - [Theory] - [InlineData(1)] - [InlineData(2)] - public void GetLastValuableElementIndex_RandomFilledFragmented(int seed) - { - static void RunTest(string seedSerialized) - { - int seed = FeatureTestRunner.Deserialize(seedSerialized); - var rng = new Random(seed); - - for (int i = 0; i < 1000; i++) - { - Block8x8F data = default; - - int fillValue = rng.Next(); - - // first filled chunk - int lastIndex1 = rng.Next(1, Block8x8F.Size / 2); - for (int dataIndex = 0; dataIndex <= lastIndex1; dataIndex++) - { - data[dataIndex] = fillValue; - } - - // second filled chunk, there might be a spot with zero(s) between first and second chunk - int lastIndex2 = rng.Next(lastIndex1 + 1, Block8x8F.Size); - for (int dataIndex = 0; dataIndex <= lastIndex2; dataIndex++) - { - data[dataIndex] = fillValue; - } - - int expected = lastIndex2; - - int actual = HuffmanScanEncoder.GetLastValuableElementIndex(ref data); - - Assert.Equal(expected, actual); - } - } - - FeatureTestRunner.RunWithHwIntrinsicsFeature( - RunTest, - seed, - HwIntrinsics.AllowAll | HwIntrinsics.DisableAVX2); - } } } diff --git a/tests/ImageSharp.Tests/Formats/Jpg/JpegColorConverterTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/JpegColorConverterTests.cs index 5f0562146..4e0970e3b 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/JpegColorConverterTests.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/JpegColorConverterTests.cs @@ -3,7 +3,6 @@ using System; using System.Numerics; - using SixLabors.ImageSharp.ColorSpaces; using SixLabors.ImageSharp.ColorSpaces.Conversion; using SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder; @@ -356,13 +355,13 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg JpegColorConverter converter = simd ? (JpegColorConverter)new JpegColorConverter.FromYCbCrVector4(8) : new JpegColorConverter.FromYCbCrBasic(8); // Warm up: - converter.ConvertToRgba(values, result); + converter.ConvertToRgbInplace(values); using (new MeasureGuard(this.Output, $"{converter.GetType().Name} x {times}")) { for (int i = 0; i < times; i++) { - converter.ConvertToRgba(values, result); + converter.ConvertToRgbInplace(values); } } } @@ -375,6 +374,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg float maxVal = 255f) { var rnd = new Random(seed); + var buffers = new Buffer2D[componentCount]; for (int i = 0; i < componentCount; i++) { @@ -416,39 +416,48 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg int resultBufferLength, int seed) { - JpegColorConverter.ComponentValues values = CreateRandomValues(componentCount, inputBufferLength, seed); - var result = new Vector4[resultBufferLength]; + JpegColorConverter.ComponentValues original = CreateRandomValues(componentCount, inputBufferLength, seed); + JpegColorConverter.ComponentValues values = Copy(original); - converter.ConvertToRgba(values, result); + converter.ConvertToRgbInplace(values); for (int i = 0; i < resultBufferLength; i++) { - Validate(converter.ColorSpace, values, result, i); + Validate(converter.ColorSpace, original, values, i); + } + + static JpegColorConverter.ComponentValues Copy(JpegColorConverter.ComponentValues values) + { + Span c0 = values.Component0.ToArray(); + Span c1 = values.ComponentCount > 1 ? values.Component1.ToArray().AsSpan() : c0; + Span c2 = values.ComponentCount > 2 ? values.Component2.ToArray().AsSpan() : c0; + Span c3 = values.ComponentCount > 3 ? values.Component3.ToArray().AsSpan() : Span.Empty; + return new JpegColorConverter.ComponentValues(values.ComponentCount, c0, c1, c2, c3); } } private static void Validate( JpegColorSpace colorSpace, - in JpegColorConverter.ComponentValues values, - Vector4[] result, + in JpegColorConverter.ComponentValues original, + in JpegColorConverter.ComponentValues result, int i) { switch (colorSpace) { case JpegColorSpace.Grayscale: - ValidateGrayScale(values, result, i); + ValidateGrayScale(original, result, i); break; case JpegColorSpace.Ycck: - ValidateCyyK(values, result, i); + ValidateCyyK(original, result, i); break; case JpegColorSpace.Cmyk: - ValidateCmyk(values, result, i); + ValidateCmyk(original, result, i); break; case JpegColorSpace.RGB: - ValidateRgb(values, result, i); + ValidateRgb(original, result, i); break; case JpegColorSpace.YCbCr: - ValidateYCbCr(values, result, i); + ValidateYCbCr(original, result, i); break; default: Assert.True(false, $"Colorspace {colorSpace} not supported!"); @@ -456,22 +465,20 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg } } - private static void ValidateYCbCr(in JpegColorConverter.ComponentValues values, Vector4[] result, int i) + private static void ValidateYCbCr(in JpegColorConverter.ComponentValues values, in JpegColorConverter.ComponentValues result, int i) { float y = values.Component0[i]; float cb = values.Component1[i]; float cr = values.Component2[i]; var ycbcr = new YCbCr(y, cb, cr); - Vector4 rgba = result[i]; - var actual = new Rgb(rgba.X, rgba.Y, rgba.Z); + var actual = new Rgb(result.Component0[i], result.Component1[i], result.Component2[i]); var expected = ColorSpaceConverter.ToRgb(ycbcr); Assert.Equal(expected, actual, ColorSpaceComparer); - Assert.Equal(1, rgba.W); } - private static void ValidateCyyK(in JpegColorConverter.ComponentValues values, Vector4[] result, int i) + private static void ValidateCyyK(in JpegColorConverter.ComponentValues values, in JpegColorConverter.ComponentValues result, int i) { var v = new Vector4(0, 0, 0, 1F); var scale = new Vector4(1 / 255F, 1 / 255F, 1 / 255F, 1F); @@ -490,39 +497,34 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg v *= scale; - Vector4 rgba = result[i]; - var actual = new Rgb(rgba.X, rgba.Y, rgba.Z); + var actual = new Rgb(result.Component0[i], result.Component1[i], result.Component2[i]); var expected = new Rgb(v.X, v.Y, v.Z); Assert.Equal(expected, actual, ColorSpaceComparer); - Assert.Equal(1, rgba.W); } - private static void ValidateRgb(in JpegColorConverter.ComponentValues values, Vector4[] result, int i) + private static void ValidateRgb(in JpegColorConverter.ComponentValues values, in JpegColorConverter.ComponentValues result, int i) { float r = values.Component0[i]; float g = values.Component1[i]; float b = values.Component2[i]; - Vector4 rgba = result[i]; - var actual = new Rgb(rgba.X, rgba.Y, rgba.Z); + + var actual = new Rgb(result.Component0[i], result.Component1[i], result.Component2[i]); var expected = new Rgb(r / 255F, g / 255F, b / 255F); Assert.Equal(expected, actual, ColorSpaceComparer); - Assert.Equal(1, rgba.W); } - private static void ValidateGrayScale(in JpegColorConverter.ComponentValues values, Vector4[] result, int i) + private static void ValidateGrayScale(in JpegColorConverter.ComponentValues values, in JpegColorConverter.ComponentValues result, int i) { float y = values.Component0[i]; - Vector4 rgba = result[i]; - var actual = new Rgb(rgba.X, rgba.Y, rgba.Z); + var actual = new Rgb(result.Component0[i], result.Component0[i], result.Component0[i]); var expected = new Rgb(y / 255F, y / 255F, y / 255F); Assert.Equal(expected, actual, ColorSpaceComparer); - Assert.Equal(1, rgba.W); } - private static void ValidateCmyk(in JpegColorConverter.ComponentValues values, Vector4[] result, int i) + private static void ValidateCmyk(in JpegColorConverter.ComponentValues values, in JpegColorConverter.ComponentValues result, int i) { var v = new Vector4(0, 0, 0, 1F); var scale = new Vector4(1 / 255F, 1 / 255F, 1 / 255F, 1F); @@ -539,12 +541,10 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg v *= scale; - Vector4 rgba = result[i]; - var actual = new Rgb(rgba.X, rgba.Y, rgba.Z); + var actual = new Rgb(result.Component0[i], result.Component1[i], result.Component2[i]); var expected = new Rgb(v.X, v.Y, v.Z); Assert.Equal(expected, actual, ColorSpaceComparer); - Assert.Equal(1, rgba.W); } } } diff --git a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Baseline.cs b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Baseline.cs index 7002bfd65..021e3d272 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Baseline.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Baseline.cs @@ -13,9 +13,9 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg public partial class JpegDecoderTests { [Theory] - [WithFileCollection(nameof(BaselineTestJpegs), PixelTypes.Rgba32, false)] - [WithFile(TestImages.Jpeg.Baseline.Calliphora, PixelTypes.Rgba32, true)] - [WithFile(TestImages.Jpeg.Baseline.Turtle420, PixelTypes.Rgba32, true)] + [WithFileCollection(nameof(BaselineTestJpegs), PixelTypes.Rgb24, false)] + [WithFile(TestImages.Jpeg.Baseline.Calliphora, PixelTypes.Rgb24, true)] + [WithFile(TestImages.Jpeg.Baseline.Turtle420, PixelTypes.Rgb24, true)] public void DecodeBaselineJpeg(TestImageProvider provider, bool enforceDiscontiguousBuffers) where TPixel : unmanaged, IPixel { @@ -26,7 +26,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg if (!string.IsNullOrEmpty(nonContiguousBuffersStr)) { - provider.LimitAllocatorBufferCapacity().InPixels(1000 * 8); + provider.LimitAllocatorBufferCapacity().InPixels(16_000); } using Image image = provider.GetImage(JpegDecoder); diff --git a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Images.cs b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Images.cs index 2faea2611..d12240cba 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Images.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Images.cs @@ -17,8 +17,6 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg TestImages.Jpeg.Baseline.Jpeg400, TestImages.Jpeg.Baseline.Turtle420, TestImages.Jpeg.Baseline.Testorig420, - - // BUG: The following image has a high difference compared to the expected output: 1.0096% TestImages.Jpeg.Baseline.Jpeg420Small, TestImages.Jpeg.Issues.Fuzz.AccessViolationException922, TestImages.Jpeg.Baseline.Jpeg444, @@ -89,7 +87,9 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg TestImages.Jpeg.Issues.Fuzz.ArgumentException826B, TestImages.Jpeg.Issues.Fuzz.ArgumentException826C, TestImages.Jpeg.Issues.Fuzz.AccessViolationException827, - TestImages.Jpeg.Issues.Fuzz.ExecutionEngineException839 + TestImages.Jpeg.Issues.Fuzz.ExecutionEngineException839, + TestImages.Jpeg.Issues.Fuzz.IndexOutOfRangeException1693A, + TestImages.Jpeg.Issues.Fuzz.IndexOutOfRangeException1693B }; private static readonly Dictionary CustomToleranceValues = @@ -101,7 +101,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg [TestImages.Jpeg.Baseline.Bad.BadRST] = 0.0589f / 100, [TestImages.Jpeg.Baseline.Testorig420] = 0.38f / 100, - [TestImages.Jpeg.Baseline.Jpeg420Small] = 1.1f / 100, + [TestImages.Jpeg.Baseline.Jpeg420Small] = 0.287f / 100, [TestImages.Jpeg.Baseline.Turtle420] = 1.0f / 100, // Progressive: diff --git a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Metadata.cs b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Metadata.cs index f47ae5522..5e42c6c8f 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Metadata.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Metadata.cs @@ -4,7 +4,6 @@ using System; using System.IO; using System.Runtime.CompilerServices; - using SixLabors.ImageSharp.Formats; using SixLabors.ImageSharp.Formats.Jpeg; using SixLabors.ImageSharp.Metadata; @@ -55,7 +54,9 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg { { TestImages.Jpeg.Baseline.Calliphora, 80 }, { TestImages.Jpeg.Progressive.Fb, 75 }, - { TestImages.Jpeg.Issues.IncorrectQuality845, 99 } + { TestImages.Jpeg.Issues.IncorrectQuality845, 98 }, + { TestImages.Jpeg.Baseline.ForestBridgeDifferentComponentsQuality, 89 }, + { TestImages.Jpeg.Progressive.Winter, 80 } }; [Theory] @@ -65,16 +66,13 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg string imagePath, int expectedPixelSize, bool exifProfilePresent, - bool iccProfilePresent) - { - TestMetadataImpl( + bool iccProfilePresent) => TestMetadataImpl( useIdentify, JpegDecoder, imagePath, expectedPixelSize, exifProfilePresent, iccProfilePresent); - } [Theory] [MemberData(nameof(RatioFiles))] @@ -84,7 +82,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg using (var stream = new MemoryStream(testFile.Bytes, false)) { var decoder = new JpegDecoder(); - using (Image image = decoder.Decode(Configuration.Default, stream)) + using (Image image = decoder.Decode(Configuration.Default, stream)) { ImageMetadata meta = image.Metadata; Assert.Equal(xResolution, meta.HorizontalResolution); @@ -131,8 +129,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg var testFile = TestFile.Create(imagePath); using (var stream = new MemoryStream(testFile.Bytes, false)) { - var decoder = new JpegDecoder(); - using (Image image = decoder.Decode(Configuration.Default, stream)) + using (Image image = JpegDecoder.Decode(Configuration.Default, stream)) { JpegMetadata meta = image.Metadata.GetJpegMetadata(); Assert.Equal(quality, meta.Quality); @@ -140,6 +137,42 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg } } + [Theory] + [InlineData(TestImages.Jpeg.Baseline.Floorplan, JpegColorType.Luminance)] + [InlineData(TestImages.Jpeg.Baseline.Jpeg420Small, JpegColorType.YCbCrRatio420)] + [InlineData(TestImages.Jpeg.Baseline.Jpeg444, JpegColorType.YCbCrRatio444)] + [InlineData(TestImages.Jpeg.Baseline.JpegRgb, JpegColorType.Rgb)] + [InlineData(TestImages.Jpeg.Baseline.Cmyk, JpegColorType.Cmyk)] + [InlineData(TestImages.Jpeg.Baseline.Jpeg410, JpegColorType.YCbCrRatio410)] + [InlineData(TestImages.Jpeg.Baseline.Jpeg422, JpegColorType.YCbCrRatio422)] + [InlineData(TestImages.Jpeg.Baseline.Jpeg411, JpegColorType.YCbCrRatio411)] + public void Identify_DetectsCorrectColorType(string imagePath, JpegColorType expectedColorType) + { + var testFile = TestFile.Create(imagePath); + using (var stream = new MemoryStream(testFile.Bytes, false)) + { + IImageInfo image = JpegDecoder.Identify(Configuration.Default, stream); + JpegMetadata meta = image.Metadata.GetJpegMetadata(); + Assert.Equal(expectedColorType, meta.ColorType); + } + } + + [Theory] + [WithFile(TestImages.Jpeg.Baseline.Floorplan, PixelTypes.Rgb24, JpegColorType.Luminance)] + [WithFile(TestImages.Jpeg.Baseline.Jpeg420Small, PixelTypes.Rgb24, JpegColorType.YCbCrRatio420)] + [WithFile(TestImages.Jpeg.Baseline.Jpeg444, PixelTypes.Rgb24, JpegColorType.YCbCrRatio444)] + [WithFile(TestImages.Jpeg.Baseline.JpegRgb, PixelTypes.Rgb24, JpegColorType.Rgb)] + [WithFile(TestImages.Jpeg.Baseline.Cmyk, PixelTypes.Rgb24, JpegColorType.Cmyk)] + public void Decode_DetectsCorrectColorType(TestImageProvider provider, JpegColorType expectedColorType) + where TPixel : unmanaged, IPixel + { + using (Image image = provider.GetImage(JpegDecoder)) + { + JpegMetadata meta = image.Metadata.GetJpegMetadata(); + Assert.Equal(expectedColorType, meta.ColorType); + } + } + private static void TestImageInfo(string imagePath, IImageDecoder decoder, bool useIdentify, Action test) { var testFile = TestFile.Create(imagePath); @@ -159,9 +192,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg string imagePath, int expectedPixelSize, bool exifProfilePresent, - bool iccProfilePresent) - { - TestImageInfo( + bool iccProfilePresent) => TestImageInfo( imagePath, decoder, useIdentify, @@ -205,7 +236,6 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg Assert.Null(iccProfile); } }); - } [Theory] [InlineData(false)] @@ -235,9 +265,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg [Theory] [InlineData(false)] [InlineData(true)] - public void Decoder_Reads_Correct_Resolution_From_Jfif(bool useIdentify) - { - TestImageInfo( + public void Decoder_Reads_Correct_Resolution_From_Jfif(bool useIdentify) => TestImageInfo( TestImages.Jpeg.Baseline.Floorplan, JpegDecoder, useIdentify, @@ -246,14 +274,11 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg Assert.Equal(300, imageInfo.Metadata.HorizontalResolution); Assert.Equal(300, imageInfo.Metadata.VerticalResolution); }); - } [Theory] [InlineData(false)] [InlineData(true)] - public void Decoder_Reads_Correct_Resolution_From_Exif(bool useIdentify) - { - TestImageInfo( + public void Decoder_Reads_Correct_Resolution_From_Exif(bool useIdentify) => TestImageInfo( TestImages.Jpeg.Baseline.Jpeg420Exif, JpegDecoder, useIdentify, @@ -262,6 +287,5 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg Assert.Equal(72, imageInfo.Metadata.HorizontalResolution); Assert.Equal(72, imageInfo.Metadata.VerticalResolution); }); - } } } diff --git a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Progressive.cs b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Progressive.cs index 9beb8358c..e8533b9bc 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Progressive.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.Progressive.cs @@ -15,7 +15,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg public const string DecodeProgressiveJpegOutputName = "DecodeProgressiveJpeg"; [Theory] - [WithFileCollection(nameof(ProgressiveTestJpegs), PixelTypes.Rgba32)] + [WithFileCollection(nameof(ProgressiveTestJpegs), PixelTypes.Rgb24)] public void DecodeProgressiveJpeg(TestImageProvider provider) where TPixel : unmanaged, IPixel { @@ -30,17 +30,17 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg } [Theory] - [WithFile(TestImages.Jpeg.Progressive.Progress, PixelTypes.Rgba32)] - public void DecodeProgressiveJpeg_WithLimitedAllocatorBufferCapacity(TestImageProvider provider) + [WithFile(TestImages.Jpeg.Progressive.Progress, PixelTypes.Rgb24)] + public void DecodeProgressiveJpeg_WithLimitedAllocatorBufferCapacity(TestImageProvider provider) { static void RunTest(string providerDump, string nonContiguousBuffersStr) { - TestImageProvider provider = - BasicSerializer.Deserialize>(providerDump); + TestImageProvider provider = + BasicSerializer.Deserialize>(providerDump); provider.LimitAllocatorBufferCapacity().InBytesSqrt(200); - using Image image = provider.GetImage(JpegDecoder); + using Image image = provider.GetImage(JpegDecoder); image.DebugSave(provider, nonContiguousBuffersStr); provider.Utility.TestName = DecodeProgressiveJpegOutputName; diff --git a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs index d13a9696c..2cbc29027 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs @@ -6,7 +6,6 @@ using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; - using SixLabors.ImageSharp.Formats.Jpeg; using SixLabors.ImageSharp.IO; using SixLabors.ImageSharp.Memory; @@ -26,7 +25,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg [Trait("Format", "Jpg")] public partial class JpegDecoderTests { - public const PixelTypes CommonNonDefaultPixelTypes = PixelTypes.Rgba32 | PixelTypes.Argb32 | PixelTypes.RgbaVector; + public const PixelTypes CommonNonDefaultPixelTypes = PixelTypes.Rgba32 | PixelTypes.Argb32 | PixelTypes.Bgr24 | PixelTypes.RgbaVector; private const float BaselineTolerance = 0.001F / 100; @@ -63,10 +62,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg return !TestEnvironment.Is64BitProcess && largeImagesToSkipOn32Bit.Contains(provider.SourceFileOrDescription); } - public JpegDecoderTests(ITestOutputHelper output) - { - this.Output = output; - } + public JpegDecoderTests(ITestOutputHelper output) => this.Output = output; private ITestOutputHelper Output { get; } @@ -78,8 +74,8 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg byte[] bytes = TestFile.Create(TestImages.Jpeg.Progressive.Progress).Bytes; using var ms = new MemoryStream(bytes); using var bufferedStream = new BufferedReadStream(Configuration.Default, ms); - var decoder = new JpegDecoderCore(Configuration.Default, new JpegDecoder()); - decoder.ParseStream(bufferedStream); + using var decoder = new JpegDecoderCore(Configuration.Default, new JpegDecoder()); + using Image image = decoder.Decode(bufferedStream, cancellationToken: default); // I don't know why these numbers are different. All I know is that the decoder works // and spectral data is exactly correct also. @@ -89,6 +85,14 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg public const string DecodeBaselineJpegOutputName = "DecodeBaselineJpeg"; + [Fact] + public void Decode_NonGeneric_CreatesRgb24Image() + { + string file = Path.Combine(TestEnvironment.InputImagesDirectoryFullPath, TestImages.Jpeg.Baseline.Jpeg420Small); + using var image = Image.Load(file); + Assert.IsType>(image); + } + [Theory] [WithFile(TestImages.Jpeg.Baseline.Calliphora, CommonNonDefaultPixelTypes)] public void JpegDecoder_IsNotBoundToSinglePixelType(TestImageProvider provider) @@ -132,10 +136,10 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg [InlineData(0)] [InlineData(0.5)] [InlineData(0.9)] - public async Task Decode_IsCancellable(int percentageOfStreamReadToCancel) + public async Task DecodeAsync_IsCancellable(int percentageOfStreamReadToCancel) { var cts = new CancellationTokenSource(); - var file = Path.Combine(TestEnvironment.InputImagesDirectoryFullPath, TestImages.Jpeg.Baseline.Jpeg420Small); + string file = Path.Combine(TestEnvironment.InputImagesDirectoryFullPath, TestImages.Jpeg.Baseline.Jpeg420Small); using var pausedStream = new PausedStream(file); pausedStream.OnWaiting(s => { @@ -164,7 +168,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg { var cts = new CancellationTokenSource(); - var file = Path.Combine(TestEnvironment.InputImagesDirectoryFullPath, TestImages.Jpeg.Baseline.Jpeg420Small); + string file = Path.Combine(TestEnvironment.InputImagesDirectoryFullPath, TestImages.Jpeg.Baseline.Jpeg420Small); using var pausedStream = new PausedStream(file); pausedStream.OnWaiting(s => { @@ -178,6 +182,32 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg await Assert.ThrowsAsync(async () => await Image.IdentifyAsync(config, "someFakeFile", cts.Token)); } + [Theory] + [WithFile(TestImages.Jpeg.Baseline.ArithmeticCoding, PixelTypes.Rgba32)] + [WithFile(TestImages.Jpeg.Baseline.ArithmeticCodingProgressive, PixelTypes.Rgba32)] + [WithFile(TestImages.Jpeg.Baseline.Lossless, PixelTypes.Rgba32)] + public void ThrowsNotSupported_WithUnsupportedJpegs(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + Assert.Throws(() => + { + using Image image = provider.GetImage(JpegDecoder); + }); + } + + // https://github.com/SixLabors/ImageSharp/pull/1732 + [Theory] + [WithFile(TestImages.Jpeg.Issues.WrongColorSpace, PixelTypes.Rgba32)] + public void Issue1732_DecodesWithRgbColorSpace(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + using (Image image = provider.GetImage(JpegDecoder)) + { + image.DebugSave(provider); + image.CompareToOriginal(provider); + } + } + // DEBUG ONLY! // The PDF.js output should be saved by "tests\ImageSharp.Tests\Formats\Jpg\pdfjs\jpeg-converter.htm" // into "\tests\Images\ActualOutput\JpegDecoderTests\" diff --git a/tests/ImageSharp.Tests/Formats/Jpg/JpegEncoderTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/JpegEncoderTests.cs index 8e12b04be..62952f537 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/JpegEncoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/JpegEncoderTests.cs @@ -5,7 +5,6 @@ using System.Collections.Generic; using System.IO; using System.Threading; using System.Threading.Tasks; - using SixLabors.ImageSharp.Formats.Jpeg; using SixLabors.ImageSharp.Metadata; using SixLabors.ImageSharp.Metadata.Profiles.Exif; @@ -24,6 +23,10 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg [Trait("Format", "Jpg")] public class JpegEncoderTests { + private static JpegEncoder JpegEncoder => new JpegEncoder(); + + private static JpegDecoder JpegDecoder => new JpegDecoder(); + public static readonly TheoryData QualityFiles = new TheoryData { @@ -31,15 +34,18 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg { TestImages.Jpeg.Progressive.Fb, 75 } }; - public static readonly TheoryData BitsPerPixel_Quality = - new TheoryData + public static readonly TheoryData BitsPerPixel_Quality = + new TheoryData { - { JpegSubsample.Ratio420, 40 }, - { JpegSubsample.Ratio420, 60 }, - { JpegSubsample.Ratio420, 100 }, - { JpegSubsample.Ratio444, 40 }, - { JpegSubsample.Ratio444, 60 }, - { JpegSubsample.Ratio444, 100 }, + { JpegColorType.YCbCrRatio420, 40 }, + { JpegColorType.YCbCrRatio420, 60 }, + { JpegColorType.YCbCrRatio420, 100 }, + { JpegColorType.YCbCrRatio444, 40 }, + { JpegColorType.YCbCrRatio444, 60 }, + { JpegColorType.YCbCrRatio444, 100 }, + { JpegColorType.Rgb, 40 }, + { JpegColorType.Rgb, 60 }, + { JpegColorType.Rgb, 100 } }; public static readonly TheoryData Grayscale_Quality = @@ -59,17 +65,84 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg }; [Theory] - [MemberData(nameof(QualityFiles))] - public void Encode_PreserveQuality(string imagePath, int quality) + [WithFile(TestImages.Jpeg.Baseline.Floorplan, PixelTypes.Rgba32, JpegColorType.Luminance)] + [WithFile(TestImages.Jpeg.Baseline.Jpeg444, PixelTypes.Rgba32, JpegColorType.YCbCrRatio444)] + [WithFile(TestImages.Jpeg.Baseline.Jpeg420Small, PixelTypes.Rgba32, JpegColorType.YCbCrRatio420)] + [WithFile(TestImages.Jpeg.Baseline.JpegRgb, PixelTypes.Rgba32, JpegColorType.Rgb)] + public void Encode_PreservesColorType(TestImageProvider provider, JpegColorType expectedColorType) + where TPixel : unmanaged, IPixel + { + // arrange + using Image input = provider.GetImage(JpegDecoder); + using var memoryStream = new MemoryStream(); + + // act + input.Save(memoryStream, JpegEncoder); + + // assert + memoryStream.Position = 0; + using var output = Image.Load(memoryStream); + JpegMetadata meta = output.Metadata.GetJpegMetadata(); + Assert.Equal(expectedColorType, meta.ColorType); + } + + [Theory] + [WithFile(TestImages.Jpeg.Baseline.Cmyk, PixelTypes.Rgba32)] + [WithFile(TestImages.Jpeg.Baseline.Jpeg410, PixelTypes.Rgba32)] + [WithFile(TestImages.Jpeg.Baseline.Jpeg411, PixelTypes.Rgba32)] + [WithFile(TestImages.Jpeg.Baseline.Jpeg422, PixelTypes.Rgba32)] + public void Encode_WithUnsupportedColorType_FromInputImage_DefaultsToYCbCr420(TestImageProvider provider) + where TPixel : unmanaged, IPixel { - var options = new JpegEncoder(); + // arrange + using Image input = provider.GetImage(JpegDecoder); + using var memoryStream = new MemoryStream(); + + // act + input.Save(memoryStream, new JpegEncoder() + { + Quality = 75 + }); + // assert + memoryStream.Position = 0; + using var output = Image.Load(memoryStream); + JpegMetadata meta = output.Metadata.GetJpegMetadata(); + Assert.Equal(JpegColorType.YCbCrRatio420, meta.ColorType); + } + + [Theory] + [InlineData(JpegColorType.Cmyk)] + [InlineData(JpegColorType.YCbCrRatio410)] + [InlineData(JpegColorType.YCbCrRatio411)] + [InlineData(JpegColorType.YCbCrRatio422)] + public void Encode_WithUnsupportedColorType_DefaultsToYCbCr420(JpegColorType colorType) + { + // arrange + var jpegEncoder = new JpegEncoder() { ColorType = colorType }; + using var input = new Image(10, 10); + using var memoryStream = new MemoryStream(); + + // act + input.Save(memoryStream, jpegEncoder); + + // assert + memoryStream.Position = 0; + using var output = Image.Load(memoryStream); + JpegMetadata meta = output.Metadata.GetJpegMetadata(); + Assert.Equal(JpegColorType.YCbCrRatio420, meta.ColorType); + } + + [Theory] + [MemberData(nameof(QualityFiles))] + public void Encode_PreservesQuality(string imagePath, int quality) + { var testFile = TestFile.Create(imagePath); using (Image input = testFile.CreateRgba32Image()) { using (var memStream = new MemoryStream()) { - input.Save(memStream, options); + input.Save(memStream, JpegEncoder); memStream.Position = 0; using (var output = Image.Load(memStream)) @@ -83,16 +156,30 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg [Theory] [WithFile(TestImages.Png.CalliphoraPartial, nameof(BitsPerPixel_Quality), PixelTypes.Rgba32)] + public void EncodeBaseline_CalliphoraPartial(TestImageProvider provider, JpegColorType colorType, int quality) + where TPixel : unmanaged, IPixel => TestJpegEncoderCore(provider, colorType, quality); + + [Theory] + [WithFile(TestImages.Png.CalliphoraPartial, nameof(BitsPerPixel_Quality), PixelTypes.Rgba32)] + [WithTestPatternImages(nameof(BitsPerPixel_Quality), 158, 24, PixelTypes.Rgba32)] + [WithTestPatternImages(nameof(BitsPerPixel_Quality), 153, 21, PixelTypes.Rgba32)] + [WithTestPatternImages(nameof(BitsPerPixel_Quality), 600, 400, PixelTypes.Rgba32)] + [WithTestPatternImages(nameof(BitsPerPixel_Quality), 138, 24, PixelTypes.Rgba32)] + public void EncodeBaseline_WorksWithDifferentSizes(TestImageProvider provider, JpegColorType colorType, int quality) + where TPixel : unmanaged, IPixel => TestJpegEncoderCore(provider, colorType, quality); + + [Theory] + [WithSolidFilledImages(nameof(BitsPerPixel_Quality), 1, 1, 100, 100, 100, 255, PixelTypes.L8)] + [WithSolidFilledImages(nameof(BitsPerPixel_Quality), 1, 1, 255, 100, 50, 255, PixelTypes.Rgba32)] + [WithTestPatternImages(nameof(BitsPerPixel_Quality), 143, 81, PixelTypes.Rgba32)] + [WithTestPatternImages(nameof(BitsPerPixel_Quality), 7, 5, PixelTypes.Rgba32)] + [WithTestPatternImages(nameof(BitsPerPixel_Quality), 96, 48, PixelTypes.Rgba32)] [WithTestPatternImages(nameof(BitsPerPixel_Quality), 73, 71, PixelTypes.Rgba32)] [WithTestPatternImages(nameof(BitsPerPixel_Quality), 48, 24, PixelTypes.Rgba32)] [WithTestPatternImages(nameof(BitsPerPixel_Quality), 46, 8, PixelTypes.Rgba32)] [WithTestPatternImages(nameof(BitsPerPixel_Quality), 51, 7, PixelTypes.Rgba32)] - [WithSolidFilledImages(nameof(BitsPerPixel_Quality), 1, 1, 255, 100, 50, 255, PixelTypes.Rgba32)] - [WithTestPatternImages(nameof(BitsPerPixel_Quality), 7, 5, PixelTypes.Rgba32)] - [WithTestPatternImages(nameof(BitsPerPixel_Quality), 600, 400, PixelTypes.Rgba32)] - [WithSolidFilledImages(nameof(BitsPerPixel_Quality), 1, 1, 100, 100, 100, 255, PixelTypes.L8)] - public void EncodeBaseline_WorksWithDifferentSizes(TestImageProvider provider, JpegSubsample subsample, int quality) - where TPixel : unmanaged, IPixel => TestJpegEncoderCore(provider, subsample, quality); + public void EncodeBaseline_WithSmallImages_WorksWithDifferentSizes(TestImageProvider provider, JpegColorType colorType, int quality) + where TPixel : unmanaged, IPixel => TestJpegEncoderCore(provider, colorType, quality, comparer: ImageComparer.Tolerant(0.12f)); [Theory] [WithFile(TestImages.Png.BikeGrayscale, nameof(Grayscale_Quality), PixelTypes.L8)] @@ -102,46 +189,51 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg [WithSolidFilledImages(1, 1, 100, 100, 100, 255, PixelTypes.La16, 100)] [WithSolidFilledImages(1, 1, 100, 100, 100, 255, PixelTypes.La32, 100)] public void EncodeBaseline_Grayscale(TestImageProvider provider, int quality) - where TPixel : unmanaged, IPixel => TestJpegEncoderCore(provider, null, quality, JpegColorType.Luminance); + where TPixel : unmanaged, IPixel => TestJpegEncoderCore(provider, JpegColorType.Luminance, quality); + + [Theory] + [WithTestPatternImages(nameof(BitsPerPixel_Quality), 96, 96, PixelTypes.Rgba32 | PixelTypes.Bgra32)] + public void EncodeBaseline_IsNotBoundToSinglePixelType(TestImageProvider provider, JpegColorType colorType, int quality) + where TPixel : unmanaged, IPixel => TestJpegEncoderCore(provider, colorType, quality); [Theory] [WithTestPatternImages(nameof(BitsPerPixel_Quality), 48, 48, PixelTypes.Rgba32 | PixelTypes.Bgra32)] - public void EncodeBaseline_IsNotBoundToSinglePixelType(TestImageProvider provider, JpegSubsample subsample, int quality) - where TPixel : unmanaged, IPixel => TestJpegEncoderCore(provider, subsample, quality); + public void EncodeBaseline_WithSmallImages_IsNotBoundToSinglePixelType(TestImageProvider provider, JpegColorType colorType, int quality) + where TPixel : unmanaged, IPixel => TestJpegEncoderCore(provider, colorType, quality, comparer: ImageComparer.Tolerant(0.06f)); [Theory] - [WithFile(TestImages.Png.CalliphoraPartial, PixelTypes.Rgba32, JpegSubsample.Ratio444)] - [WithTestPatternImages(587, 821, PixelTypes.Rgba32, JpegSubsample.Ratio444)] - [WithTestPatternImages(677, 683, PixelTypes.Bgra32, JpegSubsample.Ratio420)] - [WithSolidFilledImages(400, 400, "Red", PixelTypes.Bgr24, JpegSubsample.Ratio420)] - public void EncodeBaseline_WorksWithDiscontiguousBuffers(TestImageProvider provider, JpegSubsample subsample) + [WithFile(TestImages.Png.CalliphoraPartial, PixelTypes.Rgba32, JpegColorType.YCbCrRatio444)] + [WithTestPatternImages(587, 821, PixelTypes.Rgba32, JpegColorType.YCbCrRatio444)] + [WithTestPatternImages(677, 683, PixelTypes.Bgra32, JpegColorType.YCbCrRatio420)] + [WithSolidFilledImages(400, 400, "Red", PixelTypes.Bgr24, JpegColorType.YCbCrRatio420)] + public void EncodeBaseline_WorksWithDiscontiguousBuffers(TestImageProvider provider, JpegColorType colorType) where TPixel : unmanaged, IPixel { - ImageComparer comparer = subsample == JpegSubsample.Ratio444 + ImageComparer comparer = colorType == JpegColorType.YCbCrRatio444 ? ImageComparer.TolerantPercentage(0.1f) : ImageComparer.TolerantPercentage(5f); provider.LimitAllocatorBufferCapacity().InBytesSqrt(200); - TestJpegEncoderCore(provider, subsample, 100, JpegColorType.YCbCr, comparer); + TestJpegEncoderCore(provider, colorType, 100, comparer); } /// /// Anton's SUPER-SCIENTIFIC tolerance threshold calculation /// - private static ImageComparer GetComparer(int quality, JpegSubsample? subsample) + private static ImageComparer GetComparer(int quality, JpegColorType? colorType) { float tolerance = 0.015f; // ~1.5% if (quality < 50) { - tolerance *= 10f; + tolerance *= 4.5f; } - else if (quality < 75 || subsample == JpegSubsample.Ratio420) + else if (quality < 75 || colorType == JpegColorType.YCbCrRatio420) { - tolerance *= 5f; - if (subsample == JpegSubsample.Ratio420) + tolerance *= 2.0f; + if (colorType == JpegColorType.YCbCrRatio420) { - tolerance *= 2f; + tolerance *= 2.0f; } } @@ -150,9 +242,8 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg private static void TestJpegEncoderCore( TestImageProvider provider, - JpegSubsample? subsample, + JpegColorType colorType = JpegColorType.YCbCrRatio420, int quality = 100, - JpegColorType colorType = JpegColorType.YCbCr, ImageComparer comparer = null) where TPixel : unmanaged, IPixel { @@ -163,13 +254,12 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg var encoder = new JpegEncoder { - Subsample = subsample, Quality = quality, ColorType = colorType }; - string info = $"{subsample}-Q{quality}"; + string info = $"{colorType}-Q{quality}"; - comparer ??= GetComparer(quality, subsample); + comparer ??= GetComparer(quality, colorType); // Does DebugSave & load reference CompareToReferenceInput(): image.VerifyEncoder(provider, "jpeg", info, encoder, comparer, referenceImageExtension: "png"); @@ -225,14 +315,12 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg [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 input = testFile.CreateRgba32Image()) { using (var memStream = new MemoryStream()) { - input.Save(memStream, options); + input.Save(memStream, JpegEncoder); memStream.Position = 0; using (var output = Image.Load(memStream)) @@ -253,11 +341,10 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg using var input = new Image(1, 1); input.Metadata.IptcProfile = new IptcProfile(); input.Metadata.IptcProfile.SetValue(IptcTag.Byline, "unit_test"); - var encoder = new JpegEncoder(); // act using var memStream = new MemoryStream(); - input.Save(memStream, encoder); + input.Save(memStream, JpegEncoder); // assert memStream.Position = 0; @@ -275,11 +362,10 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg using var input = new Image(1, 1); input.Metadata.ExifProfile = new ExifProfile(); input.Metadata.ExifProfile.SetValue(ExifTag.Software, "unit_test"); - var encoder = new JpegEncoder(); // act using var memStream = new MemoryStream(); - input.Save(memStream, encoder); + input.Save(memStream, JpegEncoder); // assert memStream.Position = 0; @@ -296,11 +382,10 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg // arrange using var input = new Image(1, 1); input.Metadata.IccProfile = new IccProfile(IccTestDataProfiles.Profile_Random_Array); - var encoder = new JpegEncoder(); // act using var memStream = new MemoryStream(); - input.Save(memStream, encoder); + input.Save(memStream, JpegEncoder); // assert memStream.Position = 0; @@ -312,9 +397,9 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg } [Theory] - [InlineData(JpegSubsample.Ratio420)] - [InlineData(JpegSubsample.Ratio444)] - public async Task Encode_IsCancellable(JpegSubsample subsample) + [InlineData(JpegColorType.YCbCrRatio420)] + [InlineData(JpegColorType.YCbCrRatio444)] + public async Task Encode_IsCancellable(JpegColorType colorType) { var cts = new CancellationTokenSource(); using var pausedStream = new PausedStream(new MemoryStream()); @@ -336,7 +421,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg using var image = new Image(5000, 5000); await Assert.ThrowsAsync(async () => { - var encoder = new JpegEncoder() { Subsample = subsample }; + var encoder = new JpegEncoder() { ColorType = colorType }; await image.SaveAsync(pausedStream, encoder, cts.Token); }); } diff --git a/tests/ImageSharp.Tests/Formats/Jpg/JpegImagePostProcessorTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/JpegImagePostProcessorTests.cs deleted file mode 100644 index 93d9aee92..000000000 --- a/tests/ImageSharp.Tests/Formats/Jpg/JpegImagePostProcessorTests.cs +++ /dev/null @@ -1,97 +0,0 @@ -// Copyright (c) Six Labors. -// Licensed under the Apache License, Version 2.0. - -using SixLabors.ImageSharp.Formats.Jpeg; -using SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder; -using SixLabors.ImageSharp.PixelFormats; -using SixLabors.ImageSharp.Tests.Formats.Jpg.Utils; -using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison; - -using Xunit; -using Xunit.Abstractions; - -namespace SixLabors.ImageSharp.Tests.Formats.Jpg -{ - [Trait("Format", "Jpg")] - public class JpegImagePostProcessorTests - { - public static string[] BaselineTestJpegs = - { - TestImages.Jpeg.Baseline.Calliphora, - TestImages.Jpeg.Baseline.Cmyk, - TestImages.Jpeg.Baseline.Ycck, - TestImages.Jpeg.Baseline.Jpeg400, - TestImages.Jpeg.Baseline.Testorig420, - TestImages.Jpeg.Baseline.Jpeg444, - }; - - public JpegImagePostProcessorTests(ITestOutputHelper output) - { - this.Output = output; - } - - private ITestOutputHelper Output { get; } - - private static void SaveBuffer(JpegComponentPostProcessor cp, TestImageProvider provider) - where TPixel : unmanaged, IPixel - { - using (Image image = cp.ColorBuffer.ToGrayscaleImage(1f / 255f)) - { - image.DebugSave(provider, $"-C{cp.Component.Index}-"); - } - } - - [Theory] - [WithFile(TestImages.Jpeg.Baseline.Calliphora, PixelTypes.Rgba32)] - [WithFile(TestImages.Jpeg.Baseline.Testorig420, PixelTypes.Rgba32)] - public void DoProcessorStep(TestImageProvider provider) - where TPixel : unmanaged, IPixel - { - string imageFile = provider.SourceFileOrDescription; - using (JpegDecoderCore decoder = JpegFixture.ParseJpegStream(imageFile)) - using (var pp = new JpegImagePostProcessor(Configuration.Default, decoder)) - using (var imageFrame = new ImageFrame(Configuration.Default, decoder.ImageWidth, decoder.ImageHeight)) - { - pp.DoPostProcessorStep(imageFrame); - - JpegComponentPostProcessor[] cp = pp.ComponentProcessors; - - SaveBuffer(cp[0], provider); - SaveBuffer(cp[1], provider); - SaveBuffer(cp[2], provider); - } - } - - [Theory] - [WithFileCollection(nameof(BaselineTestJpegs), PixelTypes.Rgba32)] - public void PostProcess(TestImageProvider provider) - where TPixel : unmanaged, IPixel - { - string imageFile = provider.SourceFileOrDescription; - using (JpegDecoderCore decoder = JpegFixture.ParseJpegStream(imageFile)) - using (var pp = new JpegImagePostProcessor(Configuration.Default, decoder)) - using (var image = new Image(decoder.ImageWidth, decoder.ImageHeight)) - { - pp.PostProcess(image.Frames.RootFrame, default); - - image.DebugSave(provider); - - ImagingTestCaseUtility testUtil = provider.Utility; - testUtil.TestGroupName = nameof(JpegDecoderTests); - testUtil.TestName = JpegDecoderTests.DecodeBaselineJpegOutputName; - - using (Image referenceImage = - provider.GetReferenceOutputImage(appendPixelTypeToFileName: false)) - { - ImageSimilarityReport report = ImageComparer.Exact.CompareImagesOrFrames(referenceImage, image); - - this.Output.WriteLine($"*** {imageFile} ***"); - this.Output.WriteLine($"Difference: {report.DifferencePercentageString}"); - - // ReSharper disable once PossibleInvalidOperationException - Assert.True(report.TotalNormalizedDifference.Value < 0.005f); - } - } - } - } -} diff --git a/tests/ImageSharp.Tests/Formats/Jpg/JpegMetadataTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/JpegMetadataTests.cs index 503ede129..3f045dd1a 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/JpegMetadataTests.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/JpegMetadataTests.cs @@ -16,10 +16,49 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg var clone = (JpegMetadata)meta.DeepClone(); clone.Quality = 99; - clone.ColorType = JpegColorType.YCbCr; + clone.ColorType = JpegColorType.YCbCrRatio420; Assert.False(meta.Quality.Equals(clone.Quality)); Assert.False(meta.ColorType.Equals(clone.ColorType)); } + + [Fact] + public void Quality_DefaultQuality() + { + var meta = new JpegMetadata(); + + Assert.Equal(meta.Quality, ImageSharp.Formats.Jpeg.Components.Quantization.DefaultQualityFactor); + } + + [Fact] + public void Quality_LuminanceOnlyQuality() + { + int quality = 50; + + var meta = new JpegMetadata { LuminanceQuality = quality }; + + Assert.Equal(meta.Quality, quality); + } + + [Fact] + public void Quality_BothComponentsQuality() + { + int quality = 50; + + var meta = new JpegMetadata { LuminanceQuality = quality, ChrominanceQuality = quality }; + + Assert.Equal(meta.Quality, quality); + } + + [Fact] + public void Quality_ReturnsMaxQuality() + { + int qualityLuma = 50; + int qualityChroma = 30; + + var meta = new JpegMetadata { LuminanceQuality = qualityLuma, ChrominanceQuality = qualityChroma }; + + Assert.Equal(meta.Quality, qualityLuma); + } } } diff --git a/tests/ImageSharp.Tests/Formats/Jpg/LibJpegToolsTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/LibJpegToolsTests.cs index 1703d007f..80f6222ff 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/LibJpegToolsTests.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/LibJpegToolsTests.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. using System.IO; - using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.Tests.Formats.Jpg.Utils; diff --git a/tests/ImageSharp.Tests/Formats/Jpg/ParseStreamTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/ParseStreamTests.cs index de8103d63..c4d0faf33 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/ParseStreamTests.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/ParseStreamTests.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. using System.Text; - using SixLabors.ImageSharp.Formats.Jpeg; using SixLabors.ImageSharp.Formats.Jpeg.Components; using SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder; @@ -32,7 +31,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg { var expectedColorSpace = (JpegColorSpace)expectedColorSpaceValue; - using (JpegDecoderCore decoder = JpegFixture.ParseJpegStream(imageFile)) + using (JpegDecoderCore decoder = JpegFixture.ParseJpegStream(imageFile, metaDataOnly: true)) { Assert.Equal(expectedColorSpace, decoder.ColorSpace); } @@ -43,12 +42,12 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg { using (JpegDecoderCore decoder = JpegFixture.ParseJpegStream(TestImages.Jpeg.Baseline.Jpeg400)) { - Assert.Equal(1, decoder.ComponentCount); + Assert.Equal(1, decoder.Frame.ComponentCount); Assert.Equal(1, decoder.Components.Length); - Size expectedSizeInBlocks = decoder.ImageSizeInPixels.DivideRoundUp(8); + Size expectedSizeInBlocks = decoder.Frame.PixelSize.DivideRoundUp(8); - Assert.Equal(expectedSizeInBlocks, decoder.ImageSizeInMCU); + Assert.Equal(expectedSizeInBlocks, decoder.Frame.McuSize); var uniform1 = new Size(1, 1); JpegComponent c0 = decoder.Components[0]; @@ -70,7 +69,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg using (JpegDecoderCore decoder = JpegFixture.ParseJpegStream(imageFile)) { sb.AppendLine(imageFile); - sb.AppendLine($"Size:{decoder.ImageSizeInPixels} MCU:{decoder.ImageSizeInMCU}"); + sb.AppendLine($"Size:{decoder.Frame.PixelSize} MCU:{decoder.Frame.McuSize}"); JpegComponent c0 = decoder.Components[0]; JpegComponent c1 = decoder.Components[1]; @@ -106,7 +105,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg using (JpegDecoderCore decoder = JpegFixture.ParseJpegStream(imageFile)) { - Assert.Equal(componentCount, decoder.ComponentCount); + Assert.Equal(componentCount, decoder.Frame.ComponentCount); Assert.Equal(componentCount, decoder.Components.Length); JpegComponent c0 = decoder.Components[0]; @@ -115,7 +114,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg var uniform1 = new Size(1, 1); - Size expectedLumaSizeInBlocks = decoder.ImageSizeInMCU.MultiplyBy(fLuma); + Size expectedLumaSizeInBlocks = decoder.Frame.McuSize.MultiplyBy(fLuma); Size divisor = fLuma.DivideBy(fChroma); diff --git a/tests/ImageSharp.Tests/Formats/Jpg/ProfileResolverTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/ProfileResolverTests.cs index 8d2328a3a..6f52cb919 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/ProfileResolverTests.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/ProfileResolverTests.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. using System.Text; - using SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder; using Xunit; diff --git a/tests/ImageSharp.Tests/Formats/Jpg/QuantizationTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/QuantizationTests.cs new file mode 100644 index 000000000..e9fe3d067 --- /dev/null +++ b/tests/ImageSharp.Tests/Formats/Jpg/QuantizationTests.cs @@ -0,0 +1,45 @@ +// Copyright (c) Six Labors. +// Licensed under the Apache License, Version 2.0. + +using SixLabors.ImageSharp.Formats.Jpeg.Components; +using Xunit; +using JpegQuantization = SixLabors.ImageSharp.Formats.Jpeg.Components.Quantization; + +namespace SixLabors.ImageSharp.Tests.Formats.Jpg +{ + [Trait("Format", "Jpg")] + public class QuantizationTests + { + [Fact] + public void QualityEstimationFromStandardEncoderTables_Luminance() + { + int firstIndex = JpegQuantization.QualityEstimationConfidenceLowerThreshold; + int lastIndex = JpegQuantization.QualityEstimationConfidenceUpperThreshold; + for (int quality = firstIndex; quality <= lastIndex; quality++) + { + Block8x8F table = JpegQuantization.ScaleLuminanceTable(quality); + int estimatedQuality = JpegQuantization.EstimateLuminanceQuality(ref table); + + Assert.True( + quality.Equals(estimatedQuality), + $"Failed to estimate luminance quality for standard table at quality level {quality}"); + } + } + + [Fact] + public void QualityEstimationFromStandardEncoderTables_Chrominance() + { + int firstIndex = JpegQuantization.QualityEstimationConfidenceLowerThreshold; + int lastIndex = JpegQuantization.QualityEstimationConfidenceUpperThreshold; + for (int quality = firstIndex; quality <= lastIndex; quality++) + { + Block8x8F table = JpegQuantization.ScaleChrominanceTable(quality); + int estimatedQuality = JpegQuantization.EstimateChrominanceQuality(ref table); + + Assert.True( + quality.Equals(estimatedQuality), + $"Failed to estimate chrominance quality for standard table at quality level {quality}"); + } + } + } +} diff --git a/tests/ImageSharp.Tests/Formats/Jpg/ReferenceImplementationsTests.StandardIntegerDCT.cs b/tests/ImageSharp.Tests/Formats/Jpg/ReferenceImplementationsTests.StandardIntegerDCT.cs index c7bf9d1b6..6e25334f2 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/ReferenceImplementationsTests.StandardIntegerDCT.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/ReferenceImplementationsTests.StandardIntegerDCT.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. using System; - using SixLabors.ImageSharp.Formats.Jpeg.Components; using SixLabors.ImageSharp.Tests.Formats.Jpg.Utils; diff --git a/tests/ImageSharp.Tests/Formats/Jpg/ReferenceImplementationsTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/ReferenceImplementationsTests.cs index d3077a6e3..5c7c3267d 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/ReferenceImplementationsTests.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/ReferenceImplementationsTests.cs @@ -15,4 +15,4 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg { } } -} \ No newline at end of file +} diff --git a/tests/ImageSharp.Tests/Formats/Jpg/SpectralJpegTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/SpectralJpegTests.cs index 91b1b9cd7..1785f3dec 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/SpectralJpegTests.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/SpectralJpegTests.cs @@ -4,9 +4,11 @@ using System; using System.IO; using System.Linq; - using SixLabors.ImageSharp.Formats.Jpeg; +using SixLabors.ImageSharp.Formats.Jpeg.Components; +using SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder; using SixLabors.ImageSharp.IO; +using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.Tests.Formats.Jpg.Utils; @@ -19,10 +21,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg [Trait("Format", "Jpg")] public class SpectralJpegTests { - public SpectralJpegTests(ITestOutputHelper output) - { - this.Output = output; - } + public SpectralJpegTests(ITestOutputHelper output) => this.Output = output; private ITestOutputHelper Output { get; } @@ -48,16 +47,20 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg public void Decoder_ParseStream_SaveSpectralResult(TestImageProvider provider) where TPixel : unmanaged, IPixel { - var decoder = new JpegDecoderCore(Configuration.Default, new JpegDecoder()); - + // Calculating data from ImageSharp byte[] sourceBytes = TestFile.Create(provider.SourceFileOrDescription).Bytes; + var decoder = new JpegDecoderCore(Configuration.Default, new JpegDecoder()); using var ms = new MemoryStream(sourceBytes); using var bufferedStream = new BufferedReadStream(Configuration.Default, ms); - decoder.ParseStream(bufferedStream); - var data = LibJpegTools.SpectralData.LoadFromImageSharpDecoder(decoder); - VerifyJpeg.SaveSpectralImage(provider, data); + // internal scan decoder which we substitute to assert spectral correctness + var debugConverter = new DebugSpectralConverter(); + var scanDecoder = new HuffmanScanDecoder(bufferedStream, debugConverter, cancellationToken: default); + + // This would parse entire image + decoder.ParseStream(bufferedStream, scanDecoder, cancellationToken: default); + VerifyJpeg.SaveSpectralImage(provider, debugConverter.SpectralData); } [Theory] @@ -70,25 +73,31 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg return; } - var decoder = new JpegDecoderCore(Configuration.Default, new JpegDecoder()); + // Expected data from libjpeg + LibJpegTools.SpectralData libJpegData = LibJpegTools.ExtractSpectralData(provider.SourceFileOrDescription); + // Calculating data from ImageSharp byte[] sourceBytes = TestFile.Create(provider.SourceFileOrDescription).Bytes; + var decoder = new JpegDecoderCore(Configuration.Default, new JpegDecoder()); using var ms = new MemoryStream(sourceBytes); using var bufferedStream = new BufferedReadStream(Configuration.Default, ms); - decoder.ParseStream(bufferedStream); - var imageSharpData = LibJpegTools.SpectralData.LoadFromImageSharpDecoder(decoder); - this.VerifySpectralCorrectnessImpl(provider, imageSharpData); + // internal scan decoder which we substitute to assert spectral correctness + var debugConverter = new DebugSpectralConverter(); + var scanDecoder = new HuffmanScanDecoder(bufferedStream, debugConverter, cancellationToken: default); + + // This would parse entire image + decoder.ParseStream(bufferedStream, scanDecoder, cancellationToken: default); + + // Actual verification + this.VerifySpectralCorrectnessImpl(libJpegData, debugConverter.SpectralData); } - private void VerifySpectralCorrectnessImpl( - TestImageProvider provider, + private void VerifySpectralCorrectnessImpl( + LibJpegTools.SpectralData libJpegData, LibJpegTools.SpectralData imageSharpData) - where TPixel : unmanaged, IPixel { - LibJpegTools.SpectralData libJpegData = LibJpegTools.ExtractSpectralData(provider.SourceFileOrDescription); - bool equality = libJpegData.Equals(imageSharpData); this.Output.WriteLine("Spectral data equality: " + equality); @@ -108,11 +117,11 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg LibJpegTools.ComponentData libJpegComponent = libJpegData.Components[i]; LibJpegTools.ComponentData imageSharpComponent = imageSharpData.Components[i]; - (double total, double average) diff = LibJpegTools.CalculateDifference(libJpegComponent, imageSharpComponent); + (double total, double average) = LibJpegTools.CalculateDifference(libJpegComponent, imageSharpComponent); - this.Output.WriteLine($"Component{i}: {diff}"); - averageDifference += diff.average; - totalDifference += diff.total; + this.Output.WriteLine($"Component{i}: [total: {total} | average: {average}]"); + averageDifference += average; + totalDifference += total; tolerance += libJpegComponent.SpectralBlocks.DangerousGetSingleSpan().Length; } @@ -126,5 +135,71 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg Assert.True(totalDifference < tolerance); } + + private class DebugSpectralConverter : SpectralConverter + where TPixel : unmanaged, IPixel + { + private JpegFrame frame; + + private LibJpegTools.SpectralData spectralData; + + private int baselineScanRowCounter; + + public LibJpegTools.SpectralData SpectralData + { + get + { + // Due to underlying architecture, baseline interleaved jpegs would inject spectral data during parsing + // Progressive and multi-scan images must be loaded manually + if (this.frame.Progressive || this.frame.MultiScan) + { + LibJpegTools.ComponentData[] components = this.spectralData.Components; + for (int i = 0; i < components.Length; i++) + { + components[i].LoadSpectral(this.frame.Components[i]); + } + } + + return this.spectralData; + } + } + + public override void ConvertStrideBaseline() + { + // This would be called only for baseline non-interleaved images + // We must copy spectral strides here + LibJpegTools.ComponentData[] components = this.spectralData.Components; + for (int i = 0; i < components.Length; i++) + { + components[i].LoadSpectralStride(this.frame.Components[i].SpectralBlocks, this.baselineScanRowCounter); + } + + this.baselineScanRowCounter++; + + // As spectral buffers are reused for each stride decoding - we need to manually clear it like it's done in SpectralConverter + foreach (JpegComponent component in this.frame.Components) + { + Buffer2D spectralBlocks = component.SpectralBlocks; + for (int i = 0; i < spectralBlocks.Height; i++) + { + spectralBlocks.GetRowSpan(i).Clear(); + } + } + } + + public override void InjectFrameData(JpegFrame frame, IRawJpegData jpegData) + { + this.frame = frame; + + var spectralComponents = new LibJpegTools.ComponentData[frame.ComponentCount]; + for (int i = 0; i < spectralComponents.Length; i++) + { + JpegComponent component = frame.Components[i]; + spectralComponents[i] = new LibJpegTools.ComponentData(component.WidthInBlocks, component.HeightInBlocks, component.Index); + } + + this.spectralData = new LibJpegTools.SpectralData(spectralComponents); + } + } } } diff --git a/tests/ImageSharp.Tests/Formats/Jpg/SpectralToPixelConversionTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/SpectralToPixelConversionTests.cs new file mode 100644 index 000000000..f0f92d763 --- /dev/null +++ b/tests/ImageSharp.Tests/Formats/Jpg/SpectralToPixelConversionTests.cs @@ -0,0 +1,69 @@ +// Copyright (c) Six Labors. +// Licensed under the Apache License, Version 2.0. + +using System.IO; +using System.Linq; +using SixLabors.ImageSharp.Formats.Jpeg; +using SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder; +using SixLabors.ImageSharp.IO; +using SixLabors.ImageSharp.Metadata; +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison; +using Xunit; +using Xunit.Abstractions; + +namespace SixLabors.ImageSharp.Tests.Formats.Jpg +{ + [Trait("Format", "Jpg")] + public class SpectralToPixelConversionTests + { + public static readonly string[] BaselineTestJpegs = + { + TestImages.Jpeg.Baseline.Calliphora, TestImages.Jpeg.Baseline.Cmyk, TestImages.Jpeg.Baseline.Jpeg400, + TestImages.Jpeg.Baseline.Jpeg444, TestImages.Jpeg.Baseline.Testorig420, + TestImages.Jpeg.Baseline.Jpeg420Small, TestImages.Jpeg.Baseline.Bad.BadEOF, + TestImages.Jpeg.Baseline.MultiScanBaselineCMYK + }; + + public SpectralToPixelConversionTests(ITestOutputHelper output) + { + this.Output = output; + } + + private ITestOutputHelper Output { get; } + + [Theory] + [WithFileCollection(nameof(BaselineTestJpegs), PixelTypes.Rgba32)] + public void Decoder_PixelBufferComparison(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + // Stream + byte[] sourceBytes = TestFile.Create(provider.SourceFileOrDescription).Bytes; + using var ms = new MemoryStream(sourceBytes); + using var bufferedStream = new BufferedReadStream(Configuration.Default, ms); + + // Decoding + using var converter = new SpectralConverter(Configuration.Default, cancellationToken: default); + var decoder = new JpegDecoderCore(Configuration.Default, new JpegDecoder()); + var scanDecoder = new HuffmanScanDecoder(bufferedStream, converter, cancellationToken: default); + decoder.ParseStream(bufferedStream, scanDecoder, cancellationToken: default); + + // Test metadata + provider.Utility.TestGroupName = nameof(JpegDecoderTests); + provider.Utility.TestName = JpegDecoderTests.DecodeBaselineJpegOutputName; + + // Comparison + using (Image image = new Image(Configuration.Default, converter.GetPixelBuffer(), new ImageMetadata())) + using (Image referenceImage = provider.GetReferenceOutputImage(appendPixelTypeToFileName: false)) + { + ImageSimilarityReport report = ImageComparer.Exact.CompareImagesOrFrames(referenceImage, image); + + this.Output.WriteLine($"*** {provider.SourceFileOrDescription} ***"); + this.Output.WriteLine($"Difference: {report.DifferencePercentageString}"); + + // ReSharper disable once PossibleInvalidOperationException + Assert.True(report.TotalNormalizedDifference.Value < 0.005f); + } + } + } +} diff --git a/tests/ImageSharp.Tests/Formats/Jpg/Utils/JpegFixture.cs b/tests/ImageSharp.Tests/Formats/Jpg/Utils/JpegFixture.cs index c6f4704f0..a76b2bf2e 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/Utils/JpegFixture.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/Utils/JpegFixture.cs @@ -5,10 +5,10 @@ using System; using System.Diagnostics; using System.IO; using System.Text; - using SixLabors.ImageSharp.Formats.Jpeg; using SixLabors.ImageSharp.Formats.Jpeg.Components; using SixLabors.ImageSharp.IO; +using SixLabors.ImageSharp.PixelFormats; using Xunit; using Xunit.Abstractions; @@ -189,6 +189,38 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg.Utils Assert.False(failed); } + internal static bool CompareBlocks(Block8x8 a, Block8x8 b, int tolerance, out int diff) + { + bool res = CompareBlocks(a.AsFloatBlock(), b.AsFloatBlock(), tolerance + 1e-5f, out float fdiff); + diff = (int)fdiff; + return res; + } + + internal static bool CompareBlocks(Block8x8F a, Block8x8F b, float tolerance, out float diff) => + CompareBlocks(a.ToArray(), b.ToArray(), tolerance, out diff); + + internal static bool CompareBlocks(Span a, Span b, float tolerance, out float diff) + { + var comparer = new ApproximateFloatComparer(tolerance); + bool failed = false; + + diff = 0; + + for (int i = 0; i < 64; i++) + { + float expected = a[i]; + float actual = b[i]; + diff += Math.Abs(expected - actual); + + if (!comparer.Equals(expected, actual)) + { + failed = true; + } + } + + return !failed; + } + internal static JpegDecoderCore ParseJpegStream(string testFileName, bool metaDataOnly = false) { byte[] bytes = TestFile.Create(testFileName).Bytes; @@ -196,7 +228,14 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg.Utils using var bufferedStream = new BufferedReadStream(Configuration.Default, ms); var decoder = new JpegDecoderCore(Configuration.Default, new JpegDecoder()); - decoder.ParseStream(bufferedStream, metaDataOnly); + if (metaDataOnly) + { + decoder.Identify(bufferedStream, cancellationToken: default); + } + else + { + using Image image = decoder.Decode(bufferedStream, cancellationToken: default); + } return decoder; } diff --git a/tests/ImageSharp.Tests/Formats/Jpg/Utils/LibJpegTools.ComponentData.cs b/tests/ImageSharp.Tests/Formats/Jpg/Utils/LibJpegTools.ComponentData.cs index 6f6032ee2..adbd695c0 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/Utils/LibJpegTools.ComponentData.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/Utils/LibJpegTools.ComponentData.cs @@ -4,7 +4,6 @@ using System; using System.Linq; using System.Numerics; - using SixLabors.ImageSharp.Formats.Jpeg.Components; using SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder; using SixLabors.ImageSharp.Memory; @@ -53,26 +52,51 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg.Utils { this.MinVal = Math.Min(this.MinVal, data.Min()); this.MaxVal = Math.Max(this.MaxVal, data.Max()); - this.SpectralBlocks[x, y] = new Block8x8(data); + this.SpectralBlocks[x, y] = Block8x8.Load(data); } - public static ComponentData Load(JpegComponent c, int index) + public void LoadSpectralStride(Buffer2D data, int strideIndex) { - var result = new ComponentData( - c.WidthInBlocks, - c.HeightInBlocks, - index); + int startIndex = strideIndex * data.Height; + + int endIndex = Math.Min(this.HeightInBlocks, startIndex + data.Height); + + for (int y = startIndex; y < endIndex; y++) + { + Span blockRow = data.GetRowSpan(y - startIndex); + for (int x = 0; x < this.WidthInBlocks; x++) + { + short[] block = blockRow[x].ToArray(); + + // x coordinate stays the same - we load entire stride + // y coordinate is tricky as we load single stride to full buffer - offset is needed + this.MakeBlock(block, y, x); + } + } + } - for (int y = 0; y < result.HeightInBlocks; y++) + public void LoadSpectral(JpegComponent c) + { + Buffer2D data = c.SpectralBlocks; + for (int y = 0; y < this.HeightInBlocks; y++) { - Span blockRow = c.SpectralBlocks.GetRowSpan(y); - for (int x = 0; x < result.WidthInBlocks; x++) + Span blockRow = data.GetRowSpan(y); + for (int x = 0; x < this.WidthInBlocks; x++) { - short[] data = blockRow[x].ToArray(); - result.MakeBlock(data, y, x); + short[] block = blockRow[x].ToArray(); + this.MakeBlock(block, y, x); } } + } + + public static ComponentData Load(JpegComponent c, int index) + { + var result = new ComponentData( + c.WidthInBlocks, + c.HeightInBlocks, + index); + result.LoadSpectral(c); return result; } diff --git a/tests/ImageSharp.Tests/Formats/Jpg/Utils/LibJpegTools.SpectralData.cs b/tests/ImageSharp.Tests/Formats/Jpg/Utils/LibJpegTools.SpectralData.cs index 6ed7c15ae..2caad95b3 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/Utils/LibJpegTools.SpectralData.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/Utils/LibJpegTools.SpectralData.cs @@ -4,7 +4,6 @@ using System; using System.Linq; using System.Numerics; - using SixLabors.ImageSharp.Formats.Jpeg; using SixLabors.ImageSharp.Formats.Jpeg.Components; using SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder; @@ -29,14 +28,6 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg.Utils this.Components = components; } - public static SpectralData LoadFromImageSharpDecoder(JpegDecoderCore decoder) - { - JpegComponent[] srcComponents = decoder.Frame.Components; - LibJpegTools.ComponentData[] destComponents = srcComponents.Select(LibJpegTools.ComponentData.Load).ToArray(); - - return new SpectralData(destComponents); - } - public Image TryCreateRGBSpectralImage() { if (this.ComponentCount != 3) diff --git a/tests/ImageSharp.Tests/Formats/Jpg/Utils/LibJpegTools.cs b/tests/ImageSharp.Tests/Formats/Jpg/Utils/LibJpegTools.cs index 60187a860..b74e4445e 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/Utils/LibJpegTools.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/Utils/LibJpegTools.cs @@ -6,7 +6,6 @@ using System.Diagnostics; using System.IO; using System.Numerics; using System.Runtime.InteropServices; - using SixLabors.ImageSharp.Formats.Jpeg.Components; namespace SixLabors.ImageSharp.Tests.Formats.Jpg.Utils @@ -16,7 +15,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg.Utils /// internal static partial class LibJpegTools { - public static (double total, double average) CalculateDifference(ComponentData expected, ComponentData actual) + public static (double Total, double Average) CalculateDifference(ComponentData expected, ComponentData actual) { BigInteger totalDiff = 0; if (actual.WidthInBlocks < expected.WidthInBlocks) diff --git a/tests/ImageSharp.Tests/Formats/Jpg/Utils/ReferenceImplementations.AccurateDCT.cs b/tests/ImageSharp.Tests/Formats/Jpg/Utils/ReferenceImplementations.AccurateDCT.cs index e70bdc8cc..d640aebbb 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/Utils/ReferenceImplementations.AccurateDCT.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/Utils/ReferenceImplementations.AccurateDCT.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. using System; - using SixLabors.ImageSharp.Formats.Jpeg.Components; namespace SixLabors.ImageSharp.Tests.Formats.Jpg.Utils diff --git a/tests/ImageSharp.Tests/Formats/Jpg/Utils/ReferenceImplementations.LLM_FloatingPoint_DCT.cs b/tests/ImageSharp.Tests/Formats/Jpg/Utils/ReferenceImplementations.LLM_FloatingPoint_DCT.cs index 3d113ffd0..b917821b0 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/Utils/ReferenceImplementations.LLM_FloatingPoint_DCT.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/Utils/ReferenceImplementations.LLM_FloatingPoint_DCT.cs @@ -4,7 +4,6 @@ using System; using System.Numerics; using System.Runtime.CompilerServices; - using SixLabors.ImageSharp.Formats.Jpeg.Components; using Xunit.Abstractions; diff --git a/tests/ImageSharp.Tests/Formats/Jpg/Utils/ReferenceImplementations.StandardIntegerDCT.cs b/tests/ImageSharp.Tests/Formats/Jpg/Utils/ReferenceImplementations.StandardIntegerDCT.cs index 45159ba6f..b34a8bc00 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/Utils/ReferenceImplementations.StandardIntegerDCT.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/Utils/ReferenceImplementations.StandardIntegerDCT.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. using System; - using SixLabors.ImageSharp.Formats.Jpeg.Components; // ReSharper disable InconsistentNaming diff --git a/tests/ImageSharp.Tests/Formats/Jpg/Utils/ReferenceImplementations.cs b/tests/ImageSharp.Tests/Formats/Jpg/Utils/ReferenceImplementations.cs index 2c673f30e..c9741521c 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/Utils/ReferenceImplementations.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/Utils/ReferenceImplementations.cs @@ -3,7 +3,6 @@ using System; using System.Runtime.CompilerServices; - using SixLabors.ImageSharp.Formats.Jpeg.Components; // ReSharper disable InconsistentNaming @@ -15,18 +14,12 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg.Utils /// internal static partial class ReferenceImplementations { - public static unsafe void DequantizeBlock(Block8x8F* blockPtr, Block8x8F* qtPtr, byte* unzigPtr) + public static void DequantizeBlock(ref Block8x8F block, ref Block8x8F qt, ReadOnlySpan zigzag) { - float* b = (float*)blockPtr; - float* qtp = (float*)qtPtr; - for (int qtIndex = 0; qtIndex < Block8x8F.Size; qtIndex++) + for (int i = 0; i < Block8x8F.Size; i++) { - byte i = unzigPtr[qtIndex]; - float* unzigPos = b + i; - - float val = *unzigPos; - val *= qtp[qtIndex]; - *unzigPos = val; + int zig = zigzag[i]; + block[zig] *= qt[i]; } } @@ -101,42 +94,18 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg.Utils /// /// Reference implementation to test . - /// Rounding is done used an integer-based algorithm defined in . - /// - /// The input block - /// The destination block of integers - /// The quantization table - /// Pointer to - public static unsafe void QuantizeRational(Block8x8F* src, int* dest, Block8x8F* qt, byte* unzigPtr) - { - float* s = (float*)src; - float* q = (float*)qt; - - for (int zig = 0; zig < Block8x8F.Size; zig++) - { - int a = (int)s[unzigPtr[zig]]; - int b = (int)q[zig]; - - int val = RationalRound(a, b); - dest[zig] = val; - } - } - - /// - /// Rounds a rational number defined as dividend/divisor into an integer. /// - /// The dividend. - /// The divisor. - /// The rounded value. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static int RationalRound(int dividend, int divisor) + /// The input block. + /// The destination block of 16bit integers. + /// The quantization table. + /// Zig-Zag index sequence span. + public static void Quantize(ref Block8x8F src, ref Block8x8 dest, ref Block8x8F qt, ReadOnlySpan zigzag) { - if (dividend >= 0) + for (int i = 0; i < Block8x8F.Size; i++) { - return (dividend + (divisor >> 1)) / divisor; + int zig = zigzag[i]; + dest[i] = (short)Math.Round(src[zig] / qt[zig], MidpointRounding.AwayFromZero); } - - return -((-dividend + (divisor >> 1)) / divisor); } } } diff --git a/tests/ImageSharp.Tests/Formats/Jpg/Utils/VerifyJpeg.cs b/tests/ImageSharp.Tests/Formats/Jpg/Utils/VerifyJpeg.cs index 10717dfcf..e83b3b53d 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/Utils/VerifyJpeg.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/Utils/VerifyJpeg.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.Linq; - using SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder; using SixLabors.ImageSharp.PixelFormats; diff --git a/tests/ImageSharp.Tests/Formats/Jpg/ZigZagTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/ZigZagTests.cs index e03cf9958..39046438a 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/ZigZagTests.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/ZigZagTests.cs @@ -13,8 +13,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg public void ZigZagCanHandleAllPossibleCoefficients() { // Mimic the behaviour of the huffman scan decoder using all possible byte values - var block = new short[64]; - var zigzag = ZigZag.CreateUnzigTable(); + short[] block = new short[64]; for (int h = 0; h < 255; h++) { @@ -27,7 +26,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg if (s != 0) { i += r; - block[zigzag[i++]] = (short)s; + block[ZigZag.ZigZagOrder[i++]] = (short)s; } else { diff --git a/tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.Chunks.cs b/tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.Chunks.cs index 150b3bd0a..8b6432ac3 100644 --- a/tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.Chunks.cs +++ b/tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.Chunks.cs @@ -4,7 +4,6 @@ using System.Buffers.Binary; using System.IO; using System.Text; - using SixLabors.ImageSharp.Formats.Png; using SixLabors.ImageSharp.PixelFormats; diff --git a/tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs index 9832aeb7b..9fc4d03dd 100644 --- a/tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Png/PngDecoderTests.cs @@ -368,6 +368,24 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png Assert.Null(ex); } + // https://github.com/SixLabors/ImageSharp/issues/1765 + [Theory] + [WithFile(TestImages.Png.Issue1765_Net6DeflateStreamRead, PixelTypes.Rgba32)] + public void Issue1765(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + System.Exception ex = Record.Exception( + () => + { + using (Image image = provider.GetImage(PngDecoder)) + { + image.DebugSave(provider); + image.CompareToOriginal(provider, ImageComparer.Exact); + } + }); + Assert.Null(ex); + } + // https://github.com/SixLabors/ImageSharp/issues/410 [Theory] [WithFile(TestImages.Png.Bad.Issue410_MalformedApplePng, PixelTypes.Rgba32)] diff --git a/tests/ImageSharp.Tests/Formats/Png/PngEncoderTests.Chunks.cs b/tests/ImageSharp.Tests/Formats/Png/PngEncoderTests.Chunks.cs index 06cde65f8..30a684702 100644 --- a/tests/ImageSharp.Tests/Formats/Png/PngEncoderTests.Chunks.cs +++ b/tests/ImageSharp.Tests/Formats/Png/PngEncoderTests.Chunks.cs @@ -5,7 +5,6 @@ using System; using System.Buffers.Binary; using System.Collections.Generic; using System.IO; - using SixLabors.ImageSharp.Formats.Png; using SixLabors.ImageSharp.PixelFormats; diff --git a/tests/ImageSharp.Tests/Formats/Png/PngFilterTests.cs b/tests/ImageSharp.Tests/Formats/Png/PngFilterTests.cs index 80bfd3497..9b6119380 100644 --- a/tests/ImageSharp.Tests/Formats/Png/PngFilterTests.cs +++ b/tests/ImageSharp.Tests/Formats/Png/PngFilterTests.cs @@ -4,7 +4,6 @@ // Uncomment this to turn unit tests into benchmarks: // #define BENCHMARKING using System; - using SixLabors.ImageSharp.Formats.Png; using SixLabors.ImageSharp.Formats.Png.Filters; using SixLabors.ImageSharp.Tests.TestUtilities; diff --git a/tests/ImageSharp.Tests/Formats/Tga/TgaDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Tga/TgaDecoderTests.cs index ac94a8fc8..1c53ff6a1 100644 --- a/tests/ImageSharp.Tests/Formats/Tga/TgaDecoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tga/TgaDecoderTests.cs @@ -10,7 +10,6 @@ using SixLabors.ImageSharp.Tests.TestUtilities; using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison; using Xunit; - using static SixLabors.ImageSharp.Tests.TestImages.Tga; // ReSharper disable InconsistentNaming diff --git a/tests/ImageSharp.Tests/Formats/Tga/TgaEncoderTests.cs b/tests/ImageSharp.Tests/Formats/Tga/TgaEncoderTests.cs index 1ad4f9a84..4c768a1a5 100644 --- a/tests/ImageSharp.Tests/Formats/Tga/TgaEncoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tga/TgaEncoderTests.cs @@ -2,12 +2,10 @@ // Licensed under the Apache License, Version 2.0. using System.IO; - using SixLabors.ImageSharp.Formats.Tga; using SixLabors.ImageSharp.PixelFormats; using Xunit; - using static SixLabors.ImageSharp.Tests.TestImages.Tga; // ReSharper disable InconsistentNaming diff --git a/tests/ImageSharp.Tests/Formats/Tga/TgaFileHeaderTests.cs b/tests/ImageSharp.Tests/Formats/Tga/TgaFileHeaderTests.cs index 61ddf37b7..2cdca3ff7 100644 --- a/tests/ImageSharp.Tests/Formats/Tga/TgaFileHeaderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tga/TgaFileHeaderTests.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. using System.IO; - using SixLabors.ImageSharp.Formats; using SixLabors.ImageSharp.Formats.Tga; diff --git a/tests/ImageSharp.Tests/Formats/Tga/TgaTestUtils.cs b/tests/ImageSharp.Tests/Formats/Tga/TgaTestUtils.cs index 58ed31e61..c96777031 100644 --- a/tests/ImageSharp.Tests/Formats/Tga/TgaTestUtils.cs +++ b/tests/ImageSharp.Tests/Formats/Tga/TgaTestUtils.cs @@ -3,7 +3,6 @@ using System; using System.IO; - using ImageMagick; using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison; diff --git a/tests/ImageSharp.Tests/Formats/Tiff/Compression/DeflateTiffCompressionTests.cs b/tests/ImageSharp.Tests/Formats/Tiff/Compression/DeflateTiffCompressionTests.cs index 782a504d5..ff7025b50 100644 --- a/tests/ImageSharp.Tests/Formats/Tiff/Compression/DeflateTiffCompressionTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tiff/Compression/DeflateTiffCompressionTests.cs @@ -5,6 +5,7 @@ using System.IO; using SixLabors.ImageSharp.Compression.Zlib; using SixLabors.ImageSharp.Formats.Tiff.Compression.Decompressors; using SixLabors.ImageSharp.Formats.Tiff.Constants; +using SixLabors.ImageSharp.Formats.Tiff.PhotometricInterpretation; using SixLabors.ImageSharp.IO; using Xunit; @@ -26,9 +27,9 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff.Compression { var buffer = new byte[data.Length]; - using var decompressor = new DeflateTiffCompression(Configuration.Default.MemoryAllocator, 10, 8, TiffPredictor.None); + using var decompressor = new DeflateTiffCompression(Configuration.Default.MemoryAllocator, 10, 8, TiffColorType.BlackIsZero8, TiffPredictor.None, false); - decompressor.Decompress(stream, 0, (uint)stream.Length, buffer); + decompressor.Decompress(stream, 0, (uint)stream.Length, 1, buffer); Assert.Equal(data, buffer); } diff --git a/tests/ImageSharp.Tests/Formats/Tiff/Compression/LzwTiffCompressionTests.cs b/tests/ImageSharp.Tests/Formats/Tiff/Compression/LzwTiffCompressionTests.cs index bf585e9c8..08705738f 100644 --- a/tests/ImageSharp.Tests/Formats/Tiff/Compression/LzwTiffCompressionTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tiff/Compression/LzwTiffCompressionTests.cs @@ -5,6 +5,7 @@ using System.IO; using SixLabors.ImageSharp.Formats.Tiff.Compression.Compressors; using SixLabors.ImageSharp.Formats.Tiff.Compression.Decompressors; using SixLabors.ImageSharp.Formats.Tiff.Constants; +using SixLabors.ImageSharp.Formats.Tiff.PhotometricInterpretation; using SixLabors.ImageSharp.IO; using Xunit; @@ -38,8 +39,8 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff.Compression using BufferedReadStream stream = CreateCompressedStream(data); var buffer = new byte[data.Length]; - using var decompressor = new LzwTiffCompression(Configuration.Default.MemoryAllocator, 10, 8, TiffPredictor.None); - decompressor.Decompress(stream, 0, (uint)stream.Length, buffer); + using var decompressor = new LzwTiffCompression(Configuration.Default.MemoryAllocator, 10, 8, TiffColorType.BlackIsZero8, TiffPredictor.None, false); + decompressor.Decompress(stream, 0, (uint)stream.Length, 1, buffer); Assert.Equal(data, buffer); } diff --git a/tests/ImageSharp.Tests/Formats/Tiff/Compression/NoneTiffCompressionTests.cs b/tests/ImageSharp.Tests/Formats/Tiff/Compression/NoneTiffCompressionTests.cs index 82ecb315b..d153e1ed2 100644 --- a/tests/ImageSharp.Tests/Formats/Tiff/Compression/NoneTiffCompressionTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tiff/Compression/NoneTiffCompressionTests.cs @@ -17,10 +17,12 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff.Compression [InlineData(new byte[] { 10, 15, 20, 25, 30, 35, 40, 45 }, 5, new byte[] { 10, 15, 20, 25, 30 })] public void Decompress_ReadsData(byte[] inputData, uint byteCount, byte[] expectedResult) { - var stream = new BufferedReadStream(Configuration.Default, new MemoryStream(inputData)); - var buffer = new byte[expectedResult.Length]; + using var memoryStream = new MemoryStream(inputData); + using var stream = new BufferedReadStream(Configuration.Default, memoryStream); + byte[] buffer = new byte[expectedResult.Length]; - new NoneTiffCompression(default, default, default).Decompress(stream, 0, byteCount, buffer); + using var decompressor = new NoneTiffCompression(default, default, default); + decompressor.Decompress(stream, 0, byteCount, 1, buffer); Assert.Equal(expectedResult, buffer); } diff --git a/tests/ImageSharp.Tests/Formats/Tiff/Compression/PackBitsTiffCompressionTests.cs b/tests/ImageSharp.Tests/Formats/Tiff/Compression/PackBitsTiffCompressionTests.cs index b67cb8325..b56c1e7c9 100644 --- a/tests/ImageSharp.Tests/Formats/Tiff/Compression/PackBitsTiffCompressionTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tiff/Compression/PackBitsTiffCompressionTests.cs @@ -26,11 +26,12 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff.Compression [InlineData(new byte[] { 0xFE, 0xAA, 0x02, 0x80, 0x00, 0x2A, 0xFD, 0xAA, 0x03, 0x80, 0x00, 0x2A, 0x22, 0xF7, 0xAA }, new byte[] { 0xAA, 0xAA, 0xAA, 0x80, 0x00, 0x2A, 0xAA, 0xAA, 0xAA, 0xAA, 0x80, 0x00, 0x2A, 0x22, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA })] // Apple PackBits sample public void Decompress_ReadsData(byte[] inputData, byte[] expectedResult) { - var stream = new BufferedReadStream(Configuration.Default, new MemoryStream(inputData)); - var buffer = new byte[expectedResult.Length]; + using var memoryStream = new MemoryStream(inputData); + using var stream = new BufferedReadStream(Configuration.Default, memoryStream); + byte[] buffer = new byte[expectedResult.Length]; using var decompressor = new PackBitsTiffCompression(new ArrayPoolMemoryAllocator(), default, default); - decompressor.Decompress(stream, 0, (uint)inputData.Length, buffer); + decompressor.Decompress(stream, 0, (uint)inputData.Length, 1, buffer); Assert.Equal(expectedResult, buffer); } @@ -41,7 +42,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff.Compression { // arrange Span input = inputData.AsSpan(); - var compressed = new byte[expectedResult.Length]; + byte[] compressed = new byte[expectedResult.Length]; // act PackBitsWriter.PackBits(input, compressed); diff --git a/tests/ImageSharp.Tests/Formats/Tiff/PhotometricInterpretation/BlackIsZeroTiffColorTests.cs b/tests/ImageSharp.Tests/Formats/Tiff/PhotometricInterpretation/BlackIsZeroTiffColorTests.cs index 769ab850e..38611c6f3 100644 --- a/tests/ImageSharp.Tests/Formats/Tiff/PhotometricInterpretation/BlackIsZeroTiffColorTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tiff/PhotometricInterpretation/BlackIsZeroTiffColorTests.cs @@ -188,7 +188,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff.PhotometricInterpretation { AssertDecode(expectedResult, pixels => { - new BlackIsZero8TiffColor().Decode(inputData, pixels, left, top, width, height); + new BlackIsZero8TiffColor(Configuration.Default).Decode(inputData, pixels, left, top, width, height); }); } } diff --git a/tests/ImageSharp.Tests/Formats/Tiff/PhotometricInterpretation/RgbTiffColorTests.cs b/tests/ImageSharp.Tests/Formats/Tiff/PhotometricInterpretation/RgbTiffColorTests.cs index 9adf59e48..f9f633106 100644 --- a/tests/ImageSharp.Tests/Formats/Tiff/PhotometricInterpretation/RgbTiffColorTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tiff/PhotometricInterpretation/RgbTiffColorTests.cs @@ -179,7 +179,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff.PhotometricInterpretation { AssertDecode(expectedResult, pixels => { - new Rgb888TiffColor().Decode(inputData, pixels, left, top, width, height); + new Rgb888TiffColor(Configuration.Default).Decode(inputData, pixels, left, top, width, height); }); } } diff --git a/tests/ImageSharp.Tests/Formats/Tiff/TiffDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Tiff/TiffDecoderTests.cs index a007cd3a9..4a13bbe62 100644 --- a/tests/ImageSharp.Tests/Formats/Tiff/TiffDecoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tiff/TiffDecoderTests.cs @@ -10,9 +10,7 @@ using SixLabors.ImageSharp.Metadata; using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison; using SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs; - using Xunit; - using static SixLabors.ImageSharp.Tests.TestImages.Tiff; namespace SixLabors.ImageSharp.Tests.Formats.Tiff @@ -23,21 +21,21 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff { public static readonly string[] MultiframeTestImages = Multiframes; - public static readonly string[] NotSupportedImages = NotSupported; - private static TiffDecoder TiffDecoder => new TiffDecoder(); private static MagickReferenceDecoder ReferenceDecoder => new MagickReferenceDecoder(); [Theory] - [WithFileCollection(nameof(NotSupportedImages), PixelTypes.Rgba32)] + [WithFile(RgbUncompressedTiled, PixelTypes.Rgba32)] + [WithFile(MultiframeDifferentSize, PixelTypes.Rgba32)] + [WithFile(MultiframeDifferentVariants, PixelTypes.Rgba32)] public void ThrowsNotSupported(TestImageProvider provider) where TPixel : unmanaged, IPixel => Assert.Throws(() => provider.GetImage(TiffDecoder)); [Theory] [InlineData(RgbUncompressed, 24, 256, 256, 300, 300, PixelResolutionUnit.PixelsPerInch)] [InlineData(SmallRgbDeflate, 24, 32, 32, 96, 96, PixelResolutionUnit.PixelsPerInch)] - [InlineData(Calliphora_GrayscaleUncompressed, 8, 804, 1198, 96, 96, PixelResolutionUnit.PixelsPerInch)] + [InlineData(Calliphora_GrayscaleUncompressed, 8, 200, 298, 96, 96, PixelResolutionUnit.PixelsPerInch)] [InlineData(Flower4BitPalette, 4, 73, 43, 72, 72, PixelResolutionUnit.PixelsPerInch)] public void Identify(string imagePath, int expectedPixelSize, int expectedWidth, int expectedHeight, double expectedHResolution, double expectedVResolution, PixelResolutionUnit expectedResolutionUnit) { @@ -84,6 +82,12 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff public void TiffDecoder_CanDecode_Uncompressed(TestImageProvider provider) where TPixel : unmanaged, IPixel => TestTiffDecoder(provider); + [Theory] + [WithFile(FlowerRgb888Planar6Strips, PixelTypes.Rgba32)] + [WithFile(FlowerRgb888Planar15Strips, PixelTypes.Rgba32)] + public void TiffDecoder_Planar(TestImageProvider provider) + where TPixel : unmanaged, IPixel => TestTiffDecoder(provider); + [Theory] [WithFile(Calliphora_PaletteUncompressed, PixelTypes.Rgba32)] [WithFile(PaletteDeflateMultistrip, PixelTypes.Rgba32)] @@ -107,49 +111,120 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff [Theory] [WithFile(Flower2BitGray, PixelTypes.Rgba32)] - public void TiffDecoder_CanDecode_2Bit(TestImageProvider provider) + public void TiffDecoder_CanDecode_2Bit_Gray(TestImageProvider provider) where TPixel : unmanaged, IPixel => TestTiffDecoder(provider); [Theory] [WithFile(FlowerRgb222Contiguous, PixelTypes.Rgba32)] [WithFile(FlowerRgb222Planar, PixelTypes.Rgba32)] - [WithFile(Flower6BitGray, PixelTypes.Rgba32)] public void TiffDecoder_CanDecode_6Bit(TestImageProvider provider) where TPixel : unmanaged, IPixel => TestTiffDecoder(provider); + [Theory] + [WithFile(Flower6BitGray, PixelTypes.Rgba32)] + public void TiffDecoder_CanDecode_6Bit_Gray(TestImageProvider provider) + where TPixel : unmanaged, IPixel => TestTiffDecoder(provider); + [Theory] [WithFile(Flower8BitGray, PixelTypes.Rgba32)] - public void TiffDecoder_CanDecode_8Bit(TestImageProvider provider) + public void TiffDecoder_CanDecode_8Bit_Gray(TestImageProvider provider) where TPixel : unmanaged, IPixel => TestTiffDecoder(provider); [Theory] [WithFile(Flower10BitGray, PixelTypes.Rgba32)] - public void TiffDecoder_CanDecode_10Bit(TestImageProvider provider) + public void TiffDecoder_CanDecode_10Bit_Gray(TestImageProvider provider) where TPixel : unmanaged, IPixel => TestTiffDecoder(provider); [Theory] [WithFile(FlowerRgb444Contiguous, PixelTypes.Rgba32)] [WithFile(FlowerRgb444Planar, PixelTypes.Rgba32)] - [WithFile(Flower12BitGray, PixelTypes.Rgba32)] public void TiffDecoder_CanDecode_12Bit(TestImageProvider provider) where TPixel : unmanaged, IPixel => TestTiffDecoder(provider); + [Theory] + [WithFile(Flower12BitGray, PixelTypes.Rgba32)] + public void TiffDecoder_CanDecode_12Bit_Gray(TestImageProvider provider) + where TPixel : unmanaged, IPixel => TestTiffDecoder(provider); + [Theory] [WithFile(Flower14BitGray, PixelTypes.Rgba32)] - public void TiffDecoder_CanDecode_14Bit(TestImageProvider provider) + public void TiffDecoder_CanDecode_14Bit_Gray(TestImageProvider provider) where TPixel : unmanaged, IPixel => TestTiffDecoder(provider); [Theory] + [WithFile(Flower16BitGrayLittleEndian, PixelTypes.Rgba32)] [WithFile(Flower16BitGray, PixelTypes.Rgba32)] - public void TiffDecoder_CanDecode_16Bit(TestImageProvider provider) + [WithFile(Flower16BitGrayMinIsWhiteLittleEndian, PixelTypes.Rgba32)] + [WithFile(Flower16BitGrayMinIsWhiteBigEndian, PixelTypes.Rgba32)] + public void TiffDecoder_CanDecode_16Bit_Gray(TestImageProvider provider) where TPixel : unmanaged, IPixel => TestTiffDecoder(provider); + [Theory] + [WithFile(Flower16BitGrayPredictorBigEndian, PixelTypes.Rgba32)] + [WithFile(Flower16BitGrayPredictorLittleEndian, PixelTypes.Rgba32)] + public void TiffDecoder_CanDecode_16Bit_Gray_WithPredictor(TestImageProvider provider) + where TPixel : unmanaged, IPixel => TestTiffDecoder(provider); + + [Theory] + [WithFile(Flower24BitGray, PixelTypes.Rgba32)] + [WithFile(Flower24BitGrayLittleEndian, PixelTypes.Rgba32)] + public void TiffDecoder_CanDecode_24Bit_Gray(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + // Note: because the MagickReferenceDecoder fails to load the image, we only debug save them. + using Image image = provider.GetImage(); + image.DebugSave(provider); + } + + [Theory] + [WithFile(FlowerYCbCr888Contiguous, PixelTypes.Rgba32)] + [WithFile(FlowerYCbCr888Planar, PixelTypes.Rgba32)] + [WithFile(RgbYCbCr888Contiguoush1v1, PixelTypes.Rgba32)] + [WithFile(RgbYCbCr888Contiguoush2v1, PixelTypes.Rgba32)] + [WithFile(RgbYCbCr888Contiguoush2v2, PixelTypes.Rgba32)] + [WithFile(RgbYCbCr888Contiguoush4v4, PixelTypes.Rgba32)] + [WithFile(FlowerYCbCr888Contiguoush2v1, PixelTypes.Rgba32)] + [WithFile(FlowerYCbCr888Contiguoush2v2, PixelTypes.Rgba32)] + [WithFile(FlowerYCbCr888Contiguoush4v4, PixelTypes.Rgba32)] + public void TiffDecoder_CanDecode_YCbCr_24Bit(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + // Note: The image from MagickReferenceDecoder does not look right, maybe we are doing something wrong + // converting the pixel data from Magick.Net to our format with YCbCr? + using Image image = provider.GetImage(); + image.DebugSave(provider); + } + [Theory] [WithFile(FlowerRgb101010Contiguous, PixelTypes.Rgba32)] [WithFile(FlowerRgb101010Planar, PixelTypes.Rgba32)] public void TiffDecoder_CanDecode_30Bit(TestImageProvider provider) where TPixel : unmanaged, IPixel => TestTiffDecoder(provider); + [Theory] + [WithFile(Flower32BitGray, PixelTypes.Rgba32)] + [WithFile(Flower32BitGrayLittleEndian, PixelTypes.Rgba32)] + [WithFile(Flower32BitGrayMinIsWhite, PixelTypes.Rgba32)] + [WithFile(Flower32BitGrayMinIsWhiteLittleEndian, PixelTypes.Rgba32)] + public void TiffDecoder_CanDecode_32Bit_Gray(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + // Note: because the MagickReferenceDecoder fails to load the image, we only debug save them. + using Image image = provider.GetImage(); + image.DebugSave(provider); + } + + [Theory] + [WithFile(Flower32BitGrayPredictorBigEndian, PixelTypes.Rgba32)] + [WithFile(Flower32BitGrayPredictorLittleEndian, PixelTypes.Rgba32)] + public void TiffDecoder_CanDecode_32Bit_Gray_WithPredictor(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + // Note: because the MagickReferenceDecoder fails to load the image, we only debug save them. + using Image image = provider.GetImage(); + image.DebugSave(provider); + } + [Theory] [WithFile(FlowerRgb121212Contiguous, PixelTypes.Rgba32)] public void TiffDecoder_CanDecode_36Bit(TestImageProvider provider) @@ -163,10 +238,80 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff [Theory] [WithFile(FlowerRgb161616Contiguous, PixelTypes.Rgba32)] + [WithFile(FlowerRgb161616ContiguousLittleEndian, PixelTypes.Rgba32)] [WithFile(FlowerRgb161616Planar, PixelTypes.Rgba32)] + [WithFile(FlowerRgb161616PlanarLittleEndian, PixelTypes.Rgba32)] + [WithFile(Issues1716Rgb161616BitLittleEndian, PixelTypes.Rgba32)] public void TiffDecoder_CanDecode_48Bit(TestImageProvider provider) where TPixel : unmanaged, IPixel => TestTiffDecoder(provider); + [Theory] + [WithFile(FlowerRgb161616PredictorBigEndian, PixelTypes.Rgba32)] + [WithFile(FlowerRgb161616PredictorLittleEndian, PixelTypes.Rgba32)] + public void TiffDecoder_CanDecode_48Bit_WithPredictor(TestImageProvider provider) + where TPixel : unmanaged, IPixel => TestTiffDecoder(provider); + + [Theory] + [WithFile(FlowerRgb242424Contiguous, PixelTypes.Rgba32)] + [WithFile(FlowerRgb242424ContiguousLittleEndian, PixelTypes.Rgba32)] + [WithFile(FlowerRgb242424Planar, PixelTypes.Rgba32)] + [WithFile(FlowerRgb242424PlanarLittleEndian, PixelTypes.Rgba32)] + public void TiffDecoder_CanDecode_72Bit(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + // Note: because the MagickReferenceDecoder fails to load the image, we only debug save them. + using Image image = provider.GetImage(); + image.DebugSave(provider); + } + + [Theory] + [WithFile(FlowerRgb323232Contiguous, PixelTypes.Rgba32)] + [WithFile(FlowerRgb323232ContiguousLittleEndian, PixelTypes.Rgba32)] + [WithFile(FlowerRgb323232Planar, PixelTypes.Rgba32)] + [WithFile(FlowerRgb323232PlanarLittleEndian, PixelTypes.Rgba32)] + public void TiffDecoder_CanDecode_96Bit(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + // Note: because the MagickReferenceDecoder fails to load the image, we only debug save them. + using Image image = provider.GetImage(); + image.DebugSave(provider); + } + + [Theory] + [WithFile(FlowerRgbFloat323232, PixelTypes.Rgba32)] + [WithFile(FlowerRgbFloat323232LittleEndian, PixelTypes.Rgba32)] + public void TiffDecoder_CanDecode_Float_96Bit(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + // Note: because the MagickReferenceDecoder fails to load the image, we only debug save them. + using Image image = provider.GetImage(); + image.DebugSave(provider); + } + + [Theory] + [WithFile(FlowerRgb323232PredictorBigEndian, PixelTypes.Rgba32)] + [WithFile(FlowerRgb323232PredictorLittleEndian, PixelTypes.Rgba32)] + public void TiffDecoder_CanDecode_96Bit_WithPredictor(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + // Note: because the MagickReferenceDecoder fails to load the image, we only debug save them. + using Image image = provider.GetImage(); + image.DebugSave(provider); + } + + [Theory] + [WithFile(Flower32BitFloatGray, PixelTypes.Rgba32)] + [WithFile(Flower32BitFloatGrayLittleEndian, PixelTypes.Rgba32)] + [WithFile(Flower32BitFloatGrayMinIsWhite, PixelTypes.Rgba32)] + [WithFile(Flower32BitFloatGrayMinIsWhiteLittleEndian, PixelTypes.Rgba32)] + public void TiffDecoder_CanDecode_Float_96Bit_Gray(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + // Note: because the MagickReferenceDecoder fails to load the image, we only debug save them. + using Image image = provider.GetImage(); + image.DebugSave(provider); + } + [Theory] [WithFile(GrayscaleDeflateMultistrip, PixelTypes.Rgba32)] [WithFile(RgbDeflateMultistrip, PixelTypes.Rgba32)] @@ -209,6 +354,18 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff public void TiffDecoder_CanDecode_Fax3Compressed(TestImageProvider provider) where TPixel : unmanaged, IPixel => TestTiffDecoder(provider); + [Theory] + [WithFile(Fax4Compressed, PixelTypes.Rgba32)] + [WithFile(Fax4CompressedLowerOrderBitsFirst, PixelTypes.Rgba32)] + [WithFile(Calliphora_Fax4Compressed, PixelTypes.Rgba32)] + public void TiffDecoder_CanDecode_Fax4Compressed(TestImageProvider provider) + where TPixel : unmanaged, IPixel => TestTiffDecoder(provider); + + [Theory] + [WithFile(CcittFax3LowerOrderBitsFirst, PixelTypes.Rgba32)] + public void TiffDecoder_CanDecode_Compressed_LowerOrderBitsFirst(TestImageProvider provider) + where TPixel : unmanaged, IPixel => TestTiffDecoder(provider); + [Theory] [WithFile(Calliphora_RgbPackbits, PixelTypes.Rgba32)] [WithFile(RgbPackbits, PixelTypes.Rgba32)] @@ -216,6 +373,14 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff public void TiffDecoder_CanDecode_PackBitsCompressed(TestImageProvider provider) where TPixel : unmanaged, IPixel => TestTiffDecoder(provider); + [Theory] + [WithFile(RgbJpegCompressed, PixelTypes.Rgba32)] + [WithFile(RgbWithStripsJpegCompressed, PixelTypes.Rgba32)] + [WithFile(YCbCrJpegCompressed, PixelTypes.Rgba32)] + [WithFile(RgbJpegCompressedNoJpegTable, PixelTypes.Rgba32)] + public void TiffDecoder_CanDecode_JpegCompressed(TestImageProvider provider) + where TPixel : unmanaged, IPixel => TestTiffDecoder(provider, useExactComparer: false); + [Theory] [WithFileCollection(nameof(MultiframeTestImages), PixelTypes.Rgba32)] public void DecodeMultiframe(TestImageProvider provider) diff --git a/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderBaseTester.cs b/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderBaseTester.cs new file mode 100644 index 000000000..fb2292379 --- /dev/null +++ b/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderBaseTester.cs @@ -0,0 +1,113 @@ +// Copyright (c) Six Labors. +// Licensed under the Apache License, Version 2.0. + +using System.IO; +using SixLabors.ImageSharp.Formats; +using SixLabors.ImageSharp.Formats.Tiff; +using SixLabors.ImageSharp.Formats.Tiff.Constants; +using SixLabors.ImageSharp.Metadata.Profiles.Exif; +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison; +using SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs; + +using Xunit; + +namespace SixLabors.ImageSharp.Tests.Formats.Tiff +{ + [Trait("Format", "Tiff")] + public abstract class TiffEncoderBaseTester + { + protected static readonly IImageDecoder ReferenceDecoder = new MagickReferenceDecoder(); + + protected static void TestStripLength( + TestImageProvider provider, + TiffPhotometricInterpretation photometricInterpretation, + TiffCompression compression, + bool useExactComparer = true, + float compareTolerance = 0.01f) + where TPixel : unmanaged, IPixel + { + // arrange + var tiffEncoder = new TiffEncoder() { PhotometricInterpretation = photometricInterpretation, Compression = compression }; + using Image input = provider.GetImage(); + using var memStream = new MemoryStream(); + TiffFrameMetadata inputMeta = input.Frames.RootFrame.Metadata.GetTiffMetadata(); + TiffCompression inputCompression = inputMeta.Compression ?? TiffCompression.None; + + // act + input.Save(memStream, tiffEncoder); + + // assert + memStream.Position = 0; + using var output = Image.Load(memStream); + ExifProfile exifProfileOutput = output.Frames.RootFrame.Metadata.ExifProfile; + TiffFrameMetadata outputMeta = output.Frames.RootFrame.Metadata.GetTiffMetadata(); + ImageFrame rootFrame = output.Frames.RootFrame; + + Number rowsPerStrip = exifProfileOutput.GetValue(ExifTag.RowsPerStrip) != null ? exifProfileOutput.GetValue(ExifTag.RowsPerStrip).Value : TiffConstants.RowsPerStripInfinity; + Assert.True(output.Height > (int)rowsPerStrip); + Assert.True(exifProfileOutput.GetValue(ExifTag.StripOffsets)?.Value.Length > 1); + Number[] stripByteCounts = exifProfileOutput.GetValue(ExifTag.StripByteCounts)?.Value; + Assert.NotNull(stripByteCounts); + Assert.True(stripByteCounts.Length > 1); + Assert.NotNull(outputMeta.BitsPerPixel); + + foreach (Number sz in stripByteCounts) + { + Assert.True((uint)sz <= TiffConstants.DefaultStripSize); + } + + // For uncompressed more accurate test. + if (compression == TiffCompression.None) + { + for (int i = 0; i < stripByteCounts.Length - 1; i++) + { + // The difference must be less than one row. + int stripBytes = (int)stripByteCounts[i]; + int widthBytes = ((int)outputMeta.BitsPerPixel + 7) / 8 * rootFrame.Width; + + Assert.True((TiffConstants.DefaultStripSize - stripBytes) < widthBytes); + } + } + + // Compare with reference. + TestTiffEncoderCore( + provider, + inputMeta.BitsPerPixel, + photometricInterpretation, + inputCompression, + useExactComparer: useExactComparer, + compareTolerance: compareTolerance); + } + + protected static void TestTiffEncoderCore( + TestImageProvider provider, + TiffBitsPerPixel? bitsPerPixel, + TiffPhotometricInterpretation photometricInterpretation, + TiffCompression compression = TiffCompression.None, + TiffPredictor predictor = TiffPredictor.None, + bool useExactComparer = true, + float compareTolerance = 0.001f, + IImageDecoder imageDecoder = null) + where TPixel : unmanaged, IPixel + { + using Image image = provider.GetImage(); + var encoder = new TiffEncoder + { + PhotometricInterpretation = photometricInterpretation, + BitsPerPixel = bitsPerPixel, + Compression = compression, + HorizontalPredictor = predictor + }; + + // Does DebugSave & load reference CompareToReferenceInput(): + image.VerifyEncoder( + provider, + "tiff", + bitsPerPixel, + encoder, + useExactComparer ? ImageComparer.Exact : ImageComparer.Tolerant(compareTolerance), + referenceDecoder: imageDecoder ?? ReferenceDecoder); + } + } +} diff --git a/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderHeaderTests.cs b/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderHeaderTests.cs index acbe2b489..d05e37e2a 100644 --- a/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderHeaderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderHeaderTests.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. using System.IO; - using SixLabors.ImageSharp.Formats.Tiff; using SixLabors.ImageSharp.Formats.Tiff.Writers; using SixLabors.ImageSharp.Memory; diff --git a/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderMultiframeTests.cs b/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderMultiframeTests.cs new file mode 100644 index 000000000..3df3dea30 --- /dev/null +++ b/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderMultiframeTests.cs @@ -0,0 +1,178 @@ +// Copyright (c) Six Labors. +// Licensed under the Apache License, Version 2.0. + +using System; +using SixLabors.ImageSharp.Formats.Tiff; +using SixLabors.ImageSharp.Formats.Tiff.Constants; +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison; +using Xunit; +using static SixLabors.ImageSharp.Tests.TestImages.Tiff; + +namespace SixLabors.ImageSharp.Tests.Formats.Tiff +{ + [Trait("Format", "Tiff")] + public class TiffEncoderMultiframeTests : TiffEncoderBaseTester + { + [Theory] + [WithFile(MultiframeLzwPredictor, PixelTypes.Rgba32)] + public void TiffEncoder_EncodeMultiframe_Works(TestImageProvider provider) + where TPixel : unmanaged, IPixel => TestTiffEncoderCore(provider, TiffBitsPerPixel.Bit24, TiffPhotometricInterpretation.Rgb); + + [Theory] + [WithFile(MultiframeDifferentSize, PixelTypes.Rgba32)] + [WithFile(MultiframeDifferentVariants, PixelTypes.Rgba32)] + public void TiffEncoder_EncodeMultiframe_NotSupport(TestImageProvider provider) + where TPixel : unmanaged, IPixel => Assert.Throws(() => TestTiffEncoderCore(provider, TiffBitsPerPixel.Bit24, TiffPhotometricInterpretation.Rgb)); + + [Theory] + [WithFile(MultiframeDeflateWithPreview, PixelTypes.Rgba32)] + public void TiffEncoder_EncodeMultiframe_WithPreview(TestImageProvider provider) + where TPixel : unmanaged, IPixel => TestTiffEncoderCore(provider, TiffBitsPerPixel.Bit24, TiffPhotometricInterpretation.Rgb); + + [Theory] + [WithFile(TestImages.Gif.Receipt, PixelTypes.Rgb24)] + [WithFile(TestImages.Gif.Issues.BadDescriptorWidth, PixelTypes.Rgba32)] + public void TiffEncoder_EncodeMultiframe_Convert(TestImageProvider provider) + where TPixel : unmanaged, IPixel => TestTiffEncoderCore(provider, TiffBitsPerPixel.Bit48, TiffPhotometricInterpretation.Rgb); + + [Theory] + [WithFile(MultiframeLzwPredictor, PixelTypes.Rgba32)] + public void TiffEncoder_EncodeMultiframe_RemoveFrames(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + using Image image = provider.GetImage(); + Assert.True(image.Frames.Count > 1); + + image.Frames.RemoveFrame(0); + + TiffBitsPerPixel bitsPerPixel = TiffBitsPerPixel.Bit24; + var encoder = new TiffEncoder + { + PhotometricInterpretation = TiffPhotometricInterpretation.Rgb, + BitsPerPixel = bitsPerPixel, + Compression = TiffCompression.Deflate + }; + + image.VerifyEncoder( + provider, + "tiff", + bitsPerPixel, + encoder, + ImageComparer.Exact); + } + + [Theory] + [WithFile(TestImages.Png.Bike, PixelTypes.Rgba32)] + public void TiffEncoder_EncodeMultiframe_AddFrames(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + using Image image = provider.GetImage(); + Assert.Equal(1, image.Frames.Count); + + using var image1 = new Image(image.Width, image.Height, Color.Green.ToRgba32()); + + using var image2 = new Image(image.Width, image.Height, Color.Yellow.ToRgba32()); + + image.Frames.AddFrame(image1.Frames.RootFrame); + image.Frames.AddFrame(image2.Frames.RootFrame); + + TiffBitsPerPixel bitsPerPixel = TiffBitsPerPixel.Bit24; + var encoder = new TiffEncoder + { + PhotometricInterpretation = TiffPhotometricInterpretation.Rgb, + BitsPerPixel = bitsPerPixel, + Compression = TiffCompression.Deflate + }; + + using (var ms = new System.IO.MemoryStream()) + { + image.Save(ms, encoder); + + ms.Position = 0; + using var output = Image.Load(ms); + + Assert.Equal(3, output.Frames.Count); + + ImageFrame frame1 = output.Frames[1]; + ImageFrame frame2 = output.Frames[2]; + + Assert.Equal(Color.Green.ToRgba32(), frame1[10, 10]); + Assert.Equal(Color.Yellow.ToRgba32(), frame2[10, 10]); + + Assert.Equal(TiffCompression.Deflate, frame1.Metadata.GetTiffMetadata().Compression); + Assert.Equal(TiffCompression.Deflate, frame1.Metadata.GetTiffMetadata().Compression); + + Assert.Equal(TiffPhotometricInterpretation.Rgb, frame1.Metadata.GetTiffMetadata().PhotometricInterpretation); + Assert.Equal(TiffPhotometricInterpretation.Rgb, frame2.Metadata.GetTiffMetadata().PhotometricInterpretation); + } + + image.VerifyEncoder( + provider, + "tiff", + bitsPerPixel, + encoder, + ImageComparer.Exact); + } + + [Theory] + [WithBlankImages(100, 100, PixelTypes.Rgba32)] + public void TiffEncoder_EncodeMultiframe_Create(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + using Image image = provider.GetImage(); + + using var image0 = new Image(image.Width, image.Height, Color.Red.ToRgba32()); + + using var image1 = new Image(image.Width, image.Height, Color.Green.ToRgba32()); + + using var image2 = new Image(image.Width, image.Height, Color.Yellow.ToRgba32()); + + image.Frames.AddFrame(image0.Frames.RootFrame); + image.Frames.AddFrame(image1.Frames.RootFrame); + image.Frames.AddFrame(image2.Frames.RootFrame); + image.Frames.RemoveFrame(0); + + TiffBitsPerPixel bitsPerPixel = TiffBitsPerPixel.Bit8; + var encoder = new TiffEncoder + { + PhotometricInterpretation = TiffPhotometricInterpretation.PaletteColor, + BitsPerPixel = bitsPerPixel, + Compression = TiffCompression.Lzw + }; + + using (var ms = new System.IO.MemoryStream()) + { + image.Save(ms, encoder); + + ms.Position = 0; + using var output = Image.Load(ms); + + Assert.Equal(3, output.Frames.Count); + + ImageFrame frame0 = output.Frames[0]; + ImageFrame frame1 = output.Frames[1]; + ImageFrame frame2 = output.Frames[2]; + + Assert.Equal(Color.Red.ToRgba32(), frame0[10, 10]); + Assert.Equal(Color.Green.ToRgba32(), frame1[10, 10]); + Assert.Equal(Color.Yellow.ToRgba32(), frame2[10, 10]); + + Assert.Equal(TiffCompression.Lzw, frame0.Metadata.GetTiffMetadata().Compression); + Assert.Equal(TiffCompression.Lzw, frame1.Metadata.GetTiffMetadata().Compression); + Assert.Equal(TiffCompression.Lzw, frame1.Metadata.GetTiffMetadata().Compression); + + Assert.Equal(TiffPhotometricInterpretation.PaletteColor, frame0.Metadata.GetTiffMetadata().PhotometricInterpretation); + Assert.Equal(TiffPhotometricInterpretation.PaletteColor, frame1.Metadata.GetTiffMetadata().PhotometricInterpretation); + Assert.Equal(TiffPhotometricInterpretation.PaletteColor, frame2.Metadata.GetTiffMetadata().PhotometricInterpretation); + } + + image.VerifyEncoder( + provider, + "tiff", + bitsPerPixel, + encoder, + ImageComparer.Exact); + } + } +} diff --git a/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderTests.cs b/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderTests.cs index 0286671ae..d85ed16a7 100644 --- a/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderTests.cs @@ -2,27 +2,19 @@ // Licensed under the Apache License, Version 2.0. using System.IO; - -using SixLabors.ImageSharp.Formats; using SixLabors.ImageSharp.Formats.Tiff; using SixLabors.ImageSharp.Formats.Tiff.Constants; -using SixLabors.ImageSharp.Metadata.Profiles.Exif; using SixLabors.ImageSharp.PixelFormats; -using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison; -using SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs; using Xunit; - using static SixLabors.ImageSharp.Tests.TestImages.Tiff; namespace SixLabors.ImageSharp.Tests.Formats.Tiff { [Collection("RunSerial")] [Trait("Format", "Tiff")] - public class TiffEncoderTests + public class TiffEncoderTests : TiffEncoderBaseTester { - private static readonly IImageDecoder ReferenceDecoder = new MagickReferenceDecoder(); - [Theory] [InlineData(null, TiffBitsPerPixel.Bit24)] [InlineData(TiffPhotometricInterpretation.Rgb, TiffBitsPerPixel.Bit24)] @@ -121,10 +113,14 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff [InlineData(TiffPhotometricInterpretation.BlackIsZero, TiffCompression.Ccitt1D, TiffBitsPerPixel.Bit1, TiffCompression.Ccitt1D)] [InlineData(TiffPhotometricInterpretation.Rgb, TiffCompression.ItuTRecT43, TiffBitsPerPixel.Bit24, TiffCompression.None)] [InlineData(TiffPhotometricInterpretation.Rgb, TiffCompression.ItuTRecT82, TiffBitsPerPixel.Bit24, TiffCompression.None)] - [InlineData(TiffPhotometricInterpretation.Rgb, TiffCompression.Jpeg, TiffBitsPerPixel.Bit24, TiffCompression.None)] + [InlineData(TiffPhotometricInterpretation.Rgb, TiffCompression.Jpeg, TiffBitsPerPixel.Bit24, TiffCompression.Jpeg)] [InlineData(TiffPhotometricInterpretation.Rgb, TiffCompression.OldDeflate, TiffBitsPerPixel.Bit24, TiffCompression.None)] [InlineData(TiffPhotometricInterpretation.Rgb, TiffCompression.OldJpeg, TiffBitsPerPixel.Bit24, TiffCompression.None)] - public void EncoderOptions_SetPhotometricInterpretationAndCompression_Works(TiffPhotometricInterpretation? photometricInterpretation, TiffCompression compression, TiffBitsPerPixel expectedBitsPerPixel, TiffCompression expectedCompression) + public void EncoderOptions_SetPhotometricInterpretationAndCompression_Works( + TiffPhotometricInterpretation? photometricInterpretation, + TiffCompression compression, + TiffBitsPerPixel expectedBitsPerPixel, + TiffCompression expectedCompression) { // arrange var tiffEncoder = new TiffEncoder { PhotometricInterpretation = photometricInterpretation, Compression = compression }; @@ -291,6 +287,11 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff public void TiffEncoder_EncodeRgb_WithPackBitsCompression_Works(TestImageProvider provider) where TPixel : unmanaged, IPixel => TestTiffEncoderCore(provider, TiffBitsPerPixel.Bit24, TiffPhotometricInterpretation.Rgb, TiffCompression.PackBits); + [Theory] + [WithFile(Calliphora_RgbUncompressed, PixelTypes.Rgba32)] + public void TiffEncoder_EncodeRgb_WithJpegCompression_Works(TestImageProvider provider) + where TPixel : unmanaged, IPixel => TestTiffEncoderCore(provider, TiffBitsPerPixel.Bit24, TiffPhotometricInterpretation.Rgb, TiffCompression.Jpeg, useExactComparer: false, compareTolerance: 0.012f); + [Theory] [WithFile(Calliphora_GrayscaleUncompressed, PixelTypes.Rgba32)] public void TiffEncoder_EncodeGray_Works(TestImageProvider provider) @@ -451,96 +452,5 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff var encoder = new TiffEncoder { PhotometricInterpretation = photometricInterpretation }; image.DebugSave(provider, encoder); } - - private static void TestStripLength( - TestImageProvider provider, - TiffPhotometricInterpretation photometricInterpretation, - TiffCompression compression, - bool useExactComparer = true, - float compareTolerance = 0.01f) - where TPixel : unmanaged, IPixel - { - // arrange - var tiffEncoder = new TiffEncoder() { PhotometricInterpretation = photometricInterpretation, Compression = compression }; - using Image input = provider.GetImage(); - using var memStream = new MemoryStream(); - TiffFrameMetadata inputMeta = input.Frames.RootFrame.Metadata.GetTiffMetadata(); - TiffCompression inputCompression = inputMeta.Compression ?? TiffCompression.None; - - // act - input.Save(memStream, tiffEncoder); - - // assert - memStream.Position = 0; - using var output = Image.Load(memStream); - ExifProfile exifProfileOutput = output.Frames.RootFrame.Metadata.ExifProfile; - TiffFrameMetadata outputMeta = output.Frames.RootFrame.Metadata.GetTiffMetadata(); - ImageFrame rootFrame = output.Frames.RootFrame; - - Number rowsPerStrip = exifProfileOutput.GetValue(ExifTag.RowsPerStrip) != null ? exifProfileOutput.GetValue(ExifTag.RowsPerStrip).Value : TiffConstants.RowsPerStripInfinity; - Assert.True(output.Height > (int)rowsPerStrip); - Assert.True(exifProfileOutput.GetValue(ExifTag.StripOffsets)?.Value.Length > 1); - Number[] stripByteCounts = exifProfileOutput.GetValue(ExifTag.StripByteCounts)?.Value; - Assert.NotNull(stripByteCounts); - Assert.True(stripByteCounts.Length > 1); - Assert.NotNull(outputMeta.BitsPerPixel); - - foreach (Number sz in stripByteCounts) - { - Assert.True((uint)sz <= TiffConstants.DefaultStripSize); - } - - // For uncompressed more accurate test. - if (compression == TiffCompression.None) - { - for (int i = 0; i < stripByteCounts.Length - 1; i++) - { - // The difference must be less than one row. - int stripBytes = (int)stripByteCounts[i]; - int widthBytes = ((int)outputMeta.BitsPerPixel + 7) / 8 * rootFrame.Width; - - Assert.True((TiffConstants.DefaultStripSize - stripBytes) < widthBytes); - } - } - - // Compare with reference. - TestTiffEncoderCore( - provider, - inputMeta.BitsPerPixel, - photometricInterpretation, - inputCompression, - useExactComparer: useExactComparer, - compareTolerance: compareTolerance); - } - - private static void TestTiffEncoderCore( - TestImageProvider provider, - TiffBitsPerPixel? bitsPerPixel, - TiffPhotometricInterpretation photometricInterpretation, - TiffCompression compression = TiffCompression.None, - TiffPredictor predictor = TiffPredictor.None, - bool useExactComparer = true, - float compareTolerance = 0.001f, - IImageDecoder imageDecoder = null) - where TPixel : unmanaged, IPixel - { - using Image image = provider.GetImage(); - var encoder = new TiffEncoder - { - PhotometricInterpretation = photometricInterpretation, - BitsPerPixel = bitsPerPixel, - Compression = compression, - HorizontalPredictor = predictor - }; - - // Does DebugSave & load reference CompareToReferenceInput(): - image.VerifyEncoder( - provider, - "tiff", - bitsPerPixel, - encoder, - useExactComparer ? ImageComparer.Exact : ImageComparer.Tolerant(compareTolerance), - referenceDecoder: imageDecoder ?? ReferenceDecoder); - } } } diff --git a/tests/ImageSharp.Tests/Formats/Tiff/TiffMetadataTests.cs b/tests/ImageSharp.Tests/Formats/Tiff/TiffMetadataTests.cs index c80d9fc16..cdd9616a7 100644 --- a/tests/ImageSharp.Tests/Formats/Tiff/TiffMetadataTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tiff/TiffMetadataTests.cs @@ -12,11 +12,11 @@ using SixLabors.ImageSharp.Metadata.Profiles.Iptc; using SixLabors.ImageSharp.PixelFormats; using Xunit; - using static SixLabors.ImageSharp.Tests.TestImages.Tiff; namespace SixLabors.ImageSharp.Tests.Formats.Tiff { + [Collection("RunSerial")] [Trait("Format", "Tiff")] public class TiffMetadataTests { @@ -278,8 +278,8 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff PixelResolutionUnit resolutionUnitInput = UnitConverter.ExifProfileToResolutionUnit(exifProfileInput); PixelResolutionUnit resolutionUnitEncoded = UnitConverter.ExifProfileToResolutionUnit(encodedImageExifProfile); Assert.Equal(resolutionUnitInput, resolutionUnitEncoded); - Assert.Equal(exifProfileInput.GetValue(ExifTag.XResolution), encodedImageExifProfile.GetValue(ExifTag.XResolution)); - Assert.Equal(exifProfileInput.GetValue(ExifTag.YResolution), encodedImageExifProfile.GetValue(ExifTag.YResolution)); + Assert.Equal(exifProfileInput.GetValue(ExifTag.XResolution).Value.ToDouble(), encodedImageExifProfile.GetValue(ExifTag.XResolution).Value.ToDouble()); + Assert.Equal(exifProfileInput.GetValue(ExifTag.YResolution).Value.ToDouble(), encodedImageExifProfile.GetValue(ExifTag.YResolution).Value.ToDouble()); Assert.Equal(xmpProfileInput, encodedImageXmpProfile); diff --git a/tests/ImageSharp.Tests/Formats/Tiff/TiffTestUtils.cs b/tests/ImageSharp.Tests/Formats/Tiff/TiffTestUtils.cs index 5ac2f475e..eacadae2b 100644 --- a/tests/ImageSharp.Tests/Formats/Tiff/TiffTestUtils.cs +++ b/tests/ImageSharp.Tests/Formats/Tiff/TiffTestUtils.cs @@ -4,7 +4,6 @@ using System; using System.Collections.Generic; using System.IO; - using ImageMagick; using SixLabors.ImageSharp.PixelFormats; diff --git a/tests/ImageSharp.Tests/Formats/Tiff/Utils/TiffWriterTests.cs b/tests/ImageSharp.Tests/Formats/Tiff/Utils/TiffWriterTests.cs index 6eea0a1a9..51ad9498d 100644 --- a/tests/ImageSharp.Tests/Formats/Tiff/Utils/TiffWriterTests.cs +++ b/tests/ImageSharp.Tests/Formats/Tiff/Utils/TiffWriterTests.cs @@ -106,12 +106,13 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff.Utils Assert.Equal( new byte[] - { - 0x11, 0x11, 0x11, 0x11, - 0x78, 0x56, 0x34, 0x12, - 0x33, 0x33, 0x33, 0x33, - 0x44, 0x44, 0x44, 0x44 - }, stream.ToArray()); + { + 0x11, 0x11, 0x11, 0x11, + 0x78, 0x56, 0x34, 0x12, + 0x33, 0x33, 0x33, 0x33, + 0x44, 0x44, 0x44, 0x44 + }, + stream.ToArray()); } } } diff --git a/tests/ImageSharp.Tests/Formats/WebP/DominantCostRangeTests.cs b/tests/ImageSharp.Tests/Formats/WebP/DominantCostRangeTests.cs new file mode 100644 index 000000000..417b9fed5 --- /dev/null +++ b/tests/ImageSharp.Tests/Formats/WebP/DominantCostRangeTests.cs @@ -0,0 +1,79 @@ +// Copyright (c) Six Labors. +// Licensed under the Apache License, Version 2.0. + +using SixLabors.ImageSharp.Formats.Webp.Lossless; +using Xunit; + +namespace SixLabors.ImageSharp.Tests.Formats.Webp +{ + [Trait("Format", "Webp")] + public class DominantCostRangeTests + { + [Fact] + public void DominantCost_Constructor() + { + var dominantCostRange = new DominantCostRange(); + Assert.Equal(0, dominantCostRange.LiteralMax); + Assert.Equal(double.MaxValue, dominantCostRange.LiteralMin); + Assert.Equal(0, dominantCostRange.RedMax); + Assert.Equal(double.MaxValue, dominantCostRange.RedMin); + Assert.Equal(0, dominantCostRange.BlueMax); + Assert.Equal(double.MaxValue, dominantCostRange.BlueMin); + } + + [Fact] + public void UpdateDominantCostRange_Works() + { + // arrange + var dominantCostRange = new DominantCostRange(); + var histogram = new Vp8LHistogram(10) + { + LiteralCost = 1.0d, + RedCost = 2.0d, + BlueCost = 3.0d + }; + + // act + dominantCostRange.UpdateDominantCostRange(histogram); + + // assert + Assert.Equal(1.0d, dominantCostRange.LiteralMax); + Assert.Equal(1.0d, dominantCostRange.LiteralMin); + Assert.Equal(2.0d, dominantCostRange.RedMax); + Assert.Equal(2.0d, dominantCostRange.RedMin); + Assert.Equal(3.0d, dominantCostRange.BlueMax); + Assert.Equal(3.0d, dominantCostRange.BlueMin); + } + + [Theory] + [InlineData(3, 19)] + [InlineData(4, 34)] + public void GetHistoBinIndex_Works(int partitions, int expectedIndex) + { + // arrange + var dominantCostRange = new DominantCostRange() + { + BlueMax = 253.4625, + BlueMin = 109.0, + LiteralMax = 285.0, + LiteralMin = 133.0, + RedMax = 191.0, + RedMin = 109.0 + }; + var histogram = new Vp8LHistogram(6) + { + LiteralCost = 247.0d, + RedCost = 112.0d, + BlueCost = 202.0d, + BitCost = 733.0d + }; + dominantCostRange.UpdateDominantCostRange(histogram); + + // act + int binIndex = dominantCostRange.GetHistoBinIndex(histogram, partitions); + + // assert + Assert.Equal(expectedIndex, binIndex); + } + } +} diff --git a/tests/ImageSharp.Tests/Formats/WebP/ImageExtensionsTests.cs b/tests/ImageSharp.Tests/Formats/WebP/ImageExtensionsTests.cs new file mode 100644 index 000000000..a17248612 --- /dev/null +++ b/tests/ImageSharp.Tests/Formats/WebP/ImageExtensionsTests.cs @@ -0,0 +1,156 @@ +// Copyright (c) Six Labors. +// Licensed under the Apache License, Version 2.0. + +using System.IO; +using System.Threading.Tasks; +using SixLabors.ImageSharp.Formats; +using SixLabors.ImageSharp.Formats.Webp; +using SixLabors.ImageSharp.PixelFormats; +using Xunit; + +namespace SixLabors.ImageSharp.Tests.Formats.Webp +{ + [Trait("Format", "Webp")] + public class ImageExtensionsTests + { + [Fact] + public void SaveAsWebp_Path() + { + string dir = TestEnvironment.CreateOutputDirectory(nameof(ImageExtensionsTests)); + string file = Path.Combine(dir, "SaveAsWebp_Path.webp"); + + using (var image = new Image(10, 10)) + { + image.SaveAsWebp(file); + } + + using (Image.Load(file, out IImageFormat mime)) + { + Assert.Equal("image/webp", mime.DefaultMimeType); + } + } + + [Fact] + public async Task SaveAsWebpAsync_Path() + { + string dir = TestEnvironment.CreateOutputDirectory(nameof(ImageExtensionsTests)); + string file = Path.Combine(dir, "SaveAsWebpAsync_Path.webp"); + + using (var image = new Image(10, 10)) + { + await image.SaveAsWebpAsync(file); + } + + using (Image.Load(file, out IImageFormat mime)) + { + Assert.Equal("image/webp", mime.DefaultMimeType); + } + } + + [Fact] + public void SaveAsWebp_Path_Encoder() + { + string dir = TestEnvironment.CreateOutputDirectory(nameof(ImageExtensions)); + string file = Path.Combine(dir, "SaveAsWebp_Path_Encoder.webp"); + + using (var image = new Image(10, 10)) + { + image.SaveAsWebp(file, new WebpEncoder()); + } + + using (Image.Load(file, out IImageFormat mime)) + { + Assert.Equal("image/webp", mime.DefaultMimeType); + } + } + + [Fact] + public async Task SaveAsWebpAsync_Path_Encoder() + { + string dir = TestEnvironment.CreateOutputDirectory(nameof(ImageExtensions)); + string file = Path.Combine(dir, "SaveAsWebpAsync_Path_Encoder.webp"); + + using (var image = new Image(10, 10)) + { + await image.SaveAsWebpAsync(file, new WebpEncoder()); + } + + using (Image.Load(file, out IImageFormat mime)) + { + Assert.Equal("image/webp", mime.DefaultMimeType); + } + } + + [Fact] + public void SaveAsWebp_Stream() + { + using var memoryStream = new MemoryStream(); + + using (var image = new Image(10, 10)) + { + image.SaveAsWebp(memoryStream); + } + + memoryStream.Position = 0; + + using (Image.Load(memoryStream, out IImageFormat mime)) + { + Assert.Equal("image/webp", mime.DefaultMimeType); + } + } + + [Fact] + public async Task SaveAsWebpAsync_StreamAsync() + { + using var memoryStream = new MemoryStream(); + + using (var image = new Image(10, 10)) + { + await image.SaveAsWebpAsync(memoryStream); + } + + memoryStream.Position = 0; + + using (Image.Load(memoryStream, out IImageFormat mime)) + { + Assert.Equal("image/webp", mime.DefaultMimeType); + } + } + + [Fact] + public void SaveAsWebp_Stream_Encoder() + { + using var memoryStream = new MemoryStream(); + + using (var image = new Image(10, 10)) + { + image.SaveAsWebp(memoryStream, new WebpEncoder()); + } + + memoryStream.Position = 0; + + using (Image.Load(memoryStream, out IImageFormat mime)) + { + Assert.Equal("image/webp", mime.DefaultMimeType); + } + } + + [Fact] + public async Task SaveAsWebpAsync_Stream_Encoder() + { + using var memoryStream = new MemoryStream(); + + using (var image = new Image(10, 10)) + { + await image.SaveAsWebpAsync(memoryStream, new WebpEncoder()); + } + + memoryStream.Position = 0; + + using (Image.Load(memoryStream, out IImageFormat mime)) + { + Assert.Equal("image/webp", mime.DefaultMimeType); + } + } + } +} diff --git a/tests/ImageSharp.Tests/Formats/WebP/LosslessUtilsTests.cs b/tests/ImageSharp.Tests/Formats/WebP/LosslessUtilsTests.cs new file mode 100644 index 000000000..c70f332ef --- /dev/null +++ b/tests/ImageSharp.Tests/Formats/WebP/LosslessUtilsTests.cs @@ -0,0 +1,267 @@ +// Copyright (c) Six Labors. +// Licensed under the Apache License, Version 2.0. + +using SixLabors.ImageSharp.Formats.Webp.Lossless; +using SixLabors.ImageSharp.Tests.TestUtilities; +using Xunit; + +namespace SixLabors.ImageSharp.Tests.Formats.Webp +{ + [Trait("Format", "Webp")] + public class LosslessUtilsTests + { + private static void RunSubtractGreenTest() + { + uint[] pixelData = + { + 4293035898, 4293101432, 4292903793, 4292838511, 4292837995, 4292771950, 4292903791, 4293299316, + 4293563769, 4293629303, 4293363312, 4291913575, 4289282905, 4288692313, 4289349210, 4289809240, + 4289743703, 4289874775, 4289940567, 4289743701, 4290137943, 4290860378, 4291058267, 4291386715, + 4291583836, 4291715937, 4291585379, 4291650657, 4291650143, 4291584863, 4291716451, 4291847521, + 4291913571, 4292044130, 4291978850, 4291847521, 4291847524, 4291847779, 4291913571, 4291848293, + 4291651689, 4291585895, 4291519584, 4291715936, 4291520355, 4291650658, 4291847263, 4291913313, + 4291847777, 4291781731, 4291783015 + }; + + uint[] expectedOutput = + { + 4284188659, 4284254193, 4284318702, 4284187883, 4284318441, 4284383470, 4284318700, 4284124392, + 4283799012, 4283864546, 4284581610, 4285163264, 4284891926, 4284497945, 4284761620, 4284893965, + 4284828428, 4284959500, 4284959755, 4284828426, 4284960520, 4285289733, 4285159937, 4285292030, + 4285358077, 4285228030, 4284966398, 4285097213, 4285227773, 4285096956, 4285097470, 4285228540, + 4285163516, 4285425149, 4285294332, 4285228540, 4285228543, 4285163261, 4285163516, 4285032701, + 4284835841, 4284835584, 4284966140, 4285228029, 4284770300, 4285097214, 4285293819, 4285228795, + 4285163259, 4285228287, 4284901886 + }; + + LosslessUtils.SubtractGreenFromBlueAndRed(pixelData); + + Assert.Equal(expectedOutput, pixelData); + } + + private static void RunAddGreenToBlueAndRedTest() + { + uint[] pixelData = + { + 4284188659, 4284254193, 4284318702, 4284187883, 4284318441, 4284383470, 4284318700, 4284124392, + 4283799012, 4283864546, 4284581610, 4285163264, 4284891926, 4284497945, 4284761620, 4284893965, + 4284828428, 4284959500, 4284959755, 4284828426, 4284960520, 4285289733, 4285159937, 4285292030, + 4285358077, 4285228030, 4284966398, 4285097213, 4285227773, 4285096956, 4285097470, 4285228540, + 4285163516, 4285425149, 4285294332, 4285228540, 4285228543, 4285163261, 4285163516, 4285032701, + 4284835841, 4284835584, 4284966140, 4285228029, 4284770300, 4285097214, 4285293819, 4285228795, + 4285163259, 4285228287, 4284901886 + }; + + uint[] expectedOutput = + { + 4293035898, 4293101432, 4292903793, 4292838511, 4292837995, 4292771950, 4292903791, 4293299316, + 4293563769, 4293629303, 4293363312, 4291913575, 4289282905, 4288692313, 4289349210, 4289809240, + 4289743703, 4289874775, 4289940567, 4289743701, 4290137943, 4290860378, 4291058267, 4291386715, + 4291583836, 4291715937, 4291585379, 4291650657, 4291650143, 4291584863, 4291716451, 4291847521, + 4291913571, 4292044130, 4291978850, 4291847521, 4291847524, 4291847779, 4291913571, 4291848293, + 4291651689, 4291585895, 4291519584, 4291715936, 4291520355, 4291650658, 4291847263, 4291913313, + 4291847777, 4291781731, 4291783015 + }; + + LosslessUtils.AddGreenToBlueAndRed(pixelData); + + Assert.Equal(expectedOutput, pixelData); + } + + private static void RunTransformColorTest() + { + uint[] pixelData = + { + 5998579, 65790, 130301, 16646653, 196350, 130565, 16712702, 16583164, 16452092, 65790, 782600, + 647446, 16571414, 16448771, 263931, 132601, 16711935, 131072, 511, 16711679, 132350, 329469, + 16647676, 132093, 66303, 16647169, 16515584, 196607, 196096, 16646655, 514, 131326, 16712192, + 327169, 16646655, 16776960, 3, 16712190, 511, 16646401, 16580612, 65535, 196092, 327425, 16319743, + 392450, 196861, 16712192, 16711680, 130564, 16451071 + }; + + var m = new Vp8LMultipliers() + { + GreenToBlue = 240, + GreenToRed = 232, + RedToBlue = 0 + }; + + uint[] expectedOutput = + { + 100279, 65790, 16710907, 16712190, 130813, 65028, 131840, 264449, 133377, 65790, 61697, 15917319, + 14801924, 16317698, 591614, 394748, 16711935, 131072, 65792, 16711679, 328704, 656896, 132607, + 328703, 197120, 66563, 16646657, 196607, 130815, 16711936, 131587, 131326, 66049, 261632, 16711936, + 16776960, 3, 511, 65792, 16711938, 16580612, 65535, 65019, 327425, 16516097, 261377, 196861, 66049, + 16711680, 65027, 16712962 + }; + + LosslessUtils.TransformColor(m, pixelData, pixelData.Length); + + Assert.Equal(expectedOutput, pixelData); + } + + private static void RunTransformColorInverseTest() + { + uint[] pixelData = + { + 100279, 65790, 16710907, 16712190, 130813, 65028, 131840, 264449, 133377, 65790, 61697, 15917319, + 14801924, 16317698, 591614, 394748, 16711935, 131072, 65792, 16711679, 328704, 656896, 132607, + 328703, 197120, 66563, 16646657, 196607, 130815, 16711936, 131587, 131326, 66049, 261632, 16711936, + 16776960, 3, 511, 65792, 16711938, 16580612, 65535, 65019, 327425, 16516097, 261377, 196861, 66049, + 16711680, 65027, 16712962 + }; + + var m = new Vp8LMultipliers() + { + GreenToBlue = 240, + GreenToRed = 232, + RedToBlue = 0 + }; + + uint[] expectedOutput = + { + 5998579, 65790, 130301, 16646653, 196350, 130565, 16712702, 16583164, 16452092, 65790, 782600, + 647446, 16571414, 16448771, 263931, 132601, 16711935, 131072, 511, 16711679, 132350, 329469, + 16647676, 132093, 66303, 16647169, 16515584, 196607, 196096, 16646655, 514, 131326, 16712192, + 327169, 16646655, 16776960, 3, 16712190, 511, 16646401, 16580612, 65535, 196092, 327425, 16319743, + 392450, 196861, 16712192, 16711680, 130564, 16451071 + }; + + LosslessUtils.TransformColorInverse(m, pixelData); + + Assert.Equal(expectedOutput, pixelData); + } + + private static void RunPredictor11Test() + { + // arrange + uint[] topData = { 4278258949, 4278258949 }; + uint left = 4294839812; + short[] scratch = new short[8]; + uint expectedResult = 4294839812; + + // act + unsafe + { + fixed (uint* top = &topData[1]) + { + uint actual = LosslessUtils.Predictor11(left, top, scratch); + + // assert + Assert.Equal(expectedResult, actual); + } + } + } + + private static void RunPredictor12Test() + { + // arrange + uint[] topData = { 4294844413, 4294779388 }; + uint left = 4294844413; + uint expectedResult = 4294779388; + + // act + unsafe + { + fixed (uint* top = &topData[1]) + { + uint actual = LosslessUtils.Predictor12(left, top); + + // assert + Assert.Equal(expectedResult, actual); + } + } + } + + private static void RunPredictor13Test() + { + // arrange + uint[] topData = { 4278193922, 4278193666 }; + uint left = 4278193410; + uint expectedResult = 4278193154; + + // act + unsafe + { + fixed (uint* top = &topData[1]) + { + uint actual = LosslessUtils.Predictor13(left, top); + + // assert + Assert.Equal(expectedResult, actual); + } + } + } + + [Fact] + public void Predictor11_Works() => RunPredictor11Test(); + + [Fact] + public void Predictor12_Works() => RunPredictor12Test(); + + [Fact] + public void Predictor13_Works() => RunPredictor13Test(); + + [Fact] + public void SubtractGreen_Works() => RunSubtractGreenTest(); + + [Fact] + public void AddGreenToBlueAndRed_Works() => RunAddGreenToBlueAndRedTest(); + + [Fact] + public void TransformColor_Works() => RunTransformColorTest(); + + [Fact] + public void TransformColorInverse_Works() => RunTransformColorInverseTest(); + +#if SUPPORTS_RUNTIME_INTRINSICS + [Fact] + public void Predictor11_WithHardwareIntrinsics_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunPredictor11Test, HwIntrinsics.AllowAll); + + [Fact] + public void Predictor11_WithoutSSE2_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunPredictor11Test, HwIntrinsics.DisableSSE2); + + [Fact] + public void Predictor12_WithHardwareIntrinsics_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunPredictor12Test, HwIntrinsics.AllowAll); + + [Fact] + public void Predictor12_WithoutSSE2_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunPredictor12Test, HwIntrinsics.DisableSSE2); + + [Fact] + public void Predictor13_WithHardwareIntrinsics_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunPredictor13Test, HwIntrinsics.AllowAll); + + [Fact] + public void Predictor13_WithoutSSE2_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunPredictor13Test, HwIntrinsics.DisableSSE2); + + [Fact] + public void SubtractGreen_WithHardwareIntrinsics_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunSubtractGreenTest, HwIntrinsics.AllowAll); + + [Fact] + public void SubtractGreen_WithoutAvx_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunSubtractGreenTest, HwIntrinsics.DisableAVX); + + [Fact] + public void SubtractGreen_WithoutAvxOrSSSE3_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunSubtractGreenTest, HwIntrinsics.DisableAVX | HwIntrinsics.DisableSSSE3); + + [Fact] + public void AddGreenToBlueAndRed_WithHardwareIntrinsics_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunAddGreenToBlueAndRedTest, HwIntrinsics.AllowAll); + + [Fact] + public void AddGreenToBlueAndRed_WithoutAvx_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunAddGreenToBlueAndRedTest, HwIntrinsics.DisableAVX); + + [Fact] + public void AddGreenToBlueAndRed_WithoutAvxOrSSSE3_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunAddGreenToBlueAndRedTest, HwIntrinsics.DisableAVX | HwIntrinsics.DisableSSE2 | HwIntrinsics.DisableSSSE3); + + [Fact] + public void TransformColor_WithHardwareIntrinsics_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunTransformColorTest, HwIntrinsics.AllowAll); + + [Fact] + public void TransformColor_WithoutSSE2_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunTransformColorTest, HwIntrinsics.DisableSSE2); + + [Fact] + public void TransformColorInverse_WithHardwareIntrinsics_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunTransformColorInverseTest, HwIntrinsics.AllowAll); + + [Fact] + public void TransformColorInverse_WithoutSSE2_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunTransformColorInverseTest, HwIntrinsics.DisableSSE2); +#endif + } +} diff --git a/tests/ImageSharp.Tests/Formats/WebP/LossyUtilsTests.cs b/tests/ImageSharp.Tests/Formats/WebP/LossyUtilsTests.cs new file mode 100644 index 000000000..f8b488fde --- /dev/null +++ b/tests/ImageSharp.Tests/Formats/WebP/LossyUtilsTests.cs @@ -0,0 +1,52 @@ +// Copyright (c) Six Labors. +// Licensed under the Apache License, Version 2.0. + +using SixLabors.ImageSharp.Formats.Webp.Lossy; +using SixLabors.ImageSharp.Tests.TestUtilities; +using Xunit; + +namespace SixLabors.ImageSharp.Tests.Formats.WebP +{ + [Trait("Format", "Webp")] + public class LossyUtilsTests + { + private static void RunHadamardTransformTest() + { + byte[] a = + { + 27, 27, 28, 29, 29, 28, 27, 27, 27, 28, 28, 29, 29, 28, 28, 27, 129, 129, 129, 129, 129, 129, 129, + 129, 128, 128, 128, 128, 128, 128, 128, 128, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28, 28, 29, 29, 28, + 28, 27, 129, 129, 129, 129, 129, 129, 129, 129, 128, 128, 128, 128, 128, 128, 128, 128, 27, 27, 26, + 26, 26, 26, 27, 27, 27, 28, 28, 29, 29, 28, 28, 27, 129, 129, 129, 129, 129, 129, 129, 129, 128, + 128, 128, 128, 128, 128, 128, 128, 28, 27, 27, 26, 26, 27, 27, 28, 27, 28, 28, 29, 29, 28, 28, 27 + }; + + byte[] b = + { + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 204, 204, 204, 204, 204, 204, 204, + 204, 204, 204, 204, 204, 204, 204, 204, 204, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 204, 204, 204, 204, 204, 204, 204, 204, 204, + 204, 204, 204, 204, 204, 204, 204, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28 + }; + + ushort[] w = { 38, 32, 20, 9, 32, 28, 17, 7, 20, 17, 10, 4, 9, 7, 4, 2 }; + int expected = 2; + + int actual = LossyUtils.Vp8Disto4X4(a, b, w, new int[16]); + Assert.Equal(expected, actual); + } + + [Fact] + public void HadamardTransform_Works() => RunHadamardTransformTest(); + +#if SUPPORTS_RUNTIME_INTRINSICS + [Fact] + public void HadamardTransform_WithHardwareIntrinsics_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunHadamardTransformTest, HwIntrinsics.AllowAll); + + [Fact] + public void HadamardTransform_WithoutHardwareIntrinsics_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunHadamardTransformTest, HwIntrinsics.DisableHWIntrinsic); +#endif + + } +} diff --git a/tests/ImageSharp.Tests/Formats/WebP/PredictorEncoderTests.cs b/tests/ImageSharp.Tests/Formats/WebP/PredictorEncoderTests.cs new file mode 100644 index 000000000..d78f7e2f2 --- /dev/null +++ b/tests/ImageSharp.Tests/Formats/WebP/PredictorEncoderTests.cs @@ -0,0 +1,161 @@ +// Copyright (c) Six Labors. +// Licensed under the Apache License, Version 2.0. + +using System; +using System.IO; +using SixLabors.ImageSharp.Formats.Webp; +using SixLabors.ImageSharp.Formats.Webp.Lossless; +using SixLabors.ImageSharp.PixelFormats; +#if SUPPORTS_RUNTIME_INTRINSICS +using SixLabors.ImageSharp.Tests.TestUtilities; +#endif +using Xunit; + +namespace SixLabors.ImageSharp.Tests.Formats.Webp +{ + [Trait("Format", "Webp")] + public class PredictorEncoderTests + { + [Fact] + public static void ColorSpaceTransform_WithBikeImage_ProducesExpectedData() + => RunColorSpaceTransformTestWithBikeImage(); + + [Fact] + public static void ColorSpaceTransform_WithPeakImage_ProducesExpectedData() + => RunColorSpaceTransformTestWithPeakImage(); + +#if SUPPORTS_RUNTIME_INTRINSICS + [Fact] + public void ColorSpaceTransform_WithPeakImage_WithHardwareIntrinsics_Works() + => FeatureTestRunner.RunWithHwIntrinsicsFeature(ColorSpaceTransform_WithPeakImage_ProducesExpectedData, HwIntrinsics.AllowAll); + + [Fact] + public void ColorSpaceTransform_WithPeakImage_WithoutSSE41_Works() + => FeatureTestRunner.RunWithHwIntrinsicsFeature(ColorSpaceTransform_WithPeakImage_ProducesExpectedData, HwIntrinsics.DisableSSE41); + + [Fact] + public void ColorSpaceTransform_WithBikeImage_WithHardwareIntrinsics_Works() + => FeatureTestRunner.RunWithHwIntrinsicsFeature(ColorSpaceTransform_WithBikeImage_ProducesExpectedData, HwIntrinsics.AllowAll); + + [Fact] + public void ColorSpaceTransform_WithBikeImage_WithoutSSE41_Works() + => FeatureTestRunner.RunWithHwIntrinsicsFeature(ColorSpaceTransform_WithBikeImage_ProducesExpectedData, HwIntrinsics.DisableSSE41); +#endif + + private static void RunColorSpaceTransformTestWithPeakImage() + { + // arrange + uint[] expectedData = + { + 4278191104, 4278191104, 4278191104, 4278191104, 4278191104, 4278191104, 4278191104, 4294577152, + 4294707200, 4294707200, 4294707200, 4294707200, 4294837248, 4294837248, 4293926912, 4294316544, + 4278191104, 4278191104, 4294837248, 4294837248, 4280287232, 4280350720, 4294447104, 4294707200, + 4294838272, 4278516736, 4294837248, 4294837248, 4278516736, 4294707200, 4279298048, 4294837248, + 4294837248, 4294837248, 4294837248, 4280287232, 4280287232, 4292670464, 4279633408, 4294838272, + 4294837248, 4278516736, 4278516736, 4278516736, 4278516736, 4278516736, 4278778880, 4278193152, + 4278191104, 4280287232, 4280287232, 4280287232, 4280287232, 4293971968, 4280612864, 4292802560, + 4294837760, 4278516736, 4278516736, 4294837760, 4294707712, 4278516736, 4294837248, 4278193152, + 4280287232, 4278984704, 4280287232, 4278243328, 4280287232, 4278244352, 4280287232, 4280025088, + 4280025088, 4294837760, 4278192128, 4294838784, 4294837760, 4294707712, 4278778880, 4278324224, + 4280287232, 4280287232, 4278202368, 4279115776, 4280287232, 4278243328, 4280287232, 4280287232, + 4280025088, 4280287232, 4278192128, 4294838272, 4294838272, 4294837760, 4278190592, 4278778880, + 4280875008, 4280287232, 4279896576, 4281075712, 4281075712, 4280287232, 4280287232, 4280287232, + 4280287232, 4280287232, 4278190592, 4294709248, 4278516736, 4278516736, 4278584832, 4278909440, + 4280287232, 4280287232, 4294367744, 4294621184, 4279115776, 4280287232, 4280287232, 4280351744, + 4280287232, 4280287232, 4280287232, 4278513664, 4278516736, 4278716416, 4278584832, 4280291328, + 4293062144, 4280287232, 4280287232, 4280287232, 4294456320, 4280291328, 4280287232, 4280287232, + 4280287232, 4280287232, 4280287232, 4280287232, 4278513152, 4278716416, 4278584832, 4280291328, + 4278198272, 4278198272, 4278589952, 4278198272, 4278198272, 4280287232, 4278765568, 4280287232, + 4280287232, 4280287232, 4280287232, 4294712832, 4278513152, 4278716640, 4279300608, 4278584832, + 4280156672, 4279373312, 4278589952, 4279373312, 4278328832, 4278328832, 4278328832, 4279634432, + 4280287232, 4280287232, 4280287232, 4280287232, 4278457344, 4280483328, 4278584832, 4278385664, + 4279634432, 4279373312, 4279634432, 4280287232, 4280287232, 4280156672, 4278589952, 4278328832, + 4278198272, 4280156672, 4280483328, 4294363648, 4280287232, 4278376448, 4280287232, 4278647808, + 4280287232, 4280287232, 4279373312, 4280287232, 4280287232, 4280156672, 4280287232, 4278198272, + 4278198272, 4280156672, 4280287232, 4280287232, 4293669888, 4278765568, 4278765568, 4280287232, + 4280287232, 4280287232, 4279634432, 4279634432, 4280287232, 4280287232, 4280287232, 4280287232, + 4280287232, 4280287232, 4280287232, 4280287232, 4279373312, 4279764992, 4293539328, 4279896576, + 4280287232, 4280287232, 4280287232, 4279634432, 4278198272, 4279634432, 4280287232, 4280287232, + 4280287232, 4280287232, 4280287232, 4280287232, 4280287232, 4279503872, 4279503872, 4280288256, + 4280287232, 4280287232, 4280287232, 4280287232, 4280287232, 4280287232, 4280287232, 4280287232, + 4280287232, 4280287232, 4280287232, 4280287232, 4280287232, 4280287232, 4280287232, 4280287232 + }; + + // Convert image pixels to bgra array. + byte[] imgBytes = File.ReadAllBytes(TestImageFullPath(TestImages.Webp.Peak)); + using var image = Image.Load(imgBytes); + uint[] bgra = ToBgra(image); + + int colorTransformBits = 3; + int transformWidth = LosslessUtils.SubSampleSize(image.Width, colorTransformBits); + int transformHeight = LosslessUtils.SubSampleSize(image.Height, colorTransformBits); + uint[] transformData = new uint[transformWidth * transformHeight]; + int[] scratch = new int[256]; + + // act + PredictorEncoder.ColorSpaceTransform(image.Width, image.Height, colorTransformBits, 75, bgra, transformData, scratch); + + // assert + Assert.Equal(expectedData, transformData); + } + + private static void RunColorSpaceTransformTestWithBikeImage() + { + // arrange + uint[] expectedData = + { + 4278714368, 4278192876, 4278198304, 4278198304, 4278190304, 4278190080, 4278190080, 4278198272, + 4278197760, 4278198816, 4278197794, 4278197774, 4278190080, 4278190080, 4278198816, 4278197281, + 4278197280, 4278197792, 4278200353, 4278191343, 4278190304, 4294713873, 4278198784, 4294844416, + 4278201578, 4278200044, 4278191343, 4278190288, 4294705200, 4294717139, 4278203628, 4278201064, + 4278201586, 4278197792, 4279240909 + }; + + // Convert image pixels to bgra array. + byte[] imgBytes = File.ReadAllBytes(TestImageFullPath(TestImages.Webp.Lossy.BikeSmall)); + using var image = Image.Load(imgBytes, new WebpDecoder()); + uint[] bgra = ToBgra(image); + + int colorTransformBits = 4; + int transformWidth = LosslessUtils.SubSampleSize(image.Width, colorTransformBits); + int transformHeight = LosslessUtils.SubSampleSize(image.Height, colorTransformBits); + uint[] transformData = new uint[transformWidth * transformHeight]; + int[] scratch = new int[256]; + + // act + PredictorEncoder.ColorSpaceTransform(image.Width, image.Height, colorTransformBits, 75, bgra, transformData, scratch); + + // assert + Assert.Equal(expectedData, transformData); + } + + private static uint[] ToBgra(Image image) + where TPixel : unmanaged, IPixel + { + uint[] bgra = new uint[image.Width * image.Height]; + int idx = 0; + for (int y = 0; y < image.Height; y++) + { + Span rowSpan = image.GetPixelRowSpan(y); + for (int x = 0; x < rowSpan.Length; x++) + { + bgra[idx++] = ToBgra32(rowSpan[x]).PackedValue; + } + } + + return bgra; + } + + private static Bgra32 ToBgra32(TPixel color) + where TPixel : unmanaged, IPixel + { + Rgba32 rgba = default; + color.ToRgba32(ref rgba); + var bgra = new Bgra32(rgba.R, rgba.G, rgba.B, rgba.A); + return bgra; + } + + private static string TestImageFullPath(string path) + => Path.Combine(TestEnvironment.InputImagesDirectoryFullPath, path); + } +} diff --git a/tests/ImageSharp.Tests/Formats/WebP/QuantEncTests.cs b/tests/ImageSharp.Tests/Formats/WebP/QuantEncTests.cs new file mode 100644 index 000000000..55738199b --- /dev/null +++ b/tests/ImageSharp.Tests/Formats/WebP/QuantEncTests.cs @@ -0,0 +1,53 @@ +// Copyright (c) Six Labors. +// Licensed under the Apache License, Version 2.0. + +using System.Linq; +using SixLabors.ImageSharp.Formats.Webp.Lossy; +using SixLabors.ImageSharp.Tests.TestUtilities; +using Xunit; + +namespace SixLabors.ImageSharp.Tests.Formats.WebP +{ + [Trait("Format", "Webp")] + public class QuantEncTests + { + private static unsafe void RunQuantizeBlockTest() + { + // arrange + short[] input = { 378, 777, -851, 888, 259, 148, 0, -111, -185, -185, -74, -37, 148, 74, 111, 74 }; + short[] output = new short[16]; + ushort[] q = { 42, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37 }; + ushort[] iq = { 3120, 3542, 3542, 3542, 3542, 3542, 3542, 3542, 3542, 3542, 3542, 3542, 3542, 3542, 3542, 3542 }; + uint[] bias = { 49152, 55296, 55296, 55296, 55296, 55296, 55296, 55296, 55296, 55296, 55296, 55296, 55296, 55296, 55296, 55296 }; + uint[] zthresh = { 26, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21 }; + short[] expectedOutput = { 9, 21, 7, -5, 4, -23, 24, 0, -5, 4, 2, -2, -3, -1, 3, 2 }; + int expectedResult = 1; + Vp8Matrix vp8Matrix = default; + for (int i = 0; i < 16; i++) + { + vp8Matrix.Q[i] = q[i]; + vp8Matrix.IQ[i] = iq[i]; + vp8Matrix.Bias[i] = bias[i]; + vp8Matrix.ZThresh[i] = zthresh[i]; + } + + // act + int actualResult = QuantEnc.QuantizeBlock(input, output, ref vp8Matrix); + + // assert + Assert.True(output.SequenceEqual(expectedOutput)); + Assert.Equal(expectedResult, actualResult); + } + + [Fact] + public void QuantizeBlock_Works() => RunQuantizeBlockTest(); + +#if SUPPORTS_RUNTIME_INTRINSICS + [Fact] + public void QuantizeBlock_WithHardwareIntrinsics_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunQuantizeBlockTest, HwIntrinsics.AllowAll); + + [Fact] + public void QuantizeBlock_WithoutHardwareIntrinsics_Works() => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunQuantizeBlockTest, HwIntrinsics.DisableHWIntrinsic); +#endif + } +} diff --git a/tests/ImageSharp.Tests/Formats/WebP/Vp8HistogramTests.cs b/tests/ImageSharp.Tests/Formats/WebP/Vp8HistogramTests.cs new file mode 100644 index 000000000..4ff42f4ee --- /dev/null +++ b/tests/ImageSharp.Tests/Formats/WebP/Vp8HistogramTests.cs @@ -0,0 +1,115 @@ +// Copyright (c) Six Labors. +// Licensed under the Apache License, Version 2.0. + +using System.Collections.Generic; +using SixLabors.ImageSharp.Formats.Webp.Lossy; +using Xunit; + +namespace SixLabors.ImageSharp.Tests.Formats.Webp +{ + [Trait("Format", "Webp")] + public class Vp8HistogramTests + { + public static IEnumerable Data + { + get + { + var result = new List(); + result.Add(new object[] + { + new byte[] + { + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 19, 16, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 19, 16, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 19, 16, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 19, 16, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 19, 16, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 19, 16, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 19, 16, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 19, 16, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 19, 16, 204, 204, 204, + 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 19, 16, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, + 204, 204, 204, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 19, 16, 204, 204, 204, + 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 19, 16, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, + 204, 204, 204, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 19, 16, 204, 204, 204, + 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 19, 16, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, + 204, 204, 204, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 24, 16, 204, 204, 204, + 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, + 204, 204, 204 + }, + new byte[] + { + 128, 128, 128, 128, 129, 129, 129, 129, 127, 127, 127, 127, 129, 129, 129, 129, 128, 127, 127, + 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 128, 128, 128, 128, 129, 129, + 129, 129, 127, 127, 127, 127, 129, 129, 129, 129, 129, 128, 127, 127, 128, 127, 127, 127, 127, + 127, 127, 127, 127, 127, 127, 127, 128, 128, 128, 128, 129, 129, 129, 129, 127, 127, 127, 127, + 129, 129, 129, 129, 129, 129, 128, 127, 129, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, + 127, 128, 128, 128, 128, 129, 129, 129, 129, 127, 127, 127, 127, 129, 129, 129, 129, 129, 129, + 129, 128, 129, 128, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 128, 128, 127, 127, 129, + 129, 129, 129, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, + 204, 204, 204, 204, 204, 204, 204, 204, 129, 129, 128, 128, 129, 129, 129, 129, 204, 204, 204, + 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, + 204, 204, 129, 129, 129, 129, 129, 129, 129, 129, 204, 204, 204, 204, 204, 204, 204, 204, 204, + 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 129, 129, 129, 129, + 129, 129, 129, 129, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, 204, + 204, 204, 204, 204, 204, 204, 204, 204, 204 + } + }); + return result; + } + } + + [Fact] + public void GetAlpha_WithEmptyHistogram_Works() + { + // arrange + var histogram = new Vp8Histogram(); + + // act + int alpha = histogram.GetAlpha(); + + // assert + Assert.Equal(0, alpha); + } + + [Theory] + [MemberData(nameof(Data))] + public void GetAlpha_Works(byte[] reference, byte[] pred) + { + // arrange + var histogram = new Vp8Histogram(); + histogram.CollectHistogram(reference, pred, 0, 1); + + // act + int alpha = histogram.GetAlpha(); + + // assert + Assert.Equal(1054, alpha); + } + + [Theory] + [MemberData(nameof(Data))] + public void Merge_Works(byte[] reference, byte[] pred) + { + // arrange + var histogram1 = new Vp8Histogram(); + histogram1.CollectHistogram(reference, pred, 0, 1); + var histogram2 = new Vp8Histogram(); + histogram1.Merge(histogram2); + + // act + int alpha = histogram2.GetAlpha(); + + // assert + Assert.Equal(1054, alpha); + } + } +} diff --git a/tests/ImageSharp.Tests/Formats/WebP/Vp8ModeScoreTests.cs b/tests/ImageSharp.Tests/Formats/WebP/Vp8ModeScoreTests.cs new file mode 100644 index 000000000..d3b11bdb5 --- /dev/null +++ b/tests/ImageSharp.Tests/Formats/WebP/Vp8ModeScoreTests.cs @@ -0,0 +1,94 @@ +// Copyright (c) Six Labors. +// Licensed under the Apache License, Version 2.0. + +using SixLabors.ImageSharp.Formats.Webp.Lossy; +using Xunit; + +namespace SixLabors.ImageSharp.Tests.Formats.Webp +{ + [Trait("Format", "Webp")] + public class Vp8ModeScoreTests + { + [Fact] + public void InitScore_Works() + { + var score = new Vp8ModeScore(); + score.InitScore(); + Assert.Equal(0, score.D); + Assert.Equal(0, score.SD); + Assert.Equal(0, score.R); + Assert.Equal(0, score.H); + Assert.Equal(0u, score.Nz); + Assert.Equal(Vp8ModeScore.MaxCost, score.Score); + } + + [Fact] + public void CopyScore_Works() + { + // arrange + var score1 = new Vp8ModeScore + { + Score = 123, + Nz = 1, + D = 2, + H = 3, + ModeI16 = 4, + ModeUv = 5, + R = 6, + SD = 7 + }; + var score2 = new Vp8ModeScore(); + score2.InitScore(); + + // act + score2.CopyScore(score1); + + // assert + Assert.Equal(score1.D, score2.D); + Assert.Equal(score1.SD, score2.SD); + Assert.Equal(score1.R, score2.R); + Assert.Equal(score1.H, score2.H); + Assert.Equal(score1.Nz, score2.Nz); + Assert.Equal(score1.Score, score2.Score); + } + + [Fact] + public void AddScore_Works() + { + // arrange + var score1 = new Vp8ModeScore + { + Score = 123, + Nz = 1, + D = 2, + H = 3, + ModeI16 = 4, + ModeUv = 5, + R = 6, + SD = 7 + }; + var score2 = new Vp8ModeScore + { + Score = 123, + Nz = 1, + D = 2, + H = 3, + ModeI16 = 4, + ModeUv = 5, + R = 6, + SD = 7 + }; + + // act + score2.AddScore(score1); + + // assert + Assert.Equal(4, score2.D); + Assert.Equal(14, score2.SD); + Assert.Equal(12, score2.R); + Assert.Equal(6, score2.H); + Assert.Equal(1u, score2.Nz); + Assert.Equal(246, score2.Score); + } + } +} diff --git a/tests/ImageSharp.Tests/Formats/WebP/WebpCommonUtilsTests.cs b/tests/ImageSharp.Tests/Formats/WebP/WebpCommonUtilsTests.cs new file mode 100644 index 000000000..71bd5bf8d --- /dev/null +++ b/tests/ImageSharp.Tests/Formats/WebP/WebpCommonUtilsTests.cs @@ -0,0 +1,214 @@ +// Copyright (c) Six Labors. +// Licensed under the Apache License, Version 2.0. + +using System; +using System.Runtime.InteropServices; +using SixLabors.ImageSharp.Formats.Webp; +using SixLabors.ImageSharp.PixelFormats; +using Xunit; +#if SUPPORTS_RUNTIME_INTRINSICS +using SixLabors.ImageSharp.Tests.TestUtilities; +#endif + +namespace SixLabors.ImageSharp.Tests.Formats.Webp +{ + [Trait("Format", "Webp")] + public class WebpCommonUtilsTests + { + [Fact] + public void CheckNonOpaque_WithOpaquePixels_Works() => RunCheckNoneOpaqueWithOpaquePixelsTest(); + + [Fact] + public void CheckNonOpaque_WithNoneOpaquePixels_Works() => RunCheckNoneOpaqueWithNoneOpaquePixelsTest(); + +#if SUPPORTS_RUNTIME_INTRINSICS + [Fact] + public void CheckNonOpaque_WithOpaquePixels_WithHardwareIntrinsics_Works() + => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunCheckNoneOpaqueWithOpaquePixelsTest, HwIntrinsics.AllowAll); + + [Fact] + public void CheckNonOpaque_WithOpaquePixels_WithoutSse2_Works() + => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunCheckNoneOpaqueWithOpaquePixelsTest, HwIntrinsics.DisableSSE2); + + [Fact] + public void CheckNonOpaque_WithOpaquePixels_WithoutAvx2_Works() + => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunCheckNoneOpaqueWithOpaquePixelsTest, HwIntrinsics.DisableAVX2); + + [Fact] + public void CheckNonOpaque_WithNoneOpaquePixels_WithHardwareIntrinsics_Works() + => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunCheckNoneOpaqueWithNoneOpaquePixelsTest, HwIntrinsics.AllowAll); + + [Fact] + public void CheckNonOpaque_WithNoneOpaquePixels_WithoutSse2_Works() + => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunCheckNoneOpaqueWithNoneOpaquePixelsTest, HwIntrinsics.DisableSSE2); + + [Fact] + public void CheckNonOpaque_WithNoneOpaquePixels_WithoutAvx2_Works() + => FeatureTestRunner.RunWithHwIntrinsicsFeature(RunCheckNoneOpaqueWithNoneOpaquePixelsTest, HwIntrinsics.DisableAVX2); +#endif + + private static void RunCheckNoneOpaqueWithNoneOpaquePixelsTest() + { + // arrange + byte[] rowBytes = + { + 122, 120, 101, 255, + 171, 165, 151, 255, + 209, 208, 210, 255, + 174, 183, 189, 255, + 148, 158, 158, 255, + 122, 120, 101, 255, + 171, 165, 151, 255, + 209, 208, 210, 255, + 174, 183, 189, 255, + 148, 158, 158, 255, + 171, 165, 151, 255, + 209, 208, 210, 255, + 174, 183, 189, 255, + 148, 158, 158, 255, + 171, 165, 151, 255, + 209, 208, 210, 255, + 174, 183, 189, 255, + 148, 158, 158, 255, + 171, 165, 151, 255, + 209, 208, 210, 255, + 174, 183, 189, 255, + 148, 158, 158, 255, + 148, 158, 158, 10, + 171, 165, 151, 255, + 209, 208, 210, 255, + 171, 165, 151, 255, + 209, 208, 210, 255, + 174, 183, 189, 255, + 148, 158, 158, 255, + 171, 165, 151, 255, + 209, 208, 210, 255, + 174, 183, 189, 255, + 148, 158, 158, 10, + 171, 165, 151, 255, + 209, 208, 210, 255, + 174, 183, 189, 255, + 148, 158, 158, 255, + 171, 165, 151, 255, + 209, 208, 210, 255, + 174, 183, 189, 255, + 148, 158, 158, 255, + 209, 208, 210, 0, + 174, 183, 189, 255, + 148, 158, 158, 255, + 148, 158, 158, 255, + 171, 165, 151, 255, + 209, 208, 210, 255, + 174, 183, 189, 0, + 148, 158, 158, 255, + 148, 158, 158, 255, + 171, 165, 151, 255, + 209, 208, 210, 255, + 174, 183, 189, 255, + 148, 158, 158, 255, + 148, 158, 158, 100, + 171, 165, 151, 0, + 209, 208, 210, 100, + 174, 183, 189, 255, + 148, 158, 158, 255, + }; + Span row = MemoryMarshal.Cast(rowBytes); + + bool noneOpaque; + for (int length = 8; length < row.Length; length += 8) + { + // act + noneOpaque = WebpCommonUtils.CheckNonOpaque(row); + + // assert + Assert.True(noneOpaque); + } + + // One last test with the complete row. + noneOpaque = WebpCommonUtils.CheckNonOpaque(row); + Assert.True(noneOpaque); + } + + private static void RunCheckNoneOpaqueWithOpaquePixelsTest() + { + // arrange + byte[] rowBytes = + { + 122, 120, 101, 255, + 171, 165, 151, 255, + 209, 208, 210, 255, + 174, 183, 189, 255, + 148, 158, 158, 255, + 122, 120, 101, 255, + 171, 165, 151, 255, + 209, 208, 210, 255, + 174, 183, 189, 255, + 148, 158, 158, 255, + 171, 165, 151, 255, + 209, 208, 210, 255, + 174, 183, 189, 255, + 148, 158, 158, 255, + 171, 165, 151, 255, + 209, 208, 210, 255, + 174, 183, 189, 255, + 148, 158, 158, 255, + 171, 165, 151, 255, + 209, 208, 210, 255, + 174, 183, 189, 255, + 148, 158, 158, 255, + 148, 158, 158, 255, + 171, 165, 151, 255, + 209, 208, 210, 255, + 171, 165, 151, 255, + 209, 208, 210, 255, + 174, 183, 189, 255, + 148, 158, 158, 255, + 171, 165, 151, 255, + 209, 208, 210, 255, + 174, 183, 189, 255, + 148, 158, 158, 255, + 171, 165, 151, 255, + 209, 208, 210, 255, + 174, 183, 189, 255, + 148, 158, 158, 255, + 171, 165, 151, 255, + 209, 208, 210, 255, + 174, 183, 189, 255, + 148, 158, 158, 255, + 209, 208, 210, 255, + 174, 183, 189, 255, + 148, 158, 158, 255, + 148, 158, 158, 255, + 171, 165, 151, 255, + 209, 208, 210, 255, + 174, 183, 189, 255, + 148, 158, 158, 255, + 148, 158, 158, 255, + 171, 165, 151, 255, + 209, 208, 210, 255, + 174, 183, 189, 255, + 148, 158, 158, 255, + 148, 158, 158, 255, + 171, 165, 151, 255, + 209, 208, 210, 255, + 174, 183, 189, 255, + 148, 158, 158, 255, + }; + Span row = MemoryMarshal.Cast(rowBytes); + + bool noneOpaque; + for (int length = 8; length < row.Length; length += 8) + { + // act + noneOpaque = WebpCommonUtils.CheckNonOpaque(row.Slice(0, length)); + + // assert + Assert.False(noneOpaque); + } + + // One last test with the complete row. + noneOpaque = WebpCommonUtils.CheckNonOpaque(row); + Assert.False(noneOpaque); + } + } +} diff --git a/tests/ImageSharp.Tests/Formats/WebP/WebpDecoderTests.cs b/tests/ImageSharp.Tests/Formats/WebP/WebpDecoderTests.cs new file mode 100644 index 000000000..34fa72c63 --- /dev/null +++ b/tests/ImageSharp.Tests/Formats/WebP/WebpDecoderTests.cs @@ -0,0 +1,363 @@ +// Copyright (c) Six Labors. +// Licensed under the Apache License, Version 2.0. + +using System.IO; +using SixLabors.ImageSharp.Formats.Webp; +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs; +using Xunit; +using static SixLabors.ImageSharp.Tests.TestImages.Webp; + +// ReSharper disable InconsistentNaming +namespace SixLabors.ImageSharp.Tests.Formats.Webp +{ + [Collection("RunSerial")] + [Trait("Format", "Webp")] + public class WebpDecoderTests + { + private static WebpDecoder WebpDecoder => new(); + + private static MagickReferenceDecoder ReferenceDecoder => new(); + + [Theory] + [InlineData(Lossless.GreenTransform1, 1000, 307, 32)] + [InlineData(Lossless.BikeThreeTransforms, 250, 195, 32)] + [InlineData(Lossless.NoTransform2, 128, 128, 32)] + [InlineData(Lossy.Alpha1, 1000, 307, 32)] + [InlineData(Lossy.Alpha2, 1000, 307, 32)] + [InlineData(Lossy.Bike, 250, 195, 24)] + public void Identify_DetectsCorrectDimensionsAndBitDepth( + string imagePath, + int expectedWidth, + int expectedHeight, + int expectedBitsPerPixel) + { + var testFile = TestFile.Create(imagePath); + using (var stream = new MemoryStream(testFile.Bytes, false)) + { + IImageInfo imageInfo = Image.Identify(stream); + Assert.NotNull(imageInfo); + Assert.Equal(expectedWidth, imageInfo.Width); + Assert.Equal(expectedHeight, imageInfo.Height); + Assert.Equal(expectedBitsPerPixel, imageInfo.PixelType.BitsPerPixel); + } + } + + [Theory] + [WithFile(Lossy.Bike, PixelTypes.Rgba32)] + [WithFile(Lossy.NoFilter01, PixelTypes.Rgba32)] + [WithFile(Lossy.NoFilter02, PixelTypes.Rgba32)] + [WithFile(Lossy.NoFilter03, PixelTypes.Rgba32)] + [WithFile(Lossy.NoFilter04, PixelTypes.Rgba32)] + [WithFile(Lossy.NoFilter05, PixelTypes.Rgba32)] + [WithFile(Lossy.SegmentationNoFilter01, PixelTypes.Rgba32)] + [WithFile(Lossy.SegmentationNoFilter02, PixelTypes.Rgba32)] + [WithFile(Lossy.SegmentationNoFilter03, PixelTypes.Rgba32)] + public void WebpDecoder_CanDecode_Lossy_WithoutFilter(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + using (Image image = provider.GetImage(WebpDecoder)) + { + image.DebugSave(provider); + image.CompareToOriginal(provider, ReferenceDecoder); + } + } + + [Theory] + [WithFile(Lossy.SimpleFilter01, PixelTypes.Rgba32)] + [WithFile(Lossy.SimpleFilter02, PixelTypes.Rgba32)] + [WithFile(Lossy.SimpleFilter03, PixelTypes.Rgba32)] + [WithFile(Lossy.SimpleFilter04, PixelTypes.Rgba32)] + [WithFile(Lossy.SimpleFilter05, PixelTypes.Rgba32)] + public void WebpDecoder_CanDecode_Lossy_WithSimpleFilter(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + using (Image image = provider.GetImage(WebpDecoder)) + { + image.DebugSave(provider); + image.CompareToOriginal(provider, ReferenceDecoder); + } + } + + [Theory] + [WithFile(Lossy.IccpComplexFilter, PixelTypes.Rgba32)] + [WithFile(Lossy.VeryShort, PixelTypes.Rgba32)] + [WithFile(Lossy.BikeComplexFilter, PixelTypes.Rgba32)] + [WithFile(Lossy.ComplexFilter01, PixelTypes.Rgba32)] + [WithFile(Lossy.ComplexFilter02, PixelTypes.Rgba32)] + [WithFile(Lossy.ComplexFilter03, PixelTypes.Rgba32)] + [WithFile(Lossy.ComplexFilter04, PixelTypes.Rgba32)] + [WithFile(Lossy.ComplexFilter05, PixelTypes.Rgba32)] + [WithFile(Lossy.ComplexFilter06, PixelTypes.Rgba32)] + [WithFile(Lossy.ComplexFilter07, PixelTypes.Rgba32)] + [WithFile(Lossy.ComplexFilter08, PixelTypes.Rgba32)] + [WithFile(Lossy.ComplexFilter09, PixelTypes.Rgba32)] + public void WebpDecoder_CanDecode_Lossy_WithComplexFilter(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + using (Image image = provider.GetImage(WebpDecoder)) + { + image.DebugSave(provider); + image.CompareToOriginal(provider, ReferenceDecoder); + } + } + + [Theory] + [WithFile(Lossy.Small01, PixelTypes.Rgba32)] + [WithFile(Lossy.Small02, PixelTypes.Rgba32)] + [WithFile(Lossy.Small03, PixelTypes.Rgba32)] + [WithFile(Lossy.Small04, PixelTypes.Rgba32)] + public void WebpDecoder_CanDecode_Lossy_VerySmall(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + using (Image image = provider.GetImage(WebpDecoder)) + { + image.DebugSave(provider); + image.CompareToOriginal(provider, ReferenceDecoder); + } + } + + [Theory] + [WithFile(Lossy.SegmentationNoFilter04, PixelTypes.Rgba32)] + [WithFile(Lossy.SegmentationNoFilter05, PixelTypes.Rgba32)] + [WithFile(Lossy.SegmentationNoFilter06, PixelTypes.Rgba32)] + [WithFile(Lossy.SegmentationComplexFilter01, PixelTypes.Rgba32)] + [WithFile(Lossy.SegmentationComplexFilter02, PixelTypes.Rgba32)] + [WithFile(Lossy.SegmentationComplexFilter03, PixelTypes.Rgba32)] + [WithFile(Lossy.SegmentationComplexFilter04, PixelTypes.Rgba32)] + [WithFile(Lossy.SegmentationComplexFilter05, PixelTypes.Rgba32)] + public void WebpDecoder_CanDecode_Lossy_WithPartitions(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + using (Image image = provider.GetImage(WebpDecoder)) + { + image.DebugSave(provider); + image.CompareToOriginal(provider, ReferenceDecoder); + } + } + + [Theory] + [WithFile(Lossy.Partitions01, PixelTypes.Rgba32)] + [WithFile(Lossy.Partitions02, PixelTypes.Rgba32)] + [WithFile(Lossy.Partitions03, PixelTypes.Rgba32)] + public void WebpDecoder_CanDecode_Lossy_WithSegmentation(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + using (Image image = provider.GetImage(WebpDecoder)) + { + image.DebugSave(provider); + image.CompareToOriginal(provider, ReferenceDecoder); + } + } + + [Theory] + [WithFile(Lossy.Sharpness01, PixelTypes.Rgba32)] + [WithFile(Lossy.Sharpness02, PixelTypes.Rgba32)] + [WithFile(Lossy.Sharpness03, PixelTypes.Rgba32)] + [WithFile(Lossy.Sharpness04, PixelTypes.Rgba32)] + [WithFile(Lossy.Sharpness05, PixelTypes.Rgba32)] + [WithFile(Lossy.Sharpness06, PixelTypes.Rgba32)] + public void WebpDecoder_CanDecode_Lossy_WithSharpnessLevel(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + using (Image image = provider.GetImage(WebpDecoder)) + { + image.DebugSave(provider); + image.CompareToOriginal(provider, ReferenceDecoder); + } + } + + [Theory] + [WithFile(Lossy.AlphaNoCompression, PixelTypes.Rgba32)] + [WithFile(Lossy.AlphaNoCompressionNoFilter, PixelTypes.Rgba32)] + [WithFile(Lossy.AlphaCompressedNoFilter, PixelTypes.Rgba32)] + [WithFile(Lossy.AlphaNoCompressionHorizontalFilter, PixelTypes.Rgba32)] + [WithFile(Lossy.AlphaNoCompressionVerticalFilter, PixelTypes.Rgba32)] + [WithFile(Lossy.AlphaNoCompressionGradientFilter, PixelTypes.Rgba32)] + [WithFile(Lossy.AlphaCompressedHorizontalFilter, PixelTypes.Rgba32)] + [WithFile(Lossy.AlphaCompressedVerticalFilter, PixelTypes.Rgba32)] + [WithFile(Lossy.AlphaCompressedGradientFilter, PixelTypes.Rgba32)] + [WithFile(Lossy.Alpha1, PixelTypes.Rgba32)] + [WithFile(Lossy.Alpha2, PixelTypes.Rgba32)] + [WithFile(Lossy.Alpha3, PixelTypes.Rgba32)] + [WithFile(Lossy.AlphaThinkingSmiley, PixelTypes.Rgba32)] + [WithFile(Lossy.AlphaSticker, PixelTypes.Rgba32)] + public void WebpDecoder_CanDecode_Lossy_WithAlpha(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + using (Image image = provider.GetImage(WebpDecoder)) + { + image.DebugSave(provider); + image.CompareToOriginal(provider, ReferenceDecoder); + } + } + + [Theory] + [WithFile(Lossless.Alpha, PixelTypes.Rgba32)] + public void WebpDecoder_CanDecode_Lossless_WithAlpha(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + using (Image image = provider.GetImage(WebpDecoder)) + { + image.DebugSave(provider); + image.CompareToOriginal(provider, ReferenceDecoder); + } + } + + [Theory] + [WithFile(Lossless.NoTransform1, PixelTypes.Rgba32)] + [WithFile(Lossless.NoTransform2, PixelTypes.Rgba32)] + public void WebpDecoder_CanDecode_Lossless_WithoutTransforms(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + using (Image image = provider.GetImage(WebpDecoder)) + { + image.DebugSave(provider); + image.CompareToOriginal(provider, ReferenceDecoder); + } + } + + [Theory] + [WithFile(Lossless.GreenTransform1, PixelTypes.Rgba32)] + [WithFile(Lossless.GreenTransform2, PixelTypes.Rgba32)] + [WithFile(Lossless.GreenTransform3, PixelTypes.Rgba32)] + [WithFile(Lossless.GreenTransform4, PixelTypes.Rgba32)] + + // TODO: Reference decoder throws here MagickCorruptImageErrorException, webpinfo also indicates an error here, but decoding the image seems to work. + // [WithFile(Lossless.GreenTransform5, PixelTypes.Rgba32)] + public void WebpDecoder_CanDecode_Lossless_WithSubstractGreenTransform( + TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + using (Image image = provider.GetImage(WebpDecoder)) + { + image.DebugSave(provider); + image.CompareToOriginal(provider, ReferenceDecoder); + } + } + + [Theory] + [WithFile(Lossless.ColorIndexTransform1, PixelTypes.Rgba32)] + [WithFile(Lossless.ColorIndexTransform2, PixelTypes.Rgba32)] + [WithFile(Lossless.ColorIndexTransform3, PixelTypes.Rgba32)] + [WithFile(Lossless.ColorIndexTransform4, PixelTypes.Rgba32)] + [WithFile(Lossless.ColorIndexTransform5, PixelTypes.Rgba32)] + public void WebpDecoder_CanDecode_Lossless_WithColorIndexTransform(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + using (Image image = provider.GetImage(WebpDecoder)) + { + image.DebugSave(provider); + image.CompareToOriginal(provider, ReferenceDecoder); + } + } + + [Theory] + [WithFile(Lossless.PredictorTransform1, PixelTypes.Rgba32)] + [WithFile(Lossless.PredictorTransform2, PixelTypes.Rgba32)] + public void WebpDecoder_CanDecode_Lossless_WithPredictorTransform(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + using (Image image = provider.GetImage(WebpDecoder)) + { + image.DebugSave(provider); + image.CompareToOriginal(provider, ReferenceDecoder); + } + } + + [Theory] + [WithFile(Lossless.CrossColorTransform1, PixelTypes.Rgba32)] + [WithFile(Lossless.CrossColorTransform2, PixelTypes.Rgba32)] + public void WebpDecoder_CanDecode_Lossless_WithCrossColorTransform(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + using (Image image = provider.GetImage(WebpDecoder)) + { + image.DebugSave(provider); + image.CompareToOriginal(provider, ReferenceDecoder); + } + } + + [Theory] + [WithFile(Lossless.TwoTransforms1, PixelTypes.Rgba32)] + [WithFile(Lossless.TwoTransforms2, PixelTypes.Rgba32)] + [WithFile(Lossless.TwoTransforms3, PixelTypes.Rgba32)] + [WithFile(Lossless.TwoTransforms4, PixelTypes.Rgba32)] + [WithFile(Lossless.TwoTransforms5, PixelTypes.Rgba32)] + [WithFile(Lossless.TwoTransforms6, PixelTypes.Rgba32)] + [WithFile(Lossless.TwoTransforms7, PixelTypes.Rgba32)] + [WithFile(Lossless.TwoTransforms8, PixelTypes.Rgba32)] + [WithFile(Lossless.TwoTransforms9, PixelTypes.Rgba32)] + [WithFile(Lossless.TwoTransforms10, PixelTypes.Rgba32)] + [WithFile(Lossless.TwoTransforms11, PixelTypes.Rgba32)] + [WithFile(Lossless.TwoTransforms12, PixelTypes.Rgba32)] + [WithFile(Lossless.TwoTransforms13, PixelTypes.Rgba32)] + public void WebpDecoder_CanDecode_Lossless_WithTwoTransforms(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + using (Image image = provider.GetImage(WebpDecoder)) + { + image.DebugSave(provider); + image.CompareToOriginal(provider, ReferenceDecoder); + } + } + + [Theory] + [WithFile(Lossless.ThreeTransforms1, PixelTypes.Rgba32)] + [WithFile(Lossless.ThreeTransforms2, PixelTypes.Rgba32)] + [WithFile(Lossless.ThreeTransforms3, PixelTypes.Rgba32)] + [WithFile(Lossless.ThreeTransforms4, PixelTypes.Rgba32)] + [WithFile(Lossless.ThreeTransforms5, PixelTypes.Rgba32)] + [WithFile(Lossless.ThreeTransforms6, PixelTypes.Rgba32)] + [WithFile(Lossless.ThreeTransforms7, PixelTypes.Rgba32)] + [WithFile(Lossless.BikeThreeTransforms, PixelTypes.Rgba32)] + public void WebpDecoder_CanDecode_Lossless_WithThreeTransforms(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + using (Image image = provider.GetImage(WebpDecoder)) + { + image.DebugSave(provider); + image.CompareToOriginal(provider, ReferenceDecoder); + } + } + + [Theory] + [WithFile(Lossless.LossLessCorruptImage1, PixelTypes.Rgba32)] + [WithFile(Lossless.LossLessCorruptImage2, PixelTypes.Rgba32)] + [WithFile(Lossless.LossLessCorruptImage4, PixelTypes.Rgba32)] + public void WebpDecoder_CanDecode_Lossless_WithIssues(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + // Just make sure no exception is thrown. The reference decoder fails to load the image. + using (Image image = provider.GetImage(WebpDecoder)) + { + image.DebugSave(provider); + } + } + + // https://github.com/SixLabors/ImageSharp/issues/1594 + [Theory] + [WithFile(Lossy.Issue1594, PixelTypes.Rgba32)] + public void WebpDecoder_CanDecode_Issue1594(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + using (Image image = provider.GetImage(WebpDecoder)) + { + image.DebugSave(provider); + image.CompareToOriginal(provider, ReferenceDecoder); + } + } + + [Theory] + [WithFile(Lossless.LossLessCorruptImage3, PixelTypes.Rgba32)] + public void WebpDecoder_ThrowImageFormatException_OnInvalidImages(TestImageProvider provider) + where TPixel : unmanaged, IPixel => + Assert.Throws( + () => + { + using (provider.GetImage(WebpDecoder)) + { + } + }); + } +} diff --git a/tests/ImageSharp.Tests/Formats/WebP/WebpEncoderTests.cs b/tests/ImageSharp.Tests/Formats/WebP/WebpEncoderTests.cs new file mode 100644 index 000000000..70cc487bf --- /dev/null +++ b/tests/ImageSharp.Tests/Formats/WebP/WebpEncoderTests.cs @@ -0,0 +1,286 @@ +// Copyright (c) Six Labors. +// Licensed under the Apache License, Version 2.0. + +using System.IO; +using SixLabors.ImageSharp.Formats.Webp; +using SixLabors.ImageSharp.Metadata; +using SixLabors.ImageSharp.PixelFormats; +using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison; +using Xunit; +using static SixLabors.ImageSharp.Tests.TestImages.Webp; + +namespace SixLabors.ImageSharp.Tests.Formats.Webp +{ + [Collection("RunSerial")] + [Trait("Format", "Webp")] + public class WebpEncoderTests + { + [Theory] + [WithFile(Flag, PixelTypes.Rgba32, WebpFileFormatType.Lossless)] // if its not a webp input image, it should default to lossless. + [WithFile(Lossless.NoTransform1, PixelTypes.Rgba32, WebpFileFormatType.Lossless)] + [WithFile(Lossy.Bike, PixelTypes.Rgba32, WebpFileFormatType.Lossy)] + public void Encode_PreserveRatio(TestImageProvider provider, WebpFileFormatType expectedFormat) + where TPixel : unmanaged, IPixel + { + var options = new WebpEncoder(); + using Image input = provider.GetImage(); + using var memoryStream = new MemoryStream(); + input.Save(memoryStream, options); + + memoryStream.Position = 0; + using var output = Image.Load(memoryStream); + + ImageMetadata meta = output.Metadata; + WebpMetadata webpMetaData = meta.GetWebpMetadata(); + Assert.Equal(expectedFormat, webpMetaData.FileFormat); + } + + [Theory] + [WithFile(Flag, PixelTypes.Rgba32)] + [WithFile(TestImages.Png.PalettedTwoColor, PixelTypes.Rgba32)] + [WithFile(TestImages.Png.Paletted256Colors, PixelTypes.Rgba32)] + public void Encode_Lossless_WithPalette_Works(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + var encoder = new WebpEncoder() + { + FileFormat = WebpFileFormatType.Lossless, + Quality = 100, + Method = WebpEncodingMethod.BestQuality + }; + + using Image image = provider.GetImage(); + image.VerifyEncoder(provider, "webp", string.Empty, encoder); + } + + [Theory] + [WithFile(TestImages.Bmp.Car, PixelTypes.Rgba32, 100)] + [WithFile(TestImages.Bmp.Car, PixelTypes.Rgba32, 80)] + [WithFile(TestImages.Bmp.Car, PixelTypes.Rgba32, 20)] + public void Encode_Lossless_WithDifferentQuality_Works(TestImageProvider provider, int quality) + where TPixel : unmanaged, IPixel + { + var encoder = new WebpEncoder() + { + FileFormat = WebpFileFormatType.Lossless, + Quality = quality + }; + + using Image image = provider.GetImage(); + string testOutputDetails = string.Concat("lossless", "_q", quality); + image.VerifyEncoder(provider, "webp", testOutputDetails, encoder); + } + + [Theory] + [WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 0, 75)] + [WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 1, 75)] + [WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 2, 75)] + [WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 3, 75)] + [WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 4, 75)] + [WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 5, 75)] + [WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 6, 75)] + [WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 0, 100)] + [WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 1, 100)] + [WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 2, 100)] + [WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 3, 100)] + [WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 4, 100)] + [WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 5, 100)] + [WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 6, 100)] + public void Encode_Lossless_WithDifferentMethodAndQuality_Works(TestImageProvider provider, WebpEncodingMethod method, int quality) + where TPixel : unmanaged, IPixel + { + var encoder = new WebpEncoder() + { + FileFormat = WebpFileFormatType.Lossless, + Method = method, + Quality = quality + }; + + using Image image = provider.GetImage(); + string testOutputDetails = string.Concat("lossless", "_m", method, "_q", quality); + image.VerifyEncoder(provider, "webp", testOutputDetails, encoder); + } + + [Theory] + [WithFile(RgbTestPattern100x100, PixelTypes.Rgba32, 85)] + [WithFile(RgbTestPattern100x100, PixelTypes.Rgba32, 60)] + [WithFile(RgbTestPattern80x80, PixelTypes.Rgba32, 40)] + [WithFile(RgbTestPattern80x80, PixelTypes.Rgba32, 20)] + [WithFile(RgbTestPattern80x80, PixelTypes.Rgba32, 10)] + [WithFile(RgbTestPattern63x63, PixelTypes.Rgba32, 40)] + public void Encode_Lossless_WithNearLosslessFlag_Works(TestImageProvider provider, int nearLosslessQuality) + where TPixel : unmanaged, IPixel + { + var encoder = new WebpEncoder() + { + FileFormat = WebpFileFormatType.Lossless, + NearLossless = true, + NearLosslessQuality = nearLosslessQuality + }; + + using Image image = provider.GetImage(); + string testOutputDetails = string.Concat("nearlossless", "_q", nearLosslessQuality); + image.VerifyEncoder(provider, "webp", testOutputDetails, encoder, customComparer: GetComparer(nearLosslessQuality)); + } + + [Theory] + [WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 0)] + [WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 1)] + [WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 2)] + [WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 3)] + [WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 4)] + [WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 5)] + [WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 6)] + [WithFile(Lossy.Alpha1, PixelTypes.Rgba32, 4)] + public void Encode_Lossless_WithPreserveTransparentColor_Works(TestImageProvider provider, WebpEncodingMethod method) + where TPixel : unmanaged, IPixel + { + var encoder = new WebpEncoder() + { + FileFormat = WebpFileFormatType.Lossless, + Method = method, + TransparentColorMode = WebpTransparentColorMode.Preserve + }; + + using Image image = provider.GetImage(); + string testOutputDetails = string.Concat("lossless", "_m", method); + image.VerifyEncoder(provider, "webp", testOutputDetails, encoder); + } + + [Theory] + [WithFile(TestPatternOpaque, PixelTypes.Rgba32)] + [WithFile(TestPatternOpaqueSmall, PixelTypes.Rgba32)] + public void Encode_Lossless_WorksWithTestPattern(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + using Image image = provider.GetImage(); + + var encoder = new WebpEncoder() { FileFormat = WebpFileFormatType.Lossless }; + image.VerifyEncoder(provider, "webp", string.Empty, encoder); + } + + [Fact] + public void Encode_Lossless_OneByOnePixel_Works() + { + // Just make sure, encoding 1 pixel by 1 pixel does not throw an exception. + using var image = new Image(1, 1); + var encoder = new WebpEncoder() { FileFormat = WebpFileFormatType.Lossless }; + using (var memStream = new MemoryStream()) + { + image.SaveAsWebp(memStream, encoder); + } + } + + [Theory] + [WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 100)] + [WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 75)] + [WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 20)] + public void Encode_Lossy_WithDifferentQuality_Works(TestImageProvider provider, int quality) + where TPixel : unmanaged, IPixel + { + var encoder = new WebpEncoder() + { + FileFormat = WebpFileFormatType.Lossy, + Quality = quality + }; + + using Image image = provider.GetImage(); + string testOutputDetails = string.Concat("lossy", "_q", quality); + image.VerifyEncoder(provider, "webp", testOutputDetails, encoder, customComparer: GetComparer(quality)); + } + + [Theory] + [WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 100)] + [WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 80)] + [WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 50)] + [WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 30)] + [WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 10)] + public void Encode_Lossy_WithDifferentFilterStrength_Works(TestImageProvider provider, int filterStrength) + where TPixel : unmanaged, IPixel + { + var encoder = new WebpEncoder() + { + FileFormat = WebpFileFormatType.Lossy, + FilterStrength = filterStrength + }; + + using Image image = provider.GetImage(); + string testOutputDetails = string.Concat("lossy", "_f", filterStrength); + image.VerifyEncoder(provider, "webp", testOutputDetails, encoder, customComparer: GetComparer(75)); + } + + [Theory] + [WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 100)] + [WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 80)] + [WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 50)] + [WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 30)] + [WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 10)] + public void Encode_Lossy_WithDifferentSpatialNoiseShapingStrength_Works(TestImageProvider provider, int snsStrength) + where TPixel : unmanaged, IPixel + { + var encoder = new WebpEncoder() + { + FileFormat = WebpFileFormatType.Lossy, + SpatialNoiseShaping = snsStrength + }; + + using Image image = provider.GetImage(); + string testOutputDetails = string.Concat("lossy", "_sns", snsStrength); + image.VerifyEncoder(provider, "webp", testOutputDetails, encoder, customComparer: GetComparer(75)); + } + + [Theory] + [WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 0, 75)] + [WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 1, 75)] + [WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 2, 75)] + [WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 3, 75)] + [WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 4, 75)] + [WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 5, 75)] + [WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 6, 75)] + [WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 0, 100)] + [WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 1, 100)] + [WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 2, 100)] + [WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 3, 100)] + [WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 4, 100)] + [WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 5, 100)] + [WithFile(Lossy.NoFilter06, PixelTypes.Rgba32, 6, 100)] + public void Encode_Lossy_WithDifferentMethodsAndQuality_Works(TestImageProvider provider, WebpEncodingMethod method, int quality) + where TPixel : unmanaged, IPixel + { + var encoder = new WebpEncoder() + { + FileFormat = WebpFileFormatType.Lossy, + Method = method, + Quality = quality + }; + + using Image image = provider.GetImage(); + string testOutputDetails = string.Concat("lossy", "_m", method, "_q", quality); + image.VerifyEncoder(provider, "webp", testOutputDetails, encoder, customComparer: GetComparer(quality)); + } + + [Theory] + [WithFile(TestPatternOpaque, PixelTypes.Rgba32)] + [WithFile(TestPatternOpaqueSmall, PixelTypes.Rgba32)] + public void Encode_Lossy_WorksWithTestPattern(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + using Image image = provider.GetImage(); + + var encoder = new WebpEncoder() { FileFormat = WebpFileFormatType.Lossy }; + image.VerifyEncoder(provider, "webp", string.Empty, encoder, ImageComparer.Tolerant(0.04f)); + } + + private static ImageComparer GetComparer(int quality) + { + float tolerance = 0.01f; // ~1.0% + + if (quality < 30) + { + tolerance = 0.02f; // ~2.0% + } + + return ImageComparer.Tolerant(tolerance); + } + } +} diff --git a/tests/ImageSharp.Tests/Formats/WebP/WebpMetaDataTests.cs b/tests/ImageSharp.Tests/Formats/WebP/WebpMetaDataTests.cs new file mode 100644 index 000000000..a051de1c0 --- /dev/null +++ b/tests/ImageSharp.Tests/Formats/WebP/WebpMetaDataTests.cs @@ -0,0 +1,133 @@ +// Copyright (c) Six Labors. +// Licensed under the Apache License, Version 2.0. + +using System.IO; +using SixLabors.ImageSharp.Formats.Webp; +using SixLabors.ImageSharp.Metadata.Profiles.Exif; +using SixLabors.ImageSharp.PixelFormats; +using Xunit; + +// ReSharper disable InconsistentNaming +namespace SixLabors.ImageSharp.Tests.Formats.Webp +{ + [Trait("Format", "Webp")] + public class WebpMetaDataTests + { + private static WebpDecoder WebpDecoder => new() { IgnoreMetadata = false }; + + [Theory] + [WithFile(TestImages.Webp.Lossy.WithExif, PixelTypes.Rgba32, false)] + [WithFile(TestImages.Webp.Lossy.WithExif, PixelTypes.Rgba32, true)] + [WithFile(TestImages.Webp.Lossless.WithExif, PixelTypes.Rgba32, false)] + [WithFile(TestImages.Webp.Lossless.WithExif, PixelTypes.Rgba32, true)] + public void IgnoreMetadata_ControlsWhetherExifIsParsed(TestImageProvider provider, bool ignoreMetadata) + where TPixel : unmanaged, IPixel + { + var decoder = new WebpDecoder { IgnoreMetadata = ignoreMetadata }; + + using Image image = provider.GetImage(decoder); + if (ignoreMetadata) + { + Assert.Null(image.Metadata.ExifProfile); + } + else + { + ExifProfile exifProfile = image.Metadata.ExifProfile; + Assert.NotNull(exifProfile); + Assert.NotEmpty(exifProfile.Values); + Assert.Contains(exifProfile.Values, m => m.Tag.Equals(ExifTag.Make) && m.GetValue().Equals("Canon")); + Assert.Contains(exifProfile.Values, m => m.Tag.Equals(ExifTag.Model) && m.GetValue().Equals("Canon PowerShot S40")); + Assert.Contains(exifProfile.Values, m => m.Tag.Equals(ExifTag.Software) && m.GetValue().Equals("GIMP 2.10.2")); + } + } + + [Theory] + [WithFile(TestImages.Webp.Lossy.WithIccp, PixelTypes.Rgba32, false)] + [WithFile(TestImages.Webp.Lossy.WithIccp, PixelTypes.Rgba32, true)] + [WithFile(TestImages.Webp.Lossless.WithIccp, PixelTypes.Rgba32, false)] + [WithFile(TestImages.Webp.Lossless.WithIccp, PixelTypes.Rgba32, true)] + public void IgnoreMetadata_ControlsWhetherIccpIsParsed(TestImageProvider provider, bool ignoreMetadata) + where TPixel : unmanaged, IPixel + { + var decoder = new WebpDecoder { IgnoreMetadata = ignoreMetadata }; + + using Image image = provider.GetImage(decoder); + if (ignoreMetadata) + { + Assert.Null(image.Metadata.IccProfile); + } + else + { + Assert.NotNull(image.Metadata.IccProfile); + Assert.NotEmpty(image.Metadata.IccProfile.Entries); + } + } + + [Theory] + [InlineData(WebpFileFormatType.Lossy)] + [InlineData(WebpFileFormatType.Lossless)] + public void Encode_WritesExifWithPadding(WebpFileFormatType fileFormatType) + { + // arrange + using var input = new Image(25, 25); + using var memoryStream = new MemoryStream(); + var expectedExif = new ExifProfile(); + string expectedSoftware = "ImageSharp"; + expectedExif.SetValue(ExifTag.Software, expectedSoftware); + input.Metadata.ExifProfile = expectedExif; + + // act + input.Save(memoryStream, new WebpEncoder() { FileFormat = fileFormatType }); + memoryStream.Position = 0; + + // assert + using var image = Image.Load(memoryStream); + ExifProfile actualExif = image.Metadata.ExifProfile; + Assert.NotNull(actualExif); + Assert.Equal(expectedExif.Values.Count, actualExif.Values.Count); + Assert.Equal(expectedSoftware, actualExif.GetValue(ExifTag.Software).Value); + } + + [Theory] + [WithFile(TestImages.Webp.Lossy.WithExif, PixelTypes.Rgba32)] + public void EncodeLossyWebp_PreservesExif(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + // arrange + using Image input = provider.GetImage(WebpDecoder); + using var memoryStream = new MemoryStream(); + ExifProfile expectedExif = input.Metadata.ExifProfile; + + // act + input.Save(memoryStream, new WebpEncoder() { FileFormat = WebpFileFormatType.Lossy }); + memoryStream.Position = 0; + + // assert + using var image = Image.Load(memoryStream); + ExifProfile actualExif = image.Metadata.ExifProfile; + Assert.NotNull(actualExif); + Assert.Equal(expectedExif.Values.Count, actualExif.Values.Count); + } + + [Theory] + [WithFile(TestImages.Webp.Lossless.WithExif, PixelTypes.Rgba32)] + public void EncodeLosslessWebp_PreservesExif(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + // arrange + using Image input = provider.GetImage(WebpDecoder); + using var memoryStream = new MemoryStream(); + ExifProfile expectedExif = input.Metadata.ExifProfile; + + // act + input.Save(memoryStream, new WebpEncoder() { FileFormat = WebpFileFormatType.Lossless }); + memoryStream.Position = 0; + + // assert + using var image = Image.Load(memoryStream); + ExifProfile actualExif = image.Metadata.ExifProfile; + Assert.NotNull(actualExif); + Assert.Equal(expectedExif.Values.Count, actualExif.Values.Count); + } + } +} diff --git a/tests/ImageSharp.Tests/Formats/WebP/YuvConversionTests.cs b/tests/ImageSharp.Tests/Formats/WebP/YuvConversionTests.cs new file mode 100644 index 000000000..65b4b987e --- /dev/null +++ b/tests/ImageSharp.Tests/Formats/WebP/YuvConversionTests.cs @@ -0,0 +1,238 @@ +// Copyright (c) Six Labors. +// Licensed under the Apache License, Version 2.0. + +using System; +using SixLabors.ImageSharp.Advanced; +using SixLabors.ImageSharp.Formats.Webp.Lossy; +using SixLabors.ImageSharp.Memory; +using SixLabors.ImageSharp.PixelFormats; +using Xunit; + +namespace SixLabors.ImageSharp.Tests.Formats.Webp +{ + [Trait("Format", "Webp")] + public class YuvConversionTests + { + [Theory] + [WithFile(TestImages.Webp.Yuv, PixelTypes.Rgba32)] + public void ConvertRgbToYuv_Works(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + // arrange + using Image image = provider.GetImage(); + Configuration config = image.GetConfiguration(); + MemoryAllocator memoryAllocator = config.MemoryAllocator; + int pixels = image.Width * image.Height; + int uvWidth = (image.Width + 1) >> 1; + using System.Buffers.IMemoryOwner yBuffer = memoryAllocator.Allocate(pixels, AllocationOptions.Clean); + using System.Buffers.IMemoryOwner uBuffer = memoryAllocator.Allocate(uvWidth * image.Height, AllocationOptions.Clean); + using System.Buffers.IMemoryOwner vBuffer = memoryAllocator.Allocate(uvWidth * image.Height, AllocationOptions.Clean); + Span y = yBuffer.GetSpan(); + Span u = uBuffer.GetSpan(); + Span v = vBuffer.GetSpan(); + byte[] expectedY = + { + 82, 82, 82, 82, 128, 135, 134, 129, 167, 179, 176, 172, 192, 201, 200, 204, 188, 172, 175, 177, 168, + 151, 154, 154, 153, 152, 151, 151, 152, 160, 160, 160, 160, 82, 82, 82, 82, 140, 137, 135, 116, 174, + 183, 176, 162, 196, 199, 199, 210, 188, 166, 176, 181, 170, 145, 155, 154, 153, 154, 151, 151, 150, + 162, 159, 160, 160, 82, 82, 83, 82, 142, 139, 137, 117, 176, 184, 177, 164, 195, 199, 198, 210, 188, + 165, 175, 180, 169, 145, 155, 154, 153, 154, 152, 151, 150, 163, 160, 160, 160, 82, 82, 82, 82, 124, + 122, 120, 101, 161, 171, 165, 151, 197, 209, 208, 210, 197, 174, 183, 189, 175, 148, 158, 158, 155, + 151, 148, 148, 147, 159, 156, 156, 159, 128, 140, 142, 124, 189, 185, 183, 167, 201, 199, 198, 209, + 179, 165, 171, 179, 160, 145, 151, 152, 151, 154, 152, 151, 153, 164, 160, 160, 160, 170, 170, 170, + 169, 135, 137, 139, 122, 185, 182, 180, 165, 201, 200, 199, 210, 180, 166, 173, 180, 162, 145, 153, + 153, 151, 154, 151, 150, 152, 164, 160, 159, 159, 170, 170, 170, 170, 134, 135, 137, 120, 184, 180, + 177, 164, 200, 198, 196, 210, 181, 167, 174, 181, 163, 146, 155, 155, 153, 154, 152, 150, 152, 163, + 160, 159, 159, 167, 167, 167, 168, 129, 116, 117, 101, 167, 166, 164, 149, 205, 210, 209, 210, 191, + 177, 184, 191, 170, 149, 158, 159, 153, 151, 148, 146, 148, 159, 155, 155, 155, 170, 169, 170, 170, + 167, 174, 175, 161, 201, 201, 200, 204, 178, 173, 174, 185, 159, 148, 155, 158, 152, 152, 151, 150, + 153, 162, 159, 158, 160, 170, 169, 169, 168, 109, 122, 120, 129, 179, 183, 184, 171, 199, 200, 198, + 210, 172, 166, 170, 179, 155, 145, 150, 152, 149, 155, 152, 150, 155, 164, 161, 159, 162, 170, 170, + 170, 170, 92, 111, 109, 115, 176, 176, 177, 165, 198, 198, 196, 209, 174, 170, 173, 183, 159, 148, + 155, 156, 152, 154, 152, 150, 154, 163, 160, 158, 159, 166, 166, 168, 169, 98, 117, 116, 117, 172, + 162, 164, 152, 209, 210, 210, 210, 184, 179, 183, 192, 164, 151, 157, 159, 150, 150, 148, 146, 150, + 159, 155, 154, 157, 170, 169, 170, 170, 117, 136, 134, 123, 192, 196, 196, 197, 179, 180, 180, 191, + 159, 155, 159, 164, 153, 151, 152, 150, 154, 160, 157, 155, 160, 170, 166, 167, 165, 120, 134, 135, + 139, 69, 87, 86, 90, 201, 199, 199, 208, 165, 166, 167, 177, 148, 145, 148, 151, 150, 155, 153, 150, + 157, 165, 162, 159, 165, 170, 169, 170, 166, 84, 107, 108, 111, 49, 66, 64, 71, 200, 199, 198, 208, + 171, 173, 174, 184, 155, 150, 155, 157, 152, 153, 153, 149, 156, 163, 160, 157, 162, 167, 165, 169, + 167, 97, 121, 121, 125, 60, 77, 75, 76, 204, 210, 210, 210, 179, 180, 181, 191, 158, 152, 156, 159, + 150, 150, 149, 146, 152, 159, 156, 153, 160, 170, 169, 170, 170, 112, 135, 136, 138, 71, 88, 86, 79, + 188, 188, 188, 197, 160, 162, 163, 170, 152, 150, 152, 151, 154, 157, 156, 152, 160, 167, 164, 164, + 161, 135, 146, 150, 143, 77, 98, 99, 103, 51, 62, 60, 62, 172, 166, 165, 174, 145, 145, 145, 150, + 152, 155, 154, 150, 160, 165, 163, 159, 168, 170, 168, 170, 151, 80, 104, 109, 101, 44, 63, 63, 66, + 55, 52, 53, 51, 175, 176, 175, 183, 151, 153, 155, 158, 151, 152, 152, 148, 157, 161, 160, 156, 164, + 168, 165, 169, 156, 100, 122, 126, 118, 60, 79, 79, 81, 54, 52, 52, 51, 177, 181, 180, 188, 153, + 153, 155, 159, 149, 150, 150, 146, 155, 159, 157, 153, 164, 170, 169, 170, 170, 109, 131, 136, 127, + 66, 86, 86, 87, 46, 43, 43, 47, 168, 170, 169, 175, 151, 151, 152, 153, 153, 155, 154, 150, 160, + 164, 162, 160, 161, 151, 157, 165, 144, 88, 109, 114, 105, 55, 69, 68, 67, 62, 56, 56, 59, 151, 145, + 145, 148, 154, 154, 154, 150, 162, 164, 163, 159, 170, 170, 167, 170, 135, 80, 100, 110, 89, 41, 61, + 64, 59, 56, 53, 50, 50, 94, 85, 86, 79, 154, 155, 155, 158, 152, 152, 152, 148, 159, 161, 160, 155, + 166, 169, 165, 169, 146, 104, 122, 131, 110, 61, 80, 83, 75, 53, 53, 48, 47, 84, 74, 75, 75, 154, + 154, 154, 158, 151, 150, 150, 146, 158, 159, 158, 154, 167, 170, 169, 170, 153, 108, 127, 136, 113, + 63, 83, 87, 78, 48, 46, 43, 41, 81, 71, 72, 74, 153, 153, 153, 155, 153, 152, 152, 148, 160, 161, + 159, 157, 165, 165, 166, 170, 143, 101, 118, 127, 104, 60, 75, 78, 70, 56, 51, 48, 46, 85, 76, 77, + 81, 152, 154, 154, 151, 164, 164, 163, 159, 170, 170, 167, 170, 121, 84, 98, 114, 78, 44, 60, 68, + 52, 56, 53, 48, 56, 96, 85, 85, 83, 107, 105, 106, 100, 151, 151, 152, 148, 160, 160, 160, 155, 169, + 170, 166, 169, 134, 108, 121, 135, 98, 63, 79, 87, 69, 53, 53, 46, 50, 85, 73, 73, 71, 104, 95, 96, + 97, 151, 151, 151, 148, 160, 159, 159, 155, 169, 170, 170, 170, 137, 108, 121, 136, 99, 63, 78, 87, + 67, 51, 48, 43, 48, 85, 73, 72, 71, 105, 96, 97, 98, 152, 150, 150, 147, 160, 159, 159, 155, 169, + 170, 169, 170, 140, 111, 125, 139, 102, 67, 81, 87, 67, 50, 47, 41, 46, 83, 71, 71, 70, 103, 96, 96, + 98, 160, 162, 163, 159, 170, 170, 167, 170, 109, 91, 98, 117, 70, 49, 60, 72, 49, 55, 54, 46, 62, + 95, 84, 81, 85, 107, 104, 105, 103, 96, 98, 97, 100, 160, 159, 160, 156, 170, 170, 167, 169, 122, + 111, 118, 136, 87, 66, 77, 88, 62, 52, 53, 43, 56, 85, 74, 71, 76, 105, 95, 96, 96, 98, 100, 100, + 100, 160, 160, 160, 156, 170, 170, 167, 170, 120, 109, 116, 134, 86, 64, 75, 86, 60, 53, 51, 43, 56, + 86, 75, 72, 77, 106, 96, 97, 96, 97, 100, 100, 100, 160, 160, 160, 159, 169, 170, 168, 170, 129, + 115, 117, 123, 90, 71, 76, 79, 62, 51, 51, 47, 59, 79, 75, 74, 81, 100, 97, 98, 98, 100, 100, 100, + 100 + }; + byte[] expectedU = + { + 90, 90, 59, 63, 36, 38, 23, 20, 34, 35, 47, 48, 70, 82, 104, 121, 121, 90, 90, 61, 69, 37, 42, 22, + 18, 33, 32, 47, 47, 67, 75, 97, 113, 120, 59, 61, 30, 37, 22, 20, 38, 36, 50, 50, 78, 83, 113, 122, + 142, 166, 164, 63, 69, 37, 43, 20, 18, 34, 32, 48, 47, 70, 73, 102, 110, 136, 166, 166, 36, 37, 22, + 20, 38, 35, 50, 49, 80, 80, 116, 119, 145, 165, 185, 197, 193, 38, 42, 20, 18, 35, 32, 48, 47, 72, + 72, 106, 108, 142, 165, 184, 191, 194, 23, 22, 38, 34, 50, 48, 81, 77, 117, 115, 150, 160, 184, 194, + 212, 220, 217, 20, 18, 36, 32, 49, 47, 76, 71, 111, 108, 148, 164, 185, 190, 208, 217, 219, 34, 33, + 50, 48, 80, 73, 116, 111, 150, 154, 184, 190, 213, 217, 226, 232, 232, 35, 32, 49, 47, 80, 72, 115, + 107, 154, 164, 187, 189, 211, 216, 228, 237, 235, 47, 46, 77, 70, 115, 106, 149, 148, 184, 187, 213, + 214, 226, 230, 227, 223, 224, 48, 47, 83, 73, 119, 108, 159, 164, 190, 189, 214, 216, 229, 236, 229, + 222, 220, 70, 67, 113, 101, 145, 142, 184, 185, 213, 211, 226, 229, 226, 226, 218, 211, 212, 82, 75, + 122, 110, 165, 165, 193, 190, 217, 216, 231, 236, 226, 222, 214, 208, 207, 104, 97, 142, 136, 186, + 184, 212, 208, 227, 228, 227, 229, 218, 214, 196, 185, 188, 121, 113, 166, 166, 197, 191, 220, 217, + 232, 237, 223, 222, 211, 208, 185, 173, 172, 121, 120, 164, 166, 193, 194, 217, 219, 232, 235, 224, + 220, 212, 207, 188, 172, 172 + }; + byte[] expectedV = + { + 240, 240, 201, 206, 172, 174, 136, 136, 92, 90, 55, 50, 37, 30, 26, 23, 23, 240, 240, 204, 213, 173, + 179, 141, 141, 96, 98, 56, 54, 38, 31, 27, 25, 23, 201, 204, 164, 172, 129, 135, 82, 87, 46, 47, 33, + 29, 25, 23, 20, 16, 16, 206, 213, 172, 180, 137, 141, 93, 99, 54, 54, 36, 31, 26, 25, 21, 17, 16, + 172, 173, 129, 138, 81, 89, 45, 49, 32, 30, 24, 24, 19, 16, 42, 55, 51, 174, 179, 136, 141, 89, 99, + 51, 55, 35, 31, 26, 25, 21, 17, 39, 48, 52, 136, 141, 82, 92, 45, 51, 31, 32, 24, 24, 19, 17, 43, + 51, 74, 85, 81, 136, 141, 87, 99, 49, 55, 32, 32, 25, 25, 20, 17, 41, 46, 69, 81, 83, 92, 96, 46, + 53, 32, 34, 24, 25, 18, 18, 44, 47, 76, 81, 103, 117, 116, 90, 97, 48, 54, 30, 31, 24, 25, 18, 17, + 43, 46, 74, 80, 103, 118, 122, 55, 57, 33, 36, 24, 26, 19, 20, 44, 43, 76, 77, 102, 111, 138, 159, + 157, 50, 54, 30, 31, 24, 25, 17, 17, 47, 46, 77, 79, 106, 118, 143, 164, 168, 37, 38, 25, 26, 19, + 21, 43, 41, 75, 73, 103, 106, 138, 152, 174, 195, 194, 30, 31, 23, 25, 16, 17, 51, 46, 81, 79, 111, + 118, 151, 164, 188, 205, 206, 26, 27, 20, 21, 43, 39, 74, 69, 103, 102, 138, 143, 174, 188, 204, + 216, 218, 23, 25, 16, 17, 55, 48, 85, 81, 117, 118, 159, 164, 195, 205, 216, 227, 227, 23, 23, 16, + 16, 51, 52, 81, 83, 116, 122, 157, 168, 194, 206, 218, 227, 227 + }; + + // act + YuvConversion.ConvertRgbToYuv(image, config, memoryAllocator, y, u, v); + + // assert + Assert.True(expectedY.AsSpan().SequenceEqual(y)); + Assert.True(expectedU.AsSpan().SequenceEqual(u.Slice(0, expectedU.Length))); + Assert.True(expectedV.AsSpan().SequenceEqual(v.Slice(0, expectedV.Length))); + } + + [Theory] + [WithFile(TestImages.Png.TestPattern31x31HalfTransparent, PixelTypes.Rgba32)] + public void ConvertRgbToYuv_WithAlpha_Works(TestImageProvider provider) + where TPixel : unmanaged, IPixel + { + // arrange + using Image image = provider.GetImage(); + Configuration config = image.GetConfiguration(); + MemoryAllocator memoryAllocator = config.MemoryAllocator; + int pixels = image.Width * image.Height; + int uvWidth = (image.Width + 1) >> 1; + using System.Buffers.IMemoryOwner yBuffer = memoryAllocator.Allocate(pixels, AllocationOptions.Clean); + using System.Buffers.IMemoryOwner uBuffer = memoryAllocator.Allocate(uvWidth * image.Height, AllocationOptions.Clean); + using System.Buffers.IMemoryOwner vBuffer = memoryAllocator.Allocate(uvWidth * image.Height, AllocationOptions.Clean); + + Span y = yBuffer.GetSpan(); + Span u = uBuffer.GetSpan(); + Span v = vBuffer.GetSpan(); + byte[] expectedY = + { + 16, 16, 16, 16, 16, 235, 235, 235, 235, 235, 16, 16, 16, 16, 16, 152, 41, 41, 152, 152, 41, 41, 152, + 152, 41, 41, 152, 152, 41, 41, 152, 16, 16, 16, 16, 16, 235, 235, 235, 235, 235, 16, 16, 16, 16, 16, + 152, 41, 41, 152, 152, 41, 41, 152, 152, 41, 41, 152, 152, 41, 41, 152, 16, 16, 16, 16, 16, 235, + 235, 235, 235, 235, 16, 16, 16, 16, 16, 152, 41, 41, 152, 152, 41, 41, 152, 152, 41, 41, 152, 152, + 41, 41, 152, 16, 16, 16, 16, 16, 235, 235, 235, 235, 235, 16, 16, 16, 16, 16, 152, 41, 41, 152, 152, + 41, 41, 152, 152, 41, 41, 152, 152, 41, 41, 152, 16, 16, 16, 16, 16, 235, 235, 235, 235, 235, 16, + 16, 16, 16, 16, 152, 41, 41, 152, 152, 41, 41, 152, 152, 41, 41, 152, 152, 41, 41, 152, 235, 235, + 235, 235, 235, 16, 16, 16, 16, 16, 235, 235, 235, 235, 235, 152, 41, 41, 152, 152, 41, 41, 152, 152, + 41, 41, 152, 152, 41, 41, 152, 235, 235, 235, 235, 235, 16, 16, 16, 16, 16, 235, 235, 235, 235, 235, + 152, 41, 41, 152, 152, 41, 41, 152, 152, 41, 41, 152, 152, 41, 41, 152, 235, 235, 235, 235, 235, 16, + 16, 16, 16, 16, 235, 235, 235, 235, 235, 152, 41, 41, 152, 152, 41, 41, 152, 152, 41, 41, 152, 152, + 41, 41, 152, 235, 235, 235, 235, 235, 16, 16, 16, 16, 16, 235, 235, 235, 235, 235, 152, 41, 41, 152, + 152, 41, 41, 152, 152, 41, 41, 152, 152, 41, 41, 152, 235, 235, 235, 235, 235, 16, 16, 16, 16, 16, + 235, 235, 235, 235, 235, 152, 41, 41, 152, 152, 41, 41, 152, 152, 41, 41, 152, 152, 41, 41, 152, 16, + 16, 16, 16, 16, 235, 235, 235, 235, 235, 16, 16, 16, 16, 16, 152, 41, 41, 152, 152, 41, 41, 152, + 152, 41, 41, 152, 152, 41, 41, 152, 16, 16, 16, 16, 16, 235, 235, 235, 235, 235, 16, 16, 16, 16, 16, + 152, 41, 41, 152, 152, 41, 41, 152, 152, 41, 41, 152, 152, 41, 41, 152, 16, 16, 16, 16, 16, 235, + 235, 235, 235, 235, 16, 16, 16, 16, 16, 152, 41, 41, 152, 152, 41, 41, 152, 152, 41, 41, 152, 152, + 41, 41, 152, 16, 16, 16, 16, 16, 235, 235, 235, 235, 235, 16, 16, 16, 16, 16, 152, 41, 41, 152, 152, + 41, 41, 152, 152, 41, 41, 152, 152, 41, 41, 152, 16, 16, 16, 16, 16, 235, 235, 235, 235, 235, 16, + 16, 16, 16, 16, 152, 41, 41, 152, 152, 41, 41, 152, 152, 41, 41, 152, 152, 41, 41, 152, 82, 82, 82, + 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 81, 158, 170, 118, 130, 182, 65, 142, 220, 103, 155, + 167, 115, 127, 204, 127, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 145, 157, 106, + 118, 170, 118, 130, 207, 90, 142, 154, 103, 114, 192, 115, 127, 82, 82, 82, 82, 82, 82, 82, 82, 82, + 82, 82, 82, 82, 82, 82, 145, 93, 105, 157, 105, 117, 195, 78, 130, 142, 90, 102, 179, 102, 114, 192, + 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 80, 92, 170, 93, 105, 182, 65, 142, 129, + 77, 155, 167, 90, 102, 179, 62, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, 80, 157, + 80, 92, 170, 52, 130, 117, 65, 142, 154, 102, 89, 166, 49, 127, 82, 82, 82, 82, 82, 82, 82, 82, 82, + 82, 82, 82, 82, 82, 82, 145, 197, 80, 157, 169, 117, 104, 181, 130, 142, 90, 77, 154, 37, 114, 191, + 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 209, 67, 144, 156, 105, 117, 169, 117, + 129, 206, 64, 141, 153, 102, 179, 166, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, + 55, 132, 144, 92, 169, 156, 104, 116, 194, 77, 129, 141, 89, 166, 178, 101, 81, 81, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81, 81, 119, 131, 80, 157, 144, 92, 104, 181, 64, 116, 193, 76, 154, + 166, 89, 101, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 119, 67, 144, 156, 79, 91, + 169, 52, 104, 181, 64, 141, 153, 76, 88, 165, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, + 81, 81, 183, 132, 144, 196, 79, 156, 39, 116, 168, 51, 129, 141, 89, 76, 153, 101, 81, 81, 81, 81, + 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 119, 131, 183, 66, 143, 155, 104, 156, 168, 116, 128, + 205, 63, 140, 218, 101, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 119, 196, 54, + 131, 208, 91, 143, 155, 103, 115, 193, 51, 128, 205, 88, 165, 41, 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 183, 41, 118, 196, 79, 156, 143, 91, 103, 180, 63, 115, 193, 75, 153, 165, + 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 29, 106, 183, 66, 143, 130, 78, 90, 168, + 116, 103, 180, 63, 140, 152, 75, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 93, + 171, 53, 131, 118, 66, 78, 155, 103, 90, 167, 50, 128, 140, 63, 75 + }; + byte[] expectedU = + { + 128, 128, 128, 128, 128, 128, 128, 139, 240, 139, 240, 139, 240, 139, 240, 139, 128, 128, 128, 128, + 128, 128, 128, 139, 240, 139, 240, 139, 240, 139, 240, 139, 128, 128, 128, 128, 128, 128, 128, 139, + 240, 139, 240, 139, 240, 139, 240, 139, 128, 128, 128, 128, 128, 128, 128, 139, 240, 139, 240, 139, + 240, 139, 240, 139, 128, 128, 128, 128, 128, 128, 128, 139, 240, 139, 240, 139, 240, 139, 240, 139, + 128, 128, 128, 128, 128, 128, 128, 139, 240, 139, 240, 139, 240, 139, 240, 139, 128, 128, 128, 128, + 128, 128, 128, 139, 240, 139, 240, 139, 240, 139, 240, 139, 112, 112, 108, 106, 106, 112, 112, 139, + 229, 146, 204, 132, 199, 131, 204, 135, 90, 90, 90, 90, 90, 90, 90, 100, 161, 92, 116, 141, 99, 155, + 113, 97, 90, 90, 90, 90, 90, 90, 90, 173, 145, 114, 173, 122, 133, 127, 96, 170, 96, 96, 96, 96, 96, + 96, 96, 148, 98, 134, 122, 113, 139, 93, 169, 85, 91, 91, 91, 91, 91, 91, 91, 108, 134, 130, 112, + 149, 105, 139, 146, 110, 91, 91, 91, 91, 91, 91, 91, 107, 164, 117, 149, 127, 128, 166, 107, 129, + 159, 159, 159, 159, 159, 159, 159, 161, 112, 113, 138, 87, 143, 112, 88, 161, 240, 240, 240, 240, + 240, 240, 240, 137, 110, 162, 110, 140, 158, 104, 159, 137, 240, 240, 240, 240, 240, 240, 240, 109, + 150, 108, 140, 161, 80, 157, 162, 128 + }; + byte[] expectedV = + { + 128, 128, 128, 128, 128, 128, 128, 189, 110, 189, 110, 189, 110, 189, 110, 189, 128, 128, 128, 128, + 128, 128, 128, 189, 110, 189, 110, 189, 110, 189, 110, 189, 128, 128, 128, 128, 128, 128, 128, 189, + 110, 189, 110, 189, 110, 189, 110, 189, 128, 128, 128, 128, 128, 128, 128, 189, 110, 189, 110, 189, + 110, 189, 110, 189, 128, 128, 128, 128, 128, 128, 128, 189, 110, 189, 110, 189, 110, 189, 110, 189, + 128, 128, 128, 128, 128, 128, 128, 189, 110, 189, 110, 189, 110, 189, 110, 189, 128, 128, 128, 128, + 128, 128, 128, 189, 110, 189, 110, 189, 110, 189, 110, 189, 175, 175, 186, 193, 193, 175, 175, 188, + 109, 172, 108, 164, 119, 152, 92, 189, 240, 240, 240, 240, 240, 240, 240, 104, 121, 131, 142, 135, + 109, 92, 146, 115, 240, 240, 240, 240, 240, 240, 240, 122, 136, 148, 137, 113, 157, 155, 121, 130, + 155, 155, 155, 155, 155, 155, 155, 109, 135, 96, 88, 142, 136, 105, 138, 116, 81, 81, 81, 81, 81, + 81, 81, 143, 104, 148, 150, 111, 138, 128, 116, 141, 81, 81, 81, 81, 81, 81, 81, 63, 147, 133, 119, + 141, 165, 126, 147, 173, 101, 101, 101, 101, 101, 101, 101, 135, 109, 129, 122, 124, 107, 108, 128, + 138, 110, 110, 110, 110, 110, 110, 110, 117, 137, 151, 127, 114, 131, 139, 142, 120, 110, 110, 110, + 110, 110, 110, 110, 142, 156, 119, 137, 167, 141, 151, 66, 85 + }; + + // act + YuvConversion.ConvertRgbToYuv(image, config, memoryAllocator, y, u, v); + + // assert + Assert.True(expectedY.AsSpan().SequenceEqual(y)); + Assert.True(expectedU.AsSpan().SequenceEqual(u.Slice(0, expectedU.Length))); + Assert.True(expectedV.AsSpan().SequenceEqual(v.Slice(0, expectedV.Length))); + } + } +} diff --git a/tests/ImageSharp.Tests/Helpers/ColorNumericsTests.cs b/tests/ImageSharp.Tests/Helpers/ColorNumericsTests.cs index 7d7f5f15a..af24c3e7b 100644 --- a/tests/ImageSharp.Tests/Helpers/ColorNumericsTests.cs +++ b/tests/ImageSharp.Tests/Helpers/ColorNumericsTests.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. using System.Numerics; - using Xunit; namespace SixLabors.ImageSharp.Tests.Helpers diff --git a/tests/ImageSharp.Tests/Helpers/ParallelRowIteratorTests.cs b/tests/ImageSharp.Tests/Helpers/ParallelRowIteratorTests.cs index 7d4f2da42..5cf5db523 100644 --- a/tests/ImageSharp.Tests/Helpers/ParallelRowIteratorTests.cs +++ b/tests/ImageSharp.Tests/Helpers/ParallelRowIteratorTests.cs @@ -5,7 +5,6 @@ using System; using System.Linq; using System.Numerics; using System.Threading; - using SixLabors.ImageSharp.Advanced; using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.PixelFormats; diff --git a/tests/ImageSharp.Tests/Helpers/TolerantMathTests.cs b/tests/ImageSharp.Tests/Helpers/TolerantMathTests.cs index 0dbbaa53f..2bf0bdc84 100644 --- a/tests/ImageSharp.Tests/Helpers/TolerantMathTests.cs +++ b/tests/ImageSharp.Tests/Helpers/TolerantMathTests.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. using System; - using Xunit; // ReSharper disable InconsistentNaming diff --git a/tests/ImageSharp.Tests/IO/LocalFileSystemTests.cs b/tests/ImageSharp.Tests/IO/LocalFileSystemTests.cs index 27aaabee2..a66f10435 100644 --- a/tests/ImageSharp.Tests/IO/LocalFileSystemTests.cs +++ b/tests/ImageSharp.Tests/IO/LocalFileSystemTests.cs @@ -47,4 +47,4 @@ namespace SixLabors.ImageSharp.Tests.IO File.Delete(path); } } -} \ No newline at end of file +} diff --git a/tests/ImageSharp.Tests/Image/ImageFrameCollectionTests.Generic.cs b/tests/ImageSharp.Tests/Image/ImageFrameCollectionTests.Generic.cs index dbc5af536..dd8275ee8 100644 --- a/tests/ImageSharp.Tests/Image/ImageFrameCollectionTests.Generic.cs +++ b/tests/ImageSharp.Tests/Image/ImageFrameCollectionTests.Generic.cs @@ -3,7 +3,6 @@ using System; using System.Linq; - using SixLabors.ImageSharp.Advanced; using SixLabors.ImageSharp.PixelFormats; diff --git a/tests/ImageSharp.Tests/Image/ImageFrameCollectionTests.NonGeneric.cs b/tests/ImageSharp.Tests/Image/ImageFrameCollectionTests.NonGeneric.cs index 15838f690..b65615121 100644 --- a/tests/ImageSharp.Tests/Image/ImageFrameCollectionTests.NonGeneric.cs +++ b/tests/ImageSharp.Tests/Image/ImageFrameCollectionTests.NonGeneric.cs @@ -3,7 +3,6 @@ using System; using System.Linq; - using SixLabors.ImageSharp.Advanced; using SixLabors.ImageSharp.Formats.Gif; using SixLabors.ImageSharp.PixelFormats; diff --git a/tests/ImageSharp.Tests/Image/ImageFrameCollectionTests.cs b/tests/ImageSharp.Tests/Image/ImageFrameCollectionTests.cs index 06cd7defc..220470074 100644 --- a/tests/ImageSharp.Tests/Image/ImageFrameCollectionTests.cs +++ b/tests/ImageSharp.Tests/Image/ImageFrameCollectionTests.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. using System; - using SixLabors.ImageSharp.PixelFormats; namespace SixLabors.ImageSharp.Tests diff --git a/tests/ImageSharp.Tests/Image/ImageFrameTests.cs b/tests/ImageSharp.Tests/Image/ImageFrameTests.cs index d4aef7538..766bbd138 100644 --- a/tests/ImageSharp.Tests/Image/ImageFrameTests.cs +++ b/tests/ImageSharp.Tests/Image/ImageFrameTests.cs @@ -16,7 +16,8 @@ namespace SixLabors.ImageSharp.Tests private void LimitBufferCapacity(int bufferCapacityInBytes) { - var allocator = (ArrayPoolMemoryAllocator)this.configuration.MemoryAllocator; + var allocator = ArrayPoolMemoryAllocator.CreateDefault(); + this.configuration.MemoryAllocator = allocator; allocator.BufferCapacityInBytes = bufferCapacityInBytes; } diff --git a/tests/ImageSharp.Tests/Image/ImageRotationTests.cs b/tests/ImageSharp.Tests/Image/ImageRotationTests.cs index 4df823801..2bc53ee17 100644 --- a/tests/ImageSharp.Tests/Image/ImageRotationTests.cs +++ b/tests/ImageSharp.Tests/Image/ImageRotationTests.cs @@ -1,4 +1,4 @@ -// Copyright (c) Six Labors. +// Copyright (c) Six Labors. // Licensed under the Apache License, Version 2.0. using SixLabors.ImageSharp.PixelFormats; @@ -44,7 +44,7 @@ namespace SixLabors.ImageSharp.Tests Assert.Equal(original, rotated); } - private static (Size original, Size rotated) Rotate(int angle) + private static (Size Original, Size Rotated) Rotate(int angle) { var file = TestFile.Create(TestImages.Bmp.Car); using (var image = Image.Load(file.FullPath)) diff --git a/tests/ImageSharp.Tests/Image/ImageTests.Load_FileSystemPath_PassLocalConfiguration.cs b/tests/ImageSharp.Tests/Image/ImageTests.Load_FileSystemPath_PassLocalConfiguration.cs index 9d4ffdace..72477a832 100644 --- a/tests/ImageSharp.Tests/Image/ImageTests.Load_FileSystemPath_PassLocalConfiguration.cs +++ b/tests/ImageSharp.Tests/Image/ImageTests.Load_FileSystemPath_PassLocalConfiguration.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. using System; - using SixLabors.ImageSharp.Formats; using SixLabors.ImageSharp.PixelFormats; diff --git a/tests/ImageSharp.Tests/Image/ImageTests.Load_FromBytes_PassLocalConfiguration.cs b/tests/ImageSharp.Tests/Image/ImageTests.Load_FromBytes_PassLocalConfiguration.cs index 320f3696d..bb7c19f90 100644 --- a/tests/ImageSharp.Tests/Image/ImageTests.Load_FromBytes_PassLocalConfiguration.cs +++ b/tests/ImageSharp.Tests/Image/ImageTests.Load_FromBytes_PassLocalConfiguration.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. using System; - using SixLabors.ImageSharp.Formats; using SixLabors.ImageSharp.PixelFormats; diff --git a/tests/ImageSharp.Tests/Image/ImageTests.Load_FromBytes_UseGlobalConfiguration.cs b/tests/ImageSharp.Tests/Image/ImageTests.Load_FromBytes_UseGlobalConfiguration.cs index 0f46bfa5b..e59150629 100644 --- a/tests/ImageSharp.Tests/Image/ImageTests.Load_FromBytes_UseGlobalConfiguration.cs +++ b/tests/ImageSharp.Tests/Image/ImageTests.Load_FromBytes_UseGlobalConfiguration.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. using System; - using SixLabors.ImageSharp.Formats; using SixLabors.ImageSharp.Formats.Bmp; using SixLabors.ImageSharp.PixelFormats; diff --git a/tests/ImageSharp.Tests/Image/ImageTests.Load_FromStream_ThrowsRightException.cs b/tests/ImageSharp.Tests/Image/ImageTests.Load_FromStream_ThrowsRightException.cs index d462abf7b..644f70d41 100644 --- a/tests/ImageSharp.Tests/Image/ImageTests.Load_FromStream_ThrowsRightException.cs +++ b/tests/ImageSharp.Tests/Image/ImageTests.Load_FromStream_ThrowsRightException.cs @@ -3,7 +3,6 @@ using System; using System.IO; - using SixLabors.ImageSharp.Formats; using SixLabors.ImageSharp.PixelFormats; diff --git a/tests/ImageSharp.Tests/Image/ImageTests.WrapMemory.cs b/tests/ImageSharp.Tests/Image/ImageTests.WrapMemory.cs index 27188b0b4..7fae29a85 100644 --- a/tests/ImageSharp.Tests/Image/ImageTests.WrapMemory.cs +++ b/tests/ImageSharp.Tests/Image/ImageTests.WrapMemory.cs @@ -7,7 +7,6 @@ using System.Drawing; using System.Drawing.Imaging; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; - using SixLabors.ImageSharp.Advanced; using SixLabors.ImageSharp.Common.Helpers; using SixLabors.ImageSharp.Metadata; diff --git a/tests/ImageSharp.Tests/Image/ImageTests.cs b/tests/ImageSharp.Tests/Image/ImageTests.cs index 1296f26c4..db0479484 100644 --- a/tests/ImageSharp.Tests/Image/ImageTests.cs +++ b/tests/ImageSharp.Tests/Image/ImageTests.cs @@ -99,7 +99,8 @@ namespace SixLabors.ImageSharp.Tests private void LimitBufferCapacity(int bufferCapacityInBytes) { - var allocator = (ArrayPoolMemoryAllocator)this.configuration.MemoryAllocator; + var allocator = ArrayPoolMemoryAllocator.CreateDefault(); + this.configuration.MemoryAllocator = allocator; allocator.BufferCapacityInBytes = bufferCapacityInBytes; } diff --git a/tests/ImageSharp.Tests/ImageSharp.Tests.csproj b/tests/ImageSharp.Tests/ImageSharp.Tests.csproj index 30bd544fa..471287006 100644 --- a/tests/ImageSharp.Tests/ImageSharp.Tests.csproj +++ b/tests/ImageSharp.Tests/ImageSharp.Tests.csproj @@ -10,6 +10,11 @@ + + + net6.0;net5.0;netcoreapp3.1;netcoreapp2.1;net472 + + netcoreapp3.1 @@ -21,7 +26,7 @@ - + diff --git a/tests/ImageSharp.Tests/Memory/Allocators/ArrayPoolMemoryAllocatorTests.cs b/tests/ImageSharp.Tests/Memory/Allocators/ArrayPoolMemoryAllocatorTests.cs index 50ec09ce3..dd53b0b56 100644 --- a/tests/ImageSharp.Tests/Memory/Allocators/ArrayPoolMemoryAllocatorTests.cs +++ b/tests/ImageSharp.Tests/Memory/Allocators/ArrayPoolMemoryAllocatorTests.cs @@ -11,6 +11,7 @@ using Xunit; namespace SixLabors.ImageSharp.Tests.Memory.Allocators { + [Collection("RunSerial")] public class ArrayPoolMemoryAllocatorTests { private const int MaxPooledBufferSizeInBytes = 2048; @@ -56,19 +57,14 @@ namespace SixLabors.ImageSharp.Tests.Memory.Allocators [Fact] public void When_PoolSelectorThresholdInBytes_IsGreaterThan_MaxPooledBufferSizeInBytes_ExceptionIsThrown() - { - Assert.ThrowsAny(() => new ArrayPoolMemoryAllocator(100, 200)); - } + => Assert.ThrowsAny(() => new ArrayPoolMemoryAllocator(100, 200)); } [Theory] [InlineData(32)] [InlineData(512)] [InlineData(MaxPooledBufferSizeInBytes - 1)] - public void SmallBuffersArePooled_OfByte(int size) - { - Assert.True(this.LocalFixture.CheckIsRentingPooledBuffer(size)); - } + public void SmallBuffersArePooled_OfByte(int size) => Assert.True(this.LocalFixture.CheckIsRentingPooledBuffer(size)); [Theory] [InlineData(128 * 1024 * 1024)] @@ -118,6 +114,23 @@ namespace SixLabors.ImageSharp.Tests.Memory.Allocators } } + [Fact] + public unsafe void Allocate_MemoryIsPinnableMultipleTimes() + { + ArrayPoolMemoryAllocator allocator = this.LocalFixture.MemoryAllocator; + using IMemoryOwner memoryOwner = allocator.Allocate(100); + + using (MemoryHandle pin = memoryOwner.Memory.Pin()) + { + Assert.NotEqual(IntPtr.Zero, (IntPtr)pin.Pointer); + } + + using (MemoryHandle pin = memoryOwner.Memory.Pin()) + { + Assert.NotEqual(IntPtr.Zero, (IntPtr)pin.Pointer); + } + } + [Theory] [InlineData(false)] [InlineData(true)] diff --git a/tests/ImageSharp.Tests/Memory/Allocators/SimpleGcMemoryAllocatorTests.cs b/tests/ImageSharp.Tests/Memory/Allocators/SimpleGcMemoryAllocatorTests.cs index 8e7b30567..0e1f99725 100644 --- a/tests/ImageSharp.Tests/Memory/Allocators/SimpleGcMemoryAllocatorTests.cs +++ b/tests/ImageSharp.Tests/Memory/Allocators/SimpleGcMemoryAllocatorTests.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. using System; +using System.Buffers; using System.Runtime.InteropServices; using SixLabors.ImageSharp.Memory; using Xunit; @@ -36,9 +37,26 @@ namespace SixLabors.ImageSharp.Tests.Memory.Allocators Assert.Equal("length", ex.ParamName); } + [Fact] + public unsafe void Allocate_MemoryIsPinnableMultipleTimes() + { + SimpleGcMemoryAllocator allocator = this.MemoryAllocator; + using IMemoryOwner memoryOwner = allocator.Allocate(100); + + using (MemoryHandle pin = memoryOwner.Memory.Pin()) + { + Assert.NotEqual(IntPtr.Zero, (IntPtr)pin.Pointer); + } + + using (MemoryHandle pin = memoryOwner.Memory.Pin()) + { + Assert.NotEqual(IntPtr.Zero, (IntPtr)pin.Pointer); + } + } + [StructLayout(LayoutKind.Explicit, Size = 512)] private struct BigStruct { } } -} \ No newline at end of file +} diff --git a/tests/ImageSharp.Tests/Memory/Buffer2DTests.cs b/tests/ImageSharp.Tests/Memory/Buffer2DTests.cs index 015b3617b..9092cbb08 100644 --- a/tests/ImageSharp.Tests/Memory/Buffer2DTests.cs +++ b/tests/ImageSharp.Tests/Memory/Buffer2DTests.cs @@ -7,7 +7,6 @@ using System.Diagnostics; using System.Linq; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; - using SixLabors.ImageSharp.Memory; using Xunit; @@ -118,6 +117,32 @@ namespace SixLabors.ImageSharp.Tests.Memory } } + [Theory] + [InlineData(10, 0, 0, 0)] + [InlineData(10, 0, 2, 0)] + [InlineData(10, 1, 2, 0)] + [InlineData(10, 1, 3, 0)] + [InlineData(10, 1, 5, -1)] + [InlineData(10, 2, 2, -1)] + [InlineData(10, 3, 2, 1)] + [InlineData(10, 4, 2, -1)] + [InlineData(30, 3, 2, 0)] + [InlineData(30, 4, 1, -1)] + public void TryGetPaddedRowSpanY(int bufferCapacity, int y, int padding, int expectedBufferIndex) + { + this.MemoryAllocator.BufferCapacityInBytes = bufferCapacity; + using Buffer2D buffer = this.MemoryAllocator.Allocate2D(3, 5); + + bool expectSuccess = expectedBufferIndex >= 0; + bool success = buffer.TryGetPaddedRowSpan(y, padding, out Span paddedSpan); + Xunit.Assert.Equal(expectSuccess, success); + if (success) + { + int expectedSubBufferOffset = (3 * y) - (expectedBufferIndex * buffer.FastMemoryGroup.BufferLength); + Assert.SpanPointsTo(paddedSpan, buffer.FastMemoryGroup[expectedBufferIndex], expectedSubBufferOffset); + } + } + public static TheoryData GetRowSpanY_OutOfRange_Data = new TheoryData() { { Big, 10, 8, -1 }, diff --git a/tests/ImageSharp.Tests/Metadata/ImageMetadataTests.cs b/tests/ImageSharp.Tests/Metadata/ImageMetadataTests.cs index a82ea7017..2456246b6 100644 --- a/tests/ImageSharp.Tests/Metadata/ImageMetadataTests.cs +++ b/tests/ImageSharp.Tests/Metadata/ImageMetadataTests.cs @@ -98,8 +98,8 @@ namespace SixLabors.ImageSharp.Tests.Metadata image.Metadata.SyncProfiles(); - Assert.Equal(400, ((Rational)image.Metadata.ExifProfile.GetValue(ExifTag.XResolution).Value).ToDouble()); - Assert.Equal(500, ((Rational)image.Metadata.ExifProfile.GetValue(ExifTag.YResolution).Value).ToDouble()); + Assert.Equal(400, image.Metadata.ExifProfile.GetValue(ExifTag.XResolution).Value.ToDouble()); + Assert.Equal(500, image.Metadata.ExifProfile.GetValue(ExifTag.YResolution).Value.ToDouble()); } } } diff --git a/tests/ImageSharp.Tests/Metadata/Profiles/Exif/ExifProfileTests.cs b/tests/ImageSharp.Tests/Metadata/Profiles/Exif/ExifProfileTests.cs index 1f23838ab..ebc096852 100644 --- a/tests/ImageSharp.Tests/Metadata/Profiles/Exif/ExifProfileTests.cs +++ b/tests/ImageSharp.Tests/Metadata/Profiles/Exif/ExifProfileTests.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; +using SixLabors.ImageSharp.Formats.Webp; using SixLabors.ImageSharp.Metadata; using SixLabors.ImageSharp.Metadata.Profiles.Exif; using SixLabors.ImageSharp.PixelFormats; @@ -27,7 +28,17 @@ namespace SixLabors.ImageSharp.Tests.Metadata.Profiles.Exif /// /// Writes a png file. /// - Png + Png, + + /// + /// Writes a lossless webp file. + /// + WebpLossless, + + /// + /// Writes a lossy webp file. + /// + WebpLossy } private static readonly Dictionary TestProfileValues = new Dictionary @@ -44,6 +55,8 @@ namespace SixLabors.ImageSharp.Tests.Metadata.Profiles.Exif [Theory] [InlineData(TestImageWriteFormat.Jpeg)] [InlineData(TestImageWriteFormat.Png)] + [InlineData(TestImageWriteFormat.WebpLossless)] + [InlineData(TestImageWriteFormat.WebpLossy)] public void Constructor(TestImageWriteFormat imageFormat) { Image image = TestFile.Create(TestImages.Jpeg.Baseline.Calliphora).CreateRgba32Image(); @@ -92,6 +105,8 @@ namespace SixLabors.ImageSharp.Tests.Metadata.Profiles.Exif [Theory] [InlineData(TestImageWriteFormat.Jpeg)] [InlineData(TestImageWriteFormat.Png)] + [InlineData(TestImageWriteFormat.WebpLossless)] + [InlineData(TestImageWriteFormat.WebpLossy)] public void WriteFraction(TestImageWriteFormat imageFormat) { using (var memStream = new MemoryStream()) @@ -135,6 +150,8 @@ namespace SixLabors.ImageSharp.Tests.Metadata.Profiles.Exif [Theory] [InlineData(TestImageWriteFormat.Jpeg)] [InlineData(TestImageWriteFormat.Png)] + [InlineData(TestImageWriteFormat.WebpLossless)] + [InlineData(TestImageWriteFormat.WebpLossy)] public void ReadWriteInfinity(TestImageWriteFormat imageFormat) { Image image = TestFile.Create(TestImages.Jpeg.Baseline.Floorplan).CreateRgba32Image(); @@ -170,6 +187,7 @@ namespace SixLabors.ImageSharp.Tests.Metadata.Profiles.Exif https://exiftool.org/TagNames/EXIF.html */ [InlineData(TestImageWriteFormat.Jpeg, 16)] [InlineData(TestImageWriteFormat.Png, 16)] + [InlineData(TestImageWriteFormat.WebpLossless, 16)] public void SetValue(TestImageWriteFormat imageFormat, int expectedProfileValueCount) { Image image = TestFile.Create(TestImages.Jpeg.Baseline.Floorplan).CreateRgba32Image(); @@ -241,6 +259,8 @@ namespace SixLabors.ImageSharp.Tests.Metadata.Profiles.Exif [Theory] [InlineData(TestImageWriteFormat.Jpeg)] [InlineData(TestImageWriteFormat.Png)] + [InlineData(TestImageWriteFormat.WebpLossless)] + [InlineData(TestImageWriteFormat.WebpLossy)] public void WriteOnlyExifTags_Works(TestImageWriteFormat imageFormat) { // Arrange @@ -327,7 +347,7 @@ namespace SixLabors.ImageSharp.Tests.Metadata.Profiles.Exif [Fact] public void ReadWriteLargeProfileJpg() { - ExifTag[] tags = new[] { ExifTag.Software, ExifTag.Copyright, ExifTag.Model, ExifTag.ImageDescription }; + ExifTag[] tags = { ExifTag.Software, ExifTag.Copyright, ExifTag.Model, ExifTag.ImageDescription }; foreach (ExifTag tag in tags) { // Arrange @@ -344,7 +364,7 @@ namespace SixLabors.ImageSharp.Tests.Metadata.Profiles.Exif image.Metadata.ExifProfile = expectedProfile; // Act - using Image reloadedImage = WriteAndRead(image, TestImageWriteFormat.Jpeg); + Image reloadedImage = WriteAndRead(image, TestImageWriteFormat.Jpeg); // Assert ExifProfile actualProfile = reloadedImage.Metadata.ExifProfile; @@ -366,7 +386,7 @@ namespace SixLabors.ImageSharp.Tests.Metadata.Profiles.Exif [Fact] public void ExifTypeUndefined() { - // This image contains an 802 byte EXIF profile + // This image contains an 802 byte EXIF profile. // It has a tag with an index offset of 18,481,152 bytes (overrunning the data) using Image image = TestFile.Create(TestImages.Jpeg.Progressive.Bad.ExifUndefType).CreateRgba32Image(); Assert.NotNull(image); @@ -409,6 +429,8 @@ namespace SixLabors.ImageSharp.Tests.Metadata.Profiles.Exif [Theory] [InlineData(TestImageWriteFormat.Jpeg)] [InlineData(TestImageWriteFormat.Png)] + [InlineData(TestImageWriteFormat.WebpLossless)] + [InlineData(TestImageWriteFormat.WebpLossy)] public void WritingImagePreservesExifProfile(TestImageWriteFormat imageFormat) { // Arrange @@ -483,6 +505,10 @@ namespace SixLabors.ImageSharp.Tests.Metadata.Profiles.Exif return WriteAndReadJpeg(image); case TestImageWriteFormat.Png: return WriteAndReadPng(image); + case TestImageWriteFormat.WebpLossless: + return WriteAndReadWebp(image, WebpFileFormatType.Lossless); + case TestImageWriteFormat.WebpLossy: + return WriteAndReadWebp(image, WebpFileFormatType.Lossy); default: throw new ArgumentException("Unexpected test image format, only Jpeg and Png are allowed"); } @@ -512,6 +538,18 @@ namespace SixLabors.ImageSharp.Tests.Metadata.Profiles.Exif } } + private static Image WriteAndReadWebp(Image image, WebpFileFormatType fileFormat) + { + using (var memStream = new MemoryStream()) + { + image.SaveAsWebp(memStream, new WebpEncoder() { FileFormat = fileFormat }); + image.Dispose(); + + memStream.Position = 0; + return Image.Load(memStream, new WebpDecoder()); + } + } + private static void TestProfile(ExifProfile profile) { Assert.NotNull(profile); diff --git a/tests/ImageSharp.Tests/Metadata/Profiles/ICC/DataWriter/IccDataWriterMatrixTests.cs b/tests/ImageSharp.Tests/Metadata/Profiles/ICC/DataWriter/IccDataWriterMatrixTests.cs index 30e8da2da..88898f6d1 100644 --- a/tests/ImageSharp.Tests/Metadata/Profiles/ICC/DataWriter/IccDataWriterMatrixTests.cs +++ b/tests/ImageSharp.Tests/Metadata/Profiles/ICC/DataWriter/IccDataWriterMatrixTests.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. using System.Numerics; - using SixLabors.ImageSharp.Metadata.Profiles.Icc; using Xunit; diff --git a/tests/ImageSharp.Tests/Numerics/RationalTests.cs b/tests/ImageSharp.Tests/Numerics/RationalTests.cs index 46efe6527..8aa7de1df 100644 --- a/tests/ImageSharp.Tests/Numerics/RationalTests.cs +++ b/tests/ImageSharp.Tests/Numerics/RationalTests.cs @@ -110,4 +110,4 @@ namespace SixLabors.ImageSharp.Tests Assert.Equal("1/2", rational.ToString()); } } -} \ No newline at end of file +} diff --git a/tests/ImageSharp.Tests/PixelFormats/Bgr24Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Bgr24Tests.cs index f6a6d44bb..36cdd157d 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Bgr24Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Bgr24Tests.cs @@ -28,8 +28,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats Assert.NotEqual(color1, color2); } - public static readonly TheoryData ColorData = - new TheoryData { { 1, 2, 3 }, { 4, 5, 6 }, { 0, 255, 42 } }; + public static readonly TheoryData ColorData = new() { { 1, 2, 3 }, { 4, 5, 6 }, { 0, 255, 42 } }; [Theory] [MemberData(nameof(ColorData))] diff --git a/tests/ImageSharp.Tests/PixelFormats/Bgra32Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Bgra32Tests.cs index b7fbdde71..4b8f4c2ea 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Bgra32Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Bgra32Tests.cs @@ -35,10 +35,13 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats } public static readonly TheoryData ColorData = - new TheoryData - { - { 1, 2, 3, 4 }, { 4, 5, 6, 7 }, { 0, 255, 42, 0 }, { 1, 2, 3, 255 } - }; + new() + { + { 1, 2, 3, 4 }, + { 4, 5, 6, 7 }, + { 0, 255, 42, 0 }, + { 1, 2, 3, 255 } + }; [Theory] [MemberData(nameof(ColorData))] diff --git a/tests/ImageSharp.Tests/PixelFormats/L8Tests.cs b/tests/ImageSharp.Tests/PixelFormats/L8Tests.cs index 498606881..fc91590d2 100644 --- a/tests/ImageSharp.Tests/PixelFormats/L8Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/L8Tests.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. using System.Numerics; - using SixLabors.ImageSharp.PixelFormats; using Xunit; @@ -13,29 +12,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats public class L8Tests { public static readonly TheoryData LuminanceData - = new TheoryData - { - 0, - 1, - 2, - 3, - 5, - 13, - 31, - 71, - 73, - 79, - 83, - 109, - 127, - 128, - 131, - 199, - 250, - 251, - 254, - 255 - }; + = new() { 0, 1, 2, 3, 5, 13, 31, 71, 73, 79, 83, 109, 127, 128, 131, 199, 250, 251, 254, 255 }; [Theory] [InlineData(0)] diff --git a/tests/ImageSharp.Tests/PixelFormats/La16Tests.cs b/tests/ImageSharp.Tests/PixelFormats/La16Tests.cs index 5dec524d5..7e082147e 100644 --- a/tests/ImageSharp.Tests/PixelFormats/La16Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/La16Tests.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. using System.Numerics; - using SixLabors.ImageSharp.PixelFormats; using Xunit; @@ -13,29 +12,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats public class La16Tests { public static readonly TheoryData LuminanceData - = new TheoryData - { - 0, - 1, - 2, - 3, - 5, - 13, - 31, - 71, - 73, - 79, - 83, - 109, - 127, - 128, - 131, - 199, - 250, - 251, - 254, - 255 - }; + = new() { 0, 1, 2, 3, 5, 13, 31, 71, 73, 79, 83, 109, 127, 128, 131, 199, 250, 251, 254, 255 }; [Theory] [InlineData(0, 0)] diff --git a/tests/ImageSharp.Tests/PixelFormats/PixelBlenderTests.cs b/tests/ImageSharp.Tests/PixelFormats/PixelBlenderTests.cs index 78aa382aa..5988cc851 100644 --- a/tests/ImageSharp.Tests/PixelFormats/PixelBlenderTests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/PixelBlenderTests.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. using System; - using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.PixelFormats.PixelBlenders; using SixLabors.ImageSharp.Tests.TestUtilities; @@ -13,7 +12,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats [Trait("Category", "PixelFormats")] public class PixelBlenderTests { - public static TheoryData BlenderMappings = new TheoryData + public static TheoryData BlenderMappings = new() { { new TestPixel(), typeof(DefaultPixelBlenders.NormalSrcOver), PixelColorBlendingMode.Normal }, { new TestPixel(), typeof(DefaultPixelBlenders.ScreenSrcOver), PixelColorBlendingMode.Screen }, @@ -44,7 +43,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats Assert.IsType(type, blender); } - public static TheoryData ColorBlendingExpectedResults = new TheoryData + public static TheoryData ColorBlendingExpectedResults = new() { { Color.MistyRose, Color.MidnightBlue, 1, PixelColorBlendingMode.Normal, Color.MidnightBlue }, { Color.MistyRose, Color.MidnightBlue, 1, PixelColorBlendingMode.Screen, new Rgba32(0xFFEEE7FF) }, @@ -68,7 +67,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats Assert.Equal(actualResult.ToVector4(), expectedResult.ToVector4()); } - public static TheoryData AlphaCompositionExpectedResults = new TheoryData + public static TheoryData AlphaCompositionExpectedResults = new() { { Color.MistyRose, Color.MidnightBlue, 1, PixelAlphaCompositionMode.Clear, new Rgba32(0) }, { Color.MistyRose, Color.MidnightBlue, 1, PixelAlphaCompositionMode.Xor, new Rgba32(0) }, diff --git a/tests/ImageSharp.Tests/PixelFormats/PixelConverterTests.ReferenceImplementations.cs b/tests/ImageSharp.Tests/PixelFormats/PixelConverterTests.ReferenceImplementations.cs index b0e152b9f..8b3483145 100644 --- a/tests/ImageSharp.Tests/PixelFormats/PixelConverterTests.ReferenceImplementations.cs +++ b/tests/ImageSharp.Tests/PixelFormats/PixelConverterTests.ReferenceImplementations.cs @@ -4,7 +4,6 @@ using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; - using SixLabors.ImageSharp.PixelFormats; using Xunit; diff --git a/tests/ImageSharp.Tests/PixelFormats/PixelConverterTests.cs b/tests/ImageSharp.Tests/PixelFormats/PixelConverterTests.cs index ec53629a8..315f9f776 100644 --- a/tests/ImageSharp.Tests/PixelFormats/PixelConverterTests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/PixelConverterTests.cs @@ -11,21 +11,21 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats public abstract partial class PixelConverterTests { public static readonly TheoryData RgbaData = - new TheoryData - { - { 0, 0, 0, 0 }, - { 0, 0, 0, 255 }, - { 0, 0, 255, 0 }, - { 0, 255, 0, 0 }, - { 255, 0, 0, 0 }, - { 255, 255, 255, 255 }, - { 0, 0, 0, 1 }, - { 0, 0, 1, 0 }, - { 0, 1, 0, 0 }, - { 1, 0, 0, 0 }, - { 3, 5, 7, 11 }, - { 67, 71, 101, 109 } - }; + new() + { + { 0, 0, 0, 0 }, + { 0, 0, 0, 255 }, + { 0, 0, 255, 0 }, + { 0, 255, 0, 0 }, + { 255, 0, 0, 0 }, + { 255, 255, 255, 255 }, + { 0, 0, 0, 1 }, + { 0, 0, 1, 0 }, + { 0, 1, 0, 0 }, + { 1, 0, 0, 0 }, + { 3, 5, 7, 11 }, + { 67, 71, 101, 109 } + }; public class FromRgba32 : PixelConverterTests { @@ -34,7 +34,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats public void ToArgb32(byte r, byte g, byte b, byte a) { byte[] source = ReferenceImplementations.MakeRgba32ByteArray(r, g, b, a); - var actual = new byte[source.Length]; + byte[] actual = new byte[source.Length]; PixelConverter.FromRgba32.ToArgb32(source, actual); @@ -48,7 +48,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats public void ToBgra32(byte r, byte g, byte b, byte a) { byte[] source = ReferenceImplementations.MakeRgba32ByteArray(r, g, b, a); - var actual = new byte[source.Length]; + byte[] actual = new byte[source.Length]; PixelConverter.FromRgba32.ToBgra32(source, actual); @@ -65,7 +65,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats public void ToRgba32(byte r, byte g, byte b, byte a) { byte[] source = ReferenceImplementations.MakeArgb32ByteArray(r, g, b, a); - var actual = new byte[source.Length]; + byte[] actual = new byte[source.Length]; PixelConverter.FromArgb32.ToRgba32(source, actual); @@ -79,7 +79,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats public void ToBgra32(byte r, byte g, byte b, byte a) { byte[] source = ReferenceImplementations.MakeArgb32ByteArray(r, g, b, a); - var actual = new byte[source.Length]; + byte[] actual = new byte[source.Length]; PixelConverter.FromArgb32.ToBgra32(source, actual); @@ -96,7 +96,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats public void ToArgb32(byte r, byte g, byte b, byte a) { byte[] source = ReferenceImplementations.MakeBgra32ByteArray(r, g, b, a); - var actual = new byte[source.Length]; + byte[] actual = new byte[source.Length]; PixelConverter.FromBgra32.ToArgb32(source, actual); @@ -110,7 +110,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats public void ToRgba32(byte r, byte g, byte b, byte a) { byte[] source = ReferenceImplementations.MakeBgra32ByteArray(r, g, b, a); - var actual = new byte[source.Length]; + byte[] actual = new byte[source.Length]; PixelConverter.FromBgra32.ToRgba32(source, actual); diff --git a/tests/ImageSharp.Tests/PixelFormats/Rgb24Tests.cs b/tests/ImageSharp.Tests/PixelFormats/Rgb24Tests.cs index 4d4f8c9fb..6c98e623f 100644 --- a/tests/ImageSharp.Tests/PixelFormats/Rgb24Tests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/Rgb24Tests.cs @@ -11,7 +11,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats public class Rgb24Tests { public static readonly TheoryData ColorData = - new TheoryData + new() { { 1, 2, 3 }, { 4, 5, 6 }, @@ -76,7 +76,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats Assert.Equal(3, rgb.B); } - private static Vector4 Vec(byte r, byte g, byte b, byte a = 255) => new Vector4( + private static Vector4 Vec(byte r, byte g, byte b, byte a = 255) => new( r / 255f, g / 255f, b / 255f, diff --git a/tests/ImageSharp.Tests/PixelFormats/UnPackedPixelTests.cs b/tests/ImageSharp.Tests/PixelFormats/UnPackedPixelTests.cs index 9492fef90..20484b073 100644 --- a/tests/ImageSharp.Tests/PixelFormats/UnPackedPixelTests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/UnPackedPixelTests.cs @@ -5,7 +5,7 @@ using System.Numerics; using SixLabors.ImageSharp.PixelFormats; using Xunit; -namespace SixLabors.ImageSharp.Tests.Colors +namespace SixLabors.ImageSharp.Tests.PixelFormats { [Trait("Category", "PixelFormats")] public class UnPackedPixelTests diff --git a/tests/ImageSharp.Tests/Primitives/PointTests.cs b/tests/ImageSharp.Tests/Primitives/PointTests.cs index ffa025f56..46c2acbf1 100644 --- a/tests/ImageSharp.Tests/Primitives/PointTests.cs +++ b/tests/ImageSharp.Tests/Primitives/PointTests.cs @@ -255,4 +255,4 @@ namespace SixLabors.ImageSharp.Tests Assert.Equal(y, deconstructedY); } } -} \ No newline at end of file +} diff --git a/tests/ImageSharp.Tests/Primitives/RectangleFTests.cs b/tests/ImageSharp.Tests/Primitives/RectangleFTests.cs index 66791fd3c..39a0c367e 100644 --- a/tests/ImageSharp.Tests/Primitives/RectangleFTests.cs +++ b/tests/ImageSharp.Tests/Primitives/RectangleFTests.cs @@ -282,4 +282,4 @@ namespace SixLabors.ImageSharp.Tests Assert.Equal(height, dh); } } -} \ No newline at end of file +} diff --git a/tests/ImageSharp.Tests/Primitives/SizeFTests.cs b/tests/ImageSharp.Tests/Primitives/SizeFTests.cs index 1db4d3863..3d6ef729a 100644 --- a/tests/ImageSharp.Tests/Primitives/SizeFTests.cs +++ b/tests/ImageSharp.Tests/Primitives/SizeFTests.cs @@ -246,4 +246,4 @@ namespace SixLabors.ImageSharp.Tests Assert.Equal(height, deconstructedHeight); } } -} \ No newline at end of file +} diff --git a/tests/ImageSharp.Tests/Processing/Filters/ColorBlindnessTest.cs b/tests/ImageSharp.Tests/Processing/Filters/ColorBlindnessTest.cs index 237f132a4..24adaeda0 100644 --- a/tests/ImageSharp.Tests/Processing/Filters/ColorBlindnessTest.cs +++ b/tests/ImageSharp.Tests/Processing/Filters/ColorBlindnessTest.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. using System.Collections.Generic; - using SixLabors.ImageSharp.Processing; using SixLabors.ImageSharp.Processing.Processors; using SixLabors.ImageSharp.Processing.Processors.Filters; diff --git a/tests/ImageSharp.Tests/Processing/Filters/GrayscaleTest.cs b/tests/ImageSharp.Tests/Processing/Filters/GrayscaleTest.cs index 2e56331a7..c5e245771 100644 --- a/tests/ImageSharp.Tests/Processing/Filters/GrayscaleTest.cs +++ b/tests/ImageSharp.Tests/Processing/Filters/GrayscaleTest.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. using System.Collections.Generic; - using SixLabors.ImageSharp.Processing; using SixLabors.ImageSharp.Processing.Processors; using SixLabors.ImageSharp.Processing.Processors.Filters; diff --git a/tests/ImageSharp.Tests/Processing/ImageOperationTests.cs b/tests/ImageSharp.Tests/Processing/ImageOperationTests.cs index d85495b92..a99b6cee9 100644 --- a/tests/ImageSharp.Tests/Processing/ImageOperationTests.cs +++ b/tests/ImageSharp.Tests/Processing/ImageOperationTests.cs @@ -3,7 +3,6 @@ using System; using System.Linq; - using Moq; using SixLabors.ImageSharp.PixelFormats; diff --git a/tests/ImageSharp.Tests/Processing/Processors/Dithering/DitherTests.cs b/tests/ImageSharp.Tests/Processing/Processors/Dithering/DitherTests.cs index 37443a5b4..0465cae94 100644 --- a/tests/ImageSharp.Tests/Processing/Processors/Dithering/DitherTests.cs +++ b/tests/ImageSharp.Tests/Processing/Processors/Dithering/DitherTests.cs @@ -43,6 +43,13 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Dithering { KnownDitherings.Ordered3x3, nameof(KnownDitherings.Ordered3x3) } }; + public static readonly TheoryData DefaultInstanceDitherers + = new TheoryData + { + default(ErrorDither), + default(OrderedDither) + }; + private static readonly ImageComparer ValidatorComparer = ImageComparer.TolerantPercentage(0.05f); private static IDither DefaultDitherer => KnownDitherings.Bayer4x4; @@ -175,5 +182,18 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Dithering c => c.Dither(dither), name); } + + [Theory] + [MemberData(nameof(DefaultInstanceDitherers))] + public void ShouldThrowForDefaultDitherInstance(IDither dither) + { + void Command() + { + using var image = new Image(10, 10); + image.Mutate(x => x.Dither(dither)); + } + + Assert.Throws(Command); + } } } diff --git a/tests/ImageSharp.Tests/Processing/Processors/Effects/PixelShaderTest.cs b/tests/ImageSharp.Tests/Processing/Processors/Effects/PixelShaderTest.cs index 6edde73cd..7cef66588 100644 --- a/tests/ImageSharp.Tests/Processing/Processors/Effects/PixelShaderTest.cs +++ b/tests/ImageSharp.Tests/Processing/Processors/Effects/PixelShaderTest.cs @@ -3,7 +3,6 @@ using System; using System.Numerics; - using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.Processing; @@ -49,7 +48,8 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Effects float avg = (v4.X + v4.Y + v4.Z) / 3f; span[i] = new Vector4(avg); } - }, rect)); + }, + rect)); } [Theory] @@ -108,7 +108,8 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Effects span[i] = Vector4.Clamp(gray, Vector4.Zero, Vector4.One); } - }, rect)); + }, + rect)); } } } diff --git a/tests/ImageSharp.Tests/Processing/Processors/Quantization/QuantizerTests.cs b/tests/ImageSharp.Tests/Processing/Processors/Quantization/QuantizerTests.cs index af1d7f3f3..57cdfdb2c 100644 --- a/tests/ImageSharp.Tests/Processing/Processors/Quantization/QuantizerTests.cs +++ b/tests/ImageSharp.Tests/Processing/Processors/Quantization/QuantizerTests.cs @@ -2,9 +2,9 @@ // Licensed under the Apache License, Version 2.0. using System; - using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.Processing; +using SixLabors.ImageSharp.Processing.Processors.Dithering; using SixLabors.ImageSharp.Processing.Processors.Quantization; using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison; using Xunit; @@ -152,6 +152,13 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Quantization new WuQuantizer(OrderedDitherOptions), }; + public static readonly TheoryData DefaultInstanceDitherers + = new TheoryData + { + default(ErrorDither), + default(OrderedDither) + }; + private static readonly ImageComparer ValidatorComparer = ImageComparer.TolerantPercentage(0.05F); [Theory] @@ -217,5 +224,20 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Quantization testOutputDetails: testOutputDetails, appendPixelTypeToFileName: false); } + + [Theory] + [MemberData(nameof(DefaultInstanceDitherers))] + public void ShouldThrowForDefaultDitherInstance(IDither dither) + { + void Command() + { + using var image = new Image(10, 10); + var quantizer = new WebSafePaletteQuantizer(); + quantizer.Options.Dither = dither; + image.Mutate(x => x.Quantize(quantizer)); + } + + Assert.Throws(Command); + } } } diff --git a/tests/ImageSharp.Tests/Processing/Processors/Transforms/CropTest.cs b/tests/ImageSharp.Tests/Processing/Processors/Transforms/CropTest.cs index 52f3b65de..855a73e03 100644 --- a/tests/ImageSharp.Tests/Processing/Processors/Transforms/CropTest.cs +++ b/tests/ImageSharp.Tests/Processing/Processors/Transforms/CropTest.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. using System; - using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.Processing; using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison; diff --git a/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeKernelMapTests.ReferenceKernelMap.cs b/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeKernelMapTests.ReferenceKernelMap.cs index dfab25b11..9950a19bf 100644 --- a/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeKernelMapTests.ReferenceKernelMap.cs +++ b/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeKernelMapTests.ReferenceKernelMap.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.Linq; - using SixLabors.ImageSharp.Processing.Processors.Transforms; using Xunit; diff --git a/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeKernelMapTests.cs b/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeKernelMapTests.cs index 1d4629ccc..6a67c3cd8 100644 --- a/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeKernelMapTests.cs +++ b/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeKernelMapTests.cs @@ -4,7 +4,6 @@ using System; using System.Linq; using System.Text; - using SixLabors.ImageSharp.Processing; using SixLabors.ImageSharp.Processing.Processors.Transforms; @@ -212,15 +211,15 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms 1920, 3032, 2008, 3072, 2304, 3264, 2448 }; - IOrderedEnumerable<(int s, int d)> source2Dest = dimensionVals + IOrderedEnumerable<(int S, int D)> source2Dest = dimensionVals .SelectMany(s => dimensionVals.Select(d => (s, d))) .OrderBy(x => x.s + x.d); foreach (string resampler in resamplerNames) { - foreach ((int s, int d) x in source2Dest) + foreach ((int S, int D) x in source2Dest) { - result.Add(resampler, x.s, x.d); + result.Add(resampler, x.S, x.D); } } diff --git a/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeTests.cs b/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeTests.cs index 42cf1e3c1..3c0faf499 100644 --- a/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeTests.cs +++ b/tests/ImageSharp.Tests/Processing/Processors/Transforms/ResizeTests.cs @@ -19,9 +19,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms public class ResizeTests { private const PixelTypes CommonNonDefaultPixelTypes = - PixelTypes.Rgba32 | PixelTypes.Bgra32 | PixelTypes.RgbaVector; - - private const PixelTypes DefaultPixelType = PixelTypes.Rgba32; + PixelTypes.Rgba32 | PixelTypes.Bgra32 | PixelTypes.Bgr24 | PixelTypes.RgbaVector; public static readonly string[] AllResamplerNames = TestUtils.GetAllResamplerNames(); @@ -188,7 +186,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms } [Theory] - [WithTestPatternImages(100, 100, DefaultPixelType)] + [WithTestPatternImages(100, 100, PixelTypes.Rgba32)] public void Resize_Compand(TestImageProvider provider) where TPixel : unmanaged, IPixel { @@ -202,8 +200,8 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms } [Theory] - [WithFile(TestImages.Png.Kaboom, DefaultPixelType, false)] - [WithFile(TestImages.Png.Kaboom, DefaultPixelType, true)] + [WithFile(TestImages.Png.Kaboom, PixelTypes.Rgba32, false)] + [WithFile(TestImages.Png.Kaboom, PixelTypes.Rgba32, true)] public void Resize_DoesNotBleedAlphaPixels(TestImageProvider provider, bool compand) where TPixel : unmanaged, IPixel { @@ -217,8 +215,8 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms } [Theory] - [WithFile(TestImages.Png.Kaboom, DefaultPixelType, false)] - [WithFile(TestImages.Png.Kaboom, DefaultPixelType, true)] + [WithFile(TestImages.Png.Kaboom, PixelTypes.Rgba32, false)] + [WithFile(TestImages.Png.Kaboom, PixelTypes.Rgba32, true)] public void Resize_PremultiplyAlpha(TestImageProvider provider, bool premultiplyAlpha) where TPixel : unmanaged, IPixel { @@ -243,7 +241,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms } [Theory] - [WithFile(TestImages.Gif.Giphy, DefaultPixelType)] + [WithFile(TestImages.Gif.Giphy, PixelTypes.Rgba32)] public void Resize_IsAppliedToAllFrames(TestImageProvider provider) where TPixel : unmanaged, IPixel { @@ -265,7 +263,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms } [Theory] - [WithFileCollection(nameof(CommonTestImages), DefaultPixelType)] + [WithFileCollection(nameof(CommonTestImages), PixelTypes.Rgba32)] public void Resize_ThrowsForWrappedMemoryImage(TestImageProvider provider) where TPixel : unmanaged, IPixel { @@ -283,10 +281,10 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms } [Theory] - [WithFileCollection(nameof(CommonTestImages), DefaultPixelType, 1)] - [WithFileCollection(nameof(CommonTestImages), DefaultPixelType, 4)] - [WithFileCollection(nameof(CommonTestImages), DefaultPixelType, 8)] - [WithFileCollection(nameof(CommonTestImages), DefaultPixelType, -1)] + [WithFileCollection(nameof(CommonTestImages), PixelTypes.Rgba32 | PixelTypes.Rgb24, 1)] + [WithFileCollection(nameof(CommonTestImages), PixelTypes.Rgba32 | PixelTypes.Rgb24, 4)] + [WithFileCollection(nameof(CommonTestImages), PixelTypes.Rgba32 | PixelTypes.Rgb24, 8)] + [WithFileCollection(nameof(CommonTestImages), PixelTypes.Rgba32 | PixelTypes.Rgb24, -1)] public void Resize_WorksWithAllParallelismLevels( TestImageProvider provider, int maxDegreeOfParallelism) @@ -305,27 +303,27 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms } [Theory] - [WithFileCollection(nameof(CommonTestImages), nameof(AllResamplerNames), DefaultPixelType, 0.5f, null, null)] + [WithFileCollection(nameof(CommonTestImages), nameof(AllResamplerNames), PixelTypes.Rgba32 | PixelTypes.Rgb24, 0.5f, null, null)] [WithFileCollection( nameof(CommonTestImages), nameof(SmokeTestResamplerNames), - DefaultPixelType, + PixelTypes.Rgba32 | PixelTypes.Rgb24, 0.3f, null, null)] [WithFileCollection( nameof(CommonTestImages), nameof(SmokeTestResamplerNames), - DefaultPixelType, + PixelTypes.Rgba32 | PixelTypes.Rgb24, 1.8f, null, null)] - [WithTestPatternImages(nameof(SmokeTestResamplerNames), 100, 100, DefaultPixelType, 0.5f, null, null)] - [WithTestPatternImages(nameof(SmokeTestResamplerNames), 100, 100, DefaultPixelType, 1f, null, null)] - [WithTestPatternImages(nameof(SmokeTestResamplerNames), 50, 50, DefaultPixelType, 8f, null, null)] - [WithTestPatternImages(nameof(SmokeTestResamplerNames), 201, 199, DefaultPixelType, null, 100, 99)] - [WithTestPatternImages(nameof(SmokeTestResamplerNames), 301, 1180, DefaultPixelType, null, 300, 480)] - [WithTestPatternImages(nameof(SmokeTestResamplerNames), 49, 80, DefaultPixelType, null, 301, 100)] + [WithTestPatternImages(nameof(SmokeTestResamplerNames), 100, 100, PixelTypes.Rgba32, 0.5f, null, null)] + [WithTestPatternImages(nameof(SmokeTestResamplerNames), 100, 100, PixelTypes.Rgba32, 1f, null, null)] + [WithTestPatternImages(nameof(SmokeTestResamplerNames), 50, 50, PixelTypes.Rgba32, 8f, null, null)] + [WithTestPatternImages(nameof(SmokeTestResamplerNames), 201, 199, PixelTypes.Rgba32, null, 100, 99)] + [WithTestPatternImages(nameof(SmokeTestResamplerNames), 301, 1180, PixelTypes.Rgba32, null, 300, 480)] + [WithTestPatternImages(nameof(SmokeTestResamplerNames), 49, 80, PixelTypes.Rgba32, null, 301, 100)] public void Resize_WorksWithAllResamplers( TestImageProvider provider, string samplerName, @@ -382,7 +380,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms } [Theory] - [WithFileCollection(nameof(CommonTestImages), DefaultPixelType)] + [WithFileCollection(nameof(CommonTestImages), PixelTypes.Rgba32 | PixelTypes.Rgb24)] public void ResizeFromSourceRectangle(TestImageProvider provider) where TPixel : unmanaged, IPixel { @@ -405,12 +403,12 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms false)); image.DebugSave(provider); - image.CompareToReferenceOutput(ValidatorComparer, provider); + image.CompareToReferenceOutput(ValidatorComparer, provider, appendPixelTypeToFileName: false); } } [Theory] - [WithFileCollection(nameof(CommonTestImages), DefaultPixelType)] + [WithFileCollection(nameof(CommonTestImages), PixelTypes.Rgba32 | PixelTypes.Rgb24)] public void ResizeHeightAndKeepAspect(TestImageProvider provider) where TPixel : unmanaged, IPixel { @@ -419,12 +417,12 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms image.Mutate(x => x.Resize(0, image.Height / 3, false)); image.DebugSave(provider); - image.CompareToReferenceOutput(ValidatorComparer, provider); + image.CompareToReferenceOutput(ValidatorComparer, provider, appendPixelTypeToFileName: false); } } [Theory] - [WithTestPatternImages(10, 100, DefaultPixelType)] + [WithTestPatternImages(10, 100, PixelTypes.Rgba32 | PixelTypes.Rgb24)] public void ResizeHeightCannotKeepAspectKeepsOnePixel(TestImageProvider provider) where TPixel : unmanaged, IPixel { @@ -437,7 +435,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms } [Theory] - [WithFileCollection(nameof(CommonTestImages), DefaultPixelType)] + [WithFileCollection(nameof(CommonTestImages), PixelTypes.Rgba32 | PixelTypes.Rgb24)] public void ResizeWidthAndKeepAspect(TestImageProvider provider) where TPixel : unmanaged, IPixel { @@ -446,12 +444,12 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms image.Mutate(x => x.Resize(image.Width / 3, 0, false)); image.DebugSave(provider); - image.CompareToReferenceOutput(ValidatorComparer, provider); + image.CompareToReferenceOutput(ValidatorComparer, provider, appendPixelTypeToFileName: false); } } [Theory] - [WithTestPatternImages(100, 10, DefaultPixelType)] + [WithTestPatternImages(100, 10, PixelTypes.Rgba32 | PixelTypes.Rgb24)] public void ResizeWidthCannotKeepAspectKeepsOnePixel(TestImageProvider provider) where TPixel : unmanaged, IPixel { @@ -464,7 +462,7 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms } [Theory] - [WithFileCollection(nameof(CommonTestImages), DefaultPixelType)] + [WithFileCollection(nameof(CommonTestImages), PixelTypes.Rgba32 | PixelTypes.Rgb24)] public void ResizeWithBoxPadMode(TestImageProvider provider) where TPixel : unmanaged, IPixel { @@ -479,12 +477,12 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms image.Mutate(x => x.Resize(options)); image.DebugSave(provider); - image.CompareToReferenceOutput(ValidatorComparer, provider); + image.CompareToReferenceOutput(ValidatorComparer, provider, appendPixelTypeToFileName: false); } } [Theory] - [WithFileCollection(nameof(CommonTestImages), DefaultPixelType)] + [WithFileCollection(nameof(CommonTestImages), PixelTypes.Rgba32 | PixelTypes.Rgb24)] public void ResizeWithCropHeightMode(TestImageProvider provider) where TPixel : unmanaged, IPixel { @@ -495,12 +493,12 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms image.Mutate(x => x.Resize(options)); image.DebugSave(provider); - image.CompareToReferenceOutput(ValidatorComparer, provider); + image.CompareToReferenceOutput(ValidatorComparer, provider, appendPixelTypeToFileName: false); } } [Theory] - [WithFileCollection(nameof(CommonTestImages), DefaultPixelType)] + [WithFileCollection(nameof(CommonTestImages), PixelTypes.Rgba32 | PixelTypes.Rgb24)] public void ResizeWithCropWidthMode(TestImageProvider provider) where TPixel : unmanaged, IPixel { @@ -511,12 +509,12 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms image.Mutate(x => x.Resize(options)); image.DebugSave(provider); - image.CompareToReferenceOutput(ValidatorComparer, provider); + image.CompareToReferenceOutput(ValidatorComparer, provider, appendPixelTypeToFileName: false); } } [Theory] - [WithFile(TestImages.Jpeg.Issues.IncorrectResize1006, DefaultPixelType)] + [WithFile(TestImages.Jpeg.Issues.IncorrectResize1006, PixelTypes.Rgba32 | PixelTypes.Rgb24)] public void CanResizeLargeImageWithCropMode(TestImageProvider provider) where TPixel : unmanaged, IPixel { @@ -531,12 +529,12 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms image.Mutate(x => x.Resize(options)); image.DebugSave(provider); - image.CompareToReferenceOutput(ValidatorComparer, provider); + image.CompareToReferenceOutput(ValidatorComparer, provider, appendPixelTypeToFileName: false); } } [Theory] - [WithFileCollection(nameof(CommonTestImages), DefaultPixelType)] + [WithFileCollection(nameof(CommonTestImages), PixelTypes.Rgba32 | PixelTypes.Rgb24)] public void ResizeWithMaxMode(TestImageProvider provider) where TPixel : unmanaged, IPixel { @@ -547,12 +545,12 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms image.Mutate(x => x.Resize(options)); image.DebugSave(provider); - image.CompareToReferenceOutput(ValidatorComparer, provider); + image.CompareToReferenceOutput(ValidatorComparer, provider, appendPixelTypeToFileName: false); } } [Theory] - [WithFileCollection(nameof(CommonTestImages), DefaultPixelType)] + [WithFileCollection(nameof(CommonTestImages), PixelTypes.Rgba32 | PixelTypes.Rgb24)] public void ResizeWithMinMode(TestImageProvider provider) where TPixel : unmanaged, IPixel { @@ -560,21 +558,19 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms { var options = new ResizeOptions { - Size = new Size( - (int)Math.Round(image.Width * .75F), - (int)Math.Round(image.Height * .95F)), + Size = new Size((int)Math.Round(image.Width * .75F), (int)Math.Round(image.Height * .95F)), Mode = ResizeMode.Min }; image.Mutate(x => x.Resize(options)); image.DebugSave(provider); - image.CompareToReferenceOutput(ValidatorComparer, provider); + image.CompareToReferenceOutput(ValidatorComparer, provider, appendPixelTypeToFileName: false); } } [Theory] - [WithFileCollection(nameof(CommonTestImages), DefaultPixelType)] + [WithFileCollection(nameof(CommonTestImages), PixelTypes.Rgba32 | PixelTypes.Rgb24)] public void ResizeWithPadMode(TestImageProvider provider) where TPixel : unmanaged, IPixel { @@ -589,12 +585,12 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms image.Mutate(x => x.Resize(options)); image.DebugSave(provider); - image.CompareToReferenceOutput(ValidatorComparer, provider); + image.CompareToReferenceOutput(ValidatorComparer, provider, appendPixelTypeToFileName: false); } } [Theory] - [WithFileCollection(nameof(CommonTestImages), DefaultPixelType)] + [WithFileCollection(nameof(CommonTestImages), PixelTypes.Rgba32 | PixelTypes.Rgb24)] public void ResizeWithStretchMode(TestImageProvider provider) where TPixel : unmanaged, IPixel { @@ -609,14 +605,14 @@ namespace SixLabors.ImageSharp.Tests.Processing.Processors.Transforms image.Mutate(x => x.Resize(options)); image.DebugSave(provider); - image.CompareToReferenceOutput(ValidatorComparer, provider); + image.CompareToReferenceOutput(ValidatorComparer, provider, appendPixelTypeToFileName: false); } } [Theory] - [WithFile(TestImages.Jpeg.Issues.ExifDecodeOutOfRange694, DefaultPixelType)] - [WithFile(TestImages.Jpeg.Issues.ExifGetString750Transform, DefaultPixelType)] - [WithFile(TestImages.Jpeg.Issues.ExifResize1049, DefaultPixelType)] + [WithFile(TestImages.Jpeg.Issues.ExifDecodeOutOfRange694, PixelTypes.Rgb24)] + [WithFile(TestImages.Jpeg.Issues.ExifGetString750Transform, PixelTypes.Rgb24)] + [WithFile(TestImages.Jpeg.Issues.ExifResize1049, PixelTypes.Rgb24)] public void CanResizeExifIssueImages(TestImageProvider provider) where TPixel : unmanaged, IPixel { diff --git a/tests/ImageSharp.Tests/Processing/Transforms/CropTest.cs b/tests/ImageSharp.Tests/Processing/Transforms/CropTest.cs index ed56f681c..0eee30438 100644 --- a/tests/ImageSharp.Tests/Processing/Transforms/CropTest.cs +++ b/tests/ImageSharp.Tests/Processing/Transforms/CropTest.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. using System; - using SixLabors.ImageSharp.Processing; using SixLabors.ImageSharp.Processing.Processors.Transforms; using Xunit; diff --git a/tests/ImageSharp.Tests/ProfilingBenchmarks/JpegProfilingBenchmarks.cs b/tests/ImageSharp.Tests/ProfilingBenchmarks/JpegProfilingBenchmarks.cs index 9de3fc8df..5eb4aa76d 100644 --- a/tests/ImageSharp.Tests/ProfilingBenchmarks/JpegProfilingBenchmarks.cs +++ b/tests/ImageSharp.Tests/ProfilingBenchmarks/JpegProfilingBenchmarks.cs @@ -5,7 +5,6 @@ using System; using System.IO; using System.Linq; using System.Numerics; - using SixLabors.ImageSharp.Formats; using SixLabors.ImageSharp.Formats.Jpeg; using SixLabors.ImageSharp.PixelFormats; @@ -70,7 +69,7 @@ namespace SixLabors.ImageSharp.Tests.ProfilingBenchmarks img.Dispose(); }, #pragma warning disable SA1515 // Single-line comment should be preceded by blank line - // ReSharper disable once ExplicitCallerInfoArgument + // ReSharper disable once ExplicitCallerInfoArgument $"Decode {fileName}"); #pragma warning restore SA1515 // Single-line comment should be preceded by blank line } @@ -92,11 +91,11 @@ namespace SixLabors.ImageSharp.Tests.ProfilingBenchmarks // Benchmark, enable manually! [Theory(Skip = ProfilingSetup.SkipProfilingTests)] - [InlineData(1, 75, JpegSubsample.Ratio420)] - [InlineData(30, 75, JpegSubsample.Ratio420)] - [InlineData(30, 75, JpegSubsample.Ratio444)] - [InlineData(30, 100, JpegSubsample.Ratio444)] - public void EncodeJpeg(int executionCount, int quality, JpegSubsample subsample) + [InlineData(1, 75, JpegColorType.YCbCrRatio420)] + [InlineData(30, 75, JpegColorType.YCbCrRatio420)] + [InlineData(30, 75, JpegColorType.YCbCrRatio444)] + [InlineData(30, 100, JpegColorType.YCbCrRatio444)] + public void EncodeJpeg(int executionCount, int quality, JpegColorType colorType) { // do not run this on CI even by accident if (TestEnvironment.RunsOnCI) @@ -118,7 +117,7 @@ namespace SixLabors.ImageSharp.Tests.ProfilingBenchmarks { foreach (Image img in testImages) { - var options = new JpegEncoder { Quality = quality, Subsample = subsample }; + var options = new JpegEncoder { Quality = quality, ColorType = colorType }; img.Save(ms, options); ms.Seek(0, SeekOrigin.Begin); } diff --git a/tests/ImageSharp.Tests/ProfilingBenchmarks/LoadResizeSaveProfilingBenchmarks.cs b/tests/ImageSharp.Tests/ProfilingBenchmarks/LoadResizeSaveProfilingBenchmarks.cs index 2d67b0ebd..be2523cbb 100644 --- a/tests/ImageSharp.Tests/ProfilingBenchmarks/LoadResizeSaveProfilingBenchmarks.cs +++ b/tests/ImageSharp.Tests/ProfilingBenchmarks/LoadResizeSaveProfilingBenchmarks.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. using System.IO; - using SixLabors.ImageSharp.Processing; using Xunit; diff --git a/tests/ImageSharp.Tests/Quantization/QuantizedImageTests.cs b/tests/ImageSharp.Tests/Quantization/QuantizedImageTests.cs index 6eb0f51a3..c9e5d3aa7 100644 --- a/tests/ImageSharp.Tests/Quantization/QuantizedImageTests.cs +++ b/tests/ImageSharp.Tests/Quantization/QuantizedImageTests.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. using System; - using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.Processing.Processors.Quantization; diff --git a/tests/ImageSharp.Tests/TestFile.cs b/tests/ImageSharp.Tests/TestFile.cs index 338ccffbe..9ca95a689 100644 --- a/tests/ImageSharp.Tests/TestFile.cs +++ b/tests/ImageSharp.Tests/TestFile.cs @@ -4,7 +4,6 @@ using System; using System.Collections.Concurrent; using System.IO; - using SixLabors.ImageSharp.Advanced; using SixLabors.ImageSharp.Formats; using SixLabors.ImageSharp.PixelFormats; diff --git a/tests/ImageSharp.Tests/TestImages.cs b/tests/ImageSharp.Tests/TestImages.cs index 6d2f65f57..116c5adc3 100644 --- a/tests/ImageSharp.Tests/TestImages.cs +++ b/tests/ImageSharp.Tests/TestImages.cs @@ -44,6 +44,7 @@ namespace SixLabors.ImageSharp.Tests public const string CalliphoraPartial = "Png/CalliphoraPartial.png"; public const string CalliphoraPartialGrayscale = "Png/CalliphoraPartialGrayscale.png"; public const string Bike = "Png/Bike.png"; + public const string BikeSmall = "Png/bike-small.png"; public const string BikeGrayscale = "Png/BikeGrayscale.png"; public const string SnakeGame = "Png/SnakeGame.png"; public const string Icon = "Png/icon.png"; @@ -58,6 +59,8 @@ namespace SixLabors.ImageSharp.Tests public const string PngWithMetadata = "Png/PngWithMetaData.png"; public const string InvalidTextData = "Png/InvalidTextData.png"; public const string David = "Png/david.png"; + public const string TestPattern31x31 = "Png/testpattern31x31.png"; + public const string TestPattern31x31HalfTransparent = "Png/testpattern31x31-halftransparent.png"; // Filtered test images from http://www.schaik.com/pngsuite/pngsuite_fil_png.html public const string Filter0 = "Png/filter0.png"; @@ -111,6 +114,9 @@ namespace SixLabors.ImageSharp.Tests // Issue 935: https://github.com/SixLabors/ImageSharp/issues/935 public const string Issue935 = "Png/issues/Issue_935.png"; + // Issue 1765: https://github.com/SixLabors/ImageSharp/issues/1765 + public const string Issue1765_Net6DeflateStreamRead = "Png/issues/Issue_1765_Net6DeflateStreamRead.png"; + public static class Bad { public const string MissingDataChunk = "Png/xdtn0g01.png"; @@ -157,6 +163,7 @@ namespace SixLabors.ImageSharp.Tests public const string Fb = "Jpg/progressive/fb.jpg"; public const string Progress = "Jpg/progressive/progress.jpg"; public const string Festzug = "Jpg/progressive/Festzug.jpg"; + public const string Winter = "Jpg/progressive/winter.jpg"; public static class Bad { @@ -189,6 +196,10 @@ namespace SixLabors.ImageSharp.Tests public const string Jpeg420Exif = "Jpg/baseline/jpeg420exif.jpg"; public const string Jpeg444 = "Jpg/baseline/jpeg444.jpg"; public const string Jpeg420Small = "Jpg/baseline/jpeg420small.jpg"; + public const string JpegRgb = "Jpg/baseline/jpeg-rgb.jpg"; + public const string Jpeg410 = "Jpg/baseline/jpeg410.jpg"; + public const string Jpeg411 = "Jpg/baseline/jpeg411.jpg"; + public const string Jpeg422 = "Jpg/baseline/jpeg422.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"; @@ -198,6 +209,10 @@ namespace SixLabors.ImageSharp.Tests public const string Iptc = "Jpg/baseline/iptc.jpg"; public const string App13WithEmptyIptc = "Jpg/baseline/iptc-psAPP13-wIPTCempty.jpg"; public const string HistogramEqImage = "Jpg/baseline/640px-Unequalized_Hawkes_Bay_NZ.jpg"; + public const string ForestBridgeDifferentComponentsQuality = "Jpg/baseline/forest_bridge.jpg"; + public const string ArithmeticCoding = "Jpg/baseline/arithmetic_coding.jpg"; + public const string ArithmeticCodingProgressive = "Jpg/progressive/arithmetic_progressive.jpg"; + public const string Lossless = "Jpg/baseline/lossless.jpg"; public static readonly string[] All = { @@ -235,6 +250,7 @@ namespace SixLabors.ImageSharp.Tests public const string ExifResize1049 = "Jpg/issues/issue1049-exif-resize.jpg"; public const string BadSubSampling1076 = "Jpg/issues/issue-1076-invalid-subsampling.jpg"; public const string IdentifyMultiFrame1211 = "Jpg/issues/issue-1221-identify-multi-frame.jpg"; + public const string WrongColorSpace = "Jpg/issues/Issue1732-WrongColorSpace.jpg"; public static class Fuzz { @@ -261,6 +277,8 @@ namespace SixLabors.ImageSharp.Tests public const string AccessViolationException827 = "Jpg/issues/fuzz/Issue827-AccessViolationException.jpg"; public const string ExecutionEngineException839 = "Jpg/issues/fuzz/Issue839-ExecutionEngineException.jpg"; public const string AccessViolationException922 = "Jpg/issues/fuzz/Issue922-AccessViolationException.jpg"; + public const string IndexOutOfRangeException1693A = "Jpg/issues/fuzz/Issue1693-IndexOutOfRangeException-A.jpg"; + public const string IndexOutOfRangeException1693B = "Jpg/issues/fuzz/Issue1693-IndexOutOfRangeException-B.jpg"; } } @@ -499,6 +517,193 @@ namespace SixLabors.ImageSharp.Tests public const string NoAlphaBits32BitRle = "Tga/32bit_rle_no_alphabits.tga"; } + public static class Webp + { + // Reference image as png + public const string Peak = "Webp/peak.png"; + + // Test pattern images for testing the encoder. + public const string TestPatternOpaque = "Webp/testpattern_opaque.png"; + public const string TestPatternOpaqueSmall = "Webp/testpattern_opaque_small.png"; + public const string RgbTestPattern100x100 = "Webp/rgb_pattern_100x100.png"; + public const string RgbTestPattern80x80 = "Webp/rgb_pattern_80x80.png"; + public const string RgbTestPattern63x63 = "Webp/rgb_pattern_63x63.png"; + + // Test image for encoding image with a palette. + public const string Flag = "Webp/flag_of_germany.png"; + + // Test images for converting rgb data to yuv. + public const string Yuv = "Webp/yuv_test.png"; + + public static class Animated + { + public const string Animated1 = "Webp/animated-webp.webp"; + public const string Animated2 = "Webp/animated2.webp"; + public const string Animated3 = "Webp/animated3.webp"; + public const string Animated4 = "Webp/animated_lossy.webp"; + } + + public static class Lossless + { + public const string Earth = "Webp/earth_lossless.webp"; + public const string Alpha = "Webp/lossless_alpha_small.webp"; + public const string WithExif = "Webp/exif_lossless.webp"; + public const string WithIccp = "Webp/lossless_with_iccp.webp"; + public const string NoTransform1 = "Webp/lossless_vec_1_0.webp"; + public const string NoTransform2 = "Webp/lossless_vec_2_0.webp"; + public const string GreenTransform1 = "Webp/lossless1.webp"; + public const string GreenTransform2 = "Webp/lossless2.webp"; + public const string GreenTransform3 = "Webp/lossless3.webp"; + public const string GreenTransform4 = "Webp/lossless_vec_1_4.webp"; + public const string GreenTransform5 = "Webp/lossless_vec_2_4.webp"; + public const string CrossColorTransform1 = "Webp/lossless_vec_1_8.webp"; + public const string CrossColorTransform2 = "Webp/lossless_vec_2_8.webp"; + public const string PredictorTransform1 = "Webp/lossless_vec_1_2.webp"; + public const string PredictorTransform2 = "Webp/lossless_vec_2_2.webp"; + public const string ColorIndexTransform1 = "Webp/lossless4.webp"; + public const string ColorIndexTransform2 = "Webp/lossless_vec_1_1.webp"; + public const string ColorIndexTransform3 = "Webp/lossless_vec_1_5.webp"; + public const string ColorIndexTransform4 = "Webp/lossless_vec_2_1.webp"; + public const string ColorIndexTransform5 = "Webp/lossless_vec_2_5.webp"; + public const string TwoTransforms1 = "Webp/lossless_vec_1_10.webp"; // cross_color, predictor + public const string TwoTransforms2 = "Webp/lossless_vec_1_12.webp"; // cross_color, substract_green + public const string TwoTransforms3 = "Webp/lossless_vec_1_13.webp"; // color_indexing, cross_color + public const string TwoTransforms4 = "Webp/lossless_vec_1_3.webp"; // color_indexing, predictor + public const string TwoTransforms5 = "Webp/lossless_vec_1_6.webp"; // substract_green, predictor + public const string TwoTransforms6 = "Webp/lossless_vec_1_7.webp"; // color_indexing, predictor + public const string TwoTransforms7 = "Webp/lossless_vec_1_9.webp"; // color_indexing, cross_color + public const string TwoTransforms8 = "Webp/lossless_vec_2_10.webp"; // predictor, cross_color + public const string TwoTransforms9 = "Webp/lossless_vec_2_12.webp"; // substract_green, cross_color + public const string TwoTransforms10 = "Webp/lossless_vec_2_13.webp"; // color_indexing, cross_color + public const string TwoTransforms11 = "Webp/lossless_vec_2_3.webp"; // color_indexing, predictor + public const string TwoTransforms12 = "Webp/lossless_vec_2_6.webp"; // substract_green, predictor + public const string TwoTransforms13 = "Webp/lossless_vec_2_9.webp"; // color_indexing, predictor + + // substract_green, predictor, cross_color + public const string ThreeTransforms1 = "Webp/color_cache_bits_11.webp"; + + // color_indexing, predictor, cross_color + public const string ThreeTransforms2 = "Webp/lossless_vec_1_11.webp"; + + // substract_green, predictor, cross_color + public const string ThreeTransforms3 = "Webp/lossless_vec_1_14.webp"; + + // color_indexing, predictor, cross_color + public const string ThreeTransforms4 = "Webp/lossless_vec_1_15.webp"; + + // color_indexing, predictor, cross_color + public const string ThreeTransforms5 = "Webp/lossless_vec_2_11.webp"; + + // substract_green, predictor, cross_color + public const string ThreeTransforms6 = "Webp/lossless_vec_2_14.webp"; + + // color_indexing, predictor, cross_color + public const string ThreeTransforms7 = "Webp/lossless_vec_2_15.webp"; + + // substract_green, predictor, cross_color + public const string BikeThreeTransforms = "Webp/bike_lossless.webp"; + + // Invalid / corrupted images + // Below images have errors according to webpinfo. The error message webpinfo gives is "Truncated data detected when parsing RIFF payload." + public const string LossLessCorruptImage1 = "Webp/lossless_big_random_alpha.webp"; // substract_green, predictor, cross_color. + + public const string LossLessCorruptImage2 = "Webp/lossless_vec_2_7.webp"; // color_indexing, predictor. + + public const string LossLessCorruptImage3 = "Webp/lossless_color_transform.webp"; // cross_color, predictor + + public const string LossLessCorruptImage4 = "Webp/near_lossless_75.webp"; // predictor, cross_color. + } + + public static class Lossy + { + public const string Earth = "Webp/earth_lossy.webp"; + public const string WithExif = "Webp/exif_lossy.webp"; + public const string WithIccp = "Webp/lossy_with_iccp.webp"; + public const string BikeSmall = "Webp/bike_lossless_small.webp"; + + // Lossy images without macroblock filtering. + public const string Bike = "Webp/bike_lossy.webp"; + public const string NoFilter01 = "Webp/vp80-01-intra-1400.webp"; + public const string NoFilter02 = "Webp/vp80-00-comprehensive-010.webp"; + public const string NoFilter03 = "Webp/vp80-00-comprehensive-005.webp"; + public const string NoFilter04 = "Webp/vp80-01-intra-1417.webp"; + public const string NoFilter05 = "Webp/vp80-02-inter-1402.webp"; + public const string NoFilter06 = "Webp/test.webp"; + + // Lossy images with a simple filter. + public const string SimpleFilter01 = "Webp/segment01.webp"; + public const string SimpleFilter02 = "Webp/segment02.webp"; + public const string SimpleFilter03 = "Webp/vp80-00-comprehensive-003.webp"; + public const string SimpleFilter04 = "Webp/vp80-00-comprehensive-007.webp"; + public const string SimpleFilter05 = "Webp/test-nostrong.webp"; + + // Lossy images with a complex filter. + public const string IccpComplexFilter = WithIccp; + public const string VeryShort = "Webp/very_short.webp"; + public const string BikeComplexFilter = "Webp/bike_lossy_complex_filter.webp"; + public const string ComplexFilter01 = "Webp/vp80-02-inter-1418.webp"; + public const string ComplexFilter02 = "Webp/vp80-02-inter-1418.webp"; + public const string ComplexFilter03 = "Webp/vp80-00-comprehensive-002.webp"; + public const string ComplexFilter04 = "Webp/vp80-00-comprehensive-006.webp"; + public const string ComplexFilter05 = "Webp/vp80-00-comprehensive-009.webp"; + public const string ComplexFilter06 = "Webp/vp80-00-comprehensive-012.webp"; + public const string ComplexFilter07 = "Webp/vp80-00-comprehensive-015.webp"; + public const string ComplexFilter08 = "Webp/vp80-00-comprehensive-016.webp"; + public const string ComplexFilter09 = "Webp/vp80-00-comprehensive-017.webp"; + + // Lossy with partitions. + public const string Partitions01 = "Webp/vp80-04-partitions-1404.webp"; + public const string Partitions02 = "Webp/vp80-04-partitions-1405.webp"; + public const string Partitions03 = "Webp/vp80-04-partitions-1406.webp"; + + // Lossy with segmentation. + public const string SegmentationNoFilter01 = "Webp/vp80-03-segmentation-1401.webp"; + public const string SegmentationNoFilter02 = "Webp/vp80-03-segmentation-1403.webp"; + public const string SegmentationNoFilter03 = "Webp/vp80-03-segmentation-1407.webp"; + public const string SegmentationNoFilter04 = "Webp/vp80-03-segmentation-1408.webp"; + public const string SegmentationNoFilter05 = "Webp/vp80-03-segmentation-1409.webp"; + public const string SegmentationNoFilter06 = "Webp/vp80-03-segmentation-1410.webp"; + public const string SegmentationComplexFilter01 = "Webp/vp80-03-segmentation-1413.webp"; + public const string SegmentationComplexFilter02 = "Webp/vp80-03-segmentation-1425.webp"; + public const string SegmentationComplexFilter03 = "Webp/vp80-03-segmentation-1426.webp"; + public const string SegmentationComplexFilter04 = "Webp/vp80-03-segmentation-1427.webp"; + public const string SegmentationComplexFilter05 = "Webp/vp80-03-segmentation-1432.webp"; + + // Lossy with sharpness level. + public const string Sharpness01 = "Webp/vp80-05-sharpness-1428.webp"; + public const string Sharpness02 = "Webp/vp80-05-sharpness-1429.webp"; + public const string Sharpness03 = "Webp/vp80-05-sharpness-1430.webp"; + public const string Sharpness04 = "Webp/vp80-05-sharpness-1431.webp"; + public const string Sharpness05 = "Webp/vp80-05-sharpness-1433.webp"; + public const string Sharpness06 = "Webp/vp80-05-sharpness-1434.webp"; + + // Very small images (all with complex filter). + public const string Small01 = "Webp/small_13x1.webp"; + public const string Small02 = "Webp/small_1x1.webp"; + public const string Small03 = "Webp/small_1x13.webp"; + public const string Small04 = "Webp/small_31x13.webp"; + + // Lossy images with a alpha channel. + public const string Alpha1 = "Webp/lossy_alpha1.webp"; + public const string Alpha2 = "Webp/lossy_alpha2.webp"; + public const string Alpha3 = "Webp/alpha_color_cache.webp"; + public const string AlphaNoCompression = "Webp/alpha_no_compression.webp"; + public const string AlphaNoCompressionNoFilter = "Webp/alpha_filter_0_method_0.webp"; + public const string AlphaCompressedNoFilter = "Webp/alpha_filter_0_method_1.webp"; + public const string AlphaNoCompressionHorizontalFilter = "Webp/alpha_filter_1_method_0.webp"; + public const string AlphaCompressedHorizontalFilter = "Webp/alpha_filter_1_method_1.webp"; + public const string AlphaNoCompressionVerticalFilter = "Webp/alpha_filter_2_method_0.webp"; + public const string AlphaCompressedVerticalFilter = "Webp/alpha_filter_2_method_1.webp"; + public const string AlphaNoCompressionGradientFilter = "Webp/alpha_filter_3_method_0.webp"; + public const string AlphaCompressedGradientFilter = "Webp/alpha_filter_3_method_1.webp"; + public const string AlphaThinkingSmiley = "Webp/1602311202.webp"; + public const string AlphaSticker = "Webp/sticker.webp"; + + // Issues + public const string Issue1594 = "Webp/issues/Issue1594.webp"; + } + } + public static class Tiff { public const string Benchmark_Path = "Tiff/Benchmarks/"; @@ -530,11 +735,15 @@ namespace SixLabors.ImageSharp.Tests public const string Calliphora_Fax4Compressed = "Tiff/Calliphora_ccitt_fax4.tiff"; public const string Calliphora_HuffmanCompressed = "Tiff/Calliphora_huffman_rle.tiff"; public const string Calliphora_BiColorUncompressed = "Tiff/Calliphora_bicolor_uncompressed.tiff"; + public const string Fax4Compressed = "Tiff/basi3p02_fax4.tiff"; + public const string Fax4CompressedLowerOrderBitsFirst = "Tiff/basi3p02_fax4_lowerOrderBitsFirst.tiff"; public const string CcittFax3AllTermCodes = "Tiff/ccitt_fax3_all_terminating_codes.tiff"; public const string CcittFax3AllMakeupCodes = "Tiff/ccitt_fax3_all_makeup_codes.tiff"; public const string HuffmanRleAllTermCodes = "Tiff/huffman_rle_all_terminating_codes.tiff"; public const string HuffmanRleAllMakeupCodes = "Tiff/huffman_rle_all_makeup_codes.tiff"; + public const string CcittFax3LowerOrderBitsFirst = "Tiff/basi3p02_fax3_lowerOrderBitsFirst.tiff"; + public const string HuffmanRleLowerOrderBitsFirst = "Tiff/basi3p02_huffman_rle_lowerOrderBitsFirst.tiff"; // Test case for an issue, that the last bits in a row got ignored. public const string HuffmanRle_basi3p02 = "Tiff/basi3p02_huffman_rle.tiff"; @@ -546,7 +755,9 @@ namespace SixLabors.ImageSharp.Tests public const string RgbDeflate = "Tiff/rgb_deflate.tiff"; public const string RgbDeflatePredictor = "Tiff/rgb_deflate_predictor.tiff"; public const string RgbDeflateMultistrip = "Tiff/rgb_deflate_multistrip.tiff"; - public const string RgbJpeg = "Tiff/rgb_jpeg.tiff"; + public const string RgbJpegCompressed = "Tiff/rgb_jpegcompression.tiff"; + public const string RgbWithStripsJpegCompressed = "Tiff/rgb_jpegcompressed_stripped.tiff"; + public const string RgbJpegCompressedNoJpegTable = "Tiff/rgb_jpegcompressed_nojpegtable.tiff"; public const string RgbLzwPredictor = "Tiff/rgb_lzw_predictor.tiff"; public const string RgbLzwNoPredictor = "Tiff/rgb_lzw_no_predictor.tiff"; public const string RgbLzwNoPredictorMultistrip = "Tiff/rgb_lzw_noPredictor_multistrip.tiff"; @@ -559,13 +770,42 @@ namespace SixLabors.ImageSharp.Tests public const string RgbPalette = "Tiff/rgb_palette.tiff"; public const string Rgb4BitPalette = "Tiff/bike_colorpalette_4bit.tiff"; public const string RgbPaletteDeflate = "Tiff/rgb_palette_deflate.tiff"; + public const string FlowerRgbFloat323232 = "Tiff/flower-rgb-float32_msb.tiff"; + public const string FlowerRgbFloat323232LittleEndian = "Tiff/flower-rgb-float32_lsb.tiff"; + public const string FlowerRgb323232Contiguous = "Tiff/flower-rgb-contig-32.tiff"; + public const string FlowerRgb323232ContiguousLittleEndian = "Tiff/flower-rgb-contig-32_lsb.tiff"; + public const string FlowerRgb323232Planar = "Tiff/flower-rgb-planar-32.tiff"; + public const string FlowerRgb323232PlanarLittleEndian = "Tiff/flower-rgb-planar-32_lsb.tiff"; + public const string FlowerRgb323232PredictorBigEndian = "Tiff/flower-rgb-contig-32_msb_zip_predictor.tiff"; + public const string FlowerRgb323232PredictorLittleEndian = "Tiff/flower-rgb-contig-32_lsb_zip_predictor.tiff"; + public const string FlowerRgb242424Planar = "Tiff/flower-rgb-planar-24.tiff"; + public const string FlowerRgb242424PlanarLittleEndian = "Tiff/flower-rgb-planar-24_lsb.tiff"; + public const string FlowerRgb242424Contiguous = "Tiff/flower-rgb-contig-24.tiff"; + public const string FlowerRgb242424ContiguousLittleEndian = "Tiff/flower-rgb-contig-24_lsb.tiff"; public const string FlowerRgb161616Contiguous = "Tiff/flower-rgb-contig-16.tiff"; + public const string FlowerRgb161616ContiguousLittleEndian = "Tiff/flower-rgb-contig-16_lsb.tiff"; + public const string FlowerRgb161616PredictorBigEndian = "Tiff/flower-rgb-contig-16_msb_zip_predictor.tiff"; + public const string FlowerRgb161616PredictorLittleEndian = "Tiff/flower-rgb-contig-16_lsb_zip_predictor.tiff"; public const string FlowerRgb161616Planar = "Tiff/flower-rgb-planar-16.tiff"; + public const string FlowerRgb161616PlanarLittleEndian = "Tiff/flower-rgb-planar-16_lsb.tiff"; public const string FlowerRgb141414Contiguous = "Tiff/flower-rgb-contig-14.tiff"; public const string FlowerRgb141414Planar = "Tiff/flower-rgb-planar-14.tiff"; + public const string FlowerRgb121212Contiguous = "Tiff/flower-rgb-contig-12.tiff"; public const string FlowerRgb101010Contiguous = "Tiff/flower-rgb-contig-10.tiff"; public const string FlowerRgb101010Planar = "Tiff/flower-rgb-planar-10.tiff"; - public const string FlowerRgb121212Contiguous = "Tiff/flower-rgb-contig-12.tiff"; + public const string FlowerRgb888Contiguous = "Tiff/flower-rgb-contig-08.tiff"; + public const string FlowerRgb888Planar6Strips = "Tiff/flower-rgb-planar-08-6strips.tiff"; + public const string FlowerRgb888Planar15Strips = "Tiff/flower-rgb-planar-08-15strips.tiff"; + public const string FlowerYCbCr888Contiguous = "Tiff/flower-ycbcr-contig-08_h1v1.tiff"; + public const string FlowerYCbCr888Planar = "Tiff/flower-ycbcr-planar-08_h1v1.tiff"; + public const string FlowerYCbCr888Contiguoush2v1 = "Tiff/flower-ycbcr-contig-08_h2v1.tiff"; + public const string FlowerYCbCr888Contiguoush2v2 = "Tiff/flower-ycbcr-contig-08_h2v2.tiff"; + public const string FlowerYCbCr888Contiguoush4v4 = "Tiff/flower-ycbcr-contig-08_h4v4.tiff"; + public const string RgbYCbCr888Contiguoush1v1 = "Tiff/rgb-ycbcr-contig-08_h1v1.tiff"; + public const string RgbYCbCr888Contiguoush2v1 = "Tiff/rgb-ycbcr-contig-08_h2v1.tiff"; + public const string RgbYCbCr888Contiguoush2v2 = "Tiff/rgb-ycbcr-contig-08_h2v2.tiff"; + public const string RgbYCbCr888Contiguoush4v4 = "Tiff/rgb-ycbcr-contig-08_h4v4.tiff"; + public const string YCbCrJpegCompressed = "Tiff/ycbcr_jpegcompressed.tiff"; public const string FlowerRgb444Contiguous = "Tiff/flower-rgb-contig-04.tiff"; public const string FlowerRgb444Planar = "Tiff/flower-rgb-planar-04.tiff"; public const string FlowerRgb222Contiguous = "Tiff/flower-rgb-contig-02.tiff"; @@ -580,6 +820,25 @@ namespace SixLabors.ImageSharp.Tests public const string Flower12BitGray = "Tiff/flower-minisblack-12.tiff"; public const string Flower14BitGray = "Tiff/flower-minisblack-14.tiff"; public const string Flower16BitGray = "Tiff/flower-minisblack-16.tiff"; + public const string Flower16BitGrayLittleEndian = "Tiff/flower-minisblack-16_lsb.tiff"; + public const string Flower16BitGrayMinIsWhiteLittleEndian = "Tiff/flower-miniswhite-16_lsb.tiff"; + public const string Flower16BitGrayPredictorBigEndian = "Tiff/flower-minisblack-16_msb_lzw_predictor.tiff"; + public const string Flower16BitGrayPredictorLittleEndian = "Tiff/flower-minisblack-16_lsb_lzw_predictor.tiff"; + public const string Flower16BitGrayMinIsWhiteBigEndian = "Tiff/flower-miniswhite-16_msb.tiff"; + public const string Flower24BitGray = "Tiff/flower-minisblack-24_msb.tiff"; + public const string Flower24BitGrayLittleEndian = "Tiff/flower-minisblack-24_lsb.tiff"; + public const string Flower32BitGray = "Tiff/flower-minisblack-32_msb.tiff"; + public const string Flower32BitGrayLittleEndian = "Tiff/flower-minisblack-32_lsb.tiff"; + public const string Flower32BitFloatGray = "Tiff/flower-minisblack-float32_msb.tiff"; + public const string Flower32BitFloatGrayLittleEndian = "Tiff/flower-minisblack-float32_lsb.tiff"; + public const string Flower32BitFloatGrayMinIsWhite = "Tiff/flower-miniswhite-float32_msb.tiff"; + public const string Flower32BitFloatGrayMinIsWhiteLittleEndian = "Tiff/flower-miniswhite-float32_lsb.tiff"; + public const string Flower32BitGrayMinIsWhite = "Tiff/flower-miniswhite-32_msb.tiff"; + public const string Flower32BitGrayMinIsWhiteLittleEndian = "Tiff/flower-miniswhite-32_lsb.tiff"; + public const string Flower32BitGrayPredictorBigEndian = "Tiff/flower-minisblack-32_msb_deflate_predictor.tiff"; + public const string Flower32BitGrayPredictorLittleEndian = "Tiff/flower-minisblack-32_lsb_deflate_predictor.tiff"; + + public const string Issues1716Rgb161616BitLittleEndian = "Tiff/Issues/Issue1716.tiff"; public const string SmallRgbDeflate = "Tiff/rgb_small_deflate.tiff"; public const string SmallRgbLzw = "Tiff/rgb_small_lzw.tiff"; @@ -592,7 +851,6 @@ namespace SixLabors.ImageSharp.Tests public const string MultiframeDifferentSize = "Tiff/multipage_differentSize.tiff"; public const string MultiframeDifferentVariants = "Tiff/multipage_differentVariants.tiff"; - public const string FillOrder2 = "Tiff/b0350_fillorder2.tiff"; public const string LittleEndianByteOrder = "Tiff/little_endian.tiff"; public const string Fax4_Motorola = "Tiff/moy.tiff"; @@ -606,8 +864,6 @@ namespace SixLabors.ImageSharp.Tests public static readonly string[] Multiframes = { MultiframeDeflateWithPreview, MultiframeLzwPredictor /*, MultiFrameDifferentSize, MultiframeDifferentSizeTiled, MultiFrameDifferentVariants,*/ }; public static readonly string[] Metadata = { SampleMetadata }; - - public static readonly string[] NotSupported = { Calliphora_RgbJpeg, RgbJpeg, RgbUncompressedTiled, MultiframeDifferentSize, MultiframeDifferentVariants, FillOrder2, Calliphora_Fax4Compressed, Fax4_Motorola }; } } } diff --git a/tests/ImageSharp.Tests/TestUtilities/Attributes/WithBasicTestPatternImagesAttribute.cs b/tests/ImageSharp.Tests/TestUtilities/Attributes/WithBasicTestPatternImagesAttribute.cs index 03113e133..7f3faff8b 100644 --- a/tests/ImageSharp.Tests/TestUtilities/Attributes/WithBasicTestPatternImagesAttribute.cs +++ b/tests/ImageSharp.Tests/TestUtilities/Attributes/WithBasicTestPatternImagesAttribute.cs @@ -34,4 +34,4 @@ namespace SixLabors.ImageSharp.Tests protected override object[] GetFactoryMethodArgs(MethodInfo testMethod, Type factoryType) => new object[] { this.Width, this.Height }; } -} \ No newline at end of file +} diff --git a/tests/ImageSharp.Tests/TestUtilities/Attributes/WithFileAttribute.cs b/tests/ImageSharp.Tests/TestUtilities/Attributes/WithFileAttribute.cs index 6c79b9541..ab75c6468 100644 --- a/tests/ImageSharp.Tests/TestUtilities/Attributes/WithFileAttribute.cs +++ b/tests/ImageSharp.Tests/TestUtilities/Attributes/WithFileAttribute.cs @@ -44,4 +44,4 @@ namespace SixLabors.ImageSharp.Tests protected override string GetFactoryMethodName(MethodInfo testMethod) => "File"; } -} \ No newline at end of file +} diff --git a/tests/ImageSharp.Tests/TestUtilities/Attributes/WithFileCollectionAttribute.cs b/tests/ImageSharp.Tests/TestUtilities/Attributes/WithFileCollectionAttribute.cs index 92556024d..d54d1dd92 100644 --- a/tests/ImageSharp.Tests/TestUtilities/Attributes/WithFileCollectionAttribute.cs +++ b/tests/ImageSharp.Tests/TestUtilities/Attributes/WithFileCollectionAttribute.cs @@ -68,4 +68,4 @@ namespace SixLabors.ImageSharp.Tests /// protected override string GetFactoryMethodName(MethodInfo testMethod) => "File"; } -} \ No newline at end of file +} diff --git a/tests/ImageSharp.Tests/TestUtilities/FeatureTesting/FeatureTestRunner.cs b/tests/ImageSharp.Tests/TestUtilities/FeatureTesting/FeatureTestRunner.cs index fa0f02ca1..0d2f3fcef 100644 --- a/tests/ImageSharp.Tests/TestUtilities/FeatureTesting/FeatureTestRunner.cs +++ b/tests/ImageSharp.Tests/TestUtilities/FeatureTesting/FeatureTestRunner.cs @@ -301,6 +301,52 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities } } + /// + /// Runs the given test within an environment + /// where the given features. + /// + /// The test action to run. + /// The value to pass as a parameter #0 to the test action. + /// The value to pass as a parameter #1 to the test action. + /// The intrinsics features. + public static void RunWithHwIntrinsicsFeature( + Action action, + T arg0, + T arg1, + HwIntrinsics intrinsics) + where T : IConvertible + { + if (!RemoteExecutor.IsSupported) + { + return; + } + + foreach (KeyValuePair intrinsic in intrinsics.ToFeatureKeyValueCollection()) + { + var processStartInfo = new ProcessStartInfo(); + if (intrinsic.Key != HwIntrinsics.AllowAll) + { + processStartInfo.Environment[$"COMPlus_{intrinsic.Value}"] = "0"; + + RemoteExecutor.Invoke( + action, + arg0.ToString(), + arg1.ToString(), + new RemoteInvokeOptions + { + StartInfo = processStartInfo + }) + .Dispose(); + } + else + { + // Since we are running using the default architecture there is no + // point creating the overhead of running the action in a separate process. + action(arg0.ToString(), arg1.ToString()); + } + } + } + internal static Dictionary ToFeatureKeyValueCollection(this HwIntrinsics intrinsics) { // Loop through and translate the given values into COMPlus equivaluents diff --git a/tests/ImageSharp.Tests/TestUtilities/ImageComparison/TolerantImageComparer.cs b/tests/ImageSharp.Tests/TestUtilities/ImageComparison/TolerantImageComparer.cs index e87a83e4f..38fb4026d 100644 --- a/tests/ImageSharp.Tests/TestUtilities/ImageComparison/TolerantImageComparer.cs +++ b/tests/ImageSharp.Tests/TestUtilities/ImageComparison/TolerantImageComparer.cs @@ -4,7 +4,6 @@ using System; using System.Collections.Generic; using System.Runtime.CompilerServices; - using SixLabors.ImageSharp.Advanced; using SixLabors.ImageSharp.PixelFormats; diff --git a/tests/ImageSharp.Tests/TestUtilities/ImageProviders/BasicTestPatternProvider.cs b/tests/ImageSharp.Tests/TestUtilities/ImageProviders/BasicTestPatternProvider.cs index 409dea1c5..f5e1f238e 100644 --- a/tests/ImageSharp.Tests/TestUtilities/ImageProviders/BasicTestPatternProvider.cs +++ b/tests/ImageSharp.Tests/TestUtilities/ImageProviders/BasicTestPatternProvider.cs @@ -3,7 +3,6 @@ using System; using System.Numerics; - using SixLabors.ImageSharp.Advanced; using Xunit.Abstractions; diff --git a/tests/ImageSharp.Tests/TestUtilities/ImageProviders/TestImageProvider.cs b/tests/ImageSharp.Tests/TestUtilities/ImageProviders/TestImageProvider.cs index 700c40b72..4860524b3 100644 --- a/tests/ImageSharp.Tests/TestUtilities/ImageProviders/TestImageProvider.cs +++ b/tests/ImageSharp.Tests/TestUtilities/ImageProviders/TestImageProvider.cs @@ -21,11 +21,20 @@ namespace SixLabors.ImageSharp.Tests public abstract partial class TestImageProvider : ITestImageProvider, IXunitSerializable where TPixel : unmanaged, IPixel { + // Create a Configuration with Configuration.CreateDefaultInstance(), + // but use the shared MemoryAllocator from Configuration.Default.MemoryAllocator + private static Configuration CreateDefaultConfiguration() + { + var configuration = Configuration.CreateDefaultInstance(); + configuration.MemoryAllocator = ImageSharp.Configuration.Default.MemoryAllocator; + return configuration; + } + public PixelTypes PixelType { get; private set; } = typeof(TPixel).GetPixelType(); public virtual string SourceFileOrDescription => string.Empty; - public Configuration Configuration { get; set; } = Configuration.CreateDefaultInstance(); + public Configuration Configuration { get; set; } = CreateDefaultConfiguration(); /// /// Gets the utility instance to provide information about the test image & manage input/output. diff --git a/tests/ImageSharp.Tests/TestUtilities/ImageProviders/TestPatternProvider.cs b/tests/ImageSharp.Tests/TestUtilities/ImageProviders/TestPatternProvider.cs index 7612b663a..c61b25ace 100644 --- a/tests/ImageSharp.Tests/TestUtilities/ImageProviders/TestPatternProvider.cs +++ b/tests/ImageSharp.Tests/TestUtilities/ImageProviders/TestPatternProvider.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; - using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.PixelFormats; using Xunit.Abstractions; diff --git a/tests/ImageSharp.Tests/TestUtilities/ImagingTestCaseUtility.cs b/tests/ImageSharp.Tests/TestUtilities/ImagingTestCaseUtility.cs index 07acabccf..f1e7231a2 100644 --- a/tests/ImageSharp.Tests/TestUtilities/ImagingTestCaseUtility.cs +++ b/tests/ImageSharp.Tests/TestUtilities/ImagingTestCaseUtility.cs @@ -6,7 +6,6 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; - using SixLabors.ImageSharp.Formats; using SixLabors.ImageSharp.PixelFormats; diff --git a/tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/MagickReferenceDecoder.cs b/tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/MagickReferenceDecoder.cs index 294bd20fb..f0834dc00 100644 --- a/tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/MagickReferenceDecoder.cs +++ b/tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/MagickReferenceDecoder.cs @@ -32,15 +32,15 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs private static void FromRgba32Bytes(Configuration configuration, Span rgbaBytes, IMemoryGroup destinationGroup) where TPixel : unmanaged, ImageSharp.PixelFormats.IPixel { + Span sourcePixels = MemoryMarshal.Cast(rgbaBytes); foreach (Memory m in destinationGroup) { Span destBuffer = m.Span; - PixelOperations.Instance.FromRgba32Bytes( + PixelOperations.Instance.FromRgba32( configuration, - rgbaBytes, - destBuffer, - destBuffer.Length); - rgbaBytes = rgbaBytes.Slice(destBuffer.Length * 4); + sourcePixels.Slice(0, destBuffer.Length), + destBuffer); + sourcePixels = sourcePixels.Slice(destBuffer.Length); } } diff --git a/tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/SystemDrawingBridge.cs b/tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/SystemDrawingBridge.cs index 6d6e7bd76..157748bdd 100644 --- a/tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/SystemDrawingBridge.cs +++ b/tests/ImageSharp.Tests/TestUtilities/ReferenceCodecs/SystemDrawingBridge.cs @@ -5,7 +5,6 @@ using System; using System.Buffers; using System.Drawing; using System.Drawing.Imaging; - using SixLabors.ImageSharp.Advanced; using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.PixelFormats; diff --git a/tests/ImageSharp.Tests/TestUtilities/TestEnvironment.Formats.cs b/tests/ImageSharp.Tests/TestUtilities/TestEnvironment.Formats.cs index f68fb4d95..4b374b21f 100644 --- a/tests/ImageSharp.Tests/TestUtilities/TestEnvironment.Formats.cs +++ b/tests/ImageSharp.Tests/TestUtilities/TestEnvironment.Formats.cs @@ -10,6 +10,7 @@ using SixLabors.ImageSharp.Formats.Jpeg; using SixLabors.ImageSharp.Formats.Png; using SixLabors.ImageSharp.Formats.Tga; using SixLabors.ImageSharp.Formats.Tiff; +using SixLabors.ImageSharp.Formats.Webp; using SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs; namespace SixLabors.ImageSharp.Tests @@ -57,6 +58,7 @@ namespace SixLabors.ImageSharp.Tests new JpegConfigurationModule(), new GifConfigurationModule(), new TgaConfigurationModule(), + new WebpConfigurationModule(), new TiffConfigurationModule()); IImageEncoder pngEncoder = IsWindows ? (IImageEncoder)SystemDrawingReferenceEncoder.Png : new ImageSharpPngEncoderWithDefaultConfiguration(); diff --git a/tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs b/tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs index 26378796b..3f41281d0 100644 --- a/tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs +++ b/tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs @@ -663,7 +663,8 @@ namespace SixLabors.ImageSharp.Tests this TestImageProvider provider) where TPixel : unmanaged, IPixel { - var allocator = (ArrayPoolMemoryAllocator)provider.Configuration.MemoryAllocator; + var allocator = ArrayPoolMemoryAllocator.CreateDefault(); + provider.Configuration.MemoryAllocator = allocator; return new AllocatorBufferCapacityConfigurator(allocator, Unsafe.SizeOf()); } diff --git a/tests/ImageSharp.Tests/TestUtilities/TestMemoryAllocator.cs b/tests/ImageSharp.Tests/TestUtilities/TestMemoryAllocator.cs index ab9611d2f..eab0d5776 100644 --- a/tests/ImageSharp.Tests/TestUtilities/TestMemoryAllocator.cs +++ b/tests/ImageSharp.Tests/TestUtilities/TestMemoryAllocator.cs @@ -6,7 +6,6 @@ using System.Buffers; using System.Collections.Generic; using System.Numerics; using System.Runtime.InteropServices; - using SixLabors.ImageSharp.Memory; namespace SixLabors.ImageSharp.Tests.Memory diff --git a/tests/ImageSharp.Tests/TestUtilities/TestPixel.cs b/tests/ImageSharp.Tests/TestUtilities/TestPixel.cs index 818876065..7265e29c3 100644 --- a/tests/ImageSharp.Tests/TestUtilities/TestPixel.cs +++ b/tests/ImageSharp.Tests/TestUtilities/TestPixel.cs @@ -2,9 +2,7 @@ // Licensed under the Apache License, Version 2.0. using System; - using SixLabors.ImageSharp.PixelFormats; - using Xunit.Abstractions; namespace SixLabors.ImageSharp.Tests.TestUtilities diff --git a/tests/ImageSharp.Tests/TestUtilities/Tests/GroupOutputTests.cs b/tests/ImageSharp.Tests/TestUtilities/Tests/GroupOutputTests.cs index 03d067116..71d531360 100644 --- a/tests/ImageSharp.Tests/TestUtilities/Tests/GroupOutputTests.cs +++ b/tests/ImageSharp.Tests/TestUtilities/Tests/GroupOutputTests.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. using System.IO; - using SixLabors.ImageSharp.PixelFormats; using Xunit; diff --git a/tests/ImageSharp.Tests/TestUtilities/Tests/ImageComparerTests.cs b/tests/ImageSharp.Tests/TestUtilities/Tests/ImageComparerTests.cs index 9983ee3c8..8a6322896 100644 --- a/tests/ImageSharp.Tests/TestUtilities/Tests/ImageComparerTests.cs +++ b/tests/ImageSharp.Tests/TestUtilities/Tests/ImageComparerTests.cs @@ -3,13 +3,10 @@ using System.Collections.Generic; using System.Linq; - using Moq; - using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.Processing; using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison; - using Xunit; using Xunit.Abstractions; diff --git a/tests/ImageSharp.Tests/TestUtilities/Tests/ReferenceDecoderBenchmarks.cs b/tests/ImageSharp.Tests/TestUtilities/Tests/ReferenceDecoderBenchmarks.cs index 578af884b..3d77bc4d5 100644 --- a/tests/ImageSharp.Tests/TestUtilities/Tests/ReferenceDecoderBenchmarks.cs +++ b/tests/ImageSharp.Tests/TestUtilities/Tests/ReferenceDecoderBenchmarks.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. using System.Collections.Generic; - using SixLabors.ImageSharp.Formats; using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs; diff --git a/tests/ImageSharp.Tests/TestUtilities/Tests/SemaphoreReadMemoryStreamTests.cs b/tests/ImageSharp.Tests/TestUtilities/Tests/SemaphoreReadMemoryStreamTests.cs index 92f972941..420eaa162 100644 --- a/tests/ImageSharp.Tests/TestUtilities/Tests/SemaphoreReadMemoryStreamTests.cs +++ b/tests/ImageSharp.Tests/TestUtilities/Tests/SemaphoreReadMemoryStreamTests.cs @@ -39,13 +39,14 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.Tests Task readTask = Task.Factory.StartNew( () => - { - stream.Read(this.buffer); - stream.Read(this.buffer); - stream.Read(this.buffer); - stream.Read(this.buffer); - stream.Read(this.buffer); - }, TaskCreationOptions.LongRunning); + { + stream.Read(this.buffer); + stream.Read(this.buffer); + stream.Read(this.buffer); + stream.Read(this.buffer); + stream.Read(this.buffer); + }, + TaskCreationOptions.LongRunning); await Task.Delay(5); Assert.False(readTask.IsCompleted); @@ -70,7 +71,8 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.Tests await stream.ReadAsync(this.buffer, 0, this.buffer.Length); await stream.ReadAsync(this.buffer, 0, this.buffer.Length); await stream.ReadAsync(this.buffer, 0, this.buffer.Length); - }, TaskCreationOptions.LongRunning); + }, + TaskCreationOptions.LongRunning); await Task.Delay(5); Assert.False(readTask.IsCompleted); await this.notifyWaitPositionReachedSemaphore.WaitAsync(); diff --git a/tests/ImageSharp.Tests/TestUtilities/Tests/TestEnvironmentTests.cs b/tests/ImageSharp.Tests/TestUtilities/Tests/TestEnvironmentTests.cs index 05f4f032b..782c80ea8 100644 --- a/tests/ImageSharp.Tests/TestUtilities/Tests/TestEnvironmentTests.cs +++ b/tests/ImageSharp.Tests/TestUtilities/Tests/TestEnvironmentTests.cs @@ -4,12 +4,13 @@ using System; using System.IO; using Microsoft.DotNet.RemoteExecutor; + using SixLabors.ImageSharp.Formats; using SixLabors.ImageSharp.Formats.Bmp; using SixLabors.ImageSharp.Formats.Gif; using SixLabors.ImageSharp.Formats.Jpeg; +using SixLabors.ImageSharp.Formats.Webp; using SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs; - using Xunit; using Xunit.Abstractions; @@ -56,6 +57,7 @@ namespace SixLabors.ImageSharp.Tests [InlineData("lol/Rofl.bmp", typeof(SystemDrawingReferenceEncoder))] [InlineData("lol/Baz.JPG", typeof(JpegEncoder))] [InlineData("lol/Baz.gif", typeof(GifEncoder))] + [InlineData("lol/foobar.webp", typeof(WebpEncoder))] public void GetReferenceEncoder_ReturnsCorrectEncoders_Windows(string fileName, Type expectedEncoderType) { if (!TestEnvironment.IsWindows) @@ -72,6 +74,7 @@ namespace SixLabors.ImageSharp.Tests [InlineData("lol/Rofl.bmp", typeof(SystemDrawingReferenceDecoder))] [InlineData("lol/Baz.JPG", typeof(JpegDecoder))] [InlineData("lol/Baz.gif", typeof(GifDecoder))] + [InlineData("lol/foobar.webp", typeof(WebpDecoder))] public void GetReferenceDecoder_ReturnsCorrectDecoders_Windows(string fileName, Type expectedDecoderType) { if (!TestEnvironment.IsWindows) @@ -88,6 +91,7 @@ namespace SixLabors.ImageSharp.Tests [InlineData("lol/Rofl.bmp", typeof(BmpEncoder))] [InlineData("lol/Baz.JPG", typeof(JpegEncoder))] [InlineData("lol/Baz.gif", typeof(GifEncoder))] + [InlineData("lol/foobar.webp", typeof(WebpEncoder))] public void GetReferenceEncoder_ReturnsCorrectEncoders_Linux(string fileName, Type expectedEncoderType) { if (!TestEnvironment.IsLinux) @@ -104,6 +108,7 @@ namespace SixLabors.ImageSharp.Tests [InlineData("lol/Rofl.bmp", typeof(MagickReferenceDecoder))] [InlineData("lol/Baz.JPG", typeof(JpegDecoder))] [InlineData("lol/Baz.gif", typeof(GifDecoder))] + [InlineData("lol/foobar.webp", typeof(WebpDecoder))] public void GetReferenceDecoder_ReturnsCorrectDecoders_Linux(string fileName, Type expectedDecoderType) { if (!TestEnvironment.IsLinux) diff --git a/tests/ImageSharp.Tests/TestUtilities/Tests/TestImageExtensionsTests.cs b/tests/ImageSharp.Tests/TestUtilities/Tests/TestImageExtensionsTests.cs index 563789209..6960c97f4 100644 --- a/tests/ImageSharp.Tests/TestUtilities/Tests/TestImageExtensionsTests.cs +++ b/tests/ImageSharp.Tests/TestUtilities/Tests/TestImageExtensionsTests.cs @@ -2,7 +2,6 @@ // Licensed under the Apache License, Version 2.0. using System; - using Moq; using SixLabors.ImageSharp.PixelFormats; diff --git a/tests/ImageSharp.Tests/TestUtilities/Tests/TestUtilityExtensionsTests.cs b/tests/ImageSharp.Tests/TestUtilities/Tests/TestUtilityExtensionsTests.cs index c8a2c6c4c..bb9ed8260 100644 --- a/tests/ImageSharp.Tests/TestUtilities/Tests/TestUtilityExtensionsTests.cs +++ b/tests/ImageSharp.Tests/TestUtilities/Tests/TestUtilityExtensionsTests.cs @@ -5,7 +5,6 @@ using System; using System.Collections.Generic; using System.Linq; using System.Numerics; - using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.Processing; diff --git a/tests/ImageSharp.Tests/VectorAssert.cs b/tests/ImageSharp.Tests/VectorAssert.cs index 144681af7..1892b410a 100644 --- a/tests/ImageSharp.Tests/VectorAssert.cs +++ b/tests/ImageSharp.Tests/VectorAssert.cs @@ -4,7 +4,6 @@ using System; using System.Collections.Generic; using System.Numerics; - using SixLabors.ImageSharp.PixelFormats; using Xunit; diff --git a/tests/Images/External/ReferenceOutput/JpegDecoderTests/DecodeBaselineJpeg_jpeg420small.png b/tests/Images/External/ReferenceOutput/JpegDecoderTests/DecodeBaselineJpeg_jpeg420small.png index c57b00d0e..4032a32af 100644 --- a/tests/Images/External/ReferenceOutput/JpegDecoderTests/DecodeBaselineJpeg_jpeg420small.png +++ b/tests/Images/External/ReferenceOutput/JpegDecoderTests/DecodeBaselineJpeg_jpeg420small.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a76832570111a868ea6cb6e8287aae1976c575c94c63880c74346a4b5db5d305 -size 27007 +oid sha256:2b5e1d91fb6dc1ddb696fbee63331ba9c6ef3548b619c005887e60c5b01f4981 +size 27303 diff --git a/tests/Images/External/ReferenceOutput/ResizeTests/CanResizeLargeImageWithCropMode_Rgba32_issue1006-incorrect-resize.png b/tests/Images/External/ReferenceOutput/ResizeTests/CanResizeLargeImageWithCropMode_issue1006-incorrect-resize.png similarity index 100% rename from tests/Images/External/ReferenceOutput/ResizeTests/CanResizeLargeImageWithCropMode_Rgba32_issue1006-incorrect-resize.png rename to tests/Images/External/ReferenceOutput/ResizeTests/CanResizeLargeImageWithCropMode_issue1006-incorrect-resize.png diff --git a/tests/Images/External/ReferenceOutput/ResizeTests/ResizeFromSourceRectangle_Rgba32_CalliphoraPartial.png b/tests/Images/External/ReferenceOutput/ResizeTests/ResizeFromSourceRectangle_CalliphoraPartial.png similarity index 100% rename from tests/Images/External/ReferenceOutput/ResizeTests/ResizeFromSourceRectangle_Rgba32_CalliphoraPartial.png rename to tests/Images/External/ReferenceOutput/ResizeTests/ResizeFromSourceRectangle_CalliphoraPartial.png diff --git a/tests/Images/External/ReferenceOutput/ResizeTests/ResizeHeightAndKeepAspect_Rgba32_CalliphoraPartial.png b/tests/Images/External/ReferenceOutput/ResizeTests/ResizeHeightAndKeepAspect_CalliphoraPartial.png similarity index 100% rename from tests/Images/External/ReferenceOutput/ResizeTests/ResizeHeightAndKeepAspect_Rgba32_CalliphoraPartial.png rename to tests/Images/External/ReferenceOutput/ResizeTests/ResizeHeightAndKeepAspect_CalliphoraPartial.png diff --git a/tests/Images/External/ReferenceOutput/ResizeTests/ResizeWidthAndKeepAspect_Rgba32_CalliphoraPartial.png b/tests/Images/External/ReferenceOutput/ResizeTests/ResizeWidthAndKeepAspect_CalliphoraPartial.png similarity index 100% rename from tests/Images/External/ReferenceOutput/ResizeTests/ResizeWidthAndKeepAspect_Rgba32_CalliphoraPartial.png rename to tests/Images/External/ReferenceOutput/ResizeTests/ResizeWidthAndKeepAspect_CalliphoraPartial.png diff --git a/tests/Images/External/ReferenceOutput/ResizeTests/ResizeWithBoxPadMode_Rgba32_CalliphoraPartial.png b/tests/Images/External/ReferenceOutput/ResizeTests/ResizeWithBoxPadMode_CalliphoraPartial.png similarity index 100% rename from tests/Images/External/ReferenceOutput/ResizeTests/ResizeWithBoxPadMode_Rgba32_CalliphoraPartial.png rename to tests/Images/External/ReferenceOutput/ResizeTests/ResizeWithBoxPadMode_CalliphoraPartial.png diff --git a/tests/Images/External/ReferenceOutput/ResizeTests/ResizeWithCropHeightMode_Rgba32_CalliphoraPartial.png b/tests/Images/External/ReferenceOutput/ResizeTests/ResizeWithCropHeightMode_CalliphoraPartial.png similarity index 100% rename from tests/Images/External/ReferenceOutput/ResizeTests/ResizeWithCropHeightMode_Rgba32_CalliphoraPartial.png rename to tests/Images/External/ReferenceOutput/ResizeTests/ResizeWithCropHeightMode_CalliphoraPartial.png diff --git a/tests/Images/External/ReferenceOutput/ResizeTests/ResizeWithCropWidthMode_Rgba32_CalliphoraPartial.png b/tests/Images/External/ReferenceOutput/ResizeTests/ResizeWithCropWidthMode_CalliphoraPartial.png similarity index 100% rename from tests/Images/External/ReferenceOutput/ResizeTests/ResizeWithCropWidthMode_Rgba32_CalliphoraPartial.png rename to tests/Images/External/ReferenceOutput/ResizeTests/ResizeWithCropWidthMode_CalliphoraPartial.png diff --git a/tests/Images/External/ReferenceOutput/ResizeTests/ResizeWithMaxMode_Rgba32_CalliphoraPartial.png b/tests/Images/External/ReferenceOutput/ResizeTests/ResizeWithMaxMode_CalliphoraPartial.png similarity index 100% rename from tests/Images/External/ReferenceOutput/ResizeTests/ResizeWithMaxMode_Rgba32_CalliphoraPartial.png rename to tests/Images/External/ReferenceOutput/ResizeTests/ResizeWithMaxMode_CalliphoraPartial.png diff --git a/tests/Images/External/ReferenceOutput/ResizeTests/ResizeWithMinMode_Rgba32_CalliphoraPartial.png b/tests/Images/External/ReferenceOutput/ResizeTests/ResizeWithMinMode_CalliphoraPartial.png similarity index 100% rename from tests/Images/External/ReferenceOutput/ResizeTests/ResizeWithMinMode_Rgba32_CalliphoraPartial.png rename to tests/Images/External/ReferenceOutput/ResizeTests/ResizeWithMinMode_CalliphoraPartial.png diff --git a/tests/Images/External/ReferenceOutput/ResizeTests/ResizeWithPadMode_Rgba32_CalliphoraPartial.png b/tests/Images/External/ReferenceOutput/ResizeTests/ResizeWithPadMode_CalliphoraPartial.png similarity index 100% rename from tests/Images/External/ReferenceOutput/ResizeTests/ResizeWithPadMode_Rgba32_CalliphoraPartial.png rename to tests/Images/External/ReferenceOutput/ResizeTests/ResizeWithPadMode_CalliphoraPartial.png diff --git a/tests/Images/External/ReferenceOutput/ResizeTests/ResizeWithStretchMode_Rgba32_CalliphoraPartial.png b/tests/Images/External/ReferenceOutput/ResizeTests/ResizeWithStretchMode_CalliphoraPartial.png similarity index 100% rename from tests/Images/External/ReferenceOutput/ResizeTests/ResizeWithStretchMode_Rgba32_CalliphoraPartial.png rename to tests/Images/External/ReferenceOutput/ResizeTests/ResizeWithStretchMode_CalliphoraPartial.png diff --git a/tests/Images/External/ReferenceOutput/ResizeTests/Resize_IsNotBoundToSinglePixelType_Bgr24_TestPattern50x50.png b/tests/Images/External/ReferenceOutput/ResizeTests/Resize_IsNotBoundToSinglePixelType_Bgr24_TestPattern50x50.png new file mode 100644 index 000000000..674639d48 --- /dev/null +++ b/tests/Images/External/ReferenceOutput/ResizeTests/Resize_IsNotBoundToSinglePixelType_Bgr24_TestPattern50x50.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4a9940410cca3fe98a6d7aaf0e2184779f908c569a5a34f9965fb3a4f9e6fa8f +size 1066 diff --git a/tests/Images/Input/Jpg/baseline/arithmetic_coding.jpg b/tests/Images/Input/Jpg/baseline/arithmetic_coding.jpg new file mode 100644 index 000000000..3f57b7d7a --- /dev/null +++ b/tests/Images/Input/Jpg/baseline/arithmetic_coding.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fec7012d9ae52a12c4617fd7526e506feee812fc67e923a76b2ca88c95f7a538 +size 3111 diff --git a/tests/Images/Input/Jpg/baseline/forest_bridge.jpg b/tests/Images/Input/Jpg/baseline/forest_bridge.jpg new file mode 100644 index 000000000..a487bb9e7 --- /dev/null +++ b/tests/Images/Input/Jpg/baseline/forest_bridge.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:56b3db3d0e146ee7fe27f8fbda4bccc1483e18104bfc747cac75a2ec03d65647 +size 1936782 diff --git a/tests/Images/Input/Jpg/baseline/jpeg-rgb.jpg b/tests/Images/Input/Jpg/baseline/jpeg-rgb.jpg new file mode 100644 index 000000000..2f2be0fa1 --- /dev/null +++ b/tests/Images/Input/Jpg/baseline/jpeg-rgb.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f4630c33d722a89de5cb1834bffa43c729f204c0f8c95d4ec2127ddfcd433f60 +size 10100 diff --git a/tests/Images/Input/Jpg/baseline/jpeg410.jpg b/tests/Images/Input/Jpg/baseline/jpeg410.jpg new file mode 100644 index 000000000..3bc41af8d --- /dev/null +++ b/tests/Images/Input/Jpg/baseline/jpeg410.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:318338c1a541227632a99cc47b04fc9f6d19c3e8300a76e71136edec2d17a5f5 +size 9073 diff --git a/tests/Images/Input/Jpg/baseline/jpeg411.jpg b/tests/Images/Input/Jpg/baseline/jpeg411.jpg new file mode 100644 index 000000000..43a2ba49d --- /dev/null +++ b/tests/Images/Input/Jpg/baseline/jpeg411.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:70315936e36bb1edf38fc950b7b321f20be5a2592db59bfd28d79dbc391a5aaf +size 4465 diff --git a/tests/Images/Input/Jpg/baseline/jpeg422.jpg b/tests/Images/Input/Jpg/baseline/jpeg422.jpg new file mode 100644 index 000000000..4782b53b3 --- /dev/null +++ b/tests/Images/Input/Jpg/baseline/jpeg422.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:be21207ecb96bcb0925706649678c522c68bf08ee26e6e8878456f4f7772dd31 +size 3951 diff --git a/tests/Images/Input/Jpg/baseline/lossless.jpg b/tests/Images/Input/Jpg/baseline/lossless.jpg new file mode 100644 index 000000000..37091b73c --- /dev/null +++ b/tests/Images/Input/Jpg/baseline/lossless.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8937e245885e1f280e1843ad48a4349ec1a3f71f86c954229cd44160aeeaaac4 +size 209584 diff --git a/tests/Images/Input/Jpg/issues/Issue1732-WrongColorSpace.jpg b/tests/Images/Input/Jpg/issues/Issue1732-WrongColorSpace.jpg new file mode 100644 index 000000000..e3ba85ae8 --- /dev/null +++ b/tests/Images/Input/Jpg/issues/Issue1732-WrongColorSpace.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3c72235954cdfb9d0cc7f09c537704e617313dc77708b4dca27b47c94c5e67a6 +size 2852 diff --git a/tests/Images/Input/Jpg/issues/fuzz/Issue1693-IndexOutOfRangeException-A.jpg b/tests/Images/Input/Jpg/issues/fuzz/Issue1693-IndexOutOfRangeException-A.jpg new file mode 100644 index 000000000..eb8fb9010 --- /dev/null +++ b/tests/Images/Input/Jpg/issues/fuzz/Issue1693-IndexOutOfRangeException-A.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fbb6acd612cdb09825493d04ec7c6aba8ef2a94cc9a86c6b16218720adfb8f5c +size 58065 diff --git a/tests/Images/Input/Jpg/issues/fuzz/Issue1693-IndexOutOfRangeException-B.jpg b/tests/Images/Input/Jpg/issues/fuzz/Issue1693-IndexOutOfRangeException-B.jpg new file mode 100644 index 000000000..7dd428591 --- /dev/null +++ b/tests/Images/Input/Jpg/issues/fuzz/Issue1693-IndexOutOfRangeException-B.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8720a9ccf118c3f55407aa250ee490d583286c7e40c8c62a6f8ca449ca3ddff3 +size 58067 diff --git a/tests/Images/Input/Jpg/progressive/arithmetic_progressive.jpg b/tests/Images/Input/Jpg/progressive/arithmetic_progressive.jpg new file mode 100644 index 000000000..06b3b684e --- /dev/null +++ b/tests/Images/Input/Jpg/progressive/arithmetic_progressive.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3af237c172248d39c7b82c879de3d162e4dafaf36dc298add210740843edd33f +size 3129 diff --git a/tests/Images/Input/Jpg/progressive/winter.jpg b/tests/Images/Input/Jpg/progressive/winter.jpg new file mode 100644 index 000000000..bc08d8be0 --- /dev/null +++ b/tests/Images/Input/Jpg/progressive/winter.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d377b70cedfb9d25f1ae0244dcf2edb000540aa4a8925cce57f810f7efd0dc84 +size 234976 diff --git a/tests/Images/Input/Png/issues/Issue_1765_Net6DeflateStreamRead.png b/tests/Images/Input/Png/issues/Issue_1765_Net6DeflateStreamRead.png new file mode 100644 index 000000000..c9705550f --- /dev/null +++ b/tests/Images/Input/Png/issues/Issue_1765_Net6DeflateStreamRead.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:86ea14567bcd259d76dc782ee366c23a5755714c6d48f636524b23e75b89e5b6 +size 775275 diff --git a/tests/Images/Input/Png/testpattern31x31-halftransparent.png b/tests/Images/Input/Png/testpattern31x31-halftransparent.png new file mode 100644 index 000000000..56b8a16b2 --- /dev/null +++ b/tests/Images/Input/Png/testpattern31x31-halftransparent.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:415483fde21637bdf919244c0625665f4914f7678eb4e047507b9bcd2262ec50 +size 472 diff --git a/tests/Images/Input/Png/testpattern31x31.png b/tests/Images/Input/Png/testpattern31x31.png new file mode 100644 index 000000000..f7abd7959 --- /dev/null +++ b/tests/Images/Input/Png/testpattern31x31.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:233dc410d723204dfd63c296ee3ca165f4a3641475627eb82f5515f31d25afe5 +size 484 diff --git a/tests/Images/Input/Tiff/7324fcaff3aad96f27899da51c1bb5d9.tiff b/tests/Images/Input/Tiff/7324fcaff3aad96f27899da51c1bb5d9.tiff index 5574bd58e..24a4141f5 100644 --- a/tests/Images/Input/Tiff/7324fcaff3aad96f27899da51c1bb5d9.tiff +++ b/tests/Images/Input/Tiff/7324fcaff3aad96f27899da51c1bb5d9.tiff @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:622d69dba0a8a67aa3b87e384a2b9ea8d29689eaa5cb5d0eee857f98ed660517 -size 15154924 +oid sha256:579db6b2bd34566846de992f255c6b341d0f88d957a0eb02b01caad3f20c5b44 +size 78794 diff --git a/tests/Images/Input/Tiff/Calliphora_bicolor_uncompressed.tiff b/tests/Images/Input/Tiff/Calliphora_bicolor_uncompressed.tiff index b0dbdde54..5b668ac51 100644 --- a/tests/Images/Input/Tiff/Calliphora_bicolor_uncompressed.tiff +++ b/tests/Images/Input/Tiff/Calliphora_bicolor_uncompressed.tiff @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ed3b08730e5c34eb8d268f58d1e09efe2605398899bfd726cc3b35de21baa6ff -size 121196 +oid sha256:c35902ca485fba441230efa88f794ee5aafa9f75ad5e4a14cb3d592a0a98c538 +size 7760 diff --git a/tests/Images/Input/Tiff/Calliphora_ccitt_fax3.tiff b/tests/Images/Input/Tiff/Calliphora_ccitt_fax3.tiff index 39852d534..3592206bc 100644 --- a/tests/Images/Input/Tiff/Calliphora_ccitt_fax3.tiff +++ b/tests/Images/Input/Tiff/Calliphora_ccitt_fax3.tiff @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8b9b105857723bca5f478a9ab23c0aeca93abe863781019bbd2da47f18c46f24 -size 125778 +oid sha256:da7d98823c284d92982a88c4a51434bbc140dceac245a8a054c6e41a489d0cc7 +size 5986 diff --git a/tests/Images/Input/Tiff/Calliphora_ccitt_fax4.tiff b/tests/Images/Input/Tiff/Calliphora_ccitt_fax4.tiff index 384d00eaa..e0b4fa35e 100644 --- a/tests/Images/Input/Tiff/Calliphora_ccitt_fax4.tiff +++ b/tests/Images/Input/Tiff/Calliphora_ccitt_fax4.tiff @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7a2c95aec08b96bca30af344f7d9952a603a951802ce534a5f2c5f563795cbd2 -size 117704 +oid sha256:118e55fe0f0dbb5d2712337ec9456a27407f11c0eb9f7e7e81700d4d84b7db09 +size 4378 diff --git a/tests/Images/Input/Tiff/Calliphora_gray_deflate.tiff b/tests/Images/Input/Tiff/Calliphora_gray_deflate.tiff index 621ef158a..390952120 100644 --- a/tests/Images/Input/Tiff/Calliphora_gray_deflate.tiff +++ b/tests/Images/Input/Tiff/Calliphora_gray_deflate.tiff @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2314b31ca9938fa8b11cbabda0b118a90025a45d2931fca9afa131c0d6919aca -size 557717 +oid sha256:d4d3541db6b7751d3225599aa822c3376fb27bb9dc2dd28674ef4f78bf426191 +size 83356 diff --git a/tests/Images/Input/Tiff/Calliphora_gray_deflate_predictor.tiff b/tests/Images/Input/Tiff/Calliphora_gray_deflate_predictor.tiff index f44a6e934..e7fdef14b 100644 --- a/tests/Images/Input/Tiff/Calliphora_gray_deflate_predictor.tiff +++ b/tests/Images/Input/Tiff/Calliphora_gray_deflate_predictor.tiff @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b9576b3a49b84e26938a7e9ded5f43a1a3c3390bf4824803f5aaab8e00c1afb4 -size 630947 +oid sha256:d007429701cc20154e84909af6988414001e6e60fba5c995f67b2a04cad6e57b +size 41135 diff --git a/tests/Images/Input/Tiff/Calliphora_gray_lzw_predictor.tiff b/tests/Images/Input/Tiff/Calliphora_gray_lzw_predictor.tiff index b14eeba8d..de8562296 100644 --- a/tests/Images/Input/Tiff/Calliphora_gray_lzw_predictor.tiff +++ b/tests/Images/Input/Tiff/Calliphora_gray_lzw_predictor.tiff @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3f24fd8f36a4847fcb84a317de4fd2eacd5eb0c58ef4436d33919f0a6658d0d9 -size 698309 +oid sha256:649f0b8ad50a9465fdb447c411e33f20a8b367600e7c3af83c8f686f3ab3e6dc +size 47143 diff --git a/tests/Images/Input/Tiff/Calliphora_grayscale_uncompressed.tiff b/tests/Images/Input/Tiff/Calliphora_grayscale_uncompressed.tiff index 5db7ef564..e6ff007d4 100644 --- a/tests/Images/Input/Tiff/Calliphora_grayscale_uncompressed.tiff +++ b/tests/Images/Input/Tiff/Calliphora_grayscale_uncompressed.tiff @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0283f2be39a151ca3ed19be97ebe4a6b17978ed251dd4d0d568895865fec24c7 -size 964588 +oid sha256:5925388b374b75161ef49273e8c85c4f99713e5e3be380ea13a03895f47809ba +size 60001 diff --git a/tests/Images/Input/Tiff/Calliphora_huffman_rle.tiff b/tests/Images/Input/Tiff/Calliphora_huffman_rle.tiff index e0a39d248..1998b371c 100644 --- a/tests/Images/Input/Tiff/Calliphora_huffman_rle.tiff +++ b/tests/Images/Input/Tiff/Calliphora_huffman_rle.tiff @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1a4f687de9925863b1c9f32f53b6c05fb121f9d7b02ff5869113c4745433f10d -size 124644 +oid sha256:f27e758bb72d5e03fdcf0b1c58c417e4a7928cbdf8d432dc5b9a7d8d7ee4d06b +size 5668 diff --git a/tests/Images/Input/Tiff/Calliphora_palette_uncompressed.tiff b/tests/Images/Input/Tiff/Calliphora_palette_uncompressed.tiff index 1592645c8..1d3c9a789 100644 --- a/tests/Images/Input/Tiff/Calliphora_palette_uncompressed.tiff +++ b/tests/Images/Input/Tiff/Calliphora_palette_uncompressed.tiff @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b70500348b1af7828c15e7782eaca105ff749136d7c45eb4cab8c5cd5269c3f6 -size 966134 +oid sha256:29d4b30265158a7cc651d75130843a7f5a7ebf8b2f0f4bb0cf86c82cbec7f6ec +size 61549 diff --git a/tests/Images/Input/Tiff/Calliphora_rgb_deflate_predictor.tiff b/tests/Images/Input/Tiff/Calliphora_rgb_deflate_predictor.tiff index c2ebed364..0ded46140 100644 --- a/tests/Images/Input/Tiff/Calliphora_rgb_deflate_predictor.tiff +++ b/tests/Images/Input/Tiff/Calliphora_rgb_deflate_predictor.tiff @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:da6e6a35a0bb0f5f2d49e3c5f0eb2deb7118718dd08844f66a6cb72f48b5c489 -size 1476294 +oid sha256:392e1269220e7e3feb9e2b256e82cce6a2394a5cabef042fdb10def6b24ff165 +size 111819 diff --git a/tests/Images/Input/Tiff/Calliphora_rgb_jpeg.tiff b/tests/Images/Input/Tiff/Calliphora_rgb_jpeg.tiff index c9f5fadee..f45aacce4 100644 --- a/tests/Images/Input/Tiff/Calliphora_rgb_jpeg.tiff +++ b/tests/Images/Input/Tiff/Calliphora_rgb_jpeg.tiff @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ba79ffac35e16208406e073492d770d3a77e51a47112aa02ab8fd98b5a8487b2 -size 198564 +oid sha256:4baf0f4c462e5bef71ab36f505dfff87a31bd1d25deabccd822a359c1075e08e +size 65748 diff --git a/tests/Images/Input/Tiff/Calliphora_rgb_lzw.tif b/tests/Images/Input/Tiff/Calliphora_rgb_lzw.tif deleted file mode 100644 index 745052267..000000000 --- a/tests/Images/Input/Tiff/Calliphora_rgb_lzw.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:53006876fcdc655a794462de57eb6b56f4d0cdd3cb8b752c63328db0eb4aa3c1 -size 725085 diff --git a/tests/Images/Input/Tiff/Calliphora_rgb_lzw.tiff b/tests/Images/Input/Tiff/Calliphora_rgb_lzw.tiff new file mode 100644 index 000000000..5e4cf8be9 --- /dev/null +++ b/tests/Images/Input/Tiff/Calliphora_rgb_lzw.tiff @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d83d8a81ebb7337f00b319a8c37cfdef07423d6a61006411130e386238dd00dd +size 121907 diff --git a/tests/Images/Input/Tiff/Calliphora_rgb_lzw_predictor.tiff b/tests/Images/Input/Tiff/Calliphora_rgb_lzw_predictor.tiff index 99642af52..2fa884f36 100644 --- a/tests/Images/Input/Tiff/Calliphora_rgb_lzw_predictor.tiff +++ b/tests/Images/Input/Tiff/Calliphora_rgb_lzw_predictor.tiff @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ecb529e5e3e0eca6f5e407b034fa8ba67bb4b9068af9e9b30425b08d30a249c0 -size 1756355 +oid sha256:993207c34358165af5fac0d0b955b56cd79e9707c1c46344863e01cbc9c7707d +size 126695 diff --git a/tests/Images/Input/Tiff/Calliphora_rgb_packbits.tiff b/tests/Images/Input/Tiff/Calliphora_rgb_packbits.tiff index 862db0b39..6fc2c9b21 100644 --- a/tests/Images/Input/Tiff/Calliphora_rgb_packbits.tiff +++ b/tests/Images/Input/Tiff/Calliphora_rgb_packbits.tiff @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:59dbb48f10c40cbbd4f5617a9f57536790ce0b9a4cc241dc8d6257095598cb76 -size 2891292 +oid sha256:81e7456578510c85e5bebe8bc7c5796da6e2cd61f5bbe0a1f6bb46b8aee3d695 +size 179949 diff --git a/tests/Images/Input/Tiff/Calliphora_rgb_uncompressed.tiff b/tests/Images/Input/Tiff/Calliphora_rgb_uncompressed.tiff index 7ebd74d9d..7fc592315 100644 --- a/tests/Images/Input/Tiff/Calliphora_rgb_uncompressed.tiff +++ b/tests/Images/Input/Tiff/Calliphora_rgb_uncompressed.tiff @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:acb46c990af78fcb0e63849f0f26acffe26833d5cfd2fc77a728baf92166eea3 -size 2893218 +oid sha256:bb25349a7f803aeafc47d8a05deca1a8afdc4bdc5a53e2916f68d5c3e7d8cad3 +size 179207 diff --git a/tests/Images/Input/Tiff/Issues/Issue1716.tiff b/tests/Images/Input/Tiff/Issues/Issue1716.tiff new file mode 100644 index 000000000..b7b1fe556 --- /dev/null +++ b/tests/Images/Input/Tiff/Issues/Issue1716.tiff @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c734dd489c65fb77bd7a35cd663aa16ce986df2c2ab8c7ca43d8b65db9d47c03 +size 6666162 diff --git a/tests/Images/Input/Tiff/b0350_fillorder2.tiff b/tests/Images/Input/Tiff/b0350_fillorder2.tiff deleted file mode 100644 index 3b7ee6ac3..000000000 --- a/tests/Images/Input/Tiff/b0350_fillorder2.tiff +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:37c6a28f460d8781fdc3bcf0cc9bd23f633b03899563546bfc6234a8478f67f0 -size 68637 diff --git a/tests/Images/Input/Tiff/basi3p02_fax3_lowerOrderBitsFirst.tiff b/tests/Images/Input/Tiff/basi3p02_fax3_lowerOrderBitsFirst.tiff new file mode 100644 index 000000000..d9b5a5bfb --- /dev/null +++ b/tests/Images/Input/Tiff/basi3p02_fax3_lowerOrderBitsFirst.tiff @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:eb56b3582c5c7d91d712e68181110ab0bf74d21992030629f05803c420b7b483 +size 388 diff --git a/tests/Images/Input/Tiff/basi3p02_fax4.tiff b/tests/Images/Input/Tiff/basi3p02_fax4.tiff new file mode 100644 index 000000000..a53f8f36f --- /dev/null +++ b/tests/Images/Input/Tiff/basi3p02_fax4.tiff @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:185ae3c4174b323adcf811d125cd77b71768406845923f50395c0baebff57b7c +size 282 diff --git a/tests/Images/Input/Tiff/basi3p02_fax4_lowerOrderBitsFirst.tiff b/tests/Images/Input/Tiff/basi3p02_fax4_lowerOrderBitsFirst.tiff new file mode 100644 index 000000000..12d10ffa7 --- /dev/null +++ b/tests/Images/Input/Tiff/basi3p02_fax4_lowerOrderBitsFirst.tiff @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a19eb117f194718575681a81a4fbe7fe4a1b82b99113707295194090fb935784 +size 282 diff --git a/tests/Images/Input/Tiff/basi3p02_fax4_minisblack.tiff b/tests/Images/Input/Tiff/basi3p02_fax4_minisblack.tiff new file mode 100644 index 000000000..9c76237b5 --- /dev/null +++ b/tests/Images/Input/Tiff/basi3p02_fax4_minisblack.tiff @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:af0d8f3c18f96228aa369bc295201a1bfe1b044c23991ff168401adc5402ebb6 +size 308 diff --git a/tests/Images/Input/Tiff/basi3p02_huffman_rle_lowerOrderBitsFirst.tiff b/tests/Images/Input/Tiff/basi3p02_huffman_rle_lowerOrderBitsFirst.tiff new file mode 100644 index 000000000..6ab060324 --- /dev/null +++ b/tests/Images/Input/Tiff/basi3p02_huffman_rle_lowerOrderBitsFirst.tiff @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5ac3e56a93996464a579ae19cf5f8d9531e2f08db36879aaba176731c24951a5 +size 352 diff --git a/tests/Images/Input/Tiff/f8179f8f5e566349cf3583a1ff3ea95c.tiff b/tests/Images/Input/Tiff/f8179f8f5e566349cf3583a1ff3ea95c.tiff new file mode 100644 index 000000000..9dc10018e --- /dev/null +++ b/tests/Images/Input/Tiff/f8179f8f5e566349cf3583a1ff3ea95c.tiff @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cf75c4b679d2449e239f228cdee6a25adc7d7b16dde3fb9061a07b2fb0699db1 +size 735412 diff --git a/tests/Images/Input/Tiff/flower-minisblack-16_lsb.tiff b/tests/Images/Input/Tiff/flower-minisblack-16_lsb.tiff new file mode 100644 index 000000000..62061bfaf --- /dev/null +++ b/tests/Images/Input/Tiff/flower-minisblack-16_lsb.tiff @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c3806304a5453a6ec8a6795bc77b967b9aa8593288af36bbf9802f22ee27869e +size 6588 diff --git a/tests/Images/Input/Tiff/flower-minisblack-16_lsb_lzw_predictor.tiff b/tests/Images/Input/Tiff/flower-minisblack-16_lsb_lzw_predictor.tiff new file mode 100644 index 000000000..e28ccda48 --- /dev/null +++ b/tests/Images/Input/Tiff/flower-minisblack-16_lsb_lzw_predictor.tiff @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:263da6b84862af1bc23f2631e648b1a629b5571b253c82f3ea64f44e9b7b1fe6 +size 8478 diff --git a/tests/Images/Input/Tiff/flower-minisblack-16_msb_lzw_predictor.tiff b/tests/Images/Input/Tiff/flower-minisblack-16_msb_lzw_predictor.tiff new file mode 100644 index 000000000..144f96887 --- /dev/null +++ b/tests/Images/Input/Tiff/flower-minisblack-16_msb_lzw_predictor.tiff @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e67ac19cbdeb8585b204ee958edc7679a92c2b415a1a2c6051f14fe2966f933c +size 8504 diff --git a/tests/Images/Input/Tiff/flower-minisblack-24_lsb.tiff b/tests/Images/Input/Tiff/flower-minisblack-24_lsb.tiff new file mode 100644 index 000000000..7f9dd009d --- /dev/null +++ b/tests/Images/Input/Tiff/flower-minisblack-24_lsb.tiff @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fe2d4e0d99bdfade966e27bd9583bce39bebb90efa8e7f768ce3cec69aa306e2 +size 9770 diff --git a/tests/Images/Input/Tiff/flower-minisblack-24_msb.tiff b/tests/Images/Input/Tiff/flower-minisblack-24_msb.tiff new file mode 100644 index 000000000..1fddb22e3 --- /dev/null +++ b/tests/Images/Input/Tiff/flower-minisblack-24_msb.tiff @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6b5a96942ee27a2b25d3cbb8bdd05239be71f84acc4d63c95380841a8a67befd +size 9770 diff --git a/tests/Images/Input/Tiff/flower-minisblack-32_lsb.tiff b/tests/Images/Input/Tiff/flower-minisblack-32_lsb.tiff new file mode 100644 index 000000000..cc3be01d2 --- /dev/null +++ b/tests/Images/Input/Tiff/flower-minisblack-32_lsb.tiff @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e37a4455e6b61e32720af99127b82aacdc907be91b8ed1d8e1a1f06d6a853211 +size 12885 diff --git a/tests/Images/Input/Tiff/flower-minisblack-32_lsb_deflate_predictor.tiff b/tests/Images/Input/Tiff/flower-minisblack-32_lsb_deflate_predictor.tiff new file mode 100644 index 000000000..2dc9e8092 --- /dev/null +++ b/tests/Images/Input/Tiff/flower-minisblack-32_lsb_deflate_predictor.tiff @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d5e7998cc985ef11ab9da410f18dcfb6b9a3169fb1ec01f9e61aa38d8ee4cfb6 +size 12704 diff --git a/tests/Images/Input/Tiff/flower-minisblack-32_msb.tiff b/tests/Images/Input/Tiff/flower-minisblack-32_msb.tiff new file mode 100644 index 000000000..b64616ed2 --- /dev/null +++ b/tests/Images/Input/Tiff/flower-minisblack-32_msb.tiff @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6677c372a449fe0324b148385cf0ebaaf33ab4563484ae89831dfeacd80d7c93 +size 12885 diff --git a/tests/Images/Input/Tiff/flower-minisblack-32_msb_deflate_predictor.tiff b/tests/Images/Input/Tiff/flower-minisblack-32_msb_deflate_predictor.tiff new file mode 100644 index 000000000..f87c74c72 --- /dev/null +++ b/tests/Images/Input/Tiff/flower-minisblack-32_msb_deflate_predictor.tiff @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:630e7f46655b6e61c4de7d56946a3a9225db68f776f9062ff2d5372547cc7c02 +size 12704 diff --git a/tests/Images/Input/Tiff/flower-minisblack-float32_lsb.tiff b/tests/Images/Input/Tiff/flower-minisblack-float32_lsb.tiff new file mode 100644 index 000000000..8e94faea0 --- /dev/null +++ b/tests/Images/Input/Tiff/flower-minisblack-float32_lsb.tiff @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:af82e07e6298082c91d60a97acb29b67ecabf386bc14371fcb698b248cfd3b40 +size 12814 diff --git a/tests/Images/Input/Tiff/flower-minisblack-float32_msb.tiff b/tests/Images/Input/Tiff/flower-minisblack-float32_msb.tiff new file mode 100644 index 000000000..464074c15 --- /dev/null +++ b/tests/Images/Input/Tiff/flower-minisblack-float32_msb.tiff @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5c918b8aa9968c03c12d85b3bcacd35ae57663a19f5490fc1c351521ed835f30 +size 12814 diff --git a/tests/Images/Input/Tiff/flower-miniswhite-16_lsb.tiff b/tests/Images/Input/Tiff/flower-miniswhite-16_lsb.tiff new file mode 100644 index 000000000..ec9ceb184 --- /dev/null +++ b/tests/Images/Input/Tiff/flower-miniswhite-16_lsb.tiff @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:435c92b453587e1943940111b66afabf70307beb0e1d65e9701fd9bb753eead2 +size 6588 diff --git a/tests/Images/Input/Tiff/flower-miniswhite-16_msb.tiff b/tests/Images/Input/Tiff/flower-miniswhite-16_msb.tiff new file mode 100644 index 000000000..83266873c --- /dev/null +++ b/tests/Images/Input/Tiff/flower-miniswhite-16_msb.tiff @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d8f2c2afd8f1645717087bd2edbc3e8a46b88a54a4996c0e9350fdd652b5c382 +size 6588 diff --git a/tests/Images/Input/Tiff/flower-miniswhite-32_lsb.tiff b/tests/Images/Input/Tiff/flower-miniswhite-32_lsb.tiff new file mode 100644 index 000000000..d44ae9b91 --- /dev/null +++ b/tests/Images/Input/Tiff/flower-miniswhite-32_lsb.tiff @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:17139bc00d9fe2905fbac9226120d2823ea17a10a39b140970122153ec23265d +size 12778 diff --git a/tests/Images/Input/Tiff/flower-miniswhite-32_msb.tiff b/tests/Images/Input/Tiff/flower-miniswhite-32_msb.tiff new file mode 100644 index 000000000..d44ae9b91 --- /dev/null +++ b/tests/Images/Input/Tiff/flower-miniswhite-32_msb.tiff @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:17139bc00d9fe2905fbac9226120d2823ea17a10a39b140970122153ec23265d +size 12778 diff --git a/tests/Images/Input/Tiff/flower-miniswhite-float32_lsb.tiff b/tests/Images/Input/Tiff/flower-miniswhite-float32_lsb.tiff new file mode 100644 index 000000000..3241c8fbe --- /dev/null +++ b/tests/Images/Input/Tiff/flower-miniswhite-float32_lsb.tiff @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:93e06533486f15e33f2435d081713fbecc3ba96c842058b7ba3a5d9116fe5f5c +size 12814 diff --git a/tests/Images/Input/Tiff/flower-miniswhite-float32_msb.tiff b/tests/Images/Input/Tiff/flower-miniswhite-float32_msb.tiff new file mode 100644 index 000000000..5623a7428 --- /dev/null +++ b/tests/Images/Input/Tiff/flower-miniswhite-float32_msb.tiff @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:800a101f4d23fa2a499fcef036ebfca7d9338ac71b06a32ad05e7eb1905ddae3 +size 12814 diff --git a/tests/Images/Input/Tiff/flower-rgb-contig-08.tiff b/tests/Images/Input/Tiff/flower-rgb-contig-08.tiff new file mode 100644 index 000000000..53e890e3c --- /dev/null +++ b/tests/Images/Input/Tiff/flower-rgb-contig-08.tiff @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dd1333eb93d8e7ea614b755ca1c8909c67b4b44fc03a8cab6be5491bf4d15841 +size 9753 diff --git a/tests/Images/Input/Tiff/flower-rgb-contig-16_lsb.tiff b/tests/Images/Input/Tiff/flower-rgb-contig-16_lsb.tiff new file mode 100644 index 000000000..967d8bbf3 --- /dev/null +++ b/tests/Images/Input/Tiff/flower-rgb-contig-16_lsb.tiff @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0951a9c2207eb6864b6a19ec8513a28a874adddb37c3c06b9fd07831372924e3 +size 19150 diff --git a/tests/Images/Input/Tiff/flower-rgb-contig-16_lsb_zip_predictor.tiff b/tests/Images/Input/Tiff/flower-rgb-contig-16_lsb_zip_predictor.tiff new file mode 100644 index 000000000..69fe133f8 --- /dev/null +++ b/tests/Images/Input/Tiff/flower-rgb-contig-16_lsb_zip_predictor.tiff @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:eb465c21009def345d192319ba13ba2e1e537310eec3ab2cce680f0d111a4f18 +size 18256 diff --git a/tests/Images/Input/Tiff/flower-rgb-contig-16_msb_zip_predictor.tiff b/tests/Images/Input/Tiff/flower-rgb-contig-16_msb_zip_predictor.tiff new file mode 100644 index 000000000..231de2eaa --- /dev/null +++ b/tests/Images/Input/Tiff/flower-rgb-contig-16_msb_zip_predictor.tiff @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c098beb9c8f250e9d4f6eb66a3a42f3852ad3ca86aabbdbacfa897d93ec8bc0d +size 18254 diff --git a/tests/Images/Input/Tiff/flower-rgb-contig-24.tiff b/tests/Images/Input/Tiff/flower-rgb-contig-24.tiff new file mode 100644 index 000000000..9145c21db --- /dev/null +++ b/tests/Images/Input/Tiff/flower-rgb-contig-24.tiff @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c6368a704b0a629239024f6fbfb30723fa317593ef36ddba05d76302530bd974 +size 28568 diff --git a/tests/Images/Input/Tiff/flower-rgb-contig-24_lsb.tiff b/tests/Images/Input/Tiff/flower-rgb-contig-24_lsb.tiff new file mode 100644 index 000000000..40cf1c9b8 --- /dev/null +++ b/tests/Images/Input/Tiff/flower-rgb-contig-24_lsb.tiff @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bbb2b4ca6d7eeee4737c6963c99ef68fb6971cf6ccee463427a8246574bc6440 +size 28632 diff --git a/tests/Images/Input/Tiff/flower-rgb-contig-32.tiff b/tests/Images/Input/Tiff/flower-rgb-contig-32.tiff new file mode 100644 index 000000000..28461d8d8 --- /dev/null +++ b/tests/Images/Input/Tiff/flower-rgb-contig-32.tiff @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d7b9da8ec44da84fc89aed1ad221a5eb130a1f233a1ff8a4a15b41898a0e364f +size 38027 diff --git a/tests/Images/Input/Tiff/flower-rgb-contig-32_lsb.tiff b/tests/Images/Input/Tiff/flower-rgb-contig-32_lsb.tiff new file mode 100644 index 000000000..c602b5c4a --- /dev/null +++ b/tests/Images/Input/Tiff/flower-rgb-contig-32_lsb.tiff @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0876580f9c5d8e13656210582137104daba137c99d55eafb5ebbfa418efa6525 +size 38027 diff --git a/tests/Images/Input/Tiff/flower-rgb-contig-32_lsb_zip_predictor.tiff b/tests/Images/Input/Tiff/flower-rgb-contig-32_lsb_zip_predictor.tiff new file mode 100644 index 000000000..ca3fee9da --- /dev/null +++ b/tests/Images/Input/Tiff/flower-rgb-contig-32_lsb_zip_predictor.tiff @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3ed60ad91ea70db01789f9dd37745d8a5ab86f72b98637cf2007b4e28a71976f +size 37632 diff --git a/tests/Images/Input/Tiff/flower-rgb-contig-32_msb_zip_predictor.tiff b/tests/Images/Input/Tiff/flower-rgb-contig-32_msb_zip_predictor.tiff new file mode 100644 index 000000000..07a1ae74f --- /dev/null +++ b/tests/Images/Input/Tiff/flower-rgb-contig-32_msb_zip_predictor.tiff @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1086c2ec568c5c3c2b08fcc66691fab017eb6fad109373a1dadd2e12fae86bc8 +size 37630 diff --git a/tests/Images/Input/Tiff/flower-rgb-float32_lsb.tiff b/tests/Images/Input/Tiff/flower-rgb-float32_lsb.tiff new file mode 100644 index 000000000..da0f10438 --- /dev/null +++ b/tests/Images/Input/Tiff/flower-rgb-float32_lsb.tiff @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a1f889baa6f3bb99f15609848cdd47d548d3e2ed1b7b558d428550dfa3bd4bf9 +size 38050 diff --git a/tests/Images/Input/Tiff/flower-rgb-float32_msb.tiff b/tests/Images/Input/Tiff/flower-rgb-float32_msb.tiff new file mode 100644 index 000000000..353771db9 --- /dev/null +++ b/tests/Images/Input/Tiff/flower-rgb-float32_msb.tiff @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2c02be5dff2bcd5d60afbf379ba9095b0c8fd3a7a0063f684ac9ac9119f967a5 +size 38050 diff --git a/tests/Images/Input/Tiff/flower-rgb-planar-08-15strips.tiff b/tests/Images/Input/Tiff/flower-rgb-planar-08-15strips.tiff new file mode 100644 index 000000000..1a8deed21 --- /dev/null +++ b/tests/Images/Input/Tiff/flower-rgb-planar-08-15strips.tiff @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a49cf47fdf2ea43e5cb5a473523e50222fb13ff6a66bda2e4bdd5796f66140d8 +size 9770 diff --git a/tests/Images/Input/Tiff/flower-rgb-planar-08-6strips.tiff b/tests/Images/Input/Tiff/flower-rgb-planar-08-6strips.tiff new file mode 100644 index 000000000..1a8deed21 --- /dev/null +++ b/tests/Images/Input/Tiff/flower-rgb-planar-08-6strips.tiff @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a49cf47fdf2ea43e5cb5a473523e50222fb13ff6a66bda2e4bdd5796f66140d8 +size 9770 diff --git a/tests/Images/Input/Tiff/flower-rgb-planar-16_lsb.tiff b/tests/Images/Input/Tiff/flower-rgb-planar-16_lsb.tiff new file mode 100644 index 000000000..425ea42ef --- /dev/null +++ b/tests/Images/Input/Tiff/flower-rgb-planar-16_lsb.tiff @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:46a60552a7ff37f2c16c43e030e7180872af712f5d9c9c7673e2547049af3da9 +size 19168 diff --git a/tests/Images/Input/Tiff/flower-rgb-planar-24.tiff b/tests/Images/Input/Tiff/flower-rgb-planar-24.tiff new file mode 100644 index 000000000..b0b41901c --- /dev/null +++ b/tests/Images/Input/Tiff/flower-rgb-planar-24.tiff @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:752452ac51ad1e836fb81267ab708ff81cf81a4c7e00daeed703f67782b563ec +size 28586 diff --git a/tests/Images/Input/Tiff/flower-rgb-planar-24_lsb.tiff b/tests/Images/Input/Tiff/flower-rgb-planar-24_lsb.tiff new file mode 100644 index 000000000..c615089fd --- /dev/null +++ b/tests/Images/Input/Tiff/flower-rgb-planar-24_lsb.tiff @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:72f27af4fe177ebe47bef2af64723497d5a5f44808424bedfc2012fe4e3fc34e +size 28586 diff --git a/tests/Images/Input/Tiff/flower-rgb-planar-32.tiff b/tests/Images/Input/Tiff/flower-rgb-planar-32.tiff new file mode 100644 index 000000000..a84b4ab37 --- /dev/null +++ b/tests/Images/Input/Tiff/flower-rgb-planar-32.tiff @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a718ae37d6d7a5bb5702cc75350f6feec3e9cdcd7e22aaa4753c7fe9c2db9aae +size 38035 diff --git a/tests/Images/Input/Tiff/flower-rgb-planar-32_lsb.tiff b/tests/Images/Input/Tiff/flower-rgb-planar-32_lsb.tiff new file mode 100644 index 000000000..5caa0886e --- /dev/null +++ b/tests/Images/Input/Tiff/flower-rgb-planar-32_lsb.tiff @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2241683d74e9a52c5077870731e7bd5a7e7558c2a04fd0edf57da3a583044442 +size 38035 diff --git a/tests/Images/Input/Tiff/flower-ycbcr-contig-08_h1v1.tiff b/tests/Images/Input/Tiff/flower-ycbcr-contig-08_h1v1.tiff new file mode 100644 index 000000000..bc7f2178b --- /dev/null +++ b/tests/Images/Input/Tiff/flower-ycbcr-contig-08_h1v1.tiff @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:95f7b71c3a333734f799d73076032e31a6dfff1802bb3b454ba1eada7be50b0d +size 10058 diff --git a/tests/Images/Input/Tiff/flower-ycbcr-contig-08_h2v1.tiff b/tests/Images/Input/Tiff/flower-ycbcr-contig-08_h2v1.tiff new file mode 100644 index 000000000..f5133b9f3 --- /dev/null +++ b/tests/Images/Input/Tiff/flower-ycbcr-contig-08_h2v1.tiff @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:270e0331818a755f5fac600172eacbcbebda86f93f521bfc8d75f4b8bc530177 +size 6944 diff --git a/tests/Images/Input/Tiff/flower-ycbcr-contig-08_h2v2.tiff b/tests/Images/Input/Tiff/flower-ycbcr-contig-08_h2v2.tiff new file mode 100644 index 000000000..98fb13d66 --- /dev/null +++ b/tests/Images/Input/Tiff/flower-ycbcr-contig-08_h2v2.tiff @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7ef6ebc9dfe72fbe6ed65ebfc2465ebb18f326119a640faf3301aa4cfa31990f +size 5464 diff --git a/tests/Images/Input/Tiff/flower-ycbcr-contig-08_h4v4.tiff b/tests/Images/Input/Tiff/flower-ycbcr-contig-08_h4v4.tiff new file mode 100644 index 000000000..79aace2a3 --- /dev/null +++ b/tests/Images/Input/Tiff/flower-ycbcr-contig-08_h4v4.tiff @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c5ea966cc7b823a5d228b49cdc55a261353f73b1eb94a218f1c68321d757e25f +size 4342 diff --git a/tests/Images/Input/Tiff/flower-ycbcr-planar-08_h1v1.tiff b/tests/Images/Input/Tiff/flower-ycbcr-planar-08_h1v1.tiff new file mode 100644 index 000000000..4506ff3e9 --- /dev/null +++ b/tests/Images/Input/Tiff/flower-ycbcr-planar-08_h1v1.tiff @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cdc4d8033214a6737f41c4e32d9314db77b3b1ae14515496f10468047390f6c5 +size 10042 diff --git a/tests/Images/Input/Tiff/g3test.tiff b/tests/Images/Input/Tiff/g3test.tiff new file mode 100644 index 000000000..62207de3a --- /dev/null +++ b/tests/Images/Input/Tiff/g3test.tiff @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d5b2e1a17338133aa95cb8a16d82a171f5b50f7b9ae1a51ab06227dc3daa81d5 +size 50401 diff --git a/tests/Images/Input/Tiff/rgb-ycbcr-contig-08_h1v1.tiff b/tests/Images/Input/Tiff/rgb-ycbcr-contig-08_h1v1.tiff new file mode 100644 index 000000000..801cab574 --- /dev/null +++ b/tests/Images/Input/Tiff/rgb-ycbcr-contig-08_h1v1.tiff @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:389ee18596cd3d9f1f7f04b4db8fd21edce2900837c17ebb57cc4b64a6820f3e +size 120354 diff --git a/tests/Images/Input/Tiff/rgb-ycbcr-contig-08_h2v1.tiff b/tests/Images/Input/Tiff/rgb-ycbcr-contig-08_h2v1.tiff new file mode 100644 index 000000000..82350e5b2 --- /dev/null +++ b/tests/Images/Input/Tiff/rgb-ycbcr-contig-08_h2v1.tiff @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:95b1ba4ff48ea2263041eca4ada44d009277297bb3b3a185d48580bdf3f7caaf +size 81382 diff --git a/tests/Images/Input/Tiff/rgb-ycbcr-contig-08_h2v2.tiff b/tests/Images/Input/Tiff/rgb-ycbcr-contig-08_h2v2.tiff new file mode 100644 index 000000000..b282b1742 --- /dev/null +++ b/tests/Images/Input/Tiff/rgb-ycbcr-contig-08_h2v2.tiff @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fbd835c2406700523b239b80299b2b02c36d41182ac338f7ed7164979a787c60 +size 63438 diff --git a/tests/Images/Input/Tiff/rgb-ycbcr-contig-08_h4v2.tiff b/tests/Images/Input/Tiff/rgb-ycbcr-contig-08_h4v2.tiff new file mode 100644 index 000000000..0c8c048dc --- /dev/null +++ b/tests/Images/Input/Tiff/rgb-ycbcr-contig-08_h4v2.tiff @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:399d5bc062baa00c2054a138489709379032f8683fbcb292bb2125b62e715b5f +size 50336 diff --git a/tests/Images/Input/Tiff/rgb-ycbcr-contig-08_h4v4.tiff b/tests/Images/Input/Tiff/rgb-ycbcr-contig-08_h4v4.tiff new file mode 100644 index 000000000..45341ed26 --- /dev/null +++ b/tests/Images/Input/Tiff/rgb-ycbcr-contig-08_h4v4.tiff @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:58c4914b32b27df1ef303bb127fe9211c2aeda23e17bb5f4b349543c96d845b7 +size 45152 diff --git a/tests/Images/Input/Tiff/rgb_jpegcompressed_nojpegtable.tiff b/tests/Images/Input/Tiff/rgb_jpegcompressed_nojpegtable.tiff new file mode 100644 index 000000000..b97ab8830 --- /dev/null +++ b/tests/Images/Input/Tiff/rgb_jpegcompressed_nojpegtable.tiff @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6b81013d7b0a29ed1ac9c33e175e0c0e69494b93b2b65b692f16d9ea042b9d5d +size 7759 diff --git a/tests/Images/Input/Tiff/rgb_jpegcompressed_stripped.tiff b/tests/Images/Input/Tiff/rgb_jpegcompressed_stripped.tiff new file mode 100644 index 000000000..2d43f9778 --- /dev/null +++ b/tests/Images/Input/Tiff/rgb_jpegcompressed_stripped.tiff @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1f027d8c2ab0b244f04e51b9bf724eac0123e104a2446324496a08bdf5881922 +size 10550 diff --git a/tests/Images/Input/Tiff/rgb_jpeg.tiff b/tests/Images/Input/Tiff/rgb_jpegcompression.tiff similarity index 100% rename from tests/Images/Input/Tiff/rgb_jpeg.tiff rename to tests/Images/Input/Tiff/rgb_jpegcompression.tiff diff --git a/tests/Images/Input/Tiff/ycbcr_jpegcompressed.tiff b/tests/Images/Input/Tiff/ycbcr_jpegcompressed.tiff new file mode 100644 index 000000000..18334be2a --- /dev/null +++ b/tests/Images/Input/Tiff/ycbcr_jpegcompressed.tiff @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:27fa1d37cd62a9cf105a5e3e015e6a16a13ca7fa82f927a73d32847046c66073 +size 6136 diff --git a/tests/Images/Input/Webp/1602311202.webp b/tests/Images/Input/Webp/1602311202.webp new file mode 100644 index 000000000..4dfd0184f --- /dev/null +++ b/tests/Images/Input/Webp/1602311202.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4dac76bec0e5b23a988b0f2221e9b20e63dc207ef48f33e49a4336a874e2a915 +size 18406 diff --git a/tests/Images/Input/Webp/alpha_color_cache.webp b/tests/Images/Input/Webp/alpha_color_cache.webp new file mode 100644 index 000000000..ec5d7540e --- /dev/null +++ b/tests/Images/Input/Webp/alpha_color_cache.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c4b9e2459858e6f6a1d919c2adeb73d7e2ad251d6bfbfb99303a6b4508ca757a +size 1838 diff --git a/tests/Images/Input/Webp/alpha_filter_0_method_0.webp b/tests/Images/Input/Webp/alpha_filter_0_method_0.webp new file mode 100644 index 000000000..d85e800dc --- /dev/null +++ b/tests/Images/Input/Webp/alpha_filter_0_method_0.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:150ff79f16e254281153d7e75e5968663c7f83ae58217b36c12d11088045eb07 +size 22038 diff --git a/tests/Images/Input/Webp/alpha_filter_0_method_1.webp b/tests/Images/Input/Webp/alpha_filter_0_method_1.webp new file mode 100644 index 000000000..56318eca9 --- /dev/null +++ b/tests/Images/Input/Webp/alpha_filter_0_method_1.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:96f514bce6faa65330eba17c06eb1cf120ba8c133288ab2633afa63d7c6c66ad +size 12162 diff --git a/tests/Images/Input/Webp/alpha_filter_1.webp b/tests/Images/Input/Webp/alpha_filter_1.webp new file mode 100644 index 000000000..216f2eef6 --- /dev/null +++ b/tests/Images/Input/Webp/alpha_filter_1.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:53ad8a7038fed7bdfa90db1c1f987782a9f46903aaccd5ad04dd78d067632fba +size 114 diff --git a/tests/Images/Input/Webp/alpha_filter_1_method_0.webp b/tests/Images/Input/Webp/alpha_filter_1_method_0.webp new file mode 100644 index 000000000..94a605e13 --- /dev/null +++ b/tests/Images/Input/Webp/alpha_filter_1_method_0.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4dc2d060c723aa0a855bc696191d220a60a36bad014cda9764ee93516fa9f073 +size 22038 diff --git a/tests/Images/Input/Webp/alpha_filter_1_method_1.webp b/tests/Images/Input/Webp/alpha_filter_1_method_1.webp new file mode 100644 index 000000000..a3f0cd93e --- /dev/null +++ b/tests/Images/Input/Webp/alpha_filter_1_method_1.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:79000c9c553f28e4ea589e772dd46a47a604f961050ca191a84a03d92d212eb8 +size 15592 diff --git a/tests/Images/Input/Webp/alpha_filter_2.webp b/tests/Images/Input/Webp/alpha_filter_2.webp new file mode 100644 index 000000000..d38845444 --- /dev/null +++ b/tests/Images/Input/Webp/alpha_filter_2.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0a1eba20a9ba6a09735c2424d31e26c9282be64a0d7795dd689a42c4921d436b +size 114 diff --git a/tests/Images/Input/Webp/alpha_filter_2_method_0.webp b/tests/Images/Input/Webp/alpha_filter_2_method_0.webp new file mode 100644 index 000000000..e5429119f --- /dev/null +++ b/tests/Images/Input/Webp/alpha_filter_2_method_0.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3d169bfee11e65f1b5870142531d1e35539e2686640d19fa196b36a5b7b33a45 +size 22038 diff --git a/tests/Images/Input/Webp/alpha_filter_2_method_1.webp b/tests/Images/Input/Webp/alpha_filter_2_method_1.webp new file mode 100644 index 000000000..e7bffc1db --- /dev/null +++ b/tests/Images/Input/Webp/alpha_filter_2_method_1.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:16ce80b417c8d5d95d895e3a50be00247262a3ab5700e2a22a408f5042884042 +size 15604 diff --git a/tests/Images/Input/Webp/alpha_filter_3.webp b/tests/Images/Input/Webp/alpha_filter_3.webp new file mode 100644 index 000000000..b75c44759 --- /dev/null +++ b/tests/Images/Input/Webp/alpha_filter_3.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4052952ea401afa934b2d262f2852f615160c7cb82c4406c47622d26b343e95e +size 118 diff --git a/tests/Images/Input/Webp/alpha_filter_3_method_0.webp b/tests/Images/Input/Webp/alpha_filter_3_method_0.webp new file mode 100644 index 000000000..ca0baef06 --- /dev/null +++ b/tests/Images/Input/Webp/alpha_filter_3_method_0.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:79c7f73faec6a9b0f7ec5d274a3dd10a7eb002ebab114122a49f9794c5b8541a +size 22038 diff --git a/tests/Images/Input/Webp/alpha_filter_3_method_1.webp b/tests/Images/Input/Webp/alpha_filter_3_method_1.webp new file mode 100644 index 000000000..414723d96 --- /dev/null +++ b/tests/Images/Input/Webp/alpha_filter_3_method_1.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e11b944fd8aa2e5f90c7bea05527a94e919492bef0bc464bac1493e00724ae01 +size 18266 diff --git a/tests/Images/Input/Webp/alpha_no_compression.webp b/tests/Images/Input/Webp/alpha_no_compression.webp new file mode 100644 index 000000000..a7d058e89 --- /dev/null +++ b/tests/Images/Input/Webp/alpha_no_compression.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:864de77c2209a8346004f8fe5595ffb35cfaacb71f385cc8487236689056df7d +size 336 diff --git a/tests/Images/Input/Webp/animated-webp.webp b/tests/Images/Input/Webp/animated-webp.webp new file mode 100644 index 000000000..d221bc0ca --- /dev/null +++ b/tests/Images/Input/Webp/animated-webp.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cf633cfad0fba9b53ef84f0319db15537868bbe75c7b3cd0f31add9c0d25addf +size 37341 diff --git a/tests/Images/Input/Webp/animated2.webp b/tests/Images/Input/Webp/animated2.webp new file mode 100644 index 000000000..aa08cae87 --- /dev/null +++ b/tests/Images/Input/Webp/animated2.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b17cfa1c0f484f1fc03f16d07684831585125817e5c7fb2c12cfed3d6ad863a8 +size 11840 diff --git a/tests/Images/Input/Webp/animated3.webp b/tests/Images/Input/Webp/animated3.webp new file mode 100644 index 000000000..98d4c4114 --- /dev/null +++ b/tests/Images/Input/Webp/animated3.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:68ba327459ac40a7a054dc5d8b237d3ce0154524854a4f2334e3b839524d13a9 +size 41063 diff --git a/tests/Images/Input/Webp/animated_lossy.webp b/tests/Images/Input/Webp/animated_lossy.webp new file mode 100644 index 000000000..654c2d03f --- /dev/null +++ b/tests/Images/Input/Webp/animated_lossy.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:54957c3daa3ab0bf258c00b170fcfc0578d909acd5dfc870b752688b9b64e406 +size 73772 diff --git a/tests/Images/Input/Webp/bad_palette_index.webp b/tests/Images/Input/Webp/bad_palette_index.webp new file mode 100644 index 000000000..dd8e7fd3f --- /dev/null +++ b/tests/Images/Input/Webp/bad_palette_index.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8540997edf54f030201f7354f52438dd04bf248fb21a72b71a93095fc681fb5e +size 9682 diff --git a/tests/Images/Input/Webp/big_endian_bug_393.webp b/tests/Images/Input/Webp/big_endian_bug_393.webp new file mode 100644 index 000000000..ae0c85b42 --- /dev/null +++ b/tests/Images/Input/Webp/big_endian_bug_393.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4f2359f5425d78dbe16665d9e15cb56b84559eff527ab316c509a5dd1708c126 +size 16313 diff --git a/tests/Images/Input/Webp/bike_lossless.webp b/tests/Images/Input/Webp/bike_lossless.webp new file mode 100644 index 000000000..a311c5af1 --- /dev/null +++ b/tests/Images/Input/Webp/bike_lossless.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5a552b43d45c77ece0ab4331f054fb183725420748656d47a49c5b672e42f4f9 +size 61782 diff --git a/tests/Images/Input/Webp/bike_lossless_small.webp b/tests/Images/Input/Webp/bike_lossless_small.webp new file mode 100644 index 000000000..661129451 --- /dev/null +++ b/tests/Images/Input/Webp/bike_lossless_small.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d0cff46a5bbc4903e8e372ee79e988942c101a6cc6642658cb92a9f377443dca +size 2598 diff --git a/tests/Images/Input/Webp/bike_lossy.webp b/tests/Images/Input/Webp/bike_lossy.webp new file mode 100644 index 000000000..a9e2fc6a8 --- /dev/null +++ b/tests/Images/Input/Webp/bike_lossy.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9f93883b8ba4ebc9c048c598b9294736baddfa756c4884e85f0d3b8e7f9d996c +size 39244 diff --git a/tests/Images/Input/Webp/bike_lossy_complex_filter.webp b/tests/Images/Input/Webp/bike_lossy_complex_filter.webp new file mode 100644 index 000000000..73eabf363 --- /dev/null +++ b/tests/Images/Input/Webp/bike_lossy_complex_filter.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:21612476f2d7668f773ce286af1a2a4c33da8718352c5a5c1dd839a4643de823 +size 9396 diff --git a/tests/Images/Input/Webp/bryce.webp b/tests/Images/Input/Webp/bryce.webp new file mode 100644 index 000000000..763ac2428 --- /dev/null +++ b/tests/Images/Input/Webp/bryce.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d6ba1142638a7ae9df901bb7fc8e3a9e6afbe0ec8320fd28e35308a57a2e3e4f +size 3533772 diff --git a/tests/Images/Input/Webp/bug3.webp b/tests/Images/Input/Webp/bug3.webp new file mode 100644 index 000000000..97ae77e91 --- /dev/null +++ b/tests/Images/Input/Webp/bug3.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:37d98a0b3e2132f7b5bbc03935a88a8659735c61268d8ce6acdfccfa574f4166 +size 954 diff --git a/tests/Images/Input/Webp/color_cache_bits_11.webp b/tests/Images/Input/Webp/color_cache_bits_11.webp new file mode 100644 index 000000000..29a7f190f --- /dev/null +++ b/tests/Images/Input/Webp/color_cache_bits_11.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a19dde0c51ce4c83d9bc05ea3b8f3cfed9cfac7ca19dcb23d85c56e465242350 +size 15822 diff --git a/tests/Images/Input/Webp/earth_lossless.webp b/tests/Images/Input/Webp/earth_lossless.webp new file mode 100644 index 000000000..1abcb8668 --- /dev/null +++ b/tests/Images/Input/Webp/earth_lossless.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:35e61613388342baac7f39a4a3c3ae32587a065505269115a134592eee9563b8 +size 7813062 diff --git a/tests/Images/Input/Webp/earth_lossy.webp b/tests/Images/Input/Webp/earth_lossy.webp new file mode 100644 index 000000000..790a194de --- /dev/null +++ b/tests/Images/Input/Webp/earth_lossy.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c45c068709fa3f878564d399e539636b9e42926291dde683adb7bb5d98c2c680 +size 467258 diff --git a/tests/Images/Input/Webp/exif_lossless.webp b/tests/Images/Input/Webp/exif_lossless.webp new file mode 100644 index 000000000..a3eeae555 --- /dev/null +++ b/tests/Images/Input/Webp/exif_lossless.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:21de077dd545c182a36584955918a70643ae2b972b208234f548d95ef8535a3e +size 183286 diff --git a/tests/Images/Input/Webp/exif_lossy.webp b/tests/Images/Input/Webp/exif_lossy.webp new file mode 100644 index 000000000..35e454b96 --- /dev/null +++ b/tests/Images/Input/Webp/exif_lossy.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fdf4e9b20af4168f4177d33f7f502906343bbaaae2af9b90e1531bd4452b317b +size 40765 diff --git a/tests/Images/Input/Webp/flag_of_germany.png b/tests/Images/Input/Webp/flag_of_germany.png new file mode 100644 index 000000000..f6a4438fb --- /dev/null +++ b/tests/Images/Input/Webp/flag_of_germany.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:26bf39cea75210c9132eec4567f1f63c870b1eec3b541cfc25da7b5095902f41 +size 72315 diff --git a/tests/Images/Input/Webp/issues/Issue1594.webp b/tests/Images/Input/Webp/issues/Issue1594.webp new file mode 100644 index 000000000..664db4e2f --- /dev/null +++ b/tests/Images/Input/Webp/issues/Issue1594.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:37413b1a89ba7d42cdfe98196775c2ddc2f8f4d143f6fc65218dc288423b7177 +size 62 diff --git a/tests/Images/Input/Webp/lossless1.webp b/tests/Images/Input/Webp/lossless1.webp new file mode 100644 index 000000000..1d561f9ad --- /dev/null +++ b/tests/Images/Input/Webp/lossless1.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5eaf3d3e7f7a38487afa8d3f91062167eb061cd6a5dfa455d24a9a2004860311 +size 15368 diff --git a/tests/Images/Input/Webp/lossless2.webp b/tests/Images/Input/Webp/lossless2.webp new file mode 100644 index 000000000..1c975384f --- /dev/null +++ b/tests/Images/Input/Webp/lossless2.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5131b5d7c0ba6bd7d6e6f74a325e0ffa2d388197b5132ed46a5c36ea8453cb22 +size 15898 diff --git a/tests/Images/Input/Webp/lossless3.webp b/tests/Images/Input/Webp/lossless3.webp new file mode 100644 index 000000000..34bc7919f --- /dev/null +++ b/tests/Images/Input/Webp/lossless3.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2bcca2ea2a1a43d19c839528e9b831519e0a6875e4c9a2ce8bb9c34bb85ece3a +size 15734 diff --git a/tests/Images/Input/Webp/lossless4.webp b/tests/Images/Input/Webp/lossless4.webp new file mode 100644 index 000000000..5c46787d1 --- /dev/null +++ b/tests/Images/Input/Webp/lossless4.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a96cc5243569ada325efadb3a6c78816b4a015a73283a400c5cc94893584901f +size 4332 diff --git a/tests/Images/Input/Webp/lossless_alpha_small.webp b/tests/Images/Input/Webp/lossless_alpha_small.webp new file mode 100644 index 000000000..304080f93 --- /dev/null +++ b/tests/Images/Input/Webp/lossless_alpha_small.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d078eb784835863f12ef25d9c1c135e79c2495532cec08da6f19c2e27c0cacee +size 1638 diff --git a/tests/Images/Input/Webp/lossless_big_random_alpha.webp b/tests/Images/Input/Webp/lossless_big_random_alpha.webp new file mode 100644 index 000000000..a2baaf1a3 --- /dev/null +++ b/tests/Images/Input/Webp/lossless_big_random_alpha.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:40928dc5a6ca61e7008d212e66b24f5e62f43d5fe55f23add9843414168cbaa6 +size 13968249 diff --git a/tests/Images/Input/Webp/lossless_color_transform.webp b/tests/Images/Input/Webp/lossless_color_transform.webp new file mode 100644 index 000000000..89276eae4 --- /dev/null +++ b/tests/Images/Input/Webp/lossless_color_transform.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5b9557b7f3798bb9b511f2edad5dad330d7346f5f13440a70627488f9a53ec81 +size 163807 diff --git a/tests/Images/Input/Webp/lossless_vec_1_0.webp b/tests/Images/Input/Webp/lossless_vec_1_0.webp new file mode 100644 index 000000000..ea5faa2d2 --- /dev/null +++ b/tests/Images/Input/Webp/lossless_vec_1_0.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:011089057caf7e11c9a59d3ec2b3448ea56d83545622e313f8584a22c322bc90 +size 50 diff --git a/tests/Images/Input/Webp/lossless_vec_1_1.webp b/tests/Images/Input/Webp/lossless_vec_1_1.webp new file mode 100644 index 000000000..6cdad61d0 --- /dev/null +++ b/tests/Images/Input/Webp/lossless_vec_1_1.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:482c1304367ede7a4b2e43e14aefced318c075e82e466473720d3bdabc0526fc +size 106 diff --git a/tests/Images/Input/Webp/lossless_vec_1_10.webp b/tests/Images/Input/Webp/lossless_vec_1_10.webp new file mode 100644 index 000000000..39475bf46 --- /dev/null +++ b/tests/Images/Input/Webp/lossless_vec_1_10.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f91a575ba29729357a612eb511a9ebab725c2d34a6a6eaaf6b6a16cee3ba25a2 +size 80 diff --git a/tests/Images/Input/Webp/lossless_vec_1_11.webp b/tests/Images/Input/Webp/lossless_vec_1_11.webp new file mode 100644 index 000000000..d516737cd --- /dev/null +++ b/tests/Images/Input/Webp/lossless_vec_1_11.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e598e8d2aef6a562a80c3fc9cb7cc6fdd979e210c26ed3a4defbdf895ae1c1cc +size 132 diff --git a/tests/Images/Input/Webp/lossless_vec_1_12.webp b/tests/Images/Input/Webp/lossless_vec_1_12.webp new file mode 100644 index 000000000..6f8ed9551 --- /dev/null +++ b/tests/Images/Input/Webp/lossless_vec_1_12.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:45fa843b9d374e1949f58e9d0d2a2ecf97d4a9cc2af55dfa3ef488d846ea3c80 +size 56 diff --git a/tests/Images/Input/Webp/lossless_vec_1_13.webp b/tests/Images/Input/Webp/lossless_vec_1_13.webp new file mode 100644 index 000000000..2e2bb6dcd --- /dev/null +++ b/tests/Images/Input/Webp/lossless_vec_1_13.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:04a9d1c2e8b43224f5d12623e4a085be1e1c5dda716bfd108202c64b1d796179 +size 114 diff --git a/tests/Images/Input/Webp/lossless_vec_1_14.webp b/tests/Images/Input/Webp/lossless_vec_1_14.webp new file mode 100644 index 000000000..55b0f3b10 --- /dev/null +++ b/tests/Images/Input/Webp/lossless_vec_1_14.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a8b8130c71e6958fd7eab9539f431125a35075cf0c38fc7ebb1316aa0a4d1946 +size 78 diff --git a/tests/Images/Input/Webp/lossless_vec_1_15.webp b/tests/Images/Input/Webp/lossless_vec_1_15.webp new file mode 100644 index 000000000..13f3ff7b2 --- /dev/null +++ b/tests/Images/Input/Webp/lossless_vec_1_15.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f06eaa2e3fdc11235d9b9c14485e6e5a83f4f4de10caf05a70c0fdfc253c7a67 +size 130 diff --git a/tests/Images/Input/Webp/lossless_vec_1_2.webp b/tests/Images/Input/Webp/lossless_vec_1_2.webp new file mode 100644 index 000000000..8971121c0 --- /dev/null +++ b/tests/Images/Input/Webp/lossless_vec_1_2.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:eed151dabacbad9b99aa5ad47787240f5344d8cd653f2c3842ccc0f95d6ce798 +size 76 diff --git a/tests/Images/Input/Webp/lossless_vec_1_3.webp b/tests/Images/Input/Webp/lossless_vec_1_3.webp new file mode 100644 index 000000000..5060ae091 --- /dev/null +++ b/tests/Images/Input/Webp/lossless_vec_1_3.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:45a32abfcc449acff80249885078ffe56d244d85db7120fdb30f58ae2bf89ac9 +size 132 diff --git a/tests/Images/Input/Webp/lossless_vec_1_4.webp b/tests/Images/Input/Webp/lossless_vec_1_4.webp new file mode 100644 index 000000000..b346c4216 --- /dev/null +++ b/tests/Images/Input/Webp/lossless_vec_1_4.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6021a817ad3e17053de4b170b9ff2c7646ee2ef365b23a5e75bea3159d83023a +size 50 diff --git a/tests/Images/Input/Webp/lossless_vec_1_5.webp b/tests/Images/Input/Webp/lossless_vec_1_5.webp new file mode 100644 index 000000000..f2a2aa0d3 --- /dev/null +++ b/tests/Images/Input/Webp/lossless_vec_1_5.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:673161af330a911bd6a3bc3f0ab266a34eafba139a174372dd20727b8831e7e1 +size 106 diff --git a/tests/Images/Input/Webp/lossless_vec_1_6.webp b/tests/Images/Input/Webp/lossless_vec_1_6.webp new file mode 100644 index 000000000..248bcf6ba --- /dev/null +++ b/tests/Images/Input/Webp/lossless_vec_1_6.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b90db591321b6235cfbf2c4a9083f29459185b84953c7ca02b47da16f82df149 +size 76 diff --git a/tests/Images/Input/Webp/lossless_vec_1_7.webp b/tests/Images/Input/Webp/lossless_vec_1_7.webp new file mode 100644 index 000000000..788e7a33a --- /dev/null +++ b/tests/Images/Input/Webp/lossless_vec_1_7.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:89aaf7749eefb289403ca6bdac93c0b80ac47da498f5064ea9f064994479045e +size 122 diff --git a/tests/Images/Input/Webp/lossless_vec_1_8.webp b/tests/Images/Input/Webp/lossless_vec_1_8.webp new file mode 100644 index 000000000..d55c10e10 --- /dev/null +++ b/tests/Images/Input/Webp/lossless_vec_1_8.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8c255d6803fb2d9fa549322e9eb1ac5641ee091c32a24810310464d207bb73cc +size 56 diff --git a/tests/Images/Input/Webp/lossless_vec_1_9.webp b/tests/Images/Input/Webp/lossless_vec_1_9.webp new file mode 100644 index 000000000..07f0cdb54 --- /dev/null +++ b/tests/Images/Input/Webp/lossless_vec_1_9.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:99e579d9b23ac41a1c6162b6c0585d7cd9a797058f7c89e5a5a245bd159cd1b0 +size 112 diff --git a/tests/Images/Input/Webp/lossless_vec_2_0.webp b/tests/Images/Input/Webp/lossless_vec_2_0.webp new file mode 100644 index 000000000..f338a8642 --- /dev/null +++ b/tests/Images/Input/Webp/lossless_vec_2_0.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b90cb047e529364197e0435122e96be3e105c7e4b21688a56be9532af9a08609 +size 12822 diff --git a/tests/Images/Input/Webp/lossless_vec_2_1.webp b/tests/Images/Input/Webp/lossless_vec_2_1.webp new file mode 100644 index 000000000..007695445 --- /dev/null +++ b/tests/Images/Input/Webp/lossless_vec_2_1.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1ee2154490d6342aff5bbebae8a29aa00ba2aa4630b5c071fe7f45c327e1e56b +size 10672 diff --git a/tests/Images/Input/Webp/lossless_vec_2_10.webp b/tests/Images/Input/Webp/lossless_vec_2_10.webp new file mode 100644 index 000000000..7c5ee058c --- /dev/null +++ b/tests/Images/Input/Webp/lossless_vec_2_10.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8ef60485d13cd7c19d7974707d3c0b00bb8518f653669b992e1de9aea4fdd305 +size 20362 diff --git a/tests/Images/Input/Webp/lossless_vec_2_11.webp b/tests/Images/Input/Webp/lossless_vec_2_11.webp new file mode 100644 index 000000000..e029941fd --- /dev/null +++ b/tests/Images/Input/Webp/lossless_vec_2_11.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:418e017cafcf4bbb09ed95c7ec7d3a08935b3e266b2de2a3b392eb7c0db7e408 +size 10980 diff --git a/tests/Images/Input/Webp/lossless_vec_2_12.webp b/tests/Images/Input/Webp/lossless_vec_2_12.webp new file mode 100644 index 000000000..59d05f33e --- /dev/null +++ b/tests/Images/Input/Webp/lossless_vec_2_12.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0923abbeaf98db4d50d5a857ec4a61ca2cdf90cb9f7819e07e101c4fda574af0 +size 14280 diff --git a/tests/Images/Input/Webp/lossless_vec_2_13.webp b/tests/Images/Input/Webp/lossless_vec_2_13.webp new file mode 100644 index 000000000..5ba8186a4 --- /dev/null +++ b/tests/Images/Input/Webp/lossless_vec_2_13.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:13abcefd4630e562f132040956aa71a66df244e18ea4454bcb58c390aba0e3a7 +size 9818 diff --git a/tests/Images/Input/Webp/lossless_vec_2_14.webp b/tests/Images/Input/Webp/lossless_vec_2_14.webp new file mode 100644 index 000000000..e2ec8c74c --- /dev/null +++ b/tests/Images/Input/Webp/lossless_vec_2_14.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f73aea1e60ae1d702aefd5df65c64920c7a1f7c547ecee1189864c9ecd118c00 +size 20704 diff --git a/tests/Images/Input/Webp/lossless_vec_2_15.webp b/tests/Images/Input/Webp/lossless_vec_2_15.webp new file mode 100644 index 000000000..f3c130168 --- /dev/null +++ b/tests/Images/Input/Webp/lossless_vec_2_15.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6b5cb1bf92525785231986c48f9d668b22166d2ff78b1a1f3fdcae6548c5e24b +size 11438 diff --git a/tests/Images/Input/Webp/lossless_vec_2_2.webp b/tests/Images/Input/Webp/lossless_vec_2_2.webp new file mode 100644 index 000000000..694201b29 --- /dev/null +++ b/tests/Images/Input/Webp/lossless_vec_2_2.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:880f63d6da0647bc1468551a5117b225f84f0e9c6df0cbb7e9cffbebcec159da +size 21444 diff --git a/tests/Images/Input/Webp/lossless_vec_2_3.webp b/tests/Images/Input/Webp/lossless_vec_2_3.webp new file mode 100644 index 000000000..8bb0a902e --- /dev/null +++ b/tests/Images/Input/Webp/lossless_vec_2_3.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:50bbb2e1c3e8fb8ee86beb034a0d0673b6238fa16f83479b38dec90aba4a9019 +size 11432 diff --git a/tests/Images/Input/Webp/lossless_vec_2_4.webp b/tests/Images/Input/Webp/lossless_vec_2_4.webp new file mode 100644 index 000000000..53eb696ff --- /dev/null +++ b/tests/Images/Input/Webp/lossless_vec_2_4.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3ec19bfa2bd9852cc735320dde4fa7047b14aca8281f3fbc1ad5fa3ad8215d6b +size 12491 diff --git a/tests/Images/Input/Webp/lossless_vec_2_5.webp b/tests/Images/Input/Webp/lossless_vec_2_5.webp new file mode 100644 index 000000000..e6f83941f --- /dev/null +++ b/tests/Images/Input/Webp/lossless_vec_2_5.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:09b72c5e236ef7c27a1cc80677e2c63f2b8effd004009de1c62fad88d4ad6559 +size 10294 diff --git a/tests/Images/Input/Webp/lossless_vec_2_6.webp b/tests/Images/Input/Webp/lossless_vec_2_6.webp new file mode 100644 index 000000000..bc17d4ee3 --- /dev/null +++ b/tests/Images/Input/Webp/lossless_vec_2_6.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a6f63102a86ec168f1eeb4ad3bd80fc7c1db0d48b767736591108320b5bed9f8 +size 21922 diff --git a/tests/Images/Input/Webp/lossless_vec_2_7.webp b/tests/Images/Input/Webp/lossless_vec_2_7.webp new file mode 100644 index 000000000..81871bebc --- /dev/null +++ b/tests/Images/Input/Webp/lossless_vec_2_7.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:99353d740c62b60ddc594648f5885380aeb2ebe2acb0feb15a115539c6eebdc1 +size 11211 diff --git a/tests/Images/Input/Webp/lossless_vec_2_8.webp b/tests/Images/Input/Webp/lossless_vec_2_8.webp new file mode 100644 index 000000000..9656571eb --- /dev/null +++ b/tests/Images/Input/Webp/lossless_vec_2_8.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:215ace49899cf63ade891f4ec802ecb9657001c51fbd1a8c2f0880bc4fb2760a +size 12640 diff --git a/tests/Images/Input/Webp/lossless_vec_2_9.webp b/tests/Images/Input/Webp/lossless_vec_2_9.webp new file mode 100644 index 000000000..831be6c32 --- /dev/null +++ b/tests/Images/Input/Webp/lossless_vec_2_9.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:033e7d1034513392a7b527176eeb7fab22568af5c2365dd1f65fdc3ad4c0f270 +size 10304 diff --git a/tests/Images/Input/Webp/lossless_with_iccp.webp b/tests/Images/Input/Webp/lossless_with_iccp.webp new file mode 100644 index 000000000..56897125a --- /dev/null +++ b/tests/Images/Input/Webp/lossless_with_iccp.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:863db3c8970769ec4fc6ab729abbd172a14e3fbb22bc3530d0288761506d751e +size 75858 diff --git a/tests/Images/Input/Webp/lossy_alpha1.webp b/tests/Images/Input/Webp/lossy_alpha1.webp new file mode 100644 index 000000000..9f1e3c2be --- /dev/null +++ b/tests/Images/Input/Webp/lossy_alpha1.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:403dff2d4cffc78607bcd6088fade38ed4a0b26e83b2927b0b1f28c0a826ef1c +size 19478 diff --git a/tests/Images/Input/Webp/lossy_alpha2.webp b/tests/Images/Input/Webp/lossy_alpha2.webp new file mode 100644 index 000000000..a3cbe5c23 --- /dev/null +++ b/tests/Images/Input/Webp/lossy_alpha2.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5f2cd2585d5254903227bd86f367b400861cde62db9337fb74dd98d6123ce06c +size 13566 diff --git a/tests/Images/Input/Webp/lossy_alpha3.webp b/tests/Images/Input/Webp/lossy_alpha3.webp new file mode 100644 index 000000000..f87deec5a --- /dev/null +++ b/tests/Images/Input/Webp/lossy_alpha3.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ca1d20c440c56eb8b1507e2abafe3447a4f4e11f3d4976a0dc1e93df68881126 +size 9960 diff --git a/tests/Images/Input/Webp/lossy_alpha4.webp b/tests/Images/Input/Webp/lossy_alpha4.webp new file mode 100644 index 000000000..82193f4b8 --- /dev/null +++ b/tests/Images/Input/Webp/lossy_alpha4.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2feb221aee944cb273b11cf02c268601d657f6a8def745e4a6b24031650cd701 +size 4262 diff --git a/tests/Images/Input/Webp/lossy_extreme_probabilities.webp b/tests/Images/Input/Webp/lossy_extreme_probabilities.webp new file mode 100644 index 000000000..94110f8fe --- /dev/null +++ b/tests/Images/Input/Webp/lossy_extreme_probabilities.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4bad65a42ed076a8684494c8a11eb8be02da328195228aa635276f90b4523f27 +size 468740 diff --git a/tests/Images/Input/Webp/lossy_q0_f100.webp b/tests/Images/Input/Webp/lossy_q0_f100.webp new file mode 100644 index 000000000..c10e07c2c --- /dev/null +++ b/tests/Images/Input/Webp/lossy_q0_f100.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cf480a1328f5f68b541f80e8af1bf82545f948874dd05aacd355adee2b7ca935 +size 270 diff --git a/tests/Images/Input/Webp/lossy_with_iccp.webp b/tests/Images/Input/Webp/lossy_with_iccp.webp new file mode 100644 index 000000000..2f50e7673 --- /dev/null +++ b/tests/Images/Input/Webp/lossy_with_iccp.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:434cfe308cfcaef8d79f030906fe783df70e568d66df2e906dd98f2ffd5bcc1b +size 63036 diff --git a/tests/Images/Input/Webp/near_lossless_75.webp b/tests/Images/Input/Webp/near_lossless_75.webp new file mode 100644 index 000000000..86c426aa5 --- /dev/null +++ b/tests/Images/Input/Webp/near_lossless_75.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:12e6b033cb2e636224bd787843bc528cfe42f33fd7c1f3814b1f77269b1ec2ab +size 45274 diff --git a/tests/Images/Input/Webp/peak.png b/tests/Images/Input/Webp/peak.png new file mode 100644 index 000000000..5a417b9c0 --- /dev/null +++ b/tests/Images/Input/Webp/peak.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b9b56ed5c1278664222c77f9a452b824b4f9215c819502b3f6b0e0d44270e7e7 +size 26456 diff --git a/tests/Images/Input/Webp/rgb_pattern_100x100.png b/tests/Images/Input/Webp/rgb_pattern_100x100.png new file mode 100644 index 000000000..789424dcb --- /dev/null +++ b/tests/Images/Input/Webp/rgb_pattern_100x100.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:12f39b990367eb09ffbe69eb11bf970b5386e75a02a820e4740e66a079dda527 +size 30225 diff --git a/tests/Images/Input/Webp/rgb_pattern_63x63.png b/tests/Images/Input/Webp/rgb_pattern_63x63.png new file mode 100644 index 000000000..37a6e8812 --- /dev/null +++ b/tests/Images/Input/Webp/rgb_pattern_63x63.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3a7826312b4dabc2d8a89bf84e501ddb0bcc09932c54d2dedb0c96909da94da8 +size 12071 diff --git a/tests/Images/Input/Webp/rgb_pattern_80x80.png b/tests/Images/Input/Webp/rgb_pattern_80x80.png new file mode 100644 index 000000000..d4722cfc1 --- /dev/null +++ b/tests/Images/Input/Webp/rgb_pattern_80x80.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f4e27705d23ff33dbac5bdfe8e7e75a6eeda359ff343594fb07feb29abbc2fb5 +size 19393 diff --git a/tests/Images/Input/Webp/segment01.webp b/tests/Images/Input/Webp/segment01.webp new file mode 100644 index 000000000..0f1da8f91 --- /dev/null +++ b/tests/Images/Input/Webp/segment01.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4236341aa2f02c44ea0e6caa9a6b0c059ac87ca1d490821ce81dbb565732c5d0 +size 7658 diff --git a/tests/Images/Input/Webp/segment02.webp b/tests/Images/Input/Webp/segment02.webp new file mode 100644 index 000000000..94cc9b077 --- /dev/null +++ b/tests/Images/Input/Webp/segment02.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:99ecbb7b2b42128050242e67eb0ae424e09f2a886f9cd862d1cf176fcdf1542b +size 7112 diff --git a/tests/Images/Input/Webp/segment03.webp b/tests/Images/Input/Webp/segment03.webp new file mode 100644 index 000000000..c15e40f8e --- /dev/null +++ b/tests/Images/Input/Webp/segment03.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fbe0d3c0b2d180ea1ed92ea6321667071dea2831991741f9769745947c37ff42 +size 5470 diff --git a/tests/Images/Input/Webp/small_13x1.webp b/tests/Images/Input/Webp/small_13x1.webp new file mode 100644 index 000000000..5707e7e32 --- /dev/null +++ b/tests/Images/Input/Webp/small_13x1.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:29121ecb41cb11a2e0301f20aaa10b971bcf93d711e402fc7e331d01d86b7cf1 +size 106 diff --git a/tests/Images/Input/Webp/small_1x1.webp b/tests/Images/Input/Webp/small_1x1.webp new file mode 100644 index 000000000..77ff63d2b --- /dev/null +++ b/tests/Images/Input/Webp/small_1x1.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2f34799482dd5349b549d113fdaa188714d9737fe414e71541b752627bedbde3 +size 94 diff --git a/tests/Images/Input/Webp/small_1x13.webp b/tests/Images/Input/Webp/small_1x13.webp new file mode 100644 index 000000000..f361421c3 --- /dev/null +++ b/tests/Images/Input/Webp/small_1x13.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:15acf5b0193273afc3cfa4207718b50acd79ffea20cd6a6beab01717d080887a +size 106 diff --git a/tests/Images/Input/Webp/small_31x13.webp b/tests/Images/Input/Webp/small_31x13.webp new file mode 100644 index 000000000..dbb81c189 --- /dev/null +++ b/tests/Images/Input/Webp/small_31x13.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9649f11b7ff9ffde0119b57b7728d837a3f04854e92ef03f2f06d79fbf63748b +size 262 diff --git a/tests/Images/Input/Webp/sticker.webp b/tests/Images/Input/Webp/sticker.webp new file mode 100644 index 000000000..ae781c2d0 --- /dev/null +++ b/tests/Images/Input/Webp/sticker.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:49795fc80522dae2ca687b345c21e9b0848f307d3cc3e39fbdcda730772d338c +size 27734 diff --git a/tests/Images/Input/Webp/test-nostrong.webp b/tests/Images/Input/Webp/test-nostrong.webp new file mode 100644 index 000000000..222a0c0f9 --- /dev/null +++ b/tests/Images/Input/Webp/test-nostrong.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:85e7ca4f1361394a29f4f0c9d4e5a31f20c2cc6b8816f991bad80b523941e2f9 +size 1968 diff --git a/tests/Images/Input/Webp/test.webp b/tests/Images/Input/Webp/test.webp new file mode 100644 index 000000000..b403414b9 --- /dev/null +++ b/tests/Images/Input/Webp/test.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a3665d7a6fd48ff60137ae29ac6792207aed3f768c2c05ef324f64c78352d5a5 +size 4928 diff --git a/tests/Images/Input/Webp/testpattern_opaque.png b/tests/Images/Input/Webp/testpattern_opaque.png new file mode 100644 index 000000000..4f1f3ea09 --- /dev/null +++ b/tests/Images/Input/Webp/testpattern_opaque.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b89449ae398c5b54a120b6b1e6b394e6d5cd58f0a55e5fb86f759fa12dcd325f +size 1983 diff --git a/tests/Images/Input/Webp/testpattern_opaque_small.png b/tests/Images/Input/Webp/testpattern_opaque_small.png new file mode 100644 index 000000000..62cdcf141 --- /dev/null +++ b/tests/Images/Input/Webp/testpattern_opaque_small.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:81ef8da0aae89095da92ac82830e0f3de935d62248954e577bf4d573158ffd5f +size 35660 diff --git a/tests/Images/Input/Webp/very_short.webp b/tests/Images/Input/Webp/very_short.webp new file mode 100644 index 000000000..f1297cfc3 --- /dev/null +++ b/tests/Images/Input/Webp/very_short.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:50c3d70b2fd3caad1fbe01b7a0a6b0c9152525b2ed4dde7a50fbba6c1ea6a0d6 +size 86 diff --git a/tests/Images/Input/Webp/vp80-00-comprehensive-001.webp b/tests/Images/Input/Webp/vp80-00-comprehensive-001.webp new file mode 100644 index 000000000..410e0a090 --- /dev/null +++ b/tests/Images/Input/Webp/vp80-00-comprehensive-001.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:44e1ddf3593d26148a03fb95379e03bb21fb397e3c9a26d64b47433e521d91c6 +size 754 diff --git a/tests/Images/Input/Webp/vp80-00-comprehensive-002.webp b/tests/Images/Input/Webp/vp80-00-comprehensive-002.webp new file mode 100644 index 000000000..d16d3e20d --- /dev/null +++ b/tests/Images/Input/Webp/vp80-00-comprehensive-002.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cbd5f5c38f1d2692b1e21b9981d50f71522faff68d57929674899c810cb5ed88 +size 4448 diff --git a/tests/Images/Input/Webp/vp80-00-comprehensive-003.webp b/tests/Images/Input/Webp/vp80-00-comprehensive-003.webp new file mode 100644 index 000000000..ca443b856 --- /dev/null +++ b/tests/Images/Input/Webp/vp80-00-comprehensive-003.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:526dbfc452a5c72edc672a2bed229196a67232dcc852b0b5c806d82e9bc108f2 +size 4500 diff --git a/tests/Images/Input/Webp/vp80-00-comprehensive-004.webp b/tests/Images/Input/Webp/vp80-00-comprehensive-004.webp new file mode 100644 index 000000000..b956bf8db --- /dev/null +++ b/tests/Images/Input/Webp/vp80-00-comprehensive-004.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9fb9183e44744997a9afec7242120c2e92c1dd9a9351ca5312abbe5ee0606c39 +size 754 diff --git a/tests/Images/Input/Webp/vp80-00-comprehensive-005.webp b/tests/Images/Input/Webp/vp80-00-comprehensive-005.webp new file mode 100644 index 000000000..48574db18 --- /dev/null +++ b/tests/Images/Input/Webp/vp80-00-comprehensive-005.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:788a937a4287e41d8116fc8f79673fea47a90090e68bdc966af9a14943eff11c +size 4444 diff --git a/tests/Images/Input/Webp/vp80-00-comprehensive-006.webp b/tests/Images/Input/Webp/vp80-00-comprehensive-006.webp new file mode 100644 index 000000000..e74cf8997 --- /dev/null +++ b/tests/Images/Input/Webp/vp80-00-comprehensive-006.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9642771e93f4d43fa0cde4116a447dc108cada765c94c0d46cdd1750d3712db8 +size 8528 diff --git a/tests/Images/Input/Webp/vp80-00-comprehensive-007.webp b/tests/Images/Input/Webp/vp80-00-comprehensive-007.webp new file mode 100644 index 000000000..d727a3586 --- /dev/null +++ b/tests/Images/Input/Webp/vp80-00-comprehensive-007.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b44d063894291fb1b5309206bf476a2daa3263373db4e9f32a5f9a525b3d8b59 +size 346 diff --git a/tests/Images/Input/Webp/vp80-00-comprehensive-008.webp b/tests/Images/Input/Webp/vp80-00-comprehensive-008.webp new file mode 100644 index 000000000..1e139b39d --- /dev/null +++ b/tests/Images/Input/Webp/vp80-00-comprehensive-008.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8c3e47eaa974319611baa3c12faeb9ce9ffbdd73e088c0f9dde164384b6b866c +size 45636 diff --git a/tests/Images/Input/Webp/vp80-00-comprehensive-009.webp b/tests/Images/Input/Webp/vp80-00-comprehensive-009.webp new file mode 100644 index 000000000..80bd6f70c --- /dev/null +++ b/tests/Images/Input/Webp/vp80-00-comprehensive-009.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dc9d71fffce845fc46717bf7fc89647a711afd4398a3c16668727aa38585f5c3 +size 8502 diff --git a/tests/Images/Input/Webp/vp80-00-comprehensive-010.webp b/tests/Images/Input/Webp/vp80-00-comprehensive-010.webp new file mode 100644 index 000000000..7fcff7b58 --- /dev/null +++ b/tests/Images/Input/Webp/vp80-00-comprehensive-010.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:de3cef909dc6cf5f0211351401ab1b303efe2358b9654a8d6ac01e3a4f29178b +size 16050 diff --git a/tests/Images/Input/Webp/vp80-00-comprehensive-011.webp b/tests/Images/Input/Webp/vp80-00-comprehensive-011.webp new file mode 100644 index 000000000..8dcacc6ef --- /dev/null +++ b/tests/Images/Input/Webp/vp80-00-comprehensive-011.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a856ab961966aad8dde337c71303f145e24e3d8a066eeb7a08d323d90c84221e +size 758 diff --git a/tests/Images/Input/Webp/vp80-00-comprehensive-012.webp b/tests/Images/Input/Webp/vp80-00-comprehensive-012.webp new file mode 100644 index 000000000..b660134df --- /dev/null +++ b/tests/Images/Input/Webp/vp80-00-comprehensive-012.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2ffe43365b937f075ee508159ae166fec7bc0671358ff5c2bdc8f5689b20f860 +size 1044 diff --git a/tests/Images/Input/Webp/vp80-00-comprehensive-013.webp b/tests/Images/Input/Webp/vp80-00-comprehensive-013.webp new file mode 100644 index 000000000..51b2d184a --- /dev/null +++ b/tests/Images/Input/Webp/vp80-00-comprehensive-013.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0d5301de57b7fd3cfdf55e463020742a88e0d3b522e602090acc2cf1f7a264ef +size 758 diff --git a/tests/Images/Input/Webp/vp80-00-comprehensive-014.webp b/tests/Images/Input/Webp/vp80-00-comprehensive-014.webp new file mode 100644 index 000000000..1d537103b --- /dev/null +++ b/tests/Images/Input/Webp/vp80-00-comprehensive-014.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:957cf5dfd41e46ee332791082fdb2e42ca63881a0b76865ced7a09c4fbab6138 +size 11982 diff --git a/tests/Images/Input/Webp/vp80-00-comprehensive-015.webp b/tests/Images/Input/Webp/vp80-00-comprehensive-015.webp new file mode 100644 index 000000000..ca82dcaa1 --- /dev/null +++ b/tests/Images/Input/Webp/vp80-00-comprehensive-015.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d65d42a905b9cdccc38b968573f9b7d86a296dbb3972ec07ae56caae84ee40f1 +size 7412 diff --git a/tests/Images/Input/Webp/vp80-00-comprehensive-016.webp b/tests/Images/Input/Webp/vp80-00-comprehensive-016.webp new file mode 100644 index 000000000..eda3b185c --- /dev/null +++ b/tests/Images/Input/Webp/vp80-00-comprehensive-016.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:77d17a74d586ccd2abea002e7b966d2b887bab68be2aa1c3866d5ea2f3587e76 +size 188 diff --git a/tests/Images/Input/Webp/vp80-00-comprehensive-017.webp b/tests/Images/Input/Webp/vp80-00-comprehensive-017.webp new file mode 100644 index 000000000..abedc9556 --- /dev/null +++ b/tests/Images/Input/Webp/vp80-00-comprehensive-017.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0797cd3ff4e12e1de9a2330ccd78fb675e6d2d7422803350a00df5c1125faaf8 +size 188 diff --git a/tests/Images/Input/Webp/vp80-01-intra-1400.webp b/tests/Images/Input/Webp/vp80-01-intra-1400.webp new file mode 100644 index 000000000..3f53c34e5 --- /dev/null +++ b/tests/Images/Input/Webp/vp80-01-intra-1400.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:385b683228d78120162c4be79287010bba55175ed06c5ad0d2fe82f837704641 +size 15294 diff --git a/tests/Images/Input/Webp/vp80-01-intra-1411.webp b/tests/Images/Input/Webp/vp80-01-intra-1411.webp new file mode 100644 index 000000000..89436b3cf --- /dev/null +++ b/tests/Images/Input/Webp/vp80-01-intra-1411.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d9330d735d1cdda007810e76a9cd836f07a6e3954363a0f82b1aca52adf346b4 +size 11963 diff --git a/tests/Images/Input/Webp/vp80-01-intra-1416.webp b/tests/Images/Input/Webp/vp80-01-intra-1416.webp new file mode 100644 index 000000000..f1171b9cc --- /dev/null +++ b/tests/Images/Input/Webp/vp80-01-intra-1416.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d3e253211155418d55618ac0a70ed1118a96917ce63b129bc49914d09f3620cf +size 11227 diff --git a/tests/Images/Input/Webp/vp80-01-intra-1417.webp b/tests/Images/Input/Webp/vp80-01-intra-1417.webp new file mode 100644 index 000000000..23e8c8fc6 --- /dev/null +++ b/tests/Images/Input/Webp/vp80-01-intra-1417.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d28624b166b4bcff6494f53f14e3335d5a762faa8c8e7fbfb0045f2b04123724 +size 11364 diff --git a/tests/Images/Input/Webp/vp80-02-inter-1402.webp b/tests/Images/Input/Webp/vp80-02-inter-1402.webp new file mode 100644 index 000000000..6853283e1 --- /dev/null +++ b/tests/Images/Input/Webp/vp80-02-inter-1402.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6ea8dcf7462d978ce3f5a38f505caebe09b3d9170a03fdb6479a8111c6bf54c2 +size 15294 diff --git a/tests/Images/Input/Webp/vp80-02-inter-1412.webp b/tests/Images/Input/Webp/vp80-02-inter-1412.webp new file mode 100644 index 000000000..0af4ef532 --- /dev/null +++ b/tests/Images/Input/Webp/vp80-02-inter-1412.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b2286cf0613e7a910b44494338157ef73504fefd88cd9427b4aecfbed7a034ae +size 11963 diff --git a/tests/Images/Input/Webp/vp80-02-inter-1418.webp b/tests/Images/Input/Webp/vp80-02-inter-1418.webp new file mode 100644 index 000000000..8d825257b --- /dev/null +++ b/tests/Images/Input/Webp/vp80-02-inter-1418.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f7a9da63fdec6ca0c42447867f6a7c7d165b0c3fcbf9313cacd6fc8eeb79a6fa +size 17680 diff --git a/tests/Images/Input/Webp/vp80-02-inter-1424.webp b/tests/Images/Input/Webp/vp80-02-inter-1424.webp new file mode 100644 index 000000000..934cae5bf --- /dev/null +++ b/tests/Images/Input/Webp/vp80-02-inter-1424.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:da8ce9c3078e56a9281620cace12abb39aebdfc0ab25a6586f676e3cf2981704 +size 5254 diff --git a/tests/Images/Input/Webp/vp80-03-segmentation-1401.webp b/tests/Images/Input/Webp/vp80-03-segmentation-1401.webp new file mode 100644 index 000000000..c4f23515a --- /dev/null +++ b/tests/Images/Input/Webp/vp80-03-segmentation-1401.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a243611a69fef3a8306dd3c48d645d7d4295f60781428b39e1f32bea5c5df46c +size 15296 diff --git a/tests/Images/Input/Webp/vp80-03-segmentation-1403.webp b/tests/Images/Input/Webp/vp80-03-segmentation-1403.webp new file mode 100644 index 000000000..a0322ce69 --- /dev/null +++ b/tests/Images/Input/Webp/vp80-03-segmentation-1403.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:007c78b248d71d135638637417a458d0a89ba3a46850df4503d10b576a3433c6 +size 15296 diff --git a/tests/Images/Input/Webp/vp80-03-segmentation-1407.webp b/tests/Images/Input/Webp/vp80-03-segmentation-1407.webp new file mode 100644 index 000000000..4075c52a3 --- /dev/null +++ b/tests/Images/Input/Webp/vp80-03-segmentation-1407.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c7fdcc6f20e730074602fbf4fbfbb76f614f13f7bdb7ce038ba32dc691fdfd09 +size 26388 diff --git a/tests/Images/Input/Webp/vp80-03-segmentation-1408.webp b/tests/Images/Input/Webp/vp80-03-segmentation-1408.webp new file mode 100644 index 000000000..737b281b3 --- /dev/null +++ b/tests/Images/Input/Webp/vp80-03-segmentation-1408.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:83c9a6874afc10ef08b853b7c990947fe78206b6a9ca8ad092fda3941d78d2b4 +size 26392 diff --git a/tests/Images/Input/Webp/vp80-03-segmentation-1409.webp b/tests/Images/Input/Webp/vp80-03-segmentation-1409.webp new file mode 100644 index 000000000..0af47a0a7 --- /dev/null +++ b/tests/Images/Input/Webp/vp80-03-segmentation-1409.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:52c0f64e79056e8927ec9625e3fcfe3b0665afe30a12270f3c61665e80e5f4ed +size 26402 diff --git a/tests/Images/Input/Webp/vp80-03-segmentation-1410.webp b/tests/Images/Input/Webp/vp80-03-segmentation-1410.webp new file mode 100644 index 000000000..10cbce996 --- /dev/null +++ b/tests/Images/Input/Webp/vp80-03-segmentation-1410.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:28dd9a50e95436ca29fd8b191d6073a6a7c049de732e512bb127b925eeba9102 +size 26420 diff --git a/tests/Images/Input/Webp/vp80-03-segmentation-1413.webp b/tests/Images/Input/Webp/vp80-03-segmentation-1413.webp new file mode 100644 index 000000000..6087cae87 --- /dev/null +++ b/tests/Images/Input/Webp/vp80-03-segmentation-1413.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6a757b7f0b539d51d9c450bce6f40c99d00109a8b61ea327a07867ebce23c397 +size 11998 diff --git a/tests/Images/Input/Webp/vp80-03-segmentation-1414.webp b/tests/Images/Input/Webp/vp80-03-segmentation-1414.webp new file mode 100644 index 000000000..d4ac35db2 --- /dev/null +++ b/tests/Images/Input/Webp/vp80-03-segmentation-1414.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1f9fe429dbef950dbd9b096b22566f4df4e036af0d95a4c05c954da44490e4af +size 19884 diff --git a/tests/Images/Input/Webp/vp80-03-segmentation-1415.webp b/tests/Images/Input/Webp/vp80-03-segmentation-1415.webp new file mode 100644 index 000000000..52ee59a12 --- /dev/null +++ b/tests/Images/Input/Webp/vp80-03-segmentation-1415.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:feac273c9e5152e6f9ccdffa65f0a9ce863abbbd446625a32ad42922452429e3 +size 19877 diff --git a/tests/Images/Input/Webp/vp80-03-segmentation-1425.webp b/tests/Images/Input/Webp/vp80-03-segmentation-1425.webp new file mode 100644 index 000000000..d3e3ff1de --- /dev/null +++ b/tests/Images/Input/Webp/vp80-03-segmentation-1425.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:65b704903e9e11c43132aef1d9353011928954c9d5fdd5312477de40ddb26fb9 +size 3632 diff --git a/tests/Images/Input/Webp/vp80-03-segmentation-1426.webp b/tests/Images/Input/Webp/vp80-03-segmentation-1426.webp new file mode 100644 index 000000000..1a444068a --- /dev/null +++ b/tests/Images/Input/Webp/vp80-03-segmentation-1426.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:11bc8b1f337cbe0dd1760eee1483d82243147917c5588b9463353a71c0b03271 +size 18524 diff --git a/tests/Images/Input/Webp/vp80-03-segmentation-1427.webp b/tests/Images/Input/Webp/vp80-03-segmentation-1427.webp new file mode 100644 index 000000000..95d6289d9 --- /dev/null +++ b/tests/Images/Input/Webp/vp80-03-segmentation-1427.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c4a1ee18d804b4f83bf5ef7ff1d3d849a136a7480dd074c721c41e788b51868c +size 32982 diff --git a/tests/Images/Input/Webp/vp80-03-segmentation-1432.webp b/tests/Images/Input/Webp/vp80-03-segmentation-1432.webp new file mode 100644 index 000000000..44257b641 --- /dev/null +++ b/tests/Images/Input/Webp/vp80-03-segmentation-1432.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fa1d8b9426f595db1c92733470c60bddfcf021cb95a6c27da829598180e0a6d0 +size 20094 diff --git a/tests/Images/Input/Webp/vp80-03-segmentation-1435.webp b/tests/Images/Input/Webp/vp80-03-segmentation-1435.webp new file mode 100644 index 000000000..281b63983 --- /dev/null +++ b/tests/Images/Input/Webp/vp80-03-segmentation-1435.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cb8129ea589ab5cab6368be88861125bcc55a492ba2eb20c086aa99c7c9410d2 +size 12080 diff --git a/tests/Images/Input/Webp/vp80-03-segmentation-1436.webp b/tests/Images/Input/Webp/vp80-03-segmentation-1436.webp new file mode 100644 index 000000000..39c8b7191 --- /dev/null +++ b/tests/Images/Input/Webp/vp80-03-segmentation-1436.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:78a5fd9afa2edb44d73235a0d1a160abf34efd8ee9495121d3405aa89a8f8b63 +size 14512 diff --git a/tests/Images/Input/Webp/vp80-03-segmentation-1437.webp b/tests/Images/Input/Webp/vp80-03-segmentation-1437.webp new file mode 100644 index 000000000..0c094e8c4 --- /dev/null +++ b/tests/Images/Input/Webp/vp80-03-segmentation-1437.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:299ac1152847f4bded20bdd114c9f1f5a12ceee767a924cb347db7508d784375 +size 27132 diff --git a/tests/Images/Input/Webp/vp80-03-segmentation-1441.webp b/tests/Images/Input/Webp/vp80-03-segmentation-1441.webp new file mode 100644 index 000000000..d13f619af --- /dev/null +++ b/tests/Images/Input/Webp/vp80-03-segmentation-1441.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:70d3bc371f42f3a7d8f59eb89c66a3d1ef10476baa86e66487f158370403b595 +size 4606 diff --git a/tests/Images/Input/Webp/vp80-03-segmentation-1442.webp b/tests/Images/Input/Webp/vp80-03-segmentation-1442.webp new file mode 100644 index 000000000..047bf1572 --- /dev/null +++ b/tests/Images/Input/Webp/vp80-03-segmentation-1442.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3ef18fbc941074c644d01db06fcf06b9e29628e6bedf23db29c239aa1795cc9b +size 14804 diff --git a/tests/Images/Input/Webp/vp80-04-partitions-1404.webp b/tests/Images/Input/Webp/vp80-04-partitions-1404.webp new file mode 100644 index 000000000..2d29d86fd --- /dev/null +++ b/tests/Images/Input/Webp/vp80-04-partitions-1404.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:25cd4540f189f61ab0119f8f26e3dc28ba1a7840843b205389948dc3019eee6d +size 15298 diff --git a/tests/Images/Input/Webp/vp80-04-partitions-1405.webp b/tests/Images/Input/Webp/vp80-04-partitions-1405.webp new file mode 100644 index 000000000..f8704e166 --- /dev/null +++ b/tests/Images/Input/Webp/vp80-04-partitions-1405.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8d2daf0d7c7e902208621342450bd4009a7bfe3b6aaf36b7d43d232066cd9037 +size 15308 diff --git a/tests/Images/Input/Webp/vp80-04-partitions-1406.webp b/tests/Images/Input/Webp/vp80-04-partitions-1406.webp new file mode 100644 index 000000000..dcf7a73a5 --- /dev/null +++ b/tests/Images/Input/Webp/vp80-04-partitions-1406.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:af294ab9f4de0ca82f9df0a29d60f00b1bc20099d337ffaac63e6e1e5c4a14e6 +size 15324 diff --git a/tests/Images/Input/Webp/vp80-05-sharpness-1428.webp b/tests/Images/Input/Webp/vp80-05-sharpness-1428.webp new file mode 100644 index 000000000..727ec0e10 --- /dev/null +++ b/tests/Images/Input/Webp/vp80-05-sharpness-1428.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a13d9081c8d55dacd6819704712a64a7d25971e59c0ba7e5e5ae4c86ca522b7b +size 8864 diff --git a/tests/Images/Input/Webp/vp80-05-sharpness-1429.webp b/tests/Images/Input/Webp/vp80-05-sharpness-1429.webp new file mode 100644 index 000000000..d1f36de81 --- /dev/null +++ b/tests/Images/Input/Webp/vp80-05-sharpness-1429.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:99e3f0a30900c65f5af22e41bc60c4fc7209e2c8f93d2edf5d5ff09db6beb900 +size 14518 diff --git a/tests/Images/Input/Webp/vp80-05-sharpness-1430.webp b/tests/Images/Input/Webp/vp80-05-sharpness-1430.webp new file mode 100644 index 000000000..01399b5e2 --- /dev/null +++ b/tests/Images/Input/Webp/vp80-05-sharpness-1430.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:acd9c9fb1876fd2035405b9b72aa5a985922ec1aab2055f6c32a21e02fdd9dbd +size 290 diff --git a/tests/Images/Input/Webp/vp80-05-sharpness-1431.webp b/tests/Images/Input/Webp/vp80-05-sharpness-1431.webp new file mode 100644 index 000000000..b924e43c4 --- /dev/null +++ b/tests/Images/Input/Webp/vp80-05-sharpness-1431.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9aa0b809dc9aac340acab0f7f4953f497e4b6cefc9dda14f823ab3053a11d5cd +size 6666 diff --git a/tests/Images/Input/Webp/vp80-05-sharpness-1433.webp b/tests/Images/Input/Webp/vp80-05-sharpness-1433.webp new file mode 100644 index 000000000..340c4a448 --- /dev/null +++ b/tests/Images/Input/Webp/vp80-05-sharpness-1433.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:005811b6b16550a1da22a1df767311c1b85f1cc7c2409d7917fd594d0b48d4c1 +size 14508 diff --git a/tests/Images/Input/Webp/vp80-05-sharpness-1434.webp b/tests/Images/Input/Webp/vp80-05-sharpness-1434.webp new file mode 100644 index 000000000..c06ea3fb9 --- /dev/null +++ b/tests/Images/Input/Webp/vp80-05-sharpness-1434.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:da5bef25e427bb9a8be2889c76a65f9506cdfc4bab455b3285b6b627e5880285 +size 18224 diff --git a/tests/Images/Input/Webp/vp80-05-sharpness-1438.webp b/tests/Images/Input/Webp/vp80-05-sharpness-1438.webp new file mode 100644 index 000000000..618f5e358 --- /dev/null +++ b/tests/Images/Input/Webp/vp80-05-sharpness-1438.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dd0ea301c7446b6fd6d002b9ab48b383501ce05c3953d589be48ede5cf293f9d +size 9981 diff --git a/tests/Images/Input/Webp/vp80-05-sharpness-1439.webp b/tests/Images/Input/Webp/vp80-05-sharpness-1439.webp new file mode 100644 index 000000000..e3ac596a2 --- /dev/null +++ b/tests/Images/Input/Webp/vp80-05-sharpness-1439.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:36bf4fef87be45f49411f93102433f117d54356a7aebd294ae1b68799938ce1c +size 20068 diff --git a/tests/Images/Input/Webp/vp80-05-sharpness-1440.webp b/tests/Images/Input/Webp/vp80-05-sharpness-1440.webp new file mode 100644 index 000000000..809a2fd9d --- /dev/null +++ b/tests/Images/Input/Webp/vp80-05-sharpness-1440.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f66a1bc109f04baa07a530fb79267d931899591c10798c4dc95f59eb03c5ac44 +size 14508 diff --git a/tests/Images/Input/Webp/vp80-05-sharpness-1443.webp b/tests/Images/Input/Webp/vp80-05-sharpness-1443.webp new file mode 100644 index 000000000..851dfb6b6 --- /dev/null +++ b/tests/Images/Input/Webp/vp80-05-sharpness-1443.webp @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bcedf4d253801cf2461bd01675558dadc3895395a6432d0ba8f5cb9734b4040c +size 6188 diff --git a/tests/Images/Input/Webp/yuv_test.png b/tests/Images/Input/Webp/yuv_test.png new file mode 100644 index 000000000..5606b783e --- /dev/null +++ b/tests/Images/Input/Webp/yuv_test.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:96b86c39cad831c97c6ef9633d4d2d04ea0382547514dda5b1f639e10d7207fa +size 3389