Monochrome PCX image encoding

J

JVidal

Problem description: I have to convert a BufferedImage into a
monochrome PCX image file. So far I've tried using JIMI, until I
realize it didn't handle monochrome PCX. Since I couldn't find any Java
library supporting this format, I figured out I had to write an image
encoder myself.

I studied the JIMI code (the PCX encoding part), I found the PCX format
specs here: http://www.dcs.ed.ac.uk/home/mxr/gfx/2d/PCX.txt and here:
http://courses.ece.uiuc.edu/ece390/books/labmanual/graphics-pcx.html

anyway I'm still lost, as I'm a complete (and I mean complete!) newbie
when it comes to image manipulation - I still don't even have a precise
idea about what a ColorSpace or a ColorModel or a Raster or a palette
really are. Eg, I know I have to encode a monochrome palette in my PCX
header, but will the static array of bytes I extracted from another
monochrome PCX image do? (I guess not)

And what about encoding the image data? I've seen I could extract raw
data from the Java image with something like

BufferedImage img;
....
Raster raster = img.getData();
DataBuffer data = raster.getDataBuffer();

but is it really all the data I need to encode? Does it require some
sort of transformation before I RLE-encode this data into my PCX file?
And what if the original image comes in 16-bit, 256-bit, etc. color?
I'd really appreciate at least a few pointers or guidelines about all
these questions.
 
O

Oliver Wong

JVidal said:
Problem description: I have to convert a BufferedImage into a
monochrome PCX image file. So far I've tried using JIMI, until I
realize it didn't handle monochrome PCX. Since I couldn't find any Java
library supporting this format, I figured out I had to write an image
encoder myself.

I studied the JIMI code (the PCX encoding part), I found the PCX format
specs here: http://www.dcs.ed.ac.uk/home/mxr/gfx/2d/PCX.txt and here:
http://courses.ece.uiuc.edu/ece390/books/labmanual/graphics-pcx.html

These course notes seem geared towards a specific assignment. The first
one, for example, says "Usually you can ignore this header, since your
images will all have the same resolution.", but I strongly suspect you won't
be handling images with a pre-known resolution.

Try using this document instead: http://www.qzx.com/pc-gpe/pcx.txt It's
from ZSoft, the company which invented the format.
anyway I'm still lost, as I'm a complete (and I mean complete!) newbie
when it comes to image manipulation - I still don't even have a precise
idea about what a ColorSpace or a ColorModel or a Raster or a palette
really are. Eg, I know I have to encode a monochrome palette in my PCX
header, but will the static array of bytes I extracted from another
monochrome PCX image do? (I guess not)

You need to know what a palette is. The other terms you mentioned are
not so important. You'd also need to know the terms "resolution", "pixel"
and "run-length encoding". I'll try to explain palette here.

Your screen is made up of a bunch of electron guns which fire red, green
and blue photons of varying intensity (or brightness levels) to make up all
the colours that you can see on your screen. If all 3 guns fire at full
intensity, you'll see white. If only the red gun is firing at full
intensity, you'll see red. If red and blue are firing at full intensity,
you'll see purple. If all the guns are off, you'll see black.

Thus, in the context of computer graphics, colour is often specified as
an RGB triplet, where RGB stands for Red Green Blue respectively. This
triplet consists of 3 numerical values giving the intensity that each gun
should fire at. Depending on the context, different units will be in use. A
common one is a floating point between 0 (black) and 1 (white). 0.5 would be
grey in these units. Another common one is an integer between 0 (black) and
255 (white). 128 is grey in those units.

If you have an image which consists of black and white checker pattern,
and the image's resolution is 4 by 4, the you could describe it like this:

4,4,
(000,000,000),(255,255,255),(000,000,000),(255,255,255),
(255,255,255),(000,000,000),(255,255,255),(000,000,000),
(000,000,000),(255,255,255),(000,000,000),(255,255,255),
(255,255,255),(000,000,000),(255,255,255),(000,000,000),

The first 2 numbers give the resolution, and then the next 16 triplets
give the value at each pixel. But we could actually shrink this, by creating
a "palette". A palette is a mapping between a colour name, and an RGB value.
For example, I might have a palette-based image file like this:

4,4
black: (000,000,000)
white: (255,255,255)
black,white,black,white,
white,black,white,black,
black,white,black,white,
white,black,white,black,

This file is much smaller, but I could make it smaller still, by simply
giving the colours shorter names, like so:

4,4
b: (000,000,000)
w: (255,255,255)
b,w,b,w,
w,b,w,b,
b,w,b,w,
w,b,w,b,

It's common practice to make the "colour names" to be numbers. So, I
could have create the same file above, and name the colour (000,000,000) as
"0", and the colour (255,255,255) as "1".

That's basically all a palette is: a mapping from the colour name to the
RGB values. PCX files usually use a palette, but there exist PCX files which
store the RGB values directly.
And what about encoding the image data? I've seen I could extract raw
data from the Java image with something like

BufferedImage img;
...
Raster raster = img.getData();
DataBuffer data = raster.getDataBuffer();

but is it really all the data I need to encode?

I'd keep things simple, and use the .getRGB(int x, int y) method on
BufferedImage to extract the RGB information at every pixel, and work from
there.
Does it require some
sort of transformation before I RLE-encode this data into my PCX file?

If the original image is 16 bit, but the PCX you're writing to is a 8
bit one, then you're going to have do something special there. Perhaps
dithering or nearest-colour matching or something like that.
And what if the original image comes in 16-bit, 256-bit, etc. color?

I don't think you'll come across any 256-bit colour images any time
soon. The number of colours in an image is 2 raised to the power of its bit
depth. So a 16 bit image has 65'536 colours.

The simplest thing to do is create a PCX file whose bit depth is exactly
the same as the bit-depth of the in-memory representation of the image.

- Oliver
 
Joined
Oct 17, 2007
Messages
1
Reaction score
0
I have the same problem

Hi.
I have the same problem. I'm trying to get 1bit/px PCX file from 8bit/px. Did you made the algorithm at last?
 

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

No members online now.

Forum statistics

Threads
473,773
Messages
2,569,594
Members
45,123
Latest member
Layne6498
Top