This commit is contained in:
2025-08-06 13:29:28 +08:00
commit 957a372209
230 changed files with 43801 additions and 0 deletions

View File

@ -0,0 +1,92 @@
//
// Created by sfd on 25-8-4.
//
#include "BinaryReader.h"
#include <filesystem>
#include <fstream>
#include <iostream>
#include <vector>
namespace PKG
{
BinaryReader::BinaryReader(const std::filesystem::path& fileName)
{
m_FilePath = fileName.string();
m_File.open(m_FilePath, std::ios::in | std::ios::binary);
if (!m_File.is_open())
{
std::cerr << "Failed to open file " << m_FilePath << std::endl;
system("pause");
exit(0);
}
}
BinaryReader::~BinaryReader()
{
if (m_File.is_open())
m_File.close();
}
int32_t BinaryReader::ReadInt32()
{
int32_t result = 0;
m_File.read(reinterpret_cast<char*>(&result), sizeof(int32_t));
return result;
}
uint32_t BinaryReader::ReadUInt32()
{
uint32_t result = 0;
m_File.read(reinterpret_cast<char*>(&result), sizeof(uint32_t));
return result;
}
char BinaryReader::ReadChar()
{
char result;
m_File.read(&result, sizeof(char));
pos_type a = m_File.tellg();
return result;
}
void BinaryReader::ReadData(std::string& data, const uint32_t length)
{
data.resize(length);
m_File.read(data.data(), length);
}
void BinaryReader::ReadData(std::vector<uint8_t>& data, uint32_t length)
{
data.resize(length);
m_File.read(reinterpret_cast<char*>(data.data()), length);
}
std::string BinaryReader::ReadString(const uint32_t length)
{
std::vector<uint8_t> result;
result.resize(length);
m_File.read(reinterpret_cast<char*>(result.data()), length);
return std::string(reinterpret_cast<const char*>(result.data()), length);
}
std::string BinaryReader::ReadNString(const int32_t maxLength)
{
std::vector<uint8_t> result;
result.resize(0);
int count = maxLength <= 0 ? 16 : maxLength;
char chr = ReadChar();
while (chr != '\0' && (maxLength == -1 || count <= maxLength))
{
result.push_back(chr);
chr = ReadChar();
}
return std::string(reinterpret_cast<const char*>(result.data()), result.size());
}
}

View File

@ -0,0 +1,47 @@
//
// Created by sfd on 25-8-4.
//
#ifndef BINARYREADER_H
#define BINARYREADER_H
#include <cstdint>
#include <filesystem>
#include <fstream>
#include <vector>
#include "../Core.h"
namespace PKG
{
using pos_type = long long;
class PKG_API BinaryReader
{
public:
BinaryReader() = delete;
explicit BinaryReader(const std::filesystem::path& fileName);
~BinaryReader();
int32_t ReadInt32();
uint32_t ReadUInt32();
char ReadChar();
std::string ReadString(uint32_t length);
std::string ReadNString(int32_t maxLength = -1);
void ReadData(std::string& data, uint32_t length);
void ReadData(std::vector<uint8_t>& data, uint32_t length);
void seekg(const pos_type pos) { m_File.seekg(pos); }
pos_type tellg() { return m_File.tellg(); }
std::string GetFilePath() const { return m_FilePath; }
std::string GetFileName() const { return m_FilePath.substr(m_FilePath.find_last_of("\\/") + 1); }
private:
std::ifstream m_File;
std::string m_FilePath;
};
}
#endif //BINARYREADER_H

View File

@ -0,0 +1,51 @@
//
// Created by sfd on 25-8-4.
//
#include "BinaryWriter.h"
#include <filesystem>
#include <fstream>
#include <iostream>
namespace PKG
{
BinaryWriter::BinaryWriter(const std::filesystem::path& fileName, const std::ios_base::openmode optMode)
{
m_FilePath = fileName.string();
const std::filesystem::path path(fileName.parent_path());
m_File.open(m_FilePath, optMode);
if (!m_File.is_open() && !std::filesystem::exists(path))
{
std::filesystem::create_directories(path);
m_File.open(m_FilePath, optMode);
if (!m_File.is_open())
std::cerr << "cound not create file: " << m_FilePath << std::endl;
}
}
BinaryWriter::~BinaryWriter()
{
if (!m_File.is_open())
close();
}
void BinaryWriter::WriteBytes(const std::string& data, const uint32_t size)
{
if (size == 0)
m_File.write(data.data(), data.size());
else
m_File.write(data.data(), size);
}
void BinaryWriter::WriteString(const std::string& str)
{
m_File.write(str.c_str(), str.size());
}
void BinaryWriter::close()
{
m_File.close();
}
}

View File

@ -0,0 +1,39 @@
//
// Created by sfd on 25-8-4.
//
#ifndef BINARYWRITER_H
#define BINARYWRITER_H
#include <filesystem>
#include <fstream>
#include <vector>
#include "../Core.h"
namespace PKG
{
class PKG_API BinaryWriter
{
public:
BinaryWriter() = delete;
explicit BinaryWriter(const std::filesystem::path& fileName, std::ios_base::openmode optMode = std::ios::out);
~BinaryWriter();
void WriteBytes(const std::string& data, uint32_t size = 0);
void WriteString(const std::string& str);
std::string GetFilePath() const { return m_FilePath; }
std::string GetFileName() const { return m_FilePath.substr(m_FilePath.find_last_of("\\/") + 1); }
void close();
private:
std::ofstream m_File;
std::string m_FilePath;
};
}
#endif //BINARYWRITER_H

View File

@ -0,0 +1,267 @@
//
// Created by sfd on 25-8-5.
//
#include "ImageReader.h"
#include <filesystem>
#include <iostream>
#include "BinaryWriter.h"
#include "lz4.h"
namespace PKG
{
#include <vector>
std::vector<unsigned char> Lz4Decompress(const unsigned char* compressedData,
size_t compressedSize,
size_t decompressedSize)
{
// 准备输出缓冲区
std::vector<unsigned char> output(decompressedSize);
// 执行解压缩
int result = LZ4_decompress_safe(
reinterpret_cast<const char*>(compressedData),
reinterpret_cast<char*>(output.data()),
static_cast<int>(compressedSize),
static_cast<int>(decompressedSize)
);
// 检查解压结果
if (result < 0 || static_cast<size_t>(result) != decompressedSize) {
throw std::runtime_error("LZ4 decompression failed");
}
return output;
}
TexImage ImageReader::ReadFrom(BinaryReader& reader, const TexImageContainer& container, const TexFormat format)
{
int mipMapCount = reader.ReadInt32();
auto aFormat = GetFormatFromTex(container.ImageFormat, format);
TexImage image{};
for (int i = 0; i < mipMapCount; i++)
{
TexMipMap mipmap;
switch (container.ImageContainerVersion)
{
case ImageContainerVersion::VERSION1:
mipmap = ReadMipMapV1(reader); break;
case ImageContainerVersion::VERSION2:
case ImageContainerVersion::VERSION3:
mipmap = ReadMipMapV2AndV3(reader); break;
case ImageContainerVersion::VERSION4:
mipmap = ReadMipMapV4(reader); break;
}
mipmap.Format = aFormat;
if (mipmap.IsZ4Compressed)
{
mipmap.Data = Lz4Decompress(mipmap.Data.data(), mipmap.Data.size(), mipmap.DecompressedDataCount);
mipmap.IsZ4Compressed = false;
}
image.Mipmaps.push_back(mipmap);
}
return image;
}
TexImageContainer ImageReader::ImageContainerReaderReadFrom(BinaryReader& reader, TexFormat texFormat)
{
TexImageContainer container;
container.Magic = reader.ReadNString();
int imageCount = reader.ReadInt32();
if (container.Magic == "TEXB0001")
{
}
else if (container.Magic == "TEXB0002")
{
}
else if (container.Magic == "TEXB0003")
{
container.ImageFormat = (FreeImageFormat)reader.ReadInt32();
}
else if (container.Magic == "TEXB0004")
{
auto format = (FreeImageFormat)reader.ReadInt32();
bool isVideoMp4 = reader.ReadInt32();
if (format == FreeImageFormat::FIF_UNKNOWN)
{
if (isVideoMp4)
format = FreeImageFormat::FIF_MP4;
}
container.ImageFormat = format;
}
else
{
std::cerr << "bad image format" << std::endl;
}
int version = std::stoi(container.Magic.substr(4, 4));
container.ImageContainerVersion = (ImageContainerVersion)version;
if (container.ImageContainerVersion == ImageContainerVersion::VERSION4 && container.ImageFormat != FreeImageFormat::FIF_MP4)
{
container.ImageContainerVersion = ImageContainerVersion::VERSION3;
}
for (int i = 0; i < imageCount; i++)
{
container.Images.push_back(ReadFrom(reader, container, texFormat));
}
return container;
}
TexMipMap ImageReader::ReadMipMapV1(BinaryReader& reader)
{
TexMipMap mipmap{};
mipmap.Width = reader.ReadInt32();
mipmap.Height = reader.ReadInt32();
mipmap.Data = ReadBytes(reader);
return mipmap;
}
TexMipMap ImageReader::ReadMipMapV2AndV3(BinaryReader& reader)
{
TexMipMap mipmap{};
mipmap.Width = reader.ReadInt32();
mipmap.Height = reader.ReadInt32();
mipmap.IsZ4Compressed = reader.ReadInt32() == 1;
mipmap.DecompressedDataCount = reader.ReadInt32();
mipmap.Data = ReadBytes(reader);
return mipmap;
}
TexMipMap ImageReader::ReadMipMapV4(BinaryReader& reader)
{
int param1 = reader.ReadInt32();
if (param1 != 1)
{
std::cerr << "ReadMipmapV4 unknow param1: " << param1 << std::endl;
}
int param2 = reader.ReadInt32();
if (param2 != 2)
{
std::cerr << "ReadMipmapV4 unknow param2: " << param1 << std::endl;
}
std::string condition = reader.ReadNString();
int param3 = reader.ReadInt32();
if (param3 != 1)
{
std::cerr << "ReadMipmapV4 unknow param3: " << param1 << std::endl;
}
TexMipMap mipmap{};
mipmap.Width = reader.ReadInt32();
mipmap.Height = reader.ReadInt32();
mipmap.IsZ4Compressed = reader.ReadInt32() == 1;
mipmap.DecompressedDataCount = reader.ReadInt32();
mipmap.Data = ReadBytes(reader);
return mipmap;
}
std::vector<uint8_t> ImageReader::ReadBytes(BinaryReader& reader)
{
int count = reader.ReadInt32();
std::vector<uint8_t> bytes;
reader.ReadData(bytes, count);
return bytes;
}
MipmapFormat ImageReader::GetFormatFromTex(FreeImageFormat imageFormat, TexFormat format)
{
if (imageFormat != FreeImageFormat::FIF_UNKNOWN)
{
return FreeImageFormatToMipmapFormat(imageFormat);
}
switch (format)
{
case TexFormat::RGBA8888: return MipmapFormat::RGBA8888;
case TexFormat::DXT5: return MipmapFormat::CompressedDXT5;
case TexFormat::DXT3: return MipmapFormat::CompressedDXT3;
case TexFormat::DXT1: return MipmapFormat::CompressedDXT1;
case TexFormat::RG88: return MipmapFormat::RG88;
case TexFormat::R8: return MipmapFormat::R8;
}
std::cerr << "unknow format" << std::endl;
return MipmapFormat::Invalid;
}
MipmapFormat ImageReader::FreeImageFormatToMipmapFormat(FreeImageFormat imageFormat)
{
switch (imageFormat)
{
case FreeImageFormat::FIF_BMP: return MipmapFormat::ImageBMP;
case FreeImageFormat::FIF_ICO: return MipmapFormat::ImageICO;
case FreeImageFormat::FIF_JPEG: return MipmapFormat::ImageJPEG;
case FreeImageFormat::FIF_JNG: return MipmapFormat::ImageJNG;
case FreeImageFormat::FIF_KOALA: return MipmapFormat::ImageKOALA;
case FreeImageFormat::FIF_LBM: return MipmapFormat::ImageLBM;
case FreeImageFormat::FIF_MNG: return MipmapFormat::ImageMNG;
case FreeImageFormat::FIF_PBM: return MipmapFormat::ImagePBM;
case FreeImageFormat::FIF_PBMRAW: return MipmapFormat::ImagePBMRAW;
case FreeImageFormat::FIF_PCD: return MipmapFormat::ImagePCD;
case FreeImageFormat::FIF_PCX: return MipmapFormat::ImagePCX;
case FreeImageFormat::FIF_PGM: return MipmapFormat::ImagePGM;
case FreeImageFormat::FIF_PGMRAW: return MipmapFormat::ImagePGMRAW;
case FreeImageFormat::FIF_PNG: return MipmapFormat::ImagePNG;
case FreeImageFormat::FIF_PPM: return MipmapFormat::ImagePPM;
case FreeImageFormat::FIF_PPMRAW: return MipmapFormat::ImagePPMRAW;
case FreeImageFormat::FIF_RAS: return MipmapFormat::ImageRAS;
case FreeImageFormat::FIF_TARGA: return MipmapFormat::ImageTARGA;
case FreeImageFormat::FIF_TIFF: return MipmapFormat::ImageTIFF;
case FreeImageFormat::FIF_WBMP: return MipmapFormat::ImageWBMP;
case FreeImageFormat::FIF_PSD: return MipmapFormat::ImagePSD;
case FreeImageFormat::FIF_CUT: return MipmapFormat::ImageCUT;
case FreeImageFormat::FIF_XBM: return MipmapFormat::ImageXBM;
case FreeImageFormat::FIF_XPM: return MipmapFormat::ImageXPM;
case FreeImageFormat::FIF_DDS: return MipmapFormat::ImageDDS;
case FreeImageFormat::FIF_GIF: return MipmapFormat::ImageGIF;
case FreeImageFormat::FIF_HDR: return MipmapFormat::ImageHDR;
case FreeImageFormat::FIF_FAXG3: return MipmapFormat::ImageFAXG3;
case FreeImageFormat::FIF_SGI: return MipmapFormat::ImageSGI;
case FreeImageFormat::FIF_EXR: return MipmapFormat::ImageEXR;
case FreeImageFormat::FIF_J2K: return MipmapFormat::ImageJ2K;
case FreeImageFormat::FIF_JP2: return MipmapFormat::ImageJP2;
case FreeImageFormat::FIF_PFM: return MipmapFormat::ImagePFM;
case FreeImageFormat::FIF_PICT: return MipmapFormat::ImagePICT;
case FreeImageFormat::FIF_RAW: return MipmapFormat::ImageRAW;
case FreeImageFormat::FIF_MP4: return MipmapFormat::VideoMp4;
}
std::cerr << "unknown format" << std::endl;
return MipmapFormat::Invalid;
}
}

View File

@ -0,0 +1,32 @@
//
// Created by sfd on 25-8-5.
//
#ifndef IMAGEREADER_H
#define IMAGEREADER_H
#include "BinaryReader.h"
#include "../Tex/TexImageContainer.h"
namespace PKG
{
class PKG_API ImageReader
{
public:
static TexImage ReadFrom(BinaryReader& reader, const TexImageContainer& container, TexFormat format);
static TexImageContainer ImageContainerReaderReadFrom(BinaryReader& reader, TexFormat texFormat);
private:
static TexMipMap ReadMipMapV1(BinaryReader& reader);
static TexMipMap ReadMipMapV2AndV3(BinaryReader& reader);
static TexMipMap ReadMipMapV4(BinaryReader& reader);
static std::vector<uint8_t> ReadBytes(BinaryReader& reader);
static MipmapFormat GetFormatFromTex(FreeImageFormat imageFormat, TexFormat format);
static MipmapFormat FreeImageFormatToMipmapFormat(FreeImageFormat imageFormat);
};
}
#endif //IMAGEREADER_H