|
Class: ImageReader
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
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.
copyrightCOPYRIGHT (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.
cleanup
-
lowSpaceCleanup
-
cleanup things we do not need
constants
-
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
-
_decompressCCITT3From: src count: inCount into: dst startingAt: dstIndexIn
-
toggle if it was a terminating code
-
_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.
|
-
decodeDelta: step in: data width: width height: height
-
perform TIFF predictor = 2 delta decoding inplace on data.
Calls primitive c function for speed
-
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
-
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
-
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
-
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.
-
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.
-
decompressRLEFrom: srcBytes at: srcStartIndex into: dstBytes at: dstStartIndex increment: dstIncrement
-
common helper to expand RLE encoded data
-
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.
-
initCCITTTables
-
0
-
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.
|
-
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.
|
-
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.
|
-
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
-
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
-
fromBase64Stream: aStream
-
read an image in my format from aStream, which contains base64 encoded bytes.
Leave image description in instance variables.
-
fromBytes: aByteArray
-
read an image (in my format) from aByteArray.
Return the image or nil (if unrecognized format or error)
-
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'
|
-
fromStream: aStream
-
read an image (in my format) from aStream.
Return the image or nil (if unrecognized format or error).
The stream remains open.
-
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'
|
-
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.
-
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.
-
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
|
-
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.
-
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
|
-
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
-
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.
-
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
-
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
-
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
-
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
-
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
-
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.
-
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
-
new
-
(comment from inherited method)
return an instance of myself without indexed variables
private utilities
-
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
-
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
-
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
-
canRepresent: anImage
-
return true, if anImage can be represented in my file format.
must be redefined in concrete subclasses which support saving.
-
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'
|
-
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
accessing
-
bitsPerPixel
-
return the number of bits per pixel
-
bitsPerRow
-
return the number of bits in one scanline of the image
-
bitsPerSample
-
return the number of bits per sample
-
bytesPerRow
-
return the number of bytes in one scanline of the image
-
colorMap
-
return the colormap
-
compressQuality: qualityPercentIgnoredHere
-
intentionally ignored here (redefined in JPEGReader)
-
data
-
return the raw image data
-
hasMultipleImages
-
-
height
-
return the height of the image
-
image
-
return the image as represented by myself;
If my file contained multiple images, return the first one.
-
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.
-
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.
-
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.
-
mask
-
return the image mask (or nil)
-
metaData
-
non nil, if there was metadata (edif) info present.
-
numberOfImages
-
return the number of images as read.
By default (here), I hold a single image;
however, some fileFormats allow for multiple images
-
orientation
-
non nil, if there was metadata (edif) info present.
If nil is returned, assume topLeft (i.e. 'normal')
-
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.
-
samplesPerPixel
-
return the number of samples per pixel
-
width
-
return the width of the image
accessing-private
-
byteOrder: aSymbol
-
set the byte order - either #lsb or #msb
-
inStream
-
-
inStream: aStream
-
error reporting
-
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)
-
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
-
readLong
-
return the next 4-byte long, honoring the byte-order
-
readShort
-
return the next 2-byte short, honoring the byte-order
-
readShortLong
-
return the next 2-byte short, honoring the byte-order.
There are actually 4 bytes read, but only 2 looked at.
-
readUnsignedLong
-
return the next 4-byte long, honoring the byte-order
-
writeLong: anInteger
-
write a 4-byte long, honoring the byte-order.
-
writeShort: anInteger
-
write a 2-byte short, honoring the byte-order.
image reading
-
fromStream: aStream
-
read an image in my format from aStream.
Leave image description in instance variables.
-
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
-
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.
-
processExifData: exifData msb: msbFirst
-
exif is actually TIFF without an image...
image writing
-
save: image onFile: aFilenameOrFilenameString
-
save image in my format on aFile
-
save: image onFile: aFileName quality: qualityPercentOrNil
-
save image in my format on aFile
-
save: image onStream: aStream
-
save image in my file-format onto aStream
-
save: image onStream: aStream quality: qualityPercentOrNil
-
save image in my format on a Stream.
QualityPercent is ignored by lossless formats (jpg uses it)
-
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.
-
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
-
initialize
-
(comment from inherited method)
just to ignore initialize to objects which do not need it
progress reporting
-
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) **
-
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).
-
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
-
reportDimension
-
-
reportProgress: fraction
-
can be used by a GUI application to indicate loading progress (0..1)
EnforcedImageTypeQuery
|