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_INT32 (0x200|sizeof(INT32))
|
||||
#define TYPE_FLOAT16 (0x500|sizeof(FLOAT16))
|
||||
#define TYPE_FLOAT32 (0x300|sizeof(FLOAT32))
|
||||
#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;
|
||||
}
|
||||
|
||||
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*
|
||||
getpixel(Imaging im, ImagingAccess access, int x, int y)
|
||||
{
|
||||
|
@ -702,18 +725,19 @@ _blend(ImagingObject* self, PyObject* args)
|
|||
/* METHODS */
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
||||
|
||||
static INT16*
|
||||
_prepare_lut_table(PyObject* table, Py_ssize_t table_size)
|
||||
{
|
||||
int i;
|
||||
FLOAT32* table_data;
|
||||
float item;
|
||||
INT32 data_type = TYPE_FLOAT32;
|
||||
void* table_data;
|
||||
INT16* prepared;
|
||||
|
||||
/* NOTE: This value should be the same as in ColorLUT.c */
|
||||
#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 * "
|
||||
"size1D * size2D * size3D float items.", TYPE_FLOAT32);
|
||||
if ( ! table_data) {
|
||||
|
@ -728,20 +752,31 @@ _prepare_lut_table(PyObject* table, Py_ssize_t table_size)
|
|||
}
|
||||
|
||||
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 */
|
||||
if (table_data[i] >= (0x7fff - 0.5) / (255 << PRECISION_BITS)) {
|
||||
if (item >= (0x7fff - 0.5) / (255 << PRECISION_BITS)) {
|
||||
prepared[i] = 0x7fff;
|
||||
continue;
|
||||
}
|
||||
/* 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;
|
||||
continue;
|
||||
}
|
||||
if (table_data[i] < 0) {
|
||||
prepared[i] = table_data[i] * (255 << PRECISION_BITS) - 0.5;
|
||||
if (item < 0) {
|
||||
prepared[i] = item * (255 << PRECISION_BITS) - 0.5;
|
||||
} else {
|
||||
prepared[i] = table_data[i] * (255 << PRECISION_BITS) + 0.5;
|
||||
prepared[i] = item * (255 << PRECISION_BITS) + 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -71,6 +71,7 @@
|
|||
#endif
|
||||
|
||||
/* assume IEEE; tweak if necessary (patches are welcome) */
|
||||
#define FLOAT16 UINT16
|
||||
#define FLOAT32 float
|
||||
#define FLOAT64 double
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user