@@ -22,7 +22,7 @@ internal sealed class GifDecoderCore : IImageDecoderInternals
22
22
/// <summary>
23
23
/// The temp buffer used to reduce allocations.
24
24
/// </summary>
25
- private readonly byte [ ] buffer = new byte [ 16 ] ;
25
+ private ScratchBuffer buffer ; // mutable struct, don't make readonly
26
26
27
27
/// <summary>
28
28
/// The global color table.
@@ -249,13 +249,13 @@ public ImageInfo Identify(BufferedReadStream stream, CancellationToken cancellat
249
249
/// <param name="stream">The <see cref="BufferedReadStream"/> containing image data.</param>
250
250
private void ReadGraphicalControlExtension ( BufferedReadStream stream )
251
251
{
252
- int bytesRead = stream . Read ( this . buffer , 0 , 6 ) ;
252
+ int bytesRead = stream . Read ( this . buffer . Span , 0 , 6 ) ;
253
253
if ( bytesRead != 6 )
254
254
{
255
255
GifThrowHelper . ThrowInvalidImageContentException ( "Not enough data to read the graphic control extension" ) ;
256
256
}
257
257
258
- this . graphicsControlExtension = GifGraphicControlExtension . Parse ( this . buffer ) ;
258
+ this . graphicsControlExtension = GifGraphicControlExtension . Parse ( this . buffer . Span ) ;
259
259
}
260
260
261
261
/// <summary>
@@ -264,13 +264,13 @@ private void ReadGraphicalControlExtension(BufferedReadStream stream)
264
264
/// <param name="stream">The <see cref="BufferedReadStream"/> containing image data.</param>
265
265
private void ReadImageDescriptor ( BufferedReadStream stream )
266
266
{
267
- int bytesRead = stream . Read ( this . buffer , 0 , 9 ) ;
267
+ int bytesRead = stream . Read ( this . buffer . Span , 0 , 9 ) ;
268
268
if ( bytesRead != 9 )
269
269
{
270
270
GifThrowHelper . ThrowInvalidImageContentException ( "Not enough data to read the image descriptor" ) ;
271
271
}
272
272
273
- this . imageDescriptor = GifImageDescriptor . Parse ( this . buffer ) ;
273
+ this . imageDescriptor = GifImageDescriptor . Parse ( this . buffer . Span ) ;
274
274
if ( this . imageDescriptor . Height == 0 || this . imageDescriptor . Width == 0 )
275
275
{
276
276
GifThrowHelper . ThrowInvalidImageContentException ( "Width or height should not be 0" ) ;
@@ -283,13 +283,13 @@ private void ReadImageDescriptor(BufferedReadStream stream)
283
283
/// <param name="stream">The <see cref="BufferedReadStream"/> containing image data.</param>
284
284
private void ReadLogicalScreenDescriptor ( BufferedReadStream stream )
285
285
{
286
- int bytesRead = stream . Read ( this . buffer , 0 , 7 ) ;
286
+ int bytesRead = stream . Read ( this . buffer . Span , 0 , 7 ) ;
287
287
if ( bytesRead != 7 )
288
288
{
289
289
GifThrowHelper . ThrowInvalidImageContentException ( "Not enough data to read the logical screen descriptor" ) ;
290
290
}
291
291
292
- this . logicalScreenDescriptor = GifLogicalScreenDescriptor . Parse ( this . buffer ) ;
292
+ this . logicalScreenDescriptor = GifLogicalScreenDescriptor . Parse ( this . buffer . Span ) ;
293
293
}
294
294
295
295
/// <summary>
@@ -306,8 +306,8 @@ private void ReadApplicationExtension(BufferedReadStream stream)
306
306
long position = stream . Position ;
307
307
if ( appLength == GifConstants . ApplicationBlockSize )
308
308
{
309
- stream . Read ( this . buffer , 0 , GifConstants . ApplicationBlockSize ) ;
310
- bool isXmp = this . buffer . AsSpan ( ) . StartsWith ( GifConstants . XmpApplicationIdentificationBytes ) ;
309
+ stream . Read ( this . buffer . Span , 0 , GifConstants . ApplicationBlockSize ) ;
310
+ bool isXmp = this . buffer . Span . StartsWith ( GifConstants . XmpApplicationIdentificationBytes ) ;
311
311
if ( isXmp && ! this . skipMetadata )
312
312
{
313
313
GifXmpApplicationExtension extension = GifXmpApplicationExtension . Read ( stream , this . memoryAllocator ) ;
@@ -331,8 +331,8 @@ private void ReadApplicationExtension(BufferedReadStream stream)
331
331
// http://www.vurdalakov.net/misc/gif/netscape-buffering-application-extension
332
332
if ( subBlockSize == GifConstants . NetscapeLoopingSubBlockSize )
333
333
{
334
- stream . Read ( this . buffer , 0 , GifConstants . NetscapeLoopingSubBlockSize ) ;
335
- this . gifMetadata ! . RepeatCount = GifNetscapeLoopingApplicationExtension . Parse ( this . buffer . AsSpan ( 1 ) ) . RepeatCount ;
334
+ stream . Read ( this . buffer . Span , 0 , GifConstants . NetscapeLoopingSubBlockSize ) ;
335
+ this . gifMetadata ! . RepeatCount = GifNetscapeLoopingApplicationExtension . Parse ( this . buffer . Span . Slice ( 1 ) ) . RepeatCount ;
336
336
stream . Skip ( 1 ) ; // Skip the terminator.
337
337
return ;
338
338
}
@@ -762,4 +762,11 @@ private void ReadLogicalScreenDescriptorAndGlobalColorTable(BufferedReadStream s
762
762
}
763
763
}
764
764
}
765
+
766
+ private unsafe struct ScratchBuffer
767
+ {
768
+ private fixed byte scratch [ 16 ] ;
769
+
770
+ public Span < byte > Span => MemoryMarshal . CreateSpan ( ref this . scratch [ 0 ] , 16 ) ;
771
+ }
765
772
}
0 commit comments