Texture2D.FromSteam: strange behaviour when loading png

Hi,
today I found something that seems to be a bug in XNA and Monogame.

I tried to load this png image using Texture2D.FromStream. Using XNA this resulted in a strange color bugs. E.g. pixel (381,631) which has rgba(14,9,7,23) in the png had rgba(11,11,11,23) in the texture. I tried Monogame’s OpenGL Windows implementation and got the same results.

After looking deeper into this i found that there seems to be a problem in the ImageEx.RGBToBGR method. I have no idea why, but not using RGBToBGR and instead exchanging red and blue manually in the data-array (Texture2D.OpenGL.cs line #348) did the trick.

Here is my workaround. Starting line #330 in Texture2D.OpenGL.cs:

#if WINDOWS || LINUX || ANGLE
Bitmap image = (Bitmap)Bitmap.FromStream(stream);
try
{
    // Fix up the Image to match the expected format
    image = (Bitmap)image.RGBToBGR();
    var data = new byte[image.Width * image.Height * 4];
    BitmapData bitmapData = image.LockBits(new System.Drawing.Rectangle(0, 0, image.Width, image.Height),
    ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
    if (bitmapData.Stride != image.Width * 4)
    throw new NotImplementedException();
    Marshal.Copy(bitmapData.Scan0, data, 0, data.Length);
    image.UnlockBits(bitmapData);
    Texture2D texture = null;
    texture = new Texture2D(graphicsDevice, image.Width, image.Height);
    for (int i = 0; i < data.Length; i+=4)
    {
        byte temp = data[i+0];
        data[i + 0] = data[i + 2];
        data[i + 2] = temp;
    }
    texture.SetData(data);
    return texture;
}
finally
{
    image.Dispose();
}
#endif 

Cheers, Martin

Could you please post this to GitHub so it doesn’t get lost?

A pull request would be best with the fix in it.

Done: https://github.com/mono/MonoGame/issues/3107
I’m not sure if my workaround is an acceptable solution to this problem, so I didn’t create a pull request.