diff --git a/Tests/images/lab-green.tif b/Tests/images/lab-green.tif new file mode 100644 index 000000000..76c129ee9 Binary files /dev/null and b/Tests/images/lab-green.tif differ diff --git a/Tests/images/lab-red.tif b/Tests/images/lab-red.tif new file mode 100644 index 000000000..fc1953006 Binary files /dev/null and b/Tests/images/lab-red.tif differ diff --git a/Tests/test_format_lab.py b/Tests/test_format_lab.py new file mode 100644 index 000000000..371b06a0b --- /dev/null +++ b/Tests/test_format_lab.py @@ -0,0 +1,41 @@ +from tester import * + +from PIL import Image + +def test_white(): + i = Image.open('Tests/images/lab.tif') + + bits = i.load() + + assert_equal(i.mode, 'LAB') + + assert_equal(i.getbands(), ('L','A', 'B')) + + k = i.getpixel((0,0)) + assert_equal(k, (255,128,128)) + + L = i.getdata(0) + a = i.getdata(1) + b = i.getdata(2) + + assert_equal(list(L), [255]*100) + assert_equal(list(a), [128]*100) + assert_equal(list(b), [128]*100) + + +def test_green(): + # l= 50 (/100), a = -100 (-128 .. 128) b=0 in PS + # == RGB: 0, 152, 117 + i = Image.open('Tests/images/lab-green.tif') + + k = i.getpixel((0,0)) + assert_equal(k, (128,28,128)) + + +def test_red(): + # l= 50 (/100), a = 100 (-128 .. 128) b=0 in PS + # == RGB: 255, 0, 124 + i = Image.open('Tests/images/lab-red.tif') + + k = i.getpixel((0,0)) + assert_equal(k, (128,228,128)) diff --git a/Tests/test_image_lab.py b/Tests/test_image_lab.py deleted file mode 100644 index bbc59a2c7..000000000 --- a/Tests/test_image_lab.py +++ /dev/null @@ -1,25 +0,0 @@ -from tester import * - -from PIL import Image - -def test_sanity(): - i = Image.open('Tests/images/lab.tif') - - bits = i.load() - - assert_equal(i.mode, 'LAB') - - assert_equal(i.getbands(), ('L','A', 'B')) - - k = i.getpixel((0,0)) - assert_equal(k, (255,0,0)) - - L = i.getdata(0) - a = i.getdata(1) - b = i.getdata(2) - - assert_equal(list(L), [255]*100) - assert_equal(list(a), [0]*100) - assert_equal(list(b), [0]*100) - - diff --git a/libImaging/Pack.c b/libImaging/Pack.c index d38d9e5e3..320e94d67 100644 --- a/libImaging/Pack.c +++ b/libImaging/Pack.c @@ -372,6 +372,19 @@ packI32S(UINT8* out, const UINT8* in, int pixels) } } +void +ImagingPackLAB(UINT8* out, const UINT8* in, int pixels) +{ + int i; + /* LAB triplets */ + for (i = 0; i < pixels; i++) { + out[0] = in[0]; + out[1] = in[1] ^ 128; /* signed in outside world */ + out[2] = in[2] ^ 128; + out += 3; in += 4; + } +} + static void copy1(UINT8* out, const UINT8* in, int pixels) { @@ -527,7 +540,7 @@ static struct { {"YCbCr", "Cr", 8, band2}, /* LAB Color */ - {"LAB", "LAB", 24, ImagingPackRGB}, + {"LAB", "LAB", 24, ImagingPackLAB}, {"LAB", "L", 8, band0}, {"LAB", "A", 8, band1}, {"LAB", "B", 8, band2}, diff --git a/libImaging/Unpack.c b/libImaging/Unpack.c index e05728f49..bef563d42 100644 --- a/libImaging/Unpack.c +++ b/libImaging/Unpack.c @@ -660,6 +660,31 @@ unpackCMYKI(UINT8* out, const UINT8* in, int pixels) } } +/* Unpack to "LAB" image */ +/* There are two representations of LAB images for whatever precision: + L: Uint (in PS, it's 0-100) + A: Int (in ps, -128 .. 128, or elsewhere 0..255, with 128 as middle. + Channels in PS display a 0 value as middle grey, + LCMS appears to use 128 as the 0 value for these channels) + B: Int (as above) + + Since we don't have any signed ints, we're going with the shifted versions + internally, and we'll unshift for saving and whatnot. +*/ +void +ImagingUnpackLAB(UINT8* out, const UINT8* in, int pixels) +{ + int i; + /* LAB triplets */ + for (i = 0; i < pixels; i++) { + out[0] = in[0]; + out[1] = in[1] ^ 128; /* signed in outside world */ + out[2] = in[2] ^ 128; + out[3] = 255; + out += 4; in += 3; + } +} + static void copy1(UINT8* out, const UINT8* in, int pixels) { @@ -965,7 +990,7 @@ static struct { {"YCbCr", "YCbCrK", 32, copy4}, /* LAB Color */ - {"LAB", "LAB", 24, ImagingUnpackRGB}, + {"LAB", "LAB", 24, ImagingUnpackLAB}, {"LAB", "L", 8, band0}, {"LAB", "A", 8, band1}, {"LAB", "B", 8, band2},