重构项目,现支持多线程操作
This commit is contained in:
75
src/Decoder/TexDecoder.cpp
Normal file
75
src/Decoder/TexDecoder.cpp
Normal file
@ -0,0 +1,75 @@
|
||||
#include "TexDecoder.h"
|
||||
#include "ImageReader.h"
|
||||
|
||||
namespace PKG {
|
||||
|
||||
// TEX 文件结构:
|
||||
// [magic1:NString(16)] "TEXV0005"
|
||||
// [magic2:NString(16)] "TEXI0001"
|
||||
// [format:int32] TexFormat
|
||||
// [flags:int32] TexType 标志位
|
||||
// [texW:int32][texH:int32] 纹理尺寸
|
||||
// [imgW:int32][imgH:int32] 图像尺寸
|
||||
// [unk:uint32]
|
||||
// <TexImageContainer> 图像数据(TEXB 块)
|
||||
Result<Tex> TexDecoder::Decode(StreamReader& reader) {
|
||||
Tex tex{};
|
||||
|
||||
// 校验魔数
|
||||
auto magic1Res = reader.ReadNString(16);
|
||||
if (!magic1Res)
|
||||
return Fail<Tex>(magic1Res.error.code, magic1Res.error.message);
|
||||
tex.Magic1 = *magic1Res;
|
||||
if (tex.Magic1 != "TEXV0005")
|
||||
return Fail<Tex>(ErrorCode::BadMagic, "Invalid TEX magic1: " + tex.Magic1);
|
||||
|
||||
auto magic2Res = reader.ReadNString(16);
|
||||
if (!magic2Res)
|
||||
return Fail<Tex>(magic2Res.error.code, magic2Res.error.message);
|
||||
tex.Magic2 = *magic2Res;
|
||||
if (tex.Magic2 != "TEXI0001")
|
||||
return Fail<Tex>(ErrorCode::BadMagic, "Invalid TEX magic2: " + tex.Magic2);
|
||||
|
||||
// 读取头部字段
|
||||
auto formatRes = reader.ReadInt32();
|
||||
if (!formatRes) return Fail<Tex>(formatRes.error.code, formatRes.error.message);
|
||||
tex.Header.Format = static_cast<TexFormat>(*formatRes);
|
||||
|
||||
auto flagsRes = reader.ReadInt32();
|
||||
if (!flagsRes) return Fail<Tex>(flagsRes.error.code, flagsRes.error.message);
|
||||
tex.Header.Flags = static_cast<TexType>(*flagsRes);
|
||||
|
||||
auto texWidthRes = reader.ReadInt32();
|
||||
if (!texWidthRes) return Fail<Tex>(texWidthRes.error.code, texWidthRes.error.message);
|
||||
tex.Header.TextureWidth = *texWidthRes;
|
||||
|
||||
auto texHeightRes = reader.ReadInt32();
|
||||
if (!texHeightRes) return Fail<Tex>(texHeightRes.error.code, texHeightRes.error.message);
|
||||
tex.Header.TextureHeight = *texHeightRes;
|
||||
|
||||
auto imgWidthRes = reader.ReadInt32();
|
||||
if (!imgWidthRes) return Fail<Tex>(imgWidthRes.error.code, imgWidthRes.error.message);
|
||||
tex.Header.ImageWidth = *imgWidthRes;
|
||||
|
||||
auto imgHeightRes = reader.ReadInt32();
|
||||
if (!imgHeightRes) return Fail<Tex>(imgHeightRes.error.code, imgHeightRes.error.message);
|
||||
tex.Header.ImageHeight = *imgHeightRes;
|
||||
|
||||
auto unkRes = reader.ReadUInt32();
|
||||
if (!unkRes) return Fail<Tex>(unkRes.error.code, unkRes.error.message);
|
||||
tex.Header.UnkInt0 = *unkRes;
|
||||
|
||||
// 解析标志位
|
||||
tex.IsGif = (static_cast<int>(tex.Header.Flags) & static_cast<int>(TexType::IsGif)) != 0;
|
||||
tex.IsVideoTexture = (static_cast<int>(tex.Header.Flags) & static_cast<int>(TexType::IsVideoTexture)) != 0;
|
||||
|
||||
// 读取图像容器
|
||||
auto containerRes = ImageReader::ReadContainer(reader, tex.Header.Format);
|
||||
if (!containerRes)
|
||||
return Fail<Tex>(containerRes.error.code, containerRes.error.message);
|
||||
tex.ImageContainer = *containerRes;
|
||||
|
||||
return Ok(std::move(tex));
|
||||
}
|
||||
|
||||
} // namespace PKG
|
||||
Reference in New Issue
Block a user