@@ -828,20 +828,25 @@ public byte[] ExtractAlphaData()
828828 {
829829 if ( BitsPerPixel == 32 )
830830 {
831- var alpha = new List < byte > ( Image . Width * Image . Height ) ;
831+ var alpha = new byte [ Image . Width * Image . Height ] ;
832+ int alphaIndex = 0 ;
832833 using var rgbaImage = Image is Image < SixLabors . ImageSharp . PixelFormats . Rgba32 > image
833834 ? image
834835 : Image . CloneAs < SixLabors . ImageSharp . PixelFormats . Rgba32 > ( ) ;
835836 rgbaImage . ProcessPixelRows ( accessor =>
836837 {
837838 for ( int y = 0 ; y < accessor . Height ; y ++ )
838839 {
839- Span < SixLabors . ImageSharp . PixelFormats . Rgba32 > pixelRow = accessor . GetRowSpan ( y ) ;
840-
841- for ( int x = 0 ; x < pixelRow . Length ; x ++ )
840+ // Get the row as a span of Rgba32.
841+ Span < Rgba32 > pixelRow = accessor . GetRowSpan ( y ) ;
842+ // Interpret the row as a span of bytes.
843+ Span < byte > rowBytes = MemoryMarshal . AsBytes ( pixelRow ) ;
844+
845+ // Each pixel is 4 bytes: R, G, B, A.
846+ // The alpha channel is the fourth byte (index 3, 7, 11, ...).
847+ for ( int i = 3 ; i < rowBytes . Length ; i += 4 )
842848 {
843- SixLabors . ImageSharp . PixelFormats . Rgba32 pixel = pixelRow [ x ] ;
844- alpha . Add ( pixel . A ) ;
849+ alpha [ alphaIndex ++ ] = rowBytes [ i ] ;
845850 }
846851 }
847852 } ) ;
@@ -2332,20 +2337,35 @@ private bool IsThumbnail(Tiff tiff)
23322337
23332338 private ReadOnlySpan < byte > PrepareByteArray ( Image < Rgba32 > bmp , int [ ] raster , int width , int height )
23342339 {
2335- byte [ ] bits = new byte [ GetStride ( bmp ) * height ] ;
2340+ int stride = GetStride ( bmp ) ;
2341+ byte [ ] bits = new byte [ stride * height ] ;
23362342
2337- for ( int y = 0 ; y < height ; y ++ )
2343+ // If no extra padding exists, copy entire rows at once.
2344+ if ( stride == width * 4 && true )
23382345 {
2339- int rasterOffset = y * width ;
2340- int bitsOffset = ( height - y - 1 ) * GetStride ( bmp ) ;
2341-
2342- for ( int x = 0 ; x < width ; x ++ )
2346+ int bytesPerRow = stride ;
2347+ for ( int y = 0 ; y < height ; y ++ )
2348+ {
2349+ int srcByteIndex = y * bytesPerRow ;
2350+ int destByteIndex = ( height - y - 1 ) * bytesPerRow ;
2351+ Buffer . BlockCopy ( raster , srcByteIndex , bits , destByteIndex , bytesPerRow ) ;
2352+ }
2353+ }
2354+ else
2355+ {
2356+ // Fallback to per-pixel processing if stride includes padding.
2357+ for ( int y = 0 ; y < height ; y ++ )
23432358 {
2344- int rgba = raster [ rasterOffset ++ ] ;
2345- bits [ bitsOffset ++ ] = ( byte ) ( rgba & 0xff ) ; // R
2346- bits [ bitsOffset ++ ] = ( byte ) ( ( rgba >> 8 ) & 0xff ) ; // G
2347- bits [ bitsOffset ++ ] = ( byte ) ( ( rgba >> 16 ) & 0xff ) ; // B
2348- bits [ bitsOffset ++ ] = ( byte ) ( ( rgba >> 24 ) & 0xff ) ; // A
2359+ int rasterOffset = y * width ;
2360+ int bitsOffset = ( height - y - 1 ) * stride ;
2361+ for ( int x = 0 ; x < width ; x ++ )
2362+ {
2363+ int rgba = raster [ rasterOffset ++ ] ;
2364+ bits [ bitsOffset ++ ] = ( byte ) ( rgba & 0xff ) ; // R
2365+ bits [ bitsOffset ++ ] = ( byte ) ( ( rgba >> 8 ) & 0xff ) ; // G
2366+ bits [ bitsOffset ++ ] = ( byte ) ( ( rgba >> 16 ) & 0xff ) ; // B
2367+ bits [ bitsOffset ++ ] = ( byte ) ( ( rgba >> 24 ) & 0xff ) ; // A
2368+ }
23492369 }
23502370 }
23512371
0 commit comments