Inverted Red and blue in Intermediate T10

The Partridge Family were neither partridges nor a family. Discuss.
Post Reply
yangming
Posts: 3
Joined: November 7th, 2019, 7:06 pm

Inverted Red and blue in Intermediate T10

Post by yangming » November 26th, 2019, 12:50 am

Hi all,

I recently got to the Intermediate series in tutorial 10. And There is one HUGE problem that is really bugging me.

If you look at 22:55 in tutorial 10: https://www.youtube.com/watch?v=0z3uCzi ... Z&index=21.

In "Surface.cpp" line 31, Chilli wrote " PutPixel( x,y,Color( file.get(),file.get(),file.get() ) ); " and it all worked fine.

But then I had to try a different way:
PutPixel(x, y, {unsigned char(file.get()), unsigned char(file.get()), unsigned char(file.get()) });

Then things started happening, every BMP file I loaded gave me Red and Blue inverted image. I spent a few hours trying to get any clue but failed.

Please, can someone help me with this? I used chilli's original code from this https://github.com/planetchili/sprite and created a branch from I11-End. It should be easy to replicate my failure since its' only change of one line of code.

I've also tried a few other ways but it seems only the way chilli writes works.
Attachments
1574730585(1)_LI.jpg
Chilli's code
(1.61 MiB) Not downloaded yet
1574730324(1).png
color inverted image
1574730324(1).png (1.49 KiB) Viewed 1981 times

yangming
Posts: 3
Joined: November 7th, 2019, 7:06 pm

Re: Inverted Red and blue in Intermediate T10

Post by yangming » November 26th, 2019, 2:17 am

Ok, After spending some more time on this, I have some progress.

From wiki, BMP file is order Blue, Green and then Red. https://en.wikipedia.org/wiki/BMP_file_format.
Don't know if it's reliable, but it matches my findings.

Then I tried using '()' instead of '{}' :
PutPixel(x, y, (unsigned char(file.get()), unsigned char(file.get()), unsigned char(file.get()) ));
which gives me the correct colored image.

However, I still don't know why this is happening. It seems with bracket(), "file.get()" would read the file in reverse order, and with curly bracket{}, it reads the file in the right order.

yangming
Posts: 3
Joined: November 7th, 2019, 7:06 pm

Re: Inverted Red and blue in Intermediate T10

Post by yangming » November 26th, 2019, 2:42 am

OK, I think I got it. Thanks to this page: https://en.cppreference.com/w/cpp/language/eval_order

The main reason that () and {} give different results is that () function calls may not take the order from the left to right.

In Chilli's code:
PutPixel( x,y,Color( file.get(),file.get(),file.get() ) );

There's no guarantee that the first "file.get()" would get the first byte in the 3-byte color in the 24-bit file.
And in fact, if it does, it should read the "Blue" byte since the BMP file has the order of BGR instead of RGB.

In this case, the compiler prefers to evaluate the third "file.get()" first and giving it the value of the "Blue" byte, and then the second "file.get()" gets the value of the "Green" byte, and then first "file.get()" gets the value of the "Red" byte. Therefore Color has (Red, Green, blue) in that order.

Man does it feel good to work this out.

albinopapa
Posts: 4373
Joined: February 28th, 2013, 3:23 am
Location: Oklahoma, United States

Re: Inverted Red and blue in Intermediate T10

Post by albinopapa » November 26th, 2019, 3:53 am

Wow, not sure I would have caught that, great job.
If you think paging some data from disk into RAM is slow, try paging it into a simian cerebrum over a pair of optical nerves. - gameprogrammingpatterns.com

albinopapa
Posts: 4373
Joined: February 28th, 2013, 3:23 am
Location: Oklahoma, United States

Re: Inverted Red and blue in Intermediate T10

Post by albinopapa » November 27th, 2019, 7:34 pm

To avoid confusion, I suppose it would be a better option to just have each file.get() be assigned to temporary variables in the first place, then passed to the Color constructor:

unsigned char b = file.get();
unsigned char g = file.get();
unsigned char r = file.get();
PutPixel( x, y, Color( r, g, b ) );

This works no matter what since r,g,b aren't function calls that get the next byte from a file.
If you think paging some data from disk into RAM is slow, try paging it into a simian cerebrum over a pair of optical nerves. - gameprogrammingpatterns.com

Post Reply