eXept Software AG Logo

Smalltalk/X Webserver

Documentation of class 'ImageReader':

Home

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

Class: ImageReader


Inheritance:

   Object
   |
   +--ImageReader
      |
      +--GIFReader
      |
      +--HEICReader
      |
      +--JPEGReader
      |
      +--MacOSXIconReader
      |
      +--PBMReader
      |
      +--PNGReader
      |
      +--TIFFReader
      |
      +--WindowsIconReader
      |
      +--XBMReader
      |
      +--XPMReader

Package:
stx:libview
Category:
Graphics-Images-Readers
Version:
rev: 1.165 date: 2023/08/07 11:14:51
user: cg
file: ImageReader.st directory: libview
module: stx stc-classLibrary: libview

Description:


Abstract class to provide common functions for image-readers/writers.
(i.e. TIFFReader, GIFReader etc.).

In contrast to what the name suggests, ImageReaders are supposed to support
both reading and writing of images
(i.e. the name is somewhat outdated, but kept for historic and backward
compatibility reasons).
They provide functionality similar to Squeak's ImageReaderWriter classes.

ImageReaders are created temporary to read an image from a stream.
Normally, they are not directly used - instead, the image class is
asked to read some file, and return an instance for it:
    Image fromFile:<someFileName>
The Image class will guess the image's format and forward the task to
some concrete ImageReaderClass.
If that class thinks, that the file's format is incorrect,
other readers are tried until some reader class finds the file's format acceptable.

Image readers read the stream and collect all relevant information internally.
Once done with reading, the actual image object is created and
data filled in from the imageReaders collected info.

See the implementation of #fromStream: in concrete subclasses.
The public interfaces are:
     <ConcreteReaderClass> fromFile:aFilename
or:
     <ConcreteReaderClass> fromStream:aStream

If you add a new reader, don't forget to add the method #isValidImageFile:
which should return true, if this reader supports reading a given file.

If your new reader class supports writing files, don't forget to add
#canRepresent:anImage and return true from this method.

writing:
    tell the image, to save itself, via <image> saveOn:fileName
    or <image> saveOn:fileName using:<readerClass>

Subclasses should register themself (in their #initialize) method
towards the MIMETypes registry; i.e.
    MIMETypes defineImageType:<mimeType> suffix:<suffix> reader:self.

copyright

COPYRIGHT (c) 1991 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.

Class protocol:

cleanup
o  lowSpaceCleanup
cleanup things we do not need

constants
o  reverseBits
return a table filled with bit reverse information.
To convert from msbit-first to lsbit-first bytes, use
the value as index into the table, retrieving the reverse
value. Since indexing must start at 1, use (value + 1) as
index.

decompression support
o  _decompressCCITT3From: src count: inCount into: dst startingAt: dstIndexIn
toggle if it was a terminating code

o  _decompressCCITT3From: src count: inCount into: dst startingAt: dstIndexIn count: len
toggle if it was a terminating code

Usage example(s):

     |bytes outBytes|

     bytes := '/Users/cg/DownloadsUnsaved/images/software/libtiffpic/g3test.g3'
                asFilename binaryContentsOfEntireFile.
     outBytes := ByteArray new:100000.
     ImageReader 
        _decompressCCITT3From:bytes
        count:bytes size    
        into:outBytes
        startingAt:1.

o  decodeDelta: step in: data width: width height: height
perform TIFF predictor = 2 delta decoding inplace on data.
Calls primitive c function for speed

o  decompressCCITT3From: srcBytes into: dstBytes startingAt: offset count: count
decompress CCITT Group 3 compressed image data.
count bytes from srcBytes are decompressed into dstBytes.
Calls primitive c function for speed

o  decompressGIFFrom: srcBytes count: count into: dstBytes startingAt: offset codeLen: codeLen
decompress GIF compressed image data.
count bytes from srcBytes are decompressed into dstBytes.
Calls primitive c function for speed

o  decompressLZWFrom: srcBytes count: count into: dstBytes startingAt: offset
decompress LZW (tiff) compressed image data.
count bytes from srcBytes are decompressed into dstBytes.
Calls primitive c function for speed

o  decompressPackBits: nIn from: srcBytes to: dstBytes startingAt: dstOffset
decompress a number of input bytes.
Used by tiff and some mac image formats.
Return the number of decompressed output bytes.

o  decompressPackBitsV2From: srcBytes at: srcStart to: dstBytes at: dstStart count: outCount
decompress until a number of output bytes has been decompressed.
Used by some mac image formats.
Return the number of processed input bytes.
This does NOT treat FF as a noop.

o  decompressRLEFrom: srcBytes at: srcStartIndex into: dstBytes at: dstStartIndex increment: dstIncrement
common helper to expand RLE encoded data

o  decompressTiffPackBitsFrom: srcBytes to: dstBytes at: dstStart count: maxOutCount
decompress all of srcBytes to dstBytes starting at dstStart.
Used by TIFF image formats.
This DOES TREAT FF as a noop.

o  initCCITTTables
0

o  swap: nBytes bytesFromRGBA_to_BGRA_in: data startingAt: startIndex
swap bytes from RGBA into BGRA order.
The argument is a pixel data buffer (byteArray)

Usage example(s):

     |bytes|

     bytes := #[ 0 1 2 3 4 5 6 7 8 9 ].
     self swap:6 bytesFromRGB_to_BGR_in:bytes startingAt:1.
     bytes.

Usage example(s):

     |bytes|

     bytes := ByteArray new:1000000.
     bytes replaceFrom:1 with:#[ 0 1 2 3 4 5 6 7 8 9 10 11 12].
     Time millisecondsToRun:[
	self swap:1000000 bytesFromRGB_to_BGR_in:bytes.
     ].
     bytes copyTo:10.

o  swap: nBytes bytesFromRGB_to_BGR_in: data
swap bytes from RGB into BGR order.
The argument is a pixel data buffer (byteArray)

Usage example(s):

     |bytes|

     bytes := #[ 0 1 2 3 4 5 6 7 8 9 ].
     self swap:6 bytesFromRGB_to_BGR_in:bytes.
     bytes.

Usage example(s):

     |bytes|

     bytes := ByteArray new:1000000.
     bytes replaceFrom:1 with:#[ 0 1 2 3 4 5 6 7 8 9 10 11 12].
     Time millisecondsToRun:[
	self swap:1000000 bytesFromRGB_to_BGR_in:bytes.
     ].
     bytes copyTo:10.

o  swap: nBytes bytesFromRGB_to_BGR_in: data startingAt: startIndex
swap bytes from RGB into BGR order.
The argument is a pixel data buffer (byteArray)

Usage example(s):

     |bytes|

     bytes := #[ 0 1 2 3 4 5 6 7 8 9 ].
     self swap:6 bytesFromRGB_to_BGR_in:bytes startingAt:1.
     bytes.

Usage example(s):

     |bytes|

     bytes := ByteArray new:1000000.
     bytes replaceFrom:1 with:#[ 0 1 2 3 4 5 6 7 8 9 10 11 12].
     Time millisecondsToRun:[
	self swap:1000000 bytesFromRGB_to_BGR_in:bytes.
     ].
     bytes copyTo:10.

o  swap: count pixelsFromRGB_to_BGR_in: data startingAt: startIndex bytesPerPixel: bpp
swap bytes from RGB into BGR order.
The argument is a pixel data buffer (byteArray).
Can be used for both 24bit rgb data (bpp=3) or rgba data (bpp=4)

Usage example(s):

     |bytes|

     bytes := #[ 0 1 2  3 4 5  6 7 8  9 ].
     self swap:2 pixelsFromRGB_to_BGR_in:bytes startingAt:1 bytesPerPixel:3.
     bytes.

Usage example(s):

     |bytes|

     bytes := #[ 0 1 2 3  4 5 6 7  8 9 ].
     self swap:2 pixelsFromRGB_to_BGR_in:bytes startingAt:1 bytesPerPixel:4.
     bytes.

i/o support
o  streamReadingFile: aFilename
return a stream to read aFilename.
If the filename ends with '.Z' or '.gz', return a stream
to a pipe for the uncompressor. Otherwise, return a stream to read
the file directly.

image reading
o  fromBase64Stream: aStream
read an image in my format from aStream, which contains base64 encoded bytes.
Leave image description in instance variables.

o  fromBytes: aByteArray
read an image (in my format) from aByteArray.
Return the image or nil (if unrecognized format or error)

o  fromFile: aFileName
read an image (in my format) from aFileName.
Return the image or nil on error.

Usage example(s):

     XBMReader fromFile:'bitmaps/SBrowser.xbm'
     XPMReader fromFile:'bitmaps/xpmBitmaps/misc_icons/BOOK.xpm'
     XBMReader fromFile:'bitmaps/xpmBitmaps/misc_icons/BOOK.xpm'

o  fromStream: aStream
read an image (in my format) from aStream.
Return the image or nil (if unrecognized format or error).
The stream remains open.

o  fromURL: url
read an image (in my format) from url.
Return the image or nil (if unrecognized format or error)

Usage example(s):

     self fromURL:'http://www.lutece.paris.fr/tech/images/helloworld.png'

o  imagesFromFile: aFileName
read all images (in my format) from aFileName.
Return a collection of images or nil on error.
Not all reader may support multiple images.

o  imagesFromStream: aStream
read all images (in my format) from aStream.
Return a collection of images or nil (if unrecognized format or error).
The stream remains open.
Not all reader may support multiple images.

o  readFile: aFilename
create a reader and let it read an image (in my format) from aFilename.
Return the reader, NOT the image (however, the reader has already read the image,
so it can be asked with 'reader image').

Usage example(s):

     (XPMReader readFile:'../../goodies/bitmaps/xpmBitmaps/misc_icons/BOOK.xpm') image
     (ImageReader readFile:'../../goodies/bitmaps/xpmBitmaps/misc_icons/BOOK.xpm') image

o  readStream: aStream
create a reader and let it read a stream (in my format).
Return the reader, NOT the image (however, the reader has already read the image,
so it can be asked with 'reader image').
The stream remains open.

o  readerClassForFilename: aStringOrFilename
return a reader class, determined by the file's name/suffix

Usage example(s):

     self readerClassForFilename:('http://www.foo.bar/helloworld.png' asURL path)  => PNGReader
     self readerClassForFilename:('http://www.foo.bar/helloworld.gif' asURL path)  => GIFReader
     self readerClassForFilename:('http://www.foo.bar/helloworld.tiff' asURL path) => TIFFReader
     self readerClassForFilename:('http://www.foo.bar/helloworld.jpg' asURL path)  => JPEGReader
     self readerClassForFilename:('http://www.foo.bar/helloworld.heic' asURL path) => HEICReader

o  readerClassForSuffix: aSuffixString
return a reader class, determined by the file's name/suffix

Usage example(s):

     self readerClassForSuffix:'png'   => PNGReader
     self readerClassForSuffix:'gif'   => GIFReader
     self readerClassForSuffix:'tiff'  => TIFFReader
     self readerClassForSuffix:'jpg'   => JPEGReader
     self readerClassForSuffix:'heic'  => HEICReader

image support
o  buildMaskFromColor: maskPixelValue for: pixels depth: depth width: width height: height
helper for image formats, where an individual pixel value
has been defined as a mask-pixel (i.e. GIF).
Creates a maskImage, with zeros at positions where the image
has the given pixelValue; all other mask pixels are set to 1.

o  buildMaskFromColor: maskPixelValue for: pixels width: width height: height
marked as obsolete by cg at 04-05-2023

** This is an obsolete interface - do not use it (it may vanish in future versions) **

image writing
o  save: anImage onFile: aFilenameOrFilenameString
save the image in my format on aFileName.
Returns the imageReader instance (bad name; is a writer).
May raise Image cannotRepresentImageSignal,
if the image cannot be represented in that format,
or it is not support

o  save: anImage onFile: aFileName quality: qualityPercent
save the image in my format on aFileName.
The qualityPercent argument is ignored by all lossless formats.
(however, JPG does care for it.)
Returns the imageReader instance (bad name; is a writer).
May raise Image cannotRepresentImageSignal,
if the image cannot be represented in that format,
or it is not support

o  save: anImage onStream: aStream
save the image in my format on aStream.
Returns the imageReader instance (bad name; is a writer).
May raise Image cannotRepresentImageSignal,
if the image cannot be represented in that format,
or it is not support

o  save: anImage onStream: aStream quality: qualityPercent
save the image in my format on a Stream.
The qualityPercent argument is ignored by all lossless formats.
(however, JPG does care for it.)
Returns the imageReader instance (bad name; is a writer).
May raise Image cannotRepresentImageSignal,
if the image cannot be represented in that format,
or it is not support

o  saveAll: aCollectionOfImages onFile: aFilename
save an image collection in my format on a file.
Not all file formats support multiple images,
so be prepared for an exception to be raised.

o  saveAll: aCollectionOfImages onStream: aStream
save an image collection in my format on a Stream.
Not all file formats support multiple images,
so be prepared for an exception to be raised.

instance creation
o  new
(comment from inherited method)
return an instance of myself without indexed variables

private utilities
o  writingFile: aFilenameOrFilenameString for: something do: aBlock
helper for save image

Usage example(s):

        self writingFile:'/etc' for:nil do:[:arg| self halt].
        self writingFile:'/tmp/ttttt' for:nil do:[:arg| arg nextPutLine:'Hello'].

        self writingFile:'/tmp/ttttt' for:nil do:[:arg| ^ self].
        self assert:'/tmp/ttttt' asFilename exists not

queries
o  isAbstract
Return if this class is an abstract class.
True is returned here for myself only; false for subclasses.
Abstract subclasses must redefine this again.

signal constants
o  enforcedImageTypeQuery
the query signal which can be used to override the default type
of image as returned by a reader.
Currently, only PNGReader supports.
Usage:
ImageReader enforcedImageTypeQuery answer:#rgb
do:[
Image fromFile:anRGBAFile
]

testing
o  canRepresent: anImage
return true, if anImage can be represented in my file format.
must be redefined in concrete subclasses which support saving.

o  isValidImageFile: aFileName
return true, if aFileName contains an image which I can read.
Not all readers (currently) look into the file; some only look at the filename

Usage example(s):

     XPMReader isValidImageFile:'fooBar'    
     XPMReader isValidImageFile:'../../goodies/bitmaps/xpmBitmaps/device_images/ljet.xpm'      
     XPMReader isValidImageFile:'../../goodies/bitmaps/bitmaps/gifImages/garfield.gif' 

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.
must be redefined in concrete subclasses
which support reading


Instance protocol:

accessing
o  bitsPerPixel
return the number of bits per pixel

o  bitsPerRow
return the number of bits in one scanline of the image

o  bitsPerSample
return the number of bits per sample

o  bytesPerRow
return the number of bytes in one scanline of the image

o  colorMap
return the colormap

o  compressQuality: qualityPercentIgnoredHere
intentionally ignored here (redefined in JPEGReader)

o  data
return the raw image data

o  hasMultipleImages

o  height
return the height of the image

o  image
return the image as represented by myself;
If my file contained multiple images, return the first one.

o  imageFrames
return a collection of all imageFrames as represented by myself.
ImageFrames are wrappers for individual images, which hold
additional information (such as image delay time).
Nil is return for single image formats/files.

o  images
return a collection of all images as represented by myself.
For compatibility with single-image formats, return a collection
containing my single image here if the file format does not support
multiple images.
Readers for formats with multiple images should leave the images
in the imageSequence instVar as a side effect of reading.

o  makeImage
return the image as represented by the values found in my
instvars; these have been typically set as a side effect of
the fromStream:-method, which reads images.

o  mask
return the image mask (or nil)

o  metaData
non nil, if there was metadata (edif) info present.

o  numberOfImages
return the number of images as read.
By default (here), I hold a single image;
however, some fileFormats allow for multiple images

o  orientation
non nil, if there was metadata (edif) info present.
If nil is returned, assume topLeft (i.e. 'normal')

o  photometric
return the photometric interpretation of the image data.
This may be a somewhat old leftover from times, when tiff was the first image file type to be read.
Much better would be to always have some (possibly fake and virtual) colormap around, and ask that one.
However, in the meantime, many other classes depend on that, so that it should be kept as an API
- even when the internal representation will be replaced by something better in the future.

o  samplesPerPixel
return the number of samples per pixel

o  width
return the width of the image

accessing-private
o  byteOrder: aSymbol
set the byte order - either #lsb or #msb

o  inStream

o  inStream: aStream

error reporting
o  fileFormatError: aMessage
report a format notification - no image could be read.
The notification is ignored if not explicitlay handled.
If handled, it may be proceeded, then a nil is returned
(useful for image sequences as in ICNS)

o  fileFormatError: aMessage with: argument
report a format notification - no image could be read.
The notification is ignored if not explicitlay handled.
If handled, it may be proceeded, then a nil is returned
(useful for image sequences as in ICNS)

i/o support
o  readLong
return the next 4-byte long, honoring the byte-order

o  readShort
return the next 2-byte short, honoring the byte-order

o  readShortLong
return the next 2-byte short, honoring the byte-order.
There are actually 4 bytes read, but only 2 looked at.

o  readUnsignedLong
return the next 4-byte long, honoring the byte-order

o  writeLong: anInteger
write a 4-byte long, honoring the byte-order.

o  writeShort: anInteger
write a 2-byte short, honoring the byte-order.

image reading
o  fromStream: aStream
read an image in my format from aStream.
Leave image description in instance variables.

o  readImage
read an image in my format from my inStream.
Leave image description in instance variables.

** This method must be redefined in concrete classes (subclassResponsibility) **

image reading support
o  buildMaskFromColor: maskPixelValue
helper for image formats, where an individual pixel value
has been defined as a mask-pixel (eg. GIF).
Creates a maskImage, with zeros at positions where the image
has the given pixelValue; all other mask pixels are set to 1.

o  processExifData: exifData msb: msbFirst
exif is actually TIFF without an image...

image writing
o  save: image onFile: aFilenameOrFilenameString
save image in my format on aFile

o  save: image onFile: aFileName quality: qualityPercentOrNil
save image in my format on aFile

o  save: image onStream: aStream
save image in my file-format onto aStream

o  save: image onStream: aStream quality: qualityPercentOrNil
save image in my format on a Stream.
QualityPercent is ignored by lossless formats (jpg uses it)

o  saveAll: aCollectionOfImages onFile: aFileName
save a collection of images in my format on aFile.
Not all file formats support multiple images,
so be prepared for an exception to be raised.

o  saveAll: aCollectionOfImages onStream: aStream
save an image collection in my format on a Stream.
Not all file formats support multiple images,
so be prepared for an exception to be raised.

initialization
o  initialize
(comment from inherited method)
just to ignore initialize to objects which do not need it

progress reporting
o  dimensionCallBack: aBlock
set the block, which is evaluated during the readProcess, as soon as
the images dimension is known. This is useful for background image reading,
if the size is need to be known (for example: for formatting purposes).
Obsoleted by dimensionHolder.

** This is an obsolete interface - do not use it (it may vanish in future versions) **

o  dimensionHolder: aValueHolderOrBlock
set the valueHolder or block, which is evaluated during the readProcess,
as soon as the images dimension is known.
Useful for background image reading, if the size is need to be known (for example: for formatting purposes).

o  progressHolder: aValueHolderOrBlock
set the valueHolder or block, which is evaluated during the readProcess,
and set with progress information (0..100 percent).
Useful for user feedback

o  reportDimension

o  reportProgress: fraction
can be used by a GUI application to indicate loading progress (0..1)


Private classes:

    EnforcedImageTypeQuery


ST/X 7.7.0.0; WebServer 1.702 at 20f6060372b9.unknown:8081; Sat, 21 Dec 2024 18:56:52 GMT