mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-06-12 07:48:16 -05:00
Dump iw4 images
This commit is contained in:
@ -7,6 +7,120 @@ IwiLoader::IwiLoader(MemoryManager* memoryManager)
|
||||
m_memory_manager = memoryManager;
|
||||
}
|
||||
|
||||
const ImageFormat* IwiLoader::GetFormat8(int8_t format)
|
||||
{
|
||||
switch (static_cast<iwi8::IwiFormat>(format))
|
||||
{
|
||||
case iwi8::IwiFormat::IMG_FORMAT_BITMAP_RGBA:
|
||||
return &ImageFormat::FORMAT_R8_G8_B8_A8;
|
||||
case iwi8::IwiFormat::IMG_FORMAT_BITMAP_RGB:
|
||||
return &ImageFormat::FORMAT_R8_G8_B8;
|
||||
case iwi8::IwiFormat::IMG_FORMAT_BITMAP_ALPHA:
|
||||
return &ImageFormat::FORMAT_A8;
|
||||
case iwi8::IwiFormat::IMG_FORMAT_DXT1:
|
||||
return &ImageFormat::FORMAT_BC1;
|
||||
case iwi8::IwiFormat::IMG_FORMAT_DXT3:
|
||||
return &ImageFormat::FORMAT_BC2;
|
||||
case iwi8::IwiFormat::IMG_FORMAT_DXT5:
|
||||
return &ImageFormat::FORMAT_BC3;
|
||||
case iwi8::IwiFormat::IMG_FORMAT_DXN:
|
||||
return &ImageFormat::FORMAT_BC5;
|
||||
case iwi8::IwiFormat::IMG_FORMAT_BITMAP_LUMINANCE_ALPHA: // used
|
||||
case iwi8::IwiFormat::IMG_FORMAT_BITMAP_LUMINANCE: // used
|
||||
case iwi8::IwiFormat::IMG_FORMAT_WAVELET_RGBA: // used
|
||||
case iwi8::IwiFormat::IMG_FORMAT_WAVELET_RGB: // used
|
||||
case iwi8::IwiFormat::IMG_FORMAT_WAVELET_LUMINANCE_ALPHA:
|
||||
case iwi8::IwiFormat::IMG_FORMAT_WAVELET_LUMINANCE:
|
||||
case iwi8::IwiFormat::IMG_FORMAT_WAVELET_ALPHA:
|
||||
case iwi8::IwiFormat::IMG_FORMAT_DXT3A_AS_LUMINANCE:
|
||||
case iwi8::IwiFormat::IMG_FORMAT_DXT5A_AS_LUMINANCE:
|
||||
case iwi8::IwiFormat::IMG_FORMAT_DXT3A_AS_ALPHA:
|
||||
case iwi8::IwiFormat::IMG_FORMAT_DXT5A_AS_ALPHA:
|
||||
case iwi8::IwiFormat::IMG_FORMAT_DXT1_AS_LUMINANCE_ALPHA:
|
||||
case iwi8::IwiFormat::IMG_FORMAT_DXN_AS_LUMINANCE_ALPHA:
|
||||
case iwi8::IwiFormat::IMG_FORMAT_DXT1_AS_LUMINANCE:
|
||||
case iwi8::IwiFormat::IMG_FORMAT_DXT1_AS_ALPHA:
|
||||
printf("Unsupported IWI format: %i\n", format);
|
||||
break;
|
||||
default:
|
||||
printf("Unknown IWI format: %i\n", format);
|
||||
break;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Texture* IwiLoader::LoadIwi8(FileAPI::IFile* file)
|
||||
{
|
||||
iwi8::IwiHeader header{};
|
||||
|
||||
if (file->Read(&header, sizeof header, 1) != 1)
|
||||
return nullptr;
|
||||
|
||||
const ImageFormat* format = GetFormat8(header.format);
|
||||
if (format == nullptr)
|
||||
return nullptr;
|
||||
|
||||
uint16_t width = header.dimensions[0];
|
||||
uint16_t height = header.dimensions[1];
|
||||
uint16_t depth = header.dimensions[2];
|
||||
bool hasMipMaps = !(header.flags & iwi8::IwiFlags::IMG_FLAG_NOMIPMAPS);
|
||||
|
||||
Texture* texture;
|
||||
if ((header.flags & iwi8::IwiFlags::IMG_FLAG_MAPTYPE_MASK) == iwi8::IwiFlags::IMG_FLAG_MAPTYPE_CUBE)
|
||||
{
|
||||
texture = m_memory_manager->Create<TextureCube>(format, width, height, hasMipMaps);
|
||||
}
|
||||
else if ((header.flags & iwi8::IwiFlags::IMG_FLAG_MAPTYPE_MASK) == iwi8::IwiFlags::IMG_FLAG_MAPTYPE_3D)
|
||||
{
|
||||
texture = m_memory_manager->Create<Texture3D>(format, width, height, depth, hasMipMaps);
|
||||
}
|
||||
else if ((header.flags & iwi8::IwiFlags::IMG_FLAG_MAPTYPE_MASK) == iwi8::IwiFlags::IMG_FLAG_MAPTYPE_2D)
|
||||
{
|
||||
texture = m_memory_manager->Create<Texture2D>(format, width, height, hasMipMaps);
|
||||
}
|
||||
else if ((header.flags & iwi8::IwiFlags::IMG_FLAG_MAPTYPE_MASK) == iwi8::IwiFlags::IMG_FLAG_MAPTYPE_1D)
|
||||
{
|
||||
printf("Iwi has unsupported map type 1D\n");
|
||||
return nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Iwi has unsupported map type\n");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
texture->Allocate();
|
||||
|
||||
size_t currentFileSize = sizeof iwi8::IwiHeader + sizeof IwiVersion;
|
||||
const int mipMapCount = hasMipMaps ? texture->GetMipMapCount() : 1;
|
||||
|
||||
for (int currentMipLevel = mipMapCount - 1; currentMipLevel >= 0; currentMipLevel--)
|
||||
{
|
||||
const size_t sizeOfMipLevel = texture->GetSizeOfMipLevel(currentMipLevel) * texture->GetFaceCount();
|
||||
currentFileSize += sizeOfMipLevel;
|
||||
|
||||
if (currentMipLevel < static_cast<int>(_countof(iwi8::IwiHeader::fileSizeForPicmip))
|
||||
&& currentFileSize != header.fileSizeForPicmip[currentMipLevel])
|
||||
{
|
||||
printf("Iwi has invalid file size for picmip %i\n", currentMipLevel);
|
||||
|
||||
m_memory_manager->Delete(texture);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (file->Read(texture->GetBufferForMipLevel(currentMipLevel), 1, sizeOfMipLevel) != sizeOfMipLevel)
|
||||
{
|
||||
printf("Unexpected eof of iwi in mip level %i\n", currentMipLevel);
|
||||
|
||||
m_memory_manager->Delete(texture);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
const ImageFormat* IwiLoader::GetFormat27(int8_t format)
|
||||
{
|
||||
switch (static_cast<iwi27::IwiFormat>(format))
|
||||
@ -65,11 +179,11 @@ Texture* IwiLoader::LoadIwi27(FileAPI::IFile* file)
|
||||
bool hasMipMaps = !(header.flags & iwi27::IwiFlags::IMG_FLAG_NOMIPMAPS);
|
||||
|
||||
Texture* texture;
|
||||
if(header.flags & iwi27::IwiFlags::IMG_FLAG_CUBEMAP)
|
||||
if (header.flags & iwi27::IwiFlags::IMG_FLAG_CUBEMAP)
|
||||
{
|
||||
texture = m_memory_manager->Create<TextureCube>(format, width, height, hasMipMaps);
|
||||
}
|
||||
else if(header.flags & iwi27::IwiFlags::IMG_FLAG_VOLMAP)
|
||||
else if (header.flags & iwi27::IwiFlags::IMG_FLAG_VOLMAP)
|
||||
{
|
||||
texture = m_memory_manager->Create<Texture3D>(format, width, height, depth, hasMipMaps);
|
||||
}
|
||||
@ -125,6 +239,9 @@ Texture* IwiLoader::LoadIwi(FileAPI::IFile* file)
|
||||
|
||||
switch (iwiVersion.version)
|
||||
{
|
||||
case 8:
|
||||
return LoadIwi8(file);
|
||||
|
||||
case 27:
|
||||
return LoadIwi27(file);
|
||||
|
||||
|
@ -8,6 +8,9 @@ class IwiLoader
|
||||
{
|
||||
MemoryManager* m_memory_manager;
|
||||
|
||||
static const ImageFormat* GetFormat8(int8_t format);
|
||||
Texture* LoadIwi8(FileAPI::IFile* file);
|
||||
|
||||
static const ImageFormat* GetFormat27(int8_t format);
|
||||
Texture* LoadIwi27(FileAPI::IFile* file);
|
||||
|
||||
|
Reference in New Issue
Block a user