22// Licensed under the Apache License, Version 2.0.
33
44using System ;
5+ using System . Buffers ;
56using System . IO ;
67
78namespace ImageMagick ;
89
9- internal sealed unsafe class ByteArrayWrapper
10- {
11- private byte [ ] _bytes = new byte [ 8192 ] ;
12- private int _offset = 0 ;
13- private int _length = 0 ;
10+ internal sealed unsafe class ByteArrayWrapper {
11+ private static readonly ArrayPool < byte > _pool = ArrayPool < byte > . Create ( 1024 * 1024 * 64 , 1024 ) ;
12+ private byte [ ] _bytes = _pool . Rent ( 1024 * 1024 ) ;
13+ private int _length ;
14+ private int _offset ;
1415
1516 public byte [ ] GetBytes ( )
1617 {
17- ResizeBytes ( _length ) ;
18- return _bytes ;
18+ var result = new byte [ _length ] ;
19+ Array . Copy ( _bytes , result , Math . Min ( _bytes . Length , _length ) ) ;
20+ _pool . Return ( _bytes , true ) ;
21+ return result ;
1922 }
2023
2124 public long Read ( IntPtr data , UIntPtr count , IntPtr user_data )
2225 {
2326 if ( data == IntPtr . Zero )
27+ {
2428 return 0 ;
29+ }
30+
31+ int total = ( int ) count ;
2532
26- var total = ( int ) count ;
2733 if ( total == 0 )
34+ {
2835 return 0 ;
36+ }
37+
38+ int length = Math . Min ( total , _length - _offset ) ;
2939
30- var length = Math . Min ( total , _length - _offset ) ;
3140 if ( length != 0 )
3241 {
33- var destination = ( byte * ) data . ToPointer ( ) ;
42+ byte * destination = ( byte * ) data . ToPointer ( ) ;
43+
3444 fixed ( byte * source = _bytes )
3545 {
3646 NativeMemory . Copy ( source + _offset , destination , length ) ;
@@ -44,43 +54,54 @@ public long Read(IntPtr data, UIntPtr count, IntPtr user_data)
4454
4555 public long Seek ( long offset , IntPtr whence , IntPtr user_data )
4656 {
47- var newOffset = ( int ) ( ( SeekOrigin ) whence switch
48- {
49- SeekOrigin . Begin => offset ,
50- SeekOrigin . Current => _offset + offset ,
51- SeekOrigin . End => _length - offset ,
52- _ => - 1 ,
53- } ) ;
57+ int newOffset = ( int ) ( ( SeekOrigin ) whence switch
58+ {
59+ SeekOrigin . Begin => offset ,
60+ SeekOrigin . Current => _offset + offset ,
61+ SeekOrigin . End => _length - offset ,
62+ _ => - 1
63+ } ) ;
5464
5565 if ( _offset == newOffset )
66+ {
5667 return _offset ;
68+ }
5769
5870 if ( newOffset < 0 )
71+ {
5972 return - 1 ;
73+ }
6074
6175 _offset = newOffset ;
6276
6377 return _offset ;
6478 }
6579
6680 public long Tell ( IntPtr user_data )
67- => _offset ;
81+ {
82+ return _offset ;
83+ }
6884
6985 public long Write ( IntPtr data , UIntPtr count , IntPtr user_data )
7086 {
7187 if ( data == IntPtr . Zero )
88+ {
7289 return 0 ;
90+ }
7391
74- var total = ( int ) count ;
92+ int total = ( int ) count ;
7593
7694 if ( total == 0 )
95+ {
7796 return 0 ;
97+ }
7898
79- var newOffset = _offset + total ;
99+ int newOffset = _offset + total ;
80100
81101 EnsureLength ( newOffset ) ;
82102
83- var source = ( byte * ) data . ToPointer ( ) ;
103+ byte * source = ( byte * ) data . ToPointer ( ) ;
104+
84105 fixed ( byte * destination = _bytes )
85106 {
86107 NativeMemory . Copy ( source , destination + _offset , total ) ;
@@ -94,17 +115,26 @@ public long Write(IntPtr data, UIntPtr count, IntPtr user_data)
94115 private void EnsureLength ( int length )
95116 {
96117 if ( length < _length )
118+ {
97119 return ;
120+ }
98121
99122 _length = length ;
100123
101124 if ( _length < _bytes . Length )
125+ {
102126 return ;
127+ }
103128
104- var newLength = Math . Max ( _bytes . Length * 2 , _length ) ;
129+ int newLength = Math . Max ( _bytes . Length * 2 , _length ) ;
105130 ResizeBytes ( newLength ) ;
106131 }
107132
108133 private void ResizeBytes ( int length )
109- => Array . Resize ( ref _bytes , length ) ;
134+ {
135+ byte [ ] byte2 = _pool . Rent ( length ) ;
136+ Array . Copy ( _bytes , byte2 , Math . Min ( _bytes . Length , length ) ) ;
137+ _pool . Return ( _bytes , true ) ;
138+ _bytes = byte2 ;
139+ }
110140}
0 commit comments