THE SCOOP ON
Java Image I/O SampleModels
Introduction
A Raster, jawa.awt.image.Raster, is a rectangle of pixels.
That rectangle is represented by a big buffer of data
together with instructions for its interpretation.
Each dot in the raster is encoded as a list of samples; for example,
a pixel using RGB encoding will use three sample values (one for
each of red, green, blue "intensity") to represent its colors.
A SampleModel, java.awt.image.SampleModel, describes how to map
values in a big array (the DataBuffer) to groups of samples
composing a pixel.
Pixels vs. Samples
Pixels consist of one or more numerical values ("samples") that
mean the same. For example, pixels expressed in the RGB color model
contain three samples: Red, Green, and Blue. Some image formats
have four samples per pixel: R, G, B, and Alpha (opaqueness).
A grayscale image usually has one sample per pixel.
Bands
A group of samples that mean the same ("red") is called
a "band".
DataBuffer
The actual area that a raster image is stored in is called a
"DataBuffer". A data buffer is a big array of some underlying
data type, together with a bit of management code that lets one
consider the buffer separated into coherent areas, "banks".
ComponentSampleModel
The ComponentSampleModel, java.awt.image.ComponentSampleModel,
holds one sample per array element in the data buffer.
The different samples for a pixel may be adjacent:
R1 G1 B1 R2 G2 B2 ... Rn Gn Bn
or in separated "banks" (adjacent areas) of the DataBuffer:
R1 R2 ... Rn
G1 G2 ... Gn
B1 B1 ... Bn
By manipulating the parameters below, very different forms of
interleaving can be managed by the same class.
Pixel Stride
The "pixel stride" is the distance in elements between two samples
for the same band on the same scanline, i.e. from R1 to R2. In the
top example, it is 3; in the lower example, 1.
Scanline Stride
The distance in elements between two samples of vertically adjacent
pixels, i.e. from R1/1 to R2/1. In a RGB .. RGB raster, that would be
the number of elements per pixel, times the image width plus padding.
Band offsets
Number of elements from the start of a bank in the databuffer to the
first sample of the band. For example, in a RGB raster that's stored
like this:
R1 G1 B1 R2 G2 B2 ... Rn Gn Bn
the band offset for the Red band would be 0, for Green 1,
for Blue 2.
Band indices
Map the bands (Image Channels, e.g., R=0, G=1, B=2) to banks
(adjacent subsections of the DataBuffer).
PixelInterleavedSampleModel
A subclass of ComponentSampleModel.
The pixel components are stored as "pixel interleaved",
meaning that samples of a pixel are adjactent -- something like
R1 G1 B1 R2 G2 B2 ... Rn Gn Bn.
There is only one bank.
MultiPixelPackedSampleModel
There is only one band (as, for example, in a grayscale or
colortable-based image), and multiple pixels can be packed
into one data value.
|
Pixel view: | <4-bit-pixel> <4-bit-pixel> |
| DataBuffer view: | <--- 8-bit field value --->
|
Pixels must be powers of two, must fit exactly in the
DataBuffer elements, and can't cross DataBuffer element
boundaries. DataBuffer elements can have 8, 16, 32 bits.
Note that here, too, the scanline stride is measured
in underlying databuffer elements, not in pixels or samples.
The dataBitOffset is in number of bits from the beginning
of the Data Buffer; that has to be a multiple of the bits
per sample.
SinglePixelPackedSampleModel
Each DataBuffer element holds all samples for one pixel
(as, for example, in truecolor 32-bit RGB+alpha bitmaps).
The samples are packed together; different bits of the
pixel value are interpreted as different bands.
The scanline stride is the (width + padding) measured
in DataBuffer elements, plus any padding.
There is only one bank, the first. (That is, the image
is contiguous, although it can contain padding.)
To describe the bands within a pixel value, each band
has two parameters: a mask and an offset.
(pixel & mask) >> offset
yields the value of the corresponding band.
|