Show More
Commit Description:
Various UI improvements.
Commit Description:
Various UI improvements.
References:
File last commit:
Show/Diff file:
Action:
FNA/src/Graphics/X360TexUtil.cs
184 lines | 5.4 KiB | text/x-csharp | CSharpLexer
184 lines | 5.4 KiB | text/x-csharp | CSharpLexer
r0 | #region License | |||
/* FNA - XNA4 Reimplementation for Desktop Platforms | ||||
* Copyright 2009-2020 Ethan Lee and the MonoGame Team | ||||
* | ||||
* Released under the Microsoft Public License. | ||||
* See LICENSE for details. | ||||
*/ | ||||
#endregion | ||||
#region Using Statements | ||||
using System.IO; | ||||
#endregion | ||||
namespace Microsoft.Xna.Framework.Graphics | ||||
{ | ||||
internal static class X360TexUtil | ||||
{ | ||||
#region Internal Static Methods | ||||
internal static byte[] SwapColor(byte[] imageData) | ||||
{ | ||||
using (MemoryStream imageStream = new MemoryStream(imageData)) | ||||
{ | ||||
return SwapColor(imageStream, imageData.Length); | ||||
} | ||||
} | ||||
internal static byte[] SwapColor(Stream imageStream, int imageLength) | ||||
{ | ||||
byte[] imageData = new byte[imageLength]; | ||||
using (BinaryReader imageReader = new BinaryReader(imageStream)) | ||||
{ | ||||
for (int i = 0; i < imageLength; i += sizeof(uint)) | ||||
{ | ||||
uint data = imageReader.ReadUInt32(); | ||||
imageData[i + 0] = (byte) ((data >> 24) & 0xFF); | ||||
imageData[i + 1] = (byte) ((data >> 16) & 0xFF); | ||||
imageData[i + 2] = (byte) ((data >> 8) & 0xFF); | ||||
imageData[i + 3] = (byte) ((data >> 0) & 0xFF); | ||||
} | ||||
} | ||||
return imageData; | ||||
} | ||||
internal static byte[] SwapDxt1(byte[] imageData, int width, int height) | ||||
{ | ||||
using (MemoryStream imageStream = new MemoryStream(imageData)) | ||||
{ | ||||
return SwapDxt1(imageStream, imageData.Length, width, height); | ||||
} | ||||
} | ||||
internal static byte[] SwapDxt1(Stream imageStream, int imageLength, int width, int height) | ||||
{ | ||||
byte[] imageData = new byte[imageLength]; | ||||
using (MemoryStream imageDataStream = new MemoryStream(imageData)) | ||||
using (BinaryWriter imageWriter = new BinaryWriter(imageDataStream)) | ||||
using (BinaryReader imageReader = new BinaryReader(imageStream)) | ||||
{ | ||||
int blockCountX = (width + 3) / 4; | ||||
int blockCountY = (height + 3) / 4; | ||||
for (int y = 0; y < blockCountY; y++) | ||||
{ | ||||
for (int x = 0; x < blockCountX; x++) | ||||
{ | ||||
SwapDxt1Block(imageReader, imageWriter); | ||||
} | ||||
} | ||||
} | ||||
return imageData; | ||||
} | ||||
internal static byte[] SwapDxt3(byte[] imageData, int width, int height) | ||||
{ | ||||
using (MemoryStream imageStream = new MemoryStream(imageData)) | ||||
{ | ||||
return SwapDxt3(imageStream, imageData.Length, width, height); | ||||
} | ||||
} | ||||
internal static byte[] SwapDxt3(Stream imageStream, int imageLength, int width, int height) | ||||
{ | ||||
byte[] imageData = new byte[imageLength]; | ||||
using (MemoryStream imageDataStream = new MemoryStream(imageData)) | ||||
using (BinaryWriter imageWriter = new BinaryWriter(imageDataStream)) | ||||
using (BinaryReader imageReader = new BinaryReader(imageStream)) | ||||
{ | ||||
int blockCountX = (width + 3) / 4; | ||||
int blockCountY = (height + 3) / 4; | ||||
for (int y = 0; y < blockCountY; y++) | ||||
{ | ||||
for (int x = 0; x < blockCountX; x++) | ||||
{ | ||||
SwapDxt3Block(imageReader, imageWriter); | ||||
} | ||||
} | ||||
} | ||||
return imageData; | ||||
} | ||||
internal static byte[] SwapDxt5(byte[] imageData, int width, int height) | ||||
{ | ||||
using (MemoryStream imageStream = new MemoryStream(imageData)) | ||||
{ | ||||
return SwapDxt5(imageStream, imageData.Length, width, height); | ||||
} | ||||
} | ||||
internal static byte[] SwapDxt5(Stream imageStream, int imageLength, int width, int height) | ||||
{ | ||||
byte[] imageData = new byte[imageLength]; | ||||
using (MemoryStream imageDataStream = new MemoryStream(imageData)) | ||||
using (BinaryWriter imageWriter = new BinaryWriter(imageDataStream)) | ||||
using (BinaryReader imageReader = new BinaryReader(imageStream)) | ||||
{ | ||||
int blockCountX = (width + 3) / 4; | ||||
int blockCountY = (height + 3) / 4; | ||||
for (int y = 0; y < blockCountY; y++) | ||||
{ | ||||
for (int x = 0; x < blockCountX; x++) | ||||
{ | ||||
SwapDxt5Block(imageReader, imageWriter); | ||||
} | ||||
} | ||||
} | ||||
return imageData; | ||||
} | ||||
#endregion | ||||
#region Private Static Methods | ||||
public static ushort SwapEndian(ushort data) | ||||
{ | ||||
return (ushort) ( | ||||
((ushort) ((data & 0xFF) << 8)) | | ||||
((ushort) ((data >> 8) & 0xFF)) | ||||
); | ||||
} | ||||
private static void SwapDxt1Block(BinaryReader imageReader, BinaryWriter imageWriter) | ||||
{ | ||||
// Fix the following two big-endian words to litte-endian words. | ||||
imageWriter.Write(SwapEndian(imageReader.ReadUInt16())); | ||||
imageWriter.Write(SwapEndian(imageReader.ReadUInt16())); | ||||
// Two words / 16 bit values instead of a 4 byte / 32 bit table. | ||||
imageWriter.Write(SwapEndian(imageReader.ReadUInt16())); | ||||
imageWriter.Write(SwapEndian(imageReader.ReadUInt16())); | ||||
} | ||||
private static void SwapDxt3Block(BinaryReader imageReader, BinaryWriter imageWriter) | ||||
{ | ||||
// Alpha data. 16 4-bit values, but written to / read from as 4 16-bit values. | ||||
// Somehow, that one test game I had worked just fine with this unchanged... -ade | ||||
imageWriter.Write(SwapEndian(imageReader.ReadUInt16())); | ||||
imageWriter.Write(SwapEndian(imageReader.ReadUInt16())); | ||||
imageWriter.Write(SwapEndian(imageReader.ReadUInt16())); | ||||
imageWriter.Write(SwapEndian(imageReader.ReadUInt16())); | ||||
SwapDxt1Block(imageReader, imageWriter); | ||||
} | ||||
private static void SwapDxt5Block(BinaryReader imageReader, BinaryWriter imageWriter) | ||||
{ | ||||
// Alpha minimum and maximum. Two bytes, but handled internally as one word. | ||||
imageWriter.Write(SwapEndian(imageReader.ReadUInt16())); | ||||
// Alpha indices. 16 3-bit values, but written to / read from as 3 16-bit values. | ||||
imageWriter.Write(SwapEndian(imageReader.ReadUInt16())); | ||||
imageWriter.Write(SwapEndian(imageReader.ReadUInt16())); | ||||
imageWriter.Write(SwapEndian(imageReader.ReadUInt16())); | ||||
SwapDxt1Block(imageReader, imageWriter); | ||||
} | ||||
#endregion | ||||
} | ||||
} | ||||