Add custom implementation of half float
This commit is contained in:
@@ -54,6 +54,7 @@ set(TENMON_SRC
|
|||||||
statusbar.cpp statusbar.h
|
statusbar.cpp statusbar.h
|
||||||
stfslider.cpp stfslider.h
|
stfslider.cpp stfslider.h
|
||||||
stretchtoolbar.cpp stretchtoolbar.h
|
stretchtoolbar.cpp stretchtoolbar.h
|
||||||
|
tfloat16.h
|
||||||
)
|
)
|
||||||
|
|
||||||
qt_add_resources(TENMON_SRC resources/resources.qrc)
|
qt_add_resources(TENMON_SRC resources/resources.qrc)
|
||||||
|
|||||||
+28
-8
@@ -1,6 +1,7 @@
|
|||||||
#include "rawimage.h"
|
#include "rawimage.h"
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <lcms2.h>
|
#include <lcms2.h>
|
||||||
|
#include <algorithm>
|
||||||
#ifndef NO_QT
|
#ifndef NO_QT
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QElapsedTimer>
|
#include <QElapsedTimer>
|
||||||
@@ -8,9 +9,16 @@
|
|||||||
#include <QColorSpace>
|
#include <QColorSpace>
|
||||||
using F16 = qfloat16;
|
using F16 = qfloat16;
|
||||||
#else
|
#else
|
||||||
#include <algorithm>
|
#define __STDC_WANT_IEC_60559_TYPES_EXT__
|
||||||
|
#include <float.h>
|
||||||
|
#ifdef FLT16_MAX
|
||||||
using F16 = _Float16;
|
using F16 = _Float16;
|
||||||
#endif
|
#else
|
||||||
|
#include "tfloat16.h"
|
||||||
|
using F16 = TFloat16;// this is only for MXE
|
||||||
|
#endif // FLT16_MAX
|
||||||
|
|
||||||
|
#endif // NO_QT
|
||||||
|
|
||||||
int THUMB_SIZE = 128;
|
int THUMB_SIZE = 128;
|
||||||
int THUMB_SIZE_BORDER = 138;
|
int THUMB_SIZE_BORDER = 138;
|
||||||
@@ -464,13 +472,25 @@ void RawImage::convertToThumbnail()
|
|||||||
|
|
||||||
if(m_channels == 1)
|
if(m_channels == 1)
|
||||||
{
|
{
|
||||||
out[idx] = out[idx + 1] = out[idx + 2] = (F16)(in[idx2] * scale);
|
if(scale == 1.0f)
|
||||||
|
out[idx] = out[idx + 1] = out[idx + 2] = (F16)(in[idx2]);
|
||||||
|
else
|
||||||
|
out[idx] = out[idx + 1] = out[idx + 2] = (F16)(in[idx2] * scale);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
out[idx] = (F16)(in[idx2] * scale);
|
if(scale == 1.0f)
|
||||||
out[idx + 1] = (F16)(in[idx2 + 1] * scale);
|
{
|
||||||
out[idx + 2] = (F16)(in[idx2 + 2] * scale);
|
out[idx] = (F16)(in[idx2]);
|
||||||
|
out[idx + 1] = (F16)(in[idx2 + 1]);
|
||||||
|
out[idx + 2] = (F16)(in[idx2 + 2]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
out[idx] = (F16)(in[idx2] * scale);
|
||||||
|
out[idx + 1] = (F16)(in[idx2 + 1] * scale);
|
||||||
|
out[idx + 2] = (F16)(in[idx2 + 2] * scale);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
out[idx + 3] = (F16)1.0f;
|
out[idx + 3] = (F16)1.0f;
|
||||||
}
|
}
|
||||||
@@ -546,9 +566,9 @@ void convertType2(size_t size, const T *src, U *dst)
|
|||||||
|
|
||||||
if constexpr(std::is_integral_v<T> && (std::is_floating_point_v<U> || std::is_same_v<U, F16>))
|
if constexpr(std::is_integral_v<T> && (std::is_floating_point_v<U> || std::is_same_v<U, F16>))
|
||||||
{
|
{
|
||||||
U scale = (U)(1.0 / (double)std::numeric_limits<T>::max());
|
float scale = (float)(1.0 / (double)std::numeric_limits<T>::max());
|
||||||
for(size_t i = 0; i < size; i++)
|
for(size_t i = 0; i < size; i++)
|
||||||
dst[i] = (U)src[i] * scale;
|
dst[i] = (U)(src[i] * scale);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+61
@@ -0,0 +1,61 @@
|
|||||||
|
#ifndef TFLOAT16_H
|
||||||
|
#define TFLOAT16_H
|
||||||
|
|
||||||
|
// crude implementation of float16 for platforms that do not support _Float16
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
class TFloat16
|
||||||
|
{
|
||||||
|
uint16_t b16;
|
||||||
|
public:
|
||||||
|
TFloat16(){ b16 = 0; }
|
||||||
|
explicit inline TFloat16(float f)
|
||||||
|
{
|
||||||
|
uint32_t i = *reinterpret_cast<uint32_t*>(&f);
|
||||||
|
uint32_t sign = (i >> 16) & 0x8000;
|
||||||
|
uint32_t exp = (i >> 23) & 0xff;
|
||||||
|
uint32_t mantisa = (i & 0x7fffff) >> 13;
|
||||||
|
|
||||||
|
b16 = 0;
|
||||||
|
if(exp < 111)
|
||||||
|
{
|
||||||
|
// do nothing it map to 0
|
||||||
|
}
|
||||||
|
else if(exp == 111)
|
||||||
|
{
|
||||||
|
b16 |= sign;
|
||||||
|
b16 |= mantisa;
|
||||||
|
}
|
||||||
|
else if(exp > 142)
|
||||||
|
{
|
||||||
|
b16 = 0x7c00;// inf
|
||||||
|
b16 |= sign;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
b16 |= sign;
|
||||||
|
b16 |= (exp - 112) << 10;
|
||||||
|
b16 |= mantisa;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
friend TFloat16 operator*(TFloat16 a, TFloat16 b)
|
||||||
|
{
|
||||||
|
return TFloat16(static_cast<float>(a) * static_cast<float>(b));
|
||||||
|
}
|
||||||
|
operator float() const
|
||||||
|
{
|
||||||
|
uint32_t i = 0;
|
||||||
|
uint32_t sign = b16 & 0x8000;
|
||||||
|
uint32_t exp = (b16 & 0x7c00) >> 10;
|
||||||
|
if(b16)
|
||||||
|
{
|
||||||
|
i |= sign << 16;
|
||||||
|
i |= (exp + 112) << 23;
|
||||||
|
i |= (b16 & 0x3ff) << 13;
|
||||||
|
}
|
||||||
|
return *reinterpret_cast<float*>(&i);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // TFLOAT16_H
|
||||||
Reference in New Issue
Block a user