Contents Previous Next

Programming in Java Advanced Imaging


C H A P T E R13

Writing Image Files




THIS chapter describes JAI's codec system for writing image data files.

13.1 Introduction

The JAI codec system supports a variety of image formats for writing an image to a file or to an OutputStream for further manipulation. For writing an image to a file, the FileStore operation (see Section 13.2, "Writing to a File") writes an image to a specified file in the specified format. For encoding an image to an OutputStream, the Encode operation (see Section 13.3, "Writing to an Output Stream") writes an image to a given OutputStream in a specified format using the encoding parameters supplied via the ImageEncodeParam operation parameter.

13.2 Writing to a File

The FileStore operation writes an image to a given file in a specified format using the specified encoding parameters. This operation is much simpler than the encoders described in the remainder of this chapter.

The FileStore operation takes three parameters:

Parameter Type Description
filename
String
The path of the file to write to.
format
String
The format of the file.
param
ImageEncodeParam
The encoding parameters.

The filename parameter must be supplied or the operation will not be performed. Also, the specified file path must be writable.

The format parameter defaults to tiff if no value is provided. Table 13-1 lists the recognized JAI file formats.

Table 13-1 JAI Writable File Formats
File Format Description
BMP
Microsoft Windows bitmap image file
JPEG
A file format developed by the Joint Photographic Experts Group
PNG
Portable Network Graphics
PNM
Portable aNy Map file format. Includes PBM, PGM, and PPM
TIFF
Tag Image File Format

The param parameter must either be null or an instance of an ImageEncodeParam subclass appropriate to the format.

Listing 13-1 shows a code sample demonstrating the use of both the Encode and FileStore operations.

13.3 Writing to an Output Stream

The Encode operation writes an image to a given OutputStream in a specified format using the encoding parameters supplied via the ImageEncodeParam operation parameter. The Encode operation takes three parameters:

Parameter Type Description
stream
OutputStream
The OutputStream to write to.
format
String
The format of the created file.
param
ImageEncodeParam
The encoding parameters.

The param parameter must either be null or an instance of an ImageEncodeParam subclass appropriate to the specified image format. The image encode parameter depends on the type of image file to be encoded. This parameter contains all of the information about the file type that the encoder needs to create the file. For example, the BMP format requires two parameter values, as described in the BMPEncodeParam class:

These parameters are described in detail in Section 13.4, "Writing BMP Image Files."

Listing 13-1 shows a code sample demonstrating the use of both the Encode and FileStore operations.

Listing 13-1 Writing an OutputStream and a File


     // Define the source and destination file names.
     String inputFile = /images/FarmHouse.tif
     String outputFile = /images/FarmHouse.bmp
     // Load the input image.
     RenderedOp src = JAI.create("fileload", inputFile);
     // Encode the file as a BMP image.
     FileOutputStream stream =
         new FileOutputStream(outputFile);
     JAI.create("encode", src, stream, BMP, null);
     // Store the image in the BMP format.
     JAI.create("filestore", src, outputFile, BMP, null);

13.4 Writing BMP Image Files

As described above, the encoding of BMP images requires the specification of two parameters: version and data layout. By default, these values are:

The JAI BMP encoder does not support compression of BMP image files.

13.4.1 BMP Version

JAI currently reads and writes Version2, Version3, and some of the Version 4 images. The BMP version number is read and specified with getVersion and setVersion methods in the BMPEncodeParam class. The BMP version parameters are as follows:

Parameter Description
VERSION_2
Specifies BMP Version 2
VERSION_3
Specifies BMP Version 3
VERSION_4
Specifies BMP Version 4

If not specifically set, VERSION_3 is the default version.


API: com.sun.media.jai.codec.BMPEncodeParam

sets the BMP version to be used.

returns the BMP version to be used.

13.4.2 BMP Data Layout

The scan lines in the BMP bitmap are stored from the bottom up. This means that the first byte in the array represents the pixels in the lower-left corner of the bitmap, and the last byte represents the pixels in the upper-right corner.

The in-memory layout of the image data to be encoded is specified with getDataLayout and setDataLayout methods in the BMPEncodeParam class.


API: com.sun.media.jai.codec.BMPEncodeParam

sets the data layout to be top down.

13.4.3 Example Code

Listing 13-2 shows a code sample for encoding a BMP image.

Listing 13-2 Encoding a BMP Image


     OutputStream os = new FileOutputStream(fileToWriteTo);
     BMPEncodeParam param = new BMPEncodeParam();
     ImageEncoder enc = ImageCodec.createImageEncoder("BMP", os,
                                                      param);
     enc.encode(op);
     os.close();

13.5 Writing JPEG Image Files

The JPEG standard was developed by a working group, known as the Joint Photographic Experts Group (JPEG). The JPEG image data compression standard handles grayscale and color images of varying resolution and size.

JPEG compression identifies and discards "extra" data that is beyond what the human eye can see. Since it discards data, the JPEG compression algorithm is considered "lossy." This means that once an image has been compressed and then decompressed, it will not be identical to the original image. In most cases, the difference between the original and compressed version of the image is indistinguishable.

An advantage of JPEG compression is the ability to select the quality when compressing the image. The lower the quality, the smaller the image file size, but the more different it will appear than the original.

Table 13-2 lists the JPEG encode parameters that may be set and the default values. The remaining sections describe these settings and how to change them.

Table 13-2 JPEG Encode Parameters
Parameter Description Default Value
writeJFIFHeader
Controls whether the encoder writes a JFIF header using the APP0 marker. See Section 13.5.1, "JFIF Header."
True
qTabSlot[0],[1],[2]
Quantization tables. See Section 13.5.3, "Quantization Table."
0 for Y channel, 1 for Cb and Cr channels
qTab[0],[1],[2]
Quantization table contents. See Section 13.5.3, "Quantization Table."
Null for all three channels
qTabSet[0],[1],[2]
Quantization table usage. See Section 13.5.3, "Quantization Table."
False for all three channels
hSamp[0],[1],[2]
Horizontal subsampling. See Section 13.5.4, "Horizontal and Vertical Subsampling."
1 for Y channel, 2 for Cb and Cr channels
vSamp[0],[1],[2]
Vertical subsampling. See Section 13.5.4, "Horizontal and Vertical Subsampling."
1 for Y channel, 2 for Cb and Cr channels
qual
Quality setting. See Section 13.5.5, "Compression Quality."
0.75F
rstInterval
Restart interval. Section 13.5.6, "Restart Interval."
0
writeImageOnly
Controls whether encoder writes only the compressed image data. See Section 13.5.7, "Writing an Abbreviated JPEG Stream."
False

13.5.1 JFIF Header

The JPEG File Interchange Format (JFIF) is a minimal file format that enables JPEG bitstreams to be exchanged between a wide variety of platforms and applications. This minimal format does not include any of the advanced features found in the TIFF JPEG specification or any application-specific file format. The sole purpose of this simplified format is to allow the exchange of JPEG compressed images.

The JFIF features are:

An APP0 marker is used to identify a JFIF file. The marker provides information that is missing from the JPEG stream, such as version number, x and y pixel density (dots per inch or dots per cm.), pixel aspect ratio (derived from x and y pixel density), and thumbnail. The setWriteJFIFHeader method controls whether the encoder writes a JFIF header using the APP0 marker.


API: com.sun.media.jai.codec.JPEGEncodeParam

controls whether the encoder writes a JFIF header using the APP0 marker. By default an APP0 marker is written to create a JFIF file.

Parameter:

writeJFIF

If true, writes a JFIF header.

13.5.2 JPEG DCT Compression Parameters

JAI uses the JPEG baseline DCT coding process, shown in Figure 13-1.



Figure 13-1 JPEG Baseline DCT Coding

For encoding, the image array is divided into 8 x 8 pixel blocks and a discrete cosine transform (DCT) is taken of each block, resulting in an 8 x 8array of transform coefficients. The DCT is a mathematical operation that takes the block of image samples as its input and converts the information from the spatial domain to the frequency domain. The 8 x 8 matrix input to the DCT represents brightness levels at specific x, y coordinates. The resulting 8 x 8 matrix values represent relative amounts of 64 spatial frequencies that make up the spectrum of the input data.

The next stage in the encoder quantizes the transform coefficients by dividing each DCT coefficient by a value from a quantization table. The quantization operation discards the smaller-valued frequency components, leaving only the larger-valued components.

After an image block has been quantized, it enters the entropy encoder, which creates the actual JPEG bitstream. The entropy encoder assigns a binary Huffman code to coefficient values. The length of each code is chosen to be inversely proportional to the expected probability of occurrence of a coefficient amplitude - frequently-occurring coefficient values get short code words, seldom-occurring coefficient values get long code words. The entropy encoder uses two tables, one for the AC frequency components and one for the DC frequency components.

The JPEG decoding process is essentially the inverse of the encoding process. The compressed image array data stream passes through the entropy encoder, which recreates the quantized coefficient values. Then, the quantized coefficients are reconstructed by multiplication with the quantizer table values. Finally, an inverse DCT is performed and the reconstructed image array is produced.

The following are the parameters that may be specified for JPEG DCT compression.

13.5.3 Quantization Table

The setQTable and getQTable methods are used to specify and retrieve the quantization table that will be used in encoding a particular band of the image. There are, by default, two quantizer tables:

Table Band
0
Band 0
1
All other bands

The parameter tableNum is usually a value between 0 and 3. This value indicates which of four quantization tables you are specifying. Table 0 is designed to be used with the luminance band of eight-bit YCC images. Table 1 is designed to be used with the chrominance bands of eight-bit YCC images. The two tables can also be set individually using the setLumaQTable (table 0) and setChromaQTable (table 1) methods. Tables 2 and 3 are not normally used.


API: com.sun.media.jai.codec.JPEGEncodeParam

sets a quantization table to be used for a component. This method allows up to four independent tables to be specified. This disables any quality setting.

Parameters:

component

The band to which this table applies.

tableNum

The table number that this table is assigned to (0 to 3).

qTable

Quantization table values in "zig-zag" order.

returns the contents of the quantization table used for a component. If this method is called before the quantization table is set, an error is thrown.

sets the quantization table to be used for luminance data. This is a convenience method that explicitly sets the contents of quantization table 0. The length of the table must be 64. This disables any quality setting.

sets the quantization table to be used for luminance data. This is a convenience method that explicitly sets the contents of quantization table 0. The length of the table must be 64. This method assumes that all chroma components will use the same table. This disables any quality setting.

returns the quantization table slot used for a component. If this method is called before the quantization table data is set, an error is thrown.

13.5.4 Horizontal and Vertical Subsampling

JPEG allows the image components to be subsampled to reduce their resolution prior to encoding. This is typically done with YCC images, where the two chroma components can be subsampled, usually by a factor of two in both axes. This is possible due to the human visual system's low sensitivity to color images relative to luminance (Y) errors By default, the sampling factors for YCC input images are set to {1, 2, 2} for both horizontal and vertical axes.


API: com.sun.media.jai.codec.JPEGEncodeParam

sets the horizontal subsampling to be applied to an image band. Defaults to 1 for grayscale and (1,2,2) for RGB.

Parameter:

component

The band for which to set horizontal subsampling.

subsample

The horizontal subsampling factor.

sets the vertical subsampling to be applied to an image band. Defaults to 1 for grayscale and (1,2,2) for RGB.

returns the horizontal subsampling factor for a band.

returns the vertical subsampling factor for a band.

13.5.5 Compression Quality

Compression quality specifies a factor that relates to the desired tradeoff between image quality and the image data compression ratio. The quality value is a float between 0.0 and 1.0. A setting of 1.0 produces the highest quality image at a lower compression ratio. A setting of 0.0 produces the highest compression ratio, with a sacrifice to image quality. The quality value is typically set to 0.75.

The compression quality value controls image quality and compression ratio by determining a scale factor the encoder will use in creating scaled versions of the quantization tables. Some guidelines:

Quality Value Meaning
1.0
Highest quality, no compression
0.75
High quality, good compression ratio
0.5
Medium quality, medium compression ratio
0.25
Low quality, high compression ratio


Note: The values stored in the quantization table also affect image quality and compression ratio. See also Section 13.5.3, "Quantization Table."

API: com.sun.media.jai.codec.JPEGEncodeParam
sets the compression quality factor. Creates new quantization tables that replace the currently-installed quantization tables.

Parameter:

quality

The desired quality level; a value of 0.0 to 1.0. The default value is 0.75.

returns the quality setting for this encoding. This is a number between 0.0 and 1.0.

tests if the quality parameter has been set in this JPEGEncodeParam.

13.5.6 Restart Interval

JPEG images use restart markers to define multiple strips or tiles. The restart markers are inserted periodically into the image data to delineate image segments known as restart intervals. To limit the effect of bitstream errors to a single restart interval, JAI provides methods to set the restart interval in JPEG Minimum Coded Units (MCUs). The default is zero (no restart interval markers).


API: com.sun.media.jai.codec.JPEGEncodeParam

sets the restart interval in Minimum Coded Units (MCUs).

Parameter:

restartInterval

Number of MCUs between restart markers.

returns the restart interval.

13.5.7 Writing an Abbreviated JPEG Stream

Normally, both the JPEG table data and compressed (or uncompressed) image data is written to the output stream. However, it is possible to write just the table data or just the image data. The setWriteTablesOnly method instructs the encoder to write only the table data to the output stream. The setWriteImageOnly method instructs the encoder to write only the compressed image data to the output stream.


API: com.sun.media.jai.codec.JPEGEncodeParam

instructs the encoder to write only the table data to the output stream.

Parameter:

tablesOnly

If true, only the tables will be written.

instructs the encoder to write only the image data to the output stream.

Parameter:

imageOnly

If true, only the compressed image will be written.

13.5.8 Example Code

Listing 13-3 shows a code sample for encoding a JPEG image.

Listing 13-3 Encoding a JPEG Image (Sheet 1 of 5)


     import java.awt.*;
     import java.awt.event.*;
     import java.awt.image.*;
     import java.awt.image.renderable.*;
     import java.io.*;
     import javax.media.jai.*;
     import javax.media.jai.widget.*;
     import com.sun.media.jai.codec.*;
     public class JPEGWriterTest extends WindowContainer {
     private ImageEncoder encoder = null;
     private JPEGEncodeParam encodeParam = null;
     // Create some Quantization tables.
         private static int[] qtable1 = {
             1,1,1,1,1,1,1,1,
             1,1,1,1,1,1,1,1,
             1,1,1,1,1,1,1,1,
             1,1,1,1,1,1,1,1,
             1,1,1,1,1,1,1,1,
             1,1,1,1,1,1,1,1,
             1,1,1,1,1,1,1,1,
             1,1,1,1,1,1,1,1
         };
         private static int[] qtable2 = {
             2,2,2,2,2,2,2,2,
             2,2,2,2,2,2,2,2,
             2,2,2,2,2,2,2,2,
             2,2,2,2,2,2,2,2,
             2,2,2,2,2,2,2,2,
             2,2,2,2,2,2,2,2,
             2,2,2,2,2,2,2,2,
             2,2,2,2,2,2,2,2
         };
         private static int[] qtable3 = {
             3,3,3,3,3,3,3,3,
             3,3,3,3,3,3,3,3,
             3,3,3,3,3,3,3,3,
             3,3,3,3,3,3,3,3,
             3,3,3,3,3,3,3,3,
             3,3,3,3,3,3,3,3,
             3,3,3,3,3,3,3,3,
             3,3,3,3,3,3,3,3
         };
         // Really rotten quality Q Table
         private static int[] qtable4 = {
             200,200,200,200,200,200,200,200,
             200,200,200,200,200,200,200,200,
             200,200,200,200,200,200,200,200,
             200,200,200,200,200,200,200,200,
             200,200,200,200,200,200,200,200,
             200,200,200,200,200,200,200,200,
             200,200,200,200,200,200,200,200,
             200,200,200,200,200,200,200,200
         };
     public static void main(String args[]) {
         JPEGWriterTest jtest = new JPEGWriterTest(args);
         }
     // Load the source image.
     private PlanarImage loadImage(String imageName) {
     ParameterBlock pb = (new
             ParameterBlock()).add(imageName);
     PlanarImage src = JAI.create("fileload", pb);
             if (src == null) {
             System.out.println("Error in loading image " + imageName);
                 System.exit(1);
             }
             return src;
         }
     // Create the image encoder.
     private void encodeImage(PlanarImage img, FileOutputStream out)
         {
     encoder = ImageCodec.createImageEncoder("JPEG", out,
                                             encodeParam);
             try {
                 encoder.encode(img);
                 out.close();
             } catch (IOException e) {
                 System.out.println("IOException at encoding..");
                 System.exit(1);
             }
         }
     private FileOutputStream createOutputStream(String outFile) {
             FileOutputStream out = null;
             try {
                 out = new FileOutputStream(outFile);
             } catch(IOException e) {
                 System.out.println("IOException.");
                 System.exit(1);
             }
             return out;
         }
     public JPEGWriterTest(String args[]) {
     // Set parameters from command line arguments.
     String inFile = "images/Parrots.tif";
     FileOutputStream out1 = createOutputStream("out1.jpg");
     FileOutputStream out2 = createOutputStream("out2.jpg");
     FileOutputStream out3 = createOutputStream("out3.jpg");
     // Create the source op image.
     PlanarImage src = loadImage(inFile);
        double[] constants = new double[3];
        constants[0] = 0.0;
        constants[1] = 0.0;
        constants[2] = 0.0;
        ParameterBlock pb = new ParameterBlock();
        pb.addSource(src);
        pb.add(constants);
     // Create a new src image with weird tile sizes
     ImageLayout layout = new ImageLayout();
     layout.setTileWidth(57);
     layout.setTileHeight(57);
     RenderingHints hints = new RenderingHints(JAI.KEY_IMAGE_LAYOUT,
                                                       layout);
     PlanarImage src1 = JAI.create("addconst", pb, hints);
     // ----- End src loading ------
     // Set the encoding parameters if necessary.
     encodeParam = new JPEGEncodeParam();
     encodeParam.setQuality(0.1F);
     encodeParam.setHorizontalSubsampling(0, 1);
     encodeParam.setHorizontalSubsampling(1, 2);
     encodeParam.setHorizontalSubsampling(2, 2);
     encodeParam.setVerticalSubsampling(0, 1);
     encodeParam.setVerticalSubsampling(1, 1);
     encodeParam.setVerticalSubsampling(2, 1);
     encodeParam.setRestartInterval(64);
     //encodeParam.setWriteImageOnly(false);
     //encodeParam.setWriteTablesOnly(true);
     //encodeParam.setWriteJFIFHeader(true);
     // Create the encoder.
     encodeImage(src, out1);
     PlanarImage dst1 = loadImage("out1.jpg");
     //   ----- End first encode ---------
     encodeParam.setLumaQTable(qtable1);
     encodeParam.setChromaQTable(qtable2);
     encodeImage(src, out2);
     PlanarImage dst2 = loadImage("out2.jpg");
     //   ----- End second encode ---------
     encodeParam = new JPEGEncodeParam();
     encodeImage(loadImage("images/BlackCat.tif"), out3);
     PlanarImage dst3 = loadImage("out3.jpg");
     //   ----- End third encode ---------
     setTitle ("JPEGWriter Test");
     setLayout(new GridLayout(2, 2));
     ScrollingImagePanel panel1 = new ScrollingImagePanel(src, 512,
                                                          400);
     ScrollingImagePanel panel2 = new ScrollingImagePanel(dst1, 512,
                                                          400);
     ScrollingImagePanel panel3 = new ScrollingImagePanel(dst2, 512,
                                                          400);
     ScrollingImagePanel panel4 = new ScrollingImagePanel(dst3, 512,
                                                          400);
        add(panel1);
        add(panel2);
        add(panel3);
        add(panel4);
        pack();
        show();    }
     }

13.6 Writing PNG Image Files

The Portable Network Graphics (PNG) format is a file standard for compressed lossless bitmapped image files. A PNG file consists of an eight-byte PNG signature followed by several chunks. The signature identifies the file as a PNG file. The chunks provide additional information about the image. The JAI codec architecture supports PNG 1.1 and provides control over several of the chunks as described in this section.

13.6.1 PNG Image Layout

PNG images can be encoded in one of three pixel types, as defined by the subclass of PNGEncodeParam, as follows:

Pixel Type Description
PNGEncodeParam.Palette
Also known as indexed-color, where each pixel is represented by a single sample that is an index into a supplied color palette. The com.sun.media.jai.codec.PNGEncodeParam.Palette class supports the encoding of palette pixel images.
PNGEncodeParam.Gray
Each pixel is represented by a single sample that is a grayscale level. The com.sun.media.jai.codec.PNGEncodeParam.Gray class supports the encoding of grayscale pixel images.
PNGEncodeParam.RGB
Also known as truecolor, where each pixel is represented by three samples: red, green, and blue. The com.sun.media.jai.codec.PNGEncodeParam.RGB class supports the encoding of RGB pixel images.

Optionally, grayscale and RGB pixels can also include an alpha sample (see Section 13.6.6.12, "Transparency (tRNS Chunk)").

A call to the getDefaultEncodeParam method returns an instance of:

This method provides no guarantee that the image can be successfully encoded by the PNG encoder, since the encoder only performs a superficial analysis of the image structure.


API: com.sun.media.jai.codec.PNGEncodeParam

returns an instance of PNGEncodeParam.Palette, PNGEncodeParam.Gray, or PNGEncodeParam.RGB appropriate for encoding the given image.

13.6.2 PNG Filtering

The PNG file definition allows the image data to be filtered before it is compressed, which can improve the compressibility of the data. PNG encoding supports five filtering algorithms, including "none," which indicates no filtering. The filtering algorithms are described below.

Table 13-3 PNG Filtering Algorithms
Parameter Description
PNG_FILTER_NONE
No filtering - the scanline is transmitted unaltered.
PNG_FILTER_SUB
The filter transmits the difference between each byte and the value of the corresponding byte of the prior pixel.
PNG_FILTER_UP
Similar to the Sub filter, except that the pixel immediately above the current pixel, rather than just to its left, is used as the predictor.
PNG_FILTER_AVERAGE
The filter uses the average of the two neighboring pixels (left and above) to predict the value of a pixel.
PNG_FILTER_PAETH
The filter computes a simple linear function of the three neighboring pixels (left, above, upper left), then chooses as predictor the neighboring pixel closest to the computed value.

The filtering can be different for each row of an image by using the filterRow method. The method can be overridden to provide a custom algorithm for choosing the filter type for a given row.

The filterRow method is supplied with the current and previous rows of the image. For the first row of the image, or of an interlacing pass, the previous row array will be filled with zeros as required by the PNG specification.

The method is also supplied with five scratch arrays. These arrays may be used within the method for any purpose. At method exit, the array at the index given by the return value of the method should contain the filtered data. The return value will also be used as the filter type.

The default implementation of the method performs a trial encoding with each of the filter types, and computes the sum of absolute values of the differences between the raw bytes of the current row and the predicted values. The index of the filter producing the smallest result is returned.

As an example, to perform only "sub" filtering, this method could be implemented (non-optimally) as follows:


     for (int i = bytesPerPixel; i < bytesPerRow + bytesPerPixel; i++)
     {
          int curr = currRow[i] & 0xff;
          int left = currRow[i - bytesPerPixel] & 0xff;
          scratchRow[PNG_FILTER_SUB][i] = (byte)(curr - left);
     }
     return PNG_FILTER_SUB;


API: com.sun.media.jai.codec.PNGEncodeParam

returns the type of filtering to be used on a row of an image.

Parameters:

currRow

The current row as an array of bytes of length at least bytesPerRow + bytesPerPixel. The pixel data starts at index bytesPerPixel; the initial bytesPerPixel bytes are zero.

prevRow

The current row as an array of bytes. The pixel data starts at index bytesPerPixel; the initial bytesPerPixel bytes are zero.

scratchRows

An array of 5 byte arrays of length at least bytesPerRow + bytesPerPixel, usable to hold temporary results. The filtered row will be returned as one of the entries of this array. The returned filtered data should start at index bytesPerPixel; The initial bytesPerPixel bytes are not used.

bytesPerRow

The number of bytes in the image row. This value will always be greater than 0.

bytesPerPixel

The number of bytes representing a single pixel, rounded up to an integer. This is the bpp parameter described in the PNG specification.

13.6.3 Bit Depth

The PNG specification identifies the following bit depth restrictions for each of the color types:

Table 13-4 PNG Bit Depth Restrictions
Color Type Allowed Bit Depths Description
0
1, 2, 4, 8, 16
Grayscale. Each pixel is a grayscale sample.
2
8, 16
Truecolor (RGB) without alpha. Each pixel is an RGB triple.
3
1, 2, 4, 8
Indexed color (Palette). Each pixel is a palette index.
4
8, 16
Grayscale with alpha. Each pixel is a grayscale sample followed by an alpha sample.
6
8, 16
Truecolor (RGB) with alpha. Each pixel is an RGB triple followed by an alpha sample.

The bit depth is specified by the setBithDepth method in the class type.


API: com.sun.media.jai.codec.PNGEncodeParam.Palette

sets the desired bit depth for a palette image. The bit depth must be 1, 2, 4, or 8.


API: com.sun.media.jai.codec.PNGEncodeParam.Gray
sets the desired bit depth for a grayscale image. The bit depth must be 1, 2, 4, 8, or 16.


API: com.sun.media.jai.codec.PNGEncodeParam.RGB
sets the desired bit depth for an RGB image. The bit depth must be 8 or 16.

13.6.4 Interlaced Data Order

The interlaced data order indicates the transmission order of the image data. Two settings are currently allowed: no interlace and Adam7 interlace. With interlacing turned off, pixels are stored sequentially from left to right, and scanlines sequentially from top to bottom. Adam7 interlacing (named after its author, Adam M. Costello), consists of seven distinct passes over the image; each pass transmits a subset of the pixels in the image.


API: com.sun.media.jai.codec.PNGEncodeParam

turns Adam7 interlacing on or off.

returns true if Adam7 interlacing will be used.

13.6.5 PLTE Chunk for Palette Images

The PLTE chunk provides the palette information palette or indexed-color images. The PLTE chunk must be supplied for all palette (color type 3) images and is optional for RGB (color type 2 and 6) images.

The PLTE chunk contains from 1 to 256 palette entries, each a three-byte series of the alternating red, green, and blue values, as follows:

The number of elements in the palette must be a multiple of 3, between 3 and 768 (3 x 256). The first entry in the palette is referenced by pixel value 0, the second by pixel value 1, and so on.

For RGB (color type 2 and 6) images, the PLTE chunk, if included, provides a suggested set of from 1 to 256 colors to which the RGB image can be quantized in case the viewing system cannot display RGB directly.


API: com.sun.media.jai.codec.PNGEncodeParam

sets the RGB palette of the image to be encoded.

Parameters:

rgb

An array of ints.

returns the current RGB palette.

suppresses the PLTE chunk from being output.

returns true if a PLTE chunk will be output.

13.6.6 Ancillary Chunk Specifications

All ancillary PNG chunks are optional but are recommended. Most of the PNG chunks can be specified prior to encoding the image by set methods in the PNGEncodeParam class. The chunks that can be set and the methods used to set them are described in the following paragraphs.

13.6.6.1 Background Color (bKGD Chunk)

Methods are provided to set and read the suggested background color, which is encoded by the bKGD chunk.

For Palette (indexed color) images, the bKGD chunk contains a single value, which is the palette index of the color to be used as the background.

For Grayscale images, the bKGD chunk contains a single value, which is the gray level to be used as the background. The range of values is 0 to 2bitdepth - 1.

For RGB (truecolor) images, the bKGD chunk contains three values, one each for red, green, and blue. Each value has the range of 0 to 2bitdepth - 1.


API: com.sun.media.jai.codec.PNGEncodeParam.Palette

sets the palette index of the suggested background color.

returns the palette index of the suggested background color.


API: com.sun.media.jai.codec.PNGEncodeParam.Gray
sets the suggested gray level of the background.

returns the suggested gray level of the background.


API: com.sun.media.jai.codec.PNGEncodeParam.RGB
sets the RGB value of the suggested background color. The rgb parameter should have three entries.

returns the RGB value of the suggested background color.

13.6.6.2 Chromaticity (cHRM Chunk)

Applications that need device-independent specification of colors in a PNG file can specify the 1931 CIE (x,y) chromaticities of the red, green, and blue primaries used in the image, and the referenced white point.

The chromaticity parameter should be a float array of length 8 containing the white point X and Y, red X and Y, green X and Y, and blue X and Y values in order.


API: com.sun.media.jai.codec.PNGEncodeParam

sets the white point and primary chromaticities in CIE (x,y) space.

a convenience method that calls the array version.

returns the white point and primary chromaticities in CIE (x,y) space.

13.6.6.3 Gamma Correction (gAMA Chunk)

The gamma value specifies the relationship between the image samples and the desired display output intensity as a power function:

sample = light_outgamma

If the image's gamma value is unknown, the gAMA chunk should be suppressed. The absence of the gAMA chunk indicates that the gamma is unknown.


API: com.sun.media.jai.codec.PNGEncodeParam

sets the gamma value for the image.

returns the gamma value for the image.

suppresses the gAMA chunk from being output.

13.6.6.4 Palette Histogram (hIST Chunk)

The palette histogram is a value that gives the approximate usage frequency of each color in the color palette. If the viewer is unable to provide all the colors listed in the palette, the histogram may help decide how to choose a subset of colors for display. The hIST chunk is only valid with Palette images.


API: com.sun.media.jai.codec.PNGEncodeParam.Palette

sets the palette histogram for the image.

returns the palette histogram for the image.

suppresses the hIST chunk from being output.

13.6.6.5 Embedded ICC Profile Data (iCCP Chunk)

You can specify that RGB image samples conform to the color space presented by the embedded International Color Consortium profile. The color space of the ICC profile must be an RGB color space.


API: com.sun.media.jai.codec.PNGEncodeParam

sets the ICC profile data.

returns the ICC profile data.

suppresses the iCCP chunk from being output.

13.6.6.6 Physical Pixel Dimensions (pHYS Chunk)

The intended pixel size or aspect ratio for display of the image may be specified in the pHYS chunk. The physical pixel dimensions information is presented as three integer values:

The unit specifier may have one of two values:

0 = Unit is unknown
1 = Unit is meters

When the unit specifier is 0, the pHYS chunk defines pixel aspect ratio only; the actual size of the pixels remains unspecified.


API: com.sun.media.jai.codec.PNGEncodeParam

sets the physical pixel dimension.

a convenience method that calls the array version.

returns the physical pixel dimension.

13.6.6.7 Significant Bits (sBIT Chunk)

For PNG data that has been converted from a lower sample depth, the significant bits information in the sBIT chunk stores the number of significant bits in the original image. This value allows decoders to recover the original data losslessly, even if the data had a sample depth not directly supported by PNG.

The number of entries in the significantBits array must be equal to the number of output bands in the image:


API: com.sun.media.jai.codec.PNGEncodeParam.RGB
sets the significant bits.

returns the significant bits.

suppresses the sBIT chunk from being output.

13.6.6.8 Suggested Palette (sPLT Chunk)

A suggested palette may be specified when the display device is not capable of displaying the full range of colors in the image. This palette provides a recommended set of colors, with alpha and frequency information, that can be used to construct a reduced palette to which the image can be quantized.

The suggested palette, as defined by the PNGSuggestedPaletteEntry class, consists of the following:


API: com.sun.media.jai.codec.PNGEncodeParam.Palette
sets the suggested palette.

returns the suggested palette.

suppresses the sPLT chunk from being output.

13.6.6.9 PNG Rendering Intent (sRGB Chunk)

If the PNG image includes an sRGB chunk, the image samples confirm to the sRGB color space and should be displayed using the specified rendering "intent." The rendering intent specifies tradeoffs in colorimetric accuracy. There are four rendering intents:

Table 13-5 PNG Rendering Intent
Parameter Description
INTENT_PERCEPTUAL
The "perceptual" intent is for images that prefer good adaptation to the output device gamut at the expense of colorimetric accuracy, such as photographs.
INTENT_RELATIVE
The "relative colorimetric" intent is for images that require color appearance matching.
INTENT_SATURATION
The "saturation" intent is for images that prefer preservation of saturation at the expense of hue and lightness.
INTENT_ABSOLUTE
The "absolute colorimetric" intent is for images that require absolute colorimetry.


API: com.sun.media.jai.codec.PNGEncodeParam.RGB

sets the PNG rendering intent.

Parameter:

SRGBIntent

The sRGB rendering intent to be stored with the image. The legal values are 0 = Perceptual, 1 = Relative colorimetric, 2 = Saturation, and 3 = Absolute colorimetric.

returns the rendering intent.

suppresses the sRGB chunk from being output.

13.6.6.10 Textual Data (tEXt Chunk)

Textual data can be encoded along with the image in the tEXt chunk. The information stored in this chunk can be an image description or copyright notice. A keyword indicates what the text string contains. The following keywords are defined:

Title

A title or caption for the image

Author

The name of the image's creator

Description

A description of the image

Copyright

A copyright notice

Creation Time

The time the original image was created

Software

The software used to create the image

Disclaimer

A legal disclaimer

Warning

A warning of the nature of the image content

Source

The hardware device used to create the image

Comment

Miscellaneous information


API: com.sun.media.jai.codec.PNGEncodeParam

sets the text string to be encoded with the image.

returns the text string to be encoded with the image.

suppresses the tEXt chunk from being output.

13.6.6.11 Image Modification Timestamp (tIME Chunk)

The tIME chunk provides information on the last time the image was modified. The tIME information is a Date and the internal storage format uses UTC regardless of how the modificationTime parameter was created.


API: com.sun.media.jai.codec.PNGEncodeParam

sets the image modification time as a Date that will be sent in the tIME chunk.

returns the image modification time data that will be sent in the tIME chunk.

suppresses the tIME chunk from being output.

13.6.6.12 Transparency (tRNS Chunk)

The tRNS chunk specifies that the image uses simple transparency. Simple transparency means either alpha values associated with palette entries for Palette images, or a single transparent color, for Grayscale and RGB images.

For Palette images, the tRNS chunk should contain a series of one-byte alpha values, one for each RGB triple in the palette. Each entry indicates that pixels of the corresponding palette index must be treated as having the specified alpha value.

For grayscale images, the tRNS chunk should contain a single gray level value, stored as an int. Pixels of the specified gray value are treated as transparent. If the grayscale image has an alpha value, setting the gray level causes the image's alpha channel to be ignored.

For RGB images, the tRNS chunk should an RGB color value, stored as an int. Pixels of the specified gray value are treated as transparent. If the RGB image has an alpha value, setting the gray level causes the image's alpha channel to be ignored.


API: com.sun.media.jai.codec.PNGEncodeParam.Palette

sets the alpha values associated with each palette entry. The alpha parameter should have as many entries as there are RGB triples in the palette.

returns the alpha values associated with each palette entry.


API: com.sun.media.jai.codec.PNGEncodeParam.Gray
sets the gray value to be used to denote transparency. Setting this attribute will cause the alpha channel of the input image to be ignored.

returns the gray value to be used to denote transparency.


API: com.sun.media.jai.codec.PNGEncodeParam.RGB
sets the RGB value to be used to denote transparency. Setting this attribute will cause the alpha channel of the input image to be ignored.

returns the RGB value to be used to denote transparency.

13.6.6.13 Compressed Text Data (zTXt Chunk)

Text data may be stored in the zTXt chunk, in addition to the text in the tEXt chunk. The zTXt chunk is intended for storing large blocks of text, since the text is compressed.


API: com.sun.media.jai.codec.PNGEncodeParam

sets the compressed text to be sent in the zTXt chunk.

returns the compressed text to be sent in the zTXt chunk.

suppresses the zTXt chunk from being output.

13.6.6.14 Private Chunks

Private chunks may be added to the output file. These private chunks carry information that is not understood by most other applications. Private chunks should be given names with lowercase second letters to ensure that they do not conflict with any future public chunk information. See the PNG specification for more information on chunk naming conventions.


API: com.sun.media.jai.codec.PNGEncodeParam

adds a private chunk to the output file.

returns the number of private chunks to be written to the output file.

returns the type of the private chunk at a given index, as a four-character String. The index must be smaller than the return value of getNumPrivateChunks.

removes all private chunks associated with this parameter instance whose "safe-to-copy" bit is not set. This may be advisable when transcoding PNG images.

remove all private chunks associated with this parameter instance.

13.7 Writing PNM Image Files

The PNM format is one of the extensions of the PBM file format (PBM, PGM, and PPM). The portable bitmap format is a lowest-common-denominator monochrome file format. It was originally designed to make it reasonable to mail bitmaps between different types of machines. It now serves as the common language of a large family of bitmap conversion filters.

The PNM format comes in six variants:

The parameter values, then are RAW and ASCII.

Listing 13-4 shows a code sample for encoding a PNM image.

Listing 13-4 Encoding a PNM Image


     // Create the OutputStream.
     OutputStream out = new FileOutputStream(fileToWriteTo);
     // Create the ParameterBlock.
     PNMEncodeParam param = new PNMEncodeParam();
     param.setRaw(true.equals("raw"));
     //Create the PNM image encoder.
     ImageEncoder encoder = ImageCodec.createImageEncoder("PNM",
                                                           out,
                                                           param);


API: com.sun.media.jai.codec.PNMEncodeParam

sets the RAWBITS option flag.

retrieves the RAWBITS option flag.

13.8 Writing TIFF Image Files

The TIFF file format is a tag-based file format for storing and interchanging raster images. TIFF files typically come from scanners, frame grabbers, and paint- or photo-retouching programs.

By default, TIFF images in JAI are encoded without any compression and are written out in strips rather than tiles. However, JAI does support image compression, and the writing of tiled TIFF images.

13.8.1 TIFF Compression

JAI currently does not support compression of TIFF images.

13.8.2 TIFF Tiled Images

By default, the JAI encoder organizes TIFF images into strips. For low- to medium-resolution images, this is adequate. However, for high-resolution (large) images, the images can be accessed more efficiently if the image is divided into roughly square tiles instead of strips.

Writing of tiled TIFF images can be enabled by calling the setWriteTiled method.


API: com.sun.media.jai.codec.TIFFEncodeParam

enables writing of TIFF images in tiles rather than in strips.

Parameter:

writeTiled

Specifies whether the image data should be written out in tiled format.

returns the value of the writeTiled parameter.



Contents Previous Next

Programming in Java Advanced Imaging


Copyright © 1999, Sun Microsystems, Inc. All rights reserved.

Casa de Bender