@@ -58,31 +58,42 @@ private static IImageFormat InternalDetectFormat(Stream stream, Configuration co
5858 return null ;
5959 }
6060
61- using ( IMemoryOwner < byte > buffer = config . MemoryAllocator . Allocate < byte > ( headerSize , AllocationOptions . Clean ) )
61+ // Header sizes are so small, that headersBuffer will be always stackalloc-ed in practice,
62+ // and heap allocation will never happen, there is no need for the usual try-finally ArrayPool dance.
63+ // The array case is only a safety mechanism following stackalloc best practices.
64+ Span < byte > headersBuffer = headerSize > 512 ? new byte [ headerSize ] : stackalloc byte [ headerSize ] ;
65+ long startPosition = stream . Position ;
66+
67+ // Read doesn't always guarantee the full returned length so read a byte
68+ // at a time until we get either our count or hit the end of the stream.
69+ int n = 0 ;
70+ int i ;
71+ do
6272 {
63- Span < byte > bufferSpan = buffer . GetSpan ( ) ;
64- long startPosition = stream . Position ;
73+ i = stream . Read ( headersBuffer , n , headerSize - n ) ;
74+ n += i ;
75+ }
76+ while ( n < headerSize && i > 0 ) ;
6577
66- // Read doesn't always guarantee the full returned length so read a byte
67- // at a time until we get either our count or hit the end of the stream.
68- int n = 0 ;
69- int i ;
70- do
78+ stream . Position = startPosition ;
79+
80+ // Does the given stream contain enough data to fit in the header for the format
81+ // and does that data match the format specification?
82+ // Individual formats should still check since they are public.
83+ IImageFormat format = null ;
84+ foreach ( IImageFormatDetector formatDetector in config . ImageFormatsManager . FormatDetectors )
85+ {
86+ if ( formatDetector . HeaderSize <= headerSize )
7187 {
72- i = stream . Read ( bufferSpan , n , headerSize - n ) ;
73- n += i ;
88+ IImageFormat attemptFormat = formatDetector . DetectFormat ( headersBuffer ) ;
89+ if ( attemptFormat != null )
90+ {
91+ format = attemptFormat ;
92+ }
7493 }
75- while ( n < headerSize && i > 0 ) ;
76-
77- stream . Position = startPosition ;
78-
79- // Does the given stream contain enough data to fit in the header for the format
80- // and does that data match the format specification?
81- // Individual formats should still check since they are public.
82- return config . ImageFormatsManager . FormatDetectors
83- . Where ( x => x . HeaderSize <= headerSize )
84- . Select ( x => x . DetectFormat ( buffer . GetSpan ( ) ) ) . LastOrDefault ( x => x != null ) ;
8594 }
95+
96+ return format ;
8697 }
8798
8899 /// <summary>
0 commit comments