Add RawImage::convertToType()

This commit is contained in:
2024-10-29 19:42:36 +01:00
parent 3635ac00cb
commit 8f7f527732
2 changed files with 96 additions and 34 deletions
+95 -34
View File
@@ -435,45 +435,106 @@ void RawImage::convertToThumbnail()
void RawImage::convertToGLFormat()
{
size_t s = size() * m_ch;
if(m_type == UINT32)
{
m_origWidth = m_width;
m_origHeight = m_height;
m_original = std::move(m_pixels);
allocate(m_width, m_height, m_channels, FLOAT32);
m_origType = UINT32;
float *dst = reinterpret_cast<float*>(m_pixels.get());
uint32_t *src = reinterpret_cast<uint32_t*>(m_original.get());
if(m_type == UINT32 || m_type == FLOAT64)
convertToType(FLOAT32);
else if(OpenGLES && m_type == UINT16)
convertToType(FLOAT16);
}
for(size_t i = 0; i < s; i++)
dst[i] = src[i] / (float)UINT32_MAX;
}
else if(m_type == FLOAT64)
template<typename T, typename U>
void convertType2(uint32_t size, const T *src, U *dst)
{
if constexpr((std::is_floating_point_v<T> || std::is_same_v<T, F16>) && (std::is_floating_point_v<U> || std::is_same_v<T, F16>))
{
m_origWidth = m_width;
m_origHeight = m_height;
m_original = std::move(m_pixels);
allocate(m_width, m_height, m_channels, FLOAT32);
m_origType = FLOAT64;
float *dst = reinterpret_cast<float*>(m_pixels.get());
double *src = reinterpret_cast<double*>(m_original.get());
for(size_t i = 0; i < s; i++)
for(uint32_t i = 0; i < size; i++)
dst[i] = src[i];
}
else if(OpenGLES && m_type == UINT16)
{
m_origWidth = m_width;
m_origHeight = m_height;
m_original = std::move(m_pixels);
allocate(m_width, m_height, m_channels, FLOAT16);
m_origType = UINT16;
F16 *dst = reinterpret_cast<F16*>(m_pixels.get());
uint16_t *src = reinterpret_cast<uint16_t*>(m_original.get());
for(size_t i = 0; i < s; i++)
dst[i] = (F16)(src[i] / (float)UINT16_MAX);
if constexpr(std::is_integral_v<T> && std::is_integral_v<U>)
{
if constexpr(sizeof(T) > sizeof(U))
for(uint32_t i = 0; i < size; i++)
dst[i] = src[i] >> ((sizeof(T) - sizeof(U)) * 8);
else
for(uint32_t i = 0; i < size; i++)
dst[i] = static_cast<U>(src[i]) << ((sizeof(U) - sizeof(T)) * 8);
}
if constexpr((std::is_floating_point_v<T> || std::is_same_v<T, F16>) && std::is_integral_v<U>)
{
U max = std::numeric_limits<U>::max();
T scale = (T)(max);
for(uint32_t i = 0; i < size; i++)
dst[i] = src[i] * scale;
}
if constexpr(std::is_integral_v<T> && (std::is_floating_point_v<U> || std::is_same_v<U, F16>))
{
U scale = 1.0 / std::numeric_limits<T>::max();
for(uint32_t i = 0; i < size; i++)
dst[i] = (U)src[i] * scale;
}
}
template<typename T>
void convertType(uint32_t size, RawImage::DataType dstType, const T *src, void *dst)
{
switch(dstType)
{
case RawImage::UINT8:
convertType2(size, src, static_cast<uint8_t*>(dst));
break;
case RawImage::UINT16:
convertType2(size, src, static_cast<uint16_t*>(dst));
break;
case RawImage::UINT32:
convertType2(size, src, static_cast<uint32_t*>(dst));
break;
case RawImage::FLOAT16:
convertType2(size, src, static_cast<F16*>(dst));
break;
case RawImage::FLOAT32:
convertType2(size, src, static_cast<float*>(dst));
break;
case RawImage::FLOAT64:
convertType2(size, src, static_cast<double*>(dst));
break;
}
}
void RawImage::convertToType(DataType type)
{
if(type == m_type)
return;
m_origWidth = m_width;
m_origHeight = m_height;
m_original = std::move(m_pixels);
DataType origType = m_type;
allocate(m_width, m_height, m_channels, type);
m_origType = origType;
uint32_t s = size() * m_ch;
switch(m_origType)
{
case UINT8:
convertType(s, type, reinterpret_cast<uint8_t*>(m_original.get()), m_pixels.get());
break;
case UINT16:
convertType(s, type, reinterpret_cast<uint16_t*>(m_original.get()), m_pixels.get());
break;
case UINT32:
convertType(s, type, reinterpret_cast<uint32_t*>(m_original.get()), m_pixels.get());
break;
case FLOAT16:
convertType(s, type, reinterpret_cast<F16*>(m_original.get()), m_pixels.get());
break;
case FLOAT32:
convertType(s, type, reinterpret_cast<float*>(m_original.get()), m_pixels.get());
break;
case FLOAT64:
convertType(s, type, reinterpret_cast<double*>(m_original.get()), m_pixels.get());
break;
}
}