From 993e075c0d82b814247abca0018a57ea03a1b2ae Mon Sep 17 00:00:00 2001 From: wiredfool Date: Mon, 8 Jul 2013 23:21:41 -0700 Subject: [PATCH] Add conversions from I;16 to F to retain 16 bit precision --- Tests/test_image_convert.py | 24 ++++++++++++++++++++++++ libImaging/Convert.c | 23 +++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/Tests/test_image_convert.py b/Tests/test_image_convert.py index a6220c11e..8f70c59e5 100644 --- a/Tests/test_image_convert.py +++ b/Tests/test_image_convert.py @@ -24,3 +24,27 @@ def test_default(): assert_image(im, "RGB", im.size) im = im.convert() assert_image(im, "RGB", im.size) + + + +# ref https://github.com/python-imaging/Pillow/issues/274 + +def _test_float_conversion(im): + orig = im.getpixel((5,5)) + converted = im.convert('F').getpixel((5,5)) + assert_equal(orig, converted) + +def test_8bit(): + im = Image.open('Images/lena.jpg') + _test_float_conversion(im.convert('L')) + +def test_12bit(): + im = Image.open('Tests/images/12bit.tif') + _test_float_conversion(im) + +def test_12bit_workaround(): + im = Image.open('Tests/images/12bit.tif') + _test_float_conversion(im.convert('I')) + + + diff --git a/libImaging/Convert.c b/libImaging/Convert.c index 2bc56e1cc..ab02910a7 100644 --- a/libImaging/Convert.c +++ b/libImaging/Convert.c @@ -498,6 +498,25 @@ I16B_I(UINT8* out_, const UINT8* in, int xsize) *out++ = in[1] + ((int) in[0] << 8); } +static void +I16L_F(UINT8* out_, const UINT8* in, int xsize) +{ + int x; + FLOAT32* out = (FLOAT32*) out_; + for (x = 0; x < xsize; x++, in += 2) + *out++ = (FLOAT32) (in[0] + ((int) in[1] << 8)); +} + + +static void +I16B_F(UINT8* out_, const UINT8* in, int xsize) +{ + int x; + FLOAT32* out = (FLOAT32*) out_; + for (x = 0; x < xsize; x++, in += 2) + *out++ = (FLOAT32) (in[1] + ((int) in[0] << 8)); +} + static void L_I16L(UINT8* out, const UINT8* in, int xsize) { @@ -630,6 +649,10 @@ static struct { { "L", "I;16B", L_I16B }, { "I;16B", "L", I16B_L }, + { "I;16", "F", I16L_F }, + { "I;16L", "F", I16L_F }, + { "I;16B", "F", I16B_F }, + { NULL } };