mirror of
https://github.com/python-pillow/Pillow.git
synced 2024-12-27 10:26:19 +03:00
Support for many many LUT source on C level
This commit is contained in:
parent
63b243e1f6
commit
2c87242027
|
@ -356,6 +356,7 @@ getbands(const char* mode)
|
||||||
|
|
||||||
#define TYPE_UINT8 (0x100|sizeof(UINT8))
|
#define TYPE_UINT8 (0x100|sizeof(UINT8))
|
||||||
#define TYPE_INT32 (0x200|sizeof(INT32))
|
#define TYPE_INT32 (0x200|sizeof(INT32))
|
||||||
|
#define TYPE_FLOAT16 (0x500|sizeof(FLOAT16))
|
||||||
#define TYPE_FLOAT32 (0x300|sizeof(FLOAT32))
|
#define TYPE_FLOAT32 (0x300|sizeof(FLOAT32))
|
||||||
#define TYPE_DOUBLE (0x400|sizeof(double))
|
#define TYPE_DOUBLE (0x400|sizeof(double))
|
||||||
|
|
||||||
|
@ -439,6 +440,28 @@ getlist(PyObject* arg, Py_ssize_t* length, const char* wrong_length, int type)
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FLOAT32
|
||||||
|
float16tofloat32(const FLOAT16 in) {
|
||||||
|
UINT32 t1;
|
||||||
|
UINT32 t2;
|
||||||
|
UINT32 t3;
|
||||||
|
|
||||||
|
t1 = in & 0x7fff; // Non-sign bits
|
||||||
|
t2 = in & 0x8000; // Sign bit
|
||||||
|
t3 = in & 0x7c00; // Exponent
|
||||||
|
|
||||||
|
t1 <<= 13; // Align mantissa on MSB
|
||||||
|
t2 <<= 16; // Shift sign bit into position
|
||||||
|
|
||||||
|
t1 += 0x38000000; // Adjust bias
|
||||||
|
|
||||||
|
t1 = (t3 == 0 ? 0 : t1); // Denormals-as-zero
|
||||||
|
|
||||||
|
t1 |= t2; // Re-insert sign bit
|
||||||
|
|
||||||
|
return *(FLOAT32 *)&t1;
|
||||||
|
}
|
||||||
|
|
||||||
static inline PyObject*
|
static inline PyObject*
|
||||||
getpixel(Imaging im, ImagingAccess access, int x, int y)
|
getpixel(Imaging im, ImagingAccess access, int x, int y)
|
||||||
{
|
{
|
||||||
|
@ -702,18 +725,19 @@ _blend(ImagingObject* self, PyObject* args)
|
||||||
/* METHODS */
|
/* METHODS */
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
static INT16*
|
static INT16*
|
||||||
_prepare_lut_table(PyObject* table, Py_ssize_t table_size)
|
_prepare_lut_table(PyObject* table, Py_ssize_t table_size)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
FLOAT32* table_data;
|
float item;
|
||||||
|
INT32 data_type = TYPE_FLOAT32;
|
||||||
|
void* table_data;
|
||||||
INT16* prepared;
|
INT16* prepared;
|
||||||
|
|
||||||
/* NOTE: This value should be the same as in ColorLUT.c */
|
/* NOTE: This value should be the same as in ColorLUT.c */
|
||||||
#define PRECISION_BITS (16 - 8 - 2)
|
#define PRECISION_BITS (16 - 8 - 2)
|
||||||
|
|
||||||
table_data = (FLOAT32*) getlist(table, &table_size,
|
table_data = getlist(table, &table_size,
|
||||||
"The table should have table_channels * "
|
"The table should have table_channels * "
|
||||||
"size1D * size2D * size3D float items.", TYPE_FLOAT32);
|
"size1D * size2D * size3D float items.", TYPE_FLOAT32);
|
||||||
if ( ! table_data) {
|
if ( ! table_data) {
|
||||||
|
@ -728,20 +752,31 @@ _prepare_lut_table(PyObject* table, Py_ssize_t table_size)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < table_size; i++) {
|
for (i = 0; i < table_size; i++) {
|
||||||
|
switch (data_type) {
|
||||||
|
case TYPE_FLOAT16:
|
||||||
|
item = float16tofloat32(((FLOAT16*) table_data)[i]);
|
||||||
|
break;
|
||||||
|
case TYPE_FLOAT32:
|
||||||
|
item = ((FLOAT32*) table_data)[i];
|
||||||
|
break;
|
||||||
|
case TYPE_DOUBLE:
|
||||||
|
item = ((double*) table_data)[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
/* Max value for INT16 */
|
/* Max value for INT16 */
|
||||||
if (table_data[i] >= (0x7fff - 0.5) / (255 << PRECISION_BITS)) {
|
if (item >= (0x7fff - 0.5) / (255 << PRECISION_BITS)) {
|
||||||
prepared[i] = 0x7fff;
|
prepared[i] = 0x7fff;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
/* Min value for INT16 */
|
/* Min value for INT16 */
|
||||||
if (table_data[i] <= (-0x8000 + 0.5) / (255 << PRECISION_BITS)) {
|
if (item <= (-0x8000 + 0.5) / (255 << PRECISION_BITS)) {
|
||||||
prepared[i] = -0x8000;
|
prepared[i] = -0x8000;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (table_data[i] < 0) {
|
if (item < 0) {
|
||||||
prepared[i] = table_data[i] * (255 << PRECISION_BITS) - 0.5;
|
prepared[i] = item * (255 << PRECISION_BITS) - 0.5;
|
||||||
} else {
|
} else {
|
||||||
prepared[i] = table_data[i] * (255 << PRECISION_BITS) + 0.5;
|
prepared[i] = item * (255 << PRECISION_BITS) + 0.5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -71,6 +71,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* assume IEEE; tweak if necessary (patches are welcome) */
|
/* assume IEEE; tweak if necessary (patches are welcome) */
|
||||||
|
#define FLOAT16 UINT16
|
||||||
#define FLOAT32 float
|
#define FLOAT32 float
|
||||||
#define FLOAT64 double
|
#define FLOAT64 double
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user