mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-01-13 10:46:16 +03:00
Merge pull request #1789 from zwhfly/tiff
Add Support for 2/4 bpp Tiff Grayscale Images
This commit is contained in:
commit
14f3b45f46
|
@ -141,34 +141,56 @@ OPEN_INFO = {
|
|||
(MM, 0, (1,), 1, (1,), ()): ("1", "1;I"),
|
||||
(II, 0, (1,), 2, (1,), ()): ("1", "1;IR"),
|
||||
(MM, 0, (1,), 2, (1,), ()): ("1", "1;IR"),
|
||||
(II, 1, (1,), 1, (1,), ()): ("1", "1"),
|
||||
(MM, 1, (1,), 1, (1,), ()): ("1", "1"),
|
||||
(II, 1, (1,), 2, (1,), ()): ("1", "1;R"),
|
||||
(MM, 1, (1,), 2, (1,), ()): ("1", "1;R"),
|
||||
|
||||
(II, 0, (1,), 1, (2,), ()): ("L", "L;2I"),
|
||||
(MM, 0, (1,), 1, (2,), ()): ("L", "L;2I"),
|
||||
(II, 0, (1,), 2, (2,), ()): ("L", "L;2IR"),
|
||||
(MM, 0, (1,), 2, (2,), ()): ("L", "L;2IR"),
|
||||
(II, 1, (1,), 1, (2,), ()): ("L", "L;2"),
|
||||
(MM, 1, (1,), 1, (2,), ()): ("L", "L;2"),
|
||||
(II, 1, (1,), 2, (2,), ()): ("L", "L;2R"),
|
||||
(MM, 1, (1,), 2, (2,), ()): ("L", "L;2R"),
|
||||
|
||||
(II, 0, (1,), 1, (4,), ()): ("L", "L;4I"),
|
||||
(MM, 0, (1,), 1, (4,), ()): ("L", "L;4I"),
|
||||
(II, 0, (1,), 2, (4,), ()): ("L", "L;4IR"),
|
||||
(MM, 0, (1,), 2, (4,), ()): ("L", "L;4IR"),
|
||||
(II, 1, (1,), 1, (4,), ()): ("L", "L;4"),
|
||||
(MM, 1, (1,), 1, (4,), ()): ("L", "L;4"),
|
||||
(II, 1, (1,), 2, (4,), ()): ("L", "L;4R"),
|
||||
(MM, 1, (1,), 2, (4,), ()): ("L", "L;4R"),
|
||||
|
||||
(II, 0, (1,), 1, (8,), ()): ("L", "L;I"),
|
||||
(MM, 0, (1,), 1, (8,), ()): ("L", "L;I"),
|
||||
(II, 0, (1,), 2, (8,), ()): ("L", "L;IR"),
|
||||
(MM, 0, (1,), 2, (8,), ()): ("L", "L;IR"),
|
||||
(II, 0, (3,), 1, (32,), ()): ("F", "F;32F"),
|
||||
(MM, 0, (3,), 1, (32,), ()): ("F", "F;32BF"),
|
||||
(II, 1, (1,), 1, (1,), ()): ("1", "1"),
|
||||
(MM, 1, (1,), 1, (1,), ()): ("1", "1"),
|
||||
(II, 1, (1,), 1, (4,), ()): ("L", "L;4"),
|
||||
# ?
|
||||
(II, 1, (1,), 2, (1,), ()): ("1", "1;R"),
|
||||
(MM, 1, (1,), 2, (1,), ()): ("1", "1;R"),
|
||||
(II, 1, (1,), 1, (8,), ()): ("L", "L"),
|
||||
(MM, 1, (1,), 1, (8,), ()): ("L", "L"),
|
||||
(II, 1, (1,), 1, (8, 8), (2,)): ("LA", "LA"),
|
||||
(MM, 1, (1,), 1, (8, 8), (2,)): ("LA", "LA"),
|
||||
(II, 1, (1,), 2, (8,), ()): ("L", "L;R"),
|
||||
(MM, 1, (1,), 2, (8,), ()): ("L", "L;R"),
|
||||
|
||||
(II, 1, (1,), 1, (12,), ()): ("I;16", "I;12"),
|
||||
|
||||
(II, 1, (1,), 1, (16,), ()): ("I;16", "I;16"),
|
||||
(MM, 1, (1,), 1, (16,), ()): ("I;16B", "I;16B"),
|
||||
(II, 1, (2,), 1, (16,), ()): ("I;16S", "I;16S"),
|
||||
(MM, 1, (2,), 1, (16,), ()): ("I;16BS", "I;16BS"),
|
||||
|
||||
(II, 0, (3,), 1, (32,), ()): ("F", "F;32F"),
|
||||
(MM, 0, (3,), 1, (32,), ()): ("F", "F;32BF"),
|
||||
(II, 1, (1,), 1, (32,), ()): ("I", "I;32N"),
|
||||
(II, 1, (2,), 1, (32,), ()): ("I", "I;32S"),
|
||||
(MM, 1, (2,), 1, (32,), ()): ("I;32BS", "I;32BS"),
|
||||
(II, 1, (3,), 1, (32,), ()): ("F", "F;32F"),
|
||||
(MM, 1, (3,), 1, (32,), ()): ("F", "F;32BF"),
|
||||
|
||||
(II, 1, (1,), 1, (8, 8), (2,)): ("LA", "LA"),
|
||||
(MM, 1, (1,), 1, (8, 8), (2,)): ("LA", "LA"),
|
||||
|
||||
(II, 2, (1,), 1, (8, 8, 8), ()): ("RGB", "RGB"),
|
||||
(MM, 2, (1,), 1, (8, 8, 8), ()): ("RGB", "RGB"),
|
||||
(II, 2, (1,), 2, (8, 8, 8), ()): ("RGB", "RGB;R"),
|
||||
|
@ -183,6 +205,7 @@ OPEN_INFO = {
|
|||
(MM, 2, (1,), 1, (8, 8, 8, 8), (2,)): ("RGBA", "RGBA"),
|
||||
(II, 2, (1,), 1, (8, 8, 8, 8), (999,)): ("RGBA", "RGBA"), # Corel Draw 10
|
||||
(MM, 2, (1,), 1, (8, 8, 8, 8), (999,)): ("RGBA", "RGBA"), # Corel Draw 10
|
||||
|
||||
(II, 3, (1,), 1, (1,), ()): ("P", "P;1"),
|
||||
(MM, 3, (1,), 1, (1,), ()): ("P", "P;1"),
|
||||
(II, 3, (1,), 2, (1,), ()): ("P", "P;1R"),
|
||||
|
@ -201,10 +224,13 @@ OPEN_INFO = {
|
|||
(MM, 3, (1,), 1, (8, 8), (2,)): ("PA", "PA"),
|
||||
(II, 3, (1,), 2, (8,), ()): ("P", "P;R"),
|
||||
(MM, 3, (1,), 2, (8,), ()): ("P", "P;R"),
|
||||
|
||||
(II, 5, (1,), 1, (8, 8, 8, 8), ()): ("CMYK", "CMYK"),
|
||||
(MM, 5, (1,), 1, (8, 8, 8, 8), ()): ("CMYK", "CMYK"),
|
||||
|
||||
(II, 6, (1,), 1, (8, 8, 8), ()): ("YCbCr", "YCbCr"),
|
||||
(MM, 6, (1,), 1, (8, 8, 8), ()): ("YCbCr", "YCbCr"),
|
||||
|
||||
(II, 8, (1,), 1, (8, 8, 8), ()): ("LAB", "LAB"),
|
||||
(MM, 8, (1,), 1, (8, 8, 8), ()): ("LAB", "LAB"),
|
||||
}
|
||||
|
|
BIN
Tests/images/tiff_gray_2_4_bpp/hopper2.tif
Normal file
BIN
Tests/images/tiff_gray_2_4_bpp/hopper2.tif
Normal file
Binary file not shown.
BIN
Tests/images/tiff_gray_2_4_bpp/hopper2I.tif
Normal file
BIN
Tests/images/tiff_gray_2_4_bpp/hopper2I.tif
Normal file
Binary file not shown.
BIN
Tests/images/tiff_gray_2_4_bpp/hopper2IR.tif
Normal file
BIN
Tests/images/tiff_gray_2_4_bpp/hopper2IR.tif
Normal file
Binary file not shown.
BIN
Tests/images/tiff_gray_2_4_bpp/hopper2R.tif
Normal file
BIN
Tests/images/tiff_gray_2_4_bpp/hopper2R.tif
Normal file
Binary file not shown.
BIN
Tests/images/tiff_gray_2_4_bpp/hopper4.tif
Normal file
BIN
Tests/images/tiff_gray_2_4_bpp/hopper4.tif
Normal file
Binary file not shown.
BIN
Tests/images/tiff_gray_2_4_bpp/hopper4I.tif
Normal file
BIN
Tests/images/tiff_gray_2_4_bpp/hopper4I.tif
Normal file
Binary file not shown.
BIN
Tests/images/tiff_gray_2_4_bpp/hopper4IR.tif
Normal file
BIN
Tests/images/tiff_gray_2_4_bpp/hopper4IR.tif
Normal file
Binary file not shown.
BIN
Tests/images/tiff_gray_2_4_bpp/hopper4R.tif
Normal file
BIN
Tests/images/tiff_gray_2_4_bpp/hopper4R.tif
Normal file
Binary file not shown.
|
@ -419,6 +419,39 @@ class TestFileLibTiff(LibTiffTestCase):
|
|||
self.assertEqual(im.mode, "L")
|
||||
self.assert_image_similar(im, original, 7.3)
|
||||
|
||||
def test_gray_semibyte_per_pixel(self):
|
||||
test_files = (
|
||||
(
|
||||
24.8,#epsilon
|
||||
(#group
|
||||
"Tests/images/tiff_gray_2_4_bpp/hopper2.tif",
|
||||
"Tests/images/tiff_gray_2_4_bpp/hopper2I.tif",
|
||||
"Tests/images/tiff_gray_2_4_bpp/hopper2R.tif",
|
||||
"Tests/images/tiff_gray_2_4_bpp/hopper2IR.tif",
|
||||
)
|
||||
),
|
||||
(
|
||||
7.3,#epsilon
|
||||
(#group
|
||||
"Tests/images/tiff_gray_2_4_bpp/hopper4.tif",
|
||||
"Tests/images/tiff_gray_2_4_bpp/hopper4I.tif",
|
||||
"Tests/images/tiff_gray_2_4_bpp/hopper4R.tif",
|
||||
"Tests/images/tiff_gray_2_4_bpp/hopper4IR.tif",
|
||||
)
|
||||
),
|
||||
)
|
||||
original = hopper("L")
|
||||
for epsilon, group in test_files:
|
||||
im = Image.open(group[0])
|
||||
self.assertEqual(im.size, (128, 128))
|
||||
self.assertEqual(im.mode, "L")
|
||||
self.assert_image_similar(im, original, epsilon)
|
||||
for file in group[1:]:
|
||||
im2 = Image.open(file)
|
||||
self.assertEqual(im2.size, (128, 128))
|
||||
self.assertEqual(im2.mode, "L")
|
||||
self.assert_image_equal(im, im2)
|
||||
|
||||
def test_save_bytesio(self):
|
||||
# PR 1011
|
||||
# Test TIFF saving to io.BytesIO() object.
|
||||
|
|
|
@ -337,6 +337,39 @@ class TestFileTiff(PillowTestCase):
|
|||
self.assertEqual(im.mode, "L")
|
||||
self.assert_image_similar(im, original, 7.3)
|
||||
|
||||
def test_gray_semibyte_per_pixel(self):
|
||||
test_files = (
|
||||
(
|
||||
24.8,#epsilon
|
||||
(#group
|
||||
"Tests/images/tiff_gray_2_4_bpp/hopper2.tif",
|
||||
"Tests/images/tiff_gray_2_4_bpp/hopper2I.tif",
|
||||
"Tests/images/tiff_gray_2_4_bpp/hopper2R.tif",
|
||||
"Tests/images/tiff_gray_2_4_bpp/hopper2IR.tif",
|
||||
)
|
||||
),
|
||||
(
|
||||
7.3,#epsilon
|
||||
(#group
|
||||
"Tests/images/tiff_gray_2_4_bpp/hopper4.tif",
|
||||
"Tests/images/tiff_gray_2_4_bpp/hopper4I.tif",
|
||||
"Tests/images/tiff_gray_2_4_bpp/hopper4R.tif",
|
||||
"Tests/images/tiff_gray_2_4_bpp/hopper4IR.tif",
|
||||
)
|
||||
),
|
||||
)
|
||||
original = hopper("L")
|
||||
for epsilon, group in test_files:
|
||||
im = Image.open(group[0])
|
||||
self.assertEqual(im.size, (128, 128))
|
||||
self.assertEqual(im.mode, "L")
|
||||
self.assert_image_similar(im, original, epsilon)
|
||||
for file in group[1:]:
|
||||
im2 = Image.open(file)
|
||||
self.assertEqual(im2.size, (128, 128))
|
||||
self.assertEqual(im2.mode, "L")
|
||||
self.assert_image_equal(im, im2)
|
||||
|
||||
def test_page_number_x_0(self):
|
||||
# Issue 973
|
||||
# Test TIFF with tag 297 (Page Number) having value of 0 0.
|
||||
|
|
|
@ -191,14 +191,64 @@ unpack1IR(UINT8* out, const UINT8* in, int pixels)
|
|||
static void
|
||||
unpackL2(UINT8* out, const UINT8* in, int pixels)
|
||||
{
|
||||
/* nibbles */
|
||||
/* nibbles (msb first, white is non-zero) */
|
||||
while (pixels > 0) {
|
||||
UINT8 byte = *in++;
|
||||
switch (pixels) {
|
||||
default: *out++ = ((byte >> 6) & 3) * 255 / 3; byte <<= 2;
|
||||
case 3: *out++ = ((byte >> 6) & 3) * 255 / 3; byte <<= 2;
|
||||
case 2: *out++ = ((byte >> 6) & 3) * 255 / 3; byte <<= 2;
|
||||
case 1: *out++ = ((byte >> 6) & 3) * 255 / 3;
|
||||
default: *out++ = ((byte >> 6) & 0x03U) * 0x55U; byte <<= 2;
|
||||
case 3: *out++ = ((byte >> 6) & 0x03U) * 0x55U; byte <<= 2;
|
||||
case 2: *out++ = ((byte >> 6) & 0x03U) * 0x55U; byte <<= 2;
|
||||
case 1: *out++ = ((byte >> 6) & 0x03U) * 0x55U;
|
||||
}
|
||||
pixels -= 4;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
unpackL2I(UINT8* out, const UINT8* in, int pixels)
|
||||
{
|
||||
/* nibbles (msb first, white is zero) */
|
||||
while (pixels > 0) {
|
||||
UINT8 byte = *in++;
|
||||
switch (pixels) {
|
||||
default: *out++ = 0xFFU - (UINT8)(((byte >> 6) & 0x03U) * 0x55U); byte <<= 2;
|
||||
case 3: *out++ = 0xFFU - (UINT8)(((byte >> 6) & 0x03U) * 0x55U); byte <<= 2;
|
||||
case 2: *out++ = 0xFFU - (UINT8)(((byte >> 6) & 0x03U) * 0x55U); byte <<= 2;
|
||||
case 1: *out++ = 0xFFU - (UINT8)(((byte >> 6) & 0x03U) * 0x55U);
|
||||
}
|
||||
pixels -= 4;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
unpackL2R(UINT8* out, const UINT8* in, int pixels)
|
||||
{
|
||||
/* nibbles (bit order reversed, white is non-zero) */
|
||||
while (pixels > 0) {
|
||||
UINT8 byte = *in++;
|
||||
byte = BITFLIP[byte];
|
||||
switch (pixels) {
|
||||
default: *out++ = ((byte >> 6) & 0x03U) * 0x55U; byte <<= 2;
|
||||
case 3: *out++ = ((byte >> 6) & 0x03U) * 0x55U; byte <<= 2;
|
||||
case 2: *out++ = ((byte >> 6) & 0x03U) * 0x55U; byte <<= 2;
|
||||
case 1: *out++ = ((byte >> 6) & 0x03U) * 0x55U;
|
||||
}
|
||||
pixels -= 4;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
unpackL2IR(UINT8* out, const UINT8* in, int pixels)
|
||||
{
|
||||
/* nibbles (bit order reversed, white is zero) */
|
||||
while (pixels > 0) {
|
||||
UINT8 byte = *in++;
|
||||
byte = BITFLIP[byte];
|
||||
switch (pixels) {
|
||||
default: *out++ = 0xFFU - (UINT8)(((byte >> 6) & 0x03U) * 0x55U); byte <<= 2;
|
||||
case 3: *out++ = 0xFFU - (UINT8)(((byte >> 6) & 0x03U) * 0x55U); byte <<= 2;
|
||||
case 2: *out++ = 0xFFU - (UINT8)(((byte >> 6) & 0x03U) * 0x55U); byte <<= 2;
|
||||
case 1: *out++ = 0xFFU - (UINT8)(((byte >> 6) & 0x03U) * 0x55U);
|
||||
}
|
||||
pixels -= 4;
|
||||
}
|
||||
|
@ -207,12 +257,56 @@ unpackL2(UINT8* out, const UINT8* in, int pixels)
|
|||
static void
|
||||
unpackL4(UINT8* out, const UINT8* in, int pixels)
|
||||
{
|
||||
/* nibbles */
|
||||
/* nibbles (msb first, white is non-zero) */
|
||||
while (pixels > 0) {
|
||||
UINT8 byte = *in++;
|
||||
switch (pixels) {
|
||||
default: *out++ = ((byte >> 4) & 15) * 255 / 15; byte <<= 4;
|
||||
case 1: *out++ = ((byte >> 4) & 15) * 255 / 15;
|
||||
default: *out++ = ((byte >> 4) & 0x0FU) * 0x11U; byte <<= 4;
|
||||
case 1: *out++ = ((byte >> 4) & 0x0FU) * 0x11U;
|
||||
}
|
||||
pixels -= 2;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
unpackL4I(UINT8* out, const UINT8* in, int pixels)
|
||||
{
|
||||
/* nibbles (msb first, white is zero) */
|
||||
while (pixels > 0) {
|
||||
UINT8 byte = *in++;
|
||||
switch (pixels) {
|
||||
default: *out++ = 0xFFU - (UINT8)(((byte >> 4) & 0x0FU) * 0x11U); byte <<= 4;
|
||||
case 1: *out++ = 0xFFU - (UINT8)(((byte >> 4) & 0x0FU) * 0x11U);
|
||||
}
|
||||
pixels -= 2;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
unpackL4R(UINT8* out, const UINT8* in, int pixels)
|
||||
{
|
||||
/* nibbles (bit order reversed, white is non-zero) */
|
||||
while (pixels > 0) {
|
||||
UINT8 byte = *in++;
|
||||
byte = BITFLIP[byte];
|
||||
switch (pixels) {
|
||||
default: *out++ = ((byte >> 4) & 0x0FU) * 0x11U; byte <<= 4;
|
||||
case 1: *out++ = ((byte >> 4) & 0x0FU) * 0x11U;
|
||||
}
|
||||
pixels -= 2;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
unpackL4IR(UINT8* out, const UINT8* in, int pixels)
|
||||
{
|
||||
/* nibbles (bit order reversed, white is zero) */
|
||||
while (pixels > 0) {
|
||||
UINT8 byte = *in++;
|
||||
byte = BITFLIP[byte];
|
||||
switch (pixels) {
|
||||
default: *out++ = 0xFFU - (UINT8)(((byte >> 4) & 0x0FU) * 0x11U); byte <<= 4;
|
||||
case 1: *out++ = 0xFFU - (UINT8)(((byte >> 4) & 0x0FU) * 0x11U);
|
||||
}
|
||||
pixels -= 2;
|
||||
}
|
||||
|
@ -1053,7 +1147,15 @@ static struct {
|
|||
|
||||
/* greyscale */
|
||||
{"L", "L;2", 2, unpackL2},
|
||||
{"L", "L;2I", 2, unpackL2I},
|
||||
{"L", "L;2R", 2, unpackL2R},
|
||||
{"L", "L;2IR", 2, unpackL2IR},
|
||||
|
||||
{"L", "L;4", 4, unpackL4},
|
||||
{"L", "L;4I", 4, unpackL4I},
|
||||
{"L", "L;4R", 4, unpackL4R},
|
||||
{"L", "L;4IR", 4, unpackL4IR},
|
||||
|
||||
{"L", "L", 8, copy1},
|
||||
{"L", "L;I", 8, unpackLI},
|
||||
{"L", "L;R", 8, unpackLR},
|
||||
|
|
Loading…
Reference in New Issue
Block a user