@@ -108,7 +108,7 @@ public Image<TPixel> Decode<TPixel>(Stream stream)
108108 {
109109 try
110110 {
111- this . ReadImageHeaders ( stream , out bool inverted , out byte [ ] palette ) ;
111+ int bytesPerColorMapEntry = this . ReadImageHeaders ( stream , out bool inverted , out byte [ ] palette ) ;
112112
113113 var image = new Image < TPixel > ( this . configuration , this . infoHeader . Width , this . infoHeader . Height , this . metaData ) ;
114114
@@ -137,6 +137,7 @@ public Image<TPixel> Decode<TPixel>(Stream stream)
137137 this . infoHeader . Width ,
138138 this . infoHeader . Height ,
139139 this . infoHeader . BitsPerPixel ,
140+ bytesPerColorMapEntry ,
140141 inverted ) ;
141142 }
142143
@@ -329,18 +330,20 @@ private void UncompressRle8(int w, Span<byte> buffer)
329330 /// <param name="colors">The <see cref="T:byte[]"/> containing the colors.</param>
330331 /// <param name="width">The width of the bitmap.</param>
331332 /// <param name="height">The height of the bitmap.</param>
332- /// <param name="bits">The number of bits per pixel.</param>
333+ /// <param name="bitsPerPixel">The number of bits per pixel.</param>
334+ /// <param name="bytesPerColorMapEntry">Usually 4 bytes, but in case of Windows 2.x bitmaps or OS/2 1.x bitmaps
335+ /// the bytes per color palette entry's can be 3 bytes instead of 4.</param>
333336 /// <param name="inverted">Whether the bitmap is inverted.</param>
334- private void ReadRgbPalette < TPixel > ( Buffer2D < TPixel > pixels , byte [ ] colors , int width , int height , int bits , bool inverted )
337+ private void ReadRgbPalette < TPixel > ( Buffer2D < TPixel > pixels , byte [ ] colors , int width , int height , int bitsPerPixel , int bytesPerColorMapEntry , bool inverted )
335338 where TPixel : struct , IPixel < TPixel >
336339 {
337340 // Pixels per byte (bits per pixel)
338- int ppb = 8 / bits ;
341+ int ppb = 8 / bitsPerPixel ;
339342
340343 int arrayWidth = ( width + ppb - 1 ) / ppb ;
341344
342345 // Bit mask
343- int mask = 0xFF >> ( 8 - bits ) ;
346+ int mask = 0xFF >> ( 8 - bitsPerPixel ) ;
344347
345348 // Rows are aligned on 4 byte boundaries
346349 int padding = arrayWidth % 4 ;
@@ -366,7 +369,7 @@ private void ReadRgbPalette<TPixel>(Buffer2D<TPixel> pixels, byte[] colors, int
366369 int colOffset = x * ppb ;
367370 for ( int shift = 0 , newX = colOffset ; shift < ppb && newX < width ; shift ++ , newX ++ )
368371 {
369- int colorIndex = ( ( rowSpan [ offset ] >> ( 8 - bits - ( shift * bits ) ) ) & mask ) * 4 ;
372+ int colorIndex = ( ( rowSpan [ offset ] >> ( 8 - bitsPerPixel - ( shift * bitsPerPixel ) ) ) & mask ) * bytesPerColorMapEntry ;
370373
371374 color . FromBgr24 ( Unsafe . As < byte , Bgr24 > ( ref colors [ colorIndex ] ) ) ;
372375 pixelRow [ newX ] = color ;
@@ -576,7 +579,9 @@ private void ReadFileHeader()
576579 /// <summary>
577580 /// Reads the <see cref="BmpFileHeader"/> and <see cref="BmpInfoHeader"/> from the stream and sets the corresponding fields.
578581 /// </summary>
579- private void ReadImageHeaders ( Stream stream , out bool inverted , out byte [ ] palette )
582+ /// <returns>Bytes per color palette entry. Usually 4 bytes, but in case of Windows 2.x bitmaps or OS/2 1.x bitmaps
583+ /// the bytes per color palette entry's can be 3 bytes instead of 4.</returns>
584+ private int ReadImageHeaders ( Stream stream , out bool inverted , out byte [ ] palette )
580585 {
581586 this . stream = stream ;
582587
@@ -596,19 +601,23 @@ private void ReadImageHeaders(Stream stream, out bool inverted, out byte[] palet
596601 }
597602
598603 int colorMapSize = - 1 ;
604+ int bytesPerColorMapEntry = 4 ;
599605
600606 if ( this . infoHeader . ClrUsed == 0 )
601607 {
602608 if ( this . infoHeader . BitsPerPixel == 1
603609 || this . infoHeader . BitsPerPixel == 4
604610 || this . infoHeader . BitsPerPixel == 8 )
605611 {
606- colorMapSize = ImageMaths . GetColorCountForBitDepth ( this . infoHeader . BitsPerPixel ) * 4 ;
612+ int colorMapSizeBytes = this . fileHeader . Offset - BmpFileHeader . Size - this . infoHeader . HeaderSize ;
613+ int colorCountForBitDepth = ImageMaths . GetColorCountForBitDepth ( this . infoHeader . BitsPerPixel ) ;
614+ bytesPerColorMapEntry = colorMapSizeBytes / colorCountForBitDepth ;
615+ colorMapSize = colorMapSizeBytes ;
607616 }
608617 }
609618 else
610619 {
611- colorMapSize = this . infoHeader . ClrUsed * 4 ;
620+ colorMapSize = this . infoHeader . ClrUsed * bytesPerColorMapEntry ;
612621 }
613622
614623 palette = null ;
@@ -627,6 +636,8 @@ private void ReadImageHeaders(Stream stream, out bool inverted, out byte[] palet
627636 }
628637
629638 this . infoHeader . VerifyDimensions ( ) ;
639+
640+ return bytesPerColorMapEntry ;
630641 }
631642 }
632643}
0 commit comments