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
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<CKBYTE*>(blueBuffer.get()),
* alphaSrc = reinterpret_cast<CKBYTE*>(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.

View File

@ -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];
};

View File

@ -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<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);
// 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<const char*>(_argb);
char* rgba = reinterpret_cast<char*>(_rgba);
// copy RGB
char* abgr = reinterpret_cast<char*>(_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<CKDWORD>(x), static_cast<CKDWORD>(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<CKDWORD>(x), static_cast<CKDWORD>(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);

View File

@ -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<CK2::CKDWORD>(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<CK2::CKDWORD>(*AlphaValues) << 24);
++pixels;
++AlphaValues;
}

View File

@ -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<CK2::CKDWORD>(sizeof(uint32_t) * m_Width * m_Height);
return static_cast<CK2::CKDWORD>(PixelSize * m_Width * m_Height);
}
const CK2::CKBYTE* GetImage() const {
return m_Image;