Allow multipage CCITT group 4 TIFF images

This commit is contained in:
Johannes 'josch' Schauer 2018-08-16 00:23:18 +02:00
parent a628ed22f9
commit ba5a9a1dfc
Signed by: josch
GPG key ID: F2CBA5C78FBD83E1

View file

@ -861,45 +861,17 @@ def read_images(rawdata, colorspace, first_frame_only=False):
return [(color, ndpi, imgformat, pngidat, imgwidthpx, imgheightpx, return [(color, ndpi, imgformat, pngidat, imgwidthpx, imgheightpx,
palette, False)] palette, False)]
# We can directly copy the data out of a CCITT Group 4 encoded TIFF, if it # If our input is not JPEG or PNG, then we might have a format that
# only contains a single strip # supports multiple frames (like TIFF or GIF), so we need a loop to
if imgformat == ImageFormat.TIFF \ # iterate through all frames of the image.
and imgdata.info['compression'] == "group4" \ #
and len(imgdata.tag_v2[TiffImagePlugin.STRIPOFFSETS]) == 1: # Each frame gets compressed using PNG compression *except* if:
photo = imgdata.tag_v2[TiffImagePlugin.PHOTOMETRIC_INTERPRETATION] #
inverted = False # * The image is monochrome => encode using CCITT group 4
if photo == 0: #
inverted = True # * The image is CMYK => zip plain RGB data
elif photo != 1: #
raise ValueError("unsupported photometric interpretation for " # * We are handling a CCITT encoded TIFF frame => embed data
"group4 tiff: %d" % photo)
color, ndpi, imgwidthpx, imgheightpx = get_imgmetadata(
imgdata, imgformat, default_dpi, colorspace, rawdata)
offset, length = ccitt_payload_location_from_pil(imgdata)
im.seek(offset)
rawdata = im.read(length)
im.close()
fillorder = imgdata.tag_v2.get(TiffImagePlugin.FILLORDER)
if fillorder is None:
# no FillOrder: nothing to do
pass
elif fillorder == 1:
# msb-to-lsb: nothing to do
pass
elif fillorder == 2:
logging.debug("fillorder is lsb-to-msb => reverse bits")
# lsb-to-msb: reverse bits of each byte
rawdata = bytearray(rawdata)
for i in range(len(rawdata)):
rawdata[i] = TIFFBitRevTable[rawdata[i]]
rawdata = bytes(rawdata)
else:
raise ValueError("unsupported FillOrder: %d" % fillorder)
logging.debug("read_images() embeds a TIFF")
return [(color, ndpi, ImageFormat.CCITTGroup4, rawdata, imgwidthpx,
imgheightpx, [], inverted)]
# Everything else has to be encoded
result = [] result = []
img_page_count = 0 img_page_count = 0
@ -913,6 +885,45 @@ def read_images(rawdata, colorspace, first_frame_only=False):
if first_frame_only and img_page_count > 0: if first_frame_only and img_page_count > 0:
break break
# We can directly copy the data out of a CCITT Group 4 encoded TIFF, if it
# only contains a single strip
if imgformat == ImageFormat.TIFF \
and imgdata.info['compression'] == "group4" \
and len(imgdata.tag_v2[TiffImagePlugin.STRIPOFFSETS]) == 1:
photo = imgdata.tag_v2[TiffImagePlugin.PHOTOMETRIC_INTERPRETATION]
inverted = False
if photo == 0:
inverted = True
elif photo != 1:
raise ValueError("unsupported photometric interpretation for "
"group4 tiff: %d" % photo)
color, ndpi, imgwidthpx, imgheightpx = get_imgmetadata(
imgdata, imgformat, default_dpi, colorspace, rawdata)
offset, length = ccitt_payload_location_from_pil(imgdata)
im.seek(offset)
rawdata = im.read(length)
fillorder = imgdata.tag_v2.get(TiffImagePlugin.FILLORDER)
if fillorder is None:
# no FillOrder: nothing to do
pass
elif fillorder == 1:
# msb-to-lsb: nothing to do
pass
elif fillorder == 2:
logging.debug("fillorder is lsb-to-msb => reverse bits")
# lsb-to-msb: reverse bits of each byte
rawdata = bytearray(rawdata)
for i in range(len(rawdata)):
rawdata[i] = TIFFBitRevTable[rawdata[i]]
rawdata = bytes(rawdata)
else:
raise ValueError("unsupported FillOrder: %d" % fillorder)
logging.debug("read_images() embeds a TIFF")
result.append((color, ndpi, ImageFormat.CCITTGroup4, rawdata,
imgwidthpx, imgheightpx, [], inverted))
img_page_count += 1
continue
logging.debug("Converting frame: %d" % img_page_count) logging.debug("Converting frame: %d" % img_page_count)
color, ndpi, imgwidthpx, imgheightpx = get_imgmetadata( color, ndpi, imgwidthpx, imgheightpx = get_imgmetadata(