@@ -11,22 +11,28 @@ namespace Imazen.WebP
1111 public static class WebPEncoder
1212 {
1313 // Prevent delegate from being GC'd during encoding
14- [ ThreadStatic ] private static WebPWriterFunction ? _writerDelegate ;
14+ private static readonly WebPWriterFunction _writerDelegate = ManagedWriter ;
1515
16- private class EncodeOutput
16+ private sealed class EncodeOutput ( Stream stream )
1717 {
18- public MemoryStream Stream = new MemoryStream ( ) ;
18+ public readonly Stream Stream = stream ;
1919 }
2020
2121 private static int ManagedWriter ( IntPtr data , UIntPtr dataSize , ref WebPPicture picture )
2222 {
2323 int size = ( int ) ( uint ) dataSize ;
2424 if ( size <= 0 ) return 1 ;
25- byte [ ] buffer = new byte [ size ] ;
26- Marshal . Copy ( data , buffer , 0 , size ) ;
2725 var handle = GCHandle . FromIntPtr ( picture . custom_ptr ) ;
2826 var ctx = ( EncodeOutput ) handle . Target ! ;
27+ #if NETCOREAPP
28+ unsafe {
29+ ctx . Stream . Write ( new ReadOnlySpan < byte > ( ( void * ) data , size ) ) ;
30+ }
31+ #else
32+ byte [ ] buffer = new byte [ size ] ;
33+ Marshal . Copy ( data , buffer , 0 , size ) ;
2934 ctx . Stream . Write ( buffer , 0 , size ) ;
35+ #endif
3036 return 1 ;
3137 }
3238
@@ -169,11 +175,23 @@ private static UIntPtr EncodeLossless(IntPtr data, int width, int height, int st
169175 /// <returns>Encoded WebP data</returns>
170176 public static byte [ ] Encode ( byte [ ] pixels , int width , int height , int stride ,
171177 WebPPixelFormat format , WebPEncoderConfig config )
178+ {
179+ var outputStream = new MemoryStream ( ) ;
180+ Encode ( pixels , width , height , stride , format , config , outputStream ) ;
181+ return outputStream . ToArray ( ) ;
182+ }
183+
184+ /// <summary>
185+ /// Encodes raw pixel data using advanced WebPEncoderConfig settings and writes to a stream.
186+ /// </summary>
187+ public static void Encode ( byte [ ] pixels , int width , int height , int stride ,
188+ WebPPixelFormat format , WebPEncoderConfig config , Stream outputStream )
172189 {
173190 if ( pixels == null ) throw new ArgumentNullException ( nameof ( pixels ) ) ;
174191 if ( config == null ) throw new ArgumentNullException ( nameof ( config ) ) ;
175192 if ( width <= 0 ) throw new ArgumentOutOfRangeException ( nameof ( width ) ) ;
176193 if ( height <= 0 ) throw new ArgumentOutOfRangeException ( nameof ( height ) ) ;
194+ if ( outputStream == null ) throw new ArgumentNullException ( nameof ( outputStream ) ) ;
177195
178196 if ( ! config . Validate ( ) )
179197 throw new ArgumentException ( "Invalid WebP encoder configuration" , nameof ( config ) ) ;
@@ -193,10 +211,8 @@ public static byte[] Encode(byte[] pixels, int width, int height, int stride,
193211 picture . use_argb = 1 ;
194212
195213 var pixelHandle = GCHandle . Alloc ( pixels , GCHandleType . Pinned ) ;
196- var output = new EncodeOutput ( ) ;
214+ var output = new EncodeOutput ( outputStream ) ;
197215 var outputHandle = GCHandle . Alloc ( output ) ;
198- // Keep delegate alive during encoding
199- _writerDelegate = ManagedWriter ;
200216 try
201217 {
202218 IntPtr pixelPtr = pixelHandle . AddrOfPinnedObject ( ) ;
@@ -233,8 +249,6 @@ public static byte[] Encode(byte[] pixels, int width, int height, int stride,
233249
234250 if ( encodeResult == 0 )
235251 throw new Exception ( $ "WebP encode failed with error: { picture . error_code } ") ;
236-
237- return output . Stream . ToArray ( ) ;
238252 }
239253 finally
240254 {
@@ -245,19 +259,7 @@ public static byte[] Encode(byte[] pixels, int width, int height, int stride,
245259 } ) ;
246260 pixelHandle . Free ( ) ;
247261 outputHandle . Free ( ) ;
248- _writerDelegate = null ;
249262 }
250263 }
251-
252- /// <summary>
253- /// Encodes raw pixel data using advanced WebPEncoderConfig settings and writes to a stream.
254- /// </summary>
255- public static void Encode ( byte [ ] pixels , int width , int height , int stride ,
256- WebPPixelFormat format , WebPEncoderConfig config , Stream outputStream )
257- {
258- if ( outputStream == null ) throw new ArgumentNullException ( nameof ( outputStream ) ) ;
259- byte [ ] encoded = Encode ( pixels , width , height , stride , format , config ) ;
260- outputStream . Write ( encoded , 0 , encoded . Length ) ;
261- }
262264 }
263265}
0 commit comments