Shifting the midpoint of the ab channels to 128. unshifting back to signed int on pack

This commit is contained in:
wiredfool 2013-10-15 22:01:30 -07:00
parent 4458787f5e
commit 1865a5c438
6 changed files with 81 additions and 27 deletions

BIN
Tests/images/lab-green.tif Normal file

Binary file not shown.

BIN
Tests/images/lab-red.tif Normal file

Binary file not shown.

41
Tests/test_format_lab.py Normal file
View File

@ -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))

View File

@ -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)

View File

@ -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 static void
copy1(UINT8* out, const UINT8* in, int pixels) copy1(UINT8* out, const UINT8* in, int pixels)
{ {
@ -527,7 +540,7 @@ static struct {
{"YCbCr", "Cr", 8, band2}, {"YCbCr", "Cr", 8, band2},
/* LAB Color */ /* LAB Color */
{"LAB", "LAB", 24, ImagingPackRGB}, {"LAB", "LAB", 24, ImagingPackLAB},
{"LAB", "L", 8, band0}, {"LAB", "L", 8, band0},
{"LAB", "A", 8, band1}, {"LAB", "A", 8, band1},
{"LAB", "B", 8, band2}, {"LAB", "B", 8, band2},

View File

@ -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 static void
copy1(UINT8* out, const UINT8* in, int pixels) copy1(UINT8* out, const UINT8* in, int pixels)
{ {
@ -965,7 +990,7 @@ static struct {
{"YCbCr", "YCbCrK", 32, copy4}, {"YCbCr", "YCbCrK", 32, copy4},
/* LAB Color */ /* LAB Color */
{"LAB", "LAB", 24, ImagingUnpackRGB}, {"LAB", "LAB", 24, ImagingUnpackLAB},
{"LAB", "L", 8, band0}, {"LAB", "L", 8, band0},
{"LAB", "A", 8, band1}, {"LAB", "A", 8, band1},
{"LAB", "B", 8, band2}, {"LAB", "B", 8, band2},