Files
ExPkg/src/Decoder/TexDecoder.cpp

76 lines
2.8 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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