Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 26 additions & 9 deletions QRCoder/PngByteQRCode.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1
using System.Buffers;
#endif
using System;
using System.IO;
using System.IO.Compression;
Expand Down Expand Up @@ -36,7 +39,11 @@
using var png = new PngBuilder();
var size = (QrCodeData.ModuleMatrix.Count - (drawQuietZones ? 0 : 8)) * pixelsPerModule;
png.WriteHeader(size, size, 1, PngBuilder.ColorType.Greyscale);
png.WriteScanlines(DrawScanlines(pixelsPerModule, drawQuietZones));
var scanLines = DrawScanlines(pixelsPerModule, drawQuietZones);
png.WriteScanlines(scanLines);
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1
ArrayPool<byte>.Shared.Return(scanLines.Array!);
#endif
png.WriteEnd();
return png.GetBytes();
}
Expand Down Expand Up @@ -68,7 +75,11 @@
var size = (QrCodeData.ModuleMatrix.Count - (drawQuietZones ? 0 : 8)) * pixelsPerModule;
png.WriteHeader(size, size, 1, PngBuilder.ColorType.Indexed);
png.WritePalette(darkColorRgba, lightColorRgba);
png.WriteScanlines(DrawScanlines(pixelsPerModule, drawQuietZones));
var scanLines = DrawScanlines(pixelsPerModule, drawQuietZones);
png.WriteScanlines(scanLines);
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1
ArrayPool<byte>.Shared.Return(scanLines.Array!);
#endif
png.WriteEnd();
return png.GetBytes();
}
Expand All @@ -79,13 +90,19 @@
/// <param name="pixelsPerModule">The number of pixels each dark/light module of the QR code will occupy in the final QR code image.</param>
/// <param name="drawQuietZones">Indicates if quiet zones around the QR code should be drawn.</param>
/// <returns>Returns the bitmap as a byte array.</returns>
private byte[] DrawScanlines(int pixelsPerModule, bool drawQuietZones)
private ArraySegment<byte> DrawScanlines(int pixelsPerModule, bool drawQuietZones)
{
var moduleMatrix = QrCodeData.ModuleMatrix;
var matrixSize = moduleMatrix.Count - (drawQuietZones ? 0 : 8);
var quietZoneOffset = (drawQuietZones ? 0 : 4);
var bytesPerScanline = (matrixSize * pixelsPerModule + 7) / 8 + 1; // A monochrome scanline is one byte for filter type then one bit per pixel.
var scanlines = new byte[bytesPerScanline * matrixSize * pixelsPerModule];
var scanLinesLength = bytesPerScanline * matrixSize * pixelsPerModule;
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1

Check failure on line 100 in QRCoder/PngByteQRCode.cs

View workflow job for this annotation

GitHub Actions / format

Fix formatting

Check failure on line 100 in QRCoder/PngByteQRCode.cs

View workflow job for this annotation

GitHub Actions / format

Fix formatting

Check failure on line 100 in QRCoder/PngByteQRCode.cs

View workflow job for this annotation

GitHub Actions / format

Fix formatting

Check failure on line 100 in QRCoder/PngByteQRCode.cs

View workflow job for this annotation

GitHub Actions / format

Fix formatting
var scanlines = ArrayPool<byte>.Shared.Rent(scanLinesLength);
Comment thread
Shane32 marked this conversation as resolved.
Array.Clear(scanlines, 0, scanLinesLength);
#else

Check failure on line 103 in QRCoder/PngByteQRCode.cs

View workflow job for this annotation

GitHub Actions / format

Fix formatting

Check failure on line 103 in QRCoder/PngByteQRCode.cs

View workflow job for this annotation

GitHub Actions / format

Fix formatting

Check failure on line 103 in QRCoder/PngByteQRCode.cs

View workflow job for this annotation

GitHub Actions / format

Fix formatting
var scanlines = new byte[scanLinesLength];
#endif

Check failure on line 105 in QRCoder/PngByteQRCode.cs

View workflow job for this annotation

GitHub Actions / format

Fix formatting

Check failure on line 105 in QRCoder/PngByteQRCode.cs

View workflow job for this annotation

GitHub Actions / format

Fix formatting

Check failure on line 105 in QRCoder/PngByteQRCode.cs

View workflow job for this annotation

GitHub Actions / format

Fix formatting

Comment thread
coderabbitai[bot] marked this conversation as resolved.
for (var y = 0; y < matrixSize; y++)
{
Expand Down Expand Up @@ -115,7 +132,7 @@
}
}

return scanlines;
return new ArraySegment<byte>(scanlines, 0, scanLinesLength);
}

/// <summary>
Expand Down Expand Up @@ -249,7 +266,7 @@
/// <summary>
/// Writes the IDAT chunk with the actual picture.
/// </summary>
public void WriteScanlines(byte[] scanlines)
public void WriteScanlines(ArraySegment<byte> scanlines)
{
using var idatStream = new MemoryStream();
Deflate(idatStream, scanlines);
Expand All @@ -268,7 +285,7 @@
idatStream.CopyTo(_stream);
#endif
// Deflate checksum.
var adler = Adler32(scanlines, 0, scanlines.Length);
var adler = Adler32(scanlines.Array!, 0, scanlines.Count);
WriteIntBigEndian(adler);

WriteChunkEnd();
Expand Down Expand Up @@ -304,10 +321,10 @@
_stream.WriteByte((byte)value);
}

private static void Deflate(Stream output, byte[] bytes)
private static void Deflate(Stream output, ArraySegment<byte> bytes)
{
using var deflateStream = new DeflateStream(output, CompressionMode.Compress, leaveOpen: true);
deflateStream.Write(bytes, 0, bytes.Length);
deflateStream.Write(bytes.Array!, 0, bytes.Count);
}

// Reference implementation from RFC 1950. Not optimized.
Expand Down