Browse Source

Minor performance improvements.

pull/1574/head
James Jackson-South 6 years ago
parent
commit
b218f89cd2
  1. 6
      Directory.Build.targets
  2. 7
      src/ImageSharp/Formats/Png/PngDecoderCore.cs
  3. 29
      src/ImageSharp/Formats/Png/PngEncoderCore.cs
  4. 16
      src/ImageSharp/Formats/Png/Zlib/DeflaterEngine.cs

6
Directory.Build.targets

@ -23,12 +23,12 @@
<PackageReference Update="StyleCop.Analyzers" PrivateAssets="All" Version="1.1.118" />
<!--Src Dependencies-->
<PackageReference Update="System.Buffers" Version="4.5.0" />
<PackageReference Update="System.Buffers" Version="4.5.1" />
<PackageReference Update="System.IO.Compression" Version="4.3.0" />
<PackageReference Update="System.IO.UnmanagedMemoryStream" Version="4.3.0" />
<PackageReference Update="System.Numerics.Vectors" Version="4.5.0" />
<PackageReference Update="System.Memory" Version="4.5.3" />
<PackageReference Update="System.Runtime.CompilerServices.Unsafe" Version="4.7" />
<PackageReference Update="System.Memory" Version="4.5.4" />
<PackageReference Update="System.Runtime.CompilerServices.Unsafe" Version="4.7.1" />
<PackageReference Update="System.Threading.Tasks.Parallel" Version="4.3.0" />
<PackageReference Update="System.ValueTuple" Version="4.5.0" />

7
src/ImageSharp/Formats/Png/PngDecoderCore.cs

@ -380,7 +380,12 @@ namespace SixLabors.ImageSharp.Formats.Png
private void InitializeImage<TPixel>(ImageMetadata metadata, out Image<TPixel> image)
where TPixel : unmanaged, IPixel<TPixel>
{
image = new Image<TPixel>(this.configuration, this.header.Width, this.header.Height, metadata);
image = Image.CreateUninitialized<TPixel>(
this.configuration,
this.header.Width,
this.header.Height,
metadata);
this.bytesPerPixel = this.CalculateBytesPerPixel();
this.bytesPerScanline = this.CalculateScanlineLength(this.header.Width) + 1;
this.bytesPerSample = 1;

29
src/ImageSharp/Formats/Png/PngEncoderCore.cs

@ -5,10 +5,8 @@ using System;
using System.Buffers;
using System.Buffers.Binary;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.Formats.Png.Chunks;
using SixLabors.ImageSharp.Formats.Png.Filters;
@ -16,7 +14,6 @@ using SixLabors.ImageSharp.Formats.Png.Zlib;
using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.Metadata;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing.Processors.Quantization;
namespace SixLabors.ImageSharp.Formats.Png
{
@ -633,10 +630,21 @@ namespace SixLabors.ImageSharp.Formats.Png
private void WriteTextChunks(Stream stream, PngMetadata meta)
{
const int MaxLatinCode = 255;
foreach (PngTextData textData in meta.TextData)
for (int i = 0; i < meta.TextData.Count; i++)
{
bool hasUnicodeCharacters = textData.Value.Any(c => c > MaxLatinCode);
if (hasUnicodeCharacters || (!string.IsNullOrWhiteSpace(textData.LanguageTag) || !string.IsNullOrWhiteSpace(textData.TranslatedKeyword)))
PngTextData textData = meta.TextData[i];
bool hasUnicodeCharacters = false;
foreach (var c in textData.Value)
{
if (c > MaxLatinCode)
{
hasUnicodeCharacters = true;
break;
}
}
if (hasUnicodeCharacters || (!string.IsNullOrWhiteSpace(textData.LanguageTag) ||
!string.IsNullOrWhiteSpace(textData.TranslatedKeyword)))
{
// Write iTXt chunk.
byte[] keywordBytes = PngConstants.Encoding.GetBytes(textData.Keyword);
@ -647,7 +655,8 @@ namespace SixLabors.ImageSharp.Formats.Png
byte[] translatedKeyword = PngConstants.TranslatedEncoding.GetBytes(textData.TranslatedKeyword);
byte[] languageTag = PngConstants.LanguageEncoding.GetBytes(textData.LanguageTag);
Span<byte> outputBytes = new byte[keywordBytes.Length + textBytes.Length + translatedKeyword.Length + languageTag.Length + 5];
Span<byte> outputBytes = new byte[keywordBytes.Length + textBytes.Length +
translatedKeyword.Length + languageTag.Length + 5];
keywordBytes.CopyTo(outputBytes);
if (textData.Value.Length > this.options.TextCompressionThreshold)
{
@ -667,7 +676,8 @@ namespace SixLabors.ImageSharp.Formats.Png
if (textData.Value.Length > this.options.TextCompressionThreshold)
{
// Write zTXt chunk.
byte[] compressedData = this.GetCompressedTextBytes(PngConstants.Encoding.GetBytes(textData.Value));
byte[] compressedData =
this.GetCompressedTextBytes(PngConstants.Encoding.GetBytes(textData.Value));
Span<byte> outputBytes = new byte[textData.Keyword.Length + compressedData.Length + 2];
PngConstants.Encoding.GetBytes(textData.Keyword).CopyTo(outputBytes);
compressedData.CopyTo(outputBytes.Slice(textData.Keyword.Length + 2));
@ -678,7 +688,8 @@ namespace SixLabors.ImageSharp.Formats.Png
// Write tEXt chunk.
Span<byte> outputBytes = new byte[textData.Keyword.Length + textData.Value.Length + 1];
PngConstants.Encoding.GetBytes(textData.Keyword).CopyTo(outputBytes);
PngConstants.Encoding.GetBytes(textData.Value).CopyTo(outputBytes.Slice(textData.Keyword.Length + 1));
PngConstants.Encoding.GetBytes(textData.Value)
.CopyTo(outputBytes.Slice(textData.Keyword.Length + 1));
this.WriteChunk(stream, PngChunkType.Text, outputBytes.ToArray());
}
}

16
src/ImageSharp/Formats/Png/Zlib/DeflaterEngine.cs

@ -525,12 +525,15 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
break;
case 2:
if (pinnedWindow[++scan] == pinnedWindow[++match]
&& pinnedWindow[++scan] == pinnedWindow[++match])
if ((short*)pinnedWindow[++scan] == (short*)pinnedWindow[++match])
{
++scan;
++match;
break;
}
++scan;
++match;
break;
case 3:
@ -544,14 +547,15 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
break;
case 4:
if (pinnedWindow[++scan] == pinnedWindow[++match]
&& pinnedWindow[++scan] == pinnedWindow[++match]
&& pinnedWindow[++scan] == pinnedWindow[++match]
&& pinnedWindow[++scan] == pinnedWindow[++match])
if ((int*)pinnedWindow[++scan] == (int*)pinnedWindow[++match])
{
scan += 3;
match += 3;
break;
}
scan += 3;
match += 3;
break;
case 5:

Loading…
Cancel
Save