refactor VxImageDescEx
This commit is contained in:
@ -1,4 +1,6 @@
|
||||
#include "VxMath.hpp"
|
||||
#include "stb_image.h"
|
||||
#include "stb_image_resize.h"
|
||||
|
||||
namespace LibCmo::VxMath {
|
||||
|
||||
@ -24,26 +26,68 @@ namespace LibCmo::VxMath {
|
||||
|
||||
#pragma region Graphic Utilities
|
||||
|
||||
//CK2::CKDWORD VxGetBitCount(CK2::CKDWORD dwMask) {
|
||||
// if (dwMask == 0u) return 0;
|
||||
// dwMask >>= VxGetBitShift(dwMask);
|
||||
// CK2::CKDWORD count = 0;
|
||||
// while ((dwMask & 1u) == 0u) {
|
||||
// dwMask >>= 1u;
|
||||
// ++count;
|
||||
// }
|
||||
// return count;
|
||||
//}
|
||||
void VxDoBlit(const VxImageDescEx* origin, VxImageDescEx* dst) {
|
||||
if (dst == nullptr || origin == nullptr) return;
|
||||
if (!dst->IsValid() || !origin->IsValid()) return;
|
||||
|
||||
//CK2::CKDWORD VxGetBitShift(CK2::CKDWORD dwMask) {
|
||||
// if (dwMask == 0u) return 0;
|
||||
// CK2::CKDWORD count = 0;
|
||||
// while ((dwMask & 1u) != 0u) {
|
||||
// dwMask >>= 1u;
|
||||
// ++count;
|
||||
// }
|
||||
// return count;
|
||||
//}
|
||||
// if have same size, directly copy it
|
||||
if (dst->IsHWEqual(*origin)) {
|
||||
std::memcpy(dst->GetMutableImage(), origin->GetImage(), dst->GetImageSize());
|
||||
return;
|
||||
}
|
||||
|
||||
// perform resize by stb
|
||||
stbir_resize(
|
||||
origin->GetImage(), static_cast<int>(origin->GetWidth()), static_cast<int>(origin->GetHeight()), 0,
|
||||
dst->GetMutableImage(), static_cast<int>(dst->GetWidth()), static_cast<int>(dst->GetHeight()), 0,
|
||||
STBIR_TYPE_UINT8, 4, STBIR_ALPHA_CHANNEL_NONE, 0, // no alpha channel, mean we treat alpha channel as a normal color factor.
|
||||
STBIR_EDGE_CLAMP, STBIR_EDGE_CLAMP,
|
||||
STBIR_FILTER_BOX, STBIR_FILTER_BOX,
|
||||
STBIR_COLORSPACE_SRGB, nullptr
|
||||
);
|
||||
}
|
||||
|
||||
void VxDoBlitUpsideDown(const VxImageDescEx* origin, VxImageDescEx* dst) {
|
||||
if (dst == nullptr || origin == nullptr) return;
|
||||
if (!dst->IsValid() || !origin->IsValid()) return;
|
||||
|
||||
// if size is not matched, return
|
||||
if (!dst->IsHWEqual(*origin)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// copy and swap data by line
|
||||
CK2::CKDWORD height = dst->GetHeight(),
|
||||
rowsize = sizeof(uint32_t) * dst->GetWidth();
|
||||
for (CK2::CKDWORD row = 0; row < height; ++row) {
|
||||
std::memcpy(
|
||||
dst->GetMutableImage() + (row * rowsize),
|
||||
dst->GetImage() + ((height - row - 1) * rowsize),
|
||||
rowsize
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
CK2::CKDWORD VxGetBitCount(CK2::CKDWORD dwMask) {
|
||||
if (dwMask == 0u) return 0;
|
||||
dwMask >>= VxGetBitShift(dwMask);
|
||||
CK2::CKDWORD count = 0;
|
||||
while ((dwMask & 1u) == 0u) {
|
||||
dwMask >>= 1u;
|
||||
++count;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
CK2::CKDWORD VxGetBitShift(CK2::CKDWORD dwMask) {
|
||||
if (dwMask == 0u) return 0;
|
||||
CK2::CKDWORD count = 0;
|
||||
while ((dwMask & 1u) != 0u) {
|
||||
dwMask >>= 1u;
|
||||
++count;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
//CK2::CKDWORD VxScaleFactor(CK2::CKDWORD val, CK2::CKDWORD srcBitCount, CK2::CKDWORD dstBitCount) {
|
||||
// if (srcBitCount == dstBitCount) return val;
|
||||
|
@ -29,23 +29,33 @@ namespace LibCmo::VxMath {
|
||||
void VxCopyStructure(CK2::CKDWORD Count, void* Dst, CK2::CKDWORD OutStride, CK2::CKDWORD SizeSrc, const void* Src, CK2::CKDWORD InStride);
|
||||
|
||||
// ========== Graphic Utilities ==========
|
||||
//
|
||||
///**
|
||||
// * @brief Copy origin image to dest image.
|
||||
// * Supporting for size scaling. If the size is matched, just a direct copy.
|
||||
// * @param dest[out] The dest image.
|
||||
// * @param origin[in] The origin image.
|
||||
//*/
|
||||
//void VxDoBlit(VxImageDescEx* dst, const VxImageDescEx* origin);
|
||||
|
||||
/**
|
||||
* @brief Performs a blit between two images. This method can resize (shrink or grow) images.
|
||||
* @remark The source image must be in a 32 bit ARGB8888 per pixel format.
|
||||
* @param dest[out] The dest image.
|
||||
* @param origin[in] The origin image.
|
||||
*/
|
||||
void VxDoBlit(const VxImageDescEx* origin, VxImageDescEx* dst);
|
||||
/**
|
||||
* @brief Performs a blit between two images. This method can inverts the destination image.
|
||||
* @remark
|
||||
+ The source image must be in a 32 bit ARGB8888 per pixel format.
|
||||
+ This function usually used in the covertion between texture coordinate
|
||||
system and UV coordinate system.
|
||||
* @param dest[out] The dest image.
|
||||
* @param origin[in] The origin image.
|
||||
*/
|
||||
void VxDoBlitUpsideDown(const VxImageDescEx* origin, VxImageDescEx* dst);
|
||||
|
||||
///**
|
||||
// * @brief Counts number of bits to representing a value in dwMask
|
||||
//*/
|
||||
//CK2::CKDWORD VxGetBitCount(CK2::CKDWORD dwMask);
|
||||
///**
|
||||
// * @brief Counts number of bits to shift to acces a non zero value in dwMask.
|
||||
//*/
|
||||
//CK2::CKDWORD VxGetBitShift(CK2::CKDWORD dwMask);
|
||||
/**
|
||||
* @brief Counts number of bits to representing a value in dwMask
|
||||
*/
|
||||
CK2::CKDWORD VxGetBitCount(CK2::CKDWORD dwMask);
|
||||
/**
|
||||
* @brief Counts number of bits to shift to acces a non zero value in dwMask.
|
||||
*/
|
||||
CK2::CKDWORD VxGetBitShift(CK2::CKDWORD dwMask);
|
||||
|
||||
///**
|
||||
// * @brief scale the integer to a new range.
|
||||
@ -59,6 +69,7 @@ namespace LibCmo::VxMath {
|
||||
|
||||
/**
|
||||
* @brief Sets the alpha component of an image.
|
||||
* @remark The source image must be in a 32 bit ARGB8888 per pixel format.
|
||||
* @param dst_desc[in] A pointer to a structure describing the destination image format.
|
||||
* @param AlphaValue[in] A CKBYTE value containing the alpha value to set to the whole image
|
||||
* @remark If the destination image does not have alpha information the function returns immediatly.
|
||||
@ -66,6 +77,7 @@ namespace LibCmo::VxMath {
|
||||
void VxDoAlphaBlit(VxImageDescEx* dst_desc, CK2::CKBYTE AlphaValue);
|
||||
/**
|
||||
* @brief Sets the alpha component of an image.
|
||||
* @remark The source image must be in a 32 bit ARGB8888 per pixel format.
|
||||
* @param dst_desc[in] A pointer to a structure describing the destination image format.
|
||||
* @param AlphaValues[in] A BYTE array containing the alpha values for each pixel. This array should be allocated to Width*Height bytes.
|
||||
* @remark If the destination image does not have alpha information the function returns immediatly.
|
||||
|
@ -73,28 +73,76 @@ namespace LibCmo::VxMath {
|
||||
* VxImageDescEx describe the height, width,
|
||||
* and etc for image.
|
||||
* Also it hold a pointer to raw image data.
|
||||
* The image data must be 32bit format.
|
||||
* The image data must be 32bit ARGB8888 format.
|
||||
* Thus the size of Image must be 4 * Width * Height.
|
||||
*/
|
||||
class VxImageDescEx {
|
||||
public:
|
||||
VxImageDescEx() :
|
||||
m_Width(0), m_Height(0), m_Image(nullptr) {}
|
||||
VxImageDescEx(CK2::CKDWORD width, CK2::CKDWORD height) :
|
||||
m_Width(width), m_Height(height),
|
||||
//m_RedMask(0), m_GreenMask(0), m_BlueMask(0), m_AlphaMask(0),
|
||||
m_Image(nullptr) {
|
||||
m_Image = new CK2::CKBYTE[GetImageSize()];
|
||||
m_Width(width), m_Height(height), m_Image(nullptr) {
|
||||
CreateImage(width, height);
|
||||
}
|
||||
VxImageDescEx(const VxImageDescEx& rhs) :
|
||||
m_Width(rhs.m_Width), m_Height(rhs.m_Height),
|
||||
m_Image(nullptr) {
|
||||
m_Width(rhs.m_Width), m_Height(rhs.m_Height), m_Image(nullptr) {
|
||||
// copy image
|
||||
m_Image = new CK2::CKBYTE[GetImageSize()];
|
||||
std::memcpy(m_Image, rhs.m_Image, GetImageSize());
|
||||
if (rhs.m_Image != nullptr) {
|
||||
CreateImage(rhs.m_Width, rhs.m_Height, rhs.m_Image);
|
||||
}
|
||||
}
|
||||
VxImageDescEx(VxImageDescEx&& rhs) :
|
||||
m_Width(rhs.m_Width), m_Height(rhs.m_Height), m_Image(rhs.m_Image) {
|
||||
// move image
|
||||
rhs.m_Height = 0;
|
||||
rhs.m_Width = 0;
|
||||
rhs.m_Image = nullptr;
|
||||
}
|
||||
VxImageDescEx& operator=(const VxImageDescEx& rhs) {
|
||||
FreeImage();
|
||||
|
||||
m_Width = rhs.m_Width;
|
||||
m_Height = rhs.m_Height;
|
||||
if (rhs.m_Image != nullptr) {
|
||||
CreateImage(rhs.m_Width, rhs.m_Height, rhs.m_Image);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
VxImageDescEx& operator=(VxImageDescEx&& rhs) {
|
||||
FreeImage();
|
||||
|
||||
m_Height = rhs.m_Height;
|
||||
m_Width = rhs.m_Width;
|
||||
m_Image = rhs.m_Image;
|
||||
rhs.m_Height = 0;
|
||||
rhs.m_Width = 0;
|
||||
rhs.m_Image = nullptr;
|
||||
|
||||
return *this;
|
||||
}
|
||||
~VxImageDescEx() {
|
||||
delete[] m_Image;
|
||||
FreeImage();
|
||||
}
|
||||
|
||||
void CreateImage(CK2::CKDWORD Width, CK2::CKDWORD Height) {
|
||||
FreeImage();
|
||||
m_Width = Width;
|
||||
m_Height = Height;
|
||||
m_Image = new CK2::CKBYTE[GetImageSize()];
|
||||
}
|
||||
void CreateImage(CK2::CKDWORD Width, CK2::CKDWORD Height, void* dataptr) {
|
||||
CreateImage(Width, Height);
|
||||
std::memcpy(m_Image, dataptr, GetImageSize());
|
||||
}
|
||||
void FreeImage() {
|
||||
m_Width = 0;
|
||||
m_Height = 0;
|
||||
if (m_Image != nullptr) {
|
||||
delete[] m_Image;
|
||||
m_Image = nullptr;
|
||||
}
|
||||
}
|
||||
LIBCMO_DISABLE_COPY_MOVE(VxImageDescEx);
|
||||
|
||||
CK2::CKDWORD GetImageSize() const {
|
||||
return static_cast<CK2::CKDWORD>(sizeof(uint32_t) * m_Width * m_Height);
|
||||
@ -123,10 +171,17 @@ namespace LibCmo::VxMath {
|
||||
return m_Height;
|
||||
}
|
||||
|
||||
bool IsValid() const {
|
||||
return (
|
||||
m_Width != 0u &&
|
||||
m_Height != 0u &&
|
||||
m_Image != nullptr
|
||||
);
|
||||
}
|
||||
bool IsHWEqual(const VxImageDescEx& rhs) const {
|
||||
return (m_Width == rhs.m_Width && m_Height == rhs.m_Height);
|
||||
}
|
||||
// bool IsMaskEqual(const VxImageDescEx& rhs) const {
|
||||
// bool IsMaskEqual(const VxImageDescEx& rhs) const {
|
||||
// return (
|
||||
// m_RedMask == rhs.m_RedMask &&
|
||||
// m_GreenMask == rhs.m_GreenMask &&
|
||||
|
Reference in New Issue
Block a user