diff --git a/LibCmo/CK2/CKBitmapData.cpp b/LibCmo/CK2/CKBitmapData.cpp index d85b31e..213681c 100644 --- a/LibCmo/CK2/CKBitmapData.cpp +++ b/LibCmo/CK2/CKBitmapData.cpp @@ -90,9 +90,9 @@ namespace LibCmo::CK2 { // so return false simply return false; } else { - chk->ReadBufferWrapper(&redBuffer, &bufsize); - chk->ReadBufferWrapper(&greenBuffer, &bufsize); chk->ReadBufferWrapper(&blueBuffer, &bufsize); + chk->ReadBufferWrapper(&greenBuffer, &bufsize); + chk->ReadBufferWrapper(&redBuffer, &bufsize); } chk->ReadBufferWrapper(&alphaBuffer, &bufsize); @@ -108,11 +108,11 @@ namespace LibCmo::CK2 { * blueSrc = reinterpret_cast(blueBuffer.get()), * alphaSrc = reinterpret_cast(alphaBuffer.get()); for (CKDWORD p = 0; p < pixelcount; ++p) { + *(dst++) = *(blueSrc++); + *(dst++) = *(greenSrc++); + *(dst++) = *(redSrc++); // if no alpha data, set to 0xFF *(dst++) = (alphaBuffer != nullptr ? (*(alphaSrc++)) : 0xFFu); - *(dst++) = *(redSrc++); - *(dst++) = *(greenSrc++); - *(dst++) = *(blueSrc++); } } @@ -224,7 +224,7 @@ namespace LibCmo::CK2 { chunk->ReadString(filename); if (filename.empty()) continue; - bool isNotLoaded = i >= hasReadSlot.size() || (!hasReadSlot[i]); + bool isNotLoaded = (i >= hasReadSlot.size()) || (!hasReadSlot[i]); if (isNotLoaded) { // if this image is not loaded. // try resolve its file name and load it. diff --git a/LibCmo/CK2/CKStructs.hpp b/LibCmo/CK2/CKStructs.hpp index 55da193..c919fb8 100644 --- a/LibCmo/CK2/CKStructs.hpp +++ b/LibCmo/CK2/CKStructs.hpp @@ -53,7 +53,7 @@ namespace LibCmo::CK2 { } protected: - static const size_t c_DataLen = 4u; + static constexpr size_t c_DataLen = 4u; CKCHAR m_Data[c_DataLen]; }; diff --git a/LibCmo/CK2/DataHandlers/CKBitmapHandler.cpp b/LibCmo/CK2/DataHandlers/CKBitmapHandler.cpp index c83d8c3..72166ac 100644 --- a/LibCmo/CK2/DataHandlers/CKBitmapHandler.cpp +++ b/LibCmo/CK2/DataHandlers/CKBitmapHandler.cpp @@ -7,49 +7,92 @@ namespace LibCmo::CK2::DataHandlers { #pragma region Help Functions - static void RGBAToARGB(CK2::CKDWORD count, const void* _rgba, void* _argb) { - const char* rgba = reinterpret_cast(_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(_abgr); char* argb = reinterpret_cast(_argb); - // copy RGB + // copy R VxMath::VxCopyStructure( count, - argb + sizeof(uint8_t), - 4 * sizeof(uint8_t), - 3 * sizeof(uint8_t), - rgba, - 4 * sizeof(uint8_t) + argb + (2u * VxMath::VxImageDescEx::ColorFactorSize), + VxMath::VxImageDescEx::PixelSize, + VxMath::VxImageDescEx::ColorFactorSize, + abgr + (0u * VxMath::VxImageDescEx::ColorFactorSize), + 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 VxMath::VxCopyStructure( count, - argb, - 4 * sizeof(uint8_t), - sizeof(uint8_t), - rgba + (3 * sizeof(uint8_t)), - 4 * sizeof(uint8_t) + argb + (3u * VxMath::VxImageDescEx::ColorFactorSize), + VxMath::VxImageDescEx::PixelSize, + VxMath::VxImageDescEx::ColorFactorSize, + abgr + (3u * VxMath::VxImageDescEx::ColorFactorSize), + 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(_argb); - char* rgba = reinterpret_cast(_rgba); - // copy RGB + char* abgr = reinterpret_cast(_abgr); + // copy R VxMath::VxCopyStructure( count, - rgba, - 4 * sizeof(uint8_t), - 3 * sizeof(uint8_t), - argb + sizeof(uint8_t), - 4 * sizeof(uint8_t) + abgr + (0u * VxMath::VxImageDescEx::ColorFactorSize), + VxMath::VxImageDescEx::PixelSize, + VxMath::VxImageDescEx::ColorFactorSize, + argb + (2u * VxMath::VxImageDescEx::ColorFactorSize), + 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 VxMath::VxCopyStructure( count, - rgba + (3 * sizeof(uint8_t)), - 4 * sizeof(uint8_t), - sizeof(uint8_t), - argb, - 4 * sizeof(uint8_t) + abgr + (3u * VxMath::VxImageDescEx::ColorFactorSize), + VxMath::VxImageDescEx::PixelSize, + VxMath::VxImageDescEx::ColorFactorSize, + argb + (3u * VxMath::VxImageDescEx::ColorFactorSize), + VxMath::VxImageDescEx::PixelSize ); } @@ -68,7 +111,7 @@ namespace LibCmo::CK2::DataHandlers { read_image->CreateImage(static_cast(x), static_cast(y)); // copy data - RGBAToARGB(read_image->GetPixelCount(), data, read_image->GetMutableImage()); + ABGRToARGB(read_image->GetPixelCount(), data, read_image->GetMutableImage()); // clear data stbi_image_free(data); @@ -91,7 +134,7 @@ namespace LibCmo::CK2::DataHandlers { read_image->CreateImage(static_cast(x), static_cast(y)); // copy data - RGBAToARGB(read_image->GetPixelCount(), data, read_image->GetMutableImage()); + ABGRToARGB(read_image->GetPixelCount(), data, read_image->GetMutableImage()); // clear data stbi_image_free(data); @@ -135,7 +178,7 @@ namespace LibCmo::CK2::DataHandlers { // allocate buffer and convert data from ARGB to RGBA 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 FileSaveContext* ctx = new FileSaveContext(fs); @@ -158,7 +201,7 @@ namespace LibCmo::CK2::DataHandlers { // allocate buffer and convert data from ARGB to RGBA 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 MemorySaveContext* ctx = new MemorySaveContext(memory); diff --git a/LibCmo/VxMath/VxMath.cpp b/LibCmo/VxMath/VxMath.cpp index cbd0a8d..7ee7efc 100644 --- a/LibCmo/VxMath/VxMath.cpp +++ b/LibCmo/VxMath/VxMath.cpp @@ -58,11 +58,11 @@ namespace LibCmo::VxMath { // copy and swap data by line CK2::CKDWORD height = dst->GetHeight(), - rowsize = sizeof(uint32_t) * dst->GetWidth(); + rowsize = VxImageDescEx::PixelSize * dst->GetWidth(); for (CK2::CKDWORD row = 0; row < height; ++row) { std::memcpy( dst->GetMutableImage() + (row * rowsize), - dst->GetImage() + ((height - row - 1) * rowsize), + origin->GetImage() + ((height - row - 1) * rowsize), rowsize ); } @@ -105,7 +105,7 @@ namespace LibCmo::VxMath { CK2::CKDWORD pixelcount = dst_desc->GetPixelCount(); for (CK2::CKDWORD i = 0; i < pixelcount; ++i) { - *pixels = (*pixels) & 0xFF000000 | AlphaValue; + *pixels = (*pixels) & 0x00FFFFFF | (static_cast(AlphaValue) << 24); ++pixels; } @@ -129,7 +129,7 @@ namespace LibCmo::VxMath { CK2::CKDWORD pixelcount = dst_desc->GetPixelCount(); for (CK2::CKDWORD i = 0; i < pixelcount; ++i) { - *pixels = (*pixels) & 0xFF000000 | (*AlphaValues); + *pixels = (*pixels) & 0x00FFFFFF | (static_cast(*AlphaValues) << 24); ++pixels; ++AlphaValues; } diff --git a/LibCmo/VxMath/VxTypes.hpp b/LibCmo/VxMath/VxTypes.hpp index 332910d..ee9e278 100644 --- a/LibCmo/VxMath/VxTypes.hpp +++ b/LibCmo/VxMath/VxTypes.hpp @@ -75,8 +75,12 @@ namespace LibCmo::VxMath { * Also it hold a pointer to raw image data. * The image data must be 32bit ARGB8888 format. * 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 { + public: + static constexpr CK2::CKDWORD ColorFactorSize = 1u; + static constexpr CK2::CKDWORD PixelSize = ColorFactorSize * 4u; public: VxImageDescEx() : m_Width(0), m_Height(0), m_Image(nullptr) {} @@ -145,7 +149,7 @@ namespace LibCmo::VxMath { } CK2::CKDWORD GetImageSize() const { - return static_cast(sizeof(uint32_t) * m_Width * m_Height); + return static_cast(PixelSize * m_Width * m_Height); } const CK2::CKBYTE* GetImage() const { return m_Image;