resolve bmp alpha channel saving issue
This commit is contained in:
parent
b8b2368ef5
commit
6296261532
|
@ -9,10 +9,15 @@ namespace LibCmo::CK2::DataHandlers {
|
||||||
/*
|
/*
|
||||||
ABGR8888 is format used by std image.
|
ABGR8888 is format used by std image.
|
||||||
The data is placed in buffer with RGBA order, so the format is ABGR.
|
The data is placed in buffer with RGBA order, so the format is ABGR.
|
||||||
|
BGR888 also is non-alpha format used by std image.
|
||||||
|
The data is placed in buffer with RGB order, so the format is BGR.
|
||||||
ARGB8888 is Virtools standard.
|
ARGB8888 is Virtools standard.
|
||||||
The data is placed in buffer with BGRA order.
|
The data is placed in buffer with BGRA order.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// MARK: for std-image size, we use `n * CKSizeof(CKBYTE)` to calc offset.
|
||||||
|
// for virtools size, we use `VxMath::VxImageDescEx::ColorFactorSize` and `VxMath::VxImageDescEx::PixelSize` to calc offset.
|
||||||
|
|
||||||
static void ABGRToARGB(CKDWORD count, const void* _abgr, void* _argb) {
|
static void ABGRToARGB(CKDWORD count, const void* _abgr, void* _argb) {
|
||||||
const CKBYTE* abgr = static_cast<const CKBYTE*>(_abgr);
|
const CKBYTE* abgr = static_cast<const CKBYTE*>(_abgr);
|
||||||
CKBYTE* argb = static_cast<CKBYTE*>(_argb);
|
CKBYTE* argb = static_cast<CKBYTE*>(_argb);
|
||||||
|
@ -22,8 +27,8 @@ namespace LibCmo::CK2::DataHandlers {
|
||||||
argb + (2u * VxMath::VxImageDescEx::ColorFactorSize),
|
argb + (2u * VxMath::VxImageDescEx::ColorFactorSize),
|
||||||
VxMath::VxImageDescEx::PixelSize,
|
VxMath::VxImageDescEx::PixelSize,
|
||||||
VxMath::VxImageDescEx::ColorFactorSize,
|
VxMath::VxImageDescEx::ColorFactorSize,
|
||||||
abgr + (0u * VxMath::VxImageDescEx::ColorFactorSize),
|
abgr + (0u * CKSizeof(CKBYTE)),
|
||||||
VxMath::VxImageDescEx::PixelSize
|
4u * CKSizeof(CKBYTE)
|
||||||
);
|
);
|
||||||
// copy G
|
// copy G
|
||||||
VxMath::VxCopyStructure(
|
VxMath::VxCopyStructure(
|
||||||
|
@ -31,8 +36,8 @@ namespace LibCmo::CK2::DataHandlers {
|
||||||
argb + (1u * VxMath::VxImageDescEx::ColorFactorSize),
|
argb + (1u * VxMath::VxImageDescEx::ColorFactorSize),
|
||||||
VxMath::VxImageDescEx::PixelSize,
|
VxMath::VxImageDescEx::PixelSize,
|
||||||
VxMath::VxImageDescEx::ColorFactorSize,
|
VxMath::VxImageDescEx::ColorFactorSize,
|
||||||
abgr + (1u * VxMath::VxImageDescEx::ColorFactorSize),
|
abgr + (1u * CKSizeof(CKBYTE)),
|
||||||
VxMath::VxImageDescEx::PixelSize
|
4u * CKSizeof(CKBYTE)
|
||||||
);
|
);
|
||||||
// copy B
|
// copy B
|
||||||
VxMath::VxCopyStructure(
|
VxMath::VxCopyStructure(
|
||||||
|
@ -40,8 +45,8 @@ namespace LibCmo::CK2::DataHandlers {
|
||||||
argb + (0u * VxMath::VxImageDescEx::ColorFactorSize),
|
argb + (0u * VxMath::VxImageDescEx::ColorFactorSize),
|
||||||
VxMath::VxImageDescEx::PixelSize,
|
VxMath::VxImageDescEx::PixelSize,
|
||||||
VxMath::VxImageDescEx::ColorFactorSize,
|
VxMath::VxImageDescEx::ColorFactorSize,
|
||||||
abgr + (2u * VxMath::VxImageDescEx::ColorFactorSize),
|
abgr + (2u * CKSizeof(CKBYTE)),
|
||||||
VxMath::VxImageDescEx::PixelSize
|
4u * CKSizeof(CKBYTE)
|
||||||
);
|
);
|
||||||
// copy A
|
// copy A
|
||||||
VxMath::VxCopyStructure(
|
VxMath::VxCopyStructure(
|
||||||
|
@ -49,8 +54,8 @@ namespace LibCmo::CK2::DataHandlers {
|
||||||
argb + (3u * VxMath::VxImageDescEx::ColorFactorSize),
|
argb + (3u * VxMath::VxImageDescEx::ColorFactorSize),
|
||||||
VxMath::VxImageDescEx::PixelSize,
|
VxMath::VxImageDescEx::PixelSize,
|
||||||
VxMath::VxImageDescEx::ColorFactorSize,
|
VxMath::VxImageDescEx::ColorFactorSize,
|
||||||
abgr + (3u * VxMath::VxImageDescEx::ColorFactorSize),
|
abgr + (3u * CKSizeof(CKBYTE)),
|
||||||
VxMath::VxImageDescEx::PixelSize
|
4u * CKSizeof(CKBYTE)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,8 +65,8 @@ namespace LibCmo::CK2::DataHandlers {
|
||||||
// copy R
|
// copy R
|
||||||
VxMath::VxCopyStructure(
|
VxMath::VxCopyStructure(
|
||||||
count,
|
count,
|
||||||
abgr + (0u * VxMath::VxImageDescEx::ColorFactorSize),
|
abgr + (0u * CKSizeof(CKBYTE)),
|
||||||
VxMath::VxImageDescEx::PixelSize,
|
4u * CKSizeof(CKBYTE),
|
||||||
VxMath::VxImageDescEx::ColorFactorSize,
|
VxMath::VxImageDescEx::ColorFactorSize,
|
||||||
argb + (2u * VxMath::VxImageDescEx::ColorFactorSize),
|
argb + (2u * VxMath::VxImageDescEx::ColorFactorSize),
|
||||||
VxMath::VxImageDescEx::PixelSize
|
VxMath::VxImageDescEx::PixelSize
|
||||||
|
@ -69,8 +74,8 @@ namespace LibCmo::CK2::DataHandlers {
|
||||||
// copy G
|
// copy G
|
||||||
VxMath::VxCopyStructure(
|
VxMath::VxCopyStructure(
|
||||||
count,
|
count,
|
||||||
abgr + (1u * VxMath::VxImageDescEx::ColorFactorSize),
|
abgr + (1u * CKSizeof(CKBYTE)),
|
||||||
VxMath::VxImageDescEx::PixelSize,
|
4u * CKSizeof(CKBYTE),
|
||||||
VxMath::VxImageDescEx::ColorFactorSize,
|
VxMath::VxImageDescEx::ColorFactorSize,
|
||||||
argb + (1u * VxMath::VxImageDescEx::ColorFactorSize),
|
argb + (1u * VxMath::VxImageDescEx::ColorFactorSize),
|
||||||
VxMath::VxImageDescEx::PixelSize
|
VxMath::VxImageDescEx::PixelSize
|
||||||
|
@ -78,8 +83,8 @@ namespace LibCmo::CK2::DataHandlers {
|
||||||
// copy B
|
// copy B
|
||||||
VxMath::VxCopyStructure(
|
VxMath::VxCopyStructure(
|
||||||
count,
|
count,
|
||||||
abgr + (2u * VxMath::VxImageDescEx::ColorFactorSize),
|
abgr + (2u * CKSizeof(CKBYTE)),
|
||||||
VxMath::VxImageDescEx::PixelSize,
|
4u * CKSizeof(CKBYTE),
|
||||||
VxMath::VxImageDescEx::ColorFactorSize,
|
VxMath::VxImageDescEx::ColorFactorSize,
|
||||||
argb + (0u * VxMath::VxImageDescEx::ColorFactorSize),
|
argb + (0u * VxMath::VxImageDescEx::ColorFactorSize),
|
||||||
VxMath::VxImageDescEx::PixelSize
|
VxMath::VxImageDescEx::PixelSize
|
||||||
|
@ -87,14 +92,47 @@ namespace LibCmo::CK2::DataHandlers {
|
||||||
// copy A
|
// copy A
|
||||||
VxMath::VxCopyStructure(
|
VxMath::VxCopyStructure(
|
||||||
count,
|
count,
|
||||||
abgr + (3u * VxMath::VxImageDescEx::ColorFactorSize),
|
abgr + (3u * CKSizeof(CKBYTE)),
|
||||||
VxMath::VxImageDescEx::PixelSize,
|
4u * CKSizeof(CKBYTE),
|
||||||
VxMath::VxImageDescEx::ColorFactorSize,
|
VxMath::VxImageDescEx::ColorFactorSize,
|
||||||
argb + (3u * VxMath::VxImageDescEx::ColorFactorSize),
|
argb + (3u * VxMath::VxImageDescEx::ColorFactorSize),
|
||||||
VxMath::VxImageDescEx::PixelSize
|
VxMath::VxImageDescEx::PixelSize
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ARGBToBGR(CKDWORD count, const void* _argb, void* _bgr) {
|
||||||
|
const CKBYTE* argb = static_cast<const CKBYTE*>(_argb);
|
||||||
|
CKBYTE* bgr = static_cast<CKBYTE*>(_bgr);
|
||||||
|
// copy R
|
||||||
|
VxMath::VxCopyStructure(
|
||||||
|
count,
|
||||||
|
bgr + (0u * CKSizeof(CKBYTE)),
|
||||||
|
3u * CKSizeof(CKBYTE),
|
||||||
|
VxMath::VxImageDescEx::ColorFactorSize,
|
||||||
|
argb + (2u * VxMath::VxImageDescEx::ColorFactorSize),
|
||||||
|
VxMath::VxImageDescEx::PixelSize
|
||||||
|
);
|
||||||
|
// copy G
|
||||||
|
VxMath::VxCopyStructure(
|
||||||
|
count,
|
||||||
|
bgr + (1u * CKSizeof(CKBYTE)),
|
||||||
|
3u * CKSizeof(CKBYTE),
|
||||||
|
VxMath::VxImageDescEx::ColorFactorSize,
|
||||||
|
argb + (1u * VxMath::VxImageDescEx::ColorFactorSize),
|
||||||
|
VxMath::VxImageDescEx::PixelSize
|
||||||
|
);
|
||||||
|
// copy B
|
||||||
|
VxMath::VxCopyStructure(
|
||||||
|
count,
|
||||||
|
bgr + (2u * CKSizeof(CKBYTE)),
|
||||||
|
3u * CKSizeof(CKBYTE),
|
||||||
|
VxMath::VxImageDescEx::ColorFactorSize,
|
||||||
|
argb + (0u * VxMath::VxImageDescEx::ColorFactorSize),
|
||||||
|
VxMath::VxImageDescEx::PixelSize
|
||||||
|
);
|
||||||
|
// skip A factor
|
||||||
|
}
|
||||||
|
|
||||||
static bool StbReadFile(CKSTRING u8filename, VxMath::VxImageDescEx* read_image) {
|
static bool StbReadFile(CKSTRING u8filename, VxMath::VxImageDescEx* read_image) {
|
||||||
if (u8filename == nullptr || read_image == nullptr) return false;
|
if (u8filename == nullptr || read_image == nullptr) return false;
|
||||||
FILE* fs = EncodingHelper::U8FOpen(u8filename, "rb");
|
FILE* fs = EncodingHelper::U8FOpen(u8filename, "rb");
|
||||||
|
@ -128,7 +166,7 @@ namespace LibCmo::CK2::DataHandlers {
|
||||||
&x, &y, &channels_in_file, 4 // 4 == RGBA8888
|
&x, &y, &channels_in_file, 4 // 4 == RGBA8888
|
||||||
);
|
);
|
||||||
if (data == nullptr) return false;
|
if (data == nullptr) return false;
|
||||||
|
|
||||||
// create read image
|
// create read image
|
||||||
read_image->CreateImage(static_cast<CKDWORD>(x), static_cast<CKDWORD>(y));
|
read_image->CreateImage(static_cast<CKDWORD>(x), static_cast<CKDWORD>(y));
|
||||||
|
|
||||||
|
@ -169,22 +207,33 @@ namespace LibCmo::CK2::DataHandlers {
|
||||||
}
|
}
|
||||||
|
|
||||||
using SaveOperation = std::function<int(stbi_write_func*, void*, int, int, int, const void*)>;
|
using SaveOperation = std::function<int(stbi_write_func*, void*, int, int, int, const void*)>;
|
||||||
static bool StbSaveFile(CKSTRING u8filename, const VxMath::VxImageDescEx* write_image, SaveOperation oper) {
|
static bool StbSaveFile(CKSTRING u8filename, const VxMath::VxImageDescEx* write_image, bool save_alpha, SaveOperation oper) {
|
||||||
if (u8filename == nullptr || write_image == nullptr) return false;
|
if (u8filename == nullptr || write_image == nullptr) return false;
|
||||||
if (!write_image->IsValid()) return false;
|
if (!write_image->IsValid()) return false;
|
||||||
FILE* fs = EncodingHelper::U8FOpen(u8filename, "wb");
|
FILE* fs = EncodingHelper::U8FOpen(u8filename, "wb");
|
||||||
if (fs == nullptr) return false;
|
if (fs == nullptr) return false;
|
||||||
|
|
||||||
// allocate buffer and convert data from ARGB to RGBA
|
// allocate buffer and convert data from ARGB to RGBA or RGB
|
||||||
CKBYTE* data = new CKBYTE[write_image->GetImageSize()];
|
CKBYTE* data = nullptr;
|
||||||
ARGBToABGR(write_image->GetPixelCount(), write_image->GetImage(), data);
|
int channel_count = 0;
|
||||||
|
if (save_alpha) {
|
||||||
|
// save with alpha
|
||||||
|
data = new CKBYTE[CKSizeof(CKBYTE) * 4u * write_image->GetWidth() * write_image->GetHeight()];
|
||||||
|
ARGBToABGR(write_image->GetPixelCount(), write_image->GetImage(), data);
|
||||||
|
channel_count = 4;
|
||||||
|
} else {
|
||||||
|
// save without alpha
|
||||||
|
data = new CKBYTE[CKSizeof(CKBYTE) * 3u * write_image->GetWidth() * write_image->GetHeight()];
|
||||||
|
ARGBToBGR(write_image->GetPixelCount(), write_image->GetImage(), data);
|
||||||
|
channel_count = 3;
|
||||||
|
}
|
||||||
|
|
||||||
// write data
|
// write data
|
||||||
FileSaveContext* ctx = new FileSaveContext(fs);
|
FileSaveContext* ctx = new FileSaveContext(fs);
|
||||||
int ret = oper(
|
int ret = oper(
|
||||||
&FileWriteFunction, ctx,
|
&FileWriteFunction, ctx,
|
||||||
static_cast<int>(write_image->GetWidth()), static_cast<int>(write_image->GetHeight()),
|
static_cast<int>(write_image->GetWidth()), static_cast<int>(write_image->GetHeight()),
|
||||||
4, data // 4 == RGBA8888
|
channel_count, data // 4 == RGBA8888
|
||||||
);
|
);
|
||||||
|
|
||||||
// free data
|
// free data
|
||||||
|
@ -195,20 +244,31 @@ namespace LibCmo::CK2::DataHandlers {
|
||||||
// ret is 0 mean failed.
|
// ret is 0 mean failed.
|
||||||
return ret != 0;
|
return ret != 0;
|
||||||
}
|
}
|
||||||
static CKDWORD StbSaveMemory(void* memory, const VxMath::VxImageDescEx* write_image, SaveOperation oper) {
|
static CKDWORD StbSaveMemory(void* memory, const VxMath::VxImageDescEx* write_image, bool save_alpha, SaveOperation oper) {
|
||||||
if (write_image == nullptr) return 0;
|
if (write_image == nullptr) return 0;
|
||||||
if (!write_image->IsValid()) return 0;
|
if (!write_image->IsValid()) return 0;
|
||||||
|
|
||||||
// allocate buffer and convert data from ARGB to RGBA
|
// allocate buffer and convert data from ARGB to RGBA or RGB
|
||||||
CKBYTE* data = new CKBYTE[write_image->GetImageSize()];
|
CKBYTE* data = nullptr;
|
||||||
ARGBToABGR(write_image->GetPixelCount(), write_image->GetImage(), data);
|
int channel_count = 0;
|
||||||
|
if (save_alpha) {
|
||||||
|
// save with alpha
|
||||||
|
data = new CKBYTE[CKSizeof(CKBYTE) * 4u * write_image->GetWidth() * write_image->GetHeight()];
|
||||||
|
ARGBToABGR(write_image->GetPixelCount(), write_image->GetImage(), data);
|
||||||
|
channel_count = 4;
|
||||||
|
} else {
|
||||||
|
// save without alpha
|
||||||
|
data = new CKBYTE[CKSizeof(CKBYTE) * 3u * write_image->GetWidth() * write_image->GetHeight()];
|
||||||
|
ARGBToBGR(write_image->GetPixelCount(), write_image->GetImage(), data);
|
||||||
|
channel_count = 3;
|
||||||
|
}
|
||||||
|
|
||||||
// write data
|
// write data
|
||||||
MemorySaveContext* ctx = new MemorySaveContext(memory);
|
MemorySaveContext* ctx = new MemorySaveContext(memory);
|
||||||
int ret = oper(
|
int ret = oper(
|
||||||
&MemoryWriteFunction, ctx,
|
&MemoryWriteFunction, ctx,
|
||||||
static_cast<int>(write_image->GetWidth()), static_cast<int>(write_image->GetHeight()),
|
static_cast<int>(write_image->GetWidth()), static_cast<int>(write_image->GetHeight()),
|
||||||
4, data // 4 == RGBA8888
|
channel_count, data // 4 == RGBA8888
|
||||||
);
|
);
|
||||||
|
|
||||||
// free data
|
// free data
|
||||||
|
@ -220,7 +280,7 @@ namespace LibCmo::CK2::DataHandlers {
|
||||||
if (ret == 0) return 0;
|
if (ret == 0) return 0;
|
||||||
else return expected;
|
else return expected;
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
|
|
||||||
#pragma region CKBitmapBMPHandler
|
#pragma region CKBitmapBMPHandler
|
||||||
|
@ -244,15 +304,19 @@ namespace LibCmo::CK2::DataHandlers {
|
||||||
return StbReadMemory(memory, size, read_image);
|
return StbReadMemory(memory, size, read_image);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: when stb-image writing bmp file with alpha channel, it will create a very rare bmp file supporting alpha channel.
|
||||||
|
// this format is not supported by virtools and will result blank image.
|
||||||
|
// so we create an alpha option to forcely change channel count to 3 (RGB) then the bmp writer can work normally.
|
||||||
|
|
||||||
bool CKBitmapBMPHandler::SaveFile(CKSTRING u8filename, const VxMath::VxImageDescEx* write_image, const CKBitmapProperties& codec_param) {
|
bool CKBitmapBMPHandler::SaveFile(CKSTRING u8filename, const VxMath::VxImageDescEx* write_image, const CKBitmapProperties& codec_param) {
|
||||||
return StbSaveFile(u8filename, write_image,
|
return StbSaveFile(u8filename, write_image, false, // bmp do not support alpha
|
||||||
[&codec_param](stbi_write_func* func, void* context, int w, int h, int comp, const void* data) -> int {
|
[&codec_param](stbi_write_func* func, void* context, int w, int h, int comp, const void* data) -> int {
|
||||||
return stbi_write_bmp_to_func(func, context, w, h, comp, data);
|
return stbi_write_bmp_to_func(func, context, w, h, comp, data);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
CKDWORD CKBitmapBMPHandler::SaveMemory(void* memory, const VxMath::VxImageDescEx* write_image, const CKBitmapProperties& codec_param) {
|
CKDWORD CKBitmapBMPHandler::SaveMemory(void* memory, const VxMath::VxImageDescEx* write_image, const CKBitmapProperties& codec_param) {
|
||||||
return StbSaveMemory(memory, write_image,
|
return StbSaveMemory(memory, write_image, false, // bmp do not support alpha
|
||||||
[&codec_param](stbi_write_func* func, void* context, int w, int h, int comp, const void* data) -> int {
|
[&codec_param](stbi_write_func* func, void* context, int w, int h, int comp, const void* data) -> int {
|
||||||
return stbi_write_bmp_to_func(func, context, w, h, comp, data);
|
return stbi_write_bmp_to_func(func, context, w, h, comp, data);
|
||||||
});
|
});
|
||||||
|
@ -265,8 +329,8 @@ namespace LibCmo::CK2::DataHandlers {
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
|
|
||||||
#pragma region CKBitmapTGAHandler
|
#pragma region CKBitmapTGAHandler
|
||||||
|
|
||||||
static const CKBitmapProperties g_TGAProperties(CKGUID(0x585C7216u, 0x33302657u), "Tga");
|
static const CKBitmapProperties g_TGAProperties(CKGUID(0x585C7216u, 0x33302657u), "Tga");
|
||||||
|
|
||||||
CKBitmapTGAHandler::CKBitmapTGAHandler() :
|
CKBitmapTGAHandler::CKBitmapTGAHandler() :
|
||||||
CKBitmapHandler() {}
|
CKBitmapHandler() {}
|
||||||
|
@ -286,14 +350,14 @@ namespace LibCmo::CK2::DataHandlers {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CKBitmapTGAHandler::SaveFile(CKSTRING u8filename, const VxMath::VxImageDescEx* write_image, const CKBitmapProperties& codec_param) {
|
bool CKBitmapTGAHandler::SaveFile(CKSTRING u8filename, const VxMath::VxImageDescEx* write_image, const CKBitmapProperties& codec_param) {
|
||||||
return StbSaveFile(u8filename, write_image,
|
return StbSaveFile(u8filename, write_image, false, // tga support alpha
|
||||||
[&codec_param](stbi_write_func* func, void* context, int w, int h, int comp, const void* data) -> int {
|
[&codec_param](stbi_write_func* func, void* context, int w, int h, int comp, const void* data) -> int {
|
||||||
return stbi_write_tga_to_func(func, context, w, h, comp, data);
|
return stbi_write_tga_to_func(func, context, w, h, comp, data);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
CKDWORD CKBitmapTGAHandler::SaveMemory(void* memory, const VxMath::VxImageDescEx* write_image, const CKBitmapProperties& codec_param) {
|
CKDWORD CKBitmapTGAHandler::SaveMemory(void* memory, const VxMath::VxImageDescEx* write_image, const CKBitmapProperties& codec_param) {
|
||||||
return StbSaveMemory(memory, write_image,
|
return StbSaveMemory(memory, write_image, false, // tga support alpha
|
||||||
[&codec_param](stbi_write_func* func, void* context, int w, int h, int comp, const void* data) -> int {
|
[&codec_param](stbi_write_func* func, void* context, int w, int h, int comp, const void* data) -> int {
|
||||||
return stbi_write_tga_to_func(func, context, w, h, comp, data);
|
return stbi_write_tga_to_func(func, context, w, h, comp, data);
|
||||||
});
|
});
|
||||||
|
@ -304,7 +368,7 @@ namespace LibCmo::CK2::DataHandlers {
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
|
|
||||||
#pragma region General Getter Freer
|
#pragma region General Getter Freer
|
||||||
|
|
||||||
static CKBitmapHandler* FindHandlerByExt(const CKFileExtension& ext) {
|
static CKBitmapHandler* FindHandlerByExt(const CKFileExtension& ext) {
|
||||||
|
@ -325,7 +389,7 @@ namespace LibCmo::CK2::DataHandlers {
|
||||||
// check ext first
|
// check ext first
|
||||||
handler = FindHandlerByExt(ext);
|
handler = FindHandlerByExt(ext);
|
||||||
if (handler != nullptr) return handler;
|
if (handler != nullptr) return handler;
|
||||||
|
|
||||||
// check guid
|
// check guid
|
||||||
handler = FindHandlerByGuid(guid);
|
handler = FindHandlerByGuid(guid);
|
||||||
if (handler != nullptr) return handler;
|
if (handler != nullptr) return handler;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user