This commit is contained in:
tomgoddard 2017-09-29 09:18:54 +00:00 committed by GitHub
commit 322e88ad3e
9 changed files with 73 additions and 3 deletions

View File

@ -310,6 +310,7 @@ SAVE = {
"I;16": ("L 16", "I;16"), "I;16": ("L 16", "I;16"),
"I;16L": ("L 16L", "I;16L"), "I;16L": ("L 16L", "I;16L"),
"I;16B": ("L 16B", "I;16B"), "I;16B": ("L 16B", "I;16B"),
"I;16S": ("L 16S", "I;16S"),
"F": ("L 32F", "F;32F"), "F": ("L 32F", "F;32F"),
"RGB": ("RGB", "RGB;L"), "RGB": ("RGB", "RGB;L"),
"RGBA": ("RGBA", "RGBA;L"), "RGBA": ("RGBA", "RGBA;L"),

View File

@ -238,7 +238,7 @@ _MODEINFO = {
"LAB": ("RGB", "L", ("L", "A", "B")), "LAB": ("RGB", "L", ("L", "A", "B")),
"HSV": ("RGB", "L", ("H", "S", "V")), "HSV": ("RGB", "L", ("H", "S", "V")),
# Experimental modes include I;16, I;16L, I;16B, RGBa, BGR;15, and # Experimental modes include I;16, I;16L, I;16B, I;16S, RGBa, BGR;15, and
# BGR;24. Use these modes only if you know exactly what you're # BGR;24. Use these modes only if you know exactly what you're
# doing... # doing...

View File

@ -50,6 +50,7 @@ def getmode(mode):
modes["I;16"] = ModeDescriptor("I;16", "I", "L", "L") modes["I;16"] = ModeDescriptor("I;16", "I", "L", "L")
modes["I;16L"] = ModeDescriptor("I;16L", "I", "L", "L") modes["I;16L"] = ModeDescriptor("I;16L", "I", "L", "L")
modes["I;16B"] = ModeDescriptor("I;16B", "I", "L", "L") modes["I;16B"] = ModeDescriptor("I;16B", "I", "L", "L")
modes["I;16S"] = ModeDescriptor("I;16S", "I", "L", "L")
# set global mode cache atomically # set global mode cache atomically
_modes = modes _modes = modes
return _modes[mode] return _modes[mode]

View File

@ -79,6 +79,7 @@ class TestModeI16(PillowTestCase):
basic("I;16") basic("I;16")
basic("I;16B") basic("I;16B")
basic("I;16L") basic("I;16L")
basic("I;16S")
basic("I") basic("I")
@ -92,6 +93,7 @@ class TestModeI16(PillowTestCase):
self.assertEqual(tobytes("L"), b"\x01") self.assertEqual(tobytes("L"), b"\x01")
self.assertEqual(tobytes("I;16"), b"\x01\x00") self.assertEqual(tobytes("I;16"), b"\x01\x00")
self.assertEqual(tobytes("I;16B"), b"\x00\x01") self.assertEqual(tobytes("I;16B"), b"\x00\x01")
self.assertEqual(tobytes("I;16S"), b"\x01\x00")
self.assertEqual(tobytes("I"), b"\x01\x00\x00\x00"[::order]) self.assertEqual(tobytes("I"), b"\x01\x00\x00\x00"[::order])
def test_convert(self): def test_convert(self):
@ -106,6 +108,10 @@ class TestModeI16(PillowTestCase):
self.verify(im.convert("I;16B").convert("L")) self.verify(im.convert("I;16B").convert("L"))
self.verify(im.convert("I;16B").convert("I")) self.verify(im.convert("I;16B").convert("I"))
self.verify(im.convert("I;16S"))
self.verify(im.convert("I;16S").convert("L"))
self.verify(im.convert("I;16S").convert("I"))
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()

View File

@ -227,6 +227,7 @@ ImagingAccessInit()
ADD("I;16", line_16, get_pixel_16L, put_pixel_16L); ADD("I;16", line_16, get_pixel_16L, put_pixel_16L);
ADD("I;16L", line_16, get_pixel_16L, put_pixel_16L); ADD("I;16L", line_16, get_pixel_16L, put_pixel_16L);
ADD("I;16B", line_16, get_pixel_16B, put_pixel_16B); ADD("I;16B", line_16, get_pixel_16B, put_pixel_16B);
ADD("I;16S", line_16, get_pixel_16L, put_pixel_16L);
ADD("I;32L", line_32, get_pixel_32L, put_pixel_32L); ADD("I;32L", line_32, get_pixel_32L, put_pixel_32L);
ADD("I;32B", line_32, get_pixel_32B, put_pixel_32B); ADD("I;32B", line_32, get_pixel_32B, put_pixel_32B);
ADD("F", line_32, get_pixel_32, put_pixel_32); ADD("F", line_32, get_pixel_32, put_pixel_32);

View File

@ -49,7 +49,7 @@
#ifndef round #ifndef round
double round(double x) { double round(double x) {
return floor(x+0.5); return floor(x+0.5);
} }
#endif #endif
@ -694,6 +694,17 @@ I_I16B(UINT8* out, const UINT8* in_, int xsize)
} }
} }
static void
I_I16S(UINT8* out, const UINT8* in_, int xsize)
{
int x, v;
INT32* in = (INT32*) in_;
for (x = 0; x < xsize; x++, in++) {
v = CLIP16(*in);
*out++ = (UINT8) v;
*out++ = (UINT8) (v >> 8);
}
}
static void static void
I16L_I(UINT8* out_, const UINT8* in, int xsize) I16L_I(UINT8* out_, const UINT8* in, int xsize)
@ -714,6 +725,15 @@ I16B_I(UINT8* out_, const UINT8* in, int xsize)
*out++ = in[1] + ((int) in[0] << 8); *out++ = in[1] + ((int) in[0] << 8);
} }
static void
I16S_I(UINT8* out_, const UINT8* in, int xsize)
{
int x;
INT32* out = (INT32*) out_;
for (x = 0; x < xsize; x++, in += 2)
*out++ = (INT16)(in[0] + ((int) in[1] << 8));
}
static void static void
I16L_F(UINT8* out_, const UINT8* in, int xsize) I16L_F(UINT8* out_, const UINT8* in, int xsize)
{ {
@ -733,6 +753,15 @@ I16B_F(UINT8* out_, const UINT8* in, int xsize)
*out++ = (FLOAT32) (in[1] + ((int) in[0] << 8)); *out++ = (FLOAT32) (in[1] + ((int) in[0] << 8));
} }
static void
I16S_F(UINT8* out_, const UINT8* in, int xsize)
{
int x;
FLOAT32* out = (FLOAT32*) out_;
for (x = 0; x < xsize; x++, in += 2)
*out++ = (FLOAT32) (INT16) (in[0] + ((int) in[1] << 8));
}
static void static void
L_I16L(UINT8* out, const UINT8* in, int xsize) L_I16L(UINT8* out, const UINT8* in, int xsize)
{ {
@ -753,6 +782,16 @@ L_I16B(UINT8* out, const UINT8* in, int xsize)
} }
} }
static void
L_I16S(UINT8* out, const UINT8* in, int xsize)
{
int x;
for (x = 0; x < xsize; x++, in++) {
*out++ = *in;
*out++ = 0;
}
}
static void static void
I16L_L(UINT8* out, const UINT8* in, int xsize) I16L_L(UINT8* out, const UINT8* in, int xsize)
{ {
@ -775,6 +814,19 @@ I16B_L(UINT8* out, const UINT8* in, int xsize)
*out++ = in[1]; *out++ = in[1];
} }
static void
I16S_L(UINT8* out, const UINT8* in, int xsize)
{
int x;
for (x = 0; x < xsize; x++, in += 2)
if (in[1] & 0x80)
*out++ = 0; /* Negative -> 0 */
else if (in[1] != 0)
*out++ = 255; /* Greater than 255 -> 255 */
else
*out++ = in[0];
}
static struct { static struct {
const char* from; const char* from;
const char* to; const char* to;
@ -873,9 +925,15 @@ static struct {
{ "L", "I;16B", L_I16B }, { "L", "I;16B", L_I16B },
{ "I;16B", "L", I16B_L }, { "I;16B", "L", I16B_L },
{ "I", "I;16S", I_I16S },
{ "I;16S", "I", I16S_I },
{ "L", "I;16S", L_I16S },
{ "I;16S", "L", I16S_L },
{ "I;16", "F", I16L_F }, { "I;16", "F", I16L_F },
{ "I;16L", "F", I16L_F }, { "I;16L", "F", I16L_F },
{ "I;16B", "F", I16B_F }, { "I;16B", "F", I16B_F },
{ "I;16S", "F", I16S_F },
{ NULL } { NULL }
}; };

View File

@ -614,6 +614,7 @@ static struct {
{"I;16", "I;16", 16, copy2}, {"I;16", "I;16", 16, copy2},
{"I;16B", "I;16B", 16, copy2}, {"I;16B", "I;16B", 16, copy2},
{"I;16L", "I;16L", 16, copy2}, {"I;16L", "I;16L", 16, copy2},
{"I;16S", "I;16S", 16, copy2},
{"I;16", "I;16N", 16, packI16N_I16}, // LibTiff native->image endian. {"I;16", "I;16N", 16, packI16N_I16}, // LibTiff native->image endian.
{"I;16L", "I;16N", 16, packI16N_I16}, {"I;16L", "I;16N", 16, packI16N_I16},
{"I;16B", "I;16N", 16, packI16N_I16B}, {"I;16B", "I;16N", 16, packI16N_I16B},

View File

@ -116,7 +116,8 @@ ImagingNewPrologueSubtype(const char *mode, int xsize, int ysize, int size)
im->type = IMAGING_TYPE_INT32; im->type = IMAGING_TYPE_INT32;
} else if (strcmp(mode, "I;16") == 0 || strcmp(mode, "I;16L") == 0 \ } else if (strcmp(mode, "I;16") == 0 || strcmp(mode, "I;16L") == 0 \
|| strcmp(mode, "I;16B") == 0 || strcmp(mode, "I;16N") == 0) { || strcmp(mode, "I;16B") == 0 || strcmp(mode, "I;16N") == 0 \
|| strcmp(mode, "I;16S") == 0) {
/* EXPERIMENTAL */ /* EXPERIMENTAL */
/* 16-bit raw integer images */ /* 16-bit raw integer images */
im->bands = 1; im->bands = 1;

View File

@ -1406,6 +1406,7 @@ static struct {
{"I;16", "I;16", 16, copy2}, {"I;16", "I;16", 16, copy2},
{"I;16B", "I;16B", 16, copy2}, {"I;16B", "I;16B", 16, copy2},
{"I;16L", "I;16L", 16, copy2}, {"I;16L", "I;16L", 16, copy2},
{"I;16S", "I;16S", 16, copy2},
{"I;16", "I;16N", 16, unpackI16N_I16}, // LibTiff native->image endian. {"I;16", "I;16N", 16, unpackI16N_I16}, // LibTiff native->image endian.
{"I;16L", "I;16N", 16, unpackI16N_I16}, // LibTiff native->image endian. {"I;16L", "I;16N", 16, unpackI16N_I16}, // LibTiff native->image endian.