Skip to content

Commit

Permalink
fixed/cleaned up Xbox image parsing (#308)
Browse files Browse the repository at this point in the history
* add hopo_threshold support to please jnack

* fix DXT3 image byte parsing

* DXT3 loop cleanup

* hopo threshold fix

* actually reference hopo_threshold this time

* small RB fixes

* Update Credits.txt

* cleaned up DXT block parsing for xbox images

* move Texture2D declaration

---------

Co-authored-by: EliteAsian <lavasnakegaming@gmail.com>
  • Loading branch information
rjkiv and EliteAsian123 authored May 12, 2023
1 parent 8058f94 commit e6c317f
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 30 deletions.
3 changes: 3 additions & 0 deletions Assets/Credits.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ EscapeNumber001
grishhung
jtanan44
NevesPT
Pixelated_Pope
NyxTheShield
JayDiddyThaGOAT

<u><b>Lead-Artists</b></u>

Expand Down
40 changes: 10 additions & 30 deletions Assets/Script/Serialization/Xbox/XboxImageGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,47 +11,27 @@ public static class XboxImageTextureGenerator {
public static async UniTask<Texture2D> GetTexture(byte[] xboxImageBytes, CancellationToken ct) {
var ms = new MemoryStream(xboxImageBytes);

// Parse header
// Parse header and get DXT blocks
byte[] header = ms.ReadBytes(32);
byte BitsPerPixel = header[1];
int Format = BitConverter.ToInt32(header, 2);
short Width = BitConverter.ToInt16(header, 7);
short Height = BitConverter.ToInt16(header, 9);
byte[] DXTBlocks = null;
bool isDXT1 = ((BitsPerPixel == 0x04) && (Format == 0x08));
ms.Seek(32, SeekOrigin.Begin);
byte[] DXTBlocks = ms.ReadBytes((int) (ms.Length - 32));

ct.ThrowIfCancellationRequested();

await UniTask.RunOnThreadPool(() => {
// Parse DXT-compressed blocks, depending on format
if ((BitsPerPixel == 0x04) && (Format == 0x08)) {
// If DXT-1 format already, read the bytes straight up
ms.Seek(32, SeekOrigin.Begin);
DXTBlocks = ms.ReadBytes((int) (ms.Length - 32));
} else {
// If DXT-3 format, we have to omit the alpha bytes
var extractedDXT3 = new List<byte>();
ms.ReadBytes(8); //skip the first 8 alpha bytes
for (int i = 8; i < (ms.Length - 32) / 2; i += 8) {
ct.ThrowIfCancellationRequested();

extractedDXT3.AddRange(ms.ReadBytes(8)); // We want to read these 8 bytes
ms.ReadBytes(8); // and skip these 8 bytes
}
DXTBlocks = extractedDXT3.ToArray();
}

// Swap bytes because xbox is weird like that
for (int i = 0; i < DXTBlocks.Length / 2; i++) {
ct.ThrowIfCancellationRequested();

(DXTBlocks[i * 2], DXTBlocks[i * 2 + 1]) = (DXTBlocks[i * 2 + 1], DXTBlocks[i * 2]);
}
});
// Swap bytes because xbox is weird like that
for (int i = 0; i < DXTBlocks.Length / 2; i++) {
(DXTBlocks[i * 2], DXTBlocks[i * 2 + 1]) = (DXTBlocks[i * 2 + 1], DXTBlocks[i * 2]);
}

ct.ThrowIfCancellationRequested();

// apply DXT1 formatted bytes to a Texture2D
var tex = new Texture2D(Width, Height, GraphicsFormat.RGBA_DXT1_SRGB, TextureCreationFlags.None);
// apply DXT1 OR DXT5 formatted bytes to a Texture2D
var tex = new Texture2D(Width, Height, (isDXT1) ? GraphicsFormat.RGBA_DXT1_SRGB : GraphicsFormat.RGBA_DXT5_SRGB, TextureCreationFlags.None);
tex.LoadRawTextureData(DXTBlocks);
tex.Apply();

Expand Down

0 comments on commit e6c317f

Please sign in to comment.