Browse Source

Merge branch 'master' into bp/tiff-fax4

pull/1747/head
Brian Popow 5 years ago
committed by GitHub
parent
commit
743f4e9609
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 141
      .github/workflows/build-and-test.yml
  2. 5
      Directory.Build.props
  3. 2
      shared-infrastructure
  4. 86
      src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs
  5. 5
      src/ImageSharp/ImageSharp.csproj
  6. 2
      src/ImageSharp/Processing/Processors/Normalization/AdaptiveHistogramEqualizationSlidingWindowProcessor{TPixel}.cs
  7. 6
      tests/ImageSharp.Benchmarks/ImageSharp.Benchmarks.csproj
  8. 6
      tests/ImageSharp.Tests.ProfilingSandbox/ImageSharp.Tests.ProfilingSandbox.csproj
  9. 13
      tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs
  10. 7
      tests/ImageSharp.Tests/ImageSharp.Tests.csproj
  11. 1
      tests/ImageSharp.Tests/TestImages.cs
  12. 3
      tests/Images/Input/Jpg/issues/Issue1732-WrongColorSpace.jpg

141
.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

5
Directory.Build.props

@ -18,6 +18,11 @@
<!-- Import the shared global .props file -->
<Import Project="$(MSBuildThisFileDirectory)shared-infrastructure\msbuild\props\SixLabors.Global.props" />
<PropertyGroup Condition="$(SIXLABORS_TESTING_PREVIEW) == true">
<!-- Workaround various issues bound to implicit language features. -->
<LangVersion>preview</LangVersion>
</PropertyGroup>
<!--
Ensure all custom build configurations based upon "Release" are optimized.
This is easier than setting each project individually.

2
shared-infrastructure

@ -1 +1 @@
Subproject commit 9b94ebc4be9b7a8d7620c257e6ee485455973332
Subproject commit f48ab829167c42c69242ed0d303683232fbfccd1

86
src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs

@ -345,10 +345,10 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
}
/// <summary>
/// Returns the correct colorspace based on the image component count
/// Returns the correct colorspace based on the image component count and the jpeg frame components.
/// </summary>
/// <returns>The <see cref="JpegColorSpace"/></returns>
private JpegColorSpace DeduceJpegColorSpace(byte componentCount)
private JpegColorSpace DeduceJpegColorSpace(byte componentCount, JpegComponent[] components)
{
if (componentCount == 1)
{
@ -362,6 +362,12 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
return JpegColorSpace.RGB;
}
// If the component Id's are R, G, B in ASCII the colorspace is RGB and not YCbCr.
if (components[2].Id == 66 && components[1].Id == 71 && components[0].Id == 82)
{
return JpegColorSpace.RGB;
}
// Some images are poorly encoded and contain incorrect colorspace transform metadata.
// We ignore that and always fall back to the default colorspace.
return JpegColorSpace.YCbCr;
@ -836,60 +842,60 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
// 1 byte: Number of components
byte componentCount = this.temp[5];
this.ColorSpace = this.DeduceJpegColorSpace(componentCount);
this.Metadata.GetJpegMetadata().ColorType = this.ColorSpace == JpegColorSpace.Grayscale ? JpegColorType.Luminance : JpegColorType.YCbCr;
this.Frame = new JpegFrame(frameMarker, precision, frameWidth, frameHeight, componentCount);
if (!metadataOnly)
remaining -= length;
// Validate: remaining part must be equal to components * 3
const int componentBytes = 3;
if (remaining != componentCount * componentBytes)
{
remaining -= length;
JpegThrowHelper.ThrowBadMarker("SOFn", remaining);
}
// Validate: remaining part must be equal to components * 3
const int componentBytes = 3;
if (remaining != componentCount * componentBytes)
{
JpegThrowHelper.ThrowBadMarker("SOFn", remaining);
}
// components*3 bytes: component data
stream.Read(this.temp, 0, remaining);
// No need to pool this. They max out at 4
this.Frame.ComponentIds = new byte[componentCount];
this.Frame.ComponentOrder = new byte[componentCount];
this.Frame.Components = new JpegComponent[componentCount];
// components*3 bytes: component data
stream.Read(this.temp, 0, remaining);
int maxH = 0;
int maxV = 0;
int index = 0;
for (int i = 0; i < componentCount; i++)
{
byte hv = this.temp[index + 1];
int h = (hv >> 4) & 15;
int v = hv & 15;
// No need to pool this. They max out at 4
this.Frame.ComponentIds = new byte[componentCount];
this.Frame.ComponentOrder = new byte[componentCount];
this.Frame.Components = new JpegComponent[componentCount];
if (maxH < h)
{
maxH = h;
}
int maxH = 0;
int maxV = 0;
int index = 0;
for (int i = 0; i < componentCount; i++)
if (maxV < v)
{
byte hv = this.temp[index + 1];
int h = (hv >> 4) & 15;
int v = hv & 15;
maxV = v;
}
if (maxH < h)
{
maxH = h;
}
var component = new JpegComponent(this.Configuration.MemoryAllocator, this.Frame, this.temp[index], h, v, this.temp[index + 2], i);
if (maxV < v)
{
maxV = v;
}
this.Frame.Components[i] = component;
this.Frame.ComponentIds[i] = component.Id;
var component = new JpegComponent(this.Configuration.MemoryAllocator, this.Frame, this.temp[index], h, v, this.temp[index + 2], i);
index += componentBytes;
}
this.Frame.Components[i] = component;
this.Frame.ComponentIds[i] = component.Id;
this.ColorSpace = this.DeduceJpegColorSpace(componentCount, this.Frame.Components);
index += componentBytes;
}
this.Metadata.GetJpegMetadata().ColorType = this.ColorSpace == JpegColorSpace.Grayscale ? JpegColorType.Luminance : JpegColorType.YCbCr;
if (!metadataOnly)
{
this.Frame.Init(maxH, maxV);
this.scanDecoder.InjectFrameData(this.Frame, this);
}
}

5
src/ImageSharp/ImageSharp.csproj

@ -16,6 +16,11 @@
</PropertyGroup>
<Choose>
<When Condition="$(SIXLABORS_TESTING_PREVIEW) == true">
<PropertyGroup>
<TargetFrameworks>net6.0;net5.0;netcoreapp3.1;netcoreapp2.1;netstandard2.1;netstandard2.0;netstandard1.3;net472</TargetFrameworks>
</PropertyGroup>
</When>
<When Condition="$(SIXLABORS_TESTING) == true">
<PropertyGroup>
<TargetFrameworks>net5.0;netcoreapp3.1;netcoreapp2.1;netstandard2.1;netstandard2.0;netstandard1.3;net472</TargetFrameworks>

2
src/ImageSharp/Processing/Processors/Normalization/AdaptiveHistogramEqualizationSlidingWindowProcessor{TPixel}.cs

@ -257,7 +257,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)++;

6
tests/ImageSharp.Benchmarks/ImageSharp.Benchmarks.csproj

@ -9,12 +9,16 @@
<!--Used to hide test project from dotnet test-->
<IsTestProject>false</IsTestProject>
<Configurations>Debug;Release;Debug-InnerLoop;Release-InnerLoop</Configurations>
<LangVersion>9</LangVersion>
<!-- Uncomment this to run benchmarks depending on Colorful or Pfim (colorspaces and TGA): -->
<!--<SignAssembly>false</SignAssembly>-->
</PropertyGroup>
<Choose>
<When Condition="$(SIXLABORS_TESTING_PREVIEW) == true">
<PropertyGroup>
<TargetFrameworks>net6.0;net5.0;netcoreapp3.1;netcoreapp2.1;net472</TargetFrameworks>
</PropertyGroup>
</When>
<When Condition="$(Configuration.EndsWith('InnerLoop')) == true">
<PropertyGroup>
<TargetFrameworks>netcoreapp3.1</TargetFrameworks>

6
tests/ImageSharp.Tests.ProfilingSandbox/ImageSharp.Tests.ProfilingSandbox.csproj

@ -14,10 +14,14 @@
<EnsureNETCoreAppRuntime>false</EnsureNETCoreAppRuntime>
<Configurations>Debug;Release;Debug-InnerLoop;Release-InnerLoop</Configurations>
<ValidateExecutableReferencesMatchSelfContained>false</ValidateExecutableReferencesMatchSelfContained>
<LangVersion>9</LangVersion>
</PropertyGroup>
<Choose>
<When Condition="$(SIXLABORS_TESTING_PREVIEW) == true">
<PropertyGroup>
<TargetFrameworks>net6.0;net5.0;netcoreapp3.1;netcoreapp2.1;net472</TargetFrameworks>
</PropertyGroup>
</When>
<When Condition="$(Configuration.EndsWith('InnerLoop')) == true">
<PropertyGroup>
<TargetFrameworks>netcoreapp3.1</TargetFrameworks>

13
tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs

@ -174,6 +174,19 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
await Assert.ThrowsAsync<TaskCanceledException>(async () => await Image.IdentifyAsync(config, "someFakeFile", cts.Token));
}
// https://github.com/SixLabors/ImageSharp/pull/1732
[Theory]
[WithFile(TestImages.Jpeg.Issues.WrongColorSpace, PixelTypes.Rgba32)]
public void Issue1732_DecodesWithRgbColorSpace<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel>
{
using (Image<TPixel> image = provider.GetImage(new 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\"

7
tests/ImageSharp.Tests/ImageSharp.Tests.csproj

@ -10,6 +10,11 @@
</PropertyGroup>
<Choose>
<When Condition="$(SIXLABORS_TESTING_PREVIEW) == true">
<PropertyGroup>
<TargetFrameworks>net6.0;net5.0;netcoreapp3.1;netcoreapp2.1;net472</TargetFrameworks>
</PropertyGroup>
</When>
<When Condition="$(Configuration.EndsWith('InnerLoop')) == true">
<PropertyGroup>
<TargetFrameworks>netcoreapp3.1</TargetFrameworks>
@ -21,7 +26,7 @@
</PropertyGroup>
</Otherwise>
</Choose>
<ItemGroup>
<InternalsVisibleTo Include="ImageSharp.Tests.ProfilingSandbox" Key="$(SixLaborsPublicKey)" />
</ItemGroup>

1
tests/ImageSharp.Tests/TestImages.cs

@ -237,6 +237,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
{

3
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
Loading…
Cancel
Save