Skip to content
Matthias Grimm edited this page Aug 16, 2026 · 3 revisions

Indexed Color Tables or CLUT

Introduction

Pictures today are stored in true color, that means each pixel is stored 32 bits wide. These 32 bits contain the color directly:

  • 8 bit for RED,
  • 8 bit for GREEN and
  • 8 bit for BLUE

Each color has 256 different shades which gives us 256 * 256 * 256 = 16777216 different color.

You might say: "3 times 8 are only 24 bits, what happened to the remaining 8 bits in a 32 bit word?" and you ar right. The remaining 8 bits are often, but not always used for the alpha-channel (256 steps of transparency).

Classic computers did not have enough video memory to use true color pictures so they use different methods of encoding colors. It will be too much for this article to explain them all. Wikipedia might be a good source, if you are interested in more details.

In this article I would like to focus on the Color Table or CLUT and here especially how the CMM2 is using it.

The CMM2 CLUT - Color Look Up Table

As we already learned, true color images use 32 bits for each pixel to store the color. What would we do, if we only have 8 bits available for the color information? Store the color directly? Depending on the video hardware this could make sense. The Wikipedia Article RGB Color Formats will tell you more about different color formats and where they were used.

The CMM2 has a different method to save video memory (only 8 bit per pixel) and full 32 bit color range: The CLUT - Color Look Up Table.

Instead of storing the color information directly, it stores the colors in a table of 256 entries each 32 bit wide. Finally, we store the index of this table in the image instead. This way we can choose 256 different colors from a palette of 16777216 colors for our image and need only a 4th of video memory for it. This is also called Indexed Video Mode.

This is the default CLUT of the Color Maximite 2:

CMM2 default color table

Unfortunalety, the CLUT build into the CMM2 video hardware is a write-only memory. That means, we can set a color register to a certain color, but we can't read it back. And this comes with some implications.

First, the default CLUT from the picture above, is the default CLUT of the operating system. It is loaded to the video hardware at startup and after the basic command "map reset".

Secondly, MMBasic still allows to set any color with the RGB(R,G,B) command. But because we have only 256 different colors available, the RGB() comand checks for a color in the CLUT which is closest to the requested one and use this instead.

From the CLUT?

No, the CLUT can't be read back. So, RGB() uses the default CLUT from the firmware. That is important to understand, if you use a custom color map and RGB() for color selection. To avoid any conflicts, we can use the command map() which takes the CLUT register to set the color.

GEM cmap.inc

The source "cmap.inc" in this Gem compensates for the missing read capability by storing the color map before writing it to the video hardware. The CLUT can't stil be read back, but we always know which color code has been set to which CLUT register. Unfortunately, this cannot compensate for the RGB() behaviour which still uses the default firmware color table to find the "best" color.

This is shows a custom color table. Please notice that not all of the 256 color registeres have been modified.

custom_clut

The following picture shows an example how the color table is addressed by an image. Each pixel represents an CLUT register shown as 2-digit hexadecimal number. The small image above shows the real helicopter image.

Helicopter in CLUT view

To test the color map and play around with your own color tables, you can use the program ColorMap.bas where I got the above screenshots from

ColorMap format

To make custom color map handling easy, I implemented a reader for GIMP Palette files into cmap.inc.

It is a very easy text format just containing one color per line, seperated as R,G,B values in decimal. The "#" marks comments. See example below.

 # GIMP Palette file
   0   0   0     #0
 255   0   0     #1
   0 255   0     #2
   0   0 255     #3
 255   0 255     #4

Clone this wiki locally