mirror of
https://github.com/love2d/love.git
synced 2026-08-16 00:02:12 +02:00
ImageData and Images now support the rg11b10f format.
This commit is contained in:
@@ -43,7 +43,7 @@ Image::Image()
|
||||
{
|
||||
using namespace magpie;
|
||||
|
||||
halfInit(); // Makes sure half-float conversions can be used.
|
||||
float16Init(); // Makes sure half-float conversions can be used.
|
||||
|
||||
formatHandlers = {
|
||||
new PNGHandler,
|
||||
|
||||
@@ -280,7 +280,7 @@ union Row
|
||||
{
|
||||
uint8 *u8;
|
||||
uint16 *u16;
|
||||
half *f16;
|
||||
float16 *f16;
|
||||
float *f32;
|
||||
};
|
||||
|
||||
@@ -293,7 +293,7 @@ static void pasteRGBA8toRGBA16(Row src, Row dst, int w)
|
||||
static void pasteRGBA8toRGBA16F(Row src, Row dst, int w)
|
||||
{
|
||||
for (int i = 0; i < w * 4; i++)
|
||||
dst.f16[i] = floatToHalf(src.u8[i] / 255.0f);
|
||||
dst.f16[i] = float32to16(src.u8[i] / 255.0f);
|
||||
}
|
||||
|
||||
static void pasteRGBA8toRGBA32F(Row src, Row dst, int w)
|
||||
@@ -311,7 +311,7 @@ static void pasteRGBA16toRGBA8(Row src, Row dst, int w)
|
||||
static void pasteRGBA16toRGBA16F(Row src, Row dst, int w)
|
||||
{
|
||||
for (int i = 0; i < w * 4; i++)
|
||||
dst.f16[i] = floatToHalf(src.u16[i] / 65535.0f);
|
||||
dst.f16[i] = float32to16(src.u16[i] / 65535.0f);
|
||||
}
|
||||
|
||||
static void pasteRGBA16toRGBA32F(Row src, Row dst, int w)
|
||||
@@ -323,19 +323,19 @@ static void pasteRGBA16toRGBA32F(Row src, Row dst, int w)
|
||||
static void pasteRGBA16FtoRGBA8(Row src, Row dst, int w)
|
||||
{
|
||||
for (int i = 0; i < w * 4; i++)
|
||||
dst.u8[i] = (uint8) (halfToFloat(src.f16[i]) * 255.0f);
|
||||
dst.u8[i] = (uint8) (float16to32(src.f16[i]) * 255.0f);
|
||||
}
|
||||
|
||||
static void pasteRGBA16FtoRGBA16(Row src, Row dst, int w)
|
||||
{
|
||||
for (int i = 0; i < w * 4; i++)
|
||||
dst.u16[i] = (uint16) (halfToFloat(src.f16[i]) * 65535.0f);
|
||||
dst.u16[i] = (uint16) (float16to32(src.f16[i]) * 65535.0f);
|
||||
}
|
||||
|
||||
static void pasteRGBA16FtoRGBA32F(Row src, Row dst, int w)
|
||||
{
|
||||
for (int i = 0; i < w * 4; i++)
|
||||
dst.f32[i] = halfToFloat(src.f16[i]);
|
||||
dst.f32[i] = float16to32(src.f16[i]);
|
||||
}
|
||||
|
||||
static void pasteRGBA32FtoRGBA8(Row src, Row dst, int w)
|
||||
@@ -353,7 +353,7 @@ static void pasteRGBA32FtoRGBA16(Row src, Row dst, int w)
|
||||
static void pasteRGBA32FtoRGBA16F(Row src, Row dst, int w)
|
||||
{
|
||||
for (int i = 0; i < w * 4; i++)
|
||||
dst.f16[i] = (uint16) floatToHalf(src.f32[i]);
|
||||
dst.f16[i] = (uint16) float32to16(src.f32[i]);
|
||||
}
|
||||
|
||||
void ImageData::paste(ImageData *src, int dx, int dy, int sx, int sy, int sw, int sh)
|
||||
@@ -498,6 +498,7 @@ bool ImageData::validPixelFormat(PixelFormat format)
|
||||
case PIXELFORMAT_RGB5A1:
|
||||
case PIXELFORMAT_RGB565:
|
||||
case PIXELFORMAT_RGB10A2:
|
||||
case PIXELFORMAT_RG11B10F:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#include "common/StringMap.h"
|
||||
#include "common/int.h"
|
||||
#include "common/pixelformat.h"
|
||||
#include "common/halffloat.h"
|
||||
#include "common/floattypes.h"
|
||||
#include "filesystem/FileData.h"
|
||||
#include "thread/threads.h"
|
||||
#include "ImageDataBase.h"
|
||||
@@ -40,12 +40,12 @@ namespace image
|
||||
|
||||
union Pixel
|
||||
{
|
||||
uint8 rgba8[4];
|
||||
uint16 rgba16[4];
|
||||
half rgba16f[4];
|
||||
float rgba32f[4];
|
||||
uint16 packed16;
|
||||
uint32 packed32;
|
||||
uint8 rgba8[4];
|
||||
uint16 rgba16[4];
|
||||
float16 rgba16f[4];
|
||||
float rgba32f[4];
|
||||
uint16 packed16;
|
||||
uint32 packed32;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
// LOVE
|
||||
#include "EXRHandler.h"
|
||||
#include "common/halffloat.h"
|
||||
#include "common/floattypes.h"
|
||||
#include "common/Exception.h"
|
||||
|
||||
// zlib (for tinyexr)
|
||||
@@ -157,12 +157,12 @@ FormatHandler::DecodedImage EXRHandler::decode(Data *data)
|
||||
{
|
||||
img.format = PIXELFORMAT_RGBA16F;
|
||||
|
||||
half *rgba[4] = {nullptr};
|
||||
float16 *rgba[4] = {nullptr};
|
||||
getEXRChannels(exrHeader, exrImage, rgba);
|
||||
|
||||
try
|
||||
{
|
||||
img.data = (unsigned char *) loadEXRChannels(img.width, img.height, rgba, floatToHalf(1.0f));
|
||||
img.data = (unsigned char *) loadEXRChannels(img.width, img.height, rgba, float32to16(1.0f));
|
||||
}
|
||||
catch (love::Exception &)
|
||||
{
|
||||
|
||||
@@ -110,9 +110,9 @@ template <int components>
|
||||
static void luax_checkpixel_float16(lua_State *L, int startidx, Pixel &p)
|
||||
{
|
||||
for (int i = 0; i < std::min(components, 3); i++)
|
||||
p.rgba16f[i] = floatToHalf((float) luaL_checknumber(L, startidx + i));
|
||||
p.rgba16f[i] = float32to16((float) luaL_checknumber(L, startidx + i));
|
||||
if (components > 3)
|
||||
p.rgba16f[3] = floatToHalf((float) luaL_optnumber(L, startidx + 3, 1.0));
|
||||
p.rgba16f[3] = float32to16((float) luaL_optnumber(L, startidx + 3, 1.0));
|
||||
}
|
||||
|
||||
template <int components>
|
||||
@@ -187,40 +187,49 @@ static void luax_checkpixel_rgba32f(lua_State *L, int startidx, Pixel &p)
|
||||
static void luax_checkpixel_rgba4(lua_State *L, int startidx, Pixel &p)
|
||||
{
|
||||
// LSB->MSB: [a, b, g, r]
|
||||
uint16 r = ((uint16) ((luax_checknumberclamped01(L, startidx + 0) * 0xF) + 0.5)) << 12;
|
||||
uint16 g = ((uint16) ((luax_checknumberclamped01(L, startidx + 1) * 0xF) + 0.5)) << 8;
|
||||
uint16 b = ((uint16) ((luax_checknumberclamped01(L, startidx + 2) * 0xF) + 0.5)) << 4;
|
||||
uint16 a = ((uint16) ((luax_optnumberclamped01(L, startidx + 3, 1.0) * 0xF) + 0.5)) << 0;
|
||||
p.packed16 = r | g | b | a;
|
||||
uint16 r = (uint16) ((luax_checknumberclamped01(L, startidx + 0) * 0xF) + 0.5);
|
||||
uint16 g = (uint16) ((luax_checknumberclamped01(L, startidx + 1) * 0xF) + 0.5);
|
||||
uint16 b = (uint16) ((luax_checknumberclamped01(L, startidx + 2) * 0xF) + 0.5);
|
||||
uint16 a = (uint16) ((luax_optnumberclamped01(L, startidx + 3, 1.0) * 0xF) + 0.5);
|
||||
p.packed16 = (r << 12) | (g << 8) | (b << 4) | (a << 0);
|
||||
}
|
||||
|
||||
static void luax_checkpixel_rgb5a1(lua_State *L, int startidx, Pixel &p)
|
||||
{
|
||||
// LSB->MSB: [a, b, g, r]
|
||||
uint16 r = ((uint16) ((luax_checknumberclamped01(L, startidx + 0) * 0x1F) + 0.5)) << 11;
|
||||
uint16 g = ((uint16) ((luax_checknumberclamped01(L, startidx + 1) * 0x1F) + 0.5)) << 6;
|
||||
uint16 b = ((uint16) ((luax_checknumberclamped01(L, startidx + 2) * 0x1F) + 0.5)) << 1;
|
||||
uint16 a = ((uint16) ((luax_optnumberclamped01(L, startidx + 3, 1.0) * 0x1) + 0.5)) << 0;
|
||||
p.packed16 = r | g | b | a;
|
||||
uint16 r = (uint16) ((luax_checknumberclamped01(L, startidx + 0) * 0x1F) + 0.5);
|
||||
uint16 g = (uint16) ((luax_checknumberclamped01(L, startidx + 1) * 0x1F) + 0.5);
|
||||
uint16 b = (uint16) ((luax_checknumberclamped01(L, startidx + 2) * 0x1F) + 0.5);
|
||||
uint16 a = (uint16) ((luax_optnumberclamped01(L, startidx + 3, 1.0) * 0x1) + 0.5);
|
||||
p.packed16 = (r << 11) | (g << 6) | (b << 1) | (a << 0);
|
||||
}
|
||||
|
||||
static void luax_checkpixel_rgb565(lua_State *L, int startidx, Pixel &p)
|
||||
{
|
||||
// LSB->MSB: [b, g, r]
|
||||
uint16 r = ((uint16) ((luax_checknumberclamped01(L, startidx + 0) * 0x1F) + 0.5)) << 11;
|
||||
uint16 g = ((uint16) ((luax_checknumberclamped01(L, startidx + 1) * 0x3F) + 0.5)) << 5;
|
||||
uint16 b = ((uint16) ((luax_checknumberclamped01(L, startidx + 2) * 0x1F) + 0.5)) << 0;
|
||||
p.packed16 = r | g | b;
|
||||
uint16 r = (uint16) ((luax_checknumberclamped01(L, startidx + 0) * 0x1F) + 0.5);
|
||||
uint16 g = (uint16) ((luax_checknumberclamped01(L, startidx + 1) * 0x3F) + 0.5);
|
||||
uint16 b = (uint16) ((luax_checknumberclamped01(L, startidx + 2) * 0x1F) + 0.5);
|
||||
p.packed16 = (r << 11) | (g << 5) | (b << 0);
|
||||
}
|
||||
|
||||
static void luax_checkpixel_rgb10a2(lua_State *L, int startidx, Pixel &p)
|
||||
{
|
||||
// LSB->MSB: [r, g, b, a]
|
||||
uint32 r = ((uint32) ((luax_checknumberclamped01(L, startidx + 0) * 0x3FF) + 0.5)) << 0;
|
||||
uint32 g = ((uint32) ((luax_checknumberclamped01(L, startidx + 1) * 0x3FF) + 0.5)) << 10;
|
||||
uint32 b = ((uint32) ((luax_checknumberclamped01(L, startidx + 2) * 0x3FF) + 0.5)) << 20;
|
||||
uint32 a = ((uint32) ((luax_optnumberclamped01(L, startidx + 3, 1.0) * 0x3) + 0.5)) << 30;
|
||||
p.packed32 = r | g | b | a;
|
||||
uint32 r = (uint32) ((luax_checknumberclamped01(L, startidx + 0) * 0x3FF) + 0.5);
|
||||
uint32 g = (uint32) ((luax_checknumberclamped01(L, startidx + 1) * 0x3FF) + 0.5);
|
||||
uint32 b = (uint32) ((luax_checknumberclamped01(L, startidx + 2) * 0x3FF) + 0.5);
|
||||
uint32 a = (uint32) ((luax_optnumberclamped01(L, startidx + 3, 1.0) * 0x3) + 0.5);
|
||||
p.packed32 = (r << 0) | (g << 10) | (b << 20) | (a << 30);
|
||||
}
|
||||
|
||||
static void luax_checkpixel_rg11b10f(lua_State *L, int startidx, Pixel &p)
|
||||
{
|
||||
// LSB->MSB: [r, g, b]
|
||||
float11 r = float32to11((float) luaL_checknumber(L, startidx + 0));
|
||||
float11 g = float32to11((float) luaL_checknumber(L, startidx + 1));
|
||||
float10 b = float32to10((float) luaL_checknumber(L, startidx + 2));
|
||||
p.packed32 = (r << 0) | (g << 11) | (b << 22);
|
||||
}
|
||||
|
||||
static lua_Number fillValues[] = {0.0, 0.0, 0.0, 1.0};
|
||||
@@ -249,7 +258,7 @@ template <int components>
|
||||
static int luax_pushpixel_float16(lua_State *L, const Pixel &p)
|
||||
{
|
||||
for (int i = 0; i < components; i++)
|
||||
lua_pushnumber(L, (lua_Number) halfToFloat(p.rgba16f[i]));
|
||||
lua_pushnumber(L, (lua_Number) float16to32(p.rgba16f[i]));
|
||||
for (int i = components; i < 4; i++)
|
||||
lua_pushnumber(L, fillValues[i]);
|
||||
return 4;
|
||||
@@ -358,10 +367,20 @@ static int luax_pushpixel_rgb565(lua_State *L, const Pixel &p)
|
||||
static int luax_pushpixel_rgb10a2(lua_State *L, const Pixel &p)
|
||||
{
|
||||
// LSB->MSB: [r, g, b, a]
|
||||
lua_pushnumber(L, ((p.packed16 >> 0) & 0x3FF) / (double)0x3FF);
|
||||
lua_pushnumber(L, ((p.packed16 >> 10) & 0x3FF) / (double)0x3FF);
|
||||
lua_pushnumber(L, ((p.packed16 >> 20) & 0x3FF) / (double)0x3FF);
|
||||
lua_pushnumber(L, ((p.packed16 >> 30) & 0x3) / (double)0x3);
|
||||
lua_pushnumber(L, ((p.packed32 >> 0) & 0x3FF) / (double)0x3FF);
|
||||
lua_pushnumber(L, ((p.packed32 >> 10) & 0x3FF) / (double)0x3FF);
|
||||
lua_pushnumber(L, ((p.packed32 >> 20) & 0x3FF) / (double)0x3FF);
|
||||
lua_pushnumber(L, ((p.packed32 >> 30) & 0x3) / (double)0x3);
|
||||
return 4;
|
||||
}
|
||||
|
||||
static int luax_pushpixel_rg11b10f(lua_State *L, const Pixel &p)
|
||||
{
|
||||
// LSB->MSB: [r, g, b]
|
||||
lua_pushnumber(L, float11to32((float11) ((p.packed32 >> 0) & 0x7FF)));
|
||||
lua_pushnumber(L, float11to32((float11) ((p.packed32 >> 11) & 0x7FF)));
|
||||
lua_pushnumber(L, float10to32((float10) ((p.packed32 >> 22) & 0x3FF)));
|
||||
lua_pushnumber(L, 1.0);
|
||||
return 4;
|
||||
}
|
||||
|
||||
@@ -526,8 +545,14 @@ struct FFI_ImageData
|
||||
void (*lockMutex)(Proxy *p);
|
||||
void (*unlockMutex)(Proxy *p);
|
||||
|
||||
float (*halfToFloat)(half h);
|
||||
half (*floatToHalf)(float f);
|
||||
float (*float16to32)(float16 f);
|
||||
float16 (*float32to16)(float f);
|
||||
|
||||
float (*float11to32)(float11 f);
|
||||
float11 (*float32to11)(float f);
|
||||
|
||||
float (*float10to32)(float10 f);
|
||||
float10 (*float32to10)(float f);
|
||||
};
|
||||
|
||||
static FFI_ImageData ffifuncs =
|
||||
@@ -546,8 +571,12 @@ static FFI_ImageData ffifuncs =
|
||||
i->getMutex()->unlock();
|
||||
},
|
||||
|
||||
halfToFloat,
|
||||
floatToHalf,
|
||||
float16to32,
|
||||
float32to16,
|
||||
float11to32,
|
||||
float32to11,
|
||||
float10to32,
|
||||
float32to10,
|
||||
};
|
||||
|
||||
static const luaL_Reg w_ImageData_functions[] =
|
||||
@@ -571,39 +600,41 @@ static const luaL_Reg w_ImageData_functions[] =
|
||||
|
||||
extern "C" int luaopen_imagedata(lua_State *L)
|
||||
{
|
||||
checkFormats[PIXELFORMAT_R8] = luax_checkpixel_r8;
|
||||
checkFormats[PIXELFORMAT_RG8] = luax_checkpixel_rg8;
|
||||
checkFormats[PIXELFORMAT_RGBA8] = luax_checkpixel_rgba8;
|
||||
checkFormats[PIXELFORMAT_R16] = luax_checkpixel_r16;
|
||||
checkFormats[PIXELFORMAT_RG16] = luax_checkpixel_rg16;
|
||||
checkFormats[PIXELFORMAT_RGBA16] = luax_checkpixel_rgba16;
|
||||
checkFormats[PIXELFORMAT_R16F] = luax_checkpixel_r16f;
|
||||
checkFormats[PIXELFORMAT_RG16F] = luax_checkpixel_rg16f;
|
||||
checkFormats[PIXELFORMAT_RGBA16F] = luax_checkpixel_rgba16f;
|
||||
checkFormats[PIXELFORMAT_R32F] = luax_checkpixel_r32f;
|
||||
checkFormats[PIXELFORMAT_RG32F] = luax_checkpixel_rg32f;
|
||||
checkFormats[PIXELFORMAT_RGBA32F] = luax_checkpixel_rgba32f;
|
||||
checkFormats[PIXELFORMAT_RGBA4] = luax_checkpixel_rgba4;
|
||||
checkFormats[PIXELFORMAT_RGB5A1] = luax_checkpixel_rgb5a1;
|
||||
checkFormats[PIXELFORMAT_RGB565] = luax_checkpixel_rgb565;
|
||||
checkFormats[PIXELFORMAT_RGB10A2] = luax_checkpixel_rgb10a2;
|
||||
checkFormats[PIXELFORMAT_R8] = luax_checkpixel_r8;
|
||||
checkFormats[PIXELFORMAT_RG8] = luax_checkpixel_rg8;
|
||||
checkFormats[PIXELFORMAT_RGBA8] = luax_checkpixel_rgba8;
|
||||
checkFormats[PIXELFORMAT_R16] = luax_checkpixel_r16;
|
||||
checkFormats[PIXELFORMAT_RG16] = luax_checkpixel_rg16;
|
||||
checkFormats[PIXELFORMAT_RGBA16] = luax_checkpixel_rgba16;
|
||||
checkFormats[PIXELFORMAT_R16F] = luax_checkpixel_r16f;
|
||||
checkFormats[PIXELFORMAT_RG16F] = luax_checkpixel_rg16f;
|
||||
checkFormats[PIXELFORMAT_RGBA16F] = luax_checkpixel_rgba16f;
|
||||
checkFormats[PIXELFORMAT_R32F] = luax_checkpixel_r32f;
|
||||
checkFormats[PIXELFORMAT_RG32F] = luax_checkpixel_rg32f;
|
||||
checkFormats[PIXELFORMAT_RGBA32F] = luax_checkpixel_rgba32f;
|
||||
checkFormats[PIXELFORMAT_RGBA4] = luax_checkpixel_rgba4;
|
||||
checkFormats[PIXELFORMAT_RGB5A1] = luax_checkpixel_rgb5a1;
|
||||
checkFormats[PIXELFORMAT_RGB565] = luax_checkpixel_rgb565;
|
||||
checkFormats[PIXELFORMAT_RGB10A2] = luax_checkpixel_rgb10a2;
|
||||
checkFormats[PIXELFORMAT_RG11B10F] = luax_checkpixel_rg11b10f;
|
||||
|
||||
pushFormats[PIXELFORMAT_R8] = luax_pushpixel_r8;
|
||||
pushFormats[PIXELFORMAT_RG8] = luax_pushpixel_rg8;
|
||||
pushFormats[PIXELFORMAT_RGBA8] = luax_pushpixel_rgba8;
|
||||
pushFormats[PIXELFORMAT_R16] = luax_pushpixel_r16;
|
||||
pushFormats[PIXELFORMAT_RG16] = luax_pushpixel_rg16;
|
||||
pushFormats[PIXELFORMAT_RGBA16] = luax_pushpixel_rgba16;
|
||||
pushFormats[PIXELFORMAT_R16F] = luax_pushpixel_r16f;
|
||||
pushFormats[PIXELFORMAT_RG16F] = luax_pushpixel_rg16f;
|
||||
pushFormats[PIXELFORMAT_RGBA16F] = luax_pushpixel_rgba16f;
|
||||
pushFormats[PIXELFORMAT_R32F] = luax_pushpixel_r32f;
|
||||
pushFormats[PIXELFORMAT_RG32F] = luax_pushpixel_rg32f;
|
||||
pushFormats[PIXELFORMAT_RGBA32F] = luax_pushpixel_rgba32f;
|
||||
pushFormats[PIXELFORMAT_RGBA4] = luax_pushpixel_rgba4;
|
||||
pushFormats[PIXELFORMAT_RGB5A1] = luax_pushpixel_rgb5a1;
|
||||
pushFormats[PIXELFORMAT_RGB565] = luax_pushpixel_rgb565;
|
||||
pushFormats[PIXELFORMAT_RGB10A2] = luax_pushpixel_rgb10a2;
|
||||
pushFormats[PIXELFORMAT_R8] = luax_pushpixel_r8;
|
||||
pushFormats[PIXELFORMAT_RG8] = luax_pushpixel_rg8;
|
||||
pushFormats[PIXELFORMAT_RGBA8] = luax_pushpixel_rgba8;
|
||||
pushFormats[PIXELFORMAT_R16] = luax_pushpixel_r16;
|
||||
pushFormats[PIXELFORMAT_RG16] = luax_pushpixel_rg16;
|
||||
pushFormats[PIXELFORMAT_RGBA16] = luax_pushpixel_rgba16;
|
||||
pushFormats[PIXELFORMAT_R16F] = luax_pushpixel_r16f;
|
||||
pushFormats[PIXELFORMAT_RG16F] = luax_pushpixel_rg16f;
|
||||
pushFormats[PIXELFORMAT_RGBA16F] = luax_pushpixel_rgba16f;
|
||||
pushFormats[PIXELFORMAT_R32F] = luax_pushpixel_r32f;
|
||||
pushFormats[PIXELFORMAT_RG32F] = luax_pushpixel_rg32f;
|
||||
pushFormats[PIXELFORMAT_RGBA32F] = luax_pushpixel_rgba32f;
|
||||
pushFormats[PIXELFORMAT_RGBA4] = luax_pushpixel_rgba4;
|
||||
pushFormats[PIXELFORMAT_RGB5A1] = luax_pushpixel_rgb5a1;
|
||||
pushFormats[PIXELFORMAT_RGB565] = luax_pushpixel_rgb565;
|
||||
pushFormats[PIXELFORMAT_RGB10A2] = luax_pushpixel_rgb10a2;
|
||||
pushFormats[PIXELFORMAT_RG11B10F] = luax_pushpixel_rg11b10f;
|
||||
|
||||
int ret = luax_register_type(L, &ImageData::type, data::w_Data_functions, w_ImageData_functions, nullptr);
|
||||
|
||||
|
||||
@@ -78,15 +78,23 @@ if not bitstatus then return end
|
||||
|
||||
pcall(ffi.cdef, [[
|
||||
typedef struct Proxy Proxy;
|
||||
typedef uint16_t half;
|
||||
typedef uint16_t float16;
|
||||
typedef uint16_t float11;
|
||||
typedef uint16_t float10;
|
||||
|
||||
typedef struct FFI_ImageData
|
||||
{
|
||||
void (*lockMutex)(Proxy *p);
|
||||
void (*unlockMutex)(Proxy *p);
|
||||
|
||||
float (*halfToFloat)(half h);
|
||||
half (*floatToHalf)(float f);
|
||||
float (*float16to32)(float16 f);
|
||||
float16 (*float32to16)(float f);
|
||||
|
||||
float (*float11to32)(float11 f);
|
||||
float11 (*float32to11)(float f);
|
||||
|
||||
float (*float10to32)(float10 f);
|
||||
float10 (*float32to10)(float f);
|
||||
} FFI_ImageData;
|
||||
|
||||
struct ImageData_Pixel_R8 { uint8_t r; };
|
||||
@@ -97,9 +105,9 @@ struct ImageData_Pixel_R16 { uint16_t r; };
|
||||
struct ImageData_Pixel_RG16 { uint16_t r, g; };
|
||||
struct ImageData_Pixel_RGBA16 { uint16_t r, g, b, a; };
|
||||
|
||||
struct ImageData_Pixel_R16F { half r; };
|
||||
struct ImageData_Pixel_RG16F { half r, g; };
|
||||
struct ImageData_Pixel_RGBA16F { half r, g, b, a; };
|
||||
struct ImageData_Pixel_R16F { float16 r; };
|
||||
struct ImageData_Pixel_RG16F { float16 r, g; };
|
||||
struct ImageData_Pixel_RGBA16F { float16 r, g, b, a; };
|
||||
|
||||
struct ImageData_Pixel_R32F { float r; };
|
||||
struct ImageData_Pixel_RG32F { float r, g; };
|
||||
@@ -109,6 +117,7 @@ struct ImageData_Pixel_RGBA4 { uint16_t rgba; };
|
||||
struct ImageData_Pixel_RGB5A1 { uint16_t rgba; };
|
||||
struct ImageData_Pixel_RGB565 { uint16_t rgb; };
|
||||
struct ImageData_Pixel_RGB10A2 { uint32_t rgba; };
|
||||
struct ImageData_Pixel_RG11B10F { uint32_t rgb; };
|
||||
]])
|
||||
|
||||
local ffifuncs = ffi.cast("FFI_ImageData **", ffifuncspointer_str)[0]
|
||||
@@ -179,35 +188,35 @@ local conversions = {
|
||||
r16f = {
|
||||
pointer = ffi.typeof("struct ImageData_Pixel_R16F *"),
|
||||
tolua = function(self)
|
||||
return tonumber(ffifuncs.halfToFloat(self.r)), 0, 0, 1
|
||||
return tonumber(ffifuncs.float16to32(self.r)), 0, 0, 1
|
||||
end,
|
||||
fromlua = function(self, r)
|
||||
self.r = ffifuncs.floatToHalf(r)
|
||||
self.r = ffifuncs.float32to16(r)
|
||||
end,
|
||||
},
|
||||
rg16f = {
|
||||
pointer = ffi.typeof("struct ImageData_Pixel_RG16F *"),
|
||||
tolua = function(self)
|
||||
return tonumber(ffifuncs.halfToFloat(self.r)), tonumber(ffifuncs.halfToFloat(self.g)), 0, 1
|
||||
return tonumber(ffifuncs.float16to32(self.r)), tonumber(ffifuncs.float16to32(self.g)), 0, 1
|
||||
end,
|
||||
fromlua = function(self, r, g, b, a)
|
||||
self.r = ffifuncs.floatToHalf(r)
|
||||
self.g = ffifuncs.floatToHalf(g)
|
||||
self.r = ffifuncs.float32to16(r)
|
||||
self.g = ffifuncs.float32to16(g)
|
||||
end,
|
||||
},
|
||||
rgba16f = {
|
||||
pointer = ffi.typeof("struct ImageData_Pixel_RGBA16F *"),
|
||||
tolua = function(self)
|
||||
return tonumber(ffifuncs.halfToFloat(self.r)),
|
||||
tonumber(ffifuncs.halfToFloat(self.g)),
|
||||
tonumber(ffifuncs.halfToFloat(self.b)),
|
||||
tonumber(ffifuncs.halfToFloat(self.a))
|
||||
return tonumber(ffifuncs.float16to32(self.r)),
|
||||
tonumber(ffifuncs.float16to32(self.g)),
|
||||
tonumber(ffifuncs.float16to32(self.b)),
|
||||
tonumber(ffifuncs.float16to32(self.a))
|
||||
end,
|
||||
fromlua = function(self, r, g, b, a)
|
||||
self.r = ffifuncs.floatToHalf(r)
|
||||
self.g = ffifuncs.floatToHalf(g)
|
||||
self.b = ffifuncs.floatToHalf(b)
|
||||
self.a = ffifuncs.floatToHalf(a == nil and 1.0 or a)
|
||||
self.r = ffifuncs.float32to16(r)
|
||||
self.g = ffifuncs.float32to16(g)
|
||||
self.b = ffifuncs.float32to16(b)
|
||||
self.a = ffifuncs.float32to16(a == nil and 1.0 or a)
|
||||
end,
|
||||
},
|
||||
r32f = {
|
||||
@@ -319,6 +328,24 @@ local conversions = {
|
||||
self.rgba = bit.bor(r, bit.lshift(g, 10), bit.lshift(b, 20), bit.lshift(a, 30))
|
||||
end,
|
||||
},
|
||||
rg11b10f = {
|
||||
-- LSB->MSB: [r, g, b]
|
||||
pointer = ffi.typeof("struct ImageData_Pixel_RG11B10F *"),
|
||||
tolua = function(self)
|
||||
local rgb = self.rgb
|
||||
local r = tonumber(ffifuncs.float11to32(bit.band(rgb, 0x7FF)))
|
||||
local g = tonumber(ffifuncs.float11to32(bit.band(bit.rshift(rgb, 11), 0x7FF)))
|
||||
local b = tonumber(ffifuncs.float10to32(bit.band(bit.rshift(rgb, 22), 0x3FF)))
|
||||
return r, g, b, 1
|
||||
end,
|
||||
fromlua = function(self, r, g, b, a)
|
||||
self.rgb = bit.bor(
|
||||
ffifuncs.float32to11(r),
|
||||
bit.lshift(ffifuncs.float32to11(g), 11),
|
||||
bit.lshift(ffifuncs.float32to10(b), 22)
|
||||
)
|
||||
end,
|
||||
},
|
||||
}
|
||||
|
||||
local _getWidth = ImageData.getWidth
|
||||
|
||||
Reference in New Issue
Block a user