eXept Software AG Logo

Smalltalk/X Webserver

Documentation of class 'Image':

Home

everywhere
www.exept.de
for:
[back]

Class: Image


Inheritance:

   Object
   |
   +--Image
      |
      +--CachedImage
      |
      +--Depth16Image
      |
      +--Depth1Image
      |
      +--Depth24Image
      |
      +--Depth2Image
      |
      +--Depth32Image
      |
      +--Depth48Image
      |
      +--Depth4Image
      |
      +--Depth64Image
      |
      +--Depth8Image

Package:
stx:libview
Category:
Graphics-Images
Version:
rev: 1.435 date: 2009/11/17 13:28:46
user: cg
file: Image.st directory: libview
module: stx stc-classLibrary: libview
Author:
Claus Gittinger

Description:


this class provides (some time in the future) representation
for all kinds of images (monochrome, greyscale and color)
and will finally replace Form.
For now (only ;-) depths of 1, 2, 4, 8, 16 and 24 are supported.

An Image keeps all of its information in a device independent way,
but may be associated to a device.
The data held keeps all information which was originally present,
even if the display-device has lower resolution.
Therefore, it is possible to process and manipulate images without loosing
color information.

Images may be created manually (by providing a pixel array),
by screen capture or by reading a file (using an ImageReader).
This gives a device independent image.
For display, a device representation is required, which can be
aquired by sending the
    'onDevice:aDevice'
message to the image. This will create a (possibly dithered) device-form,
representing the image using the currently available colors.

In rare cases, an explicit monochrome representation of the image is needed
(X servers take monochrome icons only), this can be created by sending
it the message
    'monochromeOn:aDevice'.

Also, it is planned to generate another hi-color resolution version,
which uses its own colormap and allows the use of all 256 colors on an 8bit display
(this is not currently implemented).

An images pixel interpretation is controlled by the photometric instance variable
and (if that is #palette) a colorMap.
This is in contrast to the ST-80 way, where all of this info is in the colorMap
(and using specialized colorMaps for b&w / greyScale images).
This may change in future versions for more application compatibility.

To convert pictures from/to external file-formats, image readers are used
which have the file-format knowledge built in.
There are readers for most common formats available
(see ImageReader and especially subclasses such as TIFFReader, GIFReader etc.).

File formats are handled by subclasses of ImageReader, which understand
a specific format. You can add more readers, by adding an association
such as ('.jpg' -> JPEGReader) to the class variable 'FileFormats'
(see the classes #initialize method, which sets up some default, and the
patches/display.rc files, which add more).

Some algorithms used here (especially dithering & color allocation) are
experimental and far from being perfect (some are very slow).
For now, the most common cases have been optimized and perform reasonably
fast - however, with uncommon depth/visualType combinations, you may
run into slower fallback methods ...

Much more work is needed if you plan to do heavy image processing and will
(may) be done in the future if there is a demand for it ...
Dithering can be controlled by the DitherAlgorithm classVariable:

   DitherAlgorithm:

   nil                  a simple threshold algorithm
                        (i.e. for mono, p<0.5 -> black, p>=0.5 -> white)

   #pattern             patterned dither
                        (for p, take dithered color to fill pixel;
                         uses dithering in color-class)

   #error               error diffusion dither (Floyd-Steinberg)
                        planned - not yet implemented.



[instance variables:]

    width               <Integer>       the width in pixels
    height              <Integer>       the height in pixels
    bytes               <ByteArray>     the full image information
    photometric         <Symbol>        #rgb, #palette, #blackIs0 or #whiteIs0
    samplesPerPixel     <Integer>       the number of planes
    bitsPerSample       <Array>         the number of bits per plane

    colorMap            <Array>         only if photometric is #palette;
                                        maps pixel values to r/g/b values.

    device              <Workstation>   the device on which deviceForm,
                                        monoDeviceForm and lowResDeviceForm are

    deviceForm          <Form>          the device form which gives the best
                                        possible aproximation of the image on
                                        device using standard colors.

    monoDeviceForm      <Form>          the device form which gives a monochrome
                                        aproximation of the image on device.

    fullColorDeviceForm <Form>          the device form which gives the best
                                        possible aproximation of the image on
                                        device using private colors.
                                        (not yet implemented)

    mask                <ImageMask>     an optional mask;
                                        if non-nil, only pixels for which the
                                        corresponding mask bit is non-zero
                                        are drawn.

    maskedPixelsAre0    <Boolean>       a hint for image processors and drawers
                                        if true, masked pixels are known to be
                                        zero in the pixel bytes.

    fileName            <String>        the name of the file from which the
                                        image was loaded - nil otherwise.
                                        Useful for image save functions
                                        and for the UIPainter utility.

    imageSequence                       the imageSequence, of which the
                                        instance is a frame or nil,
                                        if its not part of a sequence.

    bitsPerPixel                        not used in ST/X
    depth                               - these have been added in instVar-slots
    maxPixelValue                       - according to the ST-80's image class.
    rowByteSize                         - to allow loading of st-80 images
                                        - (which are stored as instVarAt:put: expressions)

[class variables:]

    Lobby               <Registry>      keeps track of known images
                                        (for resource freeing with garbage collector)

    DitherAlgorithm     <Symbol>        defines how to dither

    NumberOfDitherColors <Integer>      defines, how many dither colors to use

    FileFormats         <Dictionary>    associates filename extensions to
                                        image reader classes (now set-up in startup-file)

    CollectGarbageWhenRunningOutOfColors
                        <Boolean>       if true, and we run out of available
                                        device colors during creation of a
                                        device image, collect garbage for
                                        possible image reclamation.
                                        If false, proceed immediately.
                                        Default is true.

    ImageNotFoundQuerySignal
                        <QuerySignal>   raised, if an image could not be loaded
                                        from a file. The parameter is the images
                                        fileName.
                                        A handler may return a replacement
                                        image or proceed with nil.
                                        If unhandled, a nil is returned from the
                                        image creation.

    BadImageFormatQuerySignal
                        <QuerySignal>   raised, if an image could not be loaded
                                        from a file due to a file error or
                                        unsupported format.
                                        A handler may return a replacement
                                        image or proceed with nil.
                                        If unhandled, a nil is returned from the
                                        image creation.

    ImageSaveErrorSignal
                        <Signal>        parent of errors below.

    FileCreationErrorSignal
                        <Signal>        file could not be created when saving an
                                        image.

    CannotRepresentImageSignal
                        <Signal>        the specified ImageReader cannot represent
                                        the given image.

    InformationLostQuerySignal
                        <Signal>        the specified ImageReader can represent
                                        the given image, but some information
                                        (typically color resolution) is lost.
                                        If unhandled, the save proceeds as usual.


caveat:
    the information in
        photometric, bitsPerPixel, bitsPerSample, samplesPerPixel, depth , colorMap and maxPixelValue
    is partially redundant and its handling stupid (not to say: braindamaged ;-).
    The only excuse is that it grew over time, had to incorporate various alien/older schemes for
    compatibility reasons. All of the above belongs into the single colorMap which must migrate from
    a stupid seqColl to a color-aware real colorMap.
    (we are in the process of doing so...)

todo:
    support alpha masks
    cleanup the dithering & conversion code
    cleanup the color/photometric mess


Related information:

    Form
    Icon
    ImageReader

Class protocol:

Signal constants
o  badImageFormatQuerySignal
return the (query-) signal, which is raised if some
bitmap-image could not be loaded due to an unrecognized format.
If unhandled, the image-load returns nil.
Otherwise, it returns whatever the handler proceeds with.
The exception gets either the images fileName or an input stream
as parameter

o  cannotRepresentImageSignal
return the signal, which is raised if some
bitmap-image could not be saved in the requested format.
This happens for example, if a true color image is saved in
xpm format or a color image saved in xbm format.
Applications should either ask the class before saving
(via #canRepresent:) or handle the error and use an alternative
format then.

o  fileCreationErrorSignal
return the signal which is raised if a file could not be
created in an image-save operation.

o  imageErrorSignal
return the parent of all image signals

o  imageLoadErrorSignal
return the parent of all image load error signals

o  imageNotFoundQuerySignal
return the (query-) signal, which is raised if some
bitmap-image could not be loaded from a file.
If unhandled, the image-load returns nil.
Otherwise, it returns whatever the handler proceeds with.
The exception gets the images fileName as parameter

o  imageSaveErrorSignal
return the parent signal of all image-save errors.

o  informationLostQuerySignal
return the (query-) signal, which is raised if some
bitmap-image is saved in a format which cannot represent
the full image (for example: the images mask).
If unhandled, the image-save proceeds.
Otherwise, the handler may show a warn box or whatever and decide
to proceed or abort the saving.

o  unrepresentableColorSignal
return the signal, which is raised if some color is not
representable in the image (when storing a pixel).

cleanup
o  releaseResourcesOnDevice: aDevice
this is sent when a display connection is closed,
to release all cached Images from that device

file reading
o  fromFile: aFileName
read an image from a file - this methods tries to find
out the file format itself (by the extension and by contents)
and lets the appropriate reader read the file.
Also, all bitmap directories along the searchPath are checked
for the file; thus, you can place your private images into a
separate directory, thereby overriding system bitmaps easily.
If the file is unreadable or does not contain an appropriate image,
the ImageNotFoundQuerySignal is raised, which may be handled to
proceed with some replacement image. If unhandled, nil is returned.

o  fromFile: aFileName inPackage: aPackage
read an image for a package from a file.
The filename is assumed to be package-relative (i.e. bitmaps/filename).
This methods tries to find out the file format itself (by the extension and by contents)
and lets the appropriate reader read the file.
Also, all bitmap directories along the searchPath are checked
for the file; thus, you can place your private images into a
separate directory, thereby overriding system bitmaps easily.
If the file is unreadable or does not contain an appropriate image,
the ImageNotFoundQuerySignal is raised, which may be handled to
proceed with some replacement image. If unhandled, nil is returned.

o  fromFile: aFileName on: aDevice
read an image from a file and prepare a device representation.
Return nil (or whatever a handler returned),
if the file is unreadable or does not contain an appropriate image.

o  fromFile: aFileName resolution: res
read an image from a file and (if required) scale the image
as appropriate (only req'd for very high resolution displays).
Return nil (or whatever a handler returned),
if the file is unreadable or does not contain an appropriate image.

o  fromFile: aFileName resolution: dpi on: aDevice
read an image from a file and (if required) scale the image
as appropriate (only req'd with very high resolution displays).
Prepare a device representation.
Return nil (or whatever a handler returned),
if the file is unreadable or does not contain an appropriate image.

o  fromStream: aStream
read an image from a stream - this methods tries to find
out the file format itself (by contents)
and lets the appropriate reader read the file.
To do this, the stream must be positionable.
Return nil (or whatever a handler returned),
if the stream does not contain an appropriate image.

o  fromStream: aStream using: aReaderClass
read an image from a stream, given an imageReaderClass.
Use this, if you know the files format, but it has an invalid
extension (or non-definite header), so #fromStream: could not
find out the images format.
Return nil (or whatever a handler returned),
if the stream does not contain an appropriate image.

initialization
o  addReader: aReaderClass suffix: aSuffix

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

o  addReader: aReaderClass suffix: aSuffix mimeType: mimeType

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

o  fileFormats
return the collection of supported file formats.
The returned dictionary maps file-extensions to image reader classes.

o  flushDeviceImages
simply release all deviceForms

o  initialize
initialize class constants

o  initializeFileFormatTable
initialize a default table to map from file extension to reader class.
The mapping here is a default needed for proper operation of ST/X;
see the 'smalltalk.rc'/'display.rc' startup files for a real (full) map.

o  initializeMIMETable
initialize a default table to map from mime type to reader class.
The mapping here is a default needed for proper operation of ST/X;
see the 'smalltalk.rc'/'display.rc' startup files for a real (full) map.

o  update: something with: aParameter from: changedObject
flush all device specific stuff when restarted from a snapshot

instance creation
o  extent: ext
create a new image, given extent.
Assume a depth of 1, unless an explicit imageClass is the receiver.

o  extent: ext depth: d
ST-80 compatibility

o  extent: ext depth: d antiAliasedPalette: aBasicColorArray bgColor: bgColor

o  extent: ext depth: d antiAliasedPalette: aBasicColorArray bgColor: bgColor mixedArray: mixedArray

o  extent: ext depth: d bits: bits
ST-80 compatibility; assume 32-bit padding

o  extent: ext depth: d bits: bits pad: padding
ST-80 compatibility

o  extent: ext depth: d bitsPerPixel: bpp palette: aColormap usingBits: bits
ST-80 compatibility

o  extent: ext depth: d palette: aColormap
create & return a blank image of the given size.
ST-80 compatibility

o  extent: ext depth: d palette: aColormap bits: bits
ST-80 compatibility

o  extent: ext depth: d palette: aColormap bits: bits pad: padding
ST-80 compatibility

o  extent: ext fromArray: bits offset: offset
ST-80 compatibility

o  fromForm: aForm
create & return an Image given a aForm

o  fromImage: anImage
create & return an Image given another image. This can be used to
convert an image to another depth.

o  fromImage: anImage photometric: photometricOrNil
create & return an Image given another image. This can be used to
convert an image to another depth.

o  fromSubForm: aRectangle in: aForm
create & return an subImage given a aForm

o  fromSubImage: anImage in: aRectangle
create & return an Image from a rectangular area in another image.
This can also be used to get a subimage in another depth.

o  new
create a new image. Redefined to set the photometric to
greyScale with black being 0 as default.

o  newForDepth: depth
create a new image. Redefined to set the photometric to
greyScale with black being 0 as default.

o  width: w height: h
create a new image, given width, height.
Assume a depth of 1, unless an explicit imageClass is the receiver.

o  width: w height: h depth: d
create a new image, given width, height and depth

o  width: w height: h depth: d fromArray: pixelData
create a new image, given width, height, depth and data.
Data must be a ByteArray containing correctly aligned bits for the specified
depth (8-bit padded).

o  width: w height: h depth: d fromArray: pixelData pad: padding
create a new image, given width, height, depth and data.
Data must be a ByteArray containing correctly aligned bits for the specified
depth.

o  width: w height: h fromArray: anArray
create a new image, given width, height. Assume a depth of 1 of the
receiving class is Image.
Data must be a ByteArray containing correctly aligned bits for depth 1
(i.e. 8 bits per byte).

misc
o  ditherAlgorithm
return the way we dither -
#threshold, or nil -> no dither
#pattern, or #ordered -> orderedDither (ugly, but fast)
#error or #floydSteinberg -> errorDiffusion; much better
#burkes -> errorDiffusion; even better.

o  ditherAlgorithm: aSymbol
define how to dither -
#threshold, or nil -> no dither
#pattern, or #ordered -> orderedDither (ugly, but fast)
#error or #floydSteinberg -> errorDiffusion; much better
#burkes -> errorDiffusion; even better.

o  numberOfDitherColors: n
define how many colors (i.e. patterns) to use when
doing a pattern dither

o  orderedDitherMatrixOfSize: sz

queries
o  bytesPerRowForWidth: width depth: bitsPerPixel padding: padding
helper - return the number of bytes in one scanline of an image,
if scanlines are to be padded to padding-bits and the depth of the image is d.

o  defaultPhotometric
return the default photometric pixel interpretation

o  imageDepth
return the depth of images represented by instances of
this class.
Must be redefined in concrete subclasses

** This method raises an error - it must be redefined in concrete classes **

o  imageFileSuffixes
return a collection of suffixes which are recognized as image-file suffix

o  imageReaderClassForMIME: mimeType
return an appropriate imageReader class for a given mime type;
nil if there is none (or it did not install itself)

o  imageReaderClassForSuffix: aSuffix
return an appropriate imageReader class for a given file-suffix;
nil if there is none (or it did not install itself)

o  implementorForDepth: depth
return the class, which best implements images of depth

o  isImageFileSuffix: aSuffix
return true, if the given suffix is known to be an image files suffix

o  mimeTypeFromSuffix: suffix
search my suffix information for a mime type and
return it; return nil if unknown

screen capture
o  fromScreen
return an image of the full screen.
WARNING: this temporarily grabs the display
it may not work from within a buttonMotion
(use #fromScreen:on:grab: with a false grabArg then).

o  fromScreen: aRectangle
return an image of a part of the screen.
WARNING: this temporarily grabs the display
it may not work from within a buttonMotion
(use #fromScreen:on:grab: with a false grabArg then).

o  fromScreen: aRectangle on: aDevice
return an image of a part of a screen, which may be on
another display device.
WARNING: this temporarily grabs the display
it may not work from within a buttonMotion
(use #fromScreen:on:grab: with a false grabArg then).

o  fromScreen: aRectangle on: aDisplay grab: doGrab
return an image of a part of the screen, which may be on
another Display. If the doGrab argument is true, the display
is grabbed (i.e. blocked for others) and a camera cursor is
shown while the readout is done.
WARNING: with doGrab true, this temporarily grabs the display
and it may not work from within a buttonMotion
(use with a false grabArg then).

o  fromScreenArea
return an image of a part of the screen;
let user specify screen area.
This is the same as #fromUser - kept for backward compatibility.
Use #fromUser for ST-80 compatibility.
WARNING: this temporarily grabs the display
it may not work from within a buttonMotion
(use #fromScreen:on:grab: with a false grabArg then).

o  fromUser
return an image of a part of the screen; let user specify screen area.
Same as fromScreenArea, for ST-80 compatibility.
WARNING: this temporarily grabs the display
it may not work from within a buttonMotion
(use #fromScreen:on:grab: with a false grabArg then).

o  fromView: aView
return an image taken from a views contents as currently
on the screen. The returned image has the same depth and photometric
as the Display.
Notice, that for invisible or partial covered views,
the returned Image is NOT correct.
You may want to raise the view before using this method.
WARNING: this temporarily grabs the display
it may not work from within a buttonMotion
(use #fromView:grab: with a false grabArg then).

o  fromView: aView grab: doGrab
return an image taken from a views contents as currently
on the screen. If the doGrab argument is true, the display
is grabbed (i.e. blocked for others) and a camera cursor is
shown while the readout is done.
The returned image has the same depth and photometric
as the Display.
Notice, that for invisible or partial covered views,
the returned Image is NOT correct.
You may want to raise the view before using this method.
WARNING: with doGrab true, this temporarily grabs the display
and it may not work from within a buttonMotion
(use with a false grabArg then).

o  fromView: aView grab: doGrab withDecoration: withDecoration
return an image taken from a views contents as currently
on the screen, optionally with decoration included.
If the doGrab argument is true, the display
is grabbed (i.e. blocked for others) and a camera cursor is
shown while the readout is done.
The returned image has the same depth and photometric
as the Display.
Notice, that for invisible or partial covered views,
the returned Image is NOT correct.
You may want to raise the view before using this method.
WARNING: with doGrab true, this temporarily grabs the display
and it may not work from within a buttonMotion
(use with a false grabArg then).


Instance protocol:

Compatibility-Squeak
o  boundingBox

o  colormapIfNeededForDepth: d

o  fill: aRectangle fillColor: aColor
fill the rectangular area specified by aRectangle with the given color

o  fillBlack: aRectangle
fill the rectangular area specified by aRectangle with the black color

o  fillWhite: aRectangle
fill the rectangular area specified by aRectangle with the white color

o  isTransparentAt: aPoint

Compatibility-VW
o  asCachedImage
return the receiver associated to the current screens device.
For ST-80 compatibility
(ST/X uses Image for both device- and nonDevice-images)

o  asRetainedMedium
return the receiver associated to the current screens device.
For ST-80 compatibility
(ST/X uses Image for both device- and nonDevice-images)

o  bounds: newBounds

o  containsPoint: aPoint
in st-80, images are visualComponents ...

o  convertToPalette: aColormap renderedBy: anImageRenderer
this does not really mimicri the corresponding ST-80 functionality

o  paintBasis
huh - whats that;
I guess, I have to return Color for images without a mask,
and CoverageValue for those with a mask; for now, always return Color

o  preferredBounds

o  tile: bounds from: origin in: tile rule: rule

o  valueAtPoint: aPoint put: aColorValue

accessing
o  bitsPerSample
return the number of bits per sample.
The return value is an array of bits-per-plane.

o  colorMap
return the colormap

o  colorMap: aColorMap
set the colorMap; this also set the photometric to a useful default.

o  colorMapFromArray: anArray
set the colorMap by reading colors from an array with rgb-byte values.
The (byte-)Array argument should be of the form:
#( red0 green0 blue0 red1 green1 blue1 ... redN greenN blueN)
where each component must be a byteValue in 0..255.

o  colorMapFromRGBValueArray: anArray
set the colorMap by reading colors from an array with rgb-integer values.
The (integer-)Array argument should be of the form:
#( rgb0 rgb1 ... rgbN)
where each element must be an rgbValue in 0..FFFFFF.

o  container: aVisualContainer
ignored here - added to allow images to be used like
VisualComponents (later, Image should inherit from it)

o  depth
return the depth of the image

o  device
return the device, the receiver is associated with.
Return nil, if the image is unassigned.

o  extent
return the images extent

o  fileName
return the value of the instance variable 'fileName' (automatically generated)

o  fileName: something
set the value of the instance variable 'fileName' (automatically generated)

o  fullColorId
return the id of the full color image on the device.
Return nil, if the image is unassigned.

o  graphicsDevice
same as #device - for ST-80 compatibility

o  height
return the height of the image

o  id
return the id of the image on the device.
Return nil, if the image is unassigned.

o  imageSequence
return the frameSequence of which this image is a part of;
nil if it is not part of a sequence.

o  imageSequence: aCollection
private entry for imageReaders - set the frameSequence of which
this image is a part of

o  mask

o  mask: anotherImage
set the images mask - currently, this may be nil or a Depth1Image.
(it is planned to support alpha information in a Depth8 maskImage in
the near future).
For depth1 masks: each pixel of the image where a corresponding
1-bit is present in the mask will be drawn;
0-bit mask pixels lead to transparent pixels.

For depth8 masks: (future):
each pixel specifies the alpha value (0..255),
which specifies the transparency of that pixel.
0 means completely transparent, 255 means completely
opaque. The 1-plane mask is a special case of this,
interpreting a 0 as a 0 alpha value and 1's as an
alpha value of 255.

o  maskedPixelsAre0
return true if masked pixels have been cleared to zero

o  maskedPixelsAre0: aBoolean
set/clear the flag which states if masked pixels
have been set to zero. Knowing this to be true allows
faster drawing of the image later; (however, not setting
it will still produce correct output).
This flag is typically set by image readers.

o  monochromeId
return the id of the monochrome image on the device.
Return nil, if the image is unassigned.

o  palette
return the colormap; ST-80 compatibility

o  palette: aColormap
set the colormap; ST-80 compatibility

o  photometric
return the photometric, a symbol such as #palette, #rgb etc.

o  samplesPerPixel
return the number of samples per pixel in the image.
The return value is an array of bits-per-plane.

o  setColorMap: aColorMap

o  width
return the width of the image

accessing-pixels
o  at: aPoint
WARNING: for now, this returns a pixels color
(backward compatibility with ST/X)
In the future, this will return a pixel value (ST-80 compatibility)
Use #colorAt: - for future compatibility.

retrieve the pixel at aPoint; return a color.
Pixels start at 0@0 for upper left pixel, end at
(width-1)@(height-1) for lower right pixel.
You should not use this method for image-processing, its
very slow ...
(it is meant to access individual pixels - for example, in a bitmap editor)

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

o  at: aPoint put: aColor
WARNING: for now, this expects a pixels color
(backward compatibility with ST/X)
In the future, this will expect a pixel value (ST-80 compatibility)
Use #colorAt:put: - for future compatibility.

set the pixel at aPoint to aColor.
Pixels start at 0@0 for the upper left pixel, end at
(width-1)@(height-1) for lower right pixel.
You should not use this method for image-processing, its
very slow ...
(it is meant to access individual pixels - for example, in a bitmap editor)

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

o  atImageAndMask: aPoint put: aColorOrPixelOrNil
set the pixel at x/y to aColor.
If aColor is a mask color (i.e. Color noColor) the mask pixel will be set to 0 (transparent),
otherwise to 1. Nil is treated like noColor.
(used by the bitmap editor)

o  atImageAndMask: aPoint putValue: aPixelValueOrNil
set the pixel at x/y to aColor.
If aPixelValueOrNil is nil, the mask pixel will be set to 0 (transparent),
otherwise to 1. (used by the bitmap editor)

o  atPoint: aPoint
ST-80 compatibility: return the pixelValue at:aPoint.

o  atPoint: aPoint put: aPixelValue
ST-80 compatibility: set the pixelValue at:aPoint.

o  atX: x y: y
WARNING: for now, this returns a pixels color
(backward compatibility with ST/X)
In the future, this will return a pixel value (ST-80 compatibility)
Use #colorAt: - for future compatibility.

Retrieve a pixel at x/y; return a color.
Pixels start at 0@0 for upper left pixel, end at
(width-1)@(height-1) for lower right pixel.
You should not use this method for image-processing, its
very slow ...
(it is meant to access individual pixels - for example, in a bitmap editor)

o  atX: x y: y put: aColor
WARNING: for now, this expects a pixels color
(backward compatibility with ST/X)
In the future, this will expect a pixel value (ST-80 compatibility)
Use #colorAt:put: - for future compatibility.

set the pixel at x/y to aColor.
Pixels start at 0@0 for the upper left pixel, end at
(width-1)@(height-1) for the lower right pixel.
This method checks if the color can be stored in the image.
(i.e. if the receiver is a palette image, the color must be present in there).
You should not use this method for image-processing, it is very slow ...
(it is meant to access individual pixels - for example, in a bitmap editor)

o  atX: x y: y putValue: aPixelValue
set the pixel at x/y to aPixelValue.
The interpretation of the pixelValue depends on the photometric
and the colormap. (see also: Image>>atX:y:put:)
Pixels start at 0@0 for the upper left pixel, end at
(width-1) @ (height-1) for the lower right pixel.
You should not use this method for image-processing, its
very slow ...
(it is meant to access individual pixels - for example, in a bitmap editor)

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

o  bits
return the raw image data; depending on the photometric,
this has to be interpreted as monochrome, greyscale,
palette or rgb data.
It is also packed to be dense, so a 4 bitPerSample palette image
will store 2 pixels per byte, whereas a 2-bitPerPixel image will store
4 pixels per byte.

o  colorAt: aPoint
retrieve a pixel at x/y; return a color.
Pixels start at 0@0 for upper left pixel, end at
(width-1)@(height-1) for lower right pixel.
You should not use this method for image-processing, its
very slow ...
(it is meant to access individual pixels - for example, in a bitmap editor)

o  colorAt: aPoint put: aColor

o  colorAtX: x y: y
retrieve a pixel at x/y; return a color.
Pixels start at 0@0 for upper left pixel, end at
(width-1)@(height-1) for lower right pixel.
You should not use this method for image-processing, its
very slow ...
(it is meant to access individual pixels - for example, in a bitmap editor)

o  colorAtX: x y: y put: aColor
set the pixel at x/y to aColor.
Pixels start at 0@0 for the upper left pixel, end at
(width-1)@(height-1) for the lower right pixel.
This method checks if the color can be stored in the image.
(i.e. if the receiver is a palette image, the color must be present in there).
You should not use this method for image-processing, it is very slow ...
(it is meant to access individual pixels - for example, in a bitmap editor)

o  data
for backward compatibility - will vanish

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

o  data: aByteArray
for backward compatibility - will vanish

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

o  maskAt: aPoint
retrieve the maskValue at aPoint - an integer number which is
0 for masked pixels (invisible), 1 for unmasked (visible).
For images without mask, 1 is returned for all pixels.

o  maskAt: aPoint put: maskValue
set the maskValue at aPoint - an integer number which is
0 for masked pixels (invisible), 1 for unmasked (visible).

o  maskAtX: x y: y
retrieve the maskValue at aPoint - an integer number which is
0 for masked pixels (invisible), 1 for unmasked (visible).
For images without mask, 1 is returned for all pixels.

o  maskAtX: x y: y put: maskValue
set the maskValue at aPoint - an integer number which is
0 for masked pixels (invisible), 1 for unmasked (visible).

o  pixelAt: aPoint
retrieve a pixel at x/y; return a pixel value.
Pixels start at 0@0 for upper left pixel, end at
(width-1)@(height-1) for lower right pixel.
You should not use this method for image-processing, its
very slow ...
(it is meant to access individual pixels - for example, in a bitmap editor)

o  pixelAt: aPoint put: aPixelValue
set the pixel at x/y to aPixelValue.
The interpretation of the pixelValue depends on the photometric
and the colormap. (see also: Image>>atX:y:put:)
Pixels start at 0@0 for the upper left pixel, end at
(width-1) @ (height-1) for the lower right pixel.
You should not use this method for image-processing, its
very slow ...
(it is meant to access individual pixels - for example, in a bitmap editor)

o  pixelAtX: x y: y
retrieve the pixelValue at aPoint; return an integer number.
Pixels start at 0/0 for upper left pixel, and end at
width-1@height-1 for lower right pixel.
The returned numbers interpretation depends on the photometric
and the colormap. (see also Image>>at: and Image>>atX:y:)
You should not use this method for image-processing of
big images, its very slow ...
(it is meant to access individual pixels - for example, in a bitmap editor)

** This method raises an error - it must be redefined in concrete classes **

o  pixelAtX: x y: y put: aPixelValue
set the pixel at x/y to aPixelValue.
The interpretation of the pixelValue depends on the photometric
and the colormap. (see also: Image>>atX:y:put:)
Pixels start at 0@0 for the upper left pixel, end at
(width-1) @ (height-1) for the lower right pixel.
You should not use this method for image-processing, its
very slow ...
(it is meant to access individual pixels - for example, in a bitmap editor)

** This method raises an error - it must be redefined in concrete classes **

o  rgbValueAt: aPoint
retrieve a pixels rgb value at x/y; return a 24bit rgbValue (rrggbb, red is MSB).
Pixels start at 0@0 for upper left pixel, end at (width-1)@(height-1) for lower right pixel.

o  rgbValueAtX: x y: y
retrieve a pixels rgb value at x/y; return a 24bit rgbValue (rrggbb, red is MSB).
Pixels start at 0@0 for upper left pixel, end at (width-1)@(height-1) for lower right pixel.

o  rgbValueAtX: x y: y put: newRGBValue

o  rowAt: y
retrieve an array filled with pixel values from
a single row.
Notice: row coordinate starts at 0.
This is a slow fallBack method, which works with any depth;
concrete image subclasses should redefine this for more performance.

o  rowAt: y into: aPixelBuffer
fill aBuffer with pixel values retrieved from a single row.
Notice: row coordinate starts at 0.

o  rowAt: y into: aPixelBuffer startingAt: startIndex
fill aBuffer with pixel values retrieved from a single row.
Notice: row coordinate starts at 0.
This is a slow fallBack method, which works with any depth;
concrete image subclasses should redefine this for more performance.

o  rowAt: y putAll: pixelArray
store a single rows pixels from bits in the argument;
Notice: row coordinate starts at 0.
This is a slow fallBack method, which works with any depth;
concrete image subclasses should redefine this for more performance.

o  rowAt: y putAll: pixelArray startingAt: startIndex
store a single rows pixels from bits in the pixelArray argument;
return the pixelArray.
Notice: row coordinate starts at 0.
This is a slow fallBack method, which works with any depth;
concrete image subclasses should redefine this for more performance.

o  valueAt: aPoint
WARNING: for now, this returns a pixels value
(backward compatibility with ST/X)
In the future, this will return a color (ST-80 compatibility)
Use #pixelAt: - for future compatibility.

Retrieve the pixelValue at aPoint; return an integer number.
Pixels start at 0@0 for upper left pixel, end at
width-1@height-1 for lower right pixel.
The returned numbers interpretation depends on the photometric
and the colormap. (see also Image>>at: and Image>>atX:y:)
You should not use this method for image-processing, its
very slow ...
(it is meant to access individual pixels - for example, in a bitmap editor)

o  valueAtX: x y: y
WARNING: for now, this returns a pixels value
(backward compatibility with ST/X)
In the future, this will return a color (ST-80 compatibility)
Use #pixelAt: - for future compatibility.

Retrieve the pixelValue at aPoint; return an integer number.
Pixels start at 0/0 for upper left pixel, and end at
width-1@height-1 for lower right pixel.
The returned numbers interpretation depends on the photometric
and the colormap. (see also Image>>at: and Image>>atX:y:)
You should not use this method for image-processing of
big images, its very slow ...
(it is meant to access individual pixels - for example, in a bitmap editor)

accessing-private
o  bits: aByteArray
set the raw data.

This interface is only to be used when initializing
instances or by image readers. Calling for a change of an
existing image may confuse later pixel interpretation
(it does not care for colormaps and/or cached device image flushing).

o  bitsPerSample: aCollection
set the number of bits per sample.

This interface is only to be used when initializing
instances or by image readers. Calling for a change of an
existing image may confuse later pixel interpretation.

o  depth: d
set the depth of the image.

This interface is only to be used when initializing
instances or by image readers. Calling for a change of an
existing image may confuse later pixel interpretation.

o  extent: anExtent
set the images extent.

This interface is only to be used when initializing
instances or by image readers. Calling for a change of an
existing image may confuse later pixel interpretation.

o  hasAlphaChannel

o  height: aNumber
set the height of the image.

This interface is only to be used when initializing
instances or by image readers. Calling for a change of an
existing image may confuse later pixel interpretation.

o  photometric: aSymbol
set the photometric interpretation of the pixel values.
The argument, aSymbol is one of:
#blackIs0, #whiteIs0, #palette, #rgb
See TIFF documentation, from which the photometric concept is borrowed.

This interface is only to be used when initializing
instances or by image readers. Calling for a change of an
existing image may confuse later pixel interpretation.

o  samplesPerPixel: aNumber
set the array of samples per pixel.

This interface is only to be used when initializing
instances or by image readers. Calling for a change of an
existing image may confuse later pixel interpretation.

o  width: aNumber
set the width of the image.

This interface is only to be used when initializing
instances or by image readers. Calling for a change of an
existing image may confuse later pixel interpretation.

o  width: w height: h
set the width and height of the image.

This interface is only to be used when initializing
instances or by image readers. Calling for a change of an
existing image may confuse later pixel interpretation.

o  width: w height: h depth: d
set the width, height and depth of the image.

This interface is only to be used when initializing
instances or by image readers. Calling for a change of an
existing image may confuse later pixel interpretation.

o  width: w height: h depth: d fromArray: bits
set the width, height, depth and pixels of the image.

This interface is only to be used when initializing
instances or by image readers. Calling for a change of an
existing image may confuse later pixel interpretation.

o  width: w height: h depth: d palette: aColormap
set the width, height and depth of the image.

This interface is only to be used when initializing
instances or by image readers. Calling for a change of an
existing image may confuse later pixel interpretation.

o  width: w height: h photometric: p samplesPerPixel: spp bitsPerSample: bps colorMap: cm bits: pixels
set all relevant internal state of the image.

This interface is only to be used when initializing
instances or by image readers. Calling for a change of an
existing image may confuse later pixel interpretation.

o  width: w height: h photometric: p samplesPerPixel: spp bitsPerSample: bps colorMap: cm bits: pixels mask: m
set all relevant internal state of the image.

This interface is only to be used when initializing
instances or by image readers. Calling for a change of an
existing image may confuse later pixel interpretation.

binary storage
o  readBinaryContentsFrom: stream manager: manager
read a binary representation of an image from stream.
Redefined to flush any device data.

o  storeBinaryDefinitionOn: stream manager: manager
store a binary representation of the receiver on stream.
This is an internal interface for binary storage mechanism.
Redefined to not store the device form (which is recreated at
load time anyway)

conversion helpers
o  rgbColormapFor: aDevice
helper for conversion to rgb format

converting
o  asBurkesDitheredMonochromeImage
return a burkes dithered monochrome image from the receiver image.
Depending on the images contents, this may or may not look better than
a floyd-steinberg dithered image.
Notice, that floyd-steinberg dithering is faster; both because less
error diffusion is done and due to being specially tuned.

o  asDitheredImageUsing: colors
return a dithered image from the picture,
using colors in colors for dithering.

o  asDitheredImageUsing: colors depth: d
return a dithered image from the picture,
using colors in colors for dithering.

o  asErrorDitheredMonochromeImage
return an error-diffusion dithered monochrome image from the receiver image.

o  asFloydSteinbergDitheredDepth8FormOn: aDevice colors: fixColors
return a floyd-steinberg dithered pseudoForm from the picture.
Use the colors in the fixColors array.
By passing the ditherColors as extra array, this method can
also be used to dither an 8bit image into a smaller number of colors,
for example to create dithered Depth4Images from Depth8Images.

o  asFloydSteinbergDitheredDepth8FormOn: aDevice colors: fixColors nRed: nRed nGreen: nGreen nBlue: nBlue
return a floyd-steinberg dithered pseudoForm from the palette picture.
Use the colors in the fixColors array, which must be fixR x fixG x fixB
colors assigned to aDevice, such as the preallocated colors of the
Color class.
By passing the ditherColors as extra array, this method can
also be used to dither an 8bit image into a smaller number of colors,
for example to create dithered Depth4Images from Depth8Images.

o  asFloydSteinbergDitheredGrayFormOn: aDevice
return a dithered depth-x grey form from the receiver image.

o  asFloydSteinbergDitheredGrayImageDepth: depth
return a floyd-steinberg dithered image from the receiver image.

o  asFloydSteinbergDitheredMonochromeFormOn: aDevice
return a dithered moncohrome form from the receiver image.

o  asFloydSteinbergDitheredMonochromeImage
return a floyd-steinberg dithered monochrome image from the receiver image.

o  asFloydSteinbergDitheredPseudoFormUsing: colors on: aDevice
return a floyd-steinberg dithered pseudoForm from the picture,
using colors in colors for dithering.

o  asFormOn: aDevice
get a device form, with best possible approximation.
remember it in case someone asks again.

o  asGrayFormOn: aDevice
get a gray device form

o  asGrayFormOn: aDevice dither: aDitherAlgorithm
get a greyscale device form, using aDitherAlgorithm.

o  asGrayImageDepth: depth
get a gray image from the receiver

o  asGrayImageDepth: depth dither: aDitherAlgorithm
get a greyscale image, using aDitherAlgorithm.

o  asImageWithDepth: depth
return a new image with another depth. Notice that this
may raise an error, if the depth is smaller than the receivers depths
and the number of colors is greater than the number of possible colors
for the new depth - i.e. you should use this only to convert to a higher depth.
In the other case, use one of the dithering converters

o  asMonochromeFormOn: aDevice
get a monochrome device form

o  asMonochromeFormOn: aDevice dither: aDitherAlgorithm
get a monochrome device form, using aDitherAlgorithm.

o  asNearestPaintDepth8FormOn: aDevice colors: fixColors
return a nearest paint pseudoForm from the palette picture.
Use the colors in the fixColors array.
By passing the ditherColors as extra array, this method can
also be used to dither an 8bit image into a smaller number of colors,
for example to create dithered Depth4Images from Depth8Images.

o  asNearestPaintDepth8FormOn: aDevice colors: fixColors nRed: nRed nGreen: nGreen nBlue: nBlue
return a nearest paint pseudoForm from the palette picture.
Use the colors in the fixColors array, which must be fixR x fixG x fixB
colors assigned to aDevice, such as the preallocated colors of the
Color class.
By passing the ditherColors as extra array, this method can
also be used to dither an 8bit image into a smaller number of colors,
for example to create dithered Depth4Images from Depth8Images.

o  asNearestPaintImageDepth: d colors: colors
return a threshold image from the receiver picture, using colors in colors.

o  asOrderedDitheredGrayFormOn: aDevice
return a dithered depth-x grey form from the receiver image.
Uses an 8x8 dithermatrix.

o  asOrderedDitheredGrayImageDepth: depth
return a dithered depth-x grey image from the receiver image.
Uses an 8x8 dithermatrix.

o  asOrderedDitheredMonochromeFormOn: aDevice
return a dithered monochrome form from the grey image.
Uses a 4x4 dithermatrix.

o  asOrderedDitheredMonochromeFormOn: aDevice ditherMatrix: ditherMatrix ditherWidth: dW
return a dithered monochrome form from the image.
Uses the passed ditherMatrix and ditherWidth.

o  asOrderedDitheredMonochromeImage
return a dithered monochrome image from the receiver image.
Uses a 4x4 dithermatrix.

o  asOrderedDitheredMonochromeImageWithDitherMatrix: ditherMatrix ditherWidth: dW
return a dithered monochrome image from the receiver image.
Uses the passed ditherMatrix and ditherWidth.

o  asPseudoFormQuickOn: aDevice
return a pseudo-deviceForm from the image.
Fail if any color is not available (i.e. do not dither).

o  asStevensonArceDitheredMonochromeImage
return a stevenson-arce dithered monochrome image from the receiver image.
Depending on the images contents, this may or may not look better than
a floyd-steinberg dithered image.
Notice, that floyd-steinberg dithering is faster; both because less
error diffusion is done and due to being specially tuned.

o  asThresholdGrayFormOn: aDevice
return a thresholded grey form from the receiver image.

o  asThresholdGrayImageDepth: depth
return a thresholded depth-x grey image from the receiver image.

o  asThresholdMonochromeFormOn: aDevice
return a threshold monochrome form from the image.

o  asThresholdMonochromeImage
return a threshold monochrome image from the image.
Threshold means: brightness < 0.5 -> black / otherwise white

o  asThresholdMonochromeImage: thresholdBrighness
return a threshold monochrome image from the image.
The argument (0..1) gives the threshold value;
Threshold means: brightness < threshold -> black / otherwise white

o  clearMaskedPixels
assuming that I already have a device representation
in deviceForm, clear any masked pixels.
This will allow faster drawing in the future.

o  exactOn: aDevice
for compatibility with color protocol - here, the same as #onDevice.

o  exactOrNearestOn: aDevice
for compatibility with color protocol - here, the same as #onDevice.

o  fromForm: aForm
setup the receiver from a form

o  fromImage: anImage
setup the receiver from another image.
Color precision may be lost, if conversion is from a higher depth image.
WARNING:
This implementation is a slow fallback (the loop over the
source pixels is very slow). If this method is used heavily, you
may want to redefine it in concrete subclasses for common source images.

o  fromImage: anImage photometric: photometricOrNil
setup the receiver from another image and optionally set the photometric.
Color precision may be lost, if conversion is from a higher depth image.
WARNING:
This implementation is a slow fallback (the loop over the
source pixels is very slow). If this method is used heavily, you
may want to redefine it in concrete subclasses for common source images.

o  fromSubImage: anImage in: aRectangle
setup the receiver from another image, extracting a rectangular
area. Color precision may be lost, if conversion is from a higher depth
image. For palette & rgb images, this may fail if a color cannot be
represented.

WARNING:
This implementation is a slow fallback (the loop over the
source pixels is very slow). If this method is used heavily, you
may want to redefine it in concrete subclasses for the common case of
of creating a subImage with the same depth & palette.

o  monochromeOn: aDevice
return a monochrome device image of the receiver for aDevice.
(monochrome, even if device supports colors)

o  nearestOn: aDevice
for compatibility with color protocol - here, the same as #onDevice.

o  on: aDevice
return an image with the same pixels as the receiver, but
associated to aDevice. If the receiver is not yet bound to
a device, this will be the receiver. Otherwise, a new image
is returned.

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

o  onDevice: aDevice
return an image with the same pixels as the receiver, but
associated to aDevice. If the receiver is not yet bound to
a device, this will be the receiver. Otherwise, a new image
is returned.

converting greyscale images
o  greyImageAsFormOn: aDevice
return a grey-deviceForm from the grey image.

o  greyImageAsPseudoFormOn: aDevice
return an 8-bit pseudo Form from the grey image

o  greyImageAsTrueColorFormOn: aDevice
return a true-color device-form for the grey-image receiver.
TODO: the pixel loops ought to be implemented as inline primitive code ...

converting palette images
o  paletteImageAsFormOn: aDevice
return a device-form for the palette-image receiver

o  paletteImageAsPseudoFormOn: aDevice
return a pseudo-deviceForm from the palette image.

** This method raises an error - it must be redefined in concrete classes **

o  paletteImageAsTrueColorFormOn: aDevice
return a true-color device-form for the palette-image receiver.

converting rgb images
o  asDitheredTrueColor8FormOn: aDevice
convert an rgb image to a dithered depth8-form on aDevice.
Return the device-form.
This method is only valid for trueColor displays.

o  rgbImageAsFormOn: aDevice
convert am rgb image to a device-form on aDevice.
Return the device-form.

o  rgbImageAsPseudoFormOn: aDevice
return a pseudocolor form from the rgb-picture

** This method raises an error - it must be redefined in concrete classes **

o  rgbImageAsTrueColorFormOn: aDevice
return a truecolor form from the rgb-picture.

copying
o  postCopy
redefined to also copy the pixels and the colorMap
and clear out any device handles in the copy.

o  skipInstvarIndexInDeepCopy: index
a helper for deepCopy; only indices for which this method returns
false are copied in a deep copy.

displaying
o  asImage
ST-80 compatibility

o  displayFilledOn: aGC
display the receiver as an opaque image.
This allows Images to be wrapped by a FillingWrapper

o  displayOn: aGC x: x y: y
draw the receiver in the graphicsContext, aGC.
Smalltalk-80 compatibility

o  displayOn: aGC x: x y: y opaque: opaque
draw the receiver in the graphicsContext, aGC.
Smalltalk-80 compatibility

o  displayOpaqueOn: aGC at: aPoint
draw the receiver in the graphicsContext, aGC.
Smalltalk-80 compatibility

o  displayOpaqueOn: aGC x: x y: y
draw the receiver in the graphicsContext, aGC.
Smalltalk-80 compatibility

o  displayStrokedOn: aGC
display the receiver as an non opaque image.
This allows Images to be wrapped by a StrokingWrapper

dither helpers
o  burkesDitheredMonochromeBits
return the bitmap for a dithered monochrome bitmap from the image.
Works for any source depths / photometric

o  floydSteinbergDitheredDepth8BitsColors: colors
return a floyd-steinberg dithered bitmap from the receiver picture,
which must be a depth-8 image.
This method expects an array of colors to be used for dithering
(which need not be a colorCubes colors).

o  floydSteinbergDitheredDepth8BitsColors: colors map: aMapOrNil
return a floyd-steinberg dithered bitmap from the receiver picture,
which must be a depth-24 image.
This method expects an array of colors to be used for dithering
(which need not be a colorCubes colors).

o  floydSteinbergDitheredDepth8BitsColors: fixColors nRed: nRed nGreen: nGreen nBlue: nBlue
return a floyd-steinberg dithered bitmap from the receiver picture,
which must be a depth-8 image.
This is a special-cased dither method for 8-bit palette images being displayed on
an 8-bit pseudoColor display, AND fixColor dithering is used.
Use the colors in the fixColors array, which must be fixR x fixG x fixB
colors assigned to aDevice, such as the preallocated colors of the
Color class.
By passing the ditherColors as extra array, this method can
also be used to dither an 8bit image into a smaller number of colors,
for example to create dithered Depth4Images from Depth8Images.

o  floydSteinbergDitheredGrayBitsDepth: depth
return the bits for dithering a gray image from the image.
Works for any source depths / photometric,
but possibly slow since each pixel is processed individually.
Redefined by some subclasses for more performance (D8Image/D24Image)

o  floydSteinbergDitheredMonochromeBits
return the bitmap for a dithered monochrome bitmap from the image.
Works for any source depths / photometric,
but very very slow since each pixel is processed individually.
Redefined by some subclasses for more performance (D8Image)

o  nearestPaintDepth8BitsColors: fixColors nRed: nRed nGreen: nGreen nBlue: nBlue
return a nearest paint bitmap from the receiver picture,
which must be a depth-8 image.
This is a special-cased dither method for 8-bit palette images being displayed on
an 8-bit pseudoColor display, AND fixColor dithering is used.
Use the colors in the fixColors array, which must be fixR x fixG x fixB
colors assigned to aDevice, such as the preallocated colors of the
Color class.

o  nfloydSteinbergDitheredDepth8BitsColors: colors
return a floyd-steinberg dithered bitmap from the receiver picture,
which must be a depth-8 image.
This method expects an array of colors to be used for dithering
(which need not be a colorCubes colors).

o  orderedDitheredGrayBitsDepth: depth
return the bitmap for a dithered depth-bitmap from the image

o  orderedDitheredGrayBitsWithDitherMatrix: ditherMatrix ditherWidth: dW depth: depth
return the bitmap for a dithered depth-bitmap from the image;
with a constant ditherMatrix, this can be used for thresholding.
Works for any source depths / photometric,
but very very slow since each pixel is processed individually.
Redefined by some subclasses for more performance (D8Image)

o  orderedDitheredMonochromeBits
return the bitmap for a dithered monochrome bitmap from the image;
using a default ditherMatrix.

o  orderedDitheredMonochromeBitsWithDitherMatrix: ditherMatrix ditherWidth: dW
return the bitmap for a dithered monochrome bitmap from the image;
with a constant ditherMatrix, this can be used for thresholding.
Works for any source depths / photometric,
but very very slow since each pixel is processed individually.
Redefined by some subclasses for more performance (D8Image)

o  stevensonArceDitheredMonochromeBits
return the bitmap for a dithered monochrome bitmap from the image.
Works for any source depths / photometric

drawing
o  displayArcOrigin: origin corner: corner from: startAngle angle: angle withColor: aColor
draw a circle with some pixel value.
By using a tempForm, we assure that the same pixel algorithm is used as in a window

o  displayArcOrigin: origin corner: corner from: startAngle angle: angle withValue: aPixelValueOrNil
draw a circle with some pixel value.
By using a tempForm, we assure that the same pixel algorithm is used as in a window.
If aPixelValueOrNil is nil, the mask pixel will be set to 0 (transparent),
otherwise to 1. (used by the bitmap editor)

o  drawEllipse: aRectangle withColor: aColor
draw a circle with some pixel value.
By using a tempForm, we assure that the same pixel algorithm is used as in a window

o  drawEllipse: aRectangle withValue: aPixelValueOrNil
draw a circle with some pixel value.
By using a tempForm, we assure that the same pixel algorithm is used as in a window.
If aPixelValueOrNil is nil, the mask pixel will be set to 0 (transparent),
otherwise to 1. (used by the bitmap editor)

o  drawLineFrom: startPoint to: endPoint withColor: aColorOrPixelValue
draw a line with some pixel value.
This is in no way tuned, as normally, display-forms are used to draw.
The only use for this is when we have to generate images in a headless webService
(such as the HumanReadableImageGenerator)

o  drawLineFrom: startPoint to: endPoint withValue: aPixelValueOrNil
draw a line with some pixel value.
This is in no way tuned, as normally, display-forms are used to draw.
The only use for this is when we have to generate images in a headless webService
(such as the HumanReadableImageGenerator).
If aPixelValueOrNil is nil, the mask pixel will be set to 0 (transparent),
otherwise to 1. (used by the bitmap editor)

o  drawRectangle: aRectangle withColor: aColor
draw a rectangle with some pixel value.
By using #atImageAndMask:put: it also works on images with mono masks.

o  drawRectangle: aRectangle withValue: aPixelValueOrNil
draw a rectangle with some pixel value.
By using #atImageAndMask:put: it also works on images with mono masks.
If aPixelValueOrNil is nil, the mask pixel will be set to 0 (transparent),
otherwise to 1. (used by the bitmap editor)

o  fillAntiAliasedArc: origin radius: r from: startAngle angle: angle withColor: aColor colorDictionary: colorDictionary blendStart: blendStart
draw a circle with some pixel value.
By using a tempForm, we assure that the same pixel algorithm is used as in a window

o  fillArc: origin radius: r from: startAngle angle: angle withColor: aColorOrIndex
draw a circle with some pixel value.
By using a tempForm, we assure that the same pixel algorithm is used as in a window

o  fillEllipse: aRectangle withColor: aColor
draw a circle with some pixel value.
By using a tempForm, we assure that the same pixel algorithm is used as in a window

o  fillEllipse: aRectangle withValue: aPixelValueOrNil
draw a circle with some pixel value.
By using a tempForm, we assure that the same pixel algorithm is used as in a window.
If aPixelValueOrNil is nil, the mask pixel will be set to 0 (transparent),
otherwise to 1. (used by the bitmap editor)

o  fillRectangle: aRectangle withColor: aColor

o  fillRectangle: aRectangle withValue: aPixelValueOrNil
fill a rectangular area with some pixel value.
May be redefined in concrete subclasses for more performance, if req'd.
If aPixelValueOrNil is nil, the mask pixel will be set to 0 (transparent),
otherwise to 1. (used by the bitmap editor)

o  fillRectangleX: x y: y width: w height: h with: aColor
fill a rectangular area with a aColor

o  fillRectangleX: x y: y width: w height: h withValue: aPixelValueOrNil
fill a rectangular area with some pixel value.
May be redefined in concrete subclasses for more performance, if req'd.
If aPixelValueOrNil is nil, the mask pixel will be set to 0 (transparent),
otherwise to 1. (used by the bitmap editor)

o  floodFillAt: aPoint withColor: aColor
fill a area with aColor like a flood up to surrounded pixels having different colors.
By using #atImageAndMask:put: it also works on images with mono masks.

o  floodFillAt: aPoint withValue: aPixelValueOrNil
fill a area with aColor like a flood up to surrounded pixels having different colors.
By using #atImageAndMask:put: it also works on images with mono masks.

o  rectangle: aRectangle withColor: aColor

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

enumerating
o  atY: y from: x1 to: x2 do: aBlock
perform aBlock for each pixel from x1 to x2 in row y.
The block is passed the color at each pixel.
The code here provides a generic and slow implementation, and
should be redefined in concrete subclasses, to avoid some processing
when going from pixel to pixel (i.e. the byte-index and mask computations
and also the color allocation).

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

o  colorsAtX: x from: y1 to: y2 do: aBlock
perform aBlock for each pixel from y1 to y2 in col x.
The block is passed the color at each pixel.
The code here provides a generic and slow implementation, and
should be redefined in concrete subclasses, to avoid some processing
when going from pixel to pixel (i.e. the byte-index and mask computations
and also the color allocation).

o  colorsAtY: y from: x1 to: x2 do: aBlock
perform aBlock for each pixel from x1 to x2 in row y.
The block is passed the color at each pixel.
The code here provides a generic and slow implementation, and
should be redefined in concrete subclasses, to avoid some processing
when going from pixel to pixel (i.e. the byte-index and mask computations
and also the color allocation).

o  colorsFromX: xStart y: yStart toX: xEnd y: yEnd do: aBlock
perform aBlock for each color in a rectangular area of the image.
Notice, that x and y coordinates start at 0@0 for the upper left corner.
The block is passed the x and y coordinates and pixelValue at each pixel.
The code here provides a generic and slow implementation, and
should be redefined in concrete subclasses, to avoid some processing
when going from pixel to pixel (i.e. the byte-index and mask computations,
and especially, the color allocations).

o  valueAtY: y from: x1 to: x2 do: aBlock
perform aBlock for each pixelValue from x1 to x2 in row y.
Obsolete - remains for backward compatibility.

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

o  valuesAtY: y from: x1 to: x2 do: aBlock
WARNING: for now, this enumerates pixel values
(backward compatibility with ST/X)
In the future, this will enumerate colors
Use #pixelAtT:from:to:do: - for future compatibility.

perform aBlock for each pixelValue from x1 to x2 in row y.
Notice, that x and y coordinates start at 0@0 for the upper left corner.
The block is passed the x coordinate and the pixelValue at each pixel.
(see also Image>>atY:from:to:do:).
The code here provides a generic and slow implementation, and
should be redefined in concrete subclasses, to avoid some processing
when going from pixel to pixel (i.e. the byte-index and mask computations).

o  valuesFromX: xStart y: yStart toX: xEnd y: yEnd do: aBlock
perform aBlock for each pixelValue in a rectangular area of the image.
Notice, that x and y coordinates start at 0@0 for the upper left corner.
The block is passed the x and y coordinates and pixelValue at each pixel.
The code here provides a generic and slow implementation, and
should be redefined in concrete subclasses, to avoid some processing
when going from pixel to pixel (i.e. the byte-index and mask computations).

finalization
o  finalizationLobby
answer the registry used for finalization.
Images have their own Registry

o  finalize
some Image has been collected - nothing to do

image manipulations
o  applyPixelValuesTo: pixelFunctionBlock in: aRectangle into: newImage
helper for withPixelFunctionAppliedToValues:
enumerate pixelValues and evaluate the block for each.
Could be redefined by subclasses for better performance.

o  applyPixelValuesTo: pixelFunctionBlock into: newImage
helper for withPixelFunctionAppliedToValues:
enumerate pixelValues and evaluate the block for each.

o  blendWith: aColor
return a new image which is blended with some color.
The receiver must be a palette image (currently).
CAVEAT: this only works with palette images (i.e. not for rgb or greyScale).
CAVEAT: Need an argument, which specifies by how much it should be lighter.

o  colorMapProcessing: aBlock
a helper for all kinds of colormap manipulations.
The argument, aBlock is called for every colormap entry,
and the returned value will replace the original entry in the map.
This will fail for non-palette images.
See examples in Image>>copyWithColorMapProcessing:

o  copyWithColorMapProcessing: aBlock
a helper to create & return new images based on the receiver with
some colorMap processing. The receiver is copied, and the copied images
colormap is modified by replacing entries with the result of the processing block,
which is called with the original color values. The block is supposed to return
a color.
CAVEAT: this only works with palette images (i.e. not for rgb or greyScale)

o  createMask

o  darkened
return a new image which is slightly darker than the receiver.
The receiver must be a palette image (currently).
CAVEAT: this only works with palette images (i.e. not for rgb or greyScale).
CAVEAT: Need an argument, which specifies by how much it should be darker.

o  easyRotateBitsInto: destinationImage angle: degrees
helper for rotation - does the actual pixel shuffling.
by degrees clockwise. Here, only 90, 180 and 270 degrees
are implemented. Hard angles are done in #hardRotate:.
The code here is depth-independent (but not too fast);
can be redefined in subclasses for more performance

o  flipHorizontal
destructively inplace horizontal flip

o  flipVertical
inplace vertical flip

o  hardAntiAliasedMagnifiedBy: scalePoint
return a new image magnified and antiAliased by scalePoint, aPoint.
This converts into a depth24Image before doing the antiAlias-magnify.
It is definitely slower than the non antiAliasing/integral magnification methods.

o  hardMagnifiedBy: scalePoint
return a new image magnified by scalePoint, aPoint.
This is the general magnification method, handling non-integral values.
It is slower than the integral magnification method.

o  hardRotated: degrees
return a new image from the old one, by rotating the image
degrees clockwise (around its center).
Warning: the returned image will be larger than the original image.

o  lightened
return a new image which is slightly brighter than the receiver.
The receiver must be a palette image (currently).
CAVEAT: this only works with palette images (i.e. not for rgb or greyScale).
CAVEAT: Need an argument, which specifies by how much it should be lighter.

o  magnifiedBy: scale
return a new image magnified by scalePoint, aPoint.
If non-integral magnify is asked for, pass the work on to 'hardMagnifyBy:'
while simple (integral) magnifications are handled here.

o  magnifiedPreservingRatioTo: anExtent
return a new image magnified to fit into anExtent,
preserving the receivers width/height ratio.
(i.e. not distorting the image).
See also #magnifiedTo: and #magnifiedBy:

o  magnifiedTo: anExtent
return a new image magnified to have the size specified by extent.
This may distort the image if the arguments ratio is not the images ratio.
See also #magnifiedPreservingRatioTo: and #magnifiedBy:

o  mixed: amount with: aColor
return a new image which is blended with some color;
amount determines how much of the blending color is applied (0..)
where 0 means: blending color pure.
The receiver must be a palette image (currently).
CAVEAT: this only works with palette images (i.e. not for rgb or greyScale).
CAVEAT: Need an argument, which specifies by how much it should be lighter.

o  negative
return a new image which is a negative of the receiver.
The receiver must be a palette image (currently).

o  rotated: degrees
return a new image from the old one, by rotating the image
degrees clockwise.
Notice, that the resulting image has a different extent.
If rotation is heavily used, the workHorse methods
(#easyRotateBitsInto:angle: and #hardRotateBitsInto:angle) may
be redefined in concrete image subclasses.

o  threeDProjected: fraction1 and: fraction2
return a 3D-projected version

o  withColorResolutionReducedBy: numBits
return a new image with the same picture as the receiver, but reduced colorResolution;
that is, the lower numBits are cleared in the r/g/b color components.
If anything fails, return nil.

o  withPixelFunctionApplied: pixelFunctionBlock
return a new image from the old one, by applying a pixel processor
on the pixel colors.
Notice: this method is very slow - either apply pixel values
(#withPixelFunctionAppliedToPixels:) or redefine this method in
a concrete subclass.
(read `Beyond photography, by Gerard J. Holzmann;
ISBM 0-13-074410-7)
See blurred / oilPointed as examples ...)

o  withPixelFunctionAppliedToPixels: pixelFunctionBlock
return a new image from the old one, by applying a pixel processor
on the pixel values.
(read `Beyond photography, by Gerard J. Holzmann;
ISBM 0-13-074410-7)
See blurred / oilPointed as examples ...)

o  withPixelFunctionAppliedToPixels: pixelFunctionBlock in: aRectangle
return a new image from the old one, by applying a pixel processor
on the pixel values.
(read `Beyond photography, by Gerard J. Holzmann;
ISBM 0-13-074410-7)
See blurred / oilPointed as examples ...)

initialization
o  createPixelStore

o  initialize

inspecting
o  inspectorClass
redefined to launch an ImageInspector
(instead of the default InspectorView).

instance release
o  close
release device resources; destroy any device-resources

o  release
release device resources

o  releaseFromDevice
release device resources

o  restored
flush device specifics after a snapin or binary restore

misc
o  edit
open an image editor on the receiver

obsolete
o  applyPixelValuesTo: pixelFunctionBlock into: newImage in: aRectangle
helper for withPixelFunctionAppliedToValues:
enumerate pixelValues and evaluate the block for each.
To be redefined by subclasses for better performance.

o  magnifyBy: scale

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

pixel copying
o  copyFrom: anImage x: srcX y: srcY toX: dstX y: dstY width: w height: h
replace a rectangular area by pixels from another image.
The sources colors must be present in the destinations
colorMap - otherwise, an error will be reported.
Any mask is copied from the source.

WARNING:
This implementation is a very slow fallback general algorithm
(the loop over the source pixels is very slow).
If this method is used heavily, you may want to redefine it in
concrete subclasses for the common case of of copying from an Image
with the same depth & palette.
If you do heavy image processing, specialized versions are even req'd
for other cases, rewriting the inner loops as inline C-code.

o  copyFrom: anImage x: srcX y: srcY toX: dstX y: dstY width: w height: h masked: maskedCopy
replace a rectangular area by pixels from another image.
The sources colors must be present in the destinations
colorMap - otherwise, an error will be reported.

WARNING:
This implementation is a very slow fallback general algorithm
(the loop over the source pixels is very slow).
If this method is used heavily, you may want to redefine it in
concrete subclasses for the common case of of copying from an Image
with the same depth & palette.
If you do heavy image processing, specialized versions are even req'd
for other cases, rewriting the inner loops as inline C-code.

o  copyMaskedFrom: anImage x: srcX y: srcY toX: dstX y: dstY width: w height: h
replace a rectangular area by pixels from another image.
The sources colors must be present in the destinations
colorMap - otherwise, an error will be reported.
Only unmasked pixels are copied from the source.

WARNING:
This implementation is a very slow fallback general algorithm
(the loop over the source pixels is very slow).
If this method is used heavily, you may want to redefine it in
concrete subclasses for the common case of of copying from an Image
with the same depth & palette.
If you do heavy image processing, specialized versions are even req'd
for other cases, rewriting the inner loops as inline C-code.

o  subImageIn: aRectangle
create and return a new image consisting of a subArea of myself

printing & storing
o  storeOn: aStream
append a printed representation of the receiver to aStream,
from which a copy of it can be reconstructed.

private
o  bestSupportedImageFormatFor: aDevice
scan through the image formats as supported by aDevice,
and return the best to use when the receiver is to be represented
on it. The best format is the one with the same number or more bits per
pixel. Here, the smallest format found which can represent enough pixels is taken.

o  colormapFromImage: anImage
setup the receivers colormap from another image.
Color precision may be lost, if conversion is from a higher depth
image. This does not convert any pixel values; it is non-public helper
for fromImage:/fromSubImake:

o  colormapFromImage: anImage photometric: photometricOrNil
setup the receivers colormap from another image.
Color precision may be lost, if conversion is from a higher depth
image. This does not convert any pixel values; it is non-public helper
for fromImage:/fromSubImake:

o  greyByteMapForRange: range
return a collection to map from pixelValues to greyLevels
in the range 0..range.
Range must be < 256 (for elements to fit into a ByteArray).
The values are rounded towards the nearest pixel.

o  greyMapForRange: range
return a collection to map from pixelValues to greyLevels
in the range 0..range. The brightness values are not rounded.

o  magnifyRowFrom: srcBytes offset: srcStart into: dstBytes offset: dstStart factor: mX
magnify a single pixel row - can only magnify by integer factors,
can only magnify 1,2,4,8 and 24 bit-per-pixel images. But this is done fast.

** This method raises an error - it must be redefined in concrete classes **

o  makeDeviceGrayPixmapOn: aDevice depth: depth fromArray: bits
given the bits of a grey/color bitmap, 8-bit padded and
pixels interpreted as greyValues, 0 is black,
create a device form for it

o  makeDeviceMonochromeBitmapOn: aDevice fromArray: monoBits
given the bits of a monochrome bitmap, 8-bit padded and
0-bits as black, create a device form for it

o  makeDevicePixmapOn: aDevice depth: depth fromArray: bits
given the bits of a grey/color bitmap, 8-bit padded and
pixels interpreted as in the devices colormap,
create a device form for it

o  repairPhotometric
kludge: repair a 'should not happen' situation...

queries
o  alphaBitsOf: pixel
if the receiver is an rgb-image:
return the alpha component of a pixelValue as integer 0..maxAlphaValue.
MaxAlphaValue is of course the largest integer representable by the number
of alpha bits i.e. (1 bitShift:bitsAlpha)-1.
This has to be redefined by subclasses.

** This method raises an error - it must be redefined in concrete classes **

o  alphaMaskForPixelValue
return the mask used with translation from pixelValues to alphaBits

** This method raises an error - it must be redefined in concrete classes **

o  alphaShiftForPixelValue
return the shift amount used with translation from pixelValues to alphaBits

** This method raises an error - it must be redefined in concrete classes **

o  ascentOn: aGC
I will not draw myself above the baseline

o  averageColor
return the average color of the image.
This usually only makes sense for textures and patterns
(i.e. to compute shadow & light colors for viewBackgrounds).
Notice, that for the above purpose, it is usually ok to process
a subImage - i.e. use Image>>averageColorIn: on a smaller rectangle

o  averageColorIn: aRectangle
return the images average color in an area.
The implementation below is slow - so you may want to
create tuned versions for DepthXImage if you plan to do
heavy image processing ...
(also, creating tuned versions of the enumeration messages helps a lot)

o  bitsPerPixel
return the number of bits per pixel

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

o  blackComponentOfCMYK: pixel
if the receiver is a cmyk-image:
return the black component scaled to a percentage (0 .. 100) of a pixelValue.

** This method raises an error - it must be redefined in concrete classes **

o  blueBitsOf: pixel
if the receiver is an rgb-image:
return the blue bits of a pixelValue as integer 0..maxBlueValue.
MaxGreenValue is of course the largest integer representable by the number
of blue bits i.e. (1 bitShift:bitsBlue)-1.
This has to be redefined by subclasses.

** This method raises an error - it must be redefined in concrete classes **

o  blueComponentOf: pixel
if the receiver is an rgb-image:
return the blue component scaled to a percentage (0 .. 100) of a pixelValue.
This has to be redefined by subclasses.

** This method raises an error - it must be redefined in concrete classes **

o  blueMaskForPixelValue
return the mask used with translation from pixelValues to blueBits

** This method raises an error - it must be redefined in concrete classes **

o  blueShiftForPixelValue
return the shift amount used with translation from pixelValues to blueBits

** This method raises an error - it must be redefined in concrete classes **

o  bounds
return my bounds (added to make images usable as VisualComponents)

o  brightness
return the (average) brightness of the image.
This usually only makes sense for textures and patterns
(i.e. to compute shadow & light colors for viewBackgrounds).
Notice, that for the above purpose, only a subimage is inspected here

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

o  bytesPerRowPaddedTo: padding
return the number of bytes in one scanline of the image,
if scanlines are to be padded to padding-bits.

o  center
for compatibility with GC protocol - return the centerPoint

o  colorFromValue: pixelValue
given a pixel value, return the corresponding color.
Pixel values start with 0.
The implementation below is generic and slow
- this method is typically redefined in subclasses.

o  cyanComponentOfCMY: pixel
if the receiver is a cmy-image:
return the cyan component scaled to a percentage (0 .. 100) of a pixelValue.

** This method raises an error - it must be redefined in concrete classes **

o  cyanComponentOfCMYK: pixel
if the receiver is a cmyk-image:
return the cyan component scaled to a percentage (0 .. 100) of a pixelValue.

** This method raises an error - it must be redefined in concrete classes **

o  greenBitsOf: pixel
if the receiver is an rgb-image:
return the green bits of a pixelValue as integer 0..maxGreenValue.
MaxGreenValue is of course the largest integer representable by the number
of green bits i.e. (1 bitShift:bitsGreen)-1.
This has to be redefined by subclasses.

** This method raises an error - it must be redefined in concrete classes **

o  greenComponentOf: pixel
if the receiver is an rgb-image:
return the green component scaled to a percentage (0..100) of a pixelValue.
This has to be redefined by subclasses.

** This method raises an error - it must be redefined in concrete classes **

o  greenMaskForPixelValue
return the mask used with translation from pixelValues to greenBits

** This method raises an error - it must be redefined in concrete classes **

o  greenShiftForPixelValue
return the shift amount used with translation from pixelValues to greenBits

** This method raises an error - it must be redefined in concrete classes **

o  heightOn: aGC
return my height, if displayed on aGC;
since my height is independent of the device (the number of pixels),
return the pixel-height

o  isDithered
for compatibility with color protocol

o  isGrayscaleImage

o  isImage
return true, if the receiver is some kind of image;
true is returned here - the method is redefined from Object.

o  isImageOrForm
return true, if the receiver is some kind of image or form;
true is returned here - the method is redefined from Object.

o  isMask

o  magentaComponentOfCMY: pixel
if the receiver is a cmy-image:
return the magenta component scaled to a percentage (0 .. 100) of a pixelValue.

** This method raises an error - it must be redefined in concrete classes **

o  magentaComponentOfCMYK: pixel
if the receiver is a cmyk-image:
return the magenta component scaled to a percentage (0 .. 100) of a pixelValue.

** This method raises an error - it must be redefined in concrete classes **

o  pixelArraySpecies
return the kind of pixel-value container in rowAt:/rowAt:put: methods

o  realColorMap
return a collection usable as a real colormap of the image.
For palette images, this is the internal colormap;
for other photometrics (which do not have a real colormap), synthesize one.
This is different from #colorMap, which returns nil for non palette images.

o  realUsedColors
return a collection of colors which are really used in the receiver.
This goes through the pixels and adds up colors as present in the image
(as opposed to #usedColors, which looks at the colorMap if present)

o  realUsedValues
return a collection of color values used in the receiver.
Notice, that the interpretation of the pixels depends on the photometric
of the image.
This is a general and therefore slow implementation; subclasses
may want to redefine this method for more performance.
This goes through the pixels and adds up colors as present in the image
(as opposed to #usedColors, which looks at the colorMap if present)

o  redBitsOf: pixel
if the receiver is an rgb-image:
return the red component of a pixelValue as integer 0..maxRedValue.
MaxRedValue is the largest integer representable by the number
of red bits i.e. (1 bitShift:bitsRed)-1.
This has to be redefined by subclasses.

** This method raises an error - it must be redefined in concrete classes **

o  redComponentOf: pixel
if the receiver is an rgb-image:
return the red component scaled to a percentage (0..100) of a pixelValue.
This has to be redefined by subclasses.

** This method raises an error - it must be redefined in concrete classes **

o  redMaskForPixelValue
return the mask used with translation from pixelValues to redBits

** This method raises an error - it must be redefined in concrete classes **

o  redShiftForPixelValue
return the shift amount used with translation from pixelValues to redBits

** This method raises an error - it must be redefined in concrete classes **

o  rgbFromValue: pixelValue
given a pixel value, return the corresponding 24bit rgbValue (rrggbb, red is MSB).
Pixel value is in 0..2^depth - 1.
The implementation below is generic and slow
- this method is typically redefined in subclasses.

o  usedColors
return a collection of colors used in the receiver.
This looks at the colorMap only if present.
(as opposed to #realUsedColors, which goes through the pixels if the bitmap)

o  usedColorsMax: nMax
return a collection of colors used in the receiver;
This looks at the colorMap only if present
(as opposed to #realUsedColors, which goes through the pixels if the bitmap).
However, stop looking for more, if more than nMax colors have been found
(useful when searching rgb images).

o  usedValues
return a collection of color values used in the receiver.
Notice, that the interpretation of the pixels depends on the photometric
of the image.
This is a general and therefore slow implementation; subclasses
may want to redefine this method for more performance.

o  valueFromColor: color
given a color, return the corresponding pixel value.
Non-representable colors return nil.

o  valueFromRGB: rgb
given a color, return the corresponding pixel value.
Non-representable colors return nil.

o  valueFromRedBits: redBits greenBits: greenBits blueBits: blueBits
given a rgb bits, each in 0..maxXXXValue (i.e. according to
r/g/b channels number of bits, return the corresponding pixel value.
For now, only useful with RGB images

o  widthOn: aGC
return my width, if displayed on aGC;
since my width is independent of the device (the number of pixels),
return the pixel-width

o  yellowComponentOfCMY: pixel
if the receiver is a cmy-image:
return the yellow component scaled to a percentage (0 .. 100) of a pixelValue.

** This method raises an error - it must be redefined in concrete classes **

o  yellowComponentOfCMYK: pixel
if the receiver is a cmyk-image:
return the yellow component scaled to a percentage (0 .. 100) of a pixelValue.

** This method raises an error - it must be redefined in concrete classes **

saving on file
o  saveOn: aFileName
save the image in aFileName. The suffix of the filename controls the format.
Currently, not all formats may be supported
(see ImageReader subclasses implementing save:onFile:).
May raise a signal, if the image cannot be written by the reader.

o  saveOn: aFileName using: readerClass
save the receiver using the representation class
(which is usually a concrete subclasses of ImageReader).
May raise a signal, if the image cannot be written by the reader.

screen capture
o  from: aDrawable in: aRectangle
read an image from aDrawable.
This may be a device Form, a view or the rootView.
If its a view or rootView, it must be completely visible (or have
the backingStore option turned on). Otherwise, only the clipped contents
is returned. This is a common helper for form-to-image conversion,
and to read hardcopy images from the screen.

o  fromScreen: aRectangle
read an image from the display screen.
WARNING: this temporarily grabs the display
it may not work from within a buttonMotion
(use #fromScreen:on:grab: with a false grabArg then).

o  fromScreen: aRectangle on: aDevice
read an image from aDevices display screen.
Since I have no other displays, only the MonoChrome, StaticGrey
and PseudoColor cases have been tested ...
(especially True- and DirectColor may be wrong).
Late note: 24bit rgb now also works.
WARNING: this temporarily grabs the display
it may not work from within a buttonMotion
(use #fromScreen:on:grab: with a false grabArg then).

o  fromScreen: aRectangle on: aDevice grab: doGrab
read an image from aDevices display screen.
If the doGrab argument is true, the display
is grabbed (i.e. blocked for others) and a camera cursor is
shown while the readout is done.
Since I have no other displays, only the MonoChrome, StaticGrey
and PseudoColor cases have been tested ...
(especially True- and DirectColor may be wrong).
Late note: 24bit rgb now also works.
WARNING: with doGrab true, this temporarily grabs the display
and it may not work from within a buttonMotion
(use with a false grabArg then).

o  photometricFromScreen: aDevice
read aDevices display photometric and set my colormap for it.
This must be used after an images bits have been read from the screen
or from an offScreen bitmap, for correct pixel interpretation.

virtual anti-aliased
o  vitualAntiAliasedAlongXvertical: bottomOrTop horizontal: leftOrRight form: tempForm color: aColor xRun: xRun yRun: yRun colorDictionary: colorDictionary blendStart: blendStart

o  vitualAntiAliasedAlongYhorizontal: leftOrRight vertical: bottomOrTop form: tempForm color: aColor xRun: xRun yRun: yRun colorDictionary: colorDictionary blendStart: blendStart


Examples:


reading from a file (many formats are supported): (notice, that the bitmaps directory is searched for along the system path - therefore, you may add your own bitmap directory to the beginning of the path and thus override any default bitmaps, or make certain that your application finds its bitmaps - even if they are in a separate directory)


    (Image fromFile:'goodies/bitmaps/gifImages/claus.gif') inspect


    (Image fromFile:'libtool/bitmaps/SmalltalkX.xbm') inspect


    (Image fromFile:'goodies/bitmaps/winBitmaps/okSmily_up.bmp') inspect
The following examples demonstrate various depth and colorMap variations ... inline image: default: depth=1 & #blackIs0


    (Image width:8 height:8
           fromArray:#( 2r11111111
                        2r10000001
                        2r10000001
                        2r10000001
                        2r10000001
                        2r10000001
                        2r10000001
                        2r11111111 )) inspect
with #whiteIs0 photometric


    ((Image width:8 height:8
           fromArray:#( 2r11111111
                        2r10000001
                        2r10000001
                        2r10000001
                        2r10000001
                        2r10000001
                        2r10000001
                        2r11111111 ))
        photometric:#whiteIs0)
             inspect
with a colorMap


    ((Image width:8 height:8
           fromArray:#( 2r11111111
                        2r10000001
                        2r10000001
                        2r10000001
                        2r10000001
                        2r10000001
                        2r10000001
                        2r11111111 ))
        colorMap:(Array with:(Color red)
                        with:(Color yellow)))
             inspect
a depth4 greyScale image: (default photometric is #blackIs0)


    (Depth4Image
         width:8
         height:4
         fromArray:#[
                        16r00 16r11 16r22 16r33
                        16r44 16r55 16r66 16r77
                        16r88 16r99 16raa 16rbb
                        16rcc 16rdd 16ree 16rff
                    ]) inspect
the same, magnified:


    ((Depth4Image
         width:4
         height:4
         fromArray:#[
                        16r01 16r23
                        16r45 16r67
                        16r89 16rab
                        16rcd 16ref
                    ])
        magnifiedBy:30)
             inspect
the following has the same effect:


    ((Image
         width:4
         height:4
         depth:4
         fromArray:#[
                        16r01 16r23
                        16r45 16r67
                        16r89 16rab
                        16rcd 16ref
                    ])
        magnifiedBy:30)
             inspect
with reverse grey-interpretation:


    ((Depth4Image
         width:4
         height:4
         fromArray:#[
                        16r01 16r23
                        16r45 16r67
                        16r89 16rab
                        16rcd 16ref
                    ])
        photometric:#whiteIs0;
        magnifiedBy:30)
             inspect
with 1-bit-per-pixel rgb interpretation:


    ((Depth4Image
         width:4
         height:4
         fromArray:#[
                        16r01 16r23
                        16r45 16r67
                        16r89 16rab
                        16rcd 16ref
                    ])
        photometric:#rgb;
        samplesPerPixel:3;
        bitsPerSample:#(1 1 1);
        magnifiedBy:30)
             inspect
with 1/2/1 rgb interpretation:


    ((Depth4Image
         width:4
         height:4
         fromArray:#[
                        16r01 16r23
                        16r45 16r67
                        16r89 16rab
                        16rcd 16ref
                    ])
        photometric:#rgb;
        samplesPerPixel:3;
        bitsPerSample:#(1 2 1);
        magnifiedBy:30)
             inspect
a 2/2/0 rgb image (i.e. no blue):


     |i|

     i := Depth4Image
                width:4
                height:4
                fromArray:#[ 16r01 16r23
                             16r45 16r67
                             16r89 16rab
                             16rcd 16ref ].
     i photometric:#rgb.
     i samplesPerPixel:3.
     i bitsPerSample:#(2 2 0).

     i := i magnifiedBy:30.
     i inspect.
a 0/0/4 rgb image (i.e. no red or green):


     |i|

     i := Depth4Image
                width:4
                height:4
                fromArray:#[ 16r01 16r23
                             16r45 16r67
                             16r89 16rab
                             16rcd 16ref ].
     i photometric:#rgb.
     i samplesPerPixel:3.
     i bitsPerSample:#(0 0 4).

     i := i magnifiedBy:30.
     i inspect.
a 2plane greyscale image:


    ((Depth2Image
         width:4
         height:4
         fromArray:#[
                        4r0123
                        4r1230
                        4r2301
                        4r3012
                    ])
        magnifiedBy:30)
             inspect
with colors:


    ((Depth2Image
         width:4
         height:4
         fromArray:#[
                        4r0123
                        4r1230
                        4r2301
                        4r3012
                    ])
        colorMap:(Array with:(Color black)
                        with:(Color red)
                        with:(Color green)
                        with:(Color blue));
        magnifiedBy:30)
             inspect
depth8 image with 3/3/2 rgb interpretation:


    ((Depth8Image
         width:16
         height:16
         fromArray:(ByteArray withAll:(0 to:16rFF)))
        photometric:#rgb;
        samplesPerPixel:3;
        bitsPerSample:#(3 3 2);
        magnifiedBy:10)
             inspect
depth8 image with 2/2/2 rgb interpretation:


    ((Depth8Image
         width:8
         height:8
         fromArray:(ByteArray withAll:(0 to:16r3F)))
        photometric:#rgb;
        samplesPerPixel:3;
        bitsPerSample:#(2 2 2);
        magnifiedBy:10)
             inspect


    ((Depth8Image
         width:4
         height:4
         fromArray:#[
                16r30 16r0C  16r03 16r3F 
                16r20 16r08  16r02 16r2A  
                16r10 16r04  16r01 16r15  
                16r00 16r00  16r00 16r00  
                    ])
        photometric:#rgb;
        samplesPerPixel:3;
        bitsPerSample:#(2 2 2);
        magnifiedBy:30)
             inspect
trueColor image: remember: bytes are MSB


    ((Depth16Image
         width:4
         height:5
         fromArray:#[
                2r01111100 2r00000000  2r00000011 2r11100000  2r00000000 2r00011111  2r01111111 2r11111111
                2r00111100 2r00000000  2r00000001 2r11100000  2r00000000 2r00001111  2r00111101 2r11101111
                2r00011100 2r00000000  2r00000000 2r11100000  2r00000000 2r00000111  2r00011100 2r11100111
                2r00001100 2r00000000  2r00000000 2r01100000  2r00000000 2r00000001  2r00001100 2r01100011
                2r00000100 2r00000000  2r00000000 2r00100000  2r00000000 2r00000001  2r00000100 2r00100001
                    ])
        photometric:#rgb;
        samplesPerPixel:3;
        bitsPerSample:#(5 5 5);
        magnifiedBy:30)
             inspect


    ((Depth24Image
         width:4
         height:4
         fromArray:#[
                16rFF 16r00 16r00  16rFF 16r00 16r00  16rFF 16r00 16r00  16rFF 16r00 16r00
                16r00 16rFF 16r00  16r00 16rFF 16r00  16r00 16rFF 16r00  16r00 16rFF 16r00
                16r00 16r00 16rFF  16r00 16r00 16rFF  16r00 16r00 16rFF  16r00 16r00 16rFF
                16rFF 16rFF 16rFF  16rFF 16rFF 16rFF  16rFF 16rFF 16rFF  16rFF 16rFF 16rFF
                    ])
        photometric:#rgb;
        samplesPerPixel:3;
        bitsPerSample:#(8 8 8);
        magnifiedBy:30)
             inspect
32bit trueColor image:


    ((Depth32Image
         width:4
         height:4
         fromArray:#[
                16rFF 16r00 16r00 16r00  16rFF 16r00 16r00 16r00  16rFF 16r00 16r00 16r00  16rFF 16r00 16r00 16r00
                16r00 16rFF 16r00 16r00  16r00 16rFF 16r00 16r00  16r00 16rFF 16r00 16r00  16r00 16rFF 16r00 16r00
                16r00 16r00 16rFF 16r00  16r00 16r00 16rFF 16r00  16r00 16r00 16rFF 16r00  16r00 16r00 16rFF 16r00
                16rFF 16rFF 16rFF 16r00  16rFF 16rFF 16rFF 16r00  16rFF 16rFF 16rFF 16r00  16rFF 16rFF 16rFF 16r00
                    ])
        photometric:#rgb;
        samplesPerPixel:4;
        bitsPerSample:#(8 8 8 8);
        magnifiedBy:30)
             inspect
storing - only a few formats (TIFF, XBM, XPM) currently support storing:


    |img|

    img := Image fromFile:'goodies/bitmaps/winBitmaps/okSmily_up.bmp'.
    img saveOn:'myImage.tiff'.
    (Image fromFile:'myImage.tiff') inspect
magnifying (any factor):


    ((Image fromFile:'goodies/bitmaps/gifImages/claus.gif')
        magnifiedTo:(48@48))
            inspect


    ((Image fromFile:'goodies/bitmaps/gifImages/claus.gif')
        magnifiedBy:0.7)
            inspect
rotating:


    ((Image fromFile:'goodies/bitmaps/gifImages/claus.gif')
        rotated:90)
            inspect


    (((Image fromFile:'goodies/bitmaps/gifImages/claus.gif')
        magnifiedBy:0.3@0.7) rotated:270)
            inspect


    (((Image fromFile:'goodies/bitmaps/gifImages/claus.gif')
        ) rotated:30)
            inspect
negative:


    ((Image fromFile:'goodies/bitmaps/gifImages/claus.gif')
        negative)
            inspect


ST/X 6.1.1; WebServer 1.620 at exept:8081; Mon, 21 May 2012 18:04:03 GMT