1
+ #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1
2
+ using System . Buffers ;
3
+ #endif
1
4
using System ;
2
5
using System . IO ;
3
6
using System . IO . Compression ;
@@ -36,7 +39,11 @@ public byte[] GetGraphic(int pixelsPerModule, bool drawQuietZones = true)
36
39
using var png = new PngBuilder ( ) ;
37
40
var size = ( QrCodeData . ModuleMatrix . Count - ( drawQuietZones ? 0 : 8 ) ) * pixelsPerModule ;
38
41
png . WriteHeader ( size , size , 1 , PngBuilder . ColorType . Greyscale ) ;
39
- png . WriteScanlines ( DrawScanlines ( pixelsPerModule , drawQuietZones ) ) ;
42
+ var scanLines = DrawScanlines ( pixelsPerModule , drawQuietZones ) ;
43
+ png . WriteScanlines ( scanLines ) ;
44
+ #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1
45
+ ArrayPool < byte > . Shared . Return ( scanLines . Array ! ) ;
46
+ #endif
40
47
png . WriteEnd ( ) ;
41
48
return png . GetBytes ( ) ;
42
49
}
@@ -68,7 +75,11 @@ public byte[] GetGraphic(int pixelsPerModule, byte[] darkColorRgba, byte[] light
68
75
var size = ( QrCodeData . ModuleMatrix . Count - ( drawQuietZones ? 0 : 8 ) ) * pixelsPerModule ;
69
76
png . WriteHeader ( size , size , 1 , PngBuilder . ColorType . Indexed ) ;
70
77
png . WritePalette ( darkColorRgba , lightColorRgba ) ;
71
- png . WriteScanlines ( DrawScanlines ( pixelsPerModule , drawQuietZones ) ) ;
78
+ var scanLines = DrawScanlines ( pixelsPerModule , drawQuietZones ) ;
79
+ png . WriteScanlines ( scanLines ) ;
80
+ #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1
81
+ ArrayPool < byte > . Shared . Return ( scanLines . Array ! ) ;
82
+ #endif
72
83
png . WriteEnd ( ) ;
73
84
return png . GetBytes ( ) ;
74
85
}
@@ -79,13 +90,19 @@ public byte[] GetGraphic(int pixelsPerModule, byte[] darkColorRgba, byte[] light
79
90
/// <param name="pixelsPerModule">The number of pixels each dark/light module of the QR code will occupy in the final QR code image.</param>
80
91
/// <param name="drawQuietZones">Indicates if quiet zones around the QR code should be drawn.</param>
81
92
/// <returns>Returns the bitmap as a byte array.</returns>
82
- private byte [ ] DrawScanlines ( int pixelsPerModule , bool drawQuietZones )
93
+ private ArraySegment < byte > DrawScanlines ( int pixelsPerModule , bool drawQuietZones )
83
94
{
84
95
var moduleMatrix = QrCodeData . ModuleMatrix ;
85
96
var matrixSize = moduleMatrix . Count - ( drawQuietZones ? 0 : 8 ) ;
86
97
var quietZoneOffset = ( drawQuietZones ? 0 : 4 ) ;
87
98
var bytesPerScanline = ( matrixSize * pixelsPerModule + 7 ) / 8 + 1 ; // A monochrome scanline is one byte for filter type then one bit per pixel.
88
- var scanlines = new byte [ bytesPerScanline * matrixSize * pixelsPerModule ] ;
99
+ var scanLinesLength = bytesPerScanline * matrixSize * pixelsPerModule ;
100
+ #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1
101
+ var scanlines = ArrayPool < byte > . Shared . Rent ( scanLinesLength ) ;
102
+ Array . Clear ( scanlines , 0 , scanLinesLength ) ;
103
+ #else
104
+ var scanlines = new byte [ scanLinesLength ] ;
105
+ #endif
89
106
90
107
for ( var y = 0 ; y < matrixSize ; y ++ )
91
108
{
@@ -115,7 +132,7 @@ private byte[] DrawScanlines(int pixelsPerModule, bool drawQuietZones)
115
132
}
116
133
}
117
134
118
- return scanlines ;
135
+ return new ArraySegment < byte > ( scanlines , 0 , scanLinesLength ) ;
119
136
}
120
137
121
138
/// <summary>
@@ -249,7 +266,7 @@ public void WritePalette(params byte[][] rgbaColors)
249
266
/// <summary>
250
267
/// Writes the IDAT chunk with the actual picture.
251
268
/// </summary>
252
- public void WriteScanlines ( byte [ ] scanlines )
269
+ public void WriteScanlines ( ArraySegment < byte > scanlines )
253
270
{
254
271
using var idatStream = new MemoryStream ( ) ;
255
272
Deflate ( idatStream , scanlines ) ;
@@ -268,7 +285,7 @@ public void WriteScanlines(byte[] scanlines)
268
285
idatStream . CopyTo ( _stream ) ;
269
286
#endif
270
287
// Deflate checksum.
271
- var adler = Adler32 ( scanlines , 0 , scanlines . Length ) ;
288
+ var adler = Adler32 ( scanlines . Array ! , 0 , scanlines . Count ) ;
272
289
WriteIntBigEndian ( adler ) ;
273
290
274
291
WriteChunkEnd ( ) ;
@@ -304,10 +321,10 @@ private void WriteIntBigEndian(uint value)
304
321
_stream . WriteByte ( ( byte ) value ) ;
305
322
}
306
323
307
- private static void Deflate ( Stream output , byte [ ] bytes )
324
+ private static void Deflate ( Stream output , ArraySegment < byte > bytes )
308
325
{
309
326
using var deflateStream = new DeflateStream ( output , CompressionMode . Compress , leaveOpen : true ) ;
310
- deflateStream . Write ( bytes , 0 , bytes . Length ) ;
327
+ deflateStream . Write ( bytes . Array ! , 0 , bytes . Count ) ;
311
328
}
312
329
313
330
// Reference implementation from RFC 1950. Not optimized.
0 commit comments