Browse Source

Update Checksum algorithms to use Spans

af/merge-core
Jason Nelson 8 years ago
parent
commit
8770cc71e9
  1. 2
      src/ImageSharp/Formats/Png/PngEncoderCore.cs
  2. 25
      src/ImageSharp/Formats/Png/Zlib/Adler32.cs
  3. 23
      src/ImageSharp/Formats/Png/Zlib/Crc32.cs
  4. 22
      src/ImageSharp/Formats/Png/Zlib/IChecksum.cs
  5. 2
      src/ImageSharp/Formats/Png/Zlib/ZlibDeflateStream.cs

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

@ -677,7 +677,7 @@ namespace SixLabors.ImageSharp.Formats.Png
if (data != null && length > 0)
{
this.crc.Update(data, offset, length);
this.crc.Update(new ReadOnlySpan<byte>(data, offset, length));
}
WriteInteger(stream, (uint)this.crc.Value);

25
src/ImageSharp/Formats/Png/Zlib/Adler32.cs

@ -113,30 +113,15 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Update(byte[] buffer)
public void Update(ReadOnlySpan<byte> data)
{
if (buffer == null)
{
throw new ArgumentNullException(nameof(buffer));
}
this.Update(buffer, 0, buffer.Length);
}
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Update(byte[] buffer, int offset, int count)
{
DebugGuard.NotNull(buffer, nameof(buffer));
DebugGuard.MustBeGreaterThanOrEqualTo(offset, 0, nameof(offset));
DebugGuard.MustBeGreaterThanOrEqualTo(count, 0, nameof(count));
DebugGuard.MustBeLessThan(offset, buffer.Length, nameof(offset));
DebugGuard.MustBeLessThanOrEqualTo(offset + count, buffer.Length, nameof(count));
// (By Per Bothner)
uint s1 = this.checksum & 0xFFFF;
uint s2 = this.checksum >> 16;
int count = data.Length;
int offset = 0;
while (count > 0)
{
// We can defer the modulo operation:
@ -151,7 +136,7 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
count -= n;
while (--n >= 0)
{
s1 = s1 + (uint)(buffer[offset++] & 0xff);
s1 = s1 + (uint)(data[offset++] & 0xff);
s2 = s2 + s1;
}

23
src/ImageSharp/Formats/Png/Zlib/Crc32.cs

@ -137,30 +137,13 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Update(byte[] buffer)
public void Update(ReadOnlySpan<byte> data)
{
if (buffer == null)
{
throw new ArgumentNullException(nameof(buffer));
}
this.Update(buffer, 0, buffer.Length);
}
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Update(byte[] buffer, int offset, int count)
{
DebugGuard.NotNull(buffer, nameof(buffer));
DebugGuard.MustBeGreaterThanOrEqualTo(count, 0, nameof(count));
DebugGuard.MustBeGreaterThanOrEqualTo(offset, 0, nameof(offset));
DebugGuard.MustBeLessThanOrEqualTo(offset + count, buffer.Length, nameof(count));
this.crc ^= CrcSeed;
while (--count >= 0)
for (int i = 0; i < data.Length; i++)
{
this.crc = CrcTable[(this.crc ^ buffer[offset++]) & 0xFF] ^ (this.crc >> 8);
this.crc = CrcTable[(this.crc ^ data[i]) & 0xFF] ^ (this.crc >> 8);
}
this.crc ^= CrcSeed;

22
src/ImageSharp/Formats/Png/Zlib/IChecksum.cs

@ -1,6 +1,8 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System;
namespace SixLabors.ImageSharp.Formats.Png.Zlib
{
/// <summary>
@ -34,25 +36,11 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
void Update(int value);
/// <summary>
/// Updates the data checksum with the bytes taken from the array.
/// Updates the data checksum with the bytes taken from the span.
/// </summary>
/// <param name="buffer">
/// <param name="data">
/// buffer an array of bytes
/// </param>
void Update(byte[] buffer);
/// <summary>
/// Adds the byte array to the data checksum.
/// </summary>
/// <param name = "buffer">
/// The buffer which contains the data
/// </param>
/// <param name = "offset">
/// The offset in the buffer where the data starts
/// </param>
/// <param name = "count">
/// the number of data bytes to add.
/// </param>
void Update(byte[] buffer, int offset, int count);
void Update(ReadOnlySpan<byte> data);
}
}

2
src/ImageSharp/Formats/Png/Zlib/ZlibDeflateStream.cs

@ -163,7 +163,7 @@ namespace SixLabors.ImageSharp.Formats.Png.Zlib
public override void Write(byte[] buffer, int offset, int count)
{
this.deflateStream.Write(buffer, offset, count);
this.adler32.Update(buffer, offset, count);
this.adler32.Update(new ReadOnlySpan<byte>(buffer, offset, count));
}
/// <inheritdoc/>

Loading…
Cancel
Save