1+ #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1
2+ using System . Buffers ;
3+ #endif
14using System ;
25using System . IO ;
36using System . IO . Compression ;
@@ -36,7 +39,11 @@ public byte[] GetGraphic(int pixelsPerModule, bool drawQuietZones = true)
3639 using var png = new PngBuilder ( ) ;
3740 var size = ( QrCodeData . ModuleMatrix . Count - ( drawQuietZones ? 0 : 8 ) ) * pixelsPerModule ;
3841 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
4047 png . WriteEnd ( ) ;
4148 return png . GetBytes ( ) ;
4249 }
@@ -68,7 +75,11 @@ public byte[] GetGraphic(int pixelsPerModule, byte[] darkColorRgba, byte[] light
6875 var size = ( QrCodeData . ModuleMatrix . Count - ( drawQuietZones ? 0 : 8 ) ) * pixelsPerModule ;
6976 png . WriteHeader ( size , size , 1 , PngBuilder . ColorType . Indexed ) ;
7077 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
7283 png . WriteEnd ( ) ;
7384 return png . GetBytes ( ) ;
7485 }
@@ -79,13 +90,19 @@ public byte[] GetGraphic(int pixelsPerModule, byte[] darkColorRgba, byte[] light
7990 /// <param name="pixelsPerModule">The number of pixels each dark/light module of the QR code will occupy in the final QR code image.</param>
8091 /// <param name="drawQuietZones">Indicates if quiet zones around the QR code should be drawn.</param>
8192 /// <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 )
8394 {
8495 var moduleMatrix = QrCodeData . ModuleMatrix ;
8596 var matrixSize = moduleMatrix . Count - ( drawQuietZones ? 0 : 8 ) ;
8697 var quietZoneOffset = ( drawQuietZones ? 0 : 4 ) ;
8798 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
89106
90107 for ( var y = 0 ; y < matrixSize ; y ++ )
91108 {
@@ -115,7 +132,7 @@ private byte[] DrawScanlines(int pixelsPerModule, bool drawQuietZones)
115132 }
116133 }
117134
118- return scanlines ;
135+ return new ArraySegment < byte > ( scanlines , 0 , scanLinesLength ) ;
119136 }
120137
121138 /// <summary>
@@ -249,7 +266,7 @@ public void WritePalette(params byte[][] rgbaColors)
249266 /// <summary>
250267 /// Writes the IDAT chunk with the actual picture.
251268 /// </summary>
252- public void WriteScanlines ( byte [ ] scanlines )
269+ public void WriteScanlines ( ArraySegment < byte > scanlines )
253270 {
254271 using var idatStream = new MemoryStream ( ) ;
255272 Deflate ( idatStream , scanlines ) ;
@@ -268,7 +285,7 @@ public void WriteScanlines(byte[] scanlines)
268285 idatStream . CopyTo ( _stream ) ;
269286#endif
270287 // Deflate checksum.
271- var adler = Adler32 ( scanlines , 0 , scanlines . Length ) ;
288+ var adler = Adler32 ( scanlines . Array ! , 0 , scanlines . Count ) ;
272289 WriteIntBigEndian ( adler ) ;
273290
274291 WriteChunkEnd ( ) ;
@@ -304,10 +321,10 @@ private void WriteIntBigEndian(uint value)
304321 _stream . WriteByte ( ( byte ) value ) ;
305322 }
306323
307- private static void Deflate ( Stream output , byte [ ] bytes )
324+ private static void Deflate ( Stream output , ArraySegment < byte > bytes )
308325 {
309326 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 ) ;
311328 }
312329
313330 // Reference implementation from RFC 1950. Not optimized.
0 commit comments