init
This commit is contained in:
92
expkg/src/BinaryOPT/BinaryReader.cpp
Normal file
92
expkg/src/BinaryOPT/BinaryReader.cpp
Normal 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());
|
||||
}
|
||||
}
|
||||
47
expkg/src/BinaryOPT/BinaryReader.h
Normal file
47
expkg/src/BinaryOPT/BinaryReader.h
Normal 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
|
||||
51
expkg/src/BinaryOPT/BinaryWriter.cpp
Normal file
51
expkg/src/BinaryOPT/BinaryWriter.cpp
Normal 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();
|
||||
}
|
||||
}
|
||||
39
expkg/src/BinaryOPT/BinaryWriter.h
Normal file
39
expkg/src/BinaryOPT/BinaryWriter.h
Normal 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
|
||||
267
expkg/src/BinaryOPT/ImageReader.cpp
Normal file
267
expkg/src/BinaryOPT/ImageReader.cpp
Normal 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;
|
||||
}
|
||||
}
|
||||
32
expkg/src/BinaryOPT/ImageReader.h
Normal file
32
expkg/src/BinaryOPT/ImageReader.h
Normal 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
|
||||
Reference in New Issue
Block a user