Most graphics we'd encounter are made up of different types of RGB. A 24-bit BMP image would have a 8-bit (R)ed component, a 8-bit (G)reen component and a 8-bit (B)lue component.
For all of these 8-bit R/G/B components, their intensity has a range of 0-255, and different combinations of R/G/B will produce different colours. Some examples of the extremes would be:
255, 0, 0 //
red0, 255, 0 //
green0, 0, 255 //
blue0, 0, 0 //
black255, 255, 255 //
white255, 255, 0 //
yellow255, 0, 255 //
magenta0, 255, 255 //
cyanImages can also have transparency, which can either be represented a few ways. There are a few ways of handling transparency, but the simplest at this point would be an additional 8-bit (A)lpha component where a value of 0 would be fully transparent and 255 would be fully opaque.
Generally when we're dealing with bitplanes, we will have a table that consists of a certain number of different colours, each with a (R)ed, (G)reen and (B)lue component.
The index value therefore represents which colour we want to use.
In
this post there are two sets of tables that have the data arranged slightly differently.
In this first version we have separate tables for the red, green and blue components. With our 2-bit index (0-3), we would be able to access the 0th, 1st, 2nd or 3rd element of each table.
If our index was 1, we'd get red[1], green[1] and blue[1] which would give us { 53, 189, 104 } which turns out to be a nice green shade. Similarly if our index was 2, we'd get { 59, 85, 142 } which is a deeper blue.
In the second version we have a struct containing a red, a green and a blue component. After that we define an array containing four groups of colours. That code block can be scrolled, there is an example of how to access and assign them.
The idea behind using tables is that you don't need to check the value of the index in an if block at all, using e.g. red[index] will retrieve the nth shade of red for you automatically.
Both versions contain the same data, just arranged slightly differently. The second version is a bit more verbose, but also a bit easier to comprehend.
The extended table you have with 6 entries each are a bit concerning. We're dealing with bitplanes consisting of 2, 4 or 8 bits per plane, so each index will be 0-3, 0-15 or 0-255. If you were using 2bpp, only the first four entries in each table would be used (0-3). If you were using 4bpp, your index could be 0-15, so if it were higher than 5 it could read past the end of the table and the results could be unpredictable.
At this stage, getting a bit more familiar with different types of debugging would be a good idea. You should have a rough idea of what colours each pixel ought to be, so why not print out what colours are going where and ensure that it matches what you expect should be happening. If you're not getting what you expect, you can study the code and try to figure out why that happened at a particular point that would cause it to go wrong.
WesternTanager794 mentioned paint which is a very good idea. I don't know what capabilities it has nowadays, but most image editors or viewers will have an eyedropper tool or some equivalent that you can use to inspect individual pixels in your output image. It's also fairly common for them to use #RRGGBB notation for colours. Those are hexadecimal values so they should be familiar by now? Calculator programs can usually convert between decimal and hexadecimal if you need that.
Some image formats use BGR (or other formats) instead of RGB, but that shouldn't be an issue here.
Image manipulation is a terrific way to learn so many ins and outs of programming, so much of it is fundamental robotic logic.