Read PPM images as BufferedImage

H

hz010c1877

Hi,

I've got PPM image files stored in raw bytes rather than ACSII which magic
identifiers are P6 and P3 respectively. I want to read them into memory and
return a BufferedImage instance. I know how to do it for ASCII PPM image
files but have no idea for raw bytes ones. Does anyone have any suggestions?
Any help will be appreciated.

Here is the mothed for reading ASCII PPM image as BufferedImage:

// some codes are not list here for simplicity
// width and height is the width and heigh of a image
// readHeader() reads the header of PPM image
// The following is supposed to run before the parsePPm() method

// private StreamTokenizer parser;
// reader = new BufferedReader(new InputStreamReader(in));
// parser = new StreamTokenizer(reader);
// parser.commentChar('#');
// readHeader();

private BufferedImage parsePPM() throws IOException, PPMDecoderException {
BufferedImage img =
new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
WritableRaster raster = img.getRaster();
for (int y = 0; y < height; ++y)
for (int x = 0; x < width; ++x)
for (int i = 0; i < 3; ++i) {
parser.nextToken();
if (parser.ttype == StreamTokenizer.TT_EOF)
throw new EOFException("image appears to be truncated");
if (parser.ttype != StreamTokenizer.TT_NUMBER)
throw new PPMDecoderException("non-numeric value for sample "
+ i + " of pixel at (" + x + "," + y + ")");
raster.setSample(x, y, i, (int) parser.nval);
}
return img;
}
 
J

John C. Bollinger

hz010c1877 said:
Hi,

I've got PPM image files stored in raw bytes rather than ACSII which magic
identifiers are P6 and P3 respectively. I want to read them into memory and
return a BufferedImage instance. I know how to do it for ASCII PPM image
files but have no idea for raw bytes ones. Does anyone have any suggestions?
Any help will be appreciated.

Here is the mothed for reading ASCII PPM image as BufferedImage:

// some codes are not list here for simplicity
// width and height is the width and heigh of a image
// readHeader() reads the header of PPM image
// The following is supposed to run before the parsePPm() method

// private StreamTokenizer parser;
// reader = new BufferedReader(new InputStreamReader(in));
// parser = new StreamTokenizer(reader);
// parser.commentChar('#');
// readHeader();

private BufferedImage parsePPM() throws IOException, PPMDecoderException {
BufferedImage img =
new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
WritableRaster raster = img.getRaster();
for (int y = 0; y < height; ++y)
for (int x = 0; x < width; ++x)
for (int i = 0; i < 3; ++i) {
parser.nextToken();
if (parser.ttype == StreamTokenizer.TT_EOF)
throw new EOFException("image appears to be truncated");
if (parser.ttype != StreamTokenizer.TT_NUMBER)
throw new PPMDecoderException("non-numeric value for sample "
+ i + " of pixel at (" + x + "," + y + ")");
raster.setSample(x, y, i, (int) parser.nval);
}
return img;
}

Magic number P3 is used by the (putatively rare) "plain" PPM format,
which appears to be exactly what the code above is supposed to handle.
(Modulo possible differences in the header.) All header information is
ASCII, with all numeric values represented in decimal.

Magic number P6 designates the more common "raw" PPM format. The header
for raw PPM is the same as for plain PPM except for the magic number.
The difference is that the pixel data is in machine format with no
intervening whitespace. There is one byte per color component if the
header specifies the maximimum color value as less than 256, or two
bytes per color component otherwise, most significant byte first. Also,
it is allowed for multiple images in that format to be concatenated
together into one file; this is not allowed for the plain format.

Do note that according to the docs the color values in a standard PPM
file are non-linear, proportional to the CIE Rec. 709 color values and
adjusted by the CIE Rec. 708n gamma transfer function. (Whatever that
means -- I'm just reading the docs to you for this bit.) The docs do
note that a common variant of the format uses linear color values,
however, so I guess you should just look to see whether the result looks
good.



John Bollinger
(e-mail address removed)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,731
Messages
2,569,432
Members
44,832
Latest member
GlennSmall

Latest Threads

Top