finish CKBitmapData::DumpToChunk

This commit is contained in:
yyc12345 2023-09-28 23:29:52 +08:00
parent b217da8fb8
commit 1575186c69
7 changed files with 119 additions and 7 deletions

View File

@ -1,6 +1,7 @@
#include "CKBitmapData.hpp" #include "CKBitmapData.hpp"
#include "CKContext.hpp" #include "CKContext.hpp"
#include "CKStateChunk.hpp" #include "CKStateChunk.hpp"
#include "CKFile.hpp"
#include "DataHandlers/CKBitmapHandler.hpp" #include "DataHandlers/CKBitmapHandler.hpp"
#include "MgrImpls/CKPathManager.hpp" #include "MgrImpls/CKPathManager.hpp"
#include <memory> #include <memory>
@ -123,7 +124,7 @@ namespace LibCmo::CK2 {
return false; return false;
} }
void CKBitmapData::WriteSpecificFormatBitmap(CKStateChunk* chk, const VxMath::VxImageDescEx* slot) { void CKBitmapData::WriteSpecificFormatBitmap(CKStateChunk* chk, const VxMath::VxImageDescEx* slot, const CKBitmapProperties* savefmt) {
} }
@ -250,7 +251,98 @@ namespace LibCmo::CK2 {
} }
bool CKBitmapData::DumpToChunk(CKStateChunk* chunk, CKFileVisitor* file, const CKBitmapDataWriteIdentifiers& identifiers) { bool CKBitmapData::DumpToChunk(CKStateChunk* chunk, CKFileVisitor* file, const CKBitmapDataWriteIdentifiers& identifiers) {
return false; // resolve save fmt and save opt
CK_TEXTURE_SAVEOPTIONS saveopt = GetSaveOptions();
if (saveopt == CK_TEXTURE_SAVEOPTIONS::CKTEXTURE_USEGLOBAL) {
saveopt = m_Context->GetGlobalImagesSaveOptions();
}
CKBitmapProperties savefmt(GetSaveFormat());
if (GetSaveOptions() == CK_TEXTURE_SAVEOPTIONS::CKTEXTURE_USEGLOBAL) {
savefmt = m_Context->GetGlobalImagesSaveFormat();
}
// filter external / original files
// the slot can not fulfill extrnal saving requirement will be written in raw data
CKDWORD slotcount = GetSlotCount();
XContainer::XBitArray validExternalSavingSlot;
if (saveopt == CK_TEXTURE_SAVEOPTIONS::CKTEXTURE_EXTERNAL) {
for (CKDWORD i = 0; i < slotcount; ++i) {
if (GetSlotFileName(i) == nullptr) {
saveopt = CK_TEXTURE_SAVEOPTIONS::CKTEXTURE_RAWDATA;
} else {
XContainer::NSXBitArray::Set(validExternalSavingSlot, i);
}
}
}
if (saveopt == CK_TEXTURE_SAVEOPTIONS::CKTEXTURE_INCLUDEORIGINALFILE) {
for (CKDWORD i = 0; i < slotcount; ++i) {
if (file->AddSavedFile(GetSlotFileName(i))) {
XContainer::NSXBitArray::Set(validExternalSavingSlot, i);
} else {
saveopt = CK_TEXTURE_SAVEOPTIONS::CKTEXTURE_RAWDATA;
}
}
}
// save data
if (saveopt == CK_TEXTURE_SAVEOPTIONS::CKTEXTURE_RAWDATA) {
// save as raw data
chunk->WriteIdentifier(identifiers.m_RawData);
chunk->WriteStruct(slotcount);
VxMath::VxImageDescEx invalidDesc;
for (CKDWORD i = 0; i < slotcount; ++i) {
if (XContainer::NSXBitArray::IsSet(validExternalSavingSlot, i)) {
// if this slot can save as external, pass a invalid desc to writer
WriteRawBitmap(chunk, &invalidDesc);
} else {
// otherwise, pass the real slot data
WriteRawBitmap(chunk, GetImageDesc(i));
}
}
}
if (saveopt == CK_TEXTURE_SAVEOPTIONS::CKTEXTURE_IMAGEFORMAT) {
// save as special format
chunk->WriteIdentifier(identifiers.m_SpecificFormat);
chunk->WriteStruct(slotcount);
// prepare height, width, bpp data
CKDWORD height = 0, width = 0, bpp = 32;
for (CKDWORD i = 0; i < slotcount; ++i) {
VxMath::VxImageDescEx* desc = GetImageDesc(i);
if (desc->IsValid()) {
height = desc->GetHeight();
width = desc->GetWidth();
break;
}
}
// write it
chunk->WriteStruct(width);
chunk->WriteStruct(height);
chunk->WriteStruct(bpp);
// write slot one by one
for (CKDWORD i = 0; i < slotcount; ++i) {
WriteSpecificFormatBitmap(chunk, GetImageDesc(i), &savefmt);
}
}
// write filename
{
chunk->WriteIdentifier(identifiers.m_FileNames);
chunk->WriteStruct(slotcount);
XContainer::XString filename;
for (CKDWORD i = 0; i < slotcount; ++i) {
XContainer::NSXString::FromCKSTRING(filename, GetSlotFileName(i));
m_Context->GetPathManager()->GetFileName(filename);
chunk->WriteString(filename);
}
}
return true;
} }
#pragma endregion #pragma endregion
@ -361,7 +453,9 @@ namespace LibCmo::CK2 {
CKSTRING CKBitmapData::GetSlotFileName(CKDWORD slot) const { CKSTRING CKBitmapData::GetSlotFileName(CKDWORD slot) const {
if (slot >= m_Slots.size()) return nullptr; if (slot >= m_Slots.size()) return nullptr;
return m_Slots[slot].m_FileName.c_str(); // return nullptr if no corresponding filename
if (m_Slots[slot].m_FileName.empty()) return nullptr;
else return m_Slots[slot].m_FileName.c_str();
} }
#pragma endregion #pragma endregion

View File

@ -43,7 +43,7 @@ namespace LibCmo::CK2 {
static bool ReadSpecificFormatBitmap(CKStateChunk* chk, VxMath::VxImageDescEx* slot); static bool ReadSpecificFormatBitmap(CKStateChunk* chk, VxMath::VxImageDescEx* slot);
static bool ReadRawBitmap(CKStateChunk* chk, VxMath::VxImageDescEx* slot); static bool ReadRawBitmap(CKStateChunk* chk, VxMath::VxImageDescEx* slot);
static bool ReadOldRawBitmap(CKStateChunk* chk, VxMath::VxImageDescEx* slot); static bool ReadOldRawBitmap(CKStateChunk* chk, VxMath::VxImageDescEx* slot);
static void WriteSpecificFormatBitmap(CKStateChunk* chk, const VxMath::VxImageDescEx* slot); static void WriteSpecificFormatBitmap(CKStateChunk* chk, const VxMath::VxImageDescEx* slot, const CKBitmapProperties* savefmt);
static void WriteRawBitmap(CKStateChunk* chk, const VxMath::VxImageDescEx* slot); static void WriteRawBitmap(CKStateChunk* chk, const VxMath::VxImageDescEx* slot);
bool ReadFromChunk(CKStateChunk* chunk, CKFileVisitor* file, const CKBitmapDataReadIdentifiers& identifiers); bool ReadFromChunk(CKStateChunk* chunk, CKFileVisitor* file, const CKBitmapDataReadIdentifiers& identifiers);

View File

@ -110,6 +110,10 @@ namespace LibCmo::CK2 {
return m_Data; return m_Data;
} }
CKDWORD GetSize() const {
return c_DataLen;
}
bool operator==(const CKFileExtension& rhs) const { bool operator==(const CKFileExtension& rhs) const {
return CKStrEqualI(m_Data, rhs.m_Data); return CKStrEqualI(m_Data, rhs.m_Data);
} }

View File

@ -174,6 +174,8 @@ namespace LibCmo::CK2 {
const CKFileObject* GetFileObjectByIndex(CKDWORD index); const CKFileObject* GetFileObjectByIndex(CKDWORD index);
CKDWORD GetIndexByObjectID(CK_ID objid); CKDWORD GetIndexByObjectID(CK_ID objid);
bool AddSavedFile(CKSTRING u8FileName);
protected: protected:
bool m_IsReader; bool m_IsReader;
CKFileReader* m_Reader; CKFileReader* m_Reader;

View File

@ -334,6 +334,14 @@ namespace LibCmo::CK2 {
return finder->second; return finder->second;
} }
bool CKFileVisitor::AddSavedFile(CKSTRING u8FileName) {
if (m_IsReader) {
return false;
} else {
return m_Writer->AddSavedFile(u8FileName);
}
}
#pragma endregion #pragma endregion
} }

View File

@ -323,8 +323,8 @@ namespace LibCmo::CK2::DataHandlers {
return nullptr; return nullptr;
} }
std::unique_ptr<CKBitmapHandler, CKBitmapHandlerDeleter> CKBitmapHandler::GetBitmapHandlerWrapper(const CKFileExtension& ext, const CKGUID& guid) { CKBitmapHandlerWrapper_t CKBitmapHandler::GetBitmapHandlerWrapper(const CKFileExtension& ext, const CKGUID& guid) {
return std::unique_ptr<CKBitmapHandler, CKBitmapHandlerDeleter>(GetBitmapHandler(ext, guid)); return CKBitmapHandlerWrapper_t(GetBitmapHandler(ext, guid));
} }
void CKBitmapHandlerDeleter::operator()(CKBitmapHandler* handler) { void CKBitmapHandlerDeleter::operator()(CKBitmapHandler* handler) {

View File

@ -16,6 +16,10 @@ namespace LibCmo::CK2::DataHandlers {
CKBitmapHandlerDeleter(const CKBitmapHandlerDeleter&) noexcept {} CKBitmapHandlerDeleter(const CKBitmapHandlerDeleter&) noexcept {}
void operator()(CKBitmapHandler* handler); void operator()(CKBitmapHandler* handler);
}; };
/**
* @brief The type of Auto-free wrapper of CKBitmapHandler.
*/
using CKBitmapHandlerWrapper_t = std::unique_ptr<CKBitmapHandler, CKBitmapHandlerDeleter>;
/** /**
* The interface about processing bitmap data between raw data and specific data. * The interface about processing bitmap data between raw data and specific data.
@ -41,7 +45,7 @@ namespace LibCmo::CK2::DataHandlers {
/** /**
* @brief A auto free wrapper for GetBitmapHandler * @brief A auto free wrapper for GetBitmapHandler
*/ */
static std::unique_ptr<CKBitmapHandler, CKBitmapHandlerDeleter> GetBitmapHandlerWrapper(const CKFileExtension& ext, const CKGUID& guid); static CKBitmapHandlerWrapper_t GetBitmapHandlerWrapper(const CKFileExtension& ext, const CKGUID& guid);
/** /**
* @brief General CKBitmapHandler disposer * @brief General CKBitmapHandler disposer
* @param handler[in] The handler need to be free. * @param handler[in] The handler need to be free.