Colored PostScript Output Always Ends Up Red

QUESTION: I got this program from a colleague that he claims produces color PostScript output. But every time I try to produce color PostScript output with it the output ends up being drawn in shades of red, no matter what colors I specify. What am I doing wrong?

ANSWER: The problem is a bit of confusion caused by the introduction of 24-bit color PostScript output in IDL 7.1. It is now possible to specify PostScript colors by using a 24-bit color value that can be "decomposed" into three 8-bit color values that represent the red, green, and blue colors that mutually create the requested color. This is sometimes known as true-color, since it is possible to simultaneously display 16.7 million colors, instead of the 256 colors the PostScript device was previously restricted to displaying.

To activate 24-bit PostScript color support, you must have version 7.1 or higher of IDL, and you must set the Decomposed keyword to 1. (Actually, it is slightly more complicated than this, because you must also have set the Color keyword to 1, and the Bits_Per_Pixel keyword to 8, but this is pretty much always done by IDL programmers and is certainly done with PostScript set-up programs like cgPS_Config.)

    Set_Plot, 'PS'    Device, DECOMPOSED=1, COLOR=1, BITS_PER_PIXEL=8

With color decomposition turned on, any color value is interpreted as being a color triple encoded into a 24-bit value, with the lowest 8 bits representing the red value and the highest 8 bits representing the blue value. It is perhaps easiest to see this with an example. Take the color "khaki", which is represented by the RGB triple (240, 230, 140).

   IDL> Print, Reform(FSC_Color('khaki', /TRIPLE))      240     230     140

Here the red value (240, in this case) is represented on the left and the blue value on the right (in the traditional RGB arrangement). But, when displaying a number, it is traditional to display the lowest eight bits (the red bits) on the right and higher bits to the left. So, to represent the color khaki, in its 24-bit representation, in binary form, we might do this.

    IDL> khaki = FSC_Color('khaki', DECOMPOSED=1)    IDL> Print, khaki
      9234160    IDL> Print, Binary(khaki, /COLOR, /SEPARATE)
      1 0 0 0 1 1 0 0    1 1 1 0 0 1 1 0    1 1 1 1 0 0 0 0 

In this representation, the red component (1 1 1 1 0 0 0 0) is on the right, and the blue component (1 0 0 0 1 1 0 0) is on the left. We can confirm by printing the binary patterns for the numbers 240 and 140, respectively.

   IDL> Print, Binary(240, /COLOR, /SEPARATE)
      0 0 0 0 0 0 0 0    0 0 0 0 0 0 0 0    1 1 1 1 0 0 0 0
   IDL> Print, Binary(140, /COLOR, /SEPARATE)
      0 0 0 0 0 0 0 0    0 0 0 0 0 0 0 0    1 0 0 0 1 1 0 0 

In other words, the 24-bit number 9234160 is decomposed into three 8-bit numbers, namely 240, 230, and 140. This is what we mean by "color decomposition."

Color Decomposition Turned Off

But what happens to a color like khaki when color decomposition is turned off? When color decomposition is turned off, we typically say we are using indexed color. We mean by this that we have a color table with 256 possible red, green, and blue color combinations loaded into the table, and that we are specifying a color by means of an 8-bit color index into that color table. (Eight bits are all that are needed to represent a number from 0 to 255, which are the indices into the 256-valued color table.)

Suppose, for example, that we had loaded the khaki color into index 200 of the current color table.

Index Red Green Blue
200 240 230 140

To draw a plot with the khaki color, we might do something like this.

    IDL> Plot, data, COLOR=200 

If we were using indexed color, the RGB colors would be looked up in the color table at index 200, and we would display the proper color. But what happens if we draw a plot like this, but color decomposition is turned on?

In this case, the value 200 is treated as if it were a 24-bit value to be decomposed. But when this 8-bit value is decomposed, only bits in the red range get set. Hence, this value will only specify red colors!

   IDL> Print, Binary(200, /COLOR, /SEPARATE)
      0 0 0 0 0 0 0 0    0 0 0 0 0 0 0 0    1 1 0 0 1 0 0 0 

To fix this problem and display the proper colors, you must turn color decomposition off in your PostScript device and use the indexed color model, like this.

   Set_Plot, 'PS'    Device, DECOMPOSED=0, COLOR=1, BITS_PER_PIXEL=8 

Remember, PostScript device set-ups are "sticky", meaning that once they are set, they stay set until they are changed. If your PostScript device gets into a decomposed color setting, it will stay there until you change it. If you wish to use color indices to express your colors, you must turn color decomposition off for your PostScript device.

Alternatively, if you have color decomposition turned off in your PostScript device, and you specify colors as 24-bit values, there is an excellent chance you will end up with a blank page of PostScript output. The page is not actually blank. Rather these 24-bit values are typically greater than 255 and so are treated as index 255 by the PostScript driver. More often than not in this case, you will draw white lines on a white background, so your output looks blank when in fact it is not. To solve this problem, set your PostScript device to display decomposed color.

   Set_Plot, 'PS'    Device, DECOMPOSED=1, COLOR=1, BITS_PER_PIXEL=8 

The secret to wonderful (and colorful!) PostScript output is to match your color specifications with the proper DECOMPOSED setting. Specifying your colors with cgColor, of course, is one way to assure this happens.

Version of IDL used to prepare this article: IDL 7.1.

Web Coyote's Guide to IDL Programming