fix image reading issue

This commit is contained in:
yyc12345 2023-09-12 20:49:19 +08:00
parent 42feff734d
commit 33c02d292b
5 changed files with 89 additions and 42 deletions

View File

@ -90,9 +90,9 @@ namespace LibCmo::CK2 {
// so return false simply // so return false simply
return false; return false;
} else { } else {
chk->ReadBufferWrapper(&redBuffer, &bufsize);
chk->ReadBufferWrapper(&greenBuffer, &bufsize);
chk->ReadBufferWrapper(&blueBuffer, &bufsize); chk->ReadBufferWrapper(&blueBuffer, &bufsize);
chk->ReadBufferWrapper(&greenBuffer, &bufsize);
chk->ReadBufferWrapper(&redBuffer, &bufsize);
} }
chk->ReadBufferWrapper(&alphaBuffer, &bufsize); chk->ReadBufferWrapper(&alphaBuffer, &bufsize);
@ -108,11 +108,11 @@ namespace LibCmo::CK2 {
* blueSrc = reinterpret_cast<CKBYTE*>(blueBuffer.get()), * blueSrc = reinterpret_cast<CKBYTE*>(blueBuffer.get()),
* alphaSrc = reinterpret_cast<CKBYTE*>(alphaBuffer.get()); * alphaSrc = reinterpret_cast<CKBYTE*>(alphaBuffer.get());
for (CKDWORD p = 0; p < pixelcount; ++p) { for (CKDWORD p = 0; p < pixelcount; ++p) {
*(dst++) = *(blueSrc++);
*(dst++) = *(greenSrc++);
*(dst++) = *(redSrc++);
// if no alpha data, set to 0xFF // if no alpha data, set to 0xFF
*(dst++) = (alphaBuffer != nullptr ? (*(alphaSrc++)) : 0xFFu); *(dst++) = (alphaBuffer != nullptr ? (*(alphaSrc++)) : 0xFFu);
*(dst++) = *(redSrc++);
*(dst++) = *(greenSrc++);
*(dst++) = *(blueSrc++);
} }
} }
@ -224,7 +224,7 @@ namespace LibCmo::CK2 {
chunk->ReadString(filename); chunk->ReadString(filename);
if (filename.empty()) continue; if (filename.empty()) continue;
bool isNotLoaded = i >= hasReadSlot.size() || (!hasReadSlot[i]); bool isNotLoaded = (i >= hasReadSlot.size()) || (!hasReadSlot[i]);
if (isNotLoaded) { if (isNotLoaded) {
// if this image is not loaded. // if this image is not loaded.
// try resolve its file name and load it. // try resolve its file name and load it.

View File

@ -53,7 +53,7 @@ namespace LibCmo::CK2 {
} }
protected: protected:
static const size_t c_DataLen = 4u; static constexpr size_t c_DataLen = 4u;
CKCHAR m_Data[c_DataLen]; CKCHAR m_Data[c_DataLen];
}; };

View File

@ -7,49 +7,92 @@ namespace LibCmo::CK2::DataHandlers {
#pragma region Help Functions #pragma region Help Functions
static void RGBAToARGB(CK2::CKDWORD count, const void* _rgba, void* _argb) { /*
const char* rgba = reinterpret_cast<const char*>(_rgba); ABGR8888 is format used by std image.
The data is placed in buffer with RGBA order, so the format is ABGR.
ARGB8888 is Virtools standard.
The data is placed in buffer with BGRA order.
*/
static void ABGRToARGB(CK2::CKDWORD count, const void* _abgr, void* _argb) {
const char* abgr = reinterpret_cast<const char*>(_abgr);
char* argb = reinterpret_cast<char*>(_argb); char* argb = reinterpret_cast<char*>(_argb);
// copy RGB // copy R
VxMath::VxCopyStructure( VxMath::VxCopyStructure(
count, count,
argb + sizeof(uint8_t), argb + (2u * VxMath::VxImageDescEx::ColorFactorSize),
4 * sizeof(uint8_t), VxMath::VxImageDescEx::PixelSize,
3 * sizeof(uint8_t), VxMath::VxImageDescEx::ColorFactorSize,
rgba, abgr + (0u * VxMath::VxImageDescEx::ColorFactorSize),
4 * sizeof(uint8_t) VxMath::VxImageDescEx::PixelSize
);
// copy G
VxMath::VxCopyStructure(
count,
argb + (1u * VxMath::VxImageDescEx::ColorFactorSize),
VxMath::VxImageDescEx::PixelSize,
VxMath::VxImageDescEx::ColorFactorSize,
abgr + (1u * VxMath::VxImageDescEx::ColorFactorSize),
VxMath::VxImageDescEx::PixelSize
);
// copy B
VxMath::VxCopyStructure(
count,
argb + (0u * VxMath::VxImageDescEx::ColorFactorSize),
VxMath::VxImageDescEx::PixelSize,
VxMath::VxImageDescEx::ColorFactorSize,
abgr + (2u * VxMath::VxImageDescEx::ColorFactorSize),
VxMath::VxImageDescEx::PixelSize
); );
// copy A // copy A
VxMath::VxCopyStructure( VxMath::VxCopyStructure(
count, count,
argb, argb + (3u * VxMath::VxImageDescEx::ColorFactorSize),
4 * sizeof(uint8_t), VxMath::VxImageDescEx::PixelSize,
sizeof(uint8_t), VxMath::VxImageDescEx::ColorFactorSize,
rgba + (3 * sizeof(uint8_t)), abgr + (3u * VxMath::VxImageDescEx::ColorFactorSize),
4 * sizeof(uint8_t) VxMath::VxImageDescEx::PixelSize
); );
} }
static void ARGBToRGBA(CK2::CKDWORD count, const void* _argb, void* _rgba) { static void ARGBToABGR(CK2::CKDWORD count, const void* _argb, void* _abgr) {
const char* argb = reinterpret_cast<const char*>(_argb); const char* argb = reinterpret_cast<const char*>(_argb);
char* rgba = reinterpret_cast<char*>(_rgba); char* abgr = reinterpret_cast<char*>(_abgr);
// copy RGB // copy R
VxMath::VxCopyStructure( VxMath::VxCopyStructure(
count, count,
rgba, abgr + (0u * VxMath::VxImageDescEx::ColorFactorSize),
4 * sizeof(uint8_t), VxMath::VxImageDescEx::PixelSize,
3 * sizeof(uint8_t), VxMath::VxImageDescEx::ColorFactorSize,
argb + sizeof(uint8_t), argb + (2u * VxMath::VxImageDescEx::ColorFactorSize),
4 * sizeof(uint8_t) VxMath::VxImageDescEx::PixelSize
);
// copy G
VxMath::VxCopyStructure(
count,
abgr + (1u * VxMath::VxImageDescEx::ColorFactorSize),
VxMath::VxImageDescEx::PixelSize,
VxMath::VxImageDescEx::ColorFactorSize,
argb + (1u * VxMath::VxImageDescEx::ColorFactorSize),
VxMath::VxImageDescEx::PixelSize
);
// copy B
VxMath::VxCopyStructure(
count,
abgr + (2u * VxMath::VxImageDescEx::ColorFactorSize),
VxMath::VxImageDescEx::PixelSize,
VxMath::VxImageDescEx::ColorFactorSize,
argb + (0u * VxMath::VxImageDescEx::ColorFactorSize),
VxMath::VxImageDescEx::PixelSize
); );
// copy A // copy A
VxMath::VxCopyStructure( VxMath::VxCopyStructure(
count, count,
rgba + (3 * sizeof(uint8_t)), abgr + (3u * VxMath::VxImageDescEx::ColorFactorSize),
4 * sizeof(uint8_t), VxMath::VxImageDescEx::PixelSize,
sizeof(uint8_t), VxMath::VxImageDescEx::ColorFactorSize,
argb, argb + (3u * VxMath::VxImageDescEx::ColorFactorSize),
4 * sizeof(uint8_t) VxMath::VxImageDescEx::PixelSize
); );
} }
@ -68,7 +111,7 @@ namespace LibCmo::CK2::DataHandlers {
read_image->CreateImage(static_cast<CKDWORD>(x), static_cast<CKDWORD>(y)); read_image->CreateImage(static_cast<CKDWORD>(x), static_cast<CKDWORD>(y));
// copy data // copy data
RGBAToARGB(read_image->GetPixelCount(), data, read_image->GetMutableImage()); ABGRToARGB(read_image->GetPixelCount(), data, read_image->GetMutableImage());
// clear data // clear data
stbi_image_free(data); stbi_image_free(data);
@ -91,7 +134,7 @@ namespace LibCmo::CK2::DataHandlers {
read_image->CreateImage(static_cast<CKDWORD>(x), static_cast<CKDWORD>(y)); read_image->CreateImage(static_cast<CKDWORD>(x), static_cast<CKDWORD>(y));
// copy data // copy data
RGBAToARGB(read_image->GetPixelCount(), data, read_image->GetMutableImage()); ABGRToARGB(read_image->GetPixelCount(), data, read_image->GetMutableImage());
// clear data // clear data
stbi_image_free(data); stbi_image_free(data);
@ -135,7 +178,7 @@ namespace LibCmo::CK2::DataHandlers {
// allocate buffer and convert data from ARGB to RGBA // allocate buffer and convert data from ARGB to RGBA
CKBYTE* data = new CKBYTE[write_image->GetImageSize()]; CKBYTE* data = new CKBYTE[write_image->GetImageSize()];
ARGBToRGBA(write_image->GetPixelCount(), write_image->GetImage(), data); ARGBToABGR(write_image->GetPixelCount(), write_image->GetImage(), data);
// write data // write data
FileSaveContext* ctx = new FileSaveContext(fs); FileSaveContext* ctx = new FileSaveContext(fs);
@ -158,7 +201,7 @@ namespace LibCmo::CK2::DataHandlers {
// allocate buffer and convert data from ARGB to RGBA // allocate buffer and convert data from ARGB to RGBA
CKBYTE* data = new CKBYTE[write_image->GetImageSize()]; CKBYTE* data = new CKBYTE[write_image->GetImageSize()];
ARGBToRGBA(write_image->GetPixelCount(), write_image->GetImage(), data); ARGBToABGR(write_image->GetPixelCount(), write_image->GetImage(), data);
// write data // write data
MemorySaveContext* ctx = new MemorySaveContext(memory); MemorySaveContext* ctx = new MemorySaveContext(memory);

View File

@ -58,11 +58,11 @@ namespace LibCmo::VxMath {
// copy and swap data by line // copy and swap data by line
CK2::CKDWORD height = dst->GetHeight(), CK2::CKDWORD height = dst->GetHeight(),
rowsize = sizeof(uint32_t) * dst->GetWidth(); rowsize = VxImageDescEx::PixelSize * dst->GetWidth();
for (CK2::CKDWORD row = 0; row < height; ++row) { for (CK2::CKDWORD row = 0; row < height; ++row) {
std::memcpy( std::memcpy(
dst->GetMutableImage() + (row * rowsize), dst->GetMutableImage() + (row * rowsize),
dst->GetImage() + ((height - row - 1) * rowsize), origin->GetImage() + ((height - row - 1) * rowsize),
rowsize rowsize
); );
} }
@ -105,7 +105,7 @@ namespace LibCmo::VxMath {
CK2::CKDWORD pixelcount = dst_desc->GetPixelCount(); CK2::CKDWORD pixelcount = dst_desc->GetPixelCount();
for (CK2::CKDWORD i = 0; i < pixelcount; ++i) { for (CK2::CKDWORD i = 0; i < pixelcount; ++i) {
*pixels = (*pixels) & 0xFF000000 | AlphaValue; *pixels = (*pixels) & 0x00FFFFFF | (static_cast<CK2::CKDWORD>(AlphaValue) << 24);
++pixels; ++pixels;
} }
@ -129,7 +129,7 @@ namespace LibCmo::VxMath {
CK2::CKDWORD pixelcount = dst_desc->GetPixelCount(); CK2::CKDWORD pixelcount = dst_desc->GetPixelCount();
for (CK2::CKDWORD i = 0; i < pixelcount; ++i) { for (CK2::CKDWORD i = 0; i < pixelcount; ++i) {
*pixels = (*pixels) & 0xFF000000 | (*AlphaValues); *pixels = (*pixels) & 0x00FFFFFF | (static_cast<CK2::CKDWORD>(*AlphaValues) << 24);
++pixels; ++pixels;
++AlphaValues; ++AlphaValues;
} }

View File

@ -75,8 +75,12 @@ namespace LibCmo::VxMath {
* Also it hold a pointer to raw image data. * Also it hold a pointer to raw image data.
* The image data must be 32bit ARGB8888 format. * The image data must be 32bit ARGB8888 format.
* Thus the size of Image must be 4 * Width * Height. * Thus the size of Image must be 4 * Width * Height.
* And the image buffer must is in B, G, R, A order because little endian.
*/ */
class VxImageDescEx { class VxImageDescEx {
public:
static constexpr CK2::CKDWORD ColorFactorSize = 1u;
static constexpr CK2::CKDWORD PixelSize = ColorFactorSize * 4u;
public: public:
VxImageDescEx() : VxImageDescEx() :
m_Width(0), m_Height(0), m_Image(nullptr) {} m_Width(0), m_Height(0), m_Image(nullptr) {}
@ -145,7 +149,7 @@ namespace LibCmo::VxMath {
} }
CK2::CKDWORD GetImageSize() const { CK2::CKDWORD GetImageSize() const {
return static_cast<CK2::CKDWORD>(sizeof(uint32_t) * m_Width * m_Height); return static_cast<CK2::CKDWORD>(PixelSize * m_Width * m_Height);
} }
const CK2::CKBYTE* GetImage() const { const CK2::CKBYTE* GetImage() const {
return m_Image; return m_Image;