eXept Software AG Logo

Smalltalk/X Webserver

Documentation of class 'WindowsIconReader':

Home

Documentation
www.exept.de
Everywhere
for:
[back]

Class: WindowsIconReader


Inheritance:

   Object
   |
   +--ImageReader
      |
      +--WindowsIconReader

Package:
stx:libview2
Category:
Graphics-Images-Readers
Version:
rev: 1.107 date: 2023/08/08 08:44:22
user: cg
file: WindowsIconReader.st directory: libview2
module: stx stc-classLibrary: libview2

Description:


this class provides methods for loading Windows and OS2 icon and bmp files.

The class name *IconReader is a bad, historic choice - it was originally
written to read icons only, but evolved over time and is now also
capable of reading/writing bmp and cursor files.

The reader should support allmost all formats: Win2, Win3, Win4, Win5, WINCE and OS2.
(incl. PNG and JPG compression, and WINCE depth2 images)

Image writing is only supported for BMP format with depth 1,4,8 and 24 bit images.

The reader tries to figure out which version of BMP/ICO is used.
It seems to be able to load most formats, but who knows ...

[notice:]
    when reading an ICO/CUR file with multiple icons in it,
    the first image is returned as such, holding on the other images via its
    imageFrames instvar.
    Thus, the imageEditor will usually present the first of the images,
    and offer a next-in-sequence button to step through them.
    To get a collection of all images, collect the images from the sequence, as in:
        someIcoImage imageFrames collect:#image
        

copyright

COPYRIGHT (c) 1993 by Claus Gittinger All Rights Reserved This software is furnished under a license and may be used only in accordance with the terms of that license and with the inclusion of the above copyright notice. This software may not be provided or otherwise made available to, or used by, any other person. No title to or ownership of the software is hereby transferred.

fileFormatDescription

Information from http://www.daubnet.com/formats/BMP.html - no Warranty. Name Size Offset Description Header 14 bytes Windows Structure: BITMAPFILEHEADER Signature 2 bytes 0 'BM' FileSize 4 bytes 2 File size in bytes reserved 4 bytes 6 unused (=0) DataOffset 4 bytes 10 File offset to Raster Data InfoHeader 40 bytes Windows Structure: BITMAPINFOHEADER different sizes, depending on Windows-version: 12 - Win2.x or OS/2 1.x 40 - WinNT, Win3.x or later 52 - adds undocumented; adds r/g/b masks 56 - adds undocumented; adds r/g/b/a masks 64 - OS/2 2.x 108 - WinNT4.0, 95 or later 124 - WinNT5.0, 98 or later Size 4 bytes 14 Size of InfoHeader =40 Width 4 bytes 18 Bitmap Width Height 4 bytes 22 Bitmap Height Planes 2 bytes 26 Number of Planes (=1) BitCount 2 bytes 28 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 30 Type of Compression 0 = RGB no compression 1 = RLE8 8bit RLE encoding 2 = RLE4 4bit RLE encoding 3 = BITFIELDS Windows V3+ only 4 = JPEG Windows V3+ only 5 = PNG Windows V3+ only 6 = ALPHA_BITFIELDS Windows CE only 3 = HUFFMAN1D OS/2 2.x-only 4 = RLE24 OS/2 2.x-only ImageSize 4 bytes 34 (compressed) Size of Image It is valid to set this =0 if Compression = 0 XpixelsPerM 4 bytes 38 horizontal resolution: Pixels/meter YpixelsPerM 4 bytes 42 vertical resolution: Pixels/meter ColorsUsed 4 bytes 46 Number of actually used colors ColorsImportant 4 bytes 50 Number of important colors 0 = all ColorTable 4 * NumColors bytes (3 on Win2) 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 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: 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. Raster Data encoding for 1bit / black & white images: 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!) Raster Data encoding for 4bit / 16 color images: 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 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?> 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 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 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. 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 Raster Data compression for 8bit / 256 color images: 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. 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 Portability: Although BMPs were invented by Microsoft for its Windows platform, a lot of programs on other platforms are capable of reading and writing them. Notice the Intel order in 2byte and 4-byte integer values (Least significant byte first). The 16bit BMPs have been introduced to Windows after the others, still puzzling many applications. Trademarks, Patents and Royalties To my knowledge: None.

Class protocol:

class initialization
o  initialize
tell Image-class, that a new fileReader is present
for the '.bmp' and '.ico' extensions.

testing
o  canRepresent: anImage
return true, if anImage can be represented in my file format.
BMP supports depth 1,4,8, 24 and 32.

o  isValidImageStream: inStream
return true, if inStream possibly contains an image in a format
which this reader class understands.
The stream is left open and position undefined afterwards.


Instance protocol:

accessing
o  image
(comment from inherited method)
return the image as represented by myself;
If my file contained multiple images, return the first one.

private
o  bitsPerPixel

o  convertPixels
figure out, how pixels should be processed,

o  loadBMP1From: aStream into: aByteArray
load bmp-1 bit per pixel imagedata.

o  loadBMP2From: aStream into: aByteArray
load bmp-2 bit per pixel imagedata.

o  loadBMP4From: aStream into: aByteArray
load bmp-4 bit per pixel imagedata.

o  loadBMP8From: aStream into: aByteArray
load bmp-8 bit per pixel imagedata.

o  loadBMPWidth: w height: h bytesPerPixel: bpp from: aStream into: aByteArray
load bmp-16/24/32 bit per pixel imagedata.

o  loadBMPWidth: w height: h depth: d from: aStream into: aByteArray
helper: load a BMP image

o  loadRLECompressedBMP4From: aStream into: aByteArray
load bmp-rle-4 pixel imagedata

o  loadRLECompressedBMP8From: aStream into: aByteArray
load bmp-8 bit per pixel imagedata

o  loadUncompressedFrom: aStream into: aByteArray
load bmp-1,2,4 and 8 bit per pixel imagedata.

o  readColorMap: nColors numBytesPerColor: nRawBytesPerColor from: aStream
read the colormap; notice: its in BGR order (sigh).

o  swapBytesFromRGBA_to_BGRA
Depth32Image keeps its data r/g/b/a; BMP has it b/g/r/a (sigh)

o  swapBytesFromRGB_to_BGR
Depth24Image keeps its data r/g/b; BMP has it b/g/r (sigh)

reading
o  fromOS2File: aFilename
read an image from an OS/2 BMP file

o  fromOS2Stream: aStream
read an image from an OS/2 BMP stream

o  fromOS2Stream: aStream alreadyRead: bytesAlreadyRead
read an image from an OS/2 BMP stream

o  fromStream: aStream
figure out which format the stream contains
(there are various different bmp/ico formats around)
and read the image.

o  fromWindowsBMPFile: aFilename
read an image from a windows BMP file

o  fromWindowsBMPStream: aStream
read an image from a windows BMP stream

o  fromWindowsBMPStream: aStream alreadyRead: fileHeaerBytesAlreadyRead
read an image from a windows BMP stream

o  fromWindowsICOFile: aFilename
read an image from a windows ICO file

o  fromWindowsICOStream: aStream
read an image from a windows ICO stream

o  fromWindowsICOStream: aStream alreadyRead: bytesAlreadyRead
read an image from a windows ICO stream

o  old_fromWindowsICOStream: aStream alreadyRead: bytesAlreadyRead
read an image from a windows ICO stream

o  readSingleImageFromWindowsICOStream: aStream
read one image from a windows ICO stream

writing
o  save: image onFile: aFilenameOrFilenameString
save image as BMP file on aFileName.
Only depth 1,4,8 and 24 images can be represented in this format.

o  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.

o  saveBMP: imageArg withFileHeader: withFileHeaderBoolean onStream: aStream
save image as BMP file on aFileName.
If withFileHeaderBoolean is false, no bitmapFileHeader is written (used when saving ICO files).
Only depth 1,4,8 and 24 images can be represented in this format.

o  saveICO: image onFile: fileName
save image as ICO file on aFileName

Usage example(s):

     |i|

     i := Image fromFile:'bitmaps/xpmBitmaps/SmalltalkX_clr.xpm'.
     i := Depth4Image fromImage:i.
     i := i magnifiedTo:32@32.
     WindowsIconReader new saveICO:i onFile:'test.ico'.



ST/X 7.7.0.0; WebServer 1.702 at 20f6060372b9.unknown:8081; Sat, 27 Jul 2024 07:33:23 GMT