Skip to content

Commit

Permalink
Add TGA and DDS sprite loaders.
Browse files Browse the repository at this point in the history
  • Loading branch information
pchote authored and reaperrr committed Jan 16, 2021
1 parent 765944c commit f341c9a
Show file tree
Hide file tree
Showing 4 changed files with 186 additions and 0 deletions.
3 changes: 3 additions & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,9 @@ distributed under MIT License.

Using ANGLE distributed under the BS3 3-Clause license.

Using Pfim developed by Nick Babcock
distributed under the MIT license.

This site or product includes IP2Location LITE data
available from http://www.ip2location.com.

Expand Down
1 change: 1 addition & 0 deletions OpenRA.Mods.Common/OpenRA.Mods.Common.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
<PackageReference Include="OpenRA-FuzzyLogicLibrary" Version="1.0.1" />
<PackageReference Include="DiscordRichPresence" Version="1.0.150" />
<PackageReference Include="rix0rrr.BeaconLib" Version="1.0.2" />
<PackageReference Include="Pfim" Version="0.9.1" />
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118" />
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.0" PrivateAssets="All" />
<AdditionalFiles Include="../stylecop.json" />
Expand Down
80 changes: 80 additions & 0 deletions OpenRA.Mods.Common/SpriteLoaders/DdsLoader.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
#region Copyright & License Information
/*
* Copyright 2007-2020 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version. For more
* information, see COPYING.
*/
#endregion

using System.IO;
using System.Linq;
using OpenRA.Graphics;
using OpenRA.Primitives;
using Pfim;

namespace OpenRA.Mods.Common.SpriteLoaders
{
public class DdsLoader : ISpriteLoader
{
public static bool IsDds(Stream s)
{
var start = s.Position;
var isDds = s.ReadUInt32() == 0x20534444;
s.Position = start;

return isDds;
}

public bool TryParseSprite(Stream s, out ISpriteFrame[] frames, out TypeDictionary metadata)
{
metadata = null;
if (!IsDds(s))
{
frames = null;
return false;
}

frames = new DdsSprite(s).Frames.ToArray();
return true;
}
}

public class DdsSprite
{
class DdsFrame : ISpriteFrame
{
public SpriteFrameType Type { get; private set; }
public Size Size { get; private set; }
public Size FrameSize { get { return Size; } }
public float2 Offset { get { return float2.Zero; } }
public byte[] Data { get; private set; }
public bool DisableExportPadding { get { return false; } }

public DdsFrame(Stream stream)
{
using (var dds = Dds.Create(stream, new PfimConfig()))
{
Size = new Size(dds.Width, dds.Height);
Data = dds.Data;
switch (dds.Format)
{
// SpriteFrameType refers to the channel byte order, which is reversed from the little-endian bit order
case ImageFormat.Rgba32: Type = SpriteFrameType.Bgra32; break;
case ImageFormat.Rgb24: Type = SpriteFrameType.Bgr24; break;
default: throw new InvalidDataException("Unhandled ImageFormat {0}".F(dds.Format));
}
}
}
}

public IReadOnlyList<ISpriteFrame> Frames { get; private set; }

public DdsSprite(Stream stream)
{
Frames = new ISpriteFrame[] { new DdsFrame(stream) }.AsReadOnly();
}
}
}
102 changes: 102 additions & 0 deletions OpenRA.Mods.Common/SpriteLoaders/TgaLoader.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
#region Copyright & License Information
/*
* Copyright 2007-2020 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version. For more
* information, see COPYING.
*/
#endregion

using System.IO;
using System.Linq;
using OpenRA.Graphics;
using OpenRA.Primitives;
using Pfim;

namespace OpenRA.Mods.Common.SpriteLoaders
{
public class TgaLoader : ISpriteLoader
{
public static bool IsTga(Stream s)
{
var start = s.Position;
try
{
// Require true-color images
s.Position += 1;
var colorMapType = s.ReadUInt8();
if (colorMapType != 0)
return false;

var imageType = s.ReadUInt8();
if (imageType != 2)
return false;

var colorMapOffsetAndSize = s.ReadUInt32();
if (colorMapOffsetAndSize != 0)
return false;

var colorMapBits = s.ReadUInt8();
if (colorMapBits != 0)
return false;

return true;
}
finally
{
s.Position = start;
}
}

public bool TryParseSprite(Stream s, out ISpriteFrame[] frames, out TypeDictionary metadata)
{
metadata = null;
if (!IsTga(s))
{
frames = null;
return false;
}

frames = new TgaSprite(s).Frames.ToArray();
return true;
}
}

public class TgaSprite
{
public class TgaFrame : ISpriteFrame
{
public SpriteFrameType Type { get; private set; }
public Size Size { get; private set; }
public Size FrameSize { get; private set; }
public float2 Offset { get; private set; }
public byte[] Data { get; private set; }
public bool DisableExportPadding { get { return false; } }

public TgaFrame(Stream stream)
{
using (var tga = Targa.Create(stream, new PfimConfig()))
{
Size = FrameSize = new Size(tga.Width, tga.Height);
Data = tga.Data;
switch (tga.Format)
{
// SpriteFrameType refers to the channel byte order, which is reversed from the little-endian bit order
case ImageFormat.Rgba32: Type = SpriteFrameType.Bgra32; break;
case ImageFormat.Rgb24: Type = SpriteFrameType.Bgr24; break;
default: throw new InvalidDataException("Unhandled ImageFormat {0}".F(tga.Format));
}
}
}
}

public IReadOnlyList<ISpriteFrame> Frames { get; private set; }

public TgaSprite(Stream stream)
{
Frames = new ISpriteFrame[] { new TgaFrame(stream) }.AsReadOnly();
}
}
}

0 comments on commit f341c9a

Please sign in to comment.