mirror of
https://github.com/LBPUnion/ProjectLighthouse.git
synced 2025-07-25 14:41:30 +00:00
86 lines
No EOL
2.7 KiB
C#
86 lines
No EOL
2.7 KiB
C#
#nullable enable
|
|
using System.IO;
|
|
using DDSReader;
|
|
using ICSharpCode.SharpZipLib.Zip.Compression;
|
|
using LBPUnion.ProjectLighthouse.Helpers.Extensions;
|
|
using LBPUnion.ProjectLighthouse.Types.Files;
|
|
|
|
namespace LBPUnion.ProjectLighthouse.Helpers;
|
|
|
|
public static class ImageHelper
|
|
{
|
|
public static bool LbpFileToPNG(LbpFile file) => LbpFileToPNG(file.Data, file.Hash, file.FileType);
|
|
|
|
public static bool LbpFileToPNG(byte[] data, string hash, LbpFileType type)
|
|
{
|
|
if (type != LbpFileType.Jpeg && type != LbpFileType.Png && type != LbpFileType.Texture) return false;
|
|
|
|
using MemoryStream ms = new(data);
|
|
using BinaryReader reader = new(ms);
|
|
|
|
if (type == LbpFileType.Texture) return TextureToPNG(hash, reader);
|
|
|
|
return false;
|
|
}
|
|
|
|
private static bool TextureToPNG(string hash, BinaryReader reader)
|
|
{
|
|
// Skip the magic (3 bytes), we already know its a texture
|
|
for(int i = 0; i < 3; i++) reader.ReadByte();
|
|
|
|
// This below is shamelessly stolen from ennuo's Toolkit: https://github.com/ennuo/toolkit/blob/d996ee4134740db0ee94e2cbf1e4edbd1b5ec798/src/main/java/ennuo/craftworld/utilities/Compressor.java#L40
|
|
|
|
// This byte determines the method of reading. We can only read a texture (' ') so if it's not ' ' it must be invalid.
|
|
if ((char)reader.ReadByte() != ' ') return false;
|
|
|
|
reader.ReadInt16(); // ?
|
|
short chunks = reader.ReadInt16BE();
|
|
|
|
int[] compressed = new int[chunks];
|
|
int[] decompressed = new int[chunks];
|
|
|
|
int decompressedSize = 0;
|
|
int compressedSize = 0;
|
|
|
|
for(int i = 0; i < chunks; ++i)
|
|
{
|
|
compressed[i] = reader.ReadUInt16BE();
|
|
decompressed[i] = reader.ReadUInt16BE();
|
|
|
|
decompressedSize += decompressed[i];
|
|
compressedSize += compressed[i];
|
|
}
|
|
|
|
using MemoryStream ms = new();
|
|
using BinaryWriter writer = new(ms);
|
|
for(int i = 0; i < chunks; ++i)
|
|
{
|
|
byte[] deflatedData = reader.ReadBytes(compressed[i]);
|
|
if (compressed[i] == decompressed[i])
|
|
{
|
|
writer.Write(deflatedData);
|
|
}
|
|
|
|
Inflater inflater = new();
|
|
inflater.SetInput(deflatedData);
|
|
byte[] inflatedData = new byte[decompressed[i]];
|
|
inflater.Inflate(inflatedData);
|
|
|
|
writer.Write(inflatedData);
|
|
}
|
|
|
|
return DDSToPNG(hash, ms.ToArray());
|
|
}
|
|
|
|
private static bool DDSToPNG(string hash, byte[] data)
|
|
{
|
|
using MemoryStream stream = new();
|
|
DDSImage image = new(data);
|
|
|
|
image.SaveAsPng(stream);
|
|
|
|
Directory.CreateDirectory("png");
|
|
File.WriteAllBytes($"png/{hash}.png", stream.ToArray());
|
|
return true;
|
|
}
|
|
} |