mirror of
https://github.com/love2d/love.git
synced 2026-08-12 00:20:52 +02:00
ImageData and Images now support the rg11b10f format.
This commit is contained in:
+2
-2
@@ -279,8 +279,8 @@ set(LOVE_SRC_COMMON
|
||||
src/common/EnumMap.h
|
||||
src/common/Exception.cpp
|
||||
src/common/Exception.h
|
||||
src/common/halffloat.cpp
|
||||
src/common/halffloat.h
|
||||
src/common/floattypes.cpp
|
||||
src/common/floattypes.h
|
||||
src/common/int.h
|
||||
src/common/math.h
|
||||
src/common/Matrix.cpp
|
||||
|
||||
@@ -64,6 +64,9 @@
|
||||
217DFC101D9F6D490055D849 /* url.lua.h in Headers */ = {isa = PBXBuildFile; fileRef = 217DFBD41D9F6D490055D849 /* url.lua.h */; };
|
||||
217DFC111D9F6D490055D849 /* usocket.c in Sources */ = {isa = PBXBuildFile; fileRef = 217DFBD51D9F6D490055D849 /* usocket.c */; };
|
||||
217DFC121D9F6D490055D849 /* usocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 217DFBD61D9F6D490055D849 /* usocket.h */; };
|
||||
FA0A3A5F23366CE9001C269E /* floattypes.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0A3A5D23366CE9001C269E /* floattypes.h */; };
|
||||
FA0A3A6023366CE9001C269E /* floattypes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0A3A5E23366CE9001C269E /* floattypes.cpp */; };
|
||||
FA0A3A6123366CE9001C269E /* floattypes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0A3A5E23366CE9001C269E /* floattypes.cpp */; };
|
||||
FA0B791B1A958E3B000E1D17 /* b64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B78F71A958E3B000E1D17 /* b64.cpp */; };
|
||||
FA0B791C1A958E3B000E1D17 /* b64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0B78F71A958E3B000E1D17 /* b64.cpp */; };
|
||||
FA0B791D1A958E3B000E1D17 /* b64.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0B78F81A958E3B000E1D17 /* b64.h */; };
|
||||
@@ -937,9 +940,6 @@
|
||||
FA8951A21AA2EDF300EC385A /* wrap_Event.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA8951A01AA2EDF300EC385A /* wrap_Event.cpp */; };
|
||||
FA8951A31AA2EDF300EC385A /* wrap_Event.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA8951A01AA2EDF300EC385A /* wrap_Event.cpp */; };
|
||||
FA8951A41AA2EDF300EC385A /* wrap_Event.h in Headers */ = {isa = PBXBuildFile; fileRef = FA8951A11AA2EDF300EC385A /* wrap_Event.h */; };
|
||||
FA91591E1CF1ED7500A7053F /* halffloat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA91591C1CF1ED7500A7053F /* halffloat.cpp */; };
|
||||
FA91591F1CF1ED7500A7053F /* halffloat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA91591C1CF1ED7500A7053F /* halffloat.cpp */; };
|
||||
FA9159201CF1ED7500A7053F /* halffloat.h in Headers */ = {isa = PBXBuildFile; fileRef = FA91591D1CF1ED7500A7053F /* halffloat.h */; };
|
||||
FA91DA8B1F377C3900C80E33 /* deprecation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA91DA891F377C3900C80E33 /* deprecation.cpp */; };
|
||||
FA91DA8C1F377C3900C80E33 /* deprecation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA91DA891F377C3900C80E33 /* deprecation.cpp */; };
|
||||
FA91DA8D1F377C3900C80E33 /* deprecation.h in Headers */ = {isa = PBXBuildFile; fileRef = FA91DA8A1F377C3900C80E33 /* deprecation.h */; };
|
||||
@@ -1281,6 +1281,8 @@
|
||||
217DFBD61D9F6D490055D849 /* usocket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = usocket.h; sourceTree = "<group>"; };
|
||||
503971A86B7167A91B670FBA /* boot.lua.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = boot.lua.h; sourceTree = "<group>"; };
|
||||
FA08F5AE16C7525600F007B5 /* liblove-macosx.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "liblove-macosx.plist"; path = "macosx/liblove-macosx.plist"; sourceTree = "<group>"; };
|
||||
FA0A3A5D23366CE9001C269E /* floattypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = floattypes.h; sourceTree = "<group>"; };
|
||||
FA0A3A5E23366CE9001C269E /* floattypes.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = floattypes.cpp; sourceTree = "<group>"; };
|
||||
FA0B78DD1A958B90000E1D17 /* liblove.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = liblove.a; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
FA0B78F71A958E3B000E1D17 /* b64.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = b64.cpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
|
||||
FA0B78F81A958E3B000E1D17 /* b64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = b64.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
|
||||
@@ -1876,8 +1878,6 @@
|
||||
FA7DA04C1C16874A0056B200 /* wrap_Math.lua */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = wrap_Math.lua; sourceTree = "<group>"; };
|
||||
FA8951A01AA2EDF300EC385A /* wrap_Event.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Event.cpp; sourceTree = "<group>"; };
|
||||
FA8951A11AA2EDF300EC385A /* wrap_Event.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Event.h; sourceTree = "<group>"; };
|
||||
FA91591C1CF1ED7500A7053F /* halffloat.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = halffloat.cpp; sourceTree = "<group>"; };
|
||||
FA91591D1CF1ED7500A7053F /* halffloat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = halffloat.h; sourceTree = "<group>"; };
|
||||
FA91DA891F377C3900C80E33 /* deprecation.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = deprecation.cpp; sourceTree = "<group>"; };
|
||||
FA91DA8A1F377C3900C80E33 /* deprecation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = deprecation.h; sourceTree = "<group>"; };
|
||||
FA93C4501F315B960087CCD4 /* FormatHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FormatHandler.h; sourceTree = "<group>"; };
|
||||
@@ -2164,8 +2164,8 @@
|
||||
FA0B78FD1A958E3B000E1D17 /* EnumMap.h */,
|
||||
FA0B78FE1A958E3B000E1D17 /* Exception.cpp */,
|
||||
FA0B78FF1A958E3B000E1D17 /* Exception.h */,
|
||||
FA91591C1CF1ED7500A7053F /* halffloat.cpp */,
|
||||
FA91591D1CF1ED7500A7053F /* halffloat.h */,
|
||||
FA0A3A5E23366CE9001C269E /* floattypes.cpp */,
|
||||
FA0A3A5D23366CE9001C269E /* floattypes.h */,
|
||||
FA0B79001A958E3B000E1D17 /* int.h */,
|
||||
FA0B7EF01A959D2C000E1D17 /* ios.h */,
|
||||
FA0B7EF11A959D2C000E1D17 /* ios.mm */,
|
||||
@@ -3795,7 +3795,6 @@
|
||||
217DFBEE1D9F6D490055D849 /* luasocket.h in Headers */,
|
||||
FACA02F31F5E396B0084B28F /* HashFunction.h in Headers */,
|
||||
FA0B7ED01A95902C000E1D17 /* wrap_LuaThread.h in Headers */,
|
||||
FA9159201CF1ED7500A7053F /* halffloat.h in Headers */,
|
||||
FA0B7CE41A95902C000E1D17 /* wrap_Audio.h in Headers */,
|
||||
FA0B7A7F1A958EA3000E1D17 /* b2ContactSolver.h in Headers */,
|
||||
FADF540F1E3D7CDD00012CC0 /* wrap_Video.h in Headers */,
|
||||
@@ -3926,6 +3925,7 @@
|
||||
FA0B7CD81A95902C000E1D17 /* Audio.h in Headers */,
|
||||
FA0B7CF61A95902C000E1D17 /* File.h in Headers */,
|
||||
FA0B7E961A95902C000E1D17 /* Mpg123Decoder.h in Headers */,
|
||||
FA0A3A5F23366CE9001C269E /* floattypes.h in Headers */,
|
||||
FADF54091E3D78F700012CC0 /* Video.h in Headers */,
|
||||
FAA54ACB1F91660400A8FA7B /* TheoraVideoStream.h in Headers */,
|
||||
FA0B7DD51A95902C000E1D17 /* BezierCurve.h in Headers */,
|
||||
@@ -4271,7 +4271,6 @@
|
||||
FA0B7EA41A95902C000E1D17 /* SoundData.cpp in Sources */,
|
||||
FA0B7D041A95902C000E1D17 /* wrap_DroppedFile.cpp in Sources */,
|
||||
FAF1406A1E20934C00F898D2 /* glslang_tab.cpp in Sources */,
|
||||
FA91591F1CF1ED7500A7053F /* halffloat.cpp in Sources */,
|
||||
FA8951A31AA2EDF300EC385A /* wrap_Event.cpp in Sources */,
|
||||
FADF540E1E3D7CDD00012CC0 /* wrap_Video.cpp in Sources */,
|
||||
FA0B7A361A958EA3000E1D17 /* b2Distance.cpp in Sources */,
|
||||
@@ -4404,6 +4403,7 @@
|
||||
FA0B7E791A95902C000E1D17 /* wrap_WheelJoint.cpp in Sources */,
|
||||
FA0B7DDD1A95902C000E1D17 /* wrap_BezierCurve.cpp in Sources */,
|
||||
FA0B7A2A1A958EA3000E1D17 /* b2BroadPhase.cpp in Sources */,
|
||||
FA0A3A6123366CE9001C269E /* floattypes.cpp in Sources */,
|
||||
FA0B7A811A958EA3000E1D17 /* b2EdgeAndCircleContact.cpp in Sources */,
|
||||
FAF188A01E9DBC4B008C1479 /* depthstencil.cpp in Sources */,
|
||||
FA0B7D071A95902C000E1D17 /* wrap_File.cpp in Sources */,
|
||||
@@ -4794,6 +4794,7 @@
|
||||
FAF140711E20934C00F898D2 /* Intermediate.cpp in Sources */,
|
||||
FAC7CD7D1FE35E95006A60C7 /* physfs_platform_winrt.cpp in Sources */,
|
||||
FA0B7E541A95902C000E1D17 /* wrap_GearJoint.cpp in Sources */,
|
||||
FA0A3A6023366CE9001C269E /* floattypes.cpp in Sources */,
|
||||
FA41A3C81C0A1F950084430C /* ASTCHandler.cpp in Sources */,
|
||||
FA0B7E781A95902C000E1D17 /* wrap_WheelJoint.cpp in Sources */,
|
||||
FA0B7DDC1A95902C000E1D17 /* wrap_BezierCurve.cpp in Sources */,
|
||||
@@ -4907,7 +4908,6 @@
|
||||
FAC756F51E4F99B400B91289 /* Effect.cpp in Sources */,
|
||||
FA620A3A1AA305F6005DB4C2 /* types.cpp in Sources */,
|
||||
FA0B7DD31A95902C000E1D17 /* BezierCurve.cpp in Sources */,
|
||||
FA91591E1CF1ED7500A7053F /* halffloat.cpp in Sources */,
|
||||
FA0B7E7B1A95902C000E1D17 /* wrap_World.cpp in Sources */,
|
||||
FA0B7B281A958EA3000E1D17 /* simplexnoise1234.cpp in Sources */,
|
||||
FA0B7D421A95902C000E1D17 /* OpenGL.cpp in Sources */,
|
||||
|
||||
@@ -18,14 +18,17 @@
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
**/
|
||||
|
||||
#include "halffloat.h"
|
||||
#include "floattypes.h"
|
||||
|
||||
#include <limits>
|
||||
#include <cmath>
|
||||
|
||||
namespace love
|
||||
{
|
||||
|
||||
// Code from ftp://www.fox-toolkit.org/pub/fasthalffloatconversion.pdf
|
||||
|
||||
static bool initialized = false;
|
||||
static bool halfInitialized = false;
|
||||
|
||||
// tables for half -> float conversions
|
||||
static uint32 mantissatable[2048];
|
||||
@@ -54,15 +57,15 @@ static uint32 convertMantissa(uint32 i)
|
||||
return m | e; // Return combined number
|
||||
}
|
||||
|
||||
void halfInit()
|
||||
void float16Init()
|
||||
{
|
||||
if (initialized)
|
||||
if (halfInitialized)
|
||||
return;
|
||||
|
||||
initialized = true;
|
||||
halfInitialized = true;
|
||||
|
||||
|
||||
// tables for half -> float conversions.
|
||||
// tables for float16 -> float32 conversions.
|
||||
|
||||
mantissatable[0] = 0;
|
||||
|
||||
@@ -93,7 +96,7 @@ void halfInit()
|
||||
}
|
||||
|
||||
|
||||
// tables for float -> half conversions.
|
||||
// tables for float32 -> float16 conversions.
|
||||
|
||||
for (uint32 i = 0; i < 256; i++)
|
||||
{
|
||||
@@ -137,20 +140,115 @@ void halfInit()
|
||||
}
|
||||
}
|
||||
|
||||
float halfToFloat(half h)
|
||||
static inline uint32 asuint32(float f)
|
||||
{
|
||||
union { float f; uint32 i; } conv;
|
||||
union { float f; uint32 u; } conv;
|
||||
conv.f = f;
|
||||
return conv.u;
|
||||
}
|
||||
|
||||
conv.i = mantissatable[offsettable[h >> 10] + (h & 0x3FF)] + exponenttable[h >> 10];
|
||||
static inline float asfloat32(uint32 u)
|
||||
{
|
||||
union { float f; uint32 u; } conv;
|
||||
conv.u = u;
|
||||
return conv.f;
|
||||
}
|
||||
|
||||
half floatToHalf(float f)
|
||||
float float16to32(float16 f)
|
||||
{
|
||||
union { float f; uint32 i; } conv;
|
||||
conv.f = f;
|
||||
return asfloat32(mantissatable[offsettable[f >> 10] + (f & 0x3FF)] + exponenttable[f >> 10]);
|
||||
}
|
||||
|
||||
return basetable[(conv.i >> 23) & 0x1FF] + ((conv.i & 0x007FFFFF) >> shifttable[(conv.i >> 23) & 0x1FF]);
|
||||
float16 float32to16(float f)
|
||||
{
|
||||
uint32 u = asuint32(f);
|
||||
return basetable[(u >> 23) & 0x1FF] + ((u & 0x007FFFFF) >> shifttable[(u >> 23) & 0x1FF]);
|
||||
}
|
||||
|
||||
// Adapted from https://stackoverflow.com/questions/41532085/how-to-pack-unpack-11-and-10-bit-floats-in-javascript-for-webgl2
|
||||
|
||||
float float11to32(float11 f)
|
||||
{
|
||||
uint16 exponent = f >> 6;
|
||||
uint16 mantissa = f & 0x3F;
|
||||
|
||||
if (exponent == 0)
|
||||
return mantissa == 0 ? 0 : powf(2.0f, -14.0f) * (mantissa / 64.0f);
|
||||
|
||||
if (exponent < 31)
|
||||
return powf(2.0f, exponent - 15) * (1.0f + mantissa / 64.0f);
|
||||
|
||||
return mantissa == 0 ? std::numeric_limits<float>::infinity() : std::numeric_limits<float>::quiet_NaN();
|
||||
}
|
||||
|
||||
float11 float32to11(float f)
|
||||
{
|
||||
const uint16 EXPONENT_BITS = 0x1F;
|
||||
const uint16 EXPONENT_SHIFT = 6;
|
||||
const uint16 EXPONENT_BIAS = 15;
|
||||
const uint16 MANTISSA_BITS = 0x3F;
|
||||
const uint16 MANTISSA_SHIFT = (23 - EXPONENT_SHIFT);
|
||||
const uint16 MAX_EXPONENT = (EXPONENT_BITS << EXPONENT_SHIFT);
|
||||
|
||||
uint32 u = asuint32(f);
|
||||
|
||||
if (u & 0x80000000)
|
||||
return 0; // Negative values go to 0.
|
||||
|
||||
// Map exponent to the range [-127,128]
|
||||
int32 exponent = (int32)((u >> 23) & 0xFF) - 127;
|
||||
uint32 mantissa = u & 0x007FFFFF;
|
||||
|
||||
if (exponent > 15) // Infinity or NaN
|
||||
return MAX_EXPONENT | (exponent == 128 ? (mantissa & MANTISSA_BITS) : 0);
|
||||
else if (exponent <= -15)
|
||||
return 0;
|
||||
|
||||
exponent += EXPONENT_BIAS;
|
||||
|
||||
return ((uint16)exponent << EXPONENT_SHIFT) | (mantissa >> MANTISSA_SHIFT);
|
||||
}
|
||||
|
||||
float float10to32(float10 f)
|
||||
{
|
||||
uint16 exponent = f >> 5;
|
||||
uint16 mantissa = f & 0x1F;
|
||||
|
||||
if (exponent == 0)
|
||||
return mantissa == 0 ? 0 : powf(2.0f, -14.0f) * (mantissa / 32.0f);
|
||||
|
||||
if (exponent < 31)
|
||||
return powf(2.0f, exponent - 15) * (1.0f + mantissa / 32.0f);
|
||||
|
||||
return mantissa == 0 ? std::numeric_limits<float>::infinity() : std::numeric_limits<float>::quiet_NaN();
|
||||
}
|
||||
|
||||
float10 float32to10(float f)
|
||||
{
|
||||
const uint16 EXPONENT_BITS = 0x1F;
|
||||
const uint16 EXPONENT_SHIFT = 5;
|
||||
const uint16 EXPONENT_BIAS = 15;
|
||||
const uint16 MANTISSA_BITS = 0x1F;
|
||||
const uint16 MANTISSA_SHIFT = (23 - EXPONENT_SHIFT);
|
||||
const uint16 MAX_EXPONENT = (EXPONENT_BITS << EXPONENT_SHIFT);
|
||||
|
||||
uint32 u = asuint32(f);
|
||||
|
||||
if (u & 0x80000000)
|
||||
return 0; // Negative values go to 0.
|
||||
|
||||
// Map exponent to the range [-127,128]
|
||||
int32 exponent = (int32)((u >> 23) & 0xFF) - 127;
|
||||
uint32 mantissa = u & 0x007FFFFF;
|
||||
|
||||
if (exponent > 15) // Infinity or NaN
|
||||
return MAX_EXPONENT | (exponent == 128 ? (mantissa & MANTISSA_BITS) : 0);
|
||||
else if (exponent <= -15)
|
||||
return 0;
|
||||
|
||||
exponent += EXPONENT_BIAS;
|
||||
|
||||
return ((uint16)exponent << EXPONENT_SHIFT) | (mantissa >> MANTISSA_SHIFT);
|
||||
}
|
||||
|
||||
} // love
|
||||
@@ -18,21 +18,26 @@
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
**/
|
||||
|
||||
#ifndef LOVE_HALF_FLOAT_H
|
||||
#define LOVE_HALF_FLOAT_H
|
||||
#pragma once
|
||||
|
||||
#include "int.h"
|
||||
|
||||
namespace love
|
||||
{
|
||||
|
||||
typedef uint16 half;
|
||||
typedef uint16 float16;
|
||||
typedef uint16 float11;
|
||||
typedef uint16 float10;
|
||||
|
||||
void halfInit();
|
||||
void float16Init();
|
||||
|
||||
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);
|
||||
|
||||
} // love
|
||||
|
||||
#endif // LOVE_HALF_FLOAT_H
|
||||
@@ -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