Skip to content

Commit ec4eca1

Browse files
Merge pull request #1054 from SixLabors/js/managed-zlib
Fix Png Encoder Compression
2 parents 2010afa + a92e7e7 commit ec4eca1

File tree

14 files changed

+2672
-70
lines changed

14 files changed

+2672
-70
lines changed

src/ImageSharp/Formats/Png/PngEncoderCore.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -699,7 +699,7 @@ private byte[] GetCompressedTextBytes(byte[] textBytes)
699699
{
700700
using (var memoryStream = new MemoryStream())
701701
{
702-
using (var deflateStream = new ZlibDeflateStream(memoryStream, this.options.CompressionLevel))
702+
using (var deflateStream = new ZlibDeflateStream(this.memoryAllocator, memoryStream, this.options.CompressionLevel))
703703
{
704704
deflateStream.Write(textBytes);
705705
}
@@ -790,7 +790,7 @@ private void WriteDataChunks<TPixel>(ImageFrame<TPixel> pixels, IQuantizedFrame<
790790

791791
using (var memoryStream = new MemoryStream())
792792
{
793-
using (var deflateStream = new ZlibDeflateStream(memoryStream, this.options.CompressionLevel))
793+
using (var deflateStream = new ZlibDeflateStream(this.memoryAllocator, memoryStream, this.options.CompressionLevel))
794794
{
795795
if (this.options.InterlaceMethod == PngInterlaceMode.Adam7)
796796
{

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

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
// Copyright (c) Six Labors and contributors.
1+
// Copyright (c) Six Labors and contributors.
22
// Licensed under the Apache License, Version 2.0.
33

44
using System;
55
using System.Runtime.CompilerServices;
6+
using System.Runtime.InteropServices;
67

78
namespace SixLabors.ImageSharp.Formats.Png.Zlib
89
{
@@ -112,7 +113,7 @@ public void Update(int value)
112113
[MethodImpl(MethodImplOptions.AggressiveInlining)]
113114
public void Update(ReadOnlySpan<byte> data)
114115
{
115-
// (By Per Bothner)
116+
ref byte dataRef = ref MemoryMarshal.GetReference(data);
116117
uint s1 = this.checksum & 0xFFFF;
117118
uint s2 = this.checksum >> 16;
118119

@@ -133,8 +134,8 @@ public void Update(ReadOnlySpan<byte> data)
133134
count -= n;
134135
while (--n >= 0)
135136
{
136-
s1 = s1 + (uint)(data[offset++] & 0xff);
137-
s2 = s2 + s1;
137+
s1 += Unsafe.Add(ref dataRef, offset++);
138+
s2 += s1;
138139
}
139140

140141
s1 %= Base;
@@ -144,4 +145,4 @@ public void Update(ReadOnlySpan<byte> data)
144145
this.checksum = (s2 << 16) | s1;
145146
}
146147
}
147-
}
148+
}

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
// Copyright (c) Six Labors and contributors.
1+
// Copyright (c) Six Labors and contributors.
22
// Licensed under the Apache License, Version 2.0.
33

44
using System;
55
using System.Runtime.CompilerServices;
6+
using System.Runtime.InteropServices;
67

78
namespace SixLabors.ImageSharp.Formats.Png.Zlib
89
{
@@ -141,9 +142,10 @@ public void Update(ReadOnlySpan<byte> data)
141142
{
142143
this.crc ^= CrcSeed;
143144

145+
ref uint crcTableRef = ref MemoryMarshal.GetReference(CrcTable.AsSpan());
144146
for (int i = 0; i < data.Length; i++)
145147
{
146-
this.crc = CrcTable[(this.crc ^ data[i]) & 0xFF] ^ (this.crc >> 8);
148+
this.crc = Unsafe.Add(ref crcTableRef, (int)((this.crc ^ data[i]) & 0xFF)) ^ (this.crc >> 8);
147149
}
148150

149151
this.crc ^= CrcSeed;
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// Copyright (c) Six Labors and contributors.
2+
// Licensed under the Apache License, Version 2.0.
3+
4+
using System;
5+
using System.Runtime.CompilerServices;
6+
7+
namespace SixLabors.ImageSharp.Formats.Png.Zlib
8+
{
9+
internal static class DeflateThrowHelper
10+
{
11+
[MethodImpl(InliningOptions.ColdPath)]
12+
public static void ThrowAlreadyFinished() => throw new InvalidOperationException("Finish() already called.");
13+
14+
[MethodImpl(InliningOptions.ColdPath)]
15+
public static void ThrowAlreadyClosed() => throw new InvalidOperationException("Deflator already closed.");
16+
17+
[MethodImpl(InliningOptions.ColdPath)]
18+
public static void ThrowUnknownCompression() => throw new InvalidOperationException("Unknown compression function.");
19+
20+
[MethodImpl(InliningOptions.ColdPath)]
21+
public static void ThrowNotProcessed() => throw new InvalidOperationException("Old input was not completely processed.");
22+
23+
[MethodImpl(InliningOptions.ColdPath)]
24+
public static void ThrowNull(string name) => throw new ArgumentNullException(name);
25+
26+
[MethodImpl(InliningOptions.ColdPath)]
27+
public static void ThrowOutOfRange(string name) => throw new ArgumentOutOfRangeException(name);
28+
29+
[MethodImpl(InliningOptions.ColdPath)]
30+
public static void ThrowHeapViolated() => throw new InvalidOperationException("Huffman heap invariant violated.");
31+
32+
[MethodImpl(InliningOptions.ColdPath)]
33+
public static void ThrowNoDeflate() => throw new ImageFormatException("Cannot deflate all input.");
34+
}
35+
}

0 commit comments

Comments
 (0)