Skip to content

Commit

Permalink
Seal and update IFilters to return ReadOnlyMemory<byte> (#843)
Browse files Browse the repository at this point in the history
* Avoid ToArray() in memoryFactory

* Seal and update IFilters to return ReadOnlyMemory<byte>

* Fix filter tests

* Seal and update IFilters to return ReadOnlyMemory<byte>
  • Loading branch information
BobLd authored Jun 8, 2024
1 parent 65a18b2 commit affc1ed
Show file tree
Hide file tree
Showing 18 changed files with 41 additions and 49 deletions.
8 changes: 4 additions & 4 deletions src/UglyToad.PdfPig.Tests/Filters/Ascii85FilterTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public void DecodesWikipediaExample()

var result = filter.Decode(bytes, dictionary, 0);

var text = Encoding.ASCII.GetString(result);
var text = Encoding.ASCII.GetString(result.ToArray());

Assert.Equal("Man is distinguished, not only by his reason, but by this singular passion from other animals, which is a lust of the mind, " +
"that by a perseverance of delight in the continued and indefatigable generation of knowledge, " +
Expand All @@ -37,7 +37,7 @@ public void ReplacesZWithEmptyBytes()

var result = filter.Decode(bytes, dictionary, 1);

var text = Encoding.ASCII.GetString(result);
var text = Encoding.ASCII.GetString(result.ToArray());

Assert.Equal("Man \0\0\0\0is d", text);
}
Expand Down Expand Up @@ -104,7 +104,7 @@ public void DecodesEncodedPdfContent()

var result = filter.Decode(Encoding.ASCII.GetBytes(input), dictionary, 0);

var text = Encoding.ASCII.GetString(result);
var text = Encoding.ASCII.GetString(result.ToArray());

Assert.Equal(PdfContent.Replace("\r\n", "\n"), text);
}
Expand All @@ -124,7 +124,7 @@ public void DecodesEncodedPdfContentMissingEndOfDataSymbol()

var result = filter.Decode(Encoding.ASCII.GetBytes(input), dictionary, 0);

var text = Encoding.ASCII.GetString(result);
var text = Encoding.ASCII.GetString(result.ToArray());

Assert.Equal(PdfContent.Replace("\r\n", "\n"), text);
}
Expand Down
12 changes: 6 additions & 6 deletions src/UglyToad.PdfPig.Tests/Filters/AsciiHexDecodeFilterTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public void DecodesEncodedTextProperly()

var decoded = new AsciiHexDecodeFilter().Decode(input, dictionary, 1);

var decodedText = Encoding.ASCII.GetString(decoded);
var decodedText = Encoding.ASCII.GetString(decoded.ToArray());

Assert.Equal(text, decodedText);
}
Expand All @@ -33,7 +33,7 @@ public void DecodesEncodedTextWithBracesProperly()

var decoded = new AsciiHexDecodeFilter().Decode(input, dictionary, 1);

var decodedText = Encoding.ASCII.GetString(decoded);
var decodedText = Encoding.ASCII.GetString(decoded.ToArray());

Assert.Equal(text, decodedText);
}
Expand All @@ -49,7 +49,7 @@ public void DecodesEncodedTextWithWhitespaceProperly()

var decoded = new AsciiHexDecodeFilter().Decode(input, dictionary, 1);

var decodedText = Encoding.ASCII.GetString(decoded);
var decodedText = Encoding.ASCII.GetString(decoded.ToArray());

Assert.Equal(text, decodedText);
}
Expand All @@ -63,7 +63,7 @@ public void DecodesEncodedTextLowercaseProperly()

var decoded = new AsciiHexDecodeFilter().Decode(input, dictionary, 1);

var decodedText = Encoding.ASCII.GetString(decoded);
var decodedText = Encoding.ASCII.GetString(decoded.ToArray());

Assert.Equal(text, decodedText);
}
Expand All @@ -88,7 +88,7 @@ public void SubstitutesZeroForLastByte()
var decoded = new AsciiHexDecodeFilter().Decode(input, dictionary, 1);

#pragma warning disable SYSLIB0001
var decodedText = Encoding.UTF7.GetString(decoded);
var decodedText = Encoding.UTF7.GetString(decoded.ToArray());
#pragma warning restore SYSLIB0001

Assert.Equal("®P", decodedText);
Expand All @@ -103,7 +103,7 @@ public void DecodesEncodedTextStoppingAtLastBrace()

var decoded = new AsciiHexDecodeFilter().Decode(input, dictionary, 1);

var decodedText = Encoding.ASCII.GetString(decoded);
var decodedText = Encoding.ASCII.GetString(decoded.ToArray());

Assert.Equal(text, decodedText);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public void CanDecodeCCittFaxCompressedImageData()

var expectedBytes = ImageHelpers.LoadFileBytes("ccittfax-decoded.bin");
var decodedBytes = filter.Decode(encodedBytes, new DictionaryToken(dictionary), 0);
Assert.Equal(expectedBytes, decodedBytes);
Assert.Equal(expectedBytes, decodedBytes.ToArray());
}
}
}
2 changes: 1 addition & 1 deletion src/UglyToad.PdfPig.Tests/Filters/FlateFilterTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public void EncodeAndDecodePreservesInput()
inputStream.Seek(0, SeekOrigin.Begin);
var result = filter.Encode(inputStream, parameters, 0);
var decoded = filter.Decode(result, parameters, 0);
Assert.Equal(input, decoded);
Assert.Equal(input, decoded.ToArray());
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/UglyToad.PdfPig.Tests/Filters/RunLengthFilterTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public void CanDecodeRunLengthEncodedData()
10, 19
};

Assert.Equal(expectedResult, decoded);
Assert.Equal(expectedResult, decoded.ToArray());
}

[Fact]
Expand All @@ -61,7 +61,7 @@ public void StopsAtEndOfDataByte()
128, 50
};

Assert.Equal(expectedResult, decoded);
Assert.Equal(expectedResult, decoded.ToArray());
}
}
}
4 changes: 2 additions & 2 deletions src/UglyToad.PdfPig.Tests/Integration/PdfParserTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -96,14 +96,14 @@ public void CanDecompressPngEncodedFlateStream()
});

var filter = new FlateFilter();
var filtered = filter.Decode(streamBytes, dictionary, 0);
var filtered = filter.Decode(streamBytes, dictionary, 0).ToArray();

var expected =
"1 0 15 0 1 0 216 0 1 2 160 0 1 2 210 0 1 3 84 0 1 4 46 0 1 7 165 0 1 70 229 0 1 72 84 0 1 96 235 0 1 98 18 0 2 0 12 0 2 0 12 1 2 0 12 2 2 0 12 3 2 0 12 4 2 0 12 5 2 0 12 6 2 0 12 7 2 0 12 8"
.Split(' ')
.Select(byte.Parse).ToArray();

Assert.Equal(filtered, expected);
Assert.Equal(expected, filtered);
}

/// <summary>
Expand Down
6 changes: 3 additions & 3 deletions src/UglyToad.PdfPig/Content/InlineImage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,14 +93,14 @@ internal InlineImage(PdfRectangle bounds, int widthInSamples, int heightInSample

memoryFactory = supportsFilters ? new Lazy<ReadOnlyMemory<byte>>(() =>
{
var b = rawMemory.Span;
var b = RawMemory;
for (var i = 0; i < filters.Count; i++)
{
var filter = filters[i];
b = filter.Decode(b, streamDictionary, i);
b = filter.Decode(b.Span, streamDictionary, i);
}
return b.ToArray();
return b;
}) : null;
}

Expand Down
8 changes: 3 additions & 5 deletions src/UglyToad.PdfPig/Filters/Ascii85Filter.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
namespace UglyToad.PdfPig.Filters
{
using System;
using System.Collections.Generic;
using Core;
using Tokens;

/// <inheritdoc />
/// <summary>
/// ASCII 85 (Base85) is a binary to text encoding using 5 ASCII characters per 4 bytes of data.
/// </summary>
internal class Ascii85Filter : IFilter
internal sealed class Ascii85Filter : IFilter
{
private const byte EmptyBlock = (byte)'z';
private const byte Offset = (byte)'!';
Expand All @@ -29,7 +28,7 @@ internal class Ascii85Filter : IFilter
public bool IsSupported { get; } = true;

/// <inheritdoc />
public byte[] Decode(ReadOnlySpan<byte> input, DictionaryToken streamDictionary, int filterIndex)
public ReadOnlyMemory<byte> Decode(ReadOnlySpan<byte> input, DictionaryToken streamDictionary, int filterIndex)
{
var asciiBuffer = new byte[5];

Expand Down Expand Up @@ -98,8 +97,7 @@ public byte[] Decode(ReadOnlySpan<byte> input, DictionaryToken streamDictionary,
WriteData(asciiBuffer, index, writer);
}

return writer.WrittenSpan.ToArray();

return writer.WrittenMemory;
}

private static void WriteData(Span<byte> ascii, int index, ArrayPoolBufferWriter<byte> writer)
Expand Down
4 changes: 2 additions & 2 deletions src/UglyToad.PdfPig/Filters/AsciiHexDecodeFilter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ internal sealed class AsciiHexDecodeFilter : IFilter
public bool IsSupported { get; } = true;

/// <inheritdoc />
public byte[] Decode(ReadOnlySpan<byte> input, DictionaryToken streamDictionary, int filterIndex)
public ReadOnlyMemory<byte> Decode(ReadOnlySpan<byte> input, DictionaryToken streamDictionary, int filterIndex)
{
Span<byte> pair = stackalloc byte[2];
var index = 0;
Expand Down Expand Up @@ -69,7 +69,7 @@ public byte[] Decode(ReadOnlySpan<byte> input, DictionaryToken streamDictionary,
WriteHexToByte(pair, writer);
}

return writer.WrittenSpan.ToArray();
return writer.WrittenMemory;
}

private static void WriteHexToByte(ReadOnlySpan<byte> hexBytes, ArrayPoolBufferWriter<byte> writer)
Expand Down
2 changes: 1 addition & 1 deletion src/UglyToad.PdfPig/Filters/CcittFaxDecodeFilter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ internal sealed class CcittFaxDecodeFilter : IFilter
public bool IsSupported { get; } = true;

/// <inheritdoc />
public byte[] Decode(ReadOnlySpan<byte> input, DictionaryToken streamDictionary, int filterIndex)
public ReadOnlyMemory<byte> Decode(ReadOnlySpan<byte> input, DictionaryToken streamDictionary, int filterIndex)
{
var decodeParms = DecodeParameterResolver.GetFilterParameters(streamDictionary, filterIndex);

Expand Down
4 changes: 2 additions & 2 deletions src/UglyToad.PdfPig/Filters/DctDecodeFilter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
using System;
using Tokens;

internal class DctDecodeFilter : IFilter
internal sealed class DctDecodeFilter : IFilter
{
/// <inheritdoc />
public bool IsSupported { get; } = false;

/// <inheritdoc />
public byte[] Decode(ReadOnlySpan<byte> input, DictionaryToken streamDictionary, int filterIndex)
public ReadOnlyMemory<byte> Decode(ReadOnlySpan<byte> input, DictionaryToken streamDictionary, int filterIndex)
{
throw new NotSupportedException("The DST (Discrete Cosine Transform) Filter indicates data is encoded in JPEG format. " +
"This filter is not currently supported but the raw data can be supplied to JPEG supporting libraries.");
Expand Down
8 changes: 3 additions & 5 deletions src/UglyToad.PdfPig/Filters/FlateFilter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ internal sealed class FlateFilter : IFilter
public bool IsSupported { get; } = true;

/// <inheritdoc />
public byte[] Decode(ReadOnlySpan<byte> input, DictionaryToken streamDictionary, int filterIndex)
public ReadOnlyMemory<byte> Decode(ReadOnlySpan<byte> input, DictionaryToken streamDictionary, int filterIndex)
{
var parameters = DecodeParameterResolver.GetFilterParameters(streamDictionary, filterIndex);

Expand All @@ -52,9 +52,7 @@ public byte[] Decode(ReadOnlySpan<byte> input, DictionaryToken streamDictionary,
var bitsPerComponent = parameters.GetIntOrDefault(NameToken.BitsPerComponent, DefaultBitsPerComponent);
var columns = parameters.GetIntOrDefault(NameToken.Columns, DefaultColumns);

var result = PngPredictor.Decode(decompressed, predictor, colors, bitsPerComponent, columns);

return result;
return PngPredictor.Decode(decompressed, predictor, colors, bitsPerComponent, columns);
}
catch
{
Expand All @@ -64,7 +62,7 @@ public byte[] Decode(ReadOnlySpan<byte> input, DictionaryToken streamDictionary,
return bytes;
}

private byte[] Decompress(byte[] input)
private static byte[] Decompress(byte[] input)
{
using (var memoryStream = new MemoryStream(input))
using (var output = new MemoryStream())
Expand Down
2 changes: 1 addition & 1 deletion src/UglyToad.PdfPig/Filters/IFilter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,6 @@ public interface IFilter
/// <param name="streamDictionary">The dictionary of the <see cref="StreamToken"/> (or other dictionary types, e.g. inline images) containing these bytes.</param>
/// <param name="filterIndex">The position of this filter in the pipeline used to encode data.</param>
/// <returns>The decoded bytes.</returns>
byte[] Decode(ReadOnlySpan<byte> input, DictionaryToken streamDictionary, int filterIndex);
ReadOnlyMemory<byte> Decode(ReadOnlySpan<byte> input, DictionaryToken streamDictionary, int filterIndex);
}
}
2 changes: 1 addition & 1 deletion src/UglyToad.PdfPig/Filters/Jbig2DecodeFilter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ internal sealed class Jbig2DecodeFilter : IFilter
public bool IsSupported { get; } = false;

/// <inheritdoc />
public byte[] Decode(ReadOnlySpan<byte> input, DictionaryToken streamDictionary, int filterIndex)
public ReadOnlyMemory<byte> Decode(ReadOnlySpan<byte> input, DictionaryToken streamDictionary, int filterIndex)
{
throw new NotSupportedException("The JBIG2 Filter for monochrome image data is not currently supported. " +
"Try accessing the raw compressed data directly.");
Expand Down
4 changes: 2 additions & 2 deletions src/UglyToad.PdfPig/Filters/JpxDecodeFilter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
using System;
using Tokens;

internal class JpxDecodeFilter : IFilter
internal sealed class JpxDecodeFilter : IFilter
{
/// <inheritdoc />
public bool IsSupported { get; } = false;

/// <inheritdoc />
public byte[] Decode(ReadOnlySpan<byte> input, DictionaryToken streamDictionary, int filterIndex)
public ReadOnlyMemory<byte> Decode(ReadOnlySpan<byte> input, DictionaryToken streamDictionary, int filterIndex)
{
throw new NotSupportedException("The JPX Filter (JPEG2000) for image data is not currently supported. " +
"Try accessing the raw compressed data directly.");
Expand Down
10 changes: 3 additions & 7 deletions src/UglyToad.PdfPig/Filters/LzwFilter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ internal sealed class LzwFilter : IFilter
public bool IsSupported { get; } = true;

/// <inheritdoc />
public byte[] Decode(ReadOnlySpan<byte> input, DictionaryToken streamDictionary, int filterIndex)
public ReadOnlyMemory<byte> Decode(ReadOnlySpan<byte> input, DictionaryToken streamDictionary, int filterIndex)
{
var parameters = DecodeParameterResolver.GetFilterParameters(streamDictionary, filterIndex);

Expand All @@ -45,14 +45,10 @@ public byte[] Decode(ReadOnlySpan<byte> input, DictionaryToken streamDictionary,
var bitsPerComponent = parameters.GetIntOrDefault(NameToken.BitsPerComponent, DefaultBitsPerComponent);
var columns = parameters.GetIntOrDefault(NameToken.Columns, DefaultColumns);

var result = PngPredictor.Decode(decompressed, predictor, colors, bitsPerComponent, columns);

return result;
return PngPredictor.Decode(decompressed, predictor, colors, bitsPerComponent, columns);
}

var data = Decode(input, earlyChange == 1);

return data;
return Decode(input, earlyChange == 1);
}

private static byte[] Decode(ReadOnlySpan<byte> input, bool isEarlyChange)
Expand Down
4 changes: 2 additions & 2 deletions src/UglyToad.PdfPig/Filters/RunLengthFilter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ internal sealed class RunLengthFilter : IFilter
public bool IsSupported { get; } = true;

/// <inheritdoc />
public byte[] Decode(ReadOnlySpan<byte> input, DictionaryToken streamDictionary, int filterIndex)
public ReadOnlyMemory<byte> Decode(ReadOnlySpan<byte> input, DictionaryToken streamDictionary, int filterIndex)
{
using var output = new ArrayPoolBufferWriter<byte>(input.Length);

Expand Down Expand Up @@ -63,7 +63,7 @@ public byte[] Decode(ReadOnlySpan<byte> input, DictionaryToken streamDictionary,
}
}

return output.WrittenSpan.ToArray();
return output.WrittenMemory;
}
}
}
4 changes: 2 additions & 2 deletions src/UglyToad.PdfPig/Polyfills/EncodingExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
#if NETFRAMEWORK || NETSTANDARD2_0
#if !NET

namespace System.Text;

internal static class EncodingExtensions
{
public static string GetString(this Encoding encoding, ReadOnlySpan<byte> bytes)
internal static string GetString(this Encoding encoding, ReadOnlySpan<byte> bytes)
{
if (bytes.IsEmpty)
{
Expand Down

0 comments on commit affc1ed

Please sign in to comment.