home   the scoop on ...   Java Image I/O SampleModels

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.

home   the scoop on ...   Java Image I/O SampleModels <jutta@pobox.com>