Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BGR bitmap swapped red and blue channels #4918

Closed
Jjagg opened this issue Jun 10, 2016 · 21 comments
Closed

BGR bitmap swapped red and blue channels #4918

Jjagg opened this issue Jun 10, 2016 · 21 comments

Comments

@Jjagg
Copy link
Contributor

Jjagg commented Jun 10, 2016

I wanted to set up a little sandbox project to mess around in, and tried to load and draw the Icon bitmap that comes with the template. The result is this
image
Opening in a text editor, I see BGR in front so I guess that's the format it's in, but it's interpreted by MG as RGB. I set the textureformat in the pipeline tool to color, since that only seems to say something about compression, it doesn't imply RGBA, right? After debugging a bit I found out FreeImage gets the channel masks as

R: 11111111 00000000 00000000, G: 00000000 11111111 00000000, B: 00000000 00000000 11111111

Now that's wrong right? Shouldn't this figure out the right masks based on the header? @KonajuGames

@KonajuGames
Copy link
Contributor

Which template? DesktopGL? I'll have to test that.

@Jjagg
Copy link
Contributor Author

Jjagg commented Jun 10, 2016

Jep

@mrhelmut
Copy link
Contributor

mrhelmut commented Jun 10, 2016

The Icon BMP in the DesktopGL template is a 32bit BMP, ARGB coded. It's not a standard 24bit BMP. It has to be like this for the icon to be loaded with transparency.

@Jjagg
Copy link
Contributor Author

Jjagg commented Jun 10, 2016

Yes, it is 32 bit, but I left out the alpha channel. I'm pretty sure it's ABGR though, checking the values in the debugger shows higher values in the third channel than the first, also opening in a text editor shows BGR somewhere at the start.

@mrhelmut
Copy link
Contributor

Verified to be BGRA.

@Jjagg
Copy link
Contributor Author

Jjagg commented Jun 10, 2016

Thanks! That means this is a bug in FreeImage right?

@mrhelmut
Copy link
Contributor

mrhelmut commented Jun 10, 2016

I don't know, this kind of BMP doesn't look to be super standard, maybe the header of this file are not correct/standard. We'll have to test with more 32bit BMP (both "X8R8G8B8" and "A8R8G8B8"). I would be surprised that FreeImage doesn't support the full spec.

@tomspilman tomspilman added this to the 3.7 Release milestone Jun 10, 2016
@Jjagg
Copy link
Contributor Author

Jjagg commented Jun 10, 2016

The thumbnail in VS displays the correct image though, as do Windows Photos and Microsoft Paint

@Tzenchor
Copy link
Contributor

If I remember the code correctly, the channels are swapped always for 32bits bitmaps.
Try with any icon from the test assets, if it is shown correctly TextureImporter is treating every bitmap as RGBA

@KonajuGames
Copy link
Contributor

KonajuGames commented Jun 10, 2016 via email

@Tzenchor
Copy link
Contributor

I have just run a little test on the mentioned bmp and compared its raw data with the one of the logos in the test assets.
The conclusion is that the problem lays inside FreeImage. The test texture brown area is BGRA={0, 60, 231, 255} while the icon bitmap is BGRA={255, 0 ,60 ,231}, all this after format conversion and with the channel swapping disabled. This means that the channels are shifted, but FreeImage does not recognize the difference between ABGR and BGRA formats

@Tzenchor
Copy link
Contributor

I'm thinking that FreeImage reads the file header as BITMAPV2INFOHEADER or BITMAPV3INFOHEADER while the file uses BITMAPV5INFOHEADER (headers can be seen here, note that v2 and v3 are undocumented, while v4 and v5 can be found at msdn, a fast overview can be seen in the following link, concretelly in this image)

@mrhelmut
Copy link
Contributor

That would make sense, v4/v5 are Microsoft only, I believe. It could be a design choice. Maybe we only have to check v4/v5 headers and manually sort the channels.

@tomspilman
Copy link
Member

@KonajuGames - Did this get fixed?

@KonajuGames
Copy link
Contributor

KonajuGames commented Feb 21, 2018 via email

@KonajuGames
Copy link
Contributor

I've now confirmed that FreeImage does not support higher than BITMAPINFOHEADER. What's worse is that you can request the bitmap info header, and FreeImage has modified the biSize parameter to 0x28, replacing the 0x7c that is in the file, and it actively ignores the channel masks that are in the file. This makes it impossible to use FreeImage for this case.

My approach now will be to fix the conflict in #6008, then use StbSharp to load BMP, PNG, JPG and GIF in the content pipeline as well as Texture2D.FromStream(). This leaves FreeImage to load the more obscure and little used image formats.

@harry-cpp
Copy link
Member

Wouldn't it be better to use something that is being actively developed and maintained, like ImageSharp, for the Content Pipeline?

@tomspilman
Copy link
Member

Wouldn't it be better

No... at least not today. Enter a new issue if we want to discuss something for the future.

@KonajuGames
Copy link
Contributor

I took a look at ImageSharp code. It does not support anything beyond BITMAPINFOHEADER either, same as FreeType. StbSharp does support V5.

@KonajuGames
Copy link
Contributor

I've got StbSharp in the TextureImporter now, and it loads the V5 BMP fine. It does not however support 1-bit monochrome BMP, which we have a unit test for, but I'm certain that no-one has ever used. 1-bit monochrome BMPs may have been used a bit in the late 80's and early 90's, but I'm of the opinion that we can drop support for them now.

KonajuGames pushed a commit to KonajuGames/MonoGame that referenced this issue Feb 27, 2018
FreeImage fails to import BMP V4 or V5 files.  StbSharp does import them correctly, so .bmp files are imported using StbSharp.  DDS is still imported using a specific loader, and the remainder are still loaded with FreeImage for now.

StbSharp does not support 1-bit BMP files, and since these files haven't really been seen since the early 90's I don't think it is a great loss to remove that support.

Fixes MonoGame#4918
@KonajuGames
Copy link
Contributor

PR #6218 has been submitted to fix this.

dellis1972 pushed a commit that referenced this issue Mar 1, 2018
FreeImage fails to import BMP V4 or V5 files.  StbSharp does import them correctly, so .bmp files are imported using StbSharp.  DDS is still imported using a specific loader, and the remainder are still loaded with FreeImage for now.

StbSharp does not support 1-bit BMP files, and since these files haven't really been seen since the early 90's I don't think it is a great loss to remove that support.

Fixes #4918
nkast pushed a commit to nkast/MonoGame that referenced this issue May 6, 2018
FreeImage fails to import BMP V4 or V5 files.  StbSharp does import them correctly, so .bmp files are imported using StbSharp.  DDS is still imported using a specific loader, and the remainder are still loaded with FreeImage for now.

StbSharp does not support 1-bit BMP files, and since these files haven't really been seen since the early 90's I don't think it is a great loss to remove that support.

Fixes MonoGame#4918
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants