WindowsIconReader.st
changeset 2578 7d49dc8ecb63
parent 2571 ae60c0d0452d
child 2756 e8bf6a023191
--- a/WindowsIconReader.st	Wed Dec 03 13:01:33 2008 +0100
+++ b/WindowsIconReader.st	Wed Dec 03 13:24:25 2008 +0100
@@ -47,10 +47,10 @@
     capapble of reading bmp and cursor files.
 
     [See also:]
-        Image Form Icon
-        BlitImageReader FaceReader GIFReader JPEGReader PBMReader PCXReader 
-        ST80FormReader SunRasterReader TargaReader TIFFReader  
-        XBMReader XPMReader XWDReader 
+	Image Form Icon
+	BlitImageReader FaceReader GIFReader JPEGReader PBMReader PCXReader
+	ST80FormReader SunRasterReader TargaReader TIFFReader
+	XBMReader XPMReader XWDReader
 "
 !
 
@@ -58,154 +58,154 @@
 "
     Information from http://www.daubnet.com/formats/BMP.html - no Warranty.
 
-          Name           Size                Description
+	  Name           Size                Description
 
       Header            14 bytes            Windows Structure: BITMAPFILEHEADER
-          Signature      2 bytes             'BM'
-          FileSize       4 bytes             File size in bytes
-          reserved       4 bytes             unused (=0)
-          DataOffset     4 bytes             File offset to Raster Data
+	  Signature      2 bytes             'BM'
+	  FileSize       4 bytes             File size in bytes
+	  reserved       4 bytes             unused (=0)
+	  DataOffset     4 bytes             File offset to Raster Data
 
       InfoHeader        40 bytes            Windows Structure: BITMAPINFOHEADER
 
-          Size           4 bytes             Size of InfoHeader =40 
-          Width          4 bytes             Bitmap Width
-          Height         4 bytes             Bitmap Height
-          Planes         2 bytes             Number of Planes (=1)
-          BitCount       2 bytes             Bits per Pixel   
-                                             1 = monochrome palette. NumColors = 1   
-                                             4 = 4bit palletized. NumColors = 16   
-                                             8 = 8bit palletized. NumColors = 256  
-                                             16 = 16bit RGB. NumColors = 65536 (?)  
-                                             24 = 24bit RGB. NumColors = 16M
-          Compression    4 bytes             Type of Compression   
-                                             0 = BI_RGB   no compression   
-                                             1 = BI_RLE8 8bit RLE encoding   
-                                             2 = BI_RLE4 4bit RLE encoding
-          ImageSize      4 bytes             (compressed) Size of Image  
-                                             It is valid to set this =0 if Compression = 0
-          XpixelsPerM    4 bytes             horizontal resolution: Pixels/meter
-          YpixelsPerM    4 bytes             vertical resolution: Pixels/meter
-          ColorsUsed     4 bytes             Number of actually used colors
-          ColorsImportant
-                         4 bytes             Number of important colors  
-                                             0 = all
+	  Size           4 bytes             Size of InfoHeader =40
+	  Width          4 bytes             Bitmap Width
+	  Height         4 bytes             Bitmap Height
+	  Planes         2 bytes             Number of Planes (=1)
+	  BitCount       2 bytes             Bits per Pixel
+					     1 = monochrome palette. NumColors = 1
+					     4 = 4bit palletized. NumColors = 16
+					     8 = 8bit palletized. NumColors = 256
+					     16 = 16bit RGB. NumColors = 65536 (?)
+					     24 = 24bit RGB. NumColors = 16M
+	  Compression    4 bytes             Type of Compression
+					     0 = BI_RGB   no compression
+					     1 = BI_RLE8 8bit RLE encoding
+					     2 = BI_RLE4 4bit RLE encoding
+	  ImageSize      4 bytes             (compressed) Size of Image
+					     It is valid to set this =0 if Compression = 0
+	  XpixelsPerM    4 bytes             horizontal resolution: Pixels/meter
+	  YpixelsPerM    4 bytes             vertical resolution: Pixels/meter
+	  ColorsUsed     4 bytes             Number of actually used colors
+	  ColorsImportant
+			 4 bytes             Number of important colors
+					     0 = all
        ColorTable        4 * NumColors bytes
-                                             present only if Info.BitsPerPixel <= 8   
-                                             colors should be ordered by importance
+					     present only if Info.BitsPerPixel <= 8
+					     colors should be ordered by importance
 
-            Red           1 byte              Red intensity
-            Green         1 byte              Green intensity
-            Blue          1 byte              Blue intensity
-            reserved      1 byte             unused (=0)
-          repeated NumColors times
+	    Red           1 byte              Red intensity
+	    Green         1 byte              Green intensity
+	    Blue          1 byte              Blue intensity
+	    reserved      1 byte             unused (=0)
+	  repeated NumColors times
 
        Raster Data      Info.ImageSize bytes     The pixel data
 
 
 Raster Data encoding:
-       Depending on the image's BitCount and on the Compression flag there are 6 different encoding schemes. 
-       All of them share the following:  
+       Depending on the image's BitCount and on the Compression flag there are 6 different encoding schemes.
+       All of them share the following:
 
        Pixels are stored bottom-up, left-to-right. Pixel lines are padded with zeros to end on a 32bit (4byte) boundary. For
        uncompressed formats every line will have the same number of bytes. Color indices are zero based, meaning a pixel
        color of 0 represents the first color table entry, a pixel color of 255 (if there are that many) represents the 256th entry.
-       For images with more than 256 colors there is no color table. 
+       For images with more than 256 colors there is no color table.
 
 Raster Data encoding for 1bit / black & white images:
-       BitCount = 1 Compression = 0  
+       BitCount = 1 Compression = 0
        Every byte holds 8 pixels, its highest order bit representing the leftmost pixel of those. There are 2 color table entries.
        Some readers will ignore them though, and assume that 0 is black and 1 is white. If you are storing black and white
        pictures you should stick to this, with any other 2 colors this is not an issue. Remember padding with zeros up to a
-       32bit boundary (This can be up to 31 zeros/pixels!!)                                                                 
+       32bit boundary (This can be up to 31 zeros/pixels!!)
 
 Raster Data encoding for 4bit / 16 color images:
-       BitCount = 4 Compression = 0  
+       BitCount = 4 Compression = 0
        Every byte holds 2 pixels, its high order 4 bits representing the left of those. There are 16 color table entries. These
        colors do not have to be the 16 MS-Windows standard colors. Padding each line with zeros up to a 32bit boundary
        will result in up to 28 zeros = 7 'wasted pixels'.
 
 Raster Data encoding for 8bit / 256 color images:
-       BitCount = 8 Compression = 0  
+       BitCount = 8 Compression = 0
        Every byte holds 1 pixel. There are 256 color table entries. Padding each line with zeros up to a 32bit boundary will
        result in up to 3 bytes of zeros = 3 'wasted pixels'.
 
 Raster Data encoding for 16bit / hicolor images:
-       BitCount = 16 Compression = 0  
-       Every 2bytes / 16bit holds 1 pixel.   
-       <information missing: the 16 bit was introduced together with Video For Windows? Is it a memory-only-format?>  
+       BitCount = 16 Compression = 0
+       Every 2bytes / 16bit holds 1 pixel.
+       <information missing: the 16 bit was introduced together with Video For Windows? Is it a memory-only-format?>
        The pixels are no color table pointers. There are no color table entries. Padding each line with zeros up to a 16bit
        boundary will result in up to 2 zero bytes.
 
 Raster Data encoding for 24bit / truecolor images:
-       BitCount = 24 Compression = 0  
+       BitCount = 24 Compression = 0
        Every 4bytes / 32bit holds 1 pixel. The first holds its red, the second its green, and the third its blue intensity. The
        fourth byte is reserved and should be zero. There are no color table entries. The pixels are no color table pointers. No
        zero padding necessary.
 
 
 Raster Data compression for 4bit / 16 color images:
-       BitCount = 4 Compression = 2  
+       BitCount = 4 Compression = 2
        The pixel data is stored in 2bytes / 16bit chunks.  The first of these specifies the number of consecutive pixels with the
        same pair of color. The second byte defines two color indices. The resulting pixel pattern will be interleaved
        high-order 4bits and low order 4 bits (ABABA...). If the first byte is zero, the second defines an escape code. The
        End-of-Bitmap is zero padded to end on a 32bit boundary. Due to the 16bit-ness of this structure this will always be
-       either two zero bytes or none.   
+       either two zero bytes or none.
 
-        n (byte 1) c (Byte 2)                                       Description
-        >0        any      n pixels are to be drawn. The 1st, 3rd, 5th, ... pixels' color is in c's high-order 4 bits, the even
-                            pixels' color is in c's low-order 4 bits. If both color indices are the same, it results in just n
-                            pixels of color c
-        0         0        End-of-line
-        0         1        End-of-Bitmap
-        0         2        Delta. The following 2 bytes define an unsigned offset in x and y direction (y being up) The
-                            skipped pixels should get a color zero.
-        0         >=3      The following c bytes will be read as single pixel colors just as in uncompressed files. up to 12
-                            bits of zeros follow, to put the file/memory pointer on a 16bit boundary again.
+	n (byte 1) c (Byte 2)                                       Description
+	>0        any      n pixels are to be drawn. The 1st, 3rd, 5th, ... pixels' color is in c's high-order 4 bits, the even
+			    pixels' color is in c's low-order 4 bits. If both color indices are the same, it results in just n
+			    pixels of color c
+	0         0        End-of-line
+	0         1        End-of-Bitmap
+	0         2        Delta. The following 2 bytes define an unsigned offset in x and y direction (y being up) The
+			    skipped pixels should get a color zero.
+	0         >=3      The following c bytes will be read as single pixel colors just as in uncompressed files. up to 12
+			    bits of zeros follow, to put the file/memory pointer on a 16bit boundary again.
 
 
-                                      Example for 4bit RLE
-        Compressed Data                           Expanded data
-        03 04              0 4 0
-        05 06              0 6 0 6 0
-        00 06 45 56 67 00  4 5 5 6 6 7
-        04 78              7 8 7 8
-        00 02 05 01        Move 5 right and 1 up. (Windows docs say down, which is wrong)
-        00 00              End-of-line
-        09 1E              1 E 1 E 1 E 1 E 1
-        00 01              EndofBitmap
-        00 00              Zero padding for 32bit boundary
+				      Example for 4bit RLE
+	Compressed Data                           Expanded data
+	03 04              0 4 0
+	05 06              0 6 0 6 0
+	00 06 45 56 67 00  4 5 5 6 6 7
+	04 78              7 8 7 8
+	00 02 05 01        Move 5 right and 1 up. (Windows docs say down, which is wrong)
+	00 00              End-of-line
+	09 1E              1 E 1 E 1 E 1 E 1
+	00 01              EndofBitmap
+	00 00              Zero padding for 32bit boundary
 
 
 Raster Data compression for 8bit / 256 color images:
 
-       BitCount = 8 Compression = 1  
+       BitCount = 8 Compression = 1
        The pixel data is stored in 2bytes / 16bit chunks.  The first of these specifies the number of consecutive pixels with the
        same color. The second byte defines their color index. If the first byte is zero, the second defines an escape code. The
        End-of-Bitmap is zero padded to end on a 32bit boundary. Due to the 16bit-ness of this structure this will always be
-       either two zero bytes or none.   
+       either two zero bytes or none.
 
-        n (byte 1)   c (Byte 2)                                    Description
-        >0       any        n pixels of color number c
-        0        0          End-of-line
-        0        1          End Of Bitmap
-        0        2          Delta. The following 2 bytes define an unsigned offset in x and y direction (y being up) The
-                            skipped pixels should get a color zero.
-        0        >=3        The following c bytes will be read as single pixel colors just as in uncompressed files. A zero
-                            follows, if c is odd, putting the file/memory pointer on a 16bit boundary again.
+	n (byte 1)   c (Byte 2)                                    Description
+	>0       any        n pixels of color number c
+	0        0          End-of-line
+	0        1          End Of Bitmap
+	0        2          Delta. The following 2 bytes define an unsigned offset in x and y direction (y being up) The
+			    skipped pixels should get a color zero.
+	0        >=3        The following c bytes will be read as single pixel colors just as in uncompressed files. A zero
+			    follows, if c is odd, putting the file/memory pointer on a 16bit boundary again.
 
 
-                                      Example for 8bit RLE
-        Compressed Data                           Expanded data
-        03 04              04 04 04
-        05 06              06 06 06 06 06
-        00 03 45 56 67 00  45 56 67
-        02 78              78 78
-        00 02 05 01        Move 5 right and 1 up. (Windows docs say down, which is wrong)
-        00 00              End-of-line
-        09 1E              1E 1E 1E 1E 1E 1E 1E 1E 1E
-        00 01              End-of-bitmap
-        00 00              Zero padding for 32bit boundary
+				      Example for 8bit RLE
+	Compressed Data                           Expanded data
+	03 04              04 04 04
+	05 06              06 06 06 06 06
+	00 03 45 56 67 00  45 56 67
+	02 78              78 78
+	00 02 05 01        Move 5 right and 1 up. (Windows docs say down, which is wrong)
+	00 00              End-of-line
+	09 1E              1E 1E 1E 1E 1E 1E 1E 1E 1E
+	00 01              End-of-bitmap
+	00 00              Zero padding for 32bit boundary
 
 
 
@@ -218,7 +218,7 @@
 
 
 Trademarks, Patents and Royalties
-       To my knowledge: None.  
+       To my knowledge: None.
 "
 
 ! !
@@ -230,41 +230,12 @@
      for the '.bmp' and '.ico' extensions."
 
     MIMETypes defineImageType:'image/x-MS-bitmap' suffix:'bmp' reader:self.
+    MIMETypes defineImageType:'image/bmp'         suffix:'bmp' reader:self.
     MIMETypes defineImageType:nil                 suffix:'ico' reader:self.
 
     "Modified: 1.2.1997 / 15:03:59 / cg"
 ! !
 
-!WindowsIconReader class methodsFor:'image support'!
-
-loadBMPWidth:w height:h bytesPerPixel:bpp compression:c from:aStream into:data
-    |buff idx fileBytesPerRow imgBytesPerRow align|
-
-    align := 4.
-    c == 0 ifTrue:[
-        imgBytesPerRow := w * bpp.
-        fileBytesPerRow := imgBytesPerRow.
-        (fileBytesPerRow bitAnd:(align-1)) ~~ 0 ifTrue:[
-            fileBytesPerRow := (fileBytesPerRow bitAnd:((align-1) bitInvert)) + align.
-        ].
-        "/
-        "/ stupid - last row comes first
-        "/
-        idx := imgBytesPerRow * (h - 1) + 1.
-        buff := ByteArray uninitializedNew:fileBytesPerRow.
-
-        1 to:h do:[:row |
-            (aStream nextBytes:fileBytesPerRow into:buff) ~~ fileBytesPerRow ifTrue:[
-                ^ false
-            ].
-            data replaceFrom:idx to:idx+imgBytesPerRow-1 with:buff.
-            idx := idx - imgBytesPerRow.
-        ].
-        ^ true
-    ].
-    ^ false.
-! !
-
 !WindowsIconReader class methodsFor:'testing'!
 
 canRepresent:anImage
@@ -287,29 +258,29 @@
     inStream binary.
     ok := false.
     inStream fileSize > 16 ifTrue:[
-        header := ByteArray uninitializedNew:4.
-        inStream nextBytes:4 into:header.
+	header := ByteArray uninitializedNew:4.
+	inStream nextBytes:4 into:header.
 
-        (header startsWith:#(66 77)) ifTrue:[     "BM"
-            ok := true.
+	(header startsWith:#(66 77)) ifTrue:[     "BM"
+	    ok := true.
 "/            'WINREADER: Win3.x or OS/2 vsn 2 BM format' infoPrintNL.
-        ].
-        (header startsWith:#(66 65)) ifTrue:[     "BA"
-            ok := true.
+	].
+	(header startsWith:#(66 65)) ifTrue:[     "BA"
+	    ok := true.
 "/            'WINREADER: OS/2 vsn 2 BA format' infoPrintNL.
-        ].
-        (header startsWith:#(73 67)) ifTrue:[     "IC"
-            ok := true.
+	].
+	(header startsWith:#(73 67)) ifTrue:[     "IC"
+	    ok := true.
 "/            'WINREADER: OS/2 IC format' infoPrintNL.
-        ].
-        (header startsWith:#(80 84)) ifTrue:[     "PT"
-            ok := true.
+	].
+	(header startsWith:#(80 84)) ifTrue:[     "PT"
+	    ok := true.
 "/            'WINREADER: OS/2 PT format' infoPrintNL.
-        ].
-        (header startsWith:#(0 0 1 0)) ifTrue:[
-            ok := true.
+	].
+	(header startsWith:#(0 0 1 0)) ifTrue:[
+	    ok := true.
 "/            'WINREADER: Win3.x ICO format' infoPrintNL.
-        ].
+	].
     ].
     inStream close.
     ^ ok
@@ -323,12 +294,26 @@
 
 !WindowsIconReader methodsFor:'private'!
 
+swapBytesFromRGB_to_BGR
+    |idx bytesPerRow|
+
+    "/ Depth24Image keeps its data r/g/b; BMP has it b/g/r (sigh)
+    idx := 1.
+    bytesPerRow := self bytesPerRow.
+    1 to:height do:[:y |
+	self class swap:bytesPerRow bytesFromRGB_to_BGR_in:data startingAt:idx.
+	idx := idx + bytesPerRow.
+    ].
+! !
+
+!WindowsIconReader methodsFor:'private-reading'!
+
 loadBMP1From:aStream into:aByteArray
     "load bmp-1 bit per pixel imagedata."
 
     compression == 0 ifFalse:[
-        ^ false
-    ].            
+	^ false
+    ].
 
     ^ self loadUncompressedFrom:aStream into:aByteArray
 !
@@ -337,8 +322,8 @@
     "load bmp-2 bit per pixel imagedata."
 
     compression == 0 ifFalse:[
-        ^ false
-    ].            
+	^ false
+    ].
 
     ^ self loadUncompressedFrom:aStream into:aByteArray
 !
@@ -347,375 +332,40 @@
     "load bmp-4 bit per pixel imagedata."
 
     compression == 0 ifTrue:[
-        ^ self loadUncompressedFrom:aStream into:aByteArray
-    ].            
+	^ self loadUncompressedFrom:aStream into:aByteArray
+    ].
     compression == 2 ifTrue:[
-        ^ self loadRLECompressedBMP4From:aStream into:aByteArray
-    ].            
+	^ self loadRLECompressedBMP4From:aStream into:aByteArray
+    ].
 
     ^ false
 !
 
-loadBMP4to8Width:width height:height from:aStream into:aByteArray
-    "load bmp-4 bit per pixel imagedata. A helper for BMP image reader.
-     Primitive c function for speed"
-
-    |f bytes offset|
-
-    aStream isExternalStream ifTrue:[
-        f := aStream filePointer.
-        f isNil ifTrue:[^ false].
-    ] ifFalse:[
-        aStream isInternalByteStream ifTrue:[
-            bytes := aStream collection.
-            bytes isNil ifTrue:[^ false].
-            offset := aStream position.
-        ] ifFalse:[
-            ^ false
-        ]
-    ].
-%{
-#define GETC(fp, cp)    (fp ? getc(fp) : *cp++)
-#define FERROR(fp)      (fp && ferror(fp))
-
-    FILE *__fp = NULL;
-    char *__cp = NULL;
-
-    if (f != nil) {
-        __fp = __FILEVal(f);
-    } else {
-        __cp = __stringVal(bytes);
-        __cp += __intVal(offset);
-    }
-
-    if (! (__bothSmallInteger(width, height)
-           && __isByteArray(aByteArray))) {
-        RETURN (false);
-    }
-
-{
-    int w = __intVal(width);
-    int h = __intVal(height);
-    int comp = __intVal(__INST(compression));
-    unsigned char *dest = __ByteArrayInstPtr(aByteArray)->ba_element;
-    int szDest = __byteArraySize(aByteArray);
-    int   i, j, c, c1, nibnum, padw, x, y;
-    unsigned char *pp;
-
-    c = c1 = 0;
-    if (comp == 0) { /* read uncompressed data */
-        padw = ((w + 7)/8) * 8;  /* 'w', padded to be a multiple of 8pix (32bits) */
-
-        for (i=h-1; i>=0; i--) {
-            pp = dest + (i * w);
-            for (j=nibnum=0; j<padw; j++,nibnum++) {
-                if ((nibnum&1) == 0) { /* read the next byte */
-                    c = GETC(__fp, __cp);
-    console_printf("\nch: %02x ", c);
-                    if (c == EOF) {
-                        if (@global(InfoPrinting) == true) {
-                            console_fprintf(stderr, "ImageReader [warning]: premature EOF\n");
-                        }
-                        RETURN (false);
-                    }
-                    nibnum = 0;
-                }
-                if (j<w) {
-                    if (pp >= (dest+szDest)) {
-                        if (@global(InfoPrinting) == true) {
-                            console_fprintf(stderr, "ImageReader [warning]: BMP outBuffer overrun\n");
-                        }
-                        { RETURN (false) };
-                    }
-                    *pp++ = (c & 0xF0) >> 4;
-console_printf("%d ", pp[-1]);
-                    c <<= 4;
-                }
-            }
-            if (FERROR(__fp)) { RETURN (false) };
-        }
-        RETURN (true);
-    }
-    if (comp == 2) {  /* read RLE4 compressed data */
-        x = y = 0;
-        pp = dest + x + (h-y-1)*w;
-
-        while (y<h) {
-            c = GETC(__fp, __cp); if (c == EOF) { RETURN (false); }
-            if (c) {                                   /* encoded mode */
-                c &= 0xFF;
-                c1 = GETC(__fp, __cp); if (c1 == EOF) { RETURN (false); }
-                for (i=0; i<c; i++,x++,pp++) {
-                    if (pp >= (dest+szDest)) {
-                        if (@global(InfoPrinting) == true) {
-                            console_fprintf(stderr, "ImageReader [warning]: BMP outBuffer overrun\n");
-                        }
-                        return 0;
-                    }
-                    *pp = (i&1) ? (c1 & 0x0f) : ((c1>>4)&0x0f);
-                }
-            } else {
-                /* c==0x00  :  escape codes */
-                c = GETC(__fp, __cp); if (c == EOF) { RETURN (false); }
-
-                if (c == 0x00) {                    /* end of line */
-                    x=0;  y++;  pp = dest + x + (h-y-1)*w;
-                } else
-                    if (c == 0x01) break;               /* end of pic8 */
-
-                    else if (c == 0x02) {                /* delta */
-                        c = GETC(__fp, __cp); if (c == EOF) { RETURN (false); }
-                        x += (c & 0xFF);
-                        c = GETC(__fp, __cp); if (c == EOF) { RETURN (false); }
-                        y += (c & 0xFF);
-                        pp = dest + x + (h-y-1)*w;
-                    } else {                        /* absolute mode */
-                        c &= 0xFF;
-                        for (i=0; i<c; i++, x++, pp++) {
-                            if ((i&1) == 0) {
-                                c1 = GETC(__fp, __cp); if (c1 == EOF) { RETURN (false); }
-                            }
-                            if (pp >= (dest+szDest)) {
-                                if (@global(InfoPrinting) == true) {
-                                    console_fprintf(stderr, "ImageReader [warning]: BMP outBuffer overrun\n");
-                                }
-                                return 0;
-                            }
-                            *pp = (i&1) ? (c1 & 0x0f) : ((c1>>4)&0x0f);
-                        }
-
-                        if (((c&3)==1) || ((c&3)==2)) {
-                            GETC(__fp, __cp);  /* read pad byte */
-                        }
-                    }
-            }  /* escape processing */
-            if (FERROR(__fp)) RETURN (false);
-        }  /* while */
-        RETURN (true);
-    }
-}
-%}.
-    ^ false
-
-    "Modified: 22.4.1996 / 19:14:32 / cg"
-!
-
-loadBMP8Width:width height:height from:aStream into:aByteArray
-    "load bmp-4 bit per pixel imagedata. A helper for BMP image reader.
-     Primitive c function for speed"
-
-    |f bytes offset|
-
-    aStream isExternalStream ifTrue:[
-        f := aStream filePointer.
-        f isNil ifTrue:[^ false].
-    ] ifFalse:[
-        aStream isInternalByteStream ifTrue:[
-            bytes := aStream collection.
-            bytes isNil ifTrue:[^ false].
-            offset := aStream position.
-        ] ifFalse:[
-            ^ false
-        ]
-    ].
-%{
-#define GETC(fp, cp)    (fp ? getc(fp) : *cp++)
-#define FERROR(fp)      (fp && ferror(fp))
-
-    FILE *__fp = NULL;
-    char *__cp = NULL;
-
-    if (f != nil) {
-        __fp = __FILEVal(f);
-    } else {
-        __cp = __stringVal(bytes);
-        __cp += __intVal(offset);
-    }
-
-    if (! (__bothSmallInteger(width, height)
-           && __isByteArray(aByteArray))) {
-        RETURN (false);
-    }
-
-{
-    int w = __intVal(width);
-    int h = __intVal(height);
-    int comp = __intVal(__INST(compression));
-    unsigned char *dest = __ByteArrayInstPtr(aByteArray)->ba_element;
-    int szDest = __byteArraySize(aByteArray);
-    int   i,j,c,c1,padw,x,y;
-    unsigned char *pp;
-
-    if (comp == 0) {   /* uncompressed data */
-        padw = ((w + 3)/4) * 4;
-
-        for (i=h-1; i>=0; i--) {
-            pp = dest + (i * w);
-
-            for (j=0; j<padw; j++) {
-                c = GETC(__fp, __cp);
-                if (c==EOF) {
-                    if (@global(InfoPrinting) == true) {
-                        console_fprintf(stderr, "ImageReader [warning]: BMP premature EOF [%d]\n", __LINE__);
-                        console_fprintf(stderr, "h=%d i=%d w=%d j=%d padw=%d\n", h, i, w, j, padw);
-                    }
-                    RETURN(false);
-                }
-                if (j<w) {
-                    if (pp >= (dest+szDest)) {
-                        if (@global(InfoPrinting) == true) {
-                            console_fprintf(stderr, "ImageReader [warning]: BMP outBuffer overrun\n");
-                        }
-                        RETURN(false);
-                    }
-                    *pp++ = c;
-                }
-            }
-            if (FERROR(__fp)) {
-                if (@global(InfoPrinting) == true) {
-                    console_fprintf(stderr, "ImageReader [warning]: BMP ferror set\n");
-                }
-                RETURN(false);
-            }
-        }
-        if (FERROR(__fp)) {
-            if (@global(InfoPrinting) == true) {
-                console_fprintf(stderr, "ImageReader [warning]: BMP ferror set at end\n");
-            }
-            RETURN(false);
-        }
-        RETURN(true);
-    }
-    if (comp == 1) {  /* RLE8 compressed */
-        x = y = 0;
-        pp = dest + x + (h-y-1)*w;
-
-        while (y<h) {
-            c = GETC(__fp, __cp);
-            if (c == EOF) {
-                if (@global(InfoPrinting) == true) {
-                    console_fprintf(stderr, "ImageReader [warning]: BMP/RLE8 premature EOF [%d]\n", __LINE__);
-                }
-                RETURN(false);
-            }
-            if (c) {                                   /* encoded mode */
-                c1 = GETC(__fp, __cp);
-                if (c1 == EOF) {
-                    if (@global(InfoPrinting) == true) {
-                        console_fprintf(stderr, "ImageReader [warning]: BMP/RLE8 premature EOF [%d]\n", __LINE__);
-                    }
-                    RETURN(false);
-                }
-                c &= 0xFF;
-
-                for (i=0; i<c; i++,x++,pp++) {
-                    if (pp >= (dest+szDest)) {
-                        if (@global(InfoPrinting) == true) {
-                            console_fprintf(stderr, "ImageReader [warning]: BMP/RLE8 outBuffer overrun\n");
-                        }
-                        RETURN(false);
-                    }
-                    *pp = c1;
-                }
-            } else {
-                /* c==0x00  :  escape codes */
-                c = GETC(__fp, __cp);
-                if (c == EOF) {
-                    if (@global(InfoPrinting) == true) {
-                        console_fprintf(stderr, "ImageReader [warning]: BMP/RLE8 premature EOF [%d]\n", __LINE__);
-                    }
-                    RETURN(false);
-                }
-                if (c == 0x00) {                    /* end of line */
-                    x=0;  y++;  pp = dest + x + (h-y-1)*w;
-                } else
-                    if (c == 0x01) break;               /* end of pic8 */
-                    else if (c == 0x02) {               /* delta */
-                        c = GETC(__fp, __cp);
-                        if (c == EOF) {
-                            if (@global(InfoPrinting) == true) {
-                                console_fprintf(stderr, "ImageReader [warning]: BMP/RLE8 premature EOF [%d]\n", __LINE__);
-                            }
-                            RETURN(false);
-                        }
-                        x += (c & 0xFF);
-                        c = GETC(__fp, __cp);
-                        if (c == EOF) {
-                            if (@global(InfoPrinting) == true) {
-                                console_fprintf(stderr, "ImageReader [warning]: BMP/RLE8 premature EOF [%d]\n", __LINE__);
-                            }
-                            RETURN(false);
-                        }
-                        y += (c & 0xFF);
-                        pp = dest + x + (h-y-1)*w;
-                    } else {                            /* absolute mode */
-                        c &= 0xFF;
-                        for (i=0; i<c; i++, x++, pp++) {
-                            c1 = GETC(__fp, __cp);
-                            if (c1 == EOF) { RETURN(false); }
-                            if (pp >= (dest+szDest)) {
-                                if (@global(InfoPrinting) == true) {
-                                    console_fprintf(stderr, "ImageReader [warning]: BMP/RLE8 outBuffer overrun\n");
-                                }
-                                RETURN(false);
-                            }
-                            *pp = c1;
-                        }
-
-                        if (c & 1) GETC(__fp, __cp);  /* odd length run: read an extra pad byte */
-                    }
-            }
-            if (FERROR(__fp)) {
-                if (@global(InfoPrinting) == true) {
-                    console_fprintf(stderr, "ImageReader [warning]: BMP/RLE8 ferror set\n");
-                }
-                RETURN(false);
-            }
-        }
-        if (FERROR(__fp)) {
-            if (@global(InfoPrinting) == true) {
-                console_fprintf(stderr, "ImageReader [warning]: BMP/RLE8 ferror set at end\n");
-            }
-            RETURN(false);
-        }
-        RETURN(true);
-    }
-    if (@global(InfoPrinting) == true) {
-        console_fprintf(stderr, "ImageReader [warning]: BMP unhandled compression: %d\n", comp);
-    }
-    RETURN(false);
-}
-%}.
-    ^ true
-
-    "Modified: 22.4.1996 / 19:14:32 / cg"
-!
-
 loadBMPWidth:w height:h bytesPerPixel:bpp from:aStream into:data
     |buff idx fileBytesPerRow imgBytesPerRow align|
 
     align := 4.
 
     compression == 0 ifTrue:[
-        imgBytesPerRow := w * bpp.
-        fileBytesPerRow := imgBytesPerRow.
-        (fileBytesPerRow bitAnd:(align-1)) ~~ 0 ifTrue:[
-            fileBytesPerRow := (fileBytesPerRow bitAnd:((align-1) bitInvert)) + align.
-        ].
-        "/
-        "/ stupid - last row comes first
-        "/
-        idx := imgBytesPerRow * (h - 1) + 1.
-        buff := ByteArray uninitializedNew:fileBytesPerRow.
+	imgBytesPerRow := w * bpp.
+	fileBytesPerRow := imgBytesPerRow.
+	(fileBytesPerRow bitAnd:(align-1)) ~~ 0 ifTrue:[
+	    fileBytesPerRow := (fileBytesPerRow bitAnd:((align-1) bitInvert)) + align.
+	].
+	"/
+	"/ stupid - last row comes first
+	"/
+	idx := imgBytesPerRow * (h - 1) + 1.
+	buff := ByteArray uninitializedNew:fileBytesPerRow.
 
-        1 to:h do:[:row |
-            (aStream nextBytes:fileBytesPerRow into:buff) ~~ fileBytesPerRow ifTrue:[
-                ^ false
-            ].
-            data replaceFrom:idx to:idx+imgBytesPerRow-1 with:buff.
-            idx := idx - imgBytesPerRow.
-        ].
-        ^ true
+	1 to:h do:[:row |
+	    (aStream nextBytes:fileBytesPerRow into:buff) ~~ fileBytesPerRow ifTrue:[
+		^ false
+	    ].
+	    data replaceFrom:idx to:idx+imgBytesPerRow-1 with:buff.
+	    idx := idx - imgBytesPerRow.
+	].
+	^ true
     ].
     ^ false.
 !
@@ -724,40 +374,40 @@
     "helper: load a BMP image"
 
     d == 8 ifTrue:[
-        compression == 0 ifTrue:[
-            ^ self loadUncompressedFrom:aStream into:data.
-        ].
-        compression == 1 ifTrue:[
-            ^ self loadRLECompressedBMP8From:aStream into:data.
-        ].
+	compression == 0 ifTrue:[
+	    ^ self loadUncompressedFrom:aStream into:data.
+	].
+	compression == 1 ifTrue:[
+	    ^ self loadRLECompressedBMP8From:aStream into:data.
+	].
 self halt.
-        ^ false
+	^ false
     ].
     d == 4 ifTrue:[
-        ^ self loadBMP4From:aStream into:data
+	^ self loadBMP4From:aStream into:data
     ].
     d == 2 ifTrue:[
-        ^ self loadBMP2From:aStream into:data
+	^ self loadBMP2From:aStream into:data
     ].
     d == 1 ifTrue:[
-        ^ self loadBMP1From:aStream into:data
+	^ self loadBMP1From:aStream into:data
     ].
-    ((d == 16) 
-    or:[ (d == 24) 
+    ((d == 16)
+    or:[ (d == 24)
     or:[ (d == 32) ]]) ifTrue:[
-        (self loadBMPWidth:w height:h bytesPerPixel:(d // 8) from:aStream into:data) ifFalse:[
-            ^ false
-        ].
-        inDepth == 16 ifTrue:[
-            "/ Depth16Image keeps its data MSB (sigh); here they come LSB.
-            data swapBytes.
-        ].
-        inDepth == 24 ifTrue:[
-            "/ Depth24Image keeps its data r/g/b; BMP has it b/g/r (sigh)
-            self swapBytesFromRGB_to_BGR.
-        ].
+	(self loadBMPWidth:w height:h bytesPerPixel:(d // 8) from:aStream into:data) ifFalse:[
+	    ^ false
+	].
+	inDepth == 16 ifTrue:[
+	    "/ Depth16Image keeps its data MSB (sigh); here they come LSB.
+	    data swapBytes.
+	].
+	inDepth == 24 ifTrue:[
+	    "/ Depth24Image keeps its data r/g/b; BMP has it b/g/r (sigh)
+	    self swapBytesFromRGB_to_BGR.
+	].
 
-        ^ true
+	^ true
     ].
     ^ false
 
@@ -807,7 +457,7 @@
                     "/ absolute; cnt pixels coming
                     cnt := code.
                     n := aStream nextBytes:cnt into:aByteArray startingAt:dstIndex.
-                    n ~~ cnt ifTrue:[self halt. ^ false].
+                    n ~~ cnt ifTrue:[^ false].
                     x := x + cnt.
                     dstIndex := dstIndex + cnt.
                     "/ odd count - padd
@@ -827,46 +477,32 @@
     |bytesPerRowInStream bytesPerRowInData skip dstIndex n|
 
     compression == 0 ifFalse:[
-        ^ false
-    ].            
+	^ false
+    ].
 
-    bytesPerRowInStream := Image bytesPerRowForWidth:width depth:inDepth padding:32.   
+    bytesPerRowInStream := Image bytesPerRowForWidth:width depth:inDepth padding:32.
     bytesPerRowInData := self bytesPerRow.
     skip := bytesPerRowInStream - bytesPerRowInData.
 
     "/ bottom row first...
     dstIndex := (height - 1) * bytesPerRowInData + 1.
     height to:1 by:-1 do:[:y |
-        n := aStream nextBytes:bytesPerRowInData into:aByteArray startingAt:dstIndex.
-        n ~~ bytesPerRowInData ifTrue:[
-            ^ false.
-        ].
-        skip ~~ 0 ifTrue:[
-            aStream skip:skip.
-        ].
-        dstIndex := dstIndex - bytesPerRowInData.
+	n := aStream nextBytes:bytesPerRowInData into:aByteArray startingAt:dstIndex.
+	n ~~ bytesPerRowInData ifTrue:[
+	    ^ false.
+	].
+	skip ~~ 0 ifTrue:[
+	    aStream skip:skip.
+	].
+	dstIndex := dstIndex - bytesPerRowInData.
     ].
     ^ true.
 !
 
-swapBytesFromRGB_to_BGR
-    |idx bytesPerRow|
-
-    "/ Depth24Image keeps its data r/g/b; BMP has it b/g/r (sigh)
-    idx := 1.
-    bytesPerRow := self bytesPerRow.
-    1 to:height do:[:y |
-        self class swap:bytesPerRow bytesFromRGB_to_BGR_in:data startingAt:idx.
-        idx := idx + bytesPerRow.
-    ].
-! !
-
-!WindowsIconReader methodsFor:'private-reading'!
-
 readColorMap:nColors numBytesPerColor:nRawBytesPerColor from:aStream
     "read the colormap; notice: its in BGR order (sigh)."
 
-    |rawMap rMap gMap bMap 
+    |rawMap rMap gMap bMap
      srcIndex  "{ Class: SmallInteger }"
      skipDelta "{ Class: SmallInteger }"|
 
@@ -882,19 +518,19 @@
     "/ stupid: this is a BGR-ordered map (otherwise, could use #rgbBytesVector:-message)
     "/ also, there might be a fourth byte (alpha ?) which is (currently) skipped.
     1 to:nColors do:[:i |
-        bMap at:i put:(rawMap at:srcIndex).
-        srcIndex := srcIndex + 1.
-        gMap at:i put:(rawMap at:srcIndex).
-        srcIndex := srcIndex + 1.
-        rMap at:i put:(rawMap at:srcIndex).
-        srcIndex := srcIndex + 1.
-        srcIndex := srcIndex + skipDelta.
+	bMap at:i put:(rawMap at:srcIndex).
+	srcIndex := srcIndex + 1.
+	gMap at:i put:(rawMap at:srcIndex).
+	srcIndex := srcIndex + 1.
+	rMap at:i put:(rawMap at:srcIndex).
+	srcIndex := srcIndex + 1.
+	srcIndex := srcIndex + skipDelta.
     ].
 
-    ^ MappedPalette 
-        redVector:rMap 
-        greenVector:gMap 
-        blueVector:bMap.
+    ^ MappedPalette
+	redVector:rMap
+	greenVector:gMap
+	blueVector:bMap.
 ! !
 
 !WindowsIconReader methodsFor:'reading'!
@@ -933,25 +569,25 @@
 
     header := ByteArray uninitializedNew:8r110.
     bytesAlreadyRead size > 0 ifTrue:[
-        header replaceFrom:1 with:bytesAlreadyRead
+	header replaceFrom:1 with:bytesAlreadyRead
     ].
     aStream nextBytes:(16-bytesAlreadyRead size) into:header startingAt:(1+bytesAlreadyRead size).
 
     (header startsWith:#(73 67)) ifTrue:[         "IC"
-        "IC format"
-        aStream nextBytes:10 into:header startingAt:17.
-        width := header at:7.
-        height := header at:9.
-        inDepth := 2 "header at:11". "where is it"
+	"IC format"
+	aStream nextBytes:10 into:header startingAt:17.
+	width := header at:7.
+	height := header at:9.
+	inDepth := 2 "header at:11". "where is it"
     ] ifFalse:[
-        (header startsWith:#(67 73)) ifTrue:[     "CI"
-            ^ self fileFormatError:'unsupported format: CI'.
-        ] ifFalse:[
-            aStream nextBytes:(8r110-16) into:header startingAt:17.
-            width := header at:8r101.
-            height := header at:8r103.
-            inDepth := header at:8r107.
-        ]
+	(header startsWith:#(67 73)) ifTrue:[     "CI"
+	    ^ self fileFormatError:'unsupported format: CI'.
+	] ifFalse:[
+	    aStream nextBytes:(8r110-16) into:header startingAt:17.
+	    width := header at:8r101.
+	    height := header at:8r103.
+	    inDepth := header at:8r107.
+	]
     ].
 
     self reportDimension.
@@ -1004,9 +640,9 @@
     inBytesPerRow := ((bytesPerRow + 3) // 4) * 4.
 
     data := ByteArray uninitializedNew:(height * width "bytesPerRow").
-    compression := 0. 
+    compression := 0.
     (self loadBMPWidth:width height:height depth:inDepth from:aStream into:data) ifFalse:[
-        ^ nil
+	^ nil
     ].
     photometric := #palette.
     samplesPerPixel := 1.
@@ -1024,7 +660,7 @@
     "Modified: / 30-05-2007 / 16:53:24 / cg"
 !
 
-fromStream:aStream 
+fromStream:aStream
     "figure out which format the stream contains
      (there are various different bmp/ico formats around)
      and read the image."
@@ -1036,10 +672,10 @@
 
     aStream binary.
     aStream isFileStream ifTrue:[
-        fileSize := aStream fileSize.
-        fileSize < 16 ifTrue:[
-            ^ self fileFormatError:'short file'.
-        ].
+	fileSize := aStream fileSize.
+	fileSize < 16 ifTrue:[
+	    ^ self fileFormatError:'short file'.
+	].
     ].
 
     header := ByteArray uninitializedNew:4.
@@ -1047,38 +683,38 @@
 
     (header startsWith:#(66 77)) ifTrue:[     "BM"
 "/        'WinIconReader [info]: Win3.x or OS/2 vsn 2 BM format' infoPrintNL.
-        ^ self fromWindowsBMPStream:aStream alreadyRead:header
+	^ self fromWindowsBMPStream:aStream alreadyRead:header
     ].
     (header startsWith:#(66 65)) ifTrue:[     "BA"
 "/        'WinIconReader [info]: OS/2 vsn 2 BA format' infoPrintNL.
-        ^ self fromOS2Stream:aStream alreadyRead:header
-    ].                    
+	^ self fromOS2Stream:aStream alreadyRead:header
+    ].
     (header startsWith:#(67 73)) ifTrue:[     "CI"
 "/        'WinIconReader [info]: OS/2 vsn 2 BA format' infoPrintNL.
 "/        ^ self fromOS2Stream:aStream
-        ^ self fileFormatError:'OS/2 CI format not supported'.
+	^ self fileFormatError:'OS/2 CI format not supported'.
     ].
     (header startsWith:#(73 67)) ifTrue:[     "IC"
 "/        'WinIconReader [info]: OS/2 IC format' infoPrintNL.
-        ^ self fromOS2Stream:aStream alreadyRead:header
+	^ self fromOS2Stream:aStream alreadyRead:header
     ].
     (header startsWith:#(80 84)) ifTrue:[     "PT"
 "/        'WinIconReader [info]: OS/2 PT format' infoPrintNL.
-        ^ self fromOS2Stream:aStream alreadyRead:header
+	^ self fromOS2Stream:aStream alreadyRead:header
     ].
     (header startsWith:#(16r53 16r5A)) ifTrue:[     "SZ"
 "/        'WinIconReader [info]: OS/2 SZ format' infoPrintNL.
 "/        ^ self fromOS2Stream:aStream
-        ^ self fileFormatError:'OS/2 SZ format not supported'.
+	^ self fileFormatError:'OS/2 SZ format not supported'.
     ].
     (header startsWith:#(0 0 1 0)) ifTrue:[
 "/        'WinIconReader [info]: Win3.x ICO format' infoPrintNL.
-        ^ self fromWindowsICOStream:aStream alreadyRead:header
+	^ self fromWindowsICOStream:aStream alreadyRead:header
     ].
     ^ self fileFormatError:('format not supported:'
-                            , ((header at:1) printStringRadix:16)
-                            , ' ' 
-                            , ((header at:2) printStringRadix:16)).
+			    , ((header at:1) printStringRadix:16)
+			    , ' '
+			    , ((header at:2) printStringRadix:16)).
 
     "
      Image fromFile:'/phys/clam//LocalLibrary/Images/OS2_icons/dos.ico'
@@ -1088,7 +724,7 @@
     "Modified: / 3.2.1998 / 20:18:14 / cg"
 !
 
-fromWindowsBMPFile: aFilename 
+fromWindowsBMPFile: aFilename
     "read an image from a windows BMP file"
 
     |reader stream|
@@ -1103,7 +739,7 @@
     "Modified: / 30-05-2007 / 16:53:48 / cg"
 !
 
-fromWindowsBMPStream:aStream 
+fromWindowsBMPStream:aStream
     "read an image from a windows BMP stream"
 
     ^ self fromWindowsBMPStream:aStream alreadyRead:nil
@@ -1112,7 +748,7 @@
 fromWindowsBMPStream:aStream alreadyRead:bytesAlreadyRead
     "read an image from a windows BMP stream"
 
-    | header iSize inPlanes 
+    | header iSize inPlanes
       imgSize resH resV numColor numImportantColor
       dataStart redMask greenMask blueMask alphaMask
       bytesPerRow numBytesPerColorInColormap|
@@ -1125,186 +761,186 @@
 
     header := ByteArray uninitializedNew:16r54.
     bytesAlreadyRead size > 0 ifTrue:[
-        header replaceFrom:1 with:bytesAlreadyRead
+	header replaceFrom:1 with:bytesAlreadyRead
     ].
     aStream nextBytes:(18-bytesAlreadyRead size) into:header startingAt:(1+bytesAlreadyRead size).
 
     iSize := header at:(16r0E + 1).
     (iSize == 40) ifTrue:[    "header-size"
-        "/
-        "/ a Windows3.x BMP file
-        "/
-        "/ 'WinIconReader [info]: Win3.x format' infoPrintCR.
+	"/
+	"/ a Windows3.x BMP file
+	"/
+	"/ 'WinIconReader [info]: Win3.x format' infoPrintCR.
 
-        aStream nextBytes:(40-4) into:header startingAt:19.
+	aStream nextBytes:(40-4) into:header startingAt:19.
 
-        width := header wordAt:(16r12 + 1) MSB:false.  
-        height := header wordAt:(16r16 + 1) MSB:false. 
-        inPlanes := header wordAt:(16r1A + 1) MSB:false.
-        inDepth := header wordAt:(16r1C + 1) MSB:false.
-        compression := header wordAt:(16r1E + 1) MSB:false.
-        imgSize := header doubleWordAt:(16r22 + 1) MSB:false.
-        resH := header doubleWordAt:(16r26 + 1) MSB:false.
-        resV := header doubleWordAt:(16r2A + 1) MSB:false.
-        numColor := header doubleWordAt:(16r2E + 1) MSB:false.
-        numImportantColor := header doubleWordAt:(16r32 + 1) MSB:false.
-        redMask := header doubleWordAt:(16r36 + 1) MSB:false.
-        greenMask := header doubleWordAt:(16r3A + 1) MSB:false.
-        blueMask := header doubleWordAt:(16r3E + 1) MSB:false.
-        alphaMask := header doubleWordAt:(16r42 + 1) MSB:false.
+	width := header wordAt:(16r12 + 1) MSB:false.
+	height := header wordAt:(16r16 + 1) MSB:false.
+	inPlanes := header wordAt:(16r1A + 1) MSB:false.
+	inDepth := header wordAt:(16r1C + 1) MSB:false.
+	compression := header wordAt:(16r1E + 1) MSB:false.
+	imgSize := header doubleWordAt:(16r22 + 1) MSB:false.
+	resH := header doubleWordAt:(16r26 + 1) MSB:false.
+	resV := header doubleWordAt:(16r2A + 1) MSB:false.
+	numColor := header doubleWordAt:(16r2E + 1) MSB:false.
+	numImportantColor := header doubleWordAt:(16r32 + 1) MSB:false.
+	redMask := header doubleWordAt:(16r36 + 1) MSB:false.
+	greenMask := header doubleWordAt:(16r3A + 1) MSB:false.
+	blueMask := header doubleWordAt:(16r3E + 1) MSB:false.
+	alphaMask := header doubleWordAt:(16r42 + 1) MSB:false.
 
-        numColor == 0 ifTrue:[
-            "
-             some bmp-writers seem to leave this as zero (which is wrong)
-            "
-            inDepth <= 8 ifTrue:[
-                numColor := 1 bitShift:inDepth.
-                "/ 'WinIconReader [warning]: missing nColor in header - assume ' infoPrint. numColor infoPrintCR
-            ]
-        ].
+	numColor == 0 ifTrue:[
+	    "
+	     some bmp-writers seem to leave this as zero (which is wrong)
+	    "
+	    inDepth <= 8 ifTrue:[
+		numColor := 1 bitShift:inDepth.
+		"/ 'WinIconReader [warning]: missing nColor in header - assume ' infoPrint. numColor infoPrintCR
+	    ]
+	].
 
-        numBytesPerColorInColormap := 4.
-        dataStart := header wordAt:(16r0A + 1) MSB:false
+	numBytesPerColorInColormap := 4.
+	dataStart := header wordAt:(16r0A + 1) MSB:false
     ] ifFalse:[
-        ((iSize == 12) or:[iSize >= 64]) ifTrue:[     
-            "/
-            "/ its an OS/2 BMP file
-            "/
-            "/ 'WinIconReader [info]: OS/2 format' infoPrintCR.
-            aStream nextBytes:(iSize-4) into:header startingAt:19.
+	((iSize == 12) or:[iSize >= 64]) ifTrue:[
+	    "/
+	    "/ its an OS/2 BMP file
+	    "/
+	    "/ 'WinIconReader [info]: OS/2 format' infoPrintCR.
+	    aStream nextBytes:(iSize-4) into:header startingAt:19.
 
-            numBytesPerColorInColormap := 3.
-            dataStart := nil.
+	    numBytesPerColorInColormap := 3.
+	    dataStart := nil.
 
-            iSize == 12 ifTrue:[
-                width := header wordAt:(16r12 + 1) MSB:false.  
-                height := header wordAt:(16r14 + 1) MSB:false. 
-                inPlanes := header wordAt:(16r16 + 1) MSB:false.
-                inDepth := header wordAt:(16r18 + 1) MSB:false.
-                "/ dataStart := header wordAt:(16r0A + 1) MSB:false.
-                compression := 0.
-            ].
-            iSize >= 64 ifTrue:[
-                "/
-                "/ its an OS/2 (vsn2) BMP file
-                "/
-                width := header doubleWordAt:(16r12 + 1) MSB:false.  
-                height := header doubleWordAt:(16r16 + 1) MSB:false.  
-                inPlanes := header wordAt:(16r1A + 1) MSB:false.  
-                inDepth := header wordAt:(16r1c + 1) MSB:false. 
-                compression := header doubleWordAt:(16r1e + 1) MSB:false. 
-                numColor := header doubleWordAt:(16r2E + 1) MSB:false.
-                numImportantColor := header doubleWordAt:(16r32 + 1) MSB:false.
-                dataStart := header wordAt:(16r0A + 1) MSB:false.
-            ].
-            numColor := 1 bitShift:inDepth.
-        ] ifFalse:[
-            ^ self fileFormatError:'unknown format'.
-        ].
+	    iSize == 12 ifTrue:[
+		width := header wordAt:(16r12 + 1) MSB:false.
+		height := header wordAt:(16r14 + 1) MSB:false.
+		inPlanes := header wordAt:(16r16 + 1) MSB:false.
+		inDepth := header wordAt:(16r18 + 1) MSB:false.
+		"/ dataStart := header wordAt:(16r0A + 1) MSB:false.
+		compression := 0.
+	    ].
+	    iSize >= 64 ifTrue:[
+		"/
+		"/ its an OS/2 (vsn2) BMP file
+		"/
+		width := header doubleWordAt:(16r12 + 1) MSB:false.
+		height := header doubleWordAt:(16r16 + 1) MSB:false.
+		inPlanes := header wordAt:(16r1A + 1) MSB:false.
+		inDepth := header wordAt:(16r1c + 1) MSB:false.
+		compression := header doubleWordAt:(16r1e + 1) MSB:false.
+		numColor := header doubleWordAt:(16r2E + 1) MSB:false.
+		numImportantColor := header doubleWordAt:(16r32 + 1) MSB:false.
+		dataStart := header wordAt:(16r0A + 1) MSB:false.
+	    ].
+	    numColor := 1 bitShift:inDepth.
+	] ifFalse:[
+	    ^ self fileFormatError:'unknown format'.
+	].
     ].
 
     self reportDimension.
 
     numColor ~~ 0 ifTrue:[
-        "read the colormap - notice: its in BGR order (sigh)"
+	"read the colormap - notice: its in BGR order (sigh)"
 
-        colorMap := self 
-                        readColorMap:numColor 
-                        numBytesPerColor:numBytesPerColorInColormap
-                        from:aStream.
+	colorMap := self
+			readColorMap:numColor
+			numBytesPerColor:numBytesPerColorInColormap
+			from:aStream.
 
-        numColor > (1 bitShift:inDepth) ifTrue:[
-            'funny number of colors in image' infoPrintCR.
-            numColor := 1 bitShift:inDepth.
-            colorMap := colorMap copyTo:numColor.
-        ].
+	numColor > (1 bitShift:inDepth) ifTrue:[
+	    'funny number of colors in image' infoPrintCR.
+	    numColor := 1 bitShift:inDepth.
+	    colorMap := colorMap copyTo:numColor.
+	].
     ].
 
     "/ check for valid compression
     compression ~~ 0 ifTrue:[
-        "/ some compression
-        compression == 1 ifTrue:[
-            "/ RLE8 - must be depth-8
-            inDepth ~~ 8 ifTrue:[
-                ^ self fileFormatError:'RLE8 compression only supported with depth8 images'.
-            ].
-        ].
-        compression == 2 ifTrue:[
-            "/ RLE4 - must be depth-4
-            inDepth ~~ 4 ifTrue:[
-                ^ self fileFormatError:'RLE4 compression only supported with depth4 images'.
-            ].
-        ].
-        compression == 3 ifTrue:[
-            "/ BITFIELDS - must be depth-16 or 32
-            ((inDepth ~~ 16) and:[inDepth ~~ 32]) ifTrue:[
-                ^ self fileFormatError:'BITFIELDS compression only supported with depth16/32 images'.
-            ].
-        ].
-        compression >= 4 ifTrue:[
-             ^ self fileFormatError:'unsupported compression'.
-        ].
+	"/ some compression
+	compression == 1 ifTrue:[
+	    "/ RLE8 - must be depth-8
+	    inDepth ~~ 8 ifTrue:[
+		^ self fileFormatError:'RLE8 compression only supported with depth8 images'.
+	    ].
+	].
+	compression == 2 ifTrue:[
+	    "/ RLE4 - must be depth-4
+	    inDepth ~~ 4 ifTrue:[
+		^ self fileFormatError:'RLE4 compression only supported with depth4 images'.
+	    ].
+	].
+	compression == 3 ifTrue:[
+	    "/ BITFIELDS - must be depth-16 or 32
+	    ((inDepth ~~ 16) and:[inDepth ~~ 32]) ifTrue:[
+		^ self fileFormatError:'BITFIELDS compression only supported with depth16/32 images'.
+	    ].
+	].
+	compression >= 4 ifTrue:[
+	     ^ self fileFormatError:'unsupported compression'.
+	].
     ].
 
     inPlanes ~~ 1 ifTrue:[
-        ^ self fileFormatError:'only 1 plane images supported'.
+	^ self fileFormatError:'only 1 plane images supported'.
     ].
 
     dataStart notNil ifTrue:[
-        aStream position:dataStart.
+	aStream position:dataStart.
     ].
 
     inDepth <= 8 ifTrue:[
-        samplesPerPixel := 1.
-        bitsPerSample := Array with:inDepth.
-        photometric := #palette.
+	samplesPerPixel := 1.
+	bitsPerSample := Array with:inDepth.
+	photometric := #palette.
     ] ifFalse:[
-        inDepth == 16 ifTrue:[
-            photometric := #palette.
-            samplesPerPixel := 3.
-            bitsPerSample := #(5 5 5).
-            colorMap := FixedPalette
-                            redShift:10 redMask:16r1f
-                            greenShift:5 greenMask:16r1f 
-                            blueShift:0 blueMask:16r1F.
+	inDepth == 16 ifTrue:[
+	    photometric := #palette.
+	    samplesPerPixel := 3.
+	    bitsPerSample := #(5 5 5).
+	    colorMap := FixedPalette
+			    redShift:10 redMask:16r1f
+			    greenShift:5 greenMask:16r1f
+			    blueShift:0 blueMask:16r1F.
 
-        ] ifFalse:[
-            inDepth == 24 ifTrue:[
-                photometric := #rgb.
-                samplesPerPixel := 3.
-                bitsPerSample := #(8 8 8).
-            ] ifFalse:[
-                inDepth == 32 ifTrue:[
-                    photometric := #rgb.
-                    samplesPerPixel := 4.
-                    bitsPerSample := #(8 8 8 8).
-                ] ifFalse:[
-                    ^ self fileFormatError:'unsupported depth'.
-                ]
-            ]
-        ]
+	] ifFalse:[
+	    inDepth == 24 ifTrue:[
+		photometric := #rgb.
+		samplesPerPixel := 3.
+		bitsPerSample := #(8 8 8).
+	    ] ifFalse:[
+		inDepth == 32 ifTrue:[
+		    photometric := #rgb.
+		    samplesPerPixel := 4.
+		    bitsPerSample := #(8 8 8 8).
+		] ifFalse:[
+		    ^ self fileFormatError:'unsupported depth'.
+		]
+	    ]
+	]
     ].
 
     inDepth == 24 ifTrue:[
-        bytesPerRow := width * 3
+	bytesPerRow := width * 3
     ] ifFalse:[
-        inDepth == 16 ifTrue:[
-            bytesPerRow := width * 2
-        ] ifFalse:[
-            inDepth == 32 ifTrue:[
-                bytesPerRow := width * 4
-            ] ifFalse:[
-                bytesPerRow := self bytesPerRow
-            ].
-        ].
+	inDepth == 16 ifTrue:[
+	    bytesPerRow := width * 2
+	] ifFalse:[
+	    inDepth == 32 ifTrue:[
+		bytesPerRow := width * 4
+	    ] ifFalse:[
+		bytesPerRow := self bytesPerRow
+	    ].
+	].
     ].
     data := ByteArray uninitializedNew:(height * bytesPerRow).
 
     "/ read & possibly decompress
 
     (self loadBMPWidth:width height:height depth:inDepth from:aStream into:data) ifFalse:[
-        self fileFormatError:('read/decompression error').
-        ^ nil
+	self fileFormatError:('read/decompression error').
+	^ nil
     ].
 
     ^ self image
@@ -1313,7 +949,7 @@
     "Modified: / 30-05-2007 / 16:57:39 / cg"
 !
 
-fromWindowsICOFile:aFilename 
+fromWindowsICOFile:aFilename
     "read an image from a windows ICO file"
 
     |reader stream|
@@ -1341,7 +977,7 @@
 fromWindowsICOStream:aStream alreadyRead:bytesAlreadyRead
     "read an image from a windows ICO stream"
 
-    |header 
+    |header
      srcIndex dstIndex
      rawData tmp bytesPerRow nColor cmapSize|
 
@@ -1352,7 +988,7 @@
 
     header := ByteArray uninitializedNew:(6 + 16 + 40).
     bytesAlreadyRead size > 0 ifTrue:[
-        header replaceFrom:1 with:bytesAlreadyRead
+	header replaceFrom:1 with:bytesAlreadyRead
     ].
     aStream nextBytes:((6 + 16 + 40)-bytesAlreadyRead size) into:header startingAt:(1+bytesAlreadyRead size).
 
@@ -1370,11 +1006,11 @@
     inDepth := header at:16r25.
     "/ mhmh - some depth4 icons seem to have a 0 in the depth field ...
     inDepth == 0 ifTrue:[
-        inDepth := 4
+	inDepth := 4
     ].
     (#(4 8) includes:inDepth) ifFalse:[
-        "/ only tested for depth 4/8 images.
-        ^ self fileFormatError:'only depth 4/8 ico-images supported (depth is ' , inDepth printString , ')'.
+	"/ only tested for depth 4/8 images.
+	^ self fileFormatError:'only depth 4/8 ico-images supported (depth is ' , inDepth printString , ')'.
 "/        self halt:'only depth 4 ico-images supported (depth is ' , inDepth printString , ')'.
     ].
     self reportDimension.
@@ -1383,9 +1019,9 @@
     cmapSize := (1 bitShift:inDepth).
 
     colorMap := self
-                readColorMap:cmapSize
-                numBytesPerColor:4
-                from:aStream.
+		readColorMap:cmapSize
+		numBytesPerColor:4
+		from:aStream.
 
     "read the data bits"
 
@@ -1406,10 +1042,10 @@
     srcIndex := 1.
     dstIndex := (height - 1) * bytesPerRow + 1.
     1 to:height do:[:row |
-        tmp replaceFrom:dstIndex to:(dstIndex + bytesPerRow - 1)
-                   with:rawData startingAt:srcIndex.
-        srcIndex := srcIndex + bytesPerRow.
-        dstIndex := dstIndex - bytesPerRow.
+	tmp replaceFrom:dstIndex to:(dstIndex + bytesPerRow - 1)
+		   with:rawData startingAt:srcIndex.
+	srcIndex := srcIndex + bytesPerRow.
+	dstIndex := dstIndex - bytesPerRow.
     ].
     rawData := tmp.
 
@@ -1417,15 +1053,15 @@
     samplesPerPixel := 1.
 
     false ifTrue:[
-        "expand into bytes"
+	"expand into bytes"
 
-        data := ByteArray new:(width * height).
-        rawData expandPixels:inDepth width:width height:height
-                      into:data mapping:nil.
-        bitsPerSample := #(8).
+	data := ByteArray new:(width * height).
+	rawData expandPixels:inDepth width:width height:height
+		      into:data mapping:nil.
+	bitsPerSample := #(8).
     ] ifFalse:[
-        data := rawData.
-        bitsPerSample := (Array with:inDepth).
+	data := rawData.
+	bitsPerSample := (Array with:inDepth).
     ].
     ^ self image
 
@@ -1446,7 +1082,7 @@
 "/        (image depth == 4
 "/        and:[image width == 32
 "/        and:[image height == 32]]) ifTrue:[
-            ^ self saveICO:image onFile:aFileName.
+	    ^ self saveICO:image onFile:aFileName.
 "/        ]
     ].
     self saveBMP:image onFile:aFileName.
@@ -1454,18 +1090,19 @@
     "Modified: 17.10.1997 / 20:16:53 / cg"
 !
 
-saveBMP:image onFile:fileName 
+saveBMP:image onFile:fileName
     "save image as BMP file on aFileName.
      Only depth 1,4,8 and 24 images can be represented in this format."
 
-    |depth bhSize biSize biClrUsed biSizeImage bfOffBits rowBytes imgBytesPerRow data srcIndex row t|
+    |depth bhSize biSize biClrUsed biSizeImage bfOffBits rowBytes imgBytesPerRow 
+     bits srcIndex row|
 
     depth := image depth.
     width := image width.
     height := image height.
 
     (#(1 4 8 24) includes:depth) ifFalse:[
-        ^ Image cannotRepresentImageSignal 
+        ^ Image cannotRepresentImageSignal
             raiseWith:image
             errorString:('BMP format only supports depths 1,4,8 and 24').
     ].
@@ -1476,11 +1113,11 @@
     ].
 
     bhSize := 14.  "# bytes in file header"
-    biSize := 40.  "info header size in bytes" 
+    biSize := 40.  "info header size in bytes"
     biClrUsed := (depth >= 24) ifTrue:[0] ifFalse:[1 bitShift: depth].  "No. color table entries"
     bfOffBits := biSize + bhSize + (4*biClrUsed).
     "/ bmp aligns rows on a longword boundary
-    rowBytes := ((depth min:24) * width + 31 // 32) * 4.
+    rowBytes := (((depth min:24) * width + 31) // 32) * 4.
     biSizeImage := height * rowBytes.
 
     outStream := fileName asFilename writeStream.
@@ -1488,24 +1125,24 @@
     byteOrder := #lsb.
 
     "Write the file header"
-    self writeShort:19778.  "bfType = BM" 
+    self writeShort:19778.  "bfType = BM"
     self writeLong:(bfOffBits + biSizeImage).  "Entire file size in bytes"
-    self writeLong:0.  "bfReserved" 
+    self writeLong:0.  "bfReserved"
     self writeLong:bfOffBits.  "Offset of bitmap data from start of hdr (and file)"
 
     "Write the bitmap info header"
     outStream position1Based: bhSize+1.
-    self writeLong:biSize.  "info header size in bytes" 
-    self writeLong:width.  "biWidth" 
-    self writeLong:height.  "biHeight" 
-    self writeShort:1.  "biPlanes" 
-    self writeShort:(depth min:24).  "biBitCount" 
-    self writeLong:0.  "biCompression" 
+    self writeLong:biSize.  "info header size in bytes"
+    self writeLong:width.  "biWidth"
+    self writeLong:height.  "biHeight"
+    self writeShort:1.  "biPlanes"
+    self writeShort:(depth min:24).  "biBitCount"
+    self writeLong:0.  "biCompression"
     self writeLong:biSizeImage.  "size of image section in bytes"
-    self writeLong:2800.  "biXPelsPerMeter" 
-    self writeLong:2800.  "biYPelsPerMeter" 
+    self writeLong:2800.  "biXPelsPerMeter"
+    self writeLong:2800.  "biYPelsPerMeter"
     self writeLong:biClrUsed.
-    self writeLong:0.  "biClrImportant" 
+    self writeLong:0.  "biClrImportant"
     1 to:biClrUsed do:[:i |  "Color map"
         |clr r g b|
 
@@ -1526,7 +1163,7 @@
     ].
 
     imgBytesPerRow := image bytesPerRow.
-    data := image data.
+    bits := image bits.
 
 
     "/ sorry, must extract rows individually
@@ -1538,15 +1175,10 @@
     srcIndex := 1 + (height * imgBytesPerRow).
     1 to:height do:[:i |
         srcIndex := srcIndex - imgBytesPerRow.
-        row replaceFrom:1 to:imgBytesPerRow with:data startingAt:srcIndex.
-        depth >= 24 ifTrue:[
+        row replaceFrom:1 to:imgBytesPerRow with:bits startingAt:srcIndex.
+        depth == 24 ifTrue:[
             "/ stupid must swap red & blue bytes
-
-            1 to:row size by:3 do:[:i |
-                t := row at:i.
-                row at:i put:(row at:i+2).
-                row at:i+2 put:t
-            ].
+            self class swap:row size bytesFromRGB_to_BGR_in:row startingAt:1.
         ].
         outStream nextPutAll:row.
     ].
@@ -1559,17 +1191,21 @@
      i := Image fromFile:'bitmaps/SBrowser.xbm'.
      WindowsIconReader save:i onFile:'test.bmp'.
     "
+
     "
-     |i|
+     |i i2|
 
-     i := Image fromFile:'bitmaps/gifImages/garfield.gif'.
-     WindowsIconReader save:i onFile:'test.bmp'.
+     i := Image fromFile:'../../goodies/bitmaps/gifImages/garfield.gif'.
+     i inspect.
+     WindowsIconReader save:i onFile:'garfield.bmp'.
+     i2 := Image fromFile:'garfield.bmp'.
+     i2 inspect.
     "
 
     "Modified: 21.10.1997 / 05:02:02 / cg"
 !
 
-saveICO:image onFile:fileName 
+saveICO:image onFile:fileName
     "save image as ICO file on aFileName.
      Only depth 4 images of size 32x32 can be represented in this format."
 
@@ -1580,14 +1216,14 @@
     height := image height.
 
     depth ~~ 4 ifTrue:[
-        ^ Image cannotRepresentImageSignal 
-            raiseWith:image
-            errorString:('ICO format only supports depths 4').
+	^ Image cannotRepresentImageSignal
+	    raiseWith:image
+	    errorString:('ICO format only supports depths 4').
     ].
     (width ~~ 32 or:[height ~~ 32]) ifTrue:[
-        ^ Image cannotRepresentImageSignal 
-            raiseWith:image
-            errorString:('ICO format (currently) only supports 32x32 bitmaps').
+	^ Image cannotRepresentImageSignal
+	    raiseWith:image
+	    errorString:('ICO format (currently) only supports 32x32 bitmaps').
     ].
 
     "/ align rows on a longword boundary
@@ -1614,22 +1250,22 @@
     "/ 16-entry RGB map
 
     1 to:16 do:[:i |  "Color map"
-        |clr r g b|
+	|clr r g b|
 
-        clr := image colorFromValue:i-1.
-        clr isNil ifTrue:[
-            r := g := b := 0.
-        ] ifFalse:[
-            r := clr redByte.
-            g := clr greenByte.
-            b := clr blueByte.
-        ].
+	clr := image colorFromValue:i-1.
+	clr isNil ifTrue:[
+	    r := g := b := 0.
+	] ifFalse:[
+	    r := clr redByte.
+	    g := clr greenByte.
+	    b := clr blueByte.
+	].
 
-        "/ put B,G,R
-        outStream nextPut:b.
-        outStream nextPut:g.
-        outStream nextPut:r.
-        outStream nextPut:0.
+	"/ put B,G,R
+	outStream nextPut:b.
+	outStream nextPut:g.
+	outStream nextPut:r.
+	outStream nextPut:0.
     ].
 
     imgBytesPerRow := image bytesPerRow.
@@ -1644,25 +1280,25 @@
 
     srcIndex := 1 + (height * imgBytesPerRow).
     1 to:height do:[:i |
-        srcIndex := srcIndex - imgBytesPerRow.
-        row replaceFrom:1 to:imgBytesPerRow with:data startingAt:srcIndex.
-        outStream nextPutAll:row.
+	srcIndex := srcIndex - imgBytesPerRow.
+	row replaceFrom:1 to:imgBytesPerRow with:data startingAt:srcIndex.
+	outStream nextPutAll:row.
     ].
 
     "/ the mask ...
     image mask isNil ifTrue:[
-        outStream next:128 put:16rFF
+	outStream next:128 put:16rFF
     ] ifFalse:[
-        imgBytesPerRow := image mask bytesPerRow.
-        data := image mask data.
-        row := ByteArray new:4.
+	imgBytesPerRow := image mask bytesPerRow.
+	data := image mask data.
+	row := ByteArray new:4.
 
-        srcIndex := 1 + (height * imgBytesPerRow).
-        1 to:height do:[:i |
-            srcIndex := srcIndex - imgBytesPerRow.
-            row replaceFrom:1 to:imgBytesPerRow with:data startingAt:srcIndex.
-            outStream nextPutAll:row.
-        ].
+	srcIndex := 1 + (height * imgBytesPerRow).
+	1 to:height do:[:i |
+	    srcIndex := srcIndex - imgBytesPerRow.
+	    row replaceFrom:1 to:imgBytesPerRow with:data startingAt:srcIndex.
+	    outStream nextPutAll:row.
+	].
     ].
 
     outStream close.
@@ -1682,7 +1318,7 @@
 !WindowsIconReader class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libview2/WindowsIconReader.st,v 1.62 2008-12-02 21:02:23 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libview2/WindowsIconReader.st,v 1.63 2008-12-03 12:24:25 cg Exp $'
 ! !
 
 WindowsIconReader initialize!