Colour glitch in code.

Hi, I am getting some inconsistency in colour values.

I am getting a strange glitch in my code. I have

1
2
3
    unsigned char   red[] = { 255,  53,  59, 154, 0, 255 };
    unsigned char green[] = { 255, 189,  85, 194, 255, 0};
    unsigned char  blue[] = { 255, 104, 142, 237, 255, 0 };


and then this....

1
2
3
4
5
6
 else if (Index == 5) // red
            {
                buf[c + 0] = red[Index];
                buf[c + 1] = green[Index];
                buf[c + 2] = blue[Index];
            }



I am getting blue and not red. the other colours seem to work.

It's like they have been swapped?
Any ideas?
Last edited on
Show enough code that it can be compiled to demonstrate your problem. The issue probably doesn't come from that 5 lines of code. You could be writing into the wrong parts of a buffer anywhere.
ok here it is. I didn't post it cuzz its messy.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
int main()
{
 

    // Below is for the sprite.
    //int Bitplane0_ROW[] = { 0b01100110 , 0b11111111, 0b01011010, 0b01111110, 0b00000000, 0b10000001, 0b11111111, 0b01111110 }; // Array to to store numbers Last Row is first.
    //int Bitplane1_ROW[] = { 0b01111110, 0b11111111, 0b11111111, 0b11011011, 0b11111111, 0b01111110, 0b00000000, 0b00000000 };
    //int Bitplane2_ROW[] = { 0b00000000 , 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000 };
    //int Bitplane3_ROW[] = { 0b00000000 , 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000 };

    
    // Colours 0 to 7
    
    int Bitplane0_ROW[] = { 0b11111111, 0b00000000,0b11111111,0b00000000,0b11111111,0b00000000,0b11111111,0b00000000 };
    int Bitplane1_ROW[] = { 0b11111111, 0b11111111,0b00000000,0b00000000,0b11111111,0b11111111,0b00000000,0b00000000 };
    int Bitplane2_ROW[] = { 0b11111111, 0b11111111,0b11111111,0b11111111,0b00000000,0b00000000,0b00000000,0b00000000};
    int Bitplane3_ROW[] = { 0b00000000, 0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000 };
    

    /* Colours 8 -  15
    int Bitplane0_ROW[] = { 0b11111111, 0b00000000,0b11111111,0b00000000,0b11111111,0b00000000,0b11111111,0b00000000 };
    int Bitplane1_ROW[] = { 0b11111111, 0b11111111,0b00000000,0b00000000,0b11111111,0b11111111,0b00000000,0b00000000 };
    int Bitplane2_ROW[] = { 0b11111111, 0b11111111,0b11111111,0b11111111,0b00000000,0b00000000,0b00000000,0b00000000 };
    int Bitplane3_ROW[] = { 0b11111111, 0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111 };
    */







 
    int N = 7; //to store bit
    int c = 0;

    
    BYTE* buf = new BYTE[8 * 5];




    unsigned char White[] = {255, 255, 255};
    unsigned char Green[] = {53, 189,104 };  ////////////////
    unsigned char Brown[] = {59,85,142 }; /////////////////////
    unsigned char Tan[] = {154,194,237 };
    unsigned char Yellow[] = {0, 255, 255 }; /////////////
    unsigned char Red[] = { 0,0,255 }; ///////////////////
    unsigned char Blue[] = { 255,0,0 };
    unsigned char Grey[] = { 128,128,128 };
    unsigned char Purple[] = {255,0,255 };
    unsigned char Black[] = { 0,0,0 };
    unsigned char Aqua[] = {255,255,0};
    unsigned char Orange[] = { 0,191,255 };
    unsigned char Maroon[] = { 0,0,128 };
    unsigned char Navy[] = { 128,0,0 };
    unsigned char Lime[] = { 0,255,0 };
    unsigned char Teal[] = { 128,128,0 };



   
    unsigned char   red[] = { 255,  104,  142, 154, 0, 0, 255 };
    unsigned char green[] = { 255, 189,  85, 194, 255, 0, 0};
    unsigned char  blue[] = { 255, 53, 59, 237, 255, 255, 0 };







    for (int p = 0; p < 8; p++)
    {
        for (int j = 0; j < 8; j++) // Row 6
        {
          
         
            std::bitset<4> bs;
            bs.set(0, (Bitplane0_ROW[p] >> N) & 1);
            bs.set(1, (Bitplane1_ROW[p] >> N) & 1);
            bs.set(2, (Bitplane2_ROW[p] >> N) & 1);
            bs.set(3, (Bitplane3_ROW[p] >> N) & 1);
            unsigned long Index = bs.to_ulong();



            cout << "The value  is " << Index;


 
          
          
            if(Index == 0) // White
            {
                buf[c + 0] = red[Index];
                buf[c + 1] = green[Index];
                buf[c + 2] = blue[Index];
            }
            else if (Index == 1) // Green   
            {
                buf[c + 0] = red[Index];
                buf[c + 1] = green[Index];
                buf[c + 2] = blue[Index];
            }
            else if (Index == 2) // Brown
            {
                buf[c + 0] = blue[Index];
                buf[c + 1] = green[Index];
                buf[c + 2] = red[Index];
            }
            else if (Index == 3) // Tan
            {
                buf[c + 0] = red[Index];
                buf[c + 1] = green[Index];
                buf[c + 2] = blue[Index];
            }
            else if (Index == 4) // Yellow
            {
                buf[c + 0] = red[Index];
                buf[c + 1] = green[Index];
                buf[c + 2] = blue[Index];
            }
            else if (Index == 5) // red
            {
                buf[c + 0] = red[Index];
                buf[c + 1] = green[Index];
                buf[c + 2] = blue[Index];
            }
            else if (Index == 6)
            {

                // Index 6 (Blue)
                buf[c + 0] = red[Index];
                buf[c + 1] = green[Index];
                buf[c + 2] = blue[Index];
            }
            else if (Index == 7)
            {

                // Index 7 (Grey)
                Index = 0;
                buf[c + 0] = Grey[Index];
                buf[c + 1] = Grey[Index + 1];
                buf[c + 2] = Grey[Index + 2];
            }
            else if (Index == 8)
            {

                // Index 8 (Purple)
                Index = 0;
                buf[c + 0] = Purple[Index];
                buf[c + 1] = Purple[Index + 1];
                buf[c + 2] = Purple[Index + 2];
            }
            else if (Index == 9)
            {

                // Index 9 (Black)
                Index = 0;
                buf[c + 0] = Black[Index];
                buf[c + 1] = Black[Index + 1];
                buf[c + 2] = Black[Index + 2];
            }
            else if (Index == 10)
            {

                // Index 10 (Aqua)
                Index = 0;
                buf[c + 0] = Aqua[Index];
                buf[c + 1] = Aqua[Index + 1];
                buf[c + 2] = Aqua[Index + 2];
            }
            else if (Index == 11)
            {

            // Index 11 (Orange)
            Index = 0;
            buf[c + 0] = Orange[Index];
            buf[c + 1] = Orange[Index + 1];
            buf[c + 2] = Orange[Index + 2];
            }
            else if (Index == 12)
            {

            // Index 12 (Maroon)
            Index = 0;
            buf[c + 0] = Maroon[Index];
            buf[c + 1] = Maroon[Index + 1];
            buf[c + 2] = Maroon[Index + 2];
            }
            else if (Index == 13)
            {

            // Index 13 (Navy)
            Index = 0;
            buf[c + 0] = Navy[Index];
            buf[c + 1] = Navy[Index + 1];
            buf[c + 2] = Navy[Index + 2];
            }
            else if (Index == 14)
            {
                // Index 14 (Lime)
                Index = 0;
                buf[c + 0] = Lime[Index];
                buf[c + 1] = Lime[Index + 1];
                buf[c + 2] = Lime[Index + 2];
            }
            else if (Index == 15)
            {
                // Index 15 (Teal)
                Index = 0;
                buf[c + 0] = Teal[Index];
                buf[c + 1] = Teal[Index+1];
                buf[c + 2] = Teal[Index+2];

            }
            c += 3;
            N--;
        }
        N = 7;
    }

    SaveBitmapToFile((BYTE*)buf, 8, 8, 24, 0, "C:\\Users\\Chris\\Desktop\\Link_Sprite.bmp");

    delete[] buf;
    return 0;
Well, that manifestly won’t compile “as is”, so there’s no way of testing it.

The p and j loops will increment c by 3 some 64 times. But there aren’t 64*3 elements in buf[], so you will go well out of range.

Later on, when you get beyond purple, most of your colours will be addressed way beyond array bounds.
Cyclone wrote:
I am getting blue and not red.

Sounds like you have reversed the order of the bytes for each pixel.
I think the 24-bit BMP format store blue, green and red in that order.
Last edited on
would it help if i post the source somewhere? There is a lot more code. I posted what I thought was the problem code.

I am getting blue and not red and red when I want blue.

Thanks for looking into my code. Appreciate it. :)
Reduce your code to a SIMPLE, COMPILEABLE EXAMPLE which illustrates the problem.

If all you are doing is outputting a square of a single colour then that code cannot possibly be long.
If you format the red/green/blue and arrays you get:

1
2
3
4
//                        0    1    2    3    4    5    6
unsigned char   red[] = { 255, 104, 142, 154, 0,   0,   255 };
unsigned char green[] = { 255, 189, 85,  194, 255, 0,   0 };
unsigned char  blue[] = { 255, 53,  59,  237, 255, 255, 0 };


which shows that an index of 5 does indeed give blue! If 5 is supposed to give red then you need to swap the values of red/blue for the 5th element.

Similarly, index 6 gives red and not blue.

As coded, index 5 gives blue and index 6 gives red.

PS Note that in post #1:

1
2
3
unsigned char   red[] = { 255,  53,  59, 154,   0, 255 };
unsigned char green[] = { 255, 189,  85, 194, 255, 0   };
unsigned char  blue[] = { 255, 104, 142, 237, 255, 0   };


and in post #3:

1
2
3
unsigned char   red[] = { 255, 104, 142, 154,   0,   0, 255 };
unsigned char green[] = { 255, 189,  85, 194, 255,   0,   0 };
unsigned char  blue[] = { 255,  53,  59, 237, 255, 255,   0 };


These are different! In the first (original), index 5 does give red but as mentioned above, in the revised it gives blue. The values for red and blue have been interchanged.
Last edited on
Well spotted, @seeplus!

Perhaps @cyclone would like to tell us which of the two versions his original post was referring to!
Also, I'm sure lines 94 to 217 could be massively simplified with a lookup table, or a map.
Last edited on
From Peter

Sounds like you have reversed the order of the bytes for each pixel.
I think the 24-bit BMP format store blue, green and red in that order.


I think that's what it is. I had to change it from RGB to BGR. I am so used to saying things are red green and blue that it confused me lol.
To be clear a BMP is in blue, green and red order? Is there an info about this somewhere in google?

From Ganado

Also, I'm sure lines 94 to 217 could be massively simplified with a lookup table, or a map.



That is beyond my knowledge... but i'm all ears ;)


Thanks and sorry for the confusion.
Cyclone wrote:
To be clear a BMP is in blue, green and red order? Is there an info about this somewhere in google?


Wikipedia wrote:
The 24-bit per pixel (24bpp) format supports 16,777,216 distinct colors and stores 1 pixel value per 3 bytes. Each pixel value defines the red, green and blue samples of the pixel (8.8.8.0.0 in RGBAX notation). Specifically, in the order: blue, green and red (8 bits per each sample).
https://en.wikipedia.org/wiki/BMP_file_format#Pixel_format

The reason for why the bytes are stored in this order is probably because the Windows devices that was used at the time when the BMP format was invented by Microsoft happened to use "little endian".

Endianness
"Little endian" means the most significant bits will be stored last in memory (i.e. have higher memory addresses).
"Big endian" means the most significant bits will be stored first in memory (i.e. have lower memory addresses).

Example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include <cstdint>

int main()
{
	std::uint32_t num = 0x11223344;
	
	// Print the underlying bytes...
	unsigned char* bytes = reinterpret_cast<unsigned char*>(&num);
	for (std::size_t i = 0; i < sizeof(num); ++i)
	{
		std::cout << std::hex << unsigned(bytes[i]) << " ";
	}
	std::cout << "\n";
}

Output on little endian computers:
44 33 22 11

Output on big endian computers:
11 22 33 44

Little endian is by far the most common.

Note that two hexadecimal digits correspond exactly to one byte (8 bits), and that the endianness only affects the order of the bytes (not bits). Reversing the bytes of a 4-byte value 0x12345678 would give you the value 0x78563412.

Read more: https://en.wikipedia.org/wiki/Endianness

In computer graphics it's quite common to write colours using RGB (or RGBA) hexadecimal notation. For example FF0000 is red, FFFF00 is yellow, 00FF00 is green, and so on. HTML/CSS, image editing programs like GIMP and PhotoShop, and many graphics libraries for C++ and other programming languages support this hexadecimal notation in one form or the other. The order in which you write the RGB values will never be reversed, but the way they get stored could very well be reversed due to the endianness of the machine as described above.

When it comes to file formats it's usually specified which byte order should be used so that it's the same everywhere and so that it can be transferred between little endian and big endian computers without problems.
Last edited on
Cool thanks for the info.
I did this, but forgot to post it :(
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#include <iostream>
#include <bitset>
typedef char BYTE;
int main()
{
    // Below is for the sprite.
    //int Bitplane0_ROW[] = { 0b01100110 , 0b11111111, 0b01011010, 0b01111110, 0b00000000, 0b10000001, 0b11111111, 0b01111110 }; // Array to to store numbers Last Row is first.
    //int Bitplane1_ROW[] = { 0b01111110, 0b11111111, 0b11111111, 0b11011011, 0b11111111, 0b01111110, 0b00000000, 0b00000000 };
    //int Bitplane2_ROW[] = { 0b00000000 , 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000 };
    //int Bitplane3_ROW[] = { 0b00000000 , 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000 };

    // Colours 0 to 7
    int Bitplane0_ROW[] = { 0b11111111, 0b00000000,0b11111111,0b00000000,0b11111111,0b00000000,0b11111111,0b00000000 };
    int Bitplane1_ROW[] = { 0b11111111, 0b11111111,0b00000000,0b00000000,0b11111111,0b11111111,0b00000000,0b00000000 };
    int Bitplane2_ROW[] = { 0b11111111, 0b11111111,0b11111111,0b11111111,0b00000000,0b00000000,0b00000000,0b00000000 };
    int Bitplane3_ROW[] = { 0b00000000, 0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000 };
    
    /* Colours 8 -  15
    int Bitplane0_ROW[] = { 0b11111111, 0b00000000,0b11111111,0b00000000,0b11111111,0b00000000,0b11111111,0b00000000 };
    int Bitplane1_ROW[] = { 0b11111111, 0b11111111,0b00000000,0b00000000,0b11111111,0b11111111,0b00000000,0b00000000 };
    int Bitplane2_ROW[] = { 0b11111111, 0b11111111,0b11111111,0b11111111,0b00000000,0b00000000,0b00000000,0b00000000 };
    int Bitplane3_ROW[] = { 0b11111111, 0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111 };
    */


    unsigned char colours[][3] = {
        //BBB  GGG  RRR
        { 255, 255, 255 }, /* White */
        {  53, 189, 104 }, /* Green */
        {  59,  85, 142 }, /* Brown */
        { 154, 194, 237 }, /* Tan */
        {   0, 255, 255 }, /* Yellow */
        {   0,   0, 255 }, /* Red */
        { 255,   0,   0 }, /* Blue */
        { 128, 128, 128 }, /* Grey */
        { 255,   0, 255 }, /* Purple */
        {   0,   0,   0 }, /* Black */
        { 255, 255,   0 }, /* Aqua */
        {   0, 191, 255 }, /* Orange */
        {   0,   0, 128 }, /* Maroon */
        { 128,   0,   0 }, /* Navy */
        {   0, 255,   0 }, /* Lime */
        { 128, 128,   0 }, /* Teal */
       };

    BYTE* buf = new BYTE[8 * 8 * 3];    // Wasn't large enough
    int c = 0;
    for (int p = 0; p < 8; p++)
    {
        for (int j = 0, N = 7; j < 8; j++, N--)
        {
            std::bitset<4> bs;
            bs.set(0, (Bitplane0_ROW[p] >> N) & 1);
            bs.set(1, (Bitplane1_ROW[p] >> N) & 1);
            bs.set(2, (Bitplane2_ROW[p] >> N) & 1);
            bs.set(3, (Bitplane3_ROW[p] >> N) & 1);
            unsigned long Index = bs.to_ulong();

            buf[c++] = colours[Index][0];   // Blue
            buf[c++] = colours[Index][1];   // Green
            buf[c++] = colours[Index][2];   // Red
        }
    }

    std::cout << c << " bytes written" << std::endl;
    //SaveBitmapToFile((BYTE*)buf, 8, 8, 24, 0, "C:\\Users\\Chris\\Desktop\\Link_Sprite.bmp");

    delete[] buf;
    return 0;
}

^ That's awesome thanks. Much tidier code then what I had.

One question though. What is the best way of going about referencing all the possible colours? There thousands of colours. I doubt I should use an array with that many entry's. Maybe a a dynamic array or one created at run time?

Thanks.
Last edited on
https://www.colorhexa.com/color-names
https://www.color-meanings.com/list-of-colors-names-hex-codes/

Then perhaps initialise
1
2
struct { unsigned char r, g, b; } rgb;
std::map<std::string,rgb> colourmap;


You could read all your colours in from a file.
Topic archived. No new replies allowed.