Skip to content

Commit

Permalink
Fixed bugs in Texture2D.FromStream() including unit tests. (MonoGame#…
Browse files Browse the repository at this point in the history
  • Loading branch information
tomspilman authored and nkast committed Jun 26, 2018
1 parent f3f906c commit 26065fb
Show file tree
Hide file tree
Showing 7 changed files with 85 additions and 6 deletions.
7 changes: 7 additions & 0 deletions Build/Projects/MonoGame.Tests.definition
Original file line number Diff line number Diff line change
Expand Up @@ -1144,5 +1144,12 @@
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>

<Content Include="Assets\Textures\blue_0.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Assets\Textures\red_128.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>

</Files>
</Project>
16 changes: 14 additions & 2 deletions MonoGame.Framework/Graphics/Texture2D.DirectX.cs
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ private void SaveAsImage(Guid encoderId, Stream stream, int width, int height)
#endif
#if !WINDOWS_PHONE

static SharpDX.Direct3D11.Texture2D CreateTex2DFromBitmap(BitmapSource bsource, GraphicsDevice device)
static unsafe SharpDX.Direct3D11.Texture2D CreateTex2DFromBitmap(BitmapSource bsource, GraphicsDevice device)
{

Texture2DDescription desc;
Expand All @@ -313,6 +313,18 @@ static SharpDX.Direct3D11.Texture2D CreateTex2DFromBitmap(BitmapSource bsource,
{
bsource.CopyPixels(bsource.Size.Width * 4, s);

// XNA blacks out any pixels with an alpha of zero.
var data = (byte*)s.DataPointer;
for (var i = 0; i < s.Length; i+=4)
{
if (data[i + 3] == 0)
{
data[i + 0] = 0;
data[i + 1] = 0;
data[i + 2] = 0;
}
}

DataRectangle rect = new DataRectangle(s.DataPointer, bsource.Size.Width * 4);

return new SharpDX.Direct3D11.Texture2D(device._d3dDevice, desc, rect);
Expand All @@ -337,7 +349,7 @@ private static BitmapSource LoadBitmap(Stream stream, out SharpDX.WIC.BitmapDeco

fconv.Initialize(
decoder.GetFrame(0),
PixelFormat.Format32bppPRGBA,
PixelFormat.Format32bppRGBA,
BitmapDitherType.None, null,
0.0, BitmapPaletteType.Custom);

Expand Down
12 changes: 8 additions & 4 deletions MonoGame.Framework/Graphics/Texture2D.cs
Original file line number Diff line number Diff line change
Expand Up @@ -247,10 +247,14 @@ public void GetData<T> (T[] data) where T : struct
/// Creates a Texture2D from a stream, supported formats bmp, gif, jpg, png, tif and dds (only for simple textures).
/// May work with other formats, but will not work with tga files.
/// </summary>
/// <param name="graphicsDevice"></param>
/// <param name="stream"></param>
/// <returns></returns>
public static Texture2D FromStream(GraphicsDevice graphicsDevice, Stream stream)
/// <param name="graphicsDevice">The graphics device where the texture will be created.</param>
/// <param name="stream">The stream from which to read the image data.</param>
/// <returns>The <see cref="SurfaceFormat.Color"/> texture created from the image stream.</returns>
/// <remarks>Note that different image decoders may generate slight differences between platforms, but perceptually
/// the images should be identical. This call does not premultiply the image alpha, but areas of zero alpha will
/// result in black color data.
/// </remarks>
public static Texture2D FromStream(GraphicsDevice graphicsDevice, Stream stream)
{
if (graphicsDevice == null)
throw new ArgumentNullException("graphicsDevice");
Expand Down
Binary file added Test/Assets/Textures/blue_0.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Test/Assets/Textures/red_128.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
50 changes: 50 additions & 0 deletions Test/Framework/Graphics/Texture2DNonVisualTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,56 @@ public void FromStreamArgumentNullTest()
#endif
}

[TestCase]
public void FromStreamNotPremultiplied()
{
// XNA will not try to premultiply your image on
// load... this test verifies that this doesn't occur.

using (var stream = File.OpenRead("Assets/Textures/red_128.png"))
using (var texture = Texture2D.FromStream(gd, stream))
{
Assert.AreEqual(8, texture.Width);
Assert.AreEqual(8, texture.Height);
Assert.AreEqual(1, texture.LevelCount);
var pngData = new Color[8 * 8];
texture.GetData(pngData);

for (var i = 0; i < pngData.Length; i++)
{
Assert.AreEqual(255, pngData[i].R);
Assert.AreEqual(0, pngData[i].G);
Assert.AreEqual(0, pngData[i].B);
Assert.AreEqual(128, pngData[i].A);
}
}
}

[TestCase]
public void FromStreamBlackAlpha()
{
// XNA will make any pixel with an alpha value
// of 0 into black throwing out any color data.

using (var stream = File.OpenRead("Assets/Textures/blue_0.png"))
using (var texture = Texture2D.FromStream(gd, stream))
{
Assert.AreEqual(8, texture.Width);
Assert.AreEqual(8, texture.Height);
Assert.AreEqual(1, texture.LevelCount);
var pngData = new Color[8 * 8];
texture.GetData(pngData);

for (var i = 0; i < pngData.Length; i++)
{
Assert.AreEqual(0, pngData[i].R);
Assert.AreEqual(0, pngData[i].G);
Assert.AreEqual(0, pngData[i].B);
Assert.AreEqual(0, pngData[i].A);
}
}
}

[Test]
public void ZeroSizeShouldFailTest()
{
Expand Down
6 changes: 6 additions & 0 deletions Test/MonoGame.Tests.XNA.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -622,6 +622,9 @@
<Content Include="Assets\tests.xsl">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Assets\Textures\blue_0.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Assets\Textures\lines-128.xnb">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
Expand Down Expand Up @@ -661,6 +664,9 @@
<Content Include="Assets\Textures\LogoOnly_64px.tif">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Assets\Textures\red_128.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="Assets\Textures\SampleCube64DXT1Mips.dds">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
Expand Down

0 comments on commit 26065fb

Please sign in to comment.