Fixed reading and saving for TIFF and IM in PA mode

This commit is contained in:
Andrew Murray 2019-05-11 14:43:48 +10:00
parent e9c0cf61f3
commit e131fa22e2
5 changed files with 22 additions and 10 deletions

View File

@ -48,7 +48,7 @@ class TestFileIm(PillowTestCase):
im.seek(n_frames-1) im.seek(n_frames-1)
def test_roundtrip(self): def test_roundtrip(self):
for mode in ["RGB", "P"]: for mode in ["RGB", "P", "PA"]:
out = self.tempfile('temp.im') out = self.tempfile('temp.im')
im = hopper(mode) im = hopper(mode)
im.save(out) im.save(out)

View File

@ -489,6 +489,16 @@ class TestFileTiff(PillowTestCase):
self.assert_image_equal_tofile(im, self.assert_image_equal_tofile(im,
"Tests/images/tiff_adobe_deflate.png") "Tests/images/tiff_adobe_deflate.png")
def test_palette(self):
for mode in ["P", "PA"]:
outfile = self.tempfile("temp.tif")
im = hopper(mode)
im.save(outfile)
reloaded = Image.open(outfile)
self.assert_image_equal(im.convert("RGB"), reloaded.convert("RGB"))
def test_tiff_save_all(self): def test_tiff_save_all(self):
import io import io
import os import os

View File

@ -71,6 +71,7 @@ OPEN = {
"RYB3 image": ("RGB", "RYB;T"), "RYB3 image": ("RGB", "RYB;T"),
# extensions # extensions
"LA image": ("LA", "LA;L"), "LA image": ("LA", "LA;L"),
"PA image": ("LA", "PA;L"),
"RGBA image": ("RGBA", "RGBA;L"), "RGBA image": ("RGBA", "RGBA;L"),
"RGBX image": ("RGBX", "RGBX;L"), "RGBX image": ("RGBX", "RGBX;L"),
"CMYK image": ("CMYK", "CMYK;L"), "CMYK image": ("CMYK", "CMYK;L"),
@ -218,15 +219,16 @@ class ImImageFile(ImageFile.ImageFile):
linear = 0 linear = 0
else: else:
greyscale = 0 greyscale = 0
if self.mode == "L" or self.mode == "LA": if self.mode in ["L", "LA", "P", "PA"]:
if greyscale: if greyscale:
if not linear: if not linear:
self.lut = [i8(c) for c in palette[:256]] self.lut = [i8(c) for c in palette[:256]]
else: else:
if self.mode == "L": if self.mode in ["L", "P"]:
self.mode = self.rawmode = "P" self.mode = self.rawmode = "P"
elif self.mode == "LA": elif self.mode in ["LA", "PA"]:
self.mode = self.rawmode = "PA" self.mode = "PA"
self.rawmode = "PA;L"
self.palette = ImagePalette.raw("RGB;L", palette) self.palette = ImagePalette.raw("RGB;L", palette)
elif self.mode == "RGB": elif self.mode == "RGB":
if not greyscale or not linear: if not greyscale or not linear:
@ -340,10 +342,10 @@ def _save(im, fp, filename):
fp.write(("Name: %s\r\n" % filename).encode('ascii')) fp.write(("Name: %s\r\n" % filename).encode('ascii'))
fp.write(("Image size (x*y): %d*%d\r\n" % im.size).encode('ascii')) fp.write(("Image size (x*y): %d*%d\r\n" % im.size).encode('ascii'))
fp.write(("File size (no of images): %d\r\n" % frames).encode('ascii')) fp.write(("File size (no of images): %d\r\n" % frames).encode('ascii'))
if im.mode == "P": if im.mode in ["P", "PA"]:
fp.write(b"Lut: 1\r\n") fp.write(b"Lut: 1\r\n")
fp.write(b"\000" * (511-fp.tell()) + b"\032") fp.write(b"\000" * (511-fp.tell()) + b"\032")
if im.mode == "P": if im.mode in ["P", "PA"]:
fp.write(im.im.getpalette("RGB", "RGB;L")) # 768 bytes fp.write(im.im.getpalette("RGB", "RGB;L")) # 768 bytes
ImageFile._save(im, fp, [("raw", (0, 0)+im.size, 0, (rawmode, 0, -1))]) ImageFile._save(im, fp, [("raw", (0, 0)+im.size, 0, (rawmode, 0, -1))])

View File

@ -1358,7 +1358,7 @@ class TiffImageFile(ImageFile.ImageFile):
# fixup palette descriptor # fixup palette descriptor
if self.mode == "P": if self.mode in ["P", "PA"]:
palette = [o8(b // 256) for b in self.tag_v2[COLORMAP]] palette = [o8(b // 256) for b in self.tag_v2[COLORMAP]]
self.palette = ImagePalette.raw("RGB;L", b"".join(palette)) self.palette = ImagePalette.raw("RGB;L", b"".join(palette))
@ -1484,7 +1484,7 @@ def _save(im, fp, filename):
ifd[PHOTOMETRIC_INTERPRETATION] = photo ifd[PHOTOMETRIC_INTERPRETATION] = photo
if im.mode == "P": if im.mode in ["P", "PA"]:
lut = im.im.getpalette("RGB", "RGB;L") lut = im.im.getpalette("RGB", "RGB;L")
ifd[COLORMAP] = tuple(i8(v) * 256 for v in lut) ifd[COLORMAP] = tuple(i8(v) * 256 for v in lut)
# data orientation # data orientation

View File

@ -1588,7 +1588,7 @@ _putpalette(ImagingObject* self, PyObject* args)
ImagingPaletteDelete(self->image->palette); ImagingPaletteDelete(self->image->palette);
strcpy(self->image->mode, "P"); strcpy(self->image->mode, strlen(self->image->mode) == 2 ? "PA" : "P");
self->image->palette = ImagingPaletteNew("RGB"); self->image->palette = ImagingPaletteNew("RGB");