2019-08-01 23:47:35 +02:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
|
|
|
|
namespace Toolbox.Library
|
|
|
|
|
{
|
|
|
|
|
public class RGBAPixelDecoder
|
|
|
|
|
{
|
2019-09-19 00:23:27 +02:00
|
|
|
|
private static byte[] GetComponentsFromPixel(TEX_FORMAT format, int pixel, byte[] comp)
|
2019-08-01 23:47:35 +02:00
|
|
|
|
{
|
|
|
|
|
switch (format)
|
|
|
|
|
{
|
|
|
|
|
case TEX_FORMAT.L8:
|
2019-09-19 00:23:27 +02:00
|
|
|
|
comp[0] = (byte)(pixel & 0xFF);
|
2019-08-01 23:47:35 +02:00
|
|
|
|
break;
|
|
|
|
|
case TEX_FORMAT.LA8:
|
2019-09-19 00:23:27 +02:00
|
|
|
|
comp[0] = (byte)(pixel & 0xFF);
|
|
|
|
|
comp[1] = (byte)((pixel & 0xFF00) >> 8);
|
|
|
|
|
break;
|
|
|
|
|
case TEX_FORMAT.LA4:
|
|
|
|
|
comp[0] = (byte)((pixel & 0xF) * 17);
|
|
|
|
|
comp[1] = (byte)(((pixel & 0xF0) >> 4) * 17);
|
2019-08-01 23:47:35 +02:00
|
|
|
|
break;
|
|
|
|
|
case TEX_FORMAT.R5G5B5_UNORM:
|
2019-09-19 00:23:27 +02:00
|
|
|
|
comp[0] = (byte)((pixel & 0x1F) / 0x1F * 0xFF);
|
|
|
|
|
comp[1] = (byte)(((pixel & 0x7E0) >> 5) / 0x3F * 0xFF);
|
|
|
|
|
comp[2] = (byte)(((pixel & 0xF800) >> 11) / 0x1F * 0xFF);
|
2019-08-01 23:47:35 +02:00
|
|
|
|
break;
|
|
|
|
|
case TEX_FORMAT.B5G6R5_UNORM:
|
2019-09-19 00:23:27 +02:00
|
|
|
|
comp[0] = (byte)(((pixel & 0xF800) >> 11) / 0x1F * 0xFF);
|
|
|
|
|
comp[1] = (byte)(((pixel & 0x7E0) >> 5) / 0x3F * 0xFF);
|
|
|
|
|
comp[2] = (byte)((pixel & 0x1F) / 0x1F * 0xFF);
|
2019-08-01 23:47:35 +02:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return comp;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//Method from https://github.com/aboood40091/BNTX-Editor/blob/master/formConv.py
|
|
|
|
|
public static byte[] Decode(byte[] data, int width, int height, TEX_FORMAT format)
|
|
|
|
|
{
|
|
|
|
|
uint bpp = STGenericTexture.GetBytesPerPixel(format);
|
|
|
|
|
int size = width * height * 4;
|
|
|
|
|
|
2019-08-29 21:45:32 +02:00
|
|
|
|
bpp = (uint)(data.Length / (width * height));
|
|
|
|
|
|
2019-08-01 23:47:35 +02:00
|
|
|
|
byte[] output = new byte[size];
|
|
|
|
|
|
|
|
|
|
int inPos = 0;
|
|
|
|
|
int outPos = 0;
|
|
|
|
|
|
2019-09-19 00:23:27 +02:00
|
|
|
|
byte[] comp = new byte[] { 0, 0, 0, 0xFF, 0, 0xFF };
|
2019-08-01 23:47:35 +02:00
|
|
|
|
byte[] compSel = new byte[4] {0,1,2,3 };
|
|
|
|
|
|
2019-09-19 00:23:27 +02:00
|
|
|
|
if (format == TEX_FORMAT.LA8)
|
|
|
|
|
{
|
|
|
|
|
compSel = new byte[4] { 0, 0, 0, 1 };
|
|
|
|
|
bpp = 2;
|
|
|
|
|
}
|
|
|
|
|
else if (format == TEX_FORMAT.L8)
|
|
|
|
|
compSel = new byte[4] { 0, 0, 0, 5 };
|
2019-08-29 21:45:32 +02:00
|
|
|
|
|
2019-08-01 23:47:35 +02:00
|
|
|
|
for (int Y = 0; Y < height; Y++)
|
|
|
|
|
{
|
|
|
|
|
for (int X = 0; X < width; X++)
|
|
|
|
|
{
|
|
|
|
|
inPos = (Y * width + X) * (int)bpp;
|
|
|
|
|
outPos = (Y * width + X) * 4;
|
|
|
|
|
|
|
|
|
|
int pixel = 0;
|
|
|
|
|
for (int i = 0; i < bpp; i++)
|
|
|
|
|
pixel |= data[inPos + i] << (8 * i);
|
|
|
|
|
|
2019-09-19 00:23:27 +02:00
|
|
|
|
comp = GetComponentsFromPixel(format, pixel, comp);
|
2019-08-01 23:47:35 +02:00
|
|
|
|
|
|
|
|
|
output[outPos + 3] = comp[compSel[3]];
|
2019-09-08 21:15:42 +02:00
|
|
|
|
output[outPos + 2] = comp[compSel[2]];
|
2019-08-01 23:47:35 +02:00
|
|
|
|
output[outPos + 1] = comp[compSel[1]];
|
2019-09-08 21:15:42 +02:00
|
|
|
|
output[outPos + 0] = comp[compSel[0]];
|
2019-08-01 23:47:35 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return output;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|