mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/PCK-Studio.git
synced 2026-07-07 14:58:18 +00:00
111 lines
4.1 KiB
C#
111 lines
4.1 KiB
C#
using Ohana3DS_Rebirth.Ohana;
|
|
using System;
|
|
using System.Drawing;
|
|
using System.IO;
|
|
using System.Text;
|
|
|
|
namespace PckStudio.Classes.Utils
|
|
{
|
|
internal class _3DSUtil
|
|
{
|
|
private static string ReadString(Stream stream, int len)
|
|
{
|
|
byte[] buffer = new byte[len];
|
|
stream.Read(buffer, 0, len);
|
|
return Encoding.ASCII.GetString(buffer);
|
|
}
|
|
|
|
private static int ReadInt32(Stream stream)
|
|
{
|
|
byte[] buffer = new byte[4];
|
|
stream.Read(buffer, 0, 4);
|
|
return BitConverter.ToInt32(buffer, 0);
|
|
}
|
|
|
|
private static void WriteString(Stream stream, string s)
|
|
{
|
|
byte[] buffer = Encoding.ASCII.GetBytes(s);
|
|
stream.Write(buffer, 0, buffer.Length);
|
|
}
|
|
|
|
private static void WriteInt32(Stream stream, int value)
|
|
{
|
|
byte[] buffer = BitConverter.GetBytes(value);
|
|
stream.Write(buffer, 0, 4);
|
|
}
|
|
|
|
public static int CalcBufferSize(RenderBase.OTextureFormat fmt, int w, int h)
|
|
{
|
|
switch (fmt)
|
|
{
|
|
case RenderBase.OTextureFormat.argb8:
|
|
return w * h * 4;
|
|
case RenderBase.OTextureFormat.rgb8:
|
|
return w * h * 3;
|
|
case RenderBase.OTextureFormat.rgba5551:
|
|
case RenderBase.OTextureFormat.rgb565:
|
|
case RenderBase.OTextureFormat.rgba4:
|
|
case RenderBase.OTextureFormat.la8:
|
|
case RenderBase.OTextureFormat.hilo8:
|
|
return w * h * 2;
|
|
case RenderBase.OTextureFormat.l8:
|
|
case RenderBase.OTextureFormat.a8:
|
|
case RenderBase.OTextureFormat.la4:
|
|
case RenderBase.OTextureFormat.etc1a4:
|
|
return w * h;
|
|
case RenderBase.OTextureFormat.l4:
|
|
case RenderBase.OTextureFormat.a4:
|
|
case RenderBase.OTextureFormat.etc1:
|
|
return w * h >> 1;
|
|
default:
|
|
throw new InvalidDataException("Invalid texture format on BCH!");
|
|
}
|
|
}
|
|
|
|
public static Image GetImageFrom3DST(Stream stream)
|
|
{
|
|
if (ReadString(stream, 4) == "3DST")
|
|
{
|
|
const int offset = 32;
|
|
stream.Seek(8L, SeekOrigin.Begin);
|
|
RenderBase.OTextureFormat format = ReadInt32(stream) switch
|
|
{
|
|
0 => RenderBase.OTextureFormat.argb8,
|
|
1 => RenderBase.OTextureFormat.rgb8,
|
|
2 => RenderBase.OTextureFormat.rgba5551,
|
|
3 => RenderBase.OTextureFormat.rgb8,
|
|
4 => RenderBase.OTextureFormat.rgba4,
|
|
9 => RenderBase.OTextureFormat.la4,
|
|
_ => RenderBase.OTextureFormat.dontCare,
|
|
};
|
|
int width = ReadInt32(stream);
|
|
int height = ReadInt32(stream);
|
|
int bufferSize = CalcBufferSize(format, width, height);
|
|
stream.Seek(offset, SeekOrigin.Begin);
|
|
byte[] buffer = new byte[bufferSize];
|
|
stream.Read(buffer, 0, bufferSize);
|
|
var img = TextureCodec.Decode(buffer, width, height, format);
|
|
img.RotateFlip(RotateFlipType.RotateNoneFlipY);
|
|
return img;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public static void SetImageTo3DST(Stream stream, Image source, RenderBase.OTextureFormat format = RenderBase.OTextureFormat.argb8)
|
|
{
|
|
// TODO: fix Encoding
|
|
WriteString(stream, "3DST"); // 0
|
|
WriteInt32(stream, 2); // 4 unknown
|
|
WriteInt32(stream, (int)format); // 8
|
|
WriteInt32(stream, source.Width); // 12
|
|
WriteInt32(stream, source.Height); // 16
|
|
WriteInt32(stream, 0); // 20
|
|
WriteInt32(stream, 0); // 24
|
|
WriteInt32(stream, 0); // 28
|
|
source.RotateFlip(RotateFlipType.RotateNoneFlipY);
|
|
byte[] buffer = TextureCodec.Encode(new Bitmap(source), format);
|
|
stream.Write(buffer, 0, buffer.Length);
|
|
}
|
|
}
|
|
}
|