Browse Source

Merge branch 'master' into js/better-transforms

af/merge-core
James Jackson-South 8 years ago
committed by GitHub
parent
commit
33684c4ceb
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 29
      src/ImageSharp/Formats/Gif/GifDecoderCore.cs
  2. 8
      src/ImageSharp/MetaData/Profiles/ICC/DataReader/IccDataReader.Curves.cs
  3. 10
      src/ImageSharp/MetaData/Profiles/ICC/DataReader/IccDataReader.TagDataEntry.cs
  4. 31
      src/ImageSharp/Processing/Processors/Convolution/BoxBlurProcessor.cs
  5. 4
      src/ImageSharp/Processing/Processors/Convolution/KirschKernels.cs
  6. 16
      src/ImageSharp/Processing/Processors/Convolution/KirschProcessor.cs
  7. 2
      tests/ImageSharp.Sandbox46/ImageSharp.Sandbox46.csproj
  8. 33
      tests/ImageSharp.Tests/Formats/Gif/GifDecoderTests.cs

29
src/ImageSharp/Formats/Gif/GifDecoderCore.cs

@ -142,8 +142,7 @@ namespace SixLabors.ImageSharp.Formats.Gif
this.ReadApplicationExtension(); this.ReadApplicationExtension();
break; break;
case GifConstants.PlainTextLabel: case GifConstants.PlainTextLabel:
int plainLength = stream.ReadByte(); this.SkipBlock(); // Not supported by any known decoder.
this.Skip(plainLength); // Not supported by any known decoder.
break; break;
} }
} }
@ -190,9 +189,7 @@ namespace SixLabors.ImageSharp.Formats.Gif
switch (stream.ReadByte()) switch (stream.ReadByte())
{ {
case GifConstants.GraphicControlLabel: case GifConstants.GraphicControlLabel:
this.SkipBlock(); // Skip graphic control extension block
// Skip graphic control extension block
this.Skip(0);
break; break;
case GifConstants.CommentLabel: case GifConstants.CommentLabel:
this.ReadComments(); this.ReadComments();
@ -201,8 +198,7 @@ namespace SixLabors.ImageSharp.Formats.Gif
this.ReadApplicationExtension(); this.ReadApplicationExtension();
break; break;
case GifConstants.PlainTextLabel: case GifConstants.PlainTextLabel:
int plainLength = stream.ReadByte(); this.SkipBlock(); // Not supported by any known decoder.
this.Skip(plainLength); // Not supported by any known decoder.
break; break;
} }
} }
@ -288,24 +284,27 @@ namespace SixLabors.ImageSharp.Formats.Gif
// Could be XMP or something else not supported yet. // Could be XMP or something else not supported yet.
// Back up and skip. // Back up and skip.
this.stream.Position -= appLength + 1; this.stream.Position -= appLength + 1;
this.Skip(appLength); this.SkipBlock(appLength);
return; return;
} }
this.Skip(appLength); // Not supported by any known decoder. this.SkipBlock(appLength); // Not supported by any known decoder.
} }
/// <summary> /// <summary>
/// Skips the designated number of bytes in the stream. /// Skips over a block or reads its terminator.
/// <param name="blockSize">The length of the block to skip.</param>
/// </summary> /// </summary>
/// <param name="length">The number of bytes to skip.</param> private void SkipBlock(int blockSize = 0)
private void Skip(int length)
{ {
this.stream.Skip(length); if (blockSize > 0)
{
this.stream.Skip(blockSize);
}
int flag; int flag;
while ((flag = this.stream.ReadByte()) != 0) while ((flag = this.stream.ReadByte()) > 0)
{ {
this.stream.Skip(flag); this.stream.Skip(flag);
} }
@ -370,7 +369,7 @@ namespace SixLabors.ImageSharp.Formats.Gif
this.ReadFrameColors(ref image, ref previousFrame, indices.GetSpan(), colorTable, this.imageDescriptor); this.ReadFrameColors(ref image, ref previousFrame, indices.GetSpan(), colorTable, this.imageDescriptor);
// Skip any remaining blocks // Skip any remaining blocks
this.Skip(0); this.SkipBlock();
} }
finally finally
{ {

8
src/ImageSharp/MetaData/Profiles/ICC/DataReader/IccDataReader.Curves.cs

@ -41,10 +41,10 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
public IccResponseCurve ReadResponseCurve(int channelCount) public IccResponseCurve ReadResponseCurve(int channelCount)
{ {
var type = (IccCurveMeasurementEncodings)this.ReadUInt32(); var type = (IccCurveMeasurementEncodings)this.ReadUInt32();
uint[] measurment = new uint[channelCount]; uint[] measurement = new uint[channelCount];
for (int i = 0; i < channelCount; i++) for (int i = 0; i < channelCount; i++)
{ {
measurment[i] = this.ReadUInt32(); measurement[i] = this.ReadUInt32();
} }
Vector3[] xyzValues = new Vector3[channelCount]; Vector3[] xyzValues = new Vector3[channelCount];
@ -56,8 +56,8 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
IccResponseNumber[][] response = new IccResponseNumber[channelCount][]; IccResponseNumber[][] response = new IccResponseNumber[channelCount][];
for (int i = 0; i < channelCount; i++) for (int i = 0; i < channelCount; i++)
{ {
response[i] = new IccResponseNumber[measurment[i]]; response[i] = new IccResponseNumber[measurement[i]];
for (uint j = 0; j < measurment[i]; j++) for (uint j = 0; j < measurement[i]; j++)
{ {
response[i][j] = this.ReadResponseNumber(); response[i][j] = this.ReadResponseNumber();
} }

10
src/ImageSharp/MetaData/Profiles/ICC/DataReader/IccDataReader.TagDataEntry.cs

@ -628,16 +628,16 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
{ {
int start = this.currentIndex - 8; // 8 is the tag header size int start = this.currentIndex - 8; // 8 is the tag header size
ushort channelCount = this.ReadUInt16(); ushort channelCount = this.ReadUInt16();
ushort measurmentCount = this.ReadUInt16(); ushort measurementCount = this.ReadUInt16();
uint[] offset = new uint[measurmentCount]; uint[] offset = new uint[measurementCount];
for (int i = 0; i < measurmentCount; i++) for (int i = 0; i < measurementCount; i++)
{ {
offset[i] = this.ReadUInt32(); offset[i] = this.ReadUInt32();
} }
var curves = new IccResponseCurve[measurmentCount]; var curves = new IccResponseCurve[measurementCount];
for (int i = 0; i < measurmentCount; i++) for (int i = 0; i < measurementCount; i++)
{ {
this.currentIndex = (int)(start + offset[i]); this.currentIndex = (int)(start + offset[i]);
curves[i] = this.ReadResponseCurve(channelCount); curves[i] = this.ReadResponseCurve(channelCount);

31
src/ImageSharp/Processing/Processors/Convolution/BoxBlurProcessor.cs

@ -66,36 +66,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
? new DenseMatrix<float>(size, 1) ? new DenseMatrix<float>(size, 1)
: new DenseMatrix<float>(1, size); : new DenseMatrix<float>(1, size);
float sum = 0F; kernel.Fill(1.0F / size);
for (int i = 0; i < size; i++)
{
float x = 1;
sum += x;
if (horizontal)
{
kernel[0, i] = x;
}
else
{
kernel[i, 0] = x;
}
}
// Normalize kernel so that the sum of all weights equals 1
if (horizontal)
{
for (int i = 0; i < size; i++)
{
kernel[0, i] = kernel[0, i] / sum;
}
}
else
{
for (int i = 0; i < size; i++)
{
kernel[i, 0] = kernel[i, 0] / sum;
}
}
return kernel; return kernel;
} }

4
src/ImageSharp/Processing/Processors/Convolution/KirshKernels.cs → src/ImageSharp/Processing/Processors/Convolution/KirschKernels.cs

@ -6,9 +6,9 @@ using SixLabors.ImageSharp.Primitives;
namespace SixLabors.ImageSharp.Processing.Processors.Convolution namespace SixLabors.ImageSharp.Processing.Processors.Convolution
{ {
/// <summary> /// <summary>
/// Contains the eight matrices used for Kirsh edge detection /// Contains the eight matrices used for Kirsch edge detection
/// </summary> /// </summary>
internal static class KirshKernels internal static class KirschKernels
{ {
/// <summary> /// <summary>
/// Gets the North gradient operator /// Gets the North gradient operator

16
src/ImageSharp/Processing/Processors/Convolution/KirschProcessor.cs

@ -23,27 +23,27 @@ namespace SixLabors.ImageSharp.Processing.Processors.Convolution
} }
/// <inheritdoc/> /// <inheritdoc/>
public override DenseMatrix<float> North => KirshKernels.KirschNorth; public override DenseMatrix<float> North => KirschKernels.KirschNorth;
/// <inheritdoc/> /// <inheritdoc/>
public override DenseMatrix<float> NorthWest => KirshKernels.KirschNorthWest; public override DenseMatrix<float> NorthWest => KirschKernels.KirschNorthWest;
/// <inheritdoc/> /// <inheritdoc/>
public override DenseMatrix<float> West => KirshKernels.KirschWest; public override DenseMatrix<float> West => KirschKernels.KirschWest;
/// <inheritdoc/> /// <inheritdoc/>
public override DenseMatrix<float> SouthWest => KirshKernels.KirschSouthWest; public override DenseMatrix<float> SouthWest => KirschKernels.KirschSouthWest;
/// <inheritdoc/> /// <inheritdoc/>
public override DenseMatrix<float> South => KirshKernels.KirschSouth; public override DenseMatrix<float> South => KirschKernels.KirschSouth;
/// <inheritdoc/> /// <inheritdoc/>
public override DenseMatrix<float> SouthEast => KirshKernels.KirschSouthEast; public override DenseMatrix<float> SouthEast => KirschKernels.KirschSouthEast;
/// <inheritdoc/> /// <inheritdoc/>
public override DenseMatrix<float> East => KirshKernels.KirschEast; public override DenseMatrix<float> East => KirschKernels.KirschEast;
/// <inheritdoc/> /// <inheritdoc/>
public override DenseMatrix<float> NorthEast => KirshKernels.KirschNorthEast; public override DenseMatrix<float> NorthEast => KirschKernels.KirschNorthEast;
} }
} }

2
tests/ImageSharp.Sandbox46/ImageSharp.Sandbox46.csproj

@ -11,7 +11,7 @@
<Authors>James Jackson-South and contributors</Authors> <Authors>James Jackson-South and contributors</Authors>
<Company>James Jackson-South</Company> <Company>James Jackson-South</Company>
<RootNamespace>SixLabors.ImageSharp.Sandbox46</RootNamespace> <RootNamespace>SixLabors.ImageSharp.Sandbox46</RootNamespace>
<LangVersion>7.2</LangVersion> <LangVersion>7.3</LangVersion>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\src\ImageSharp.Drawing\ImageSharp.Drawing.csproj" /> <ProjectReference Include="..\..\src\ImageSharp.Drawing\ImageSharp.Drawing.csproj" />

33
tests/ImageSharp.Tests/Formats/Gif/GifDecoderTests.cs

@ -1,20 +1,20 @@
// Copyright (c) Six Labors and contributors. // Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0. // Licensed under the Apache License, Version 2.0.
using System;
using System.Collections.Generic;
using System.IO;
using System.Text; using System.Text;
using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.Formats.Gif; using SixLabors.ImageSharp.Formats.Gif;
using SixLabors.ImageSharp.MetaData;
using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison;
using Xunit; using Xunit;
using System.IO;
using SixLabors.ImageSharp.Advanced;
// ReSharper disable InconsistentNaming // ReSharper disable InconsistentNaming
namespace SixLabors.ImageSharp.Tests.Formats.Gif namespace SixLabors.ImageSharp.Tests.Formats.Gif
{ {
using System.Collections.Generic;
using SixLabors.ImageSharp.MetaData;
using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison;
public class GifDecoderTests public class GifDecoderTests
{ {
private const PixelTypes TestPixelTypes = PixelTypes.Rgba32 | PixelTypes.RgbaVector | PixelTypes.Argb32; private const PixelTypes TestPixelTypes = PixelTypes.Rgba32 | PixelTypes.RgbaVector | PixelTypes.Argb32;
@ -70,6 +70,27 @@ namespace SixLabors.ImageSharp.Tests.Formats.Gif
} }
} }
[Fact]
public unsafe void Decode_NonTerminatedFinalFrame()
{
var testFile = TestFile.Create(TestImages.Gif.Rings);
int length = testFile.Bytes.Length - 2;
fixed (byte* data = testFile.Bytes.AsSpan(0, length))
{
using (var stream = new UnmanagedMemoryStream(data, length))
{
var decoder = new GifDecoder();
using (Image<Rgba32> image = decoder.Decode<Rgba32>(Configuration.Default, stream))
{
Assert.Equal((200, 200), (image.Width, image.Height));
}
}
}
}
[Theory] [Theory]
[MemberData(nameof(RatioFiles))] [MemberData(nameof(RatioFiles))]
public void Decode_VerifyRatio(string imagePath, int xResolution, int yResolution, PixelResolutionUnit resolutionUnit) public void Decode_VerifyRatio(string imagePath, int xResolution, int yResolution, PixelResolutionUnit resolutionUnit)

Loading…
Cancel
Save