summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohannes Schauer Marin Rodrigues <josch@debian.org>2021-10-11 17:21:44 +0200
committerJohannes Schauer Marin Rodrigues <josch@debian.org>2021-10-11 17:21:44 +0200
commit0b488a95d20ff071cdd5d20a4800e48bed8bfe58 (patch)
tree99003b460e36c6dbd712328a3040300fe019115b
parent0bb7732c5e4e79e9bf096b44f596e69be0554d59 (diff)
New upstream version 0.4.2
-rw-r--r--CHANGES.rst18
-rw-r--r--PKG-INFO57
-rw-r--r--README.md53
-rwxr-xr-xmagick.py353
-rw-r--r--setup.cfg3
-rw-r--r--setup.py6
-rw-r--r--src/img2pdf.egg-info/PKG-INFO57
-rw-r--r--src/img2pdf.egg-info/SOURCES.txt3
-rwxr-xr-xsrc/img2pdf.py641
-rwxr-xr-x[-rw-r--r--]src/img2pdf_test.py1504
-rwxr-xr-xtest.sh1631
11 files changed, 1493 insertions, 2833 deletions
diff --git a/CHANGES.rst b/CHANGES.rst
index 4b325bb..68a0187 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -2,6 +2,24 @@
CHANGES
=======
+0.4.2 (2021-10-11)
+------------------
+
+ - add --rotation
+ - allow palette PNG images with ICC profile
+ - sort globbing result on windows
+ - convert 8-bit PNG alpha channels to /SMasks in PDF
+ - remove pdfrw from tests
+
+0.4.1 (2021-05-09)
+------------------
+
+ - support wildcards in paths on windows
+ - support MPO images
+ - fix page border computation
+ - use "img2pdf" logger instead of "root" logger
+ - add --from-file
+
0.4.0 (2020-08-07)
------------------
diff --git a/PKG-INFO b/PKG-INFO
index f790551..a1b430d 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,14 +1,14 @@
Metadata-Version: 2.1
Name: img2pdf
-Version: 0.4.0
+Version: 0.4.2
Summary: Convert images to PDF via direct JPEG inclusion.
Home-page: https://gitlab.mister-muffin.de/josch/img2pdf
Author: Johannes 'josch' Schauer
Author-email: josch@mister-muffin.de
License: LGPL
-Download-URL: https://gitlab.mister-muffin.de/josch/img2pdf/repository/archive.tar.gz?ref=0.4.0
-Description: [![Travis Status](https://travis-ci.org/josch/img2pdf.svg?branch=master)](https://travis-ci.org/josch/img2pdf)
- [![Appveyor Status](https://ci.appveyor.com/api/projects/status/2kws3wkqvi526llj/branch/master?svg=true)](https://ci.appveyor.com/project/josch/img2pdf/branch/master)
+Download-URL: https://gitlab.mister-muffin.de/josch/img2pdf/repository/archive.tar.gz?ref=0.4.2
+Description: [![Travis Status](https://travis-ci.com/josch/img2pdf.svg?branch=main)](https://app.travis-ci.com/josch/img2pdf)
+ [![Appveyor Status](https://ci.appveyor.com/api/projects/status/2kws3wkqvi526llj/branch/main?svg=true)](https://ci.appveyor.com/project/josch/img2pdf/branch/main)
img2pdf
=======
@@ -86,10 +86,12 @@ Description: [![Travis Status](https://travis-ci.org/josch/img2pdf.svg?branch=ma
files with other colorspaces, you must explicitly specify it using the
`--colorspace` option.
- - Input images with alpha channels are not allowed. PDF only supports
- transparency using binary masks but is unable to store 8-bit transparency
- information as part of the image itself. But img2pdf will always be lossless
- and thus, input images must not carry transparency information.
+ - An error is produced if the input image is broken. This commonly happens if
+ the input image has an invalid EXIF Orientation value of zero. Even though
+ only nine different values from 1 to 9 are permitted, Anroid phones and
+ Canon DSLR cameras produce JPEG images with the invalid value of zero.
+ Either fix your input images with `exiftool` or similar software before
+ passing the JPEG to `img2pdf` or run `img2pdf` with `--rotation=ifvalid`.
- img2pdf uses PIL (or Pillow) to obtain image meta data and to convert the
input if necessary. To prevent decompression bomb denial of service attacks,
@@ -170,26 +172,26 @@ Description: [![Travis Status](https://travis-ci.org/josch/img2pdf.svg?branch=ma
# convert all files ending in .jpg inside a directory
dirname = "/path/to/images"
+ imgs = []
+ for fname in os.listdir(dirname):
+ if not fname.endswith(".jpg"):
+ continue
+ path = os.path.join(dirname, fname)
+ if os.path.isdir(path):
+ continue
+ imgs.append(path)
with open("name.pdf","wb") as f:
- imgs = []
- for fname in os.listdir(dirname):
- if not fname.endswith(".jpg"):
- continue
- path = os.path.join(dirname, fname)
- if os.path.isdir(path):
- continue
- imgs.append(path)
f.write(img2pdf.convert(imgs))
# convert all files ending in .jpg in a directory and its subdirectories
dirname = "/path/to/images"
+ imgs = []
+ for r, _, f in os.walk(dirname):
+ for fname in f:
+ if not fname.endswith(".jpg"):
+ continue
+ imgs.append(os.path.join(r, fname))
with open("name.pdf","wb") as f:
- imgs = []
- for r, _, f in os.walk(dirname):
- for fname in f:
- if not fname.endswith(".jpg"):
- continue
- imgs.append(os.path.join(r, fname))
f.write(img2pdf.convert(imgs))
@@ -208,6 +210,16 @@ Description: [![Travis Status](https://travis-ci.org/josch/img2pdf.svg?branch=ma
with open("name.pdf","wb") as f:
f.write(img2pdf.convert('test.jpg', layout_fun=layout_fun))
+ # use a fixed dpi of 300 instead of reading it from the image
+ dpix = dpiy = 300
+ layout_fun = img2pdf.get_fixed_dpi_layout_fun((dpix, dpiy))
+ with open("name.pdf","wb") as f:
+ f.write(img2pdf.convert('test.jpg', layout_fun=layout_fun))
+
+ # create a PDF/A-1b compliant document by passing an ICC profile
+ with open("name.pdf","wb") as f:
+ f.write(img2pdf.convert('test.jpg', pdfa="/usr/share/color/icc/sRGB.icc"))
+
Comparison to ImageMagick
-------------------------
@@ -295,7 +307,6 @@ Description: [![Travis Status](https://travis-ci.org/josch/img2pdf.svg?branch=ma
input to RGB and removes the alpha channel from images with transparency. For
multipage TIFF or animated GIF, it will only convert the first frame.
-
Keywords: jpeg pdf converter
Platform: UNKNOWN
Classifier: Development Status :: 5 - Production/Stable
diff --git a/README.md b/README.md
index 846f1fa..5e47383 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,5 @@
-[![Travis Status](https://travis-ci.org/josch/img2pdf.svg?branch=master)](https://travis-ci.org/josch/img2pdf)
-[![Appveyor Status](https://ci.appveyor.com/api/projects/status/2kws3wkqvi526llj/branch/master?svg=true)](https://ci.appveyor.com/project/josch/img2pdf/branch/master)
+[![Travis Status](https://travis-ci.com/josch/img2pdf.svg?branch=main)](https://app.travis-ci.com/josch/img2pdf)
+[![Appveyor Status](https://ci.appveyor.com/api/projects/status/2kws3wkqvi526llj/branch/main?svg=true)](https://ci.appveyor.com/project/josch/img2pdf/branch/main)
img2pdf
=======
@@ -77,10 +77,12 @@ Bugs
files with other colorspaces, you must explicitly specify it using the
`--colorspace` option.
- - Input images with alpha channels are not allowed. PDF only supports
- transparency using binary masks but is unable to store 8-bit transparency
- information as part of the image itself. But img2pdf will always be lossless
- and thus, input images must not carry transparency information.
+ - An error is produced if the input image is broken. This commonly happens if
+ the input image has an invalid EXIF Orientation value of zero. Even though
+ only nine different values from 1 to 9 are permitted, Anroid phones and
+ Canon DSLR cameras produce JPEG images with the invalid value of zero.
+ Either fix your input images with `exiftool` or similar software before
+ passing the JPEG to `img2pdf` or run `img2pdf` with `--rotation=ifvalid`.
- img2pdf uses PIL (or Pillow) to obtain image meta data and to convert the
input if necessary. To prevent decompression bomb denial of service attacks,
@@ -161,26 +163,26 @@ The package can also be used as a library:
# convert all files ending in .jpg inside a directory
dirname = "/path/to/images"
+ imgs = []
+ for fname in os.listdir(dirname):
+ if not fname.endswith(".jpg"):
+ continue
+ path = os.path.join(dirname, fname)
+ if os.path.isdir(path):
+ continue
+ imgs.append(path)
with open("name.pdf","wb") as f:
- imgs = []
- for fname in os.listdir(dirname):
- if not fname.endswith(".jpg"):
- continue
- path = os.path.join(dirname, fname)
- if os.path.isdir(path):
- continue
- imgs.append(path)
f.write(img2pdf.convert(imgs))
# convert all files ending in .jpg in a directory and its subdirectories
dirname = "/path/to/images"
+ imgs = []
+ for r, _, f in os.walk(dirname):
+ for fname in f:
+ if not fname.endswith(".jpg"):
+ continue
+ imgs.append(os.path.join(r, fname))
with open("name.pdf","wb") as f:
- imgs = []
- for r, _, f in os.walk(dirname):
- for fname in f:
- if not fname.endswith(".jpg"):
- continue
- imgs.append(os.path.join(r, fname))
f.write(img2pdf.convert(imgs))
@@ -199,6 +201,16 @@ The package can also be used as a library:
with open("name.pdf","wb") as f:
f.write(img2pdf.convert('test.jpg', layout_fun=layout_fun))
+ # use a fixed dpi of 300 instead of reading it from the image
+ dpix = dpiy = 300
+ layout_fun = img2pdf.get_fixed_dpi_layout_fun((dpix, dpiy))
+ with open("name.pdf","wb") as f:
+ f.write(img2pdf.convert('test.jpg', layout_fun=layout_fun))
+
+ # create a PDF/A-1b compliant document by passing an ICC profile
+ with open("name.pdf","wb") as f:
+ f.write(img2pdf.convert('test.jpg', pdfa="/usr/share/color/icc/sRGB.icc"))
+
Comparison to ImageMagick
-------------------------
@@ -285,4 +297,3 @@ you should safely be able to use Tesseract instead of img2pdf. For other input,
Tesseract might not do a lossless conversion. For example it converts CMYK
input to RGB and removes the alpha channel from images with transparency. For
multipage TIFF or animated GIF, it will only convert the first frame.
-
diff --git a/magick.py b/magick.py
deleted file mode 100755
index 1a074a1..0000000
--- a/magick.py
+++ /dev/null
@@ -1,353 +0,0 @@
-#!/usr/bin/env python3
-
-import sys
-import numpy
-import scipy.signal
-import zlib
-import struct
-
-
-def find_closest_palette_color(color, palette):
- if color.ndim == 0:
- idx = (numpy.abs(palette - color)).argmin()
- else:
- # naive distance function by computing the euclidean distance in RGB space
- idx = ((palette - color) ** 2).sum(axis=-1).argmin()
- return palette[idx]
-
-
-def floyd_steinberg(img, palette):
- result = numpy.array(img, copy=True)
- for y in range(result.shape[0]):
- for x in range(result.shape[1]):
- oldpixel = result[y, x]
- newpixel = find_closest_palette_color(oldpixel, palette)
- quant_error = oldpixel - newpixel
- result[y, x] = newpixel
- if x + 1 < result.shape[1]:
- result[y, x + 1] += quant_error * 7 / 16
- if y + 1 < result.shape[0]:
- result[y + 1, x - 1] += quant_error * 3 / 16
- result[y + 1, x] += quant_error * 5 / 16
- if x + 1 < result.shape[1] and y + 1 < result.shape[0]:
- result[y + 1, x + 1] += quant_error * 1 / 16
- return result
-
-
-def convolve_rgba(img, kernel):
- return numpy.stack(
- (
- scipy.signal.convolve2d(img[:, :, 0], kernel, "same"),
- scipy.signal.convolve2d(img[:, :, 1], kernel, "same"),
- scipy.signal.convolve2d(img[:, :, 2], kernel, "same"),
- scipy.signal.convolve2d(img[:, :, 3], kernel, "same"),
- ),
- axis=-1,
- )
-
-
-def rgb2gray(img):
- result = numpy.zeros((60, 60), dtype=numpy.dtype("int64"))
- for y in range(img.shape[0]):
- for x in range(img.shape[1]):
- clin = sum(img[y, x] * [0.2126, 0.7152, 0.0722]) / 0xFFFF
- if clin <= 0.0031308:
- csrgb = 12.92 * clin
- else:
- csrgb = 1.055 * clin ** (1 / 2.4) - 0.055
- result[y, x] = csrgb * 0xFFFF
- return result
-
-
-def palettize(img, pal):
- result = numpy.zeros((img.shape[0], img.shape[1]), dtype=numpy.dtype("int64"))
- for y in range(img.shape[0]):
- for x in range(img.shape[1]):
- for i, col in enumerate(pal):
- if numpy.array_equal(img[y, x], col):
- result[y, x] = i
- break
- else:
- raise Exception()
- return result
-
-
-# we cannot use zlib.compress() because different compressors may compress the
-# same data differently, for example by using different optimizations on
-# different architectures:
-# https://lists.fedoraproject.org/archives/list/devel@lists.fedoraproject.org/thread/R7GD4L5Z6HELCDAL2RDESWR2F3ZXHWVX/
-#
-# to make the compressed representation of the uncompressed data bit-by-bit
-# identical on all platforms we make use of the compression method 0, that is,
-# no compression at all :)
-def compress(data):
- # two-byte zlib header (rfc1950)
- # common header for lowest compression level
- # bits 0-3: Compression info, base-2 logarithm of the LZ77 window size,
- # minus eight -- 7 indicates a 32K window size
- # bits 4-7: Compression method -- 8 is deflate
- # bits 8-9: Compression level -- 0 is fastest
- # bit 10: preset dictionary -- 0 is none
- # bits 11-15: check bits so that the 16-bit unsigned integer stored in MSB
- # order is a multiple of 31
- result = b"\x78\x01"
- # content is stored in deflate format (rfc1951)
- # maximum chunk size is the largest 16 bit unsigned integer
- chunksize = 0xFFFF
- for i in range(0, len(data), chunksize):
- # bits 0-4 are unused
- # bits 5-6 indicate compression method -- 0 is no compression
- # bit 7 indicates the last chunk
- if i * chunksize < len(data) - chunksize:
- result += b"\x00"
- else:
- # last chunck
- result += b"\x01"
- chunk = data[i : i + chunksize]
- # the chunk length as little endian 16 bit unsigned integer
- result += struct.pack("<H", len(chunk))
- # the one's complement of the chunk length
- # one's complement is all bits inverted which is the result of
- # xor with 0xffff for a 16 bit unsigned integer
- result += struct.pack("<H", len(chunk) ^ 0xFFFF)
- result += chunk
- # adler32 checksum of the uncompressed data as big endian 32 bit unsigned
- # integer
- result += struct.pack(">I", zlib.adler32(data))
- return result
-
-
-def write_png(data, path, bitdepth, colortype, palette=None):
- with open(path, "wb") as f:
- f.write(b"\x89PNG\r\n\x1A\n")
- # PNG image type Colour type Allowed bit depths
- # Greyscale 0 1, 2, 4, 8, 16
- # Truecolour 2 8, 16
- # Indexed-colour 3 1, 2, 4, 8
- # Greyscale with alpha 4 8, 16
- # Truecolour with alpha 6 8, 16
- block = b"IHDR" + struct.pack(
- ">IIBBBBB",
- data.shape[1], # width
- data.shape[0], # height
- bitdepth, # bitdepth
- colortype, # colortype
- 0, # compression
- 0, # filtertype
- 0, # interlaced
- )
- f.write(
- struct.pack(">I", len(block) - 4)
- + block
- + struct.pack(">I", zlib.crc32(block))
- )
- if palette is not None:
- block = b"PLTE"
- for col in palette:
- block += struct.pack(">BBB", col[0], col[1], col[2])
- f.write(
- struct.pack(">I", len(block) - 4)
- + block
- + struct.pack(">I", zlib.crc32(block))
- )
- raw = b""
- for y in range(data.shape[0]):
- raw += b"\0"
- if bitdepth == 16:
- raw += data[y].astype(">u2").tobytes()
- elif bitdepth == 8:
- raw += data[y].astype(">u1").tobytes()
- elif bitdepth in [4, 2, 1]:
- valsperbyte = 8 // bitdepth
- for x in range(0, data.shape[1], valsperbyte):
- val = 0
- for j in range(valsperbyte):
- if x + j >= data.shape[1]:
- break
- val |= (data[y, x + j].astype(">u2") & (2 ** bitdepth - 1)) << (
- (valsperbyte - j - 1) * bitdepth
- )
- raw += struct.pack(">B", val)
- else:
- raise Exception()
- compressed = compress(raw)
- block = b"IDAT" + compressed
- f.write(
- struct.pack(">I", len(compressed))
- + block
- + struct.pack(">I", zlib.crc32(block))
- )
- block = b"IEND"
- f.write(struct.pack(">I", 0) + block + struct.pack(">I", zlib.crc32(block)))
-
-
-def main():
- outdir = sys.argv[1]
-
- # create a 256 color palette by first writing 16 shades of gray
- # and then writing an array of RGB colors with 6, 8 and 5 levels
- # for red, green and blue, respectively
- pal8 = numpy.zeros((256, 3), dtype=numpy.dtype("int64"))
- i = 0
- for gray in range(15, 255, 15):
- pal8[i] = [gray, gray, gray]
- i += 1
- for red in 0, 0x33, 0x66, 0x99, 0xCC, 0xFF:
- for green in 0, 0x24, 0x49, 0x6D, 0x92, 0xB6, 0xDB, 0xFF:
- for blue in 0, 0x40, 0x80, 0xBF, 0xFF:
- pal8[i] = [red, green, blue]
- i += 1
- assert i == 256
-
- # windows 16 color palette
- pal4 = numpy.array(
- [
- [0x00, 0x00, 0x00],
- [0x80, 0x00, 0x00],
- [0x00, 0x80, 0x00],
- [0x80, 0x80, 0x00],
- [0x00, 0x00, 0x80],
- [0x80, 0x00, 0x80],
- [0x00, 0x80, 0x80],
- [0xC0, 0xC0, 0xC0],
- [0x80, 0x80, 0x80],
- [0xFF, 0x00, 0x00],
- [0x00, 0xFF, 0x00],
- [0xFF, 0x00, 0x00],
- [0x00, 0xFF, 0x00],
- [0xFF, 0x00, 0xFF],
- [0x00, 0xFF, 0x00],
- [0xFF, 0xFF, 0xFF],
- ],
- dtype=numpy.dtype("int64"),
- )
-
- # choose values slightly off red, lime and blue because otherwise
- # imagemagick will classify the image as Depth: 8/1-bit
- pal2 = numpy.array(
- [[0, 0, 0], [0xFE, 0, 0], [0, 0xFE, 0], [0, 0, 0xFE]],
- dtype=numpy.dtype("int64"),
- )
-
- # don't choose black and white or otherwise imagemagick will classify the
- # image as bilevel with 8/1-bit depth instead of palette with 8-bit color
- # don't choose gray colors or otherwise imagemagick will classify the
- # image as grayscale
- pal1 = numpy.array(
- [[0x01, 0x02, 0x03], [0xFE, 0xFD, 0xFC]], dtype=numpy.dtype("int64")
- )
-
- # gaussian kernel with sigma=3
- kernel = numpy.array(
- [
- [0.011362, 0.014962, 0.017649, 0.018648, 0.017649, 0.014962, 0.011362],
- [0.014962, 0.019703, 0.02324, 0.024556, 0.02324, 0.019703, 0.014962],
- [0.017649, 0.02324, 0.027413, 0.028964, 0.027413, 0.02324, 0.017649],
- [0.018648, 0.024556, 0.028964, 0.030603, 0.028964, 0.024556, 0.018648],
- [0.017649, 0.02324, 0.027413, 0.028964, 0.027413, 0.02324, 0.017649],
- [0.014962, 0.019703, 0.02324, 0.024556, 0.02324, 0.019703, 0.014962],
- [0.011362, 0.014962, 0.017649, 0.018648, 0.017649, 0.014962, 0.011362],
- ],
- numpy.float,
- )
-
- # constructs a 2D array of a circle with a width of 36
- circle = list()
- offsets_36 = [14, 11, 9, 7, 6, 5, 4, 3, 3, 2, 2, 1, 1, 1, 0, 0, 0, 0]
- for offs in offsets_36 + offsets_36[::-1]:
- circle.append([0] * offs + [1] * (len(offsets_36) - offs) * 2 + [0] * offs)
-
- alpha = numpy.zeros((60, 60, 4), dtype=numpy.dtype("int64"))
-
- # draw three circles
- for (xpos, ypos, color) in [
- (12, 3, [0xFFFF, 0, 0, 0xFFFF]),
- (21, 21, [0, 0xFFFF, 0, 0xFFFF]),
- (3, 21, [0, 0, 0xFFFF, 0xFFFF]),
- ]:
- for x, row in enumerate(circle):
- for y, pos in enumerate(row):
- if pos:
- alpha[y + ypos, x + xpos] += color
- alpha = numpy.clip(alpha, 0, 0xFFFF)
- alpha = convolve_rgba(alpha, kernel)
-
- write_png(alpha, outdir + "/alpha.png", 16, 6)
-
- normal16 = alpha[:, :, 0:3]
- write_png(normal16, outdir + "/normal16.png", 16, 2)
-
- write_png(normal16 / 0xFFFF * 0xFF, outdir + "/normal.png", 8, 2)
-
- write_png(0xFF - normal16 / 0xFFFF * 0xFF, outdir + "/inverse.png", 8, 2)
-
- gray16 = rgb2gray(normal16)
-
- write_png(gray16, outdir + "/gray16.png", 16, 0)
-
- write_png(gray16 / 0xFFFF * 0xFF, outdir + "/gray8.png", 8, 0)
-
- write_png(
- floyd_steinberg(gray16, numpy.arange(16) / 0xF * 0xFFFF) / 0xFFFF * 0xF,
- outdir + "/gray4.png",
- 4,
- 0,
- )
-
- write_png(
- floyd_steinberg(gray16, numpy.arange(4) / 0x3 * 0xFFFF) / 0xFFFF * 0x3,
- outdir + "/gray2.png",
- 2,
- 0,
- )
-
- write_png(
- floyd_steinberg(gray16, numpy.arange(2) / 0x1 * 0xFFFF) / 0xFFFF * 0x1,
- outdir + "/gray1.png",
- 1,
- 0,
- )
-
- write_png(
- palettize(
- floyd_steinberg(normal16, pal8 * 0xFFFF / 0xFF) / 0xFFFF * 0xFF, pal8
- ),
- outdir + "/palette8.png",
- 8,
- 3,
- pal8,
- )
-
- write_png(
- palettize(
- floyd_steinberg(normal16, pal4 * 0xFFFF / 0xFF) / 0xFFFF * 0xFF, pal4
- ),
- outdir + "/palette4.png",
- 4,
- 3,
- pal4,
- )
-
- write_png(
- palettize(
- floyd_steinberg(normal16, pal2 * 0xFFFF / 0xFF) / 0xFFFF * 0xFF, pal2
- ),
- outdir + "/palette2.png",
- 2,
- 3,
- pal2,
- )
-
- write_png(
- palettize(
- floyd_steinberg(normal16, pal1 * 0xFFFF / 0xFF) / 0xFFFF * 0xFF, pal1
- ),
- outdir + "/palette1.png",
- 1,
- 3,
- pal1,
- )
-
-
-if __name__ == "__main__":
- main()
diff --git a/setup.cfg b/setup.cfg
index 9f88734..8bfd5a1 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,6 +1,3 @@
-[metadata]
-description-file = README.md
-
[egg_info]
tag_build =
tag_date = 0
diff --git a/setup.py b/setup.py
index 8b2c01f..070b1ea 100644
--- a/setup.py
+++ b/setup.py
@@ -1,7 +1,7 @@
import sys
from setuptools import setup
-VERSION = "0.4.0"
+VERSION = "0.4.2"
INSTALL_REQUIRES = (
"Pillow",
@@ -40,7 +40,9 @@ setup(
include_package_data=True,
zip_safe=True,
install_requires=INSTALL_REQUIRES,
- extras_require={"gui": ("tkinter"),},
+ extras_require={
+ "gui": ("tkinter"),
+ },
entry_points={
"setuptools.installation": ["eggsecutable = img2pdf:main"],
"console_scripts": ["img2pdf = img2pdf:main"],
diff --git a/src/img2pdf.egg-info/PKG-INFO b/src/img2pdf.egg-info/PKG-INFO
index f790551..a1b430d 100644
--- a/src/img2pdf.egg-info/PKG-INFO
+++ b/src/img2pdf.egg-info/PKG-INFO
@@ -1,14 +1,14 @@
Metadata-Version: 2.1
Name: img2pdf
-Version: 0.4.0
+Version: 0.4.2
Summary: Convert images to PDF via direct JPEG inclusion.
Home-page: https://gitlab.mister-muffin.de/josch/img2pdf
Author: Johannes 'josch' Schauer
Author-email: josch@mister-muffin.de
License: LGPL
-Download-URL: https://gitlab.mister-muffin.de/josch/img2pdf/repository/archive.tar.gz?ref=0.4.0
-Description: [![Travis Status](https://travis-ci.org/josch/img2pdf.svg?branch=master)](https://travis-ci.org/josch/img2pdf)
- [![Appveyor Status](https://ci.appveyor.com/api/projects/status/2kws3wkqvi526llj/branch/master?svg=true)](https://ci.appveyor.com/project/josch/img2pdf/branch/master)
+Download-URL: https://gitlab.mister-muffin.de/josch/img2pdf/repository/archive.tar.gz?ref=0.4.2
+Description: [![Travis Status](https://travis-ci.com/josch/img2pdf.svg?branch=main)](https://app.travis-ci.com/josch/img2pdf)
+ [![Appveyor Status](https://ci.appveyor.com/api/projects/status/2kws3wkqvi526llj/branch/main?svg=true)](https://ci.appveyor.com/project/josch/img2pdf/branch/main)
img2pdf
=======
@@ -86,10 +86,12 @@ Description: [![Travis Status](https://travis-ci.org/josch/img2pdf.svg?branch=ma
files with other colorspaces, you must explicitly specify it using the
`--colorspace` option.
- - Input images with alpha channels are not allowed. PDF only supports
- transparency using binary masks but is unable to store 8-bit transparency
- information as part of the image itself. But img2pdf will always be lossless
- and thus, input images must not carry transparency information.
+ - An error is produced if the input image is broken. This commonly happens if
+ the input image has an invalid EXIF Orientation value of zero. Even though
+ only nine different values from 1 to 9 are permitted, Anroid phones and
+ Canon DSLR cameras produce JPEG images with the invalid value of zero.
+ Either fix your input images with `exiftool` or similar software before
+ passing the JPEG to `img2pdf` or run `img2pdf` with `--rotation=ifvalid`.
- img2pdf uses PIL (or Pillow) to obtain image meta data and to convert the
input if necessary. To prevent decompression bomb denial of service attacks,
@@ -170,26 +172,26 @@ Description: [![Travis Status](https://travis-ci.org/josch/img2pdf.svg?branch=ma
# convert all files ending in .jpg inside a directory
dirname = "/path/to/images"
+ imgs = []
+ for fname in os.listdir(dirname):
+ if not fname.endswith(".jpg"):
+ continue
+ path = os.path.join(dirname, fname)
+ if os.path.isdir(path):
+ continue
+ imgs.append(path)
with open("name.pdf","wb") as f:
- imgs = []
- for fname in os.listdir(dirname):
- if not fname.endswith(".jpg"):
- continue
- path = os.path.join(dirname, fname)
- if os.path.isdir(path):
- continue
- imgs.append(path)
f.write(img2pdf.convert(imgs))
# convert all files ending in .jpg in a directory and its subdirectories
dirname = "/path/to/images"
+ imgs = []
+ for r, _, f in os.walk(dirname):
+ for fname in f:
+ if not fname.endswith(".jpg"):
+ continue
+ imgs.append(os.path.join(r, fname))
with open("name.pdf","wb") as f:
- imgs = []
- for r, _, f in os.walk(dirname):
- for fname in f:
- if not fname.endswith(".jpg"):
- continue
- imgs.append(os.path.join(r, fname))
f.write(img2pdf.convert(imgs))
@@ -208,6 +210,16 @@ Description: [![Travis Status](https://travis-ci.org/josch/img2pdf.svg?branch=ma
with open("name.pdf","wb") as f:
f.write(img2pdf.convert('test.jpg', layout_fun=layout_fun))
+ # use a fixed dpi of 300 instead of reading it from the image
+ dpix = dpiy = 300
+ layout_fun = img2pdf.get_fixed_dpi_layout_fun((dpix, dpiy))
+ with open("name.pdf","wb") as f:
+ f.write(img2pdf.convert('test.jpg', layout_fun=layout_fun))
+
+ # create a PDF/A-1b compliant document by passing an ICC profile
+ with open("name.pdf","wb") as f:
+ f.write(img2pdf.convert('test.jpg', pdfa="/usr/share/color/icc/sRGB.icc"))
+
Comparison to ImageMagick
-------------------------
@@ -295,7 +307,6 @@ Description: [![Travis Status](https://travis-ci.org/josch/img2pdf.svg?branch=ma
input to RGB and removes the alpha channel from images with transparency. For
multipage TIFF or animated GIF, it will only convert the first frame.
-
Keywords: jpeg pdf converter
Platform: UNKNOWN
Classifier: Development Status :: 5 - Production/Stable
diff --git a/src/img2pdf.egg-info/SOURCES.txt b/src/img2pdf.egg-info/SOURCES.txt
index b58fe4a..4d8a27e 100644
--- a/src/img2pdf.egg-info/SOURCES.txt
+++ b/src/img2pdf.egg-info/SOURCES.txt
@@ -2,10 +2,7 @@ CHANGES.rst
LICENSE
MANIFEST.in
README.md
-magick.py
-setup.cfg
setup.py
-test.sh
test_comp.sh
src/img2pdf.py
src/img2pdf_test.py
diff --git a/src/img2pdf.py b/src/img2pdf.py
index 78d7639..d6bb54f 100755
--- a/src/img2pdf.py
+++ b/src/img2pdf.py
@@ -1,7 +1,7 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
-# Copyright (C) 2012-2014 Johannes 'josch' Schauer <j.schauer at email.de>
+# Copyright (C) 2012-2021 Johannes Schauer Marin Rodrigues <josch@mister-muffin.de>
#
# This program is free software: you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -34,6 +34,9 @@ import logging
import struct
import platform
import hashlib
+from itertools import chain
+
+logger = logging.getLogger(__name__)
have_pdfrw = True
try:
@@ -47,7 +50,7 @@ try:
except ImportError:
have_pikepdf = False
-__version__ = "0.4.0"
+__version__ = "0.4.2"
default_dpi = 96.0
papersizes = {
"letter": "8.5inx11in",
@@ -76,13 +79,15 @@ papernames = {
Engine = Enum("Engine", "internal pdfrw pikepdf")
+Rotation = Enum("Rotation", "auto none ifvalid 0 90 180 270")
+
FitMode = Enum("FitMode", "into fill exact shrink enlarge")
PageOrientation = Enum("PageOrientation", "portrait landscape")
-Colorspace = Enum("Colorspace", "RGB L 1 CMYK CMYK;I RGBA P other")
+Colorspace = Enum("Colorspace", "RGB RGBA L LA 1 CMYK CMYK;I P PA other")
-ImageFormat = Enum("ImageFormat", "JPEG JPEG2000 CCITTGroup4 PNG TIFF other")
+ImageFormat = Enum("ImageFormat", "JPEG JPEG2000 CCITTGroup4 PNG GIF TIFF MPO other")
PageMode = Enum("PageMode", "none outlines thumbs")
@@ -737,6 +742,7 @@ class pdfdoc(object):
imgheightpx,
imgformat,
imgdata,
+ smaskdata,
imgwidthpdf,
imgheightpdf,
imgxpdf,
@@ -754,6 +760,10 @@ class pdfdoc(object):
artborder=None,
iccp=None,
):
+ assert (color != Colorspace.RGBA and color != Colorspace.LA) or (
+ imgformat == ImageFormat.PNG and smaskdata is not None
+ )
+
if self.engine == Engine.pikepdf:
PdfArray = pikepdf.Array
PdfDict = pikepdf.Dictionary
@@ -772,9 +782,9 @@ class pdfdoc(object):
TrueObject = True if self.engine == Engine.pikepdf else PdfObject("true")
FalseObject = False if self.engine == Engine.pikepdf else PdfObject("false")
- if color == Colorspace["1"] or color == Colorspace.L:
+ if color == Colorspace["1"] or color == Colorspace.L or color == Colorspace.LA:
colorspace = PdfName.DeviceGray
- elif color == Colorspace.RGB:
+ elif color == Colorspace.RGB or color == Colorspace.RGBA:
colorspace = PdfName.DeviceRGB
elif color == Colorspace.CMYK or color == Colorspace["CMYK;I"]:
colorspace = PdfName.DeviceCMYK
@@ -811,9 +821,13 @@ class pdfdoc(object):
else:
iccpdict = PdfDict(stream=convert_load(iccp))
iccpdict[PdfName.Alternate] = colorspace
- if color == Colorspace["1"] or color == Colorspace.L:
+ if (
+ color == Colorspace["1"]
+ or color == Colorspace.L
+ or color == Colorspace.LA
+ ):
iccpdict[PdfName.N] = 1
- elif color == Colorspace.RGB:
+ elif color == Colorspace.RGB or color == Colorspace.RGBA:
iccpdict[PdfName.N] = 3
elif color == Colorspace.CMYK or color == Colorspace["CMYK;I"]:
iccpdict[PdfName.N] = 4
@@ -845,6 +859,8 @@ class pdfdoc(object):
image[PdfName.ColorSpace] = colorspace
image[PdfName.BitsPerComponent] = depth
+ smask = None
+
if color == Colorspace["CMYK;I"]:
# Inverts all four channels
image[PdfName.Decode] = [1, 0, 1, 0, 1, 0, 1, 0]
@@ -862,9 +878,35 @@ class pdfdoc(object):
decodeparms[PdfName.Rows] = imgheightpx
image[PdfName.DecodeParms] = [decodeparms]
elif imgformat is ImageFormat.PNG:
+ if smaskdata is not None:
+ if self.engine == Engine.pikepdf:
+ smask = self.writer.make_stream(smaskdata)
+ else:
+ smask = PdfDict(stream=convert_load(smaskdata))
+ smask[PdfName.Type] = PdfName.XObject
+ smask[PdfName.Subtype] = PdfName.Image
+ smask[PdfName.Filter] = PdfName.FlateDecode
+ smask[PdfName.Width] = imgwidthpx
+ smask[PdfName.Height] = imgheightpx
+ smask[PdfName.ColorSpace] = PdfName.DeviceGray
+ smask[PdfName.BitsPerComponent] = depth
+
+ decodeparms = PdfDict()
+ decodeparms[PdfName.Predictor] = 15
+ decodeparms[PdfName.Colors] = 1
+ decodeparms[PdfName.Columns] = imgwidthpx
+ decodeparms[PdfName.BitsPerComponent] = depth
+ smask[PdfName.DecodeParms] = decodeparms
+
+ image[PdfName.SMask] = smask
+
+ # /SMask requires PDF 1.4
+ if self.output_version < "1.4":
+ self.output_version = "1.4"
+
decodeparms = PdfDict()
decodeparms[PdfName.Predictor] = 15
- if color in [Colorspace.P, Colorspace["1"], Colorspace.L]:
+ if color in [Colorspace.P, Colorspace["1"], Colorspace.L, Colorspace.LA]:
decodeparms[PdfName.Colors] = 1
else:
decodeparms[PdfName.Colors] = 3
@@ -898,8 +940,8 @@ class pdfdoc(object):
page[PdfName.CropBox] = [
cropborder[1],
cropborder[0],
- pagewidth - 2 * cropborder[1],
- pageheight - 2 * cropborder[0],
+ pagewidth - cropborder[1],
+ pageheight - cropborder[0],
]
if bleedborder is None:
if PdfName.CropBox in page:
@@ -908,8 +950,8 @@ class pdfdoc(object):
page[PdfName.BleedBox] = [
bleedborder[1],
bleedborder[0],
- pagewidth - 2 * bleedborder[1],
- pageheight - 2 * bleedborder[0],
+ pagewidth - bleedborder[1],
+ pageheight - bleedborder[0],
]
if trimborder is None:
if PdfName.CropBox in page:
@@ -918,8 +960,8 @@ class pdfdoc(object):
page[PdfName.TrimBox] = [
trimborder[1],
trimborder[0],
- pagewidth - 2 * trimborder[1],
- pageheight - 2 * trimborder[0],
+ pagewidth - trimborder[1],
+ pageheight - trimborder[0],
]
if artborder is None:
if PdfName.CropBox in page:
@@ -928,8 +970,8 @@ class pdfdoc(object):
page[PdfName.ArtBox] = [
artborder[1],
artborder[0],
- pagewidth - 2 * artborder[1],
- pageheight - 2 * artborder[0],
+ pagewidth - artborder[1],
+ pageheight - artborder[0],
]
page[PdfName.Resources] = resources
page[PdfName.Contents] = content
@@ -947,6 +989,8 @@ class pdfdoc(object):
if self.engine == Engine.internal:
self.writer.addobj(content)
self.writer.addobj(image)
+ if smask is not None:
+ self.writer.addobj(smask)
if iccp is not None:
self.writer.addobj(iccpdict)
@@ -1152,7 +1196,9 @@ class pdfdoc(object):
raise ValueError("unknown engine: %s" % self.engine)
-def get_imgmetadata(imgdata, imgformat, default_dpi, colorspace, rawdata=None):
+def get_imgmetadata(
+ imgdata, imgformat, default_dpi, colorspace, rawdata=None, rotreq=None
+):
if imgformat == ImageFormat.JPEG2000 and rawdata is not None and imgdata is None:
# this codepath gets called if the PIL installation is not able to
# handle JPEG2000 files
@@ -1175,15 +1221,22 @@ def get_imgmetadata(imgdata, imgformat, default_dpi, colorspace, rawdata=None):
ndpi = (int(round(ndpi[0])), int(round(ndpi[1])))
ics = imgdata.mode
- if ics in ["LA", "PA", "RGBA"] or "transparency" in imgdata.info:
- logging.warning("Image contains transparency which cannot be retained in PDF.")
- logging.warning("img2pdf will not perform a lossy operation.")
- logging.warning("You can remove the alpha channel using imagemagick:")
- logging.warning(
- " $ convert input.png -background white -alpha "
- "remove -alpha off output.png"
- )
- raise AlphaChannelError("Refusing to work on images with alpha channel")
+ # GIF and PNG files with transparency are supported
+ if (imgformat == ImageFormat.PNG or imgformat == ImageFormat.GIF) and (
+ ics in ["RGBA", "LA"] or "transparency" in imgdata.info
+ ):
+ # Must check the IHDR chunk for the bit depth, because PIL would lossily
+ # convert 16-bit RGBA/LA images to 8-bit.
+ if imgformat == ImageFormat.PNG and rawdata is not None:
+ depth = rawdata[24]
+ if depth > 8:
+ logger.warning("Image with transparency and a bit depth of %d." % depth)
+ logger.warning("This is unsupported due to PIL limitations.")
+ raise AlphaChannelError(
+ "Refusing to work with multiple >8bit channels."
+ )
+ elif ics in ["LA", "PA", "RGBA"] or "transparency" in imgdata.info:
+ raise AlphaChannelError("This function must not be called on images with alpha")
# Since commit 07a96209597c5e8dfe785c757d7051ce67a980fb or release 4.1.0
# Pillow retrieves the DPI from EXIF if it cannot find the DPI in the JPEG
@@ -1200,34 +1253,53 @@ def get_imgmetadata(imgdata, imgformat, default_dpi, colorspace, rawdata=None):
imgdata.tag_v2.get(TiffImagePlugin.Y_RESOLUTION, default_dpi),
)
- logging.debug("input dpi = %d x %d", *ndpi)
+ logger.debug("input dpi = %d x %d", *ndpi)
rotation = 0
- if hasattr(imgdata, "_getexif") and imgdata._getexif() is not None:
- for tag, value in imgdata._getexif().items():
- if TAGS.get(tag, tag) == "Orientation":
- # Detailed information on EXIF rotation tags:
- # http://impulseadventure.com/photo/exif-orientation.html
- if value == 1:
- rotation = 0
- elif value == 6:
- rotation = 90
- elif value == 3:
- rotation = 180
- elif value == 8:
- rotation = 270
- elif value in (2, 4, 5, 7):
- raise ExifOrientationError(
- "Unsupported flipped rotation mode (%d)" % value
- )
- else:
- raise ExifOrientationError("Invalid rotation (%d)" % value)
+ if rotreq in (None, Rotation.auto, Rotation.ifvalid):
+ if hasattr(imgdata, "_getexif") and imgdata._getexif() is not None:
+ for tag, value in imgdata._getexif().items():
+ if TAGS.get(tag, tag) == "Orientation":
+ # Detailed information on EXIF rotation tags:
+ # http://impulseadventure.com/photo/exif-orientation.html
+ if value == 1:
+ rotation = 0
+ elif value == 6:
+ rotation = 90
+ elif value == 3:
+ rotation = 180
+ elif value == 8:
+ rotation = 270
+ elif value in (2, 4, 5, 7):
+ if rotreq == Rotation.ifvalid:
+ logger.warning(
+ "Unsupported flipped rotation mode (%d)", value
+ )
+ else:
+ raise ExifOrientationError(
+ "Unsupported flipped rotation mode (%d)" % value
+ )
+ else:
+ if rotreq == Rotation.ifvalid:
+ logger.warning("Invalid rotation (%d)", value)
+ else:
+ raise ExifOrientationError("Invalid rotation (%d)" % value)
+ elif rotreq in (Rotation.none, Rotation["0"]):
+ rotation = 0
+ elif rotreq == Rotation["90"]:
+ rotation = 90
+ elif rotreq == Rotation["180"]:
+ rotation = 180
+ elif rotreq == Rotation["270"]:
+ rotation = 270
+ else:
+ raise Exception("invalid rotreq")
- logging.debug("rotation = %d°", rotation)
+ logger.debug("rotation = %d°", rotation)
if colorspace:
color = colorspace
- logging.debug("input colorspace (forced) = %s", color)
+ logger.debug("input colorspace (forced) = %s", color)
else:
color = None
for c in Colorspace:
@@ -1257,13 +1329,13 @@ def get_imgmetadata(imgdata, imgformat, default_dpi, colorspace, rawdata=None):
# with the first approach for now.
if "adobe" in imgdata.info:
color = Colorspace["CMYK;I"]
- logging.debug("input colorspace = %s", color.name)
+ logger.debug("input colorspace = %s", color.name)
iccp = None
if "icc_profile" in imgdata.info:
iccp = imgdata.info.get("icc_profile")
- logging.debug("width x height = %dpx x %dpx", imgwidthpx, imgheightpx)
+ logger.debug("width x height = %dpx x %dpx", imgwidthpx, imgheightpx)
return (color, ndpi, imgwidthpx, imgheightpx, rotation, iccp)
@@ -1280,19 +1352,20 @@ def ccitt_payload_location_from_pil(img):
# Read the TIFF tags to find the offset(s) of the compressed data strips.
strip_offsets = img.tag_v2[TiffImagePlugin.STRIPOFFSETS]
strip_bytes = img.tag_v2[TiffImagePlugin.STRIPBYTECOUNTS]
- rows_per_strip = img.tag_v2.get(TiffImagePlugin.ROWSPERSTRIP, 2 ** 32 - 1)
# PIL always seems to create a single strip even for very large TIFFs when
# it saves images, so assume we only have to read a single strip.
# A test ~10 GPixel image was still encoded as a single strip. Just to be
# safe check throw an error if there is more than one offset.
if len(strip_offsets) != 1 or len(strip_bytes) != 1:
- raise NotImplementedError("Transcoding multiple strips not supported")
+ raise NotImplementedError(
+ "Transcoding multiple strips not supported by the PDF format"
+ )
(offset,), (length,) = strip_offsets, strip_bytes
- logging.debug("TIFF strip_offsets: %d" % offset)
- logging.debug("TIFF strip_bytes: %d" % length)
+ logger.debug("TIFF strip_offsets: %d" % offset)
+ logger.debug("TIFF strip_bytes: %d" % length)
return offset, length
@@ -1300,7 +1373,7 @@ def ccitt_payload_location_from_pil(img):
def transcode_monochrome(imgdata):
"""Convert the open PIL.Image imgdata to compressed CCITT Group4 data"""
- logging.debug("Converting monochrome to CCITT Group4")
+ logger.debug("Converting monochrome to CCITT Group4")
# Convert the image to Group 4 in memory. If libtiff is not installed and
# Pillow is not compiled against it, .save() will raise an exception.
@@ -1311,7 +1384,33 @@ def transcode_monochrome(imgdata):
# killed by a SIGABRT:
# https://gitlab.mister-muffin.de/josch/img2pdf/issues/46
im = Image.frombytes(imgdata.mode, imgdata.size, imgdata.tobytes())
- im.save(newimgio, format="TIFF", compression="group4")
+
+ # Since version 8.3.0 Pillow limits strips to 64 KB. Since PDF only
+ # supports single strip CCITT Group4 payloads, we have to coerce it back
+ # into putting everything into a single strip. Thanks to Andrew Murray for
+ # the hack.
+ #
+ # This can be dropped once this gets merged:
+ # https://github.com/python-pillow/Pillow/pull/5744
+ pillow__getitem__ = TiffImagePlugin.ImageFileDirectory_v2.__getitem__
+
+ def __getitem__(self, tag):
+ overrides = {
+ TiffImagePlugin.ROWSPERSTRIP: imgdata.size[1],
+ TiffImagePlugin.STRIPBYTECOUNTS: [
+ (imgdata.size[0] + 7) // 8 * imgdata.size[1]
+ ],
+ TiffImagePlugin.STRIPOFFSETS: [0],
+ }
+ return overrides.get(tag, pillow__getitem__(self, tag))
+
+ # use try/finally to make sure that __getitem__ is reset even if save()
+ # raises an exception
+ try:
+ TiffImagePlugin.ImageFileDirectory_v2.__getitem__ = __getitem__
+ im.save(newimgio, format="TIFF", compression="group4")
+ finally:
+ TiffImagePlugin.ImageFileDirectory_v2.__getitem__ = pillow__getitem__
# Open new image in memory
newimgio.seek(0)
@@ -1341,7 +1440,7 @@ def parse_png(rawdata):
return pngidat, palette
-def read_images(rawdata, colorspace, first_frame_only=False):
+def read_images(rawdata, colorspace, first_frame_only=False, rot=None):
im = BytesIO(rawdata)
im.seek(0)
imgdata = None
@@ -1357,6 +1456,7 @@ def read_images(rawdata, colorspace, first_frame_only=False):
# image is jpeg2000
imgformat = ImageFormat.JPEG2000
else:
+ logger.debug("PIL format = %s", imgdata.format)
imgformat = None
for f in ImageFormat:
if f.name == imgdata.format:
@@ -1364,7 +1464,17 @@ def read_images(rawdata, colorspace, first_frame_only=False):
if imgformat is None:
imgformat = ImageFormat.other
- logging.debug("imgformat = %s", imgformat.name)
+ def cleanup():
+ if imgdata is not None:
+ # the python-pil version 2.3.0-1ubuntu3 in Ubuntu does not have the
+ # close() method
+ try:
+ imgdata.close()
+ except AttributeError:
+ pass
+ im.close()
+
+ logger.debug("imgformat = %s", imgformat.name)
# depending on the input format, determine whether to pass the raw
# image or the zlib compressed color information
@@ -1372,7 +1482,7 @@ def read_images(rawdata, colorspace, first_frame_only=False):
# JPEG and JPEG2000 can be embedded into the PDF as-is
if imgformat == ImageFormat.JPEG or imgformat == ImageFormat.JPEG2000:
color, ndpi, imgwidthpx, imgheightpx, rotation, iccp = get_imgmetadata(
- imgdata, imgformat, default_dpi, colorspace, rawdata
+ imgdata, imgformat, default_dpi, colorspace, rawdata, rot
)
if color == Colorspace["1"]:
raise JpegColorspaceError("jpeg can't be monochrome")
@@ -1380,14 +1490,15 @@ def read_images(rawdata, colorspace, first_frame_only=False):
raise JpegColorspaceError("jpeg can't have a color palette")
if color == Colorspace["RGBA"]:
raise JpegColorspaceError("jpeg can't have an alpha channel")
- im.close()
- logging.debug("read_images() embeds a JPEG")
+ logger.debug("read_images() embeds a JPEG")
+ cleanup()
return [
(
color,
ndpi,
imgformat,
rawdata,
+ None,
imgwidthpx,
imgheightpx,
[],
@@ -1398,6 +1509,66 @@ def read_images(rawdata, colorspace, first_frame_only=False):
)
]
+ # The MPO format is multiple JPEG images concatenated together
+ # we use the offset and size information to dissect the MPO into its
+ # individual JPEG images and then embed those into the PDF individually.
+ #
+ # The downside is, that this truncates the first JPEG as the MPO metadata
+ # will still be in it but the referenced images are chopped off. We still
+ # do it that way instead of adding the full MPO as the first image to not
+ # store duplicate image data.
+ if imgformat == ImageFormat.MPO:
+ result = []
+ img_page_count = 0
+ for offset, mpent in zip(
+ imgdata._MpoImageFile__mpoffsets, imgdata.mpinfo[0xB002]
+ ):
+ if first_frame_only and img_page_count > 0:
+ break
+ with BytesIO(rawdata[offset : offset + mpent["Size"]]) as rawframe:
+ with Image.open(rawframe) as imframe:
+ # The first frame contains the data that makes the JPEG a MPO
+ # Could we thus embed an MPO into another MPO? Lets not support
+ # such madness ;)
+ if img_page_count > 0 and imframe.format != "JPEG":
+ raise Exception("MPO payload must be a JPEG %s", imframe.format)
+ (
+ color,
+ ndpi,
+ imgwidthpx,
+ imgheightpx,
+ rotation,
+ iccp,
+ ) = get_imgmetadata(
+ imframe, ImageFormat.JPEG, default_dpi, colorspace, rotreq=rot
+ )
+ if color == Colorspace["1"]:
+ raise JpegColorspaceError("jpeg can't be monochrome")
+ if color == Colorspace["P"]:
+ raise JpegColorspaceError("jpeg can't have a color palette")
+ if color == Colorspace["RGBA"]:
+ raise JpegColorspaceError("jpeg can't have an alpha channel")
+ logger.debug("read_images() embeds a JPEG from MPO")
+ result.append(
+ (
+ color,
+ ndpi,
+ ImageFormat.JPEG,
+ rawdata[offset : offset + mpent["Size"]],
+ None,
+ imgwidthpx,
+ imgheightpx,
+ [],
+ False,
+ 8,
+ rotation,
+ iccp,
+ )
+ )
+ img_page_count += 1
+ cleanup()
+ return result
+
# We can directly embed the IDAT chunk of PNG images if the PNG is not
# interlaced
#
@@ -1407,33 +1578,44 @@ def read_images(rawdata, colorspace, first_frame_only=False):
# must be the first chunk.
if imgformat == ImageFormat.PNG and rawdata[28] == 0:
color, ndpi, imgwidthpx, imgheightpx, rotation, iccp = get_imgmetadata(
- imgdata, imgformat, default_dpi, colorspace, rawdata
+ imgdata, imgformat, default_dpi, colorspace, rawdata, rot
)
- pngidat, palette = parse_png(rawdata)
- im.close()
- # PIL does not provide the information about the original bits per
- # sample. Thus, we retrieve that info manually by looking at byte 9 in
- # the IHDR chunk. We know where to find that in the file because the
- # IHDR chunk must be the first chunk
- depth = rawdata[24]
- if depth not in [1, 2, 4, 8, 16]:
- raise ValueError("invalid bit depth: %d" % depth)
- logging.debug("read_images() embeds a PNG")
- return [
- (
- color,
- ndpi,
- imgformat,
- pngidat,
- imgwidthpx,
- imgheightpx,
- palette,
- False,
- depth,
- rotation,
- iccp,
- )
- ]
+ if (
+ color != Colorspace.RGBA
+ and color != Colorspace.LA
+ and color != Colorspace.PA
+ and "transparency" not in imgdata.info
+ ):
+ pngidat, palette = parse_png(rawdata)
+ # PIL does not provide the information about the original bits per
+ # sample. Thus, we retrieve that info manually by looking at byte 9 in
+ # the IHDR chunk. We know where to find that in the file because the
+ # IHDR chunk must be the first chunk
+ depth = rawdata[24]
+ if depth not in [1, 2, 4, 8, 16]:
+ raise ValueError("invalid bit depth: %d" % depth)
+ # we embed the PNG only if it is not at the same time palette based
+ # and has an icc profile because PDF doesn't support icc profiles
+ # on palette images
+ if palette == b"" or iccp is None:
+ logger.debug("read_images() embeds a PNG")
+ cleanup()
+ return [
+ (
+ color,
+ ndpi,
+ imgformat,
+ pngidat,
+ None,
+ imgwidthpx,
+ imgheightpx,
+ palette,
+ False,
+ depth,
+ rotation,
+ iccp,
+ )
+ ]
# If our input is not JPEG or PNG, then we might have a format that
# supports multiple frames (like TIFF or GIF), so we need a loop to
@@ -1478,6 +1660,7 @@ def read_images(rawdata, colorspace, first_frame_only=False):
imgformat == ImageFormat.TIFF
and imgdata.info["compression"] == "group4"
and len(imgdata.tag_v2[TiffImagePlugin.STRIPOFFSETS]) == 1
+ and len(imgdata.tag_v2[TiffImagePlugin.STRIPBYTECOUNTS]) == 1
):
photo = imgdata.tag_v2[TiffImagePlugin.PHOTOMETRIC_INTERPRETATION]
inverted = False
@@ -1489,7 +1672,7 @@ def read_images(rawdata, colorspace, first_frame_only=False):
"group4 tiff: %d" % photo
)
color, ndpi, imgwidthpx, imgheightpx, rotation, iccp = get_imgmetadata(
- imgdata, imgformat, default_dpi, colorspace, rawdata
+ imgdata, imgformat, default_dpi, colorspace, rawdata, rot
)
offset, length = ccitt_payload_location_from_pil(imgdata)
im.seek(offset)
@@ -1502,7 +1685,7 @@ def read_images(rawdata, colorspace, first_frame_only=False):
# msb-to-lsb: nothing to do
pass
elif fillorder == 2:
- logging.debug("fillorder is lsb-to-msb => reverse bits")
+ logger.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)):
@@ -1510,13 +1693,14 @@ def read_images(rawdata, colorspace, first_frame_only=False):
rawdata = bytes(rawdata)
else:
raise ValueError("unsupported FillOrder: %d" % fillorder)
- logging.debug("read_images() embeds Group4 from TIFF")
+ logger.debug("read_images() embeds Group4 from TIFF")
result.append(
(
color,
ndpi,
ImageFormat.CCITTGroup4,
rawdata,
+ None,
imgwidthpx,
imgheightpx,
[],
@@ -1529,23 +1713,24 @@ def read_images(rawdata, colorspace, first_frame_only=False):
img_page_count += 1
continue
- logging.debug("Converting frame: %d" % img_page_count)
+ logger.debug("Converting frame: %d" % img_page_count)
color, ndpi, imgwidthpx, imgheightpx, rotation, iccp = get_imgmetadata(
- imgdata, imgformat, default_dpi, colorspace
+ imgdata, imgformat, default_dpi, colorspace, rotreq=rot
)
newimg = None
if color == Colorspace["1"]:
try:
ccittdata = transcode_monochrome(imgdata)
- logging.debug("read_images() encoded a B/W image as CCITT group 4")
+ logger.debug("read_images() encoded a B/W image as CCITT group 4")
result.append(
(
color,
ndpi,
ImageFormat.CCITTGroup4,
ccittdata,
+ None,
imgwidthpx,
imgheightpx,
[],
@@ -1558,18 +1743,20 @@ def read_images(rawdata, colorspace, first_frame_only=False):
img_page_count += 1
continue
except Exception as e:
- logging.debug(e)
- logging.debug("Converting colorspace 1 to L")
+ logger.debug(e)
+ logger.debug("Converting colorspace 1 to L")
newimg = imgdata.convert("L")
color = Colorspace.L
elif color in [
Colorspace.RGB,
+ Colorspace.RGBA,
Colorspace.L,
+ Colorspace.LA,
Colorspace.CMYK,
Colorspace["CMYK;I"],
Colorspace.P,
]:
- logging.debug("Colorspace is OK: %s", color)
+ logger.debug("Colorspace is OK: %s", color)
newimg = imgdata
else:
raise ValueError("unknown or unsupported colorspace: %s" % color.name)
@@ -1577,13 +1764,14 @@ def read_images(rawdata, colorspace, first_frame_only=False):
# compression
if color in [Colorspace.CMYK, Colorspace["CMYK;I"]]:
imggz = zlib.compress(newimg.tobytes())
- logging.debug("read_images() encoded CMYK with flate compression")
+ logger.debug("read_images() encoded CMYK with flate compression")
result.append(
(
color,
ndpi,
imgformat,
imggz,
+ None,
imgwidthpx,
imgheightpx,
[],
@@ -1594,27 +1782,52 @@ def read_images(rawdata, colorspace, first_frame_only=False):
)
)
else:
- # cheapo version to retrieve a PNG encoding of the payload is to
- # just save it with PIL. In the future this could be replaced by
- # dedicated function applying the Paeth PNG filter to the raw pixel
- pngbuffer = BytesIO()
- newimg.save(pngbuffer, format="png")
- pngidat, palette = parse_png(pngbuffer.getvalue())
- # PIL does not provide the information about the original bits per
- # sample. Thus, we retrieve that info manually by looking at byte 9 in
- # the IHDR chunk. We know where to find that in the file because the
- # IHDR chunk must be the first chunk
- pngbuffer.seek(24)
- depth = ord(pngbuffer.read(1))
- if depth not in [1, 2, 4, 8, 16]:
- raise ValueError("invalid bit depth: %d" % depth)
- logging.debug("read_images() encoded an image as PNG")
+ if (
+ color == Colorspace.RGBA
+ or color == Colorspace.LA
+ or color == Colorspace.PA
+ or "transparency" in newimg.info
+ ):
+ if color == Colorspace.RGBA:
+ newcolor = color
+ r, g, b, a = newimg.split()
+ newimg = Image.merge("RGB", (r, g, b))
+ elif color == Colorspace.LA:
+ newcolor = color
+ l, a = newimg.split()
+ newimg = l
+ else:
+ newcolor = Colorspace.RGBA
+ r, g, b, a = newimg.convert(mode="RGBA").split()
+ newimg = Image.merge("RGB", (r, g, b))
+
+ smaskidat, _, _ = to_png_data(a)
+ logger.warning(
+ "Image contains an alpha channel which will be stored "
+ "as a separate soft mask (/SMask) image in PDF."
+ )
+ elif color in [Colorspace.P, Colorspace.PA] and iccp is not None:
+ # PDF does not support palette images with icc profile
+ if color == Colorspace.P:
+ newcolor = Colorspace.RGB
+ newimg = newimg.convert(mode="RGB")
+ elif color == Colorspace.PA:
+ newcolor = Colorspace.RGBA
+ newimg = newimg.convert(mode="RGBA")
+ smaskidat = None
+ else:
+ newcolor = color
+ smaskidat = None
+
+ pngidat, palette, depth = to_png_data(newimg)
+ logger.debug("read_images() encoded an image as PNG")
result.append(
(
- color,
+ newcolor,
ndpi,
ImageFormat.PNG,
pngidat,
+ smaskidat,
imgwidthpx,
imgheightpx,
palette,
@@ -1625,16 +1838,29 @@ def read_images(rawdata, colorspace, first_frame_only=False):
)
)
img_page_count += 1
- # the python-pil version 2.3.0-1ubuntu3 in Ubuntu does not have the
- # close() method
- try:
- imgdata.close()
- except AttributeError:
- pass
- im.close()
+ cleanup()
return result
+def to_png_data(img):
+ # cheapo version to retrieve a PNG encoding of the payload is to
+ # just save it with PIL. In the future this could be replaced by
+ # dedicated function applying the Paeth PNG filter to the raw pixel
+ pngbuffer = BytesIO()
+ img.save(pngbuffer, format="png")
+
+ pngidat, palette = parse_png(pngbuffer.getvalue())
+ # PIL does not provide the information about the original bits per
+ # sample. Thus, we retrieve that info manually by looking at byte 9 in
+ # the IHDR chunk. We know where to find that in the file because the
+ # IHDR chunk must be the first chunk
+ pngbuffer.seek(24)
+ depth = ord(pngbuffer.read(1))
+ if depth not in [1, 2, 4, 8, 16]:
+ raise ValueError("invalid bit depth: %d" % depth)
+ return pngidat, palette, depth
+
+
# converts a length in pixels to a length in PDF units (1/72 of an inch)
def px_to_pt(length, dpi):
return 72.0 * length / dpi
@@ -1955,6 +2181,7 @@ def convert(*images, **kwargs):
trimborder=None,
artborder=None,
pdfa=None,
+ rotation=None,
)
for kwname, default in _default_kwargs.items():
if kwname not in kwargs:
@@ -1991,6 +2218,9 @@ def convert(*images, **kwargs):
if not isinstance(images, (list, tuple)):
images = [images]
+ else:
+ if len(images) == 0:
+ raise ValueError("Unable to process empty list")
for img in images:
# img is allowed to be a path, a binary string representing image data
@@ -2022,6 +2252,7 @@ def convert(*images, **kwargs):
ndpi,
imgformat,
imgdata,
+ smaskdata,
imgwidthpx,
imgheightpx,
palette,
@@ -2029,14 +2260,19 @@ def convert(*images, **kwargs):
depth,
rotation,
iccp,
- ) in read_images(rawdata, kwargs["colorspace"], kwargs["first_frame_only"]):
+ ) in read_images(
+ rawdata,
+ kwargs["colorspace"],
+ kwargs["first_frame_only"],
+ kwargs["rotation"],
+ ):
pagewidth, pageheight, imgwidthpdf, imgheightpdf = kwargs["layout_fun"](
imgwidthpx, imgheightpx, ndpi
)
userunit = None
if pagewidth < 3.00 or pageheight < 3.00:
- logging.warning(
+ logger.warning(
"pdf width or height is below 3.00 - too small for some viewers!"
)
elif pagewidth > 14400.0 or pageheight > 14400.0:
@@ -2050,6 +2286,17 @@ def convert(*images, **kwargs):
raise PdfTooLargeError(
"pdf width or height must not exceed 200 inches."
)
+ for border in ["crop", "bleed", "trim", "art"]:
+ if kwargs[border + "border"] is None:
+ continue
+ if pagewidth < 2 * kwargs[border + "border"][1]:
+ raise ValueError(
+ "horizontal %s border larger than page width" % border
+ )
+ if pageheight < 2 * kwargs[border + "border"][0]:
+ raise ValueError(
+ "vertical %s border larger than page height" % border
+ )
# the image is always centered on the page
imgxpdf = (pagewidth - imgwidthpdf) / 2.0
imgypdf = (pageheight - imgheightpdf) / 2.0
@@ -2059,6 +2306,7 @@ def convert(*images, **kwargs):
imgheightpx,
imgformat,
imgdata,
+ smaskdata,
imgwidthpdf,
imgheightpdf,
imgxpdf,
@@ -2262,16 +2510,17 @@ def parse_borderarg(string):
return h, v
-def input_images(path):
+def from_file(path):
+ result = []
if path == "-":
- # we slurp in all data from stdin because we need to seek in it later
- result = sys.stdin.buffer.read()
- if len(result) == 0:
- raise argparse.ArgumentTypeError('"%s" is empty' % path)
+ content = sys.stdin.buffer.read()
else:
+ with open(path, "rb") as f:
+ content = f.read()
+ for path in content.split(b"\0"):
+ if path == b"":
+ continue
try:
- if os.path.getsize(path) == 0:
- raise argparse.ArgumentTypeError('"%s" is empty' % path)
# test-read a byte from it so that we can abort early in case
# we cannot read data from the file
with open(path, "rb") as im:
@@ -2282,10 +2531,51 @@ def input_images(path):
raise argparse.ArgumentTypeError('"%s" permission denied' % path)
except FileNotFoundError:
raise argparse.ArgumentTypeError('"%s" does not exist' % path)
- result = path
+ result.append(path)
return result
+def input_images(path_expr):
+ if path_expr == "-":
+ # we slurp in all data from stdin because we need to seek in it later
+ result = [sys.stdin.buffer.read()]
+ if len(result) == 0:
+ raise argparse.ArgumentTypeError('"%s" is empty' % path_expr)
+ else:
+ result = []
+ paths = [path_expr]
+ if sys.platform == "win32" and ("*" in path_expr or "?" in path_expr):
+ # on windows, program is responsible for expanding wildcards such as *.jpg
+ # glob won't return files that don't exist so we only use it for wildcards
+ # paths without wildcards that do not exist will trigger "does not exist"
+ from glob import glob
+
+ paths = sorted(glob(path_expr))
+ for path in paths:
+ try:
+ if os.path.getsize(path) == 0:
+ raise argparse.ArgumentTypeError('"%s" is empty' % path)
+ # test-read a byte from it so that we can abort early in case
+ # we cannot read data from the file
+ with open(path, "rb") as im:
+ im.read(1)
+ except IsADirectoryError:
+ raise argparse.ArgumentTypeError('"%s" is a directory' % path)
+ except PermissionError:
+ raise argparse.ArgumentTypeError('"%s" permission denied' % path)
+ except FileNotFoundError:
+ raise argparse.ArgumentTypeError('"%s" does not exist' % path)
+ result.append(path)
+ return result
+
+
+def parse_rotationarg(string):
+ for m in Rotation:
+ if m.name == string.lower():
+ return m
+ raise argparse.ArgumentTypeError("unknown rotation value: %s" % string)
+
+
def parse_fitarg(string):
for m in FitMode:
if m.name == string.lower():
@@ -2497,7 +2787,6 @@ def gui():
args = {
"engine": tkinter.StringVar(),
- "first_frame_only": tkinter.BooleanVar(),
"auto_orient": tkinter.BooleanVar(),
"fit": tkinter.StringVar(),
"title": tkinter.StringVar(),
@@ -3078,9 +3367,9 @@ Losslessly convert raster images to PDF without re-encoding PNG, JPEG, and
JPEG2000 images. This leads to a lossless conversion of PNG, JPEG and JPEG2000
images with the only added file size coming from the PDF container itself.
Other raster graphics formats are losslessly stored using the same encoding
-that PNG uses. Since PDF does not support images with transparency and since
-img2pdf aims to never be lossy, input images with an alpha channel are not
-supported.
+that PNG uses.
+For images with transparency, the alpha channel will be stored as a separate
+soft mask. This is lossless, too.
The output is sent to standard output so that it can be redirected into a file
or to another program as part of a shell pipe. To directly write the output
@@ -3208,8 +3497,10 @@ Report bugs at https://gitlab.mister-muffin.de/josch/img2pdf/issues
"the Python Imaging Library (PIL). If no input images are given, then "
'a single image is read from standard input. The special filename "-" '
"can be used once to read an image from standard input. To read a "
- 'file in the current directory with the filename "-", pass it to '
- 'img2pdf by explicitly stating its relative path like "./-".',
+ 'file in the current directory with the filename "-" (or with a '
+ 'filename starting with "-"), pass it to img2pdf by explicitly '
+ 'stating its relative path like "./-". Cannot be used together with '
+ "--from-file.",
)
parser.add_argument(
"-v",
@@ -3228,6 +3519,19 @@ Report bugs at https://gitlab.mister-muffin.de/josch/img2pdf/issues
parser.add_argument(
"--gui", dest="gui", action="store_true", help="run experimental tkinter gui"
)
+ parser.add_argument(
+ "--from-file",
+ metavar="FILE",
+ type=from_file,
+ default=[],
+ help="Read the list of images from FILE instead of passing them as "
+ "positional arguments. If this option is used, then the list of "
+ "positional arguments must be empty. The paths to the input images "
+ 'in FILE are separated by NUL bytes. If FILE is "-" then the paths '
+ "are expected on standard input. This option is useful if you want "
+ "to pass more images than the maximum command length of your shell "
+ "permits. This option can be used with commands like `find -print0`.",
+ )
outargs = parser.add_argument_group(
title="General output arguments",
@@ -3310,7 +3614,7 @@ RGB.""",
nargs="?",
const="/usr/share/color/icc/sRGB.icc",
default=None,
- help="Output a PDF/A-1b complient document. By default, this will "
+ help="Output a PDF/A-1b compliant document. By default, this will "
"embed /usr/share/color/icc/sRGB.icc as the color profile.",
)
@@ -3430,6 +3734,24 @@ values set via the --border option.
""",
)
sizeargs.add_argument(
+ "-r",
+ "--rotation",
+ "--orientation",
+ metavar="ROT",
+ type=parse_rotationarg,
+ default=Rotation.auto,
+ help="""
+Specifies how input images should be rotated. ROT can be one of auto, none,
+ifvalid, 0, 90, 180 and 270. The default value is auto and indicates that input
+images are rotated according to their EXIF Orientation tag. The values none and
+0 ignore the EXIF Orientation values of the input images. The value ifvalid
+acts like auto but ignores invalid EXIF rotation values and only issues a
+warning instead of throwing an error. This is useful because many devices like
+Android phones, Canon cameras or scanners emit an invalid Orientation tag value
+of zero. The values 90, 180 and 270 perform a clockwise rotation of the image.
+ """,
+ )
+ sizeargs.add_argument(
"--crop-border",
metavar="L[:L]",
type=parse_borderarg,
@@ -3598,36 +3920,48 @@ and left/right, respectively. It is not possible to specify asymmetric borders.
args.pagesize, args.imgsize, args.border, args.fit, args.auto_orient
)
- # if no positional arguments were supplied, read a single image from
- # standard input
- if len(args.images) == 0:
- logging.info("reading image from standard input")
+ if len(args.images) > 0 and len(args.from_file) > 0:
+ logger.error(
+ "%s: error: cannot use --from-file with positional arguments" % parser.prog
+ )
+ sys.exit(2)
+ elif len(args.images) == 0 and len(args.from_file) == 0:
+ # if no positional arguments were supplied, read a single image from
+ # standard input
+ logger.info("reading image from standard input")
try:
- args.images = [sys.stdin.buffer.read()]
+ images = [sys.stdin.buffer.read()]
except KeyboardInterrupt:
- exit(0)
+ sys.exit(0)
+ elif len(args.images) > 0 and len(args.from_file) == 0:
+ # On windows, each positional argument can expand into multiple paths
+ # because we do globbing ourselves. Here we flatten the list of lists
+ # again.
+ images = chain.from_iterable(args.images)
+ elif len(args.images) == 0 and len(args.from_file) > 0:
+ images = args.from_file
# with the number of pages being equal to the number of images, the
# value passed to --viewer-initial-page must be between 1 and that number
if args.viewer_initial_page is not None:
if args.viewer_initial_page < 1:
parser.print_usage(file=sys.stderr)
- logging.error(
+ logger.error(
"%s: error: argument --viewer-initial-page: must be "
"greater than zero" % parser.prog
)
- exit(2)
- if args.viewer_initial_page > len(args.images):
+ sys.exit(2)
+ if args.viewer_initial_page > len(images):
parser.print_usage(file=sys.stderr)
- logging.error(
+ logger.error(
"%s: error: argument --viewer-initial-page: must be "
"less than or equal to the total number of pages" % parser.prog
)
- exit(2)
+ sys.exit(2)
try:
convert(
- *args.images,
+ *images,
engine=args.engine,
title=args.title,
author=args.author,
@@ -3654,14 +3988,15 @@ and left/right, respectively. It is not possible to specify asymmetric borders.
trimborder=args.trim_border,
artborder=args.art_border,
pdfa=args.pdfa,
+ rotation=args.rotation,
)
except Exception as e:
- logging.error("error: " + str(e))
- if logging.getLogger().isEnabledFor(logging.DEBUG):
+ logger.error("error: " + str(e))
+ if logger.isEnabledFor(logging.DEBUG):
import traceback
traceback.print_exc(file=sys.stderr)
- exit(1)
+ sys.exit(1)
if __name__ == "__main__":
diff --git a/src/img2pdf_test.py b/src/img2pdf_test.py
index 8877d25..8d4f2b5 100644..100755
--- a/src/img2pdf_test.py
+++ b/src/img2pdf_test.py
@@ -20,6 +20,21 @@ import warnings
import json
import pathlib
+ICC_PROFILE = None
+ICC_PROFILE_PATHS = (
+ # Debian
+ "/usr/share/color/icc/ghostscript/srgb.icc",
+ # Fedora
+ "/usr/share/ghostscript/iccprofiles/srgb.icc",
+ # Archlinux and Gentoo
+ "/usr/share/ghostscript/*/iccprofiles/srgb.icc",
+)
+for glob in ICC_PROFILE_PATHS:
+ for path in pathlib.Path("/").glob(glob.lstrip("/")):
+ if path.is_file():
+ ICC_PROFILE = path
+ break
+
HAVE_MUTOOL = True
try:
ver = subprocess.check_output(["mutool", "-v"], stderr=subprocess.STDOUT)
@@ -50,9 +65,16 @@ except FileNotFoundError:
if not HAVE_PDFIMAGES_CMYK:
warnings.warn("pdfimages >= 0.42.0 not available, skipping CMYK checks...")
+for prog in ["convert", "compare", "identify"]:
+ try:
+ subprocess.check_call([prog] + ["-version"], stderr=subprocess.STDOUT)
+ globals()[prog.upper()] = [prog]
+ except subprocess.CalledProcessError:
+ globals()[prog.upper()] = ["magick", prog]
+
HAVE_IMAGEMAGICK_MODERN = True
try:
- ver = subprocess.check_output(["convert", "-version"], stderr=subprocess.STDOUT)
+ ver = subprocess.check_output(CONVERT + ["-version"], stderr=subprocess.STDOUT)
m = re.fullmatch(
r"Version: ImageMagick ([0-9.]+-[0-9]+) .*", ver.split(b"\n")[0].decode("utf8")
)
@@ -72,7 +94,7 @@ if not HAVE_IMAGEMAGICK_MODERN:
HAVE_JP2 = True
try:
ver = subprocess.check_output(
- ["identify", "-list", "format"], stderr=subprocess.STDOUT
+ IDENTIFY + ["-list", "format"], stderr=subprocess.STDOUT
)
found = False
for line in ver.split(b"\n"):
@@ -284,62 +306,37 @@ def write_png(data, path, bitdepth, colortype, palette=None, iccp=None):
f.write(struct.pack(">I", 0) + block + struct.pack(">I", zlib.crc32(block)))
-def compare_ghostscript(tmpdir, img, pdf, gsdevice="png16m", exact=True, icc=False):
- if gsdevice in ["png16m", "pnggray"]:
- ext = "png"
- elif gsdevice in ["tiff24nc", "tiff32nc", "tiff48nc"]:
- ext = "tiff"
- else:
- raise Exception("unknown gsdevice: " + gsdevice)
- subprocess.check_call(
- [
- "gs",
- "-dQUIET",
- "-dNOPAUSE",
- "-dBATCH",
- "-sDEVICE=" + gsdevice,
- "-r96",
- "-sOutputFile=" + str(tmpdir / "gs-") + "%00d." + ext,
- str(pdf),
- ]
- )
+def compare(im1, im2, exact, icc, cmyk):
if exact:
- if icc:
- subprocess.check_call(
- [
- "compare",
- "-metric",
- "AE",
- "(",
- "-profile",
- "/usr/share/color/icc/ghostscript/srgb.icc",
- "-depth",
- "8",
- str(img),
- ")",
- str(tmpdir / "gs-1.") + ext,
- "null:",
- ]
- )
+ if cmyk:
+ raise Exception("cmyk cannot be exact")
+ elif icc:
+ raise Exception("icc cannot be exact")
else:
subprocess.check_call(
- [
- "compare",
+ COMPARE
+ + [
"-metric",
"AE",
- str(img),
- str(tmpdir / "gs-1.") + ext,
+ im1,
+ im2,
"null:",
]
)
else:
+ iccargs = []
+ if icc:
+ if ICC_PROFILE is None:
+ pytest.skip("Could not locate an ICC profile")
+ iccargs = ["-profile", ICC_PROFILE]
psnr = subprocess.run(
- [
- "compare",
+ COMPARE
+ + iccargs
+ + [
"-metric",
"PSNR",
- str(img),
- str(tmpdir / "gs-1.") + ext,
+ im1,
+ im2,
"null:",
],
check=False,
@@ -349,41 +346,36 @@ def compare_ghostscript(tmpdir, img, pdf, gsdevice="png16m", exact=True, icc=Fal
psnr = float(psnr.strip(b"0"))
assert psnr != 0 # or otherwise we would use the exact variant
assert psnr > 50
+
+
+def compare_ghostscript(tmpdir, img, pdf, gsdevice="png16m", exact=True, icc=False):
+ if gsdevice in ["png16m", "pnggray"]:
+ ext = "png"
+ elif gsdevice in ["tiff24nc", "tiff32nc", "tiff48nc"]:
+ ext = "tiff"
+ else:
+ raise Exception("unknown gsdevice: " + gsdevice)
+ subprocess.check_call(
+ [
+ "gs",
+ "-dQUIET",
+ "-dNOPAUSE",
+ "-dBATCH",
+ "-sDEVICE=" + gsdevice,
+ "-r96",
+ "-sOutputFile=" + str(tmpdir / "gs-") + "%00d." + ext,
+ str(pdf),
+ ]
+ )
+ compare(str(img), str(tmpdir / "gs-1.") + ext, exact, icc, False)
(tmpdir / ("gs-1." + ext)).unlink()
-def compare_poppler(tmpdir, img, pdf, exact=True):
+def compare_poppler(tmpdir, img, pdf, exact=True, icc=False):
subprocess.check_call(
["pdftocairo", "-r", "96", "-png", str(pdf), str(tmpdir / "poppler")]
)
- if exact:
- subprocess.check_call(
- [
- "compare",
- "-metric",
- "AE",
- str(img),
- str(tmpdir / "poppler-1.png"),
- "null:",
- ]
- )
- else:
- psnr = subprocess.run(
- [
- "compare",
- "-metric",
- "PSNR",
- str(img),
- str(tmpdir / "poppler-1.png"),
- "null:",
- ],
- check=False,
- stderr=subprocess.PIPE,
- ).stderr
- assert psnr != b"0"
- psnr = float(psnr.strip(b"0"))
- assert psnr != 0 # or otherwise we would use the exact variant
- assert psnr > 50
+ compare(str(img), str(tmpdir / "poppler-1.png"), exact, icc, False)
(tmpdir / "poppler-1.png").unlink()
@@ -400,20 +392,7 @@ def compare_mupdf(tmpdir, img, pdf, exact=True, cmyk=False):
subprocess.check_call(
["mutool", "draw", "-r", "96", "-png", "-o", str(out), str(pdf)]
)
- if exact:
- if cmyk:
- raise Exception("cmyk cannot be exact")
- subprocess.check_call(["compare", "-metric", "AE", str(img), str(out), "null:"])
- else:
- psnr = subprocess.run(
- ["compare", "-metric", "PSNR", str(img), str(out), "null:"],
- check=False,
- stderr=subprocess.PIPE,
- ).stderr
- assert psnr != b"0"
- psnr = float(psnr.strip(b"0"))
- assert psnr != 0 # or otherwise we would use the exact variant
- assert psnr > 50
+ compare(str(img), str(out), exact, False, cmyk)
out.unlink()
@@ -440,17 +419,43 @@ def compare_pdfimages_jp2(tmpdir, img, pdf):
def compare_pdfimages_tiff(tmpdir, img, pdf):
subprocess.check_call(["pdfimages", "-tiff", str(pdf), str(tmpdir / "images")])
subprocess.check_call(
- ["compare", "-metric", "AE", str(img), str(tmpdir / "images-000.tif"), "null:"]
+ COMPARE
+ + [
+ "-metric",
+ "AE",
+ str(img),
+ str(tmpdir / "images-000.tif"),
+ "null:",
+ ]
)
(tmpdir / "images-000.tif").unlink()
-def compare_pdfimages_png(tmpdir, img, pdf, exact=True):
+def compare_pdfimages_png(tmpdir, img, pdf, exact=True, icc=False):
subprocess.check_call(["pdfimages", "-png", str(pdf), str(tmpdir / "images")])
+ # images-001.png is the grayscale SMask image (the original alpha channel)
+ if os.path.isfile(tmpdir / "images-001.png"):
+ subprocess.check_call(
+ CONVERT
+ + [
+ str(tmpdir / "images-000.png"),
+ str(tmpdir / "images-001.png"),
+ "-compose",
+ "copy-opacity",
+ "-composite",
+ str(tmpdir / "composite.png"),
+ ]
+ )
+ (tmpdir / "images-000.png").unlink()
+ (tmpdir / "images-001.png").unlink()
+ os.rename(tmpdir / "composite.png", tmpdir / "images-000.png")
+
if exact:
+ if icc:
+ raise Exception("not exact with icc")
subprocess.check_call(
- [
- "compare",
+ COMPARE
+ + [
"-metric",
"AE",
str(img),
@@ -459,18 +464,40 @@ def compare_pdfimages_png(tmpdir, img, pdf, exact=True):
]
)
else:
- psnr = subprocess.run(
- [
- "compare",
- "-metric",
- "PSNR",
- str(img),
- str(tmpdir / "images-000.png"),
- "null:",
- ],
- check=False,
- stderr=subprocess.PIPE,
- ).stderr
+ if icc:
+ if ICC_PROFILE is None:
+ pytest.skip("Could not locate an ICC profile")
+ psnr = subprocess.run(
+ COMPARE
+ + [
+ "-metric",
+ "PSNR",
+ "(",
+ "-profile",
+ ICC_PROFILE,
+ "-depth",
+ "8",
+ str(img),
+ ")",
+ str(tmpdir / "images-000.png"),
+ "null:",
+ ],
+ check=False,
+ stderr=subprocess.PIPE,
+ ).stderr
+ else:
+ psnr = subprocess.run(
+ COMPARE
+ + [
+ "-metric",
+ "PSNR",
+ str(img),
+ str(tmpdir / "images-000.png"),
+ "null:",
+ ],
+ check=False,
+ stderr=subprocess.PIPE,
+ ).stderr
assert psnr != b"0"
psnr = float(psnr.strip(b"0"))
assert psnr != 0 # or otherwise we would use the exact variant
@@ -504,13 +531,36 @@ def tiff_header_for_ccitt(width, height, img_size, ccitt_group=4):
)
-###############################################################################
-# INPUT FIXTURES #
-###############################################################################
-
-
-@pytest.fixture(scope="session")
-def alpha():
+pixel_R = [
+ [1, 1, 1, 0],
+ [1, 0, 0, 1],
+ [1, 0, 0, 1],
+ [1, 1, 1, 0],
+ [1, 0, 0, 1],
+ [1, 0, 0, 1],
+ [1, 0, 0, 1],
+]
+pixel_G = [
+ [0, 1, 1, 0],
+ [1, 0, 0, 1],
+ [1, 0, 0, 0],
+ [1, 0, 1, 1],
+ [1, 0, 0, 1],
+ [1, 0, 0, 1],
+ [0, 1, 1, 0],
+]
+pixel_B = [
+ [1, 1, 1, 0],
+ [1, 0, 0, 1],
+ [1, 0, 0, 1],
+ [1, 1, 1, 0],
+ [1, 0, 0, 1],
+ [1, 0, 0, 1],
+ [1, 1, 1, 0],
+]
+
+
+def alpha_value():
# gaussian kernel with sigma=3
kernel = numpy.array(
[
@@ -522,7 +572,7 @@ def alpha():
[0.014962, 0.019703, 0.02324, 0.024556, 0.02324, 0.019703, 0.014962],
[0.011362, 0.014962, 0.017649, 0.018648, 0.017649, 0.014962, 0.011362],
],
- numpy.float,
+ float,
)
# constructs a 2D array of a circle with a width of 36
@@ -545,16 +595,127 @@ def alpha():
alpha[y + ypos, x + xpos] += color
alpha = numpy.clip(alpha, 0, 0xFFFF)
alpha = convolve_rgba(alpha, kernel)
+
+ # draw letters
+ for y, row in enumerate(pixel_R):
+ for x, pos in enumerate(row):
+ if pos:
+ alpha[13 + y, 28 + x] = [0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF]
+ for y, row in enumerate(pixel_G):
+ for x, pos in enumerate(row):
+ if pos:
+ alpha[39 + y, 40 + x] = [0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF]
+ for y, row in enumerate(pixel_B):
+ for x, pos in enumerate(row):
+ if pos:
+ alpha[39 + y, 15 + x] = [0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF]
return alpha
+def icc_profile():
+ PCS = (0.96420288, 1.0, 0.82490540) # D50 illuminant constants
+ # approximate X,Y,Z values for white, red, green and blue
+ white = (0.95, 1.0, 1.09)
+ red = (0.44, 0.22, 0.014)
+ green = (0.39, 0.72, 0.1)
+ blue = (0.14, 0.06, 0.71)
+
+ getxyz = lambda v: (round(65536 * v[0]), round(65536 * v[1]), round(65536 * v[2]))
+
+ header = (
+ # header
+ +4 * b"\0" # cmmsignatures
+ + 4 * b"\0" # version
+ + b"mntr" # device class
+ + b"RGB " # color space
+ + b"XYZ " # PCS
+ + 12 * b"\0" # datetime
+ + b"\x61\x63\x73\x70" # static signature
+ + 4 * b"\0" # platform
+ + 4 * b"\0" # flags
+ + 4 * b"\0" # device manufacturer
+ + 4 * b"\0" # device model
+ + 8 * b"\0" # device attributes
+ + 4 * b"\0" # rendering intents
+ + struct.pack(">III", *getxyz(PCS))
+ + 4 * b"\0" # creator
+ + 16 * b"\0" # identifier
+ + 28 * b"\0" # reserved
+ )
+
+ def pad4(s):
+ if len(s) % 4 == 0:
+ return s
+ else:
+ return s + b"\x00" * (4 - len(s) % 4)
+
+ tagdata = [
+ b"desc\x00\x00\x00\x00" + struct.pack(">I", 5) + b"fake" + 79 * b"\x00",
+ b"XYZ \x00\x00\x00\x00" + struct.pack(">III", *getxyz(white)),
+ # by mixing up red, green and blue, we create a test profile
+ b"XYZ \x00\x00\x00\x00" + struct.pack(">III", *getxyz(blue)), # red
+ b"XYZ \x00\x00\x00\x00" + struct.pack(">III", *getxyz(red)), # green
+ b"XYZ \x00\x00\x00\x00" + struct.pack(">III", *getxyz(green)), # blue
+ # by only supplying two values, we create the most trivial "curve",
+ # where the remaining values will be linearly interpolated between them
+ b"curv\x00\x00\x00\x00" + struct.pack(">IHH", 2, 0, 65535),
+ b"text\x00\x00\x00\x00" + b"no copyright, use freely" + 1 * b"\x00",
+ ]
+
+ table = [
+ (b"desc", 0),
+ (b"wtpt", 1),
+ (b"rXYZ", 2),
+ (b"gXYZ", 3),
+ (b"bXYZ", 4),
+ # we use the same curve for all three channels, so the same offset is referenced
+ (b"rTRC", 5),
+ (b"gTRC", 5),
+ (b"bTRC", 5),
+ (b"cprt", 6),
+ ]
+
+ offset = (
+ lambda n: 4 # total size
+ + len(header) # header length
+ + 4 # number table entries
+ + len(table) * 12 # table length
+ + sum([len(pad4(s)) for s in tagdata[:n]])
+ )
+
+ table = struct.pack(">I", len(table)) + b"".join(
+ [t + struct.pack(">II", offset(o), len(tagdata[o])) for t, o in table]
+ )
+
+ data = b"".join([pad4(s) for s in tagdata])
+
+ data = (
+ struct.pack(">I", 4 + len(header) + len(table) + len(data))
+ + header
+ + table
+ + data
+ )
+
+ return data
+
+
+###############################################################################
+# INPUT FIXTURES #
+###############################################################################
+
+
+@pytest.fixture(scope="session")
+def alpha():
+ return alpha_value()
+
+
@pytest.fixture(scope="session")
def tmp_alpha_png(tmp_path_factory, alpha):
tmp_alpha_png = tmp_path_factory.mktemp("alpha_png") / "alpha.png"
write_png(alpha, str(tmp_alpha_png), 16, 6)
assert (
hashlib.md5(tmp_alpha_png.read_bytes()).hexdigest()
- == "cc611e80cde3b9b7adb7723801a4e5d4"
+ == "600bb4cffb039a022cec6ed55537deba"
)
yield tmp_alpha_png
tmp_alpha_png.unlink()
@@ -573,7 +734,7 @@ def tmp_gray1_png(tmp_path_factory, alpha):
)
assert (
hashlib.md5(tmp_gray1_png.read_bytes()).hexdigest()
- == "ff4d9f18de39be879926be2e65990167"
+ == "dd2c528152d34324747355b73495a115"
)
yield tmp_gray1_png
tmp_gray1_png.unlink()
@@ -592,7 +753,7 @@ def tmp_gray2_png(tmp_path_factory, alpha):
)
assert (
hashlib.md5(tmp_gray2_png.read_bytes()).hexdigest()
- == "d51900476658a1c9dd26a7b27db8a21f"
+ == "68e614f4e6a85053d47098dad0ca3976"
)
yield tmp_gray2_png
tmp_gray2_png.unlink()
@@ -611,7 +772,7 @@ def tmp_gray4_png(tmp_path_factory, alpha):
)
assert (
hashlib.md5(tmp_gray4_png.read_bytes()).hexdigest()
- == "722223ba74be9cba1af4a549076b70d3"
+ == "ff04a6fea88133eb77bbb748692ae0fd"
)
yield tmp_gray4_png
tmp_gray4_png.unlink()
@@ -625,7 +786,7 @@ def tmp_gray8_png(tmp_path_factory, alpha):
write_png(gray16 / 0xFFFF * 0xFF, tmp_gray8_png, 8, 0)
assert (
hashlib.md5(tmp_gray8_png.read_bytes()).hexdigest()
- == "2320216faa5a10bf0f5f04ebce07f8e1"
+ == "90b4ed9123f295dda7fde499744dede7"
)
yield tmp_gray8_png
tmp_gray8_png.unlink()
@@ -639,7 +800,7 @@ def tmp_gray16_png(tmp_path_factory, alpha):
write_png(gray16, str(tmp_gray16_png), 16, 0)
assert (
hashlib.md5(tmp_gray16_png.read_bytes()).hexdigest()
- == "706175887af8ca1a33cfd93449f970df"
+ == "f76153d2e72fada11d934c32c8168a57"
)
yield tmp_gray16_png
tmp_gray16_png.unlink()
@@ -652,26 +813,34 @@ def tmp_inverse_png(tmp_path_factory, alpha):
write_png(0xFF - normal16 / 0xFFFF * 0xFF, str(tmp_inverse_png), 8, 2)
assert (
hashlib.md5(tmp_inverse_png.read_bytes()).hexdigest()
- == "35a47d6ae6de8c9d0b31aa0cda8648f3"
+ == "0a7d57dc09c4d8fd1ad3511b116c7dfa"
)
yield tmp_inverse_png
tmp_inverse_png.unlink()
@pytest.fixture(scope="session")
-def tmp_icc_png(tmp_path_factory, alpha):
+def tmp_icc_profile(tmp_path_factory):
+ tmp_icc_profile = tmp_path_factory.mktemp("icc_profile") / "fake.icc"
+ tmp_icc_profile.write_bytes(icc_profile())
+ yield tmp_icc_profile
+ tmp_icc_profile.unlink()
+
+
+@pytest.fixture(scope="session")
+def tmp_icc_png(tmp_path_factory, alpha, tmp_icc_profile):
normal16 = alpha[:, :, 0:3]
tmp_icc_png = tmp_path_factory.mktemp("icc_png") / "icc.png"
write_png(
- 0xFF - normal16 / 0xFFFF * 0xFF,
+ normal16 / 0xFFFF * 0xFF,
str(tmp_icc_png),
8,
2,
- iccp="/usr/share/color/icc/sRGB.icc",
+ iccp=str(tmp_icc_profile),
)
assert (
hashlib.md5(tmp_icc_png.read_bytes()).hexdigest()
- == "d09865464626a87b4e7f398e1f914cca"
+ == "bf25f673c1617f5f9353b2a043747655"
)
yield tmp_icc_png
tmp_icc_png.unlink()
@@ -684,7 +853,7 @@ def tmp_normal16_png(tmp_path_factory, alpha):
write_png(normal16, str(tmp_normal16_png), 16, 2)
assert (
hashlib.md5(tmp_normal16_png.read_bytes()).hexdigest()
- == "6ad810399058a87d8145d8d9a7734da5"
+ == "820dd30a2566775fc64c110e8ac65c7e"
)
yield tmp_normal16_png
tmp_normal16_png.unlink()
@@ -697,7 +866,7 @@ def tmp_normal_png(tmp_path_factory, alpha):
write_png(normal16 / 0xFFFF * 0xFF, str(tmp_normal_png), 8, 2)
assert (
hashlib.md5(tmp_normal_png.read_bytes()).hexdigest()
- == "c8d2e1f116f31ecdeae050524efca7b6"
+ == "bc30c705f455991cd04be1c298063002"
)
yield tmp_normal_png
tmp_normal_png.unlink()
@@ -725,7 +894,7 @@ def tmp_palette1_png(tmp_path_factory, alpha):
)
assert (
hashlib.md5(tmp_palette1_png.read_bytes()).hexdigest()
- == "18a3dfca369f976996ef93389ddfad61"
+ == "3d065f731540e928fb730b3233e4e8a7"
)
yield tmp_palette1_png
tmp_palette1_png.unlink()
@@ -752,7 +921,7 @@ def tmp_palette2_png(tmp_path_factory, alpha):
)
assert (
hashlib.md5(tmp_palette2_png.read_bytes()).hexdigest()
- == "d38646afa6fa0714be9badef25ff9392"
+ == "0b0d4412c28da26163a622d218ee02ca"
)
yield tmp_palette2_png
tmp_palette2_png.unlink()
@@ -795,7 +964,7 @@ def tmp_palette4_png(tmp_path_factory, alpha):
)
assert (
hashlib.md5(tmp_palette4_png.read_bytes()).hexdigest()
- == "e1c59e68a68fca3273b6dc164d526ed7"
+ == "163f6d7964b80eefa0dc6a48cb7315dd"
)
yield tmp_palette4_png
tmp_palette4_png.unlink()
@@ -830,7 +999,7 @@ def tmp_palette8_png(tmp_path_factory, alpha):
)
assert (
hashlib.md5(tmp_palette8_png.read_bytes()).hexdigest()
- == "50bf09eb3571901f0bf642b9a733038c"
+ == "8847bb734eba0e2d85e3f97fc2849dd4"
)
yield tmp_palette8_png
tmp_palette8_png.unlink()
@@ -839,8 +1008,8 @@ def tmp_palette8_png(tmp_path_factory, alpha):
@pytest.fixture(scope="session")
def jpg_img(tmp_path_factory, tmp_normal_png):
in_img = tmp_path_factory.mktemp("jpg") / "in.jpg"
- subprocess.check_call(["convert", str(tmp_normal_png), str(in_img)])
- identify = json.loads(subprocess.check_output(["convert", str(in_img), "json:"]))
+ subprocess.check_call(CONVERT + [str(tmp_normal_png), str(in_img)])
+ identify = json.loads(subprocess.check_output(CONVERT + [str(in_img), "json:"]))
assert len(identify) == 1
# somewhere between imagemagick 6.9.7.4 and 6.9.9.34, the json output was
# put into an array, here we cater for the older version containing just
@@ -849,10 +1018,6 @@ def jpg_img(tmp_path_factory, tmp_normal_png):
identify = [identify]
assert "image" in identify[0]
assert identify[0]["image"].get("format") == "JPEG", str(identify)
- assert (
- identify[0]["image"]["formatDescription"]
- == "Joint Photographic Experts Group JFIF format"
- ), str(identify)
assert identify[0]["image"].get("mimeType") == "image/jpeg", str(identify)
assert identify[0]["image"].get("geometry") == {
"width": 60,
@@ -863,7 +1028,8 @@ def jpg_img(tmp_path_factory, tmp_normal_png):
assert "resolution" not in identify[0]["image"]
assert identify[0]["image"].get("units") == "Undefined", str(identify)
assert identify[0]["image"].get("type") == "TrueColor", str(identify)
- assert identify[0]["image"].get("endianess") == "Undefined", str(identify)
+ endian = "endianess" if identify[0].get("version", "0") < "1.0" else "endianness"
+ assert identify[0]["image"].get(endian) == "Undefined", str(identify)
assert identify[0]["image"].get("colorspace") == "sRGB", str(identify)
assert identify[0]["image"].get("depth") == 8, str(identify)
assert identify[0]["image"].get("pageGeometry") == {
@@ -884,7 +1050,7 @@ def jpg_img(tmp_path_factory, tmp_normal_png):
@pytest.fixture(scope="session")
def jpg_rot_img(tmp_path_factory, tmp_normal_png):
in_img = tmp_path_factory.mktemp("jpg_rot") / "in.jpg"
- subprocess.check_call(["convert", str(tmp_normal_png), str(in_img)])
+ subprocess.check_call(CONVERT + [str(tmp_normal_png), str(in_img)])
subprocess.check_call(
["exiftool", "-overwrite_original", "-all=", str(in_img), "-n"]
)
@@ -899,7 +1065,7 @@ def jpg_rot_img(tmp_path_factory, tmp_normal_png):
str(in_img),
]
)
- identify = json.loads(subprocess.check_output(["convert", str(in_img), "json:"]))
+ identify = json.loads(subprocess.check_output(CONVERT + [str(in_img), "json:"]))
assert len(identify) == 1
# somewhere between imagemagick 6.9.7.4 and 6.9.9.34, the json output was
# put into an array, here we cater for the older version containing just
@@ -908,10 +1074,6 @@ def jpg_rot_img(tmp_path_factory, tmp_normal_png):
identify = [identify]
assert "image" in identify[0]
assert identify[0]["image"].get("format") == "JPEG", str(identify)
- assert (
- identify[0]["image"]["formatDescription"]
- == "Joint Photographic Experts Group JFIF format"
- ), str(identify)
assert identify[0]["image"].get("mimeType") == "image/jpeg", str(identify)
assert identify[0]["image"].get("geometry") == {
"width": 60,
@@ -940,9 +1102,9 @@ def jpg_rot_img(tmp_path_factory, tmp_normal_png):
def jpg_cmyk_img(tmp_path_factory, tmp_normal_png):
in_img = tmp_path_factory.mktemp("jpg_cmyk") / "in.jpg"
subprocess.check_call(
- ["convert", str(tmp_normal_png), "-colorspace", "cmyk", str(in_img)]
+ CONVERT + [str(tmp_normal_png), "-colorspace", "cmyk", str(in_img)]
)
- identify = json.loads(subprocess.check_output(["convert", str(in_img), "json:"]))
+ identify = json.loads(subprocess.check_output(CONVERT + [str(in_img), "json:"]))
assert len(identify) == 1
# somewhere between imagemagick 6.9.7.4 and 6.9.9.34, the json output was
# put into an array, here we cater for the older version containing just
@@ -951,10 +1113,6 @@ def jpg_cmyk_img(tmp_path_factory, tmp_normal_png):
identify = [identify]
assert "image" in identify[0]
assert identify[0]["image"].get("format") == "JPEG", str(identify)
- assert (
- identify[0]["image"]["formatDescription"]
- == "Joint Photographic Experts Group JFIF format"
- ), str(identify)
assert identify[0]["image"].get("mimeType") == "image/jpeg", str(identify)
assert identify[0]["image"].get("geometry") == {
"width": 60,
@@ -979,8 +1137,8 @@ def jpg_cmyk_img(tmp_path_factory, tmp_normal_png):
@pytest.fixture(scope="session")
def jpg_2000_img(tmp_path_factory, tmp_normal_png):
in_img = tmp_path_factory.mktemp("jpg_2000") / "in.jp2"
- subprocess.check_call(["convert", str(tmp_normal_png), str(in_img)])
- identify = json.loads(subprocess.check_output(["convert", str(in_img), "json:"]))
+ subprocess.check_call(CONVERT + [str(tmp_normal_png), str(in_img)])
+ identify = json.loads(subprocess.check_output(CONVERT + [str(in_img), "json:"]))
assert len(identify) == 1
# somewhere between imagemagick 6.9.7.4 and 6.9.9.34, the json output was
# put into an array, here we cater for the older version containing just
@@ -989,9 +1147,6 @@ def jpg_2000_img(tmp_path_factory, tmp_normal_png):
identify = [identify]
assert "image" in identify[0]
assert identify[0]["image"].get("format") == "JP2", str(identify)
- assert (
- identify[0]["image"].get("formatDescription") == "JPEG-2000 File Format Syntax"
- ), str(identify)
assert identify[0]["image"].get("mimeType") == "image/jp2", str(identify)
assert identify[0]["image"].get("geometry") == {
"width": 60,
@@ -1016,7 +1171,7 @@ def jpg_2000_img(tmp_path_factory, tmp_normal_png):
@pytest.fixture(scope="session")
def png_rgb8_img(tmp_normal_png):
in_img = tmp_normal_png
- identify = json.loads(subprocess.check_output(["convert", str(in_img), "json:"]))
+ identify = json.loads(subprocess.check_output(CONVERT + [str(in_img), "json:"]))
assert len(identify) == 1
# somewhere between imagemagick 6.9.7.4 and 6.9.9.34, the json output was
# put into an array, here we cater for the older version containing just
@@ -1025,9 +1180,6 @@ def png_rgb8_img(tmp_normal_png):
identify = [identify]
assert "image" in identify[0]
assert identify[0]["image"].get("format") == "PNG", str(identify)
- assert (
- identify[0]["image"].get("formatDescription") == "Portable Network Graphics"
- ), str(identify)
assert identify[0]["image"].get("mimeType") == "image/png", str(identify)
assert identify[0]["image"].get("geometry") == {
"width": 60,
@@ -1044,7 +1196,6 @@ def png_rgb8_img(tmp_normal_png):
"x": 0,
"y": 0,
}, str(identify)
- assert identify[0]["image"].get("compression") == "Zip", str(identify)
assert (
identify[0]["image"].get("properties", {}).get("png:IHDR.bit-depth-orig") == "8"
), str(identify)
@@ -1069,7 +1220,7 @@ def png_rgb8_img(tmp_normal_png):
@pytest.fixture(scope="session")
def png_rgb16_img(tmp_normal16_png):
in_img = tmp_normal16_png
- identify = json.loads(subprocess.check_output(["convert", str(in_img), "json:"]))
+ identify = json.loads(subprocess.check_output(CONVERT + [str(in_img), "json:"]))
assert len(identify) == 1
# somewhere between imagemagick 6.9.7.4 and 6.9.9.34, the json output was
# put into an array, here we cater for the older version containing just
@@ -1078,9 +1229,6 @@ def png_rgb16_img(tmp_normal16_png):
identify = [identify]
assert "image" in identify[0]
assert identify[0]["image"].get("format") == "PNG", str(identify)
- assert (
- identify[0]["image"].get("formatDescription") == "Portable Network Graphics"
- ), str(identify)
assert identify[0]["image"].get("mimeType") == "image/png", str(identify)
assert identify[0]["image"].get("geometry") == {
"width": 60,
@@ -1097,7 +1245,6 @@ def png_rgb16_img(tmp_normal16_png):
"x": 0,
"y": 0,
}, str(identify)
- assert identify[0]["image"].get("compression") == "Zip", str(identify)
assert (
identify[0]["image"].get("properties", {}).get("png:IHDR.bit-depth-orig")
== "16"
@@ -1124,9 +1271,9 @@ def png_rgb16_img(tmp_normal16_png):
def png_rgba8_img(tmp_path_factory, tmp_alpha_png):
in_img = tmp_path_factory.mktemp("png_rgba8") / "in.png"
subprocess.check_call(
- ["convert", str(tmp_alpha_png), "-depth", "8", "-strip", str(in_img)]
+ CONVERT + [str(tmp_alpha_png), "-depth", "8", "-strip", str(in_img)]
)
- identify = json.loads(subprocess.check_output(["convert", str(in_img), "json:"]))
+ identify = json.loads(subprocess.check_output(CONVERT + [str(in_img), "json:"]))
assert len(identify) == 1
# somewhere between imagemagick 6.9.7.4 and 6.9.9.34, the json output was
# put into an array, here we cater for the older version containing just
@@ -1135,9 +1282,6 @@ def png_rgba8_img(tmp_path_factory, tmp_alpha_png):
identify = [identify]
assert "image" in identify[0]
assert identify[0]["image"].get("format") == "PNG", str(identify)
- assert (
- identify[0]["image"].get("formatDescription") == "Portable Network Graphics"
- ), str(identify)
assert identify[0]["image"].get("mimeType") == "image/png", str(identify)
assert identify[0]["image"].get("geometry") == {
"width": 60,
@@ -1154,7 +1298,6 @@ def png_rgba8_img(tmp_path_factory, tmp_alpha_png):
"x": 0,
"y": 0,
}, str(identify)
- assert identify[0]["image"].get("compression") == "Zip", str(identify)
assert (
identify[0]["image"].get("properties", {}).get("png:IHDR.bit-depth-orig") == "8"
), str(identify)
@@ -1180,7 +1323,7 @@ def png_rgba8_img(tmp_path_factory, tmp_alpha_png):
@pytest.fixture(scope="session")
def png_rgba16_img(tmp_alpha_png):
in_img = tmp_alpha_png
- identify = json.loads(subprocess.check_output(["convert", str(in_img), "json:"]))
+ identify = json.loads(subprocess.check_output(CONVERT + [str(in_img), "json:"]))
assert len(identify) == 1
# somewhere between imagemagick 6.9.7.4 and 6.9.9.34, the json output was
# put into an array, here we cater for the older version containing just
@@ -1189,9 +1332,6 @@ def png_rgba16_img(tmp_alpha_png):
identify = [identify]
assert "image" in identify[0]
assert identify[0]["image"].get("format") == "PNG", str(identify)
- assert (
- identify[0]["image"].get("formatDescription") == "Portable Network Graphics"
- ), str(identify)
assert identify[0]["image"].get("mimeType") == "image/png", str(identify)
assert identify[0]["image"].get("geometry") == {
"width": 60,
@@ -1208,7 +1348,6 @@ def png_rgba16_img(tmp_alpha_png):
"x": 0,
"y": 0,
}, str(identify)
- assert identify[0]["image"].get("compression") == "Zip", str(identify)
assert (
identify[0]["image"].get("properties", {}).get("png:IHDR.bit-depth-orig")
== "16"
@@ -1235,8 +1374,8 @@ def png_rgba16_img(tmp_alpha_png):
def png_gray8a_img(tmp_path_factory, tmp_alpha_png):
in_img = tmp_path_factory.mktemp("png_gray8a") / "in.png"
subprocess.check_call(
- [
- "convert",
+ CONVERT
+ + [
str(tmp_alpha_png),
"-colorspace",
"Gray",
@@ -1250,7 +1389,7 @@ def png_gray8a_img(tmp_path_factory, tmp_alpha_png):
str(in_img),
]
)
- identify = json.loads(subprocess.check_output(["convert", str(in_img), "json:"]))
+ identify = json.loads(subprocess.check_output(CONVERT + [str(in_img), "json:"]))
assert len(identify) == 1
# somewhere between imagemagick 6.9.7.4 and 6.9.9.34, the json output was
# put into an array, here we cater for the older version containing just
@@ -1259,9 +1398,6 @@ def png_gray8a_img(tmp_path_factory, tmp_alpha_png):
identify = [identify]
assert "image" in identify[0]
assert identify[0]["image"].get("format") == "PNG", str(identify)
- assert (
- identify[0]["image"].get("formatDescription") == "Portable Network Graphics"
- ), str(identify)
assert identify[0]["image"].get("mimeType") == "image/png", str(identify)
assert identify[0]["image"].get("geometry") == {
"width": 60,
@@ -1278,7 +1414,6 @@ def png_gray8a_img(tmp_path_factory, tmp_alpha_png):
"x": 0,
"y": 0,
}, str(identify)
- assert identify[0]["image"].get("compression") == "Zip", str(identify)
assert (
identify[0]["image"].get("properties", {}).get("png:IHDR.bit-depth-orig") == "8"
), str(identify)
@@ -1305,8 +1440,8 @@ def png_gray8a_img(tmp_path_factory, tmp_alpha_png):
def png_gray16a_img(tmp_path_factory, tmp_alpha_png):
in_img = tmp_path_factory.mktemp("png_gray16a") / "in.png"
subprocess.check_call(
- [
- "convert",
+ CONVERT
+ + [
str(tmp_alpha_png),
"-colorspace",
"Gray",
@@ -1316,7 +1451,7 @@ def png_gray16a_img(tmp_path_factory, tmp_alpha_png):
str(in_img),
]
)
- identify = json.loads(subprocess.check_output(["convert", str(in_img), "json:"]))
+ identify = json.loads(subprocess.check_output(CONVERT + [str(in_img), "json:"]))
assert len(identify) == 1
# somewhere between imagemagick 6.9.7.4 and 6.9.9.34, the json output was
# put into an array, here we cater for the older version containing just
@@ -1325,9 +1460,6 @@ def png_gray16a_img(tmp_path_factory, tmp_alpha_png):
identify = [identify]
assert "image" in identify[0]
assert identify[0]["image"].get("format") == "PNG", str(identify)
- assert (
- identify[0]["image"].get("formatDescription") == "Portable Network Graphics"
- ), str(identify)
assert identify[0]["image"].get("mimeType") == "image/png", str(identify)
assert identify[0]["image"].get("geometry") == {
"width": 60,
@@ -1344,7 +1476,6 @@ def png_gray16a_img(tmp_path_factory, tmp_alpha_png):
"x": 0,
"y": 0,
}, str(identify)
- assert identify[0]["image"].get("compression") == "Zip", str(identify)
assert (
identify[0]["image"].get("properties", {}).get("png:IHDR.bit-depth-orig")
== "16"
@@ -1372,9 +1503,16 @@ def png_gray16a_img(tmp_path_factory, tmp_alpha_png):
def png_interlaced_img(tmp_path_factory, tmp_normal_png):
in_img = tmp_path_factory.mktemp("png_interlaced") / "in.png"
subprocess.check_call(
- ["convert", str(tmp_normal_png), "-interlace", "PNG", "-strip", str(in_img)]
+ CONVERT
+ + [
+ str(tmp_normal_png),
+ "-interlace",
+ "PNG",
+ "-strip",
+ str(in_img),
+ ]
)
- identify = json.loads(subprocess.check_output(["convert", str(in_img), "json:"]))
+ identify = json.loads(subprocess.check_output(CONVERT + [str(in_img), "json:"]))
assert len(identify) == 1
# somewhere between imagemagick 6.9.7.4 and 6.9.9.34, the json output was
# put into an array, here we cater for the older version containing just
@@ -1383,9 +1521,6 @@ def png_interlaced_img(tmp_path_factory, tmp_normal_png):
identify = [identify]
assert "image" in identify[0]
assert identify[0]["image"].get("format") == "PNG", str(identify)
- assert (
- identify[0]["image"].get("formatDescription") == "Portable Network Graphics"
- ), str(identify)
assert identify[0]["image"].get("mimeType") == "image/png", str(identify)
assert identify[0]["image"].get("geometry") == {
"width": 60,
@@ -1402,7 +1537,6 @@ def png_interlaced_img(tmp_path_factory, tmp_normal_png):
"x": 0,
"y": 0,
}, str(identify)
- assert identify[0]["image"].get("compression") == "Zip", str(identify)
assert (
identify[0]["image"].get("properties", {}).get("png:IHDR.bit-depth-orig") == "8"
), str(identify)
@@ -1428,7 +1562,7 @@ def png_interlaced_img(tmp_path_factory, tmp_normal_png):
@pytest.fixture(scope="session")
def png_gray1_img(tmp_path_factory, tmp_gray1_png):
identify = json.loads(
- subprocess.check_output(["convert", str(tmp_gray1_png), "json:"])
+ subprocess.check_output(CONVERT + [str(tmp_gray1_png), "json:"])
)
assert len(identify) == 1
# somewhere between imagemagick 6.9.7.4 and 6.9.9.34, the json output was
@@ -1438,9 +1572,6 @@ def png_gray1_img(tmp_path_factory, tmp_gray1_png):
identify = [identify]
assert "image" in identify[0]
assert identify[0]["image"].get("format") == "PNG", str(identify)
- assert (
- identify[0]["image"].get("formatDescription") == "Portable Network Graphics"
- ), str(identify)
assert identify[0]["image"].get("mimeType") == "image/png", str(identify)
assert identify[0]["image"].get("geometry") == {
"width": 60,
@@ -1457,7 +1588,6 @@ def png_gray1_img(tmp_path_factory, tmp_gray1_png):
"x": 0,
"y": 0,
}, str(identify)
- assert identify[0]["image"].get("compression") == "Zip", str(identify)
assert (
identify[0]["image"].get("properties", {}).get("png:IHDR.bit-depth-orig") == "1"
), str(identify)
@@ -1482,7 +1612,7 @@ def png_gray1_img(tmp_path_factory, tmp_gray1_png):
@pytest.fixture(scope="session")
def png_gray2_img(tmp_path_factory, tmp_gray2_png):
identify = json.loads(
- subprocess.check_output(["convert", str(tmp_gray2_png), "json:"])
+ subprocess.check_output(CONVERT + [str(tmp_gray2_png), "json:"])
)
assert len(identify) == 1
# somewhere between imagemagick 6.9.7.4 and 6.9.9.34, the json output was
@@ -1492,9 +1622,6 @@ def png_gray2_img(tmp_path_factory, tmp_gray2_png):
identify = [identify]
assert "image" in identify[0]
assert identify[0]["image"].get("format") == "PNG", str(identify)
- assert (
- identify[0]["image"].get("formatDescription") == "Portable Network Graphics"
- ), str(identify)
assert identify[0]["image"].get("mimeType") == "image/png", str(identify)
assert identify[0]["image"].get("geometry") == {
"width": 60,
@@ -1511,7 +1638,6 @@ def png_gray2_img(tmp_path_factory, tmp_gray2_png):
"x": 0,
"y": 0,
}, str(identify)
- assert identify[0]["image"].get("compression") == "Zip", str(identify)
assert (
identify[0]["image"].get("properties", {}).get("png:IHDR.bit-depth-orig") == "2"
), str(identify)
@@ -1536,7 +1662,7 @@ def png_gray2_img(tmp_path_factory, tmp_gray2_png):
@pytest.fixture(scope="session")
def png_gray4_img(tmp_path_factory, tmp_gray4_png):
identify = json.loads(
- subprocess.check_output(["convert", str(tmp_gray4_png), "json:"])
+ subprocess.check_output(CONVERT + [str(tmp_gray4_png), "json:"])
)
assert len(identify) == 1
# somewhere between imagemagick 6.9.7.4 and 6.9.9.34, the json output was
@@ -1546,9 +1672,6 @@ def png_gray4_img(tmp_path_factory, tmp_gray4_png):
identify = [identify]
assert "image" in identify[0]
assert identify[0]["image"].get("format") == "PNG", str(identify)
- assert (
- identify[0]["image"].get("formatDescription") == "Portable Network Graphics"
- ), str(identify)
assert identify[0]["image"].get("mimeType") == "image/png", str(identify)
assert identify[0]["image"].get("geometry") == {
"width": 60,
@@ -1565,7 +1688,6 @@ def png_gray4_img(tmp_path_factory, tmp_gray4_png):
"x": 0,
"y": 0,
}, str(identify)
- assert identify[0]["image"].get("compression") == "Zip", str(identify)
assert (
identify[0]["image"].get("properties", {}).get("png:IHDR.bit-depth-orig") == "4"
), str(identify)
@@ -1590,7 +1712,7 @@ def png_gray4_img(tmp_path_factory, tmp_gray4_png):
@pytest.fixture(scope="session")
def png_gray8_img(tmp_path_factory, tmp_gray8_png):
identify = json.loads(
- subprocess.check_output(["convert", str(tmp_gray8_png), "json:"])
+ subprocess.check_output(CONVERT + [str(tmp_gray8_png), "json:"])
)
assert len(identify) == 1
# somewhere between imagemagick 6.9.7.4 and 6.9.9.34, the json output was
@@ -1600,9 +1722,6 @@ def png_gray8_img(tmp_path_factory, tmp_gray8_png):
identify = [identify]
assert "image" in identify[0]
assert identify[0]["image"].get("format") == "PNG", str(identify)
- assert (
- identify[0]["image"].get("formatDescription") == "Portable Network Graphics"
- ), str(identify)
assert identify[0]["image"].get("mimeType") == "image/png", str(identify)
assert identify[0]["image"].get("geometry") == {
"width": 60,
@@ -1619,7 +1738,6 @@ def png_gray8_img(tmp_path_factory, tmp_gray8_png):
"x": 0,
"y": 0,
}, str(identify)
- assert identify[0]["image"].get("compression") == "Zip", str(identify)
assert (
identify[0]["image"].get("properties", {}).get("png:IHDR.bit-depth-orig") == "8"
), str(identify)
@@ -1644,7 +1762,7 @@ def png_gray8_img(tmp_path_factory, tmp_gray8_png):
@pytest.fixture(scope="session")
def png_gray16_img(tmp_path_factory, tmp_gray16_png):
identify = json.loads(
- subprocess.check_output(["convert", str(tmp_gray16_png), "json:"])
+ subprocess.check_output(CONVERT + [str(tmp_gray16_png), "json:"])
)
assert len(identify) == 1
# somewhere between imagemagick 6.9.7.4 and 6.9.9.34, the json output was
@@ -1654,9 +1772,6 @@ def png_gray16_img(tmp_path_factory, tmp_gray16_png):
identify = [identify]
assert "image" in identify[0]
assert identify[0]["image"].get("format") == "PNG", str(identify)
- assert (
- identify[0]["image"].get("formatDescription") == "Portable Network Graphics"
- ), str(identify)
assert identify[0]["image"].get("mimeType") == "image/png", str(identify)
assert identify[0]["image"].get("geometry") == {
"width": 60,
@@ -1673,7 +1788,6 @@ def png_gray16_img(tmp_path_factory, tmp_gray16_png):
"x": 0,
"y": 0,
}, str(identify)
- assert identify[0]["image"].get("compression") == "Zip", str(identify)
assert (
identify[0]["image"].get("properties", {}).get("png:IHDR.bit-depth-orig")
== "16"
@@ -1699,7 +1813,7 @@ def png_gray16_img(tmp_path_factory, tmp_gray16_png):
@pytest.fixture(scope="session")
def png_palette1_img(tmp_path_factory, tmp_palette1_png):
identify = json.loads(
- subprocess.check_output(["convert", str(tmp_palette1_png), "json:"])
+ subprocess.check_output(CONVERT + [str(tmp_palette1_png), "json:"])
)
assert len(identify) == 1
# somewhere between imagemagick 6.9.7.4 and 6.9.9.34, the json output was
@@ -1709,9 +1823,6 @@ def png_palette1_img(tmp_path_factory, tmp_palette1_png):
identify = [identify]
assert "image" in identify[0]
assert identify[0]["image"].get("format") == "PNG", str(identify)
- assert (
- identify[0]["image"].get("formatDescription") == "Portable Network Graphics"
- ), str(identify)
assert identify[0]["image"].get("mimeType") == "image/png", str(identify)
assert identify[0]["image"].get("geometry") == {
"width": 60,
@@ -1728,7 +1839,6 @@ def png_palette1_img(tmp_path_factory, tmp_palette1_png):
"x": 0,
"y": 0,
}, str(identify)
- assert identify[0]["image"].get("compression") == "Zip", str(identify)
assert (
identify[0]["image"].get("properties", {}).get("png:IHDR.bit-depth-orig") == "1"
), str(identify)
@@ -1753,7 +1863,7 @@ def png_palette1_img(tmp_path_factory, tmp_palette1_png):
@pytest.fixture(scope="session")
def png_palette2_img(tmp_path_factory, tmp_palette2_png):
identify = json.loads(
- subprocess.check_output(["convert", str(tmp_palette2_png), "json:"])
+ subprocess.check_output(CONVERT + [str(tmp_palette2_png), "json:"])
)
assert len(identify) == 1
# somewhere between imagemagick 6.9.7.4 and 6.9.9.34, the json output was
@@ -1763,9 +1873,6 @@ def png_palette2_img(tmp_path_factory, tmp_palette2_png):
identify = [identify]
assert "image" in identify[0]
assert identify[0]["image"].get("format") == "PNG", str(identify)
- assert (
- identify[0]["image"].get("formatDescription") == "Portable Network Graphics"
- ), str(identify)
assert identify[0]["image"].get("mimeType") == "image/png", str(identify)
assert identify[0]["image"].get("geometry") == {
"width": 60,
@@ -1782,7 +1889,6 @@ def png_palette2_img(tmp_path_factory, tmp_palette2_png):
"x": 0,
"y": 0,
}, str(identify)
- assert identify[0]["image"].get("compression") == "Zip", str(identify)
assert (
identify[0]["image"].get("properties", {}).get("png:IHDR.bit-depth-orig") == "2"
), str(identify)
@@ -1807,7 +1913,7 @@ def png_palette2_img(tmp_path_factory, tmp_palette2_png):
@pytest.fixture(scope="session")
def png_palette4_img(tmp_path_factory, tmp_palette4_png):
identify = json.loads(
- subprocess.check_output(["convert", str(tmp_palette4_png), "json:"])
+ subprocess.check_output(CONVERT + [str(tmp_palette4_png), "json:"])
)
assert len(identify) == 1
# somewhere between imagemagick 6.9.7.4 and 6.9.9.34, the json output was
@@ -1817,9 +1923,6 @@ def png_palette4_img(tmp_path_factory, tmp_palette4_png):
identify = [identify]
assert "image" in identify[0]
assert identify[0]["image"].get("format") == "PNG", str(identify)
- assert (
- identify[0]["image"].get("formatDescription") == "Portable Network Graphics"
- ), str(identify)
assert identify[0]["image"].get("mimeType") == "image/png", str(identify)
assert identify[0]["image"].get("geometry") == {
"width": 60,
@@ -1836,7 +1939,6 @@ def png_palette4_img(tmp_path_factory, tmp_palette4_png):
"x": 0,
"y": 0,
}, str(identify)
- assert identify[0]["image"].get("compression") == "Zip", str(identify)
assert (
identify[0]["image"].get("properties", {}).get("png:IHDR.bit-depth-orig") == "4"
), str(identify)
@@ -1861,7 +1963,7 @@ def png_palette4_img(tmp_path_factory, tmp_palette4_png):
@pytest.fixture(scope="session")
def png_palette8_img(tmp_path_factory, tmp_palette8_png):
identify = json.loads(
- subprocess.check_output(["convert", str(tmp_palette8_png), "json:"])
+ subprocess.check_output(CONVERT + [str(tmp_palette8_png), "json:"])
)
assert len(identify) == 1
# somewhere between imagemagick 6.9.7.4 and 6.9.9.34, the json output was
@@ -1871,9 +1973,6 @@ def png_palette8_img(tmp_path_factory, tmp_palette8_png):
identify = [identify]
assert "image" in identify[0]
assert identify[0]["image"].get("format") == "PNG", str(identify)
- assert (
- identify[0]["image"].get("formatDescription") == "Portable Network Graphics"
- ), str(identify)
assert identify[0]["image"].get("mimeType") == "image/png", str(identify)
assert identify[0]["image"].get("geometry") == {
"width": 60,
@@ -1890,7 +1989,6 @@ def png_palette8_img(tmp_path_factory, tmp_palette8_png):
"x": 0,
"y": 0,
}, str(identify)
- assert identify[0]["image"].get("compression") == "Zip", str(identify)
assert (
identify[0]["image"].get("properties", {}).get("png:IHDR.bit-depth-orig") == "8"
), str(identify)
@@ -1915,8 +2013,8 @@ def png_palette8_img(tmp_path_factory, tmp_palette8_png):
@pytest.fixture(scope="session")
def gif_transparent_img(tmp_path_factory, tmp_alpha_png):
in_img = tmp_path_factory.mktemp("gif_transparent_img") / "in.gif"
- subprocess.check_call(["convert", str(tmp_alpha_png), str(in_img)])
- identify = json.loads(subprocess.check_output(["convert", str(in_img), "json:"]))
+ subprocess.check_call(CONVERT + [str(tmp_alpha_png), str(in_img)])
+ identify = json.loads(subprocess.check_output(CONVERT + [str(in_img), "json:"]))
assert len(identify) == 1
# somewhere between imagemagick 6.9.7.4 and 6.9.9.34, the json output was
# put into an array, here we cater for the older version containing just
@@ -1925,10 +2023,6 @@ def gif_transparent_img(tmp_path_factory, tmp_alpha_png):
identify = [identify]
assert "image" in identify[0]
assert identify[0]["image"].get("format") == "GIF", str(identify)
- assert (
- identify[0]["image"]["formatDescription"]
- == "CompuServe graphics interchange format"
- ), str(identify)
assert identify[0]["image"].get("mimeType") == "image/gif", str(identify)
assert identify[0]["image"].get("geometry") == {
"width": 60,
@@ -1954,8 +2048,8 @@ def gif_transparent_img(tmp_path_factory, tmp_alpha_png):
@pytest.fixture(scope="session")
def gif_palette1_img(tmp_path_factory, tmp_palette1_png):
in_img = tmp_path_factory.mktemp("gif_palette1_img") / "in.gif"
- subprocess.check_call(["convert", str(tmp_palette1_png), str(in_img)])
- identify = json.loads(subprocess.check_output(["convert", str(in_img), "json:"]))
+ subprocess.check_call(CONVERT + [str(tmp_palette1_png), str(in_img)])
+ identify = json.loads(subprocess.check_output(CONVERT + [str(in_img), "json:"]))
assert len(identify) == 1
# somewhere between imagemagick 6.9.7.4 and 6.9.9.34, the json output was
# put into an array, here we cater for the older version containing just
@@ -1964,10 +2058,6 @@ def gif_palette1_img(tmp_path_factory, tmp_palette1_png):
identify = [identify]
assert "image" in identify[0]
assert identify[0]["image"].get("format") == "GIF", str(identify)
- assert (
- identify[0]["image"]["formatDescription"]
- == "CompuServe graphics interchange format"
- ), str(identify)
assert identify[0]["image"].get("mimeType") == "image/gif", str(identify)
assert identify[0]["image"].get("geometry") == {
"width": 60,
@@ -1993,8 +2083,8 @@ def gif_palette1_img(tmp_path_factory, tmp_palette1_png):
@pytest.fixture(scope="session")
def gif_palette2_img(tmp_path_factory, tmp_palette2_png):
in_img = tmp_path_factory.mktemp("gif_palette2_img") / "in.gif"
- subprocess.check_call(["convert", str(tmp_palette2_png), str(in_img)])
- identify = json.loads(subprocess.check_output(["convert", str(in_img), "json:"]))
+ subprocess.check_call(CONVERT + [str(tmp_palette2_png), str(in_img)])
+ identify = json.loads(subprocess.check_output(CONVERT + [str(in_img), "json:"]))
assert len(identify) == 1
# somewhere between imagemagick 6.9.7.4 and 6.9.9.34, the json output was
# put into an array, here we cater for the older version containing just
@@ -2003,10 +2093,6 @@ def gif_palette2_img(tmp_path_factory, tmp_palette2_png):
identify = [identify]
assert "image" in identify[0]
assert identify[0]["image"].get("format") == "GIF", str(identify)
- assert (
- identify[0]["image"]["formatDescription"]
- == "CompuServe graphics interchange format"
- ), str(identify)
assert identify[0]["image"].get("mimeType") == "image/gif", str(identify)
assert identify[0]["image"].get("geometry") == {
"width": 60,
@@ -2032,8 +2118,8 @@ def gif_palette2_img(tmp_path_factory, tmp_palette2_png):
@pytest.fixture(scope="session")
def gif_palette4_img(tmp_path_factory, tmp_palette4_png):
in_img = tmp_path_factory.mktemp("gif_palette4_img") / "in.gif"
- subprocess.check_call(["convert", str(tmp_palette4_png), str(in_img)])
- identify = json.loads(subprocess.check_output(["convert", str(in_img), "json:"]))
+ subprocess.check_call(CONVERT + [str(tmp_palette4_png), str(in_img)])
+ identify = json.loads(subprocess.check_output(CONVERT + [str(in_img), "json:"]))
assert len(identify) == 1
# somewhere between imagemagick 6.9.7.4 and 6.9.9.34, the json output was
# put into an array, here we cater for the older version containing just
@@ -2042,10 +2128,6 @@ def gif_palette4_img(tmp_path_factory, tmp_palette4_png):
identify = [identify]
assert "image" in identify[0]
assert identify[0]["image"].get("format") == "GIF", str(identify)
- assert (
- identify[0]["image"]["formatDescription"]
- == "CompuServe graphics interchange format"
- ), str(identify)
assert identify[0]["image"].get("mimeType") == "image/gif", str(identify)
assert identify[0]["image"].get("geometry") == {
"width": 60,
@@ -2071,8 +2153,8 @@ def gif_palette4_img(tmp_path_factory, tmp_palette4_png):
@pytest.fixture(scope="session")
def gif_palette8_img(tmp_path_factory, tmp_palette8_png):
in_img = tmp_path_factory.mktemp("gif_palette8_img") / "in.gif"
- subprocess.check_call(["convert", str(tmp_palette8_png), str(in_img)])
- identify = json.loads(subprocess.check_output(["convert", str(in_img), "json:"]))
+ subprocess.check_call(CONVERT + [str(tmp_palette8_png), str(in_img)])
+ identify = json.loads(subprocess.check_output(CONVERT + [str(in_img), "json:"]))
assert len(identify) == 1
# somewhere between imagemagick 6.9.7.4 and 6.9.9.34, the json output was
# put into an array, here we cater for the older version containing just
@@ -2081,10 +2163,6 @@ def gif_palette8_img(tmp_path_factory, tmp_palette8_png):
identify = [identify]
assert "image" in identify[0]
assert identify[0]["image"].get("format") == "GIF", str(identify)
- assert (
- identify[0]["image"]["formatDescription"]
- == "CompuServe graphics interchange format"
- ), str(identify)
assert identify[0]["image"].get("mimeType") == "image/gif", str(identify)
assert identify[0]["image"].get("geometry") == {
"width": 60,
@@ -2111,10 +2189,16 @@ def gif_palette8_img(tmp_path_factory, tmp_palette8_png):
def gif_animation_img(tmp_path_factory, tmp_normal_png, tmp_inverse_png):
in_img = tmp_path_factory.mktemp("gif_animation_img") / "in.gif"
subprocess.check_call(
- ["convert", str(tmp_normal_png), str(tmp_inverse_png), "-strip", str(in_img)]
+ CONVERT
+ + [
+ str(tmp_normal_png),
+ str(tmp_inverse_png),
+ "-strip",
+ str(in_img),
+ ]
)
identify = json.loads(
- subprocess.check_output(["convert", str(in_img) + "[0]", "json:"])
+ subprocess.check_output(CONVERT + [str(in_img) + "[0]", "json:"])
)
assert len(identify) == 1
# somewhere between imagemagick 6.9.7.4 and 6.9.9.34, the json output was
@@ -2124,10 +2208,6 @@ def gif_animation_img(tmp_path_factory, tmp_normal_png, tmp_inverse_png):
identify = [identify]
assert "image" in identify[0]
assert identify[0]["image"].get("format") == "GIF", str(identify)
- assert (
- identify[0]["image"]["formatDescription"]
- == "CompuServe graphics interchange format"
- ), str(identify)
assert identify[0]["image"].get("mimeType") == "image/gif", str(identify)
assert identify[0]["image"].get("geometry") == {
"width": 60,
@@ -2147,7 +2227,7 @@ def gif_animation_img(tmp_path_factory, tmp_normal_png, tmp_inverse_png):
}, str(identify)
assert identify[0]["image"].get("compression") == "LZW", str(identify)
identify = json.loads(
- subprocess.check_output(["convert", str(in_img) + "[1]", "json:"])
+ subprocess.check_output(CONVERT + [str(in_img) + "[1]", "json:"])
)
assert len(identify) == 1
# somewhere between imagemagick 6.9.7.4 and 6.9.9.34, the json output was
@@ -2157,10 +2237,6 @@ def gif_animation_img(tmp_path_factory, tmp_normal_png, tmp_inverse_png):
identify = [identify]
assert "image" in identify[0]
assert identify[0]["image"].get("format") == "GIF", str(identify)
- assert (
- identify[0]["image"]["formatDescription"]
- == "CompuServe graphics interchange format"
- ), str(identify)
assert identify[0]["image"].get("mimeType") == "image/gif", str(identify)
assert identify[0]["image"].get("geometry") == {
"width": 60,
@@ -2188,8 +2264,8 @@ def gif_animation_img(tmp_path_factory, tmp_normal_png, tmp_inverse_png):
def tiff_float_img(tmp_path_factory, tmp_normal_png):
in_img = tmp_path_factory.mktemp("tiff_float_img") / "in.tiff"
subprocess.check_call(
- [
- "convert",
+ CONVERT
+ + [
str(tmp_normal_png),
"-depth",
"32",
@@ -2198,7 +2274,7 @@ def tiff_float_img(tmp_path_factory, tmp_normal_png):
str(in_img),
]
)
- identify = json.loads(subprocess.check_output(["convert", str(in_img), "json:"]))
+ identify = json.loads(subprocess.check_output(CONVERT + [str(in_img), "json:"]))
assert len(identify) == 1
# somewhere between imagemagick 6.9.7.4 and 6.9.9.34, the json output was
# put into an array, here we cater for the older version containing just
@@ -2207,9 +2283,6 @@ def tiff_float_img(tmp_path_factory, tmp_normal_png):
identify = [identify]
assert "image" in identify[0]
assert identify[0]["image"].get("format") == "TIFF", str(identify)
- assert (
- identify[0]["image"].get("formatDescription") == "Tagged Image File Format"
- ), str(identify)
assert identify[0]["image"].get("mimeType") == "image/tiff", str(identify)
assert identify[0]["image"].get("geometry") == {
"width": 60,
@@ -2219,7 +2292,8 @@ def tiff_float_img(tmp_path_factory, tmp_normal_png):
}, str(identify)
assert identify[0]["image"].get("colorspace") == "sRGB", str(identify)
assert identify[0]["image"].get("type") == "TrueColor", str(identify)
- assert identify[0]["image"].get("endianess") in ["Undefined", "LSB",], str(
+ endian = "endianess" if identify[0].get("version", "0") < "1.0" else "endianness"
+ assert identify[0]["image"].get(endian) in ["Undefined", "LSB",], str(
identify
) # FIXME: should be LSB
assert identify[0]["image"].get("depth") == 8, str(identify)
@@ -2230,7 +2304,6 @@ def tiff_float_img(tmp_path_factory, tmp_normal_png):
"x": 0,
"y": 0,
}, str(identify)
- assert identify[0]["image"].get("compression") == "Zip", str(identify)
assert (
identify[0]["image"].get("properties", {}).get("quantum:format")
== "floating-point"
@@ -2252,9 +2325,17 @@ def tiff_float_img(tmp_path_factory, tmp_normal_png):
def tiff_cmyk8_img(tmp_path_factory, tmp_normal_png):
in_img = tmp_path_factory.mktemp("tiff_cmyk8") / "in.tiff"
subprocess.check_call(
- ["convert", str(tmp_normal_png), "-colorspace", "cmyk", str(in_img)]
+ CONVERT
+ + [
+ str(tmp_normal_png),
+ "-colorspace",
+ "cmyk",
+ "-compress",
+ "Zip",
+ str(in_img),
+ ]
)
- identify = json.loads(subprocess.check_output(["convert", str(in_img), "json:"]))
+ identify = json.loads(subprocess.check_output(CONVERT + [str(in_img), "json:"]))
assert len(identify) == 1
# somewhere between imagemagick 6.9.7.4 and 6.9.9.34, the json output was
# put into an array, here we cater for the older version containing just
@@ -2263,9 +2344,6 @@ def tiff_cmyk8_img(tmp_path_factory, tmp_normal_png):
identify = [identify]
assert "image" in identify[0]
assert identify[0]["image"].get("format") == "TIFF", str(identify)
- assert (
- identify[0]["image"].get("formatDescription") == "Tagged Image File Format"
- ), str(identify)
assert identify[0]["image"].get("mimeType") == "image/tiff", str(identify)
assert identify[0]["image"].get("geometry") == {
"width": 60,
@@ -2275,7 +2353,8 @@ def tiff_cmyk8_img(tmp_path_factory, tmp_normal_png):
}, str(identify)
assert identify[0]["image"].get("colorspace") == "CMYK", str(identify)
assert identify[0]["image"].get("type") == "ColorSeparation", str(identify)
- assert identify[0]["image"].get("endianess") in ["Undefined", "LSB",], str(
+ endian = "endianess" if identify[0].get("version", "0") < "1.0" else "endianness"
+ assert identify[0]["image"].get(endian) in ["Undefined", "LSB",], str(
identify
) # FIXME: should be LSB
assert identify[0]["image"].get("depth") == 8, str(identify)
@@ -2285,7 +2364,6 @@ def tiff_cmyk8_img(tmp_path_factory, tmp_normal_png):
"x": 0,
"y": 0,
}, str(identify)
- assert identify[0]["image"].get("compression") == "Zip", str(identify)
assert (
identify[0]["image"].get("properties", {}).get("tiff:alpha") == "unspecified"
), str(identify)
@@ -2304,17 +2382,19 @@ def tiff_cmyk8_img(tmp_path_factory, tmp_normal_png):
def tiff_cmyk16_img(tmp_path_factory, tmp_normal_png):
in_img = tmp_path_factory.mktemp("tiff_cmyk16") / "in.tiff"
subprocess.check_call(
- [
- "convert",
+ CONVERT
+ + [
str(tmp_normal_png),
"-depth",
"16",
"-colorspace",
"cmyk",
+ "-compress",
+ "Zip",
str(in_img),
]
)
- identify = json.loads(subprocess.check_output(["convert", str(in_img), "json:"]))
+ identify = json.loads(subprocess.check_output(CONVERT + [str(in_img), "json:"]))
assert len(identify) == 1
# somewhere between imagemagick 6.9.7.4 and 6.9.9.34, the json output was
# put into an array, here we cater for the older version containing just
@@ -2323,9 +2403,6 @@ def tiff_cmyk16_img(tmp_path_factory, tmp_normal_png):
identify = [identify]
assert "image" in identify[0]
assert identify[0]["image"].get("format") == "TIFF", str(identify)
- assert (
- identify[0]["image"].get("formatDescription") == "Tagged Image File Format"
- ), str(identify)
assert identify[0]["image"].get("mimeType") == "image/tiff", str(identify)
assert identify[0]["image"].get("geometry") == {
"width": 60,
@@ -2335,7 +2412,8 @@ def tiff_cmyk16_img(tmp_path_factory, tmp_normal_png):
}, str(identify)
assert identify[0]["image"].get("colorspace") == "CMYK", str(identify)
assert identify[0]["image"].get("type") == "ColorSeparation", str(identify)
- assert identify[0]["image"].get("endianess") in ["Undefined", "LSB",], str(
+ endian = "endianess" if identify[0].get("version", "0") < "1.0" else "endianness"
+ assert identify[0]["image"].get(endian) in ["Undefined", "LSB",], str(
identify
) # FIXME: should be LSB
assert identify[0]["image"].get("depth") == 16, str(identify)
@@ -2345,7 +2423,6 @@ def tiff_cmyk16_img(tmp_path_factory, tmp_normal_png):
"x": 0,
"y": 0,
}, str(identify)
- assert identify[0]["image"].get("compression") == "Zip", str(identify)
assert (
identify[0]["image"].get("properties", {}).get("tiff:alpha") == "unspecified"
), str(identify)
@@ -2363,8 +2440,10 @@ def tiff_cmyk16_img(tmp_path_factory, tmp_normal_png):
@pytest.fixture(scope="session")
def tiff_rgb8_img(tmp_path_factory, tmp_normal_png):
in_img = tmp_path_factory.mktemp("tiff_rgb8") / "in.tiff"
- subprocess.check_call(["convert", str(tmp_normal_png), str(in_img)])
- identify = json.loads(subprocess.check_output(["convert", str(in_img), "json:"]))
+ subprocess.check_call(
+ CONVERT + [str(tmp_normal_png), "-compress", "Zip", str(in_img)]
+ )
+ identify = json.loads(subprocess.check_output(CONVERT + [str(in_img), "json:"]))
assert len(identify) == 1
# somewhere between imagemagick 6.9.7.4 and 6.9.9.34, the json output was
# put into an array, here we cater for the older version containing just
@@ -2373,9 +2452,6 @@ def tiff_rgb8_img(tmp_path_factory, tmp_normal_png):
identify = [identify]
assert "image" in identify[0]
assert identify[0]["image"].get("format") == "TIFF", str(identify)
- assert (
- identify[0]["image"].get("formatDescription") == "Tagged Image File Format"
- ), str(identify)
assert identify[0]["image"].get("mimeType") == "image/tiff", str(identify)
assert identify[0]["image"].get("geometry") == {
"width": 60,
@@ -2385,7 +2461,8 @@ def tiff_rgb8_img(tmp_path_factory, tmp_normal_png):
}, str(identify)
assert identify[0]["image"].get("colorspace") == "sRGB", str(identify)
assert identify[0]["image"].get("type") == "TrueColor", str(identify)
- assert identify[0]["image"].get("endianess") in ["Undefined", "LSB",], str(
+ endian = "endianess" if identify[0].get("version", "0") < "1.0" else "endianness"
+ assert identify[0]["image"].get(endian) in ["Undefined", "LSB",], str(
identify
) # FIXME: should be LSB
assert identify[0]["image"].get("depth") == 8, str(identify)
@@ -2395,7 +2472,6 @@ def tiff_rgb8_img(tmp_path_factory, tmp_normal_png):
"x": 0,
"y": 0,
}, str(identify)
- assert identify[0]["image"].get("compression") == "Zip", str(identify)
assert (
identify[0]["image"].get("properties", {}).get("tiff:alpha") == "unspecified"
), str(identify)
@@ -2413,9 +2489,17 @@ def tiff_rgb8_img(tmp_path_factory, tmp_normal_png):
def tiff_rgb12_img(tmp_path_factory, tmp_normal16_png):
in_img = tmp_path_factory.mktemp("tiff_rgb8") / "in.tiff"
subprocess.check_call(
- ["convert", str(tmp_normal16_png), "-depth", "12", str(in_img)]
+ CONVERT
+ + [
+ str(tmp_normal16_png),
+ "-depth",
+ "12",
+ "-compress",
+ "Zip",
+ str(in_img),
+ ]
)
- identify = json.loads(subprocess.check_output(["convert", str(in_img), "json:"]))
+ identify = json.loads(subprocess.check_output(CONVERT + [str(in_img), "json:"]))
assert len(identify) == 1
# somewhere between imagemagick 6.9.7.4 and 6.9.9.34, the json output was
# put into an array, here we cater for the older version containing just
@@ -2424,9 +2508,6 @@ def tiff_rgb12_img(tmp_path_factory, tmp_normal16_png):
identify = [identify]
assert "image" in identify[0]
assert identify[0]["image"].get("format") == "TIFF", str(identify)
- assert (
- identify[0]["image"].get("formatDescription") == "Tagged Image File Format"
- ), str(identify)
assert identify[0]["image"].get("mimeType") == "image/tiff", str(identify)
assert identify[0]["image"].get("geometry") == {
"width": 60,
@@ -2436,17 +2517,21 @@ def tiff_rgb12_img(tmp_path_factory, tmp_normal16_png):
}, str(identify)
assert identify[0]["image"].get("colorspace") == "sRGB", str(identify)
assert identify[0]["image"].get("type") == "TrueColor", str(identify)
- assert identify[0]["image"].get("endianess") in ["Undefined", "LSB",], str(
+ endian = "endianess" if identify[0].get("version", "0") < "1.0" else "endianness"
+ assert identify[0]["image"].get(endian) in ["Undefined", "LSB",], str(
identify
) # FIXME: should be LSB
- assert identify[0]["image"].get("depth") == 12, str(identify)
+ if identify[0].get("version", "0") < "1.0":
+ assert identify[0]["image"].get("depth") == 12, str(identify)
+ else:
+ assert identify[0]["image"].get("depth") == 16, str(identify)
+ assert identify[0]["image"].get("baseDepth") == 12, str(identify)
assert identify[0]["image"].get("pageGeometry") == {
"width": 60,
"height": 60,
"x": 0,
"y": 0,
}, str(identify)
- assert identify[0]["image"].get("compression") == "Zip", str(identify)
assert (
identify[0]["image"].get("properties", {}).get("tiff:alpha") == "unspecified"
), str(identify)
@@ -2464,9 +2549,17 @@ def tiff_rgb12_img(tmp_path_factory, tmp_normal16_png):
def tiff_rgb14_img(tmp_path_factory, tmp_normal16_png):
in_img = tmp_path_factory.mktemp("tiff_rgb8") / "in.tiff"
subprocess.check_call(
- ["convert", str(tmp_normal16_png), "-depth", "14", str(in_img)]
+ CONVERT
+ + [
+ str(tmp_normal16_png),
+ "-depth",
+ "14",
+ "-compress",
+ "Zip",
+ str(in_img),
+ ]
)
- identify = json.loads(subprocess.check_output(["convert", str(in_img), "json:"]))
+ identify = json.loads(subprocess.check_output(CONVERT + [str(in_img), "json:"]))
assert len(identify) == 1
# somewhere between imagemagick 6.9.7.4 and 6.9.9.34, the json output was
# put into an array, here we cater for the older version containing just
@@ -2475,9 +2568,6 @@ def tiff_rgb14_img(tmp_path_factory, tmp_normal16_png):
identify = [identify]
assert "image" in identify[0]
assert identify[0]["image"].get("format") == "TIFF", str(identify)
- assert (
- identify[0]["image"].get("formatDescription") == "Tagged Image File Format"
- ), str(identify)
assert identify[0]["image"].get("mimeType") == "image/tiff", str(identify)
assert identify[0]["image"].get("geometry") == {
"width": 60,
@@ -2487,17 +2577,18 @@ def tiff_rgb14_img(tmp_path_factory, tmp_normal16_png):
}, str(identify)
assert identify[0]["image"].get("colorspace") == "sRGB", str(identify)
assert identify[0]["image"].get("type") == "TrueColor", str(identify)
- assert identify[0]["image"].get("endianess") in ["Undefined", "LSB",], str(
+ endian = "endianess" if identify[0].get("version", "0") < "1.0" else "endianness"
+ assert identify[0]["image"].get(endian) in ["Undefined", "LSB",], str(
identify
) # FIXME: should be LSB
- assert identify[0]["image"].get("depth") == 14, str(identify)
+ assert identify[0]["image"].get("depth") == 16, str(identify)
+ assert identify[0]["image"].get("baseDepth") == 14, str(identify)
assert identify[0]["image"].get("pageGeometry") == {
"width": 60,
"height": 60,
"x": 0,
"y": 0,
}, str(identify)
- assert identify[0]["image"].get("compression") == "Zip", str(identify)
assert (
identify[0]["image"].get("properties", {}).get("tiff:alpha") == "unspecified"
), str(identify)
@@ -2515,9 +2606,17 @@ def tiff_rgb14_img(tmp_path_factory, tmp_normal16_png):
def tiff_rgb16_img(tmp_path_factory, tmp_normal16_png):
in_img = tmp_path_factory.mktemp("tiff_rgb8") / "in.tiff"
subprocess.check_call(
- ["convert", str(tmp_normal16_png), "-depth", "16", str(in_img)]
+ CONVERT
+ + [
+ str(tmp_normal16_png),
+ "-depth",
+ "16",
+ "-compress",
+ "Zip",
+ str(in_img),
+ ]
)
- identify = json.loads(subprocess.check_output(["convert", str(in_img), "json:"]))
+ identify = json.loads(subprocess.check_output(CONVERT + [str(in_img), "json:"]))
assert len(identify) == 1
# somewhere between imagemagick 6.9.7.4 and 6.9.9.34, the json output was
# put into an array, here we cater for the older version containing just
@@ -2526,9 +2625,6 @@ def tiff_rgb16_img(tmp_path_factory, tmp_normal16_png):
identify = [identify]
assert "image" in identify[0]
assert identify[0]["image"].get("format") == "TIFF", str(identify)
- assert (
- identify[0]["image"].get("formatDescription") == "Tagged Image File Format"
- ), str(identify)
assert identify[0]["image"].get("mimeType") == "image/tiff", str(identify)
assert identify[0]["image"].get("geometry") == {
"width": 60,
@@ -2538,7 +2634,8 @@ def tiff_rgb16_img(tmp_path_factory, tmp_normal16_png):
}, str(identify)
assert identify[0]["image"].get("colorspace") == "sRGB", str(identify)
assert identify[0]["image"].get("type") == "TrueColor", str(identify)
- assert identify[0]["image"].get("endianess") in ["Undefined", "LSB",], str(
+ endian = "endianess" if identify[0].get("version", "0") < "1.0" else "endianness"
+ assert identify[0]["image"].get(endian) in ["Undefined", "LSB",], str(
identify
) # FIXME: should be LSB
assert identify[0]["image"].get("depth") == 16, str(identify)
@@ -2548,7 +2645,6 @@ def tiff_rgb16_img(tmp_path_factory, tmp_normal16_png):
"x": 0,
"y": 0,
}, str(identify)
- assert identify[0]["image"].get("compression") == "Zip", str(identify)
assert (
identify[0]["image"].get("properties", {}).get("tiff:alpha") == "unspecified"
), str(identify)
@@ -2566,9 +2662,18 @@ def tiff_rgb16_img(tmp_path_factory, tmp_normal16_png):
def tiff_rgba8_img(tmp_path_factory, tmp_alpha_png):
in_img = tmp_path_factory.mktemp("tiff_rgba8") / "in.tiff"
subprocess.check_call(
- ["convert", str(tmp_alpha_png), "-depth", "8", "-strip", str(in_img)]
+ CONVERT
+ + [
+ str(tmp_alpha_png),
+ "-depth",
+ "8",
+ "-strip",
+ "-compress",
+ "Zip",
+ str(in_img),
+ ]
)
- identify = json.loads(subprocess.check_output(["convert", str(in_img), "json:"]))
+ identify = json.loads(subprocess.check_output(CONVERT + [str(in_img), "json:"]))
assert len(identify) == 1
# somewhere between imagemagick 6.9.7.4 and 6.9.9.34, the json output was
# put into an array, here we cater for the older version containing just
@@ -2577,9 +2682,6 @@ def tiff_rgba8_img(tmp_path_factory, tmp_alpha_png):
identify = [identify]
assert "image" in identify[0]
assert identify[0]["image"].get("format") == "TIFF", str(identify)
- assert (
- identify[0]["image"].get("formatDescription") == "Tagged Image File Format"
- ), str(identify)
assert identify[0]["image"].get("mimeType") == "image/tiff", str(identify)
assert identify[0]["image"].get("geometry") == {
"width": 60,
@@ -2589,7 +2691,8 @@ def tiff_rgba8_img(tmp_path_factory, tmp_alpha_png):
}, str(identify)
assert identify[0]["image"].get("colorspace") == "sRGB", str(identify)
assert identify[0]["image"].get("type") == "TrueColorAlpha", str(identify)
- assert identify[0]["image"].get("endianess") in ["Undefined", "LSB",], str(
+ endian = "endianess" if identify[0].get("version", "0") < "1.0" else "endianness"
+ assert identify[0]["image"].get(endian) in ["Undefined", "LSB",], str(
identify
) # FIXME: should be LSB
assert identify[0]["image"].get("depth") == 8, str(identify)
@@ -2599,7 +2702,6 @@ def tiff_rgba8_img(tmp_path_factory, tmp_alpha_png):
"x": 0,
"y": 0,
}, str(identify)
- assert identify[0]["image"].get("compression") == "Zip", str(identify)
assert (
identify[0]["image"].get("properties", {}).get("tiff:alpha") == "unassociated"
), str(identify)
@@ -2617,9 +2719,18 @@ def tiff_rgba8_img(tmp_path_factory, tmp_alpha_png):
def tiff_rgba16_img(tmp_path_factory, tmp_alpha_png):
in_img = tmp_path_factory.mktemp("tiff_rgba16") / "in.tiff"
subprocess.check_call(
- ["convert", str(tmp_alpha_png), "-depth", "16", "-strip", str(in_img)]
+ CONVERT
+ + [
+ str(tmp_alpha_png),
+ "-depth",
+ "16",
+ "-strip",
+ "-compress",
+ "Zip",
+ str(in_img),
+ ]
)
- identify = json.loads(subprocess.check_output(["convert", str(in_img), "json:"]))
+ identify = json.loads(subprocess.check_output(CONVERT + [str(in_img), "json:"]))
assert len(identify) == 1
# somewhere between imagemagick 6.9.7.4 and 6.9.9.34, the json output was
# put into an array, here we cater for the older version containing just
@@ -2628,9 +2739,6 @@ def tiff_rgba16_img(tmp_path_factory, tmp_alpha_png):
identify = [identify]
assert "image" in identify[0]
assert identify[0]["image"].get("format") == "TIFF", str(identify)
- assert (
- identify[0]["image"].get("formatDescription") == "Tagged Image File Format"
- ), str(identify)
assert identify[0]["image"].get("mimeType") == "image/tiff", str(identify)
assert identify[0]["image"].get("geometry") == {
"width": 60,
@@ -2640,7 +2748,8 @@ def tiff_rgba16_img(tmp_path_factory, tmp_alpha_png):
}, str(identify)
assert identify[0]["image"].get("colorspace") == "sRGB", str(identify)
assert identify[0]["image"].get("type") == "TrueColorAlpha", str(identify)
- assert identify[0]["image"].get("endianess") in ["Undefined", "LSB",], str(
+ endian = "endianess" if identify[0].get("version", "0") < "1.0" else "endianness"
+ assert identify[0]["image"].get(endian) in ["Undefined", "LSB",], str(
identify
) # FIXME: should be LSB
assert identify[0]["image"].get("depth") == 16, str(identify)
@@ -2650,7 +2759,6 @@ def tiff_rgba16_img(tmp_path_factory, tmp_alpha_png):
"x": 0,
"y": 0,
}, str(identify)
- assert identify[0]["image"].get("compression") == "Zip", str(identify)
assert (
identify[0]["image"].get("properties", {}).get("tiff:alpha") == "unassociated"
), str(identify)
@@ -2667,8 +2775,18 @@ def tiff_rgba16_img(tmp_path_factory, tmp_alpha_png):
@pytest.fixture(scope="session")
def tiff_gray1_img(tmp_path_factory, tmp_gray1_png):
in_img = tmp_path_factory.mktemp("tiff_gray1") / "in.tiff"
- subprocess.check_call(["convert", str(tmp_gray1_png), "-depth", "1", str(in_img)])
- identify = json.loads(subprocess.check_output(["convert", str(in_img), "json:"]))
+ subprocess.check_call(
+ CONVERT
+ + [
+ str(tmp_gray1_png),
+ "-depth",
+ "1",
+ "-compress",
+ "Zip",
+ str(in_img),
+ ]
+ )
+ identify = json.loads(subprocess.check_output(CONVERT + [str(in_img), "json:"]))
assert len(identify) == 1
# somewhere between imagemagick 6.9.7.4 and 6.9.9.34, the json output was
# put into an array, here we cater for the older version containing just
@@ -2677,9 +2795,6 @@ def tiff_gray1_img(tmp_path_factory, tmp_gray1_png):
identify = [identify]
assert "image" in identify[0]
assert identify[0]["image"].get("format") == "TIFF", str(identify)
- assert (
- identify[0]["image"].get("formatDescription") == "Tagged Image File Format"
- ), str(identify)
assert identify[0]["image"].get("mimeType") == "image/tiff", str(identify)
assert identify[0]["image"].get("geometry") == {
"width": 60,
@@ -2689,7 +2804,8 @@ def tiff_gray1_img(tmp_path_factory, tmp_gray1_png):
}, str(identify)
assert identify[0]["image"].get("colorspace") == "Gray", str(identify)
assert identify[0]["image"].get("type") == "Bilevel", str(identify)
- assert identify[0]["image"].get("endianess") in ["Undefined", "LSB",], str(
+ endian = "endianess" if identify[0].get("version", "0") < "1.0" else "endianness"
+ assert identify[0]["image"].get(endian) in ["Undefined", "LSB",], str(
identify
) # FIXME: should be LSB
assert identify[0]["image"].get("depth") == 1, str(identify)
@@ -2699,7 +2815,6 @@ def tiff_gray1_img(tmp_path_factory, tmp_gray1_png):
"x": 0,
"y": 0,
}, str(identify)
- assert identify[0]["image"].get("compression") == "Zip", str(identify)
assert (
identify[0]["image"].get("properties", {}).get("tiff:alpha") == "unspecified"
), str(identify)
@@ -2717,8 +2832,18 @@ def tiff_gray1_img(tmp_path_factory, tmp_gray1_png):
@pytest.fixture(scope="session")
def tiff_gray2_img(tmp_path_factory, tmp_gray2_png):
in_img = tmp_path_factory.mktemp("tiff_gray2") / "in.tiff"
- subprocess.check_call(["convert", str(tmp_gray2_png), "-depth", "2", str(in_img)])
- identify = json.loads(subprocess.check_output(["convert", str(in_img), "json:"]))
+ subprocess.check_call(
+ CONVERT
+ + [
+ str(tmp_gray2_png),
+ "-depth",
+ "2",
+ "-compress",
+ "Zip",
+ str(in_img),
+ ]
+ )
+ identify = json.loads(subprocess.check_output(CONVERT + [str(in_img), "json:"]))
assert len(identify) == 1
# somewhere between imagemagick 6.9.7.4 and 6.9.9.34, the json output was
# put into an array, here we cater for the older version containing just
@@ -2727,9 +2852,6 @@ def tiff_gray2_img(tmp_path_factory, tmp_gray2_png):
identify = [identify]
assert "image" in identify[0]
assert identify[0]["image"].get("format") == "TIFF", str(identify)
- assert (
- identify[0]["image"].get("formatDescription") == "Tagged Image File Format"
- ), str(identify)
assert identify[0]["image"].get("mimeType") == "image/tiff", str(identify)
assert identify[0]["image"].get("geometry") == {
"width": 60,
@@ -2739,7 +2861,8 @@ def tiff_gray2_img(tmp_path_factory, tmp_gray2_png):
}, str(identify)
assert identify[0]["image"].get("colorspace") == "Gray", str(identify)
assert identify[0]["image"].get("type") == "Grayscale", str(identify)
- assert identify[0]["image"].get("endianess") in ["Undefined", "LSB",], str(
+ endian = "endianess" if identify[0].get("version", "0") < "1.0" else "endianness"
+ assert identify[0]["image"].get(endian) in ["Undefined", "LSB",], str(
identify
) # FIXME: should be LSB
assert identify[0]["image"].get("depth") == 2, str(identify)
@@ -2749,7 +2872,6 @@ def tiff_gray2_img(tmp_path_factory, tmp_gray2_png):
"x": 0,
"y": 0,
}, str(identify)
- assert identify[0]["image"].get("compression") == "Zip", str(identify)
assert (
identify[0]["image"].get("properties", {}).get("tiff:alpha") == "unspecified"
), str(identify)
@@ -2767,8 +2889,18 @@ def tiff_gray2_img(tmp_path_factory, tmp_gray2_png):
@pytest.fixture(scope="session")
def tiff_gray4_img(tmp_path_factory, tmp_gray4_png):
in_img = tmp_path_factory.mktemp("tiff_gray4") / "in.tiff"
- subprocess.check_call(["convert", str(tmp_gray4_png), "-depth", "4", str(in_img)])
- identify = json.loads(subprocess.check_output(["convert", str(in_img), "json:"]))
+ subprocess.check_call(
+ CONVERT
+ + [
+ str(tmp_gray4_png),
+ "-depth",
+ "4",
+ "-compress",
+ "Zip",
+ str(in_img),
+ ]
+ )
+ identify = json.loads(subprocess.check_output(CONVERT + [str(in_img), "json:"]))
assert len(identify) == 1
# somewhere between imagemagick 6.9.7.4 and 6.9.9.34, the json output was
# put into an array, here we cater for the older version containing just
@@ -2777,9 +2909,6 @@ def tiff_gray4_img(tmp_path_factory, tmp_gray4_png):
identify = [identify]
assert "image" in identify[0]
assert identify[0]["image"].get("format") == "TIFF", str(identify)
- assert (
- identify[0]["image"].get("formatDescription") == "Tagged Image File Format"
- ), str(identify)
assert identify[0]["image"].get("mimeType") == "image/tiff", str(identify)
assert identify[0]["image"].get("geometry") == {
"width": 60,
@@ -2789,7 +2918,8 @@ def tiff_gray4_img(tmp_path_factory, tmp_gray4_png):
}, str(identify)
assert identify[0]["image"].get("colorspace") == "Gray", str(identify)
assert identify[0]["image"].get("type") == "Grayscale", str(identify)
- assert identify[0]["image"].get("endianess") in ["Undefined", "LSB",], str(
+ endian = "endianess" if identify[0].get("version", "0") < "1.0" else "endianness"
+ assert identify[0]["image"].get(endian) in ["Undefined", "LSB",], str(
identify
) # FIXME: should be LSB
assert identify[0]["image"].get("depth") == 4, str(identify)
@@ -2799,7 +2929,6 @@ def tiff_gray4_img(tmp_path_factory, tmp_gray4_png):
"x": 0,
"y": 0,
}, str(identify)
- assert identify[0]["image"].get("compression") == "Zip", str(identify)
assert (
identify[0]["image"].get("properties", {}).get("tiff:alpha") == "unspecified"
), str(identify)
@@ -2817,8 +2946,18 @@ def tiff_gray4_img(tmp_path_factory, tmp_gray4_png):
@pytest.fixture(scope="session")
def tiff_gray8_img(tmp_path_factory, tmp_gray8_png):
in_img = tmp_path_factory.mktemp("tiff_gray8") / "in.tiff"
- subprocess.check_call(["convert", str(tmp_gray8_png), "-depth", "8", str(in_img)])
- identify = json.loads(subprocess.check_output(["convert", str(in_img), "json:"]))
+ subprocess.check_call(
+ CONVERT
+ + [
+ str(tmp_gray8_png),
+ "-depth",
+ "8",
+ "-compress",
+ "Zip",
+ str(in_img),
+ ]
+ )
+ identify = json.loads(subprocess.check_output(CONVERT + [str(in_img), "json:"]))
assert len(identify) == 1
# somewhere between imagemagick 6.9.7.4 and 6.9.9.34, the json output was
# put into an array, here we cater for the older version containing just
@@ -2827,9 +2966,6 @@ def tiff_gray8_img(tmp_path_factory, tmp_gray8_png):
identify = [identify]
assert "image" in identify[0]
assert identify[0]["image"].get("format") == "TIFF", str(identify)
- assert (
- identify[0]["image"].get("formatDescription") == "Tagged Image File Format"
- ), str(identify)
assert identify[0]["image"].get("mimeType") == "image/tiff", str(identify)
assert identify[0]["image"].get("geometry") == {
"width": 60,
@@ -2839,7 +2975,8 @@ def tiff_gray8_img(tmp_path_factory, tmp_gray8_png):
}, str(identify)
assert identify[0]["image"].get("colorspace") == "Gray", str(identify)
assert identify[0]["image"].get("type") == "Grayscale", str(identify)
- assert identify[0]["image"].get("endianess") in ["Undefined", "LSB",], str(
+ endian = "endianess" if identify[0].get("version", "0") < "1.0" else "endianness"
+ assert identify[0]["image"].get(endian) in ["Undefined", "LSB",], str(
identify
) # FIXME: should be LSB
assert identify[0]["image"].get("depth") == 8, str(identify)
@@ -2849,7 +2986,6 @@ def tiff_gray8_img(tmp_path_factory, tmp_gray8_png):
"x": 0,
"y": 0,
}, str(identify)
- assert identify[0]["image"].get("compression") == "Zip", str(identify)
assert (
identify[0]["image"].get("properties", {}).get("tiff:alpha") == "unspecified"
), str(identify)
@@ -2867,8 +3003,18 @@ def tiff_gray8_img(tmp_path_factory, tmp_gray8_png):
@pytest.fixture(scope="session")
def tiff_gray16_img(tmp_path_factory, tmp_gray16_png):
in_img = tmp_path_factory.mktemp("tiff_gray16") / "in.tiff"
- subprocess.check_call(["convert", str(tmp_gray16_png), "-depth", "16", str(in_img)])
- identify = json.loads(subprocess.check_output(["convert", str(in_img), "json:"]))
+ subprocess.check_call(
+ CONVERT
+ + [
+ str(tmp_gray16_png),
+ "-depth",
+ "16",
+ "-compress",
+ "Zip",
+ str(in_img),
+ ]
+ )
+ identify = json.loads(subprocess.check_output(CONVERT + [str(in_img), "json:"]))
assert len(identify) == 1
# somewhere between imagemagick 6.9.7.4 and 6.9.9.34, the json output was
# put into an array, here we cater for the older version containing just
@@ -2877,9 +3023,6 @@ def tiff_gray16_img(tmp_path_factory, tmp_gray16_png):
identify = [identify]
assert "image" in identify[0]
assert identify[0]["image"].get("format") == "TIFF", str(identify)
- assert (
- identify[0]["image"].get("formatDescription") == "Tagged Image File Format"
- ), str(identify)
assert identify[0]["image"].get("mimeType") == "image/tiff", str(identify)
assert identify[0]["image"].get("geometry") == {
"width": 60,
@@ -2889,7 +3032,8 @@ def tiff_gray16_img(tmp_path_factory, tmp_gray16_png):
}, str(identify)
assert identify[0]["image"].get("colorspace") == "Gray", str(identify)
assert identify[0]["image"].get("type") == "Grayscale", str(identify)
- assert identify[0]["image"].get("endianess") in ["Undefined", "LSB",], str(
+ endian = "endianess" if identify[0].get("version", "0") < "1.0" else "endianness"
+ assert identify[0]["image"].get(endian) in ["Undefined", "LSB",], str(
identify
) # FIXME: should be LSB
assert identify[0]["image"].get("depth") == 16, str(identify)
@@ -2899,7 +3043,6 @@ def tiff_gray16_img(tmp_path_factory, tmp_gray16_png):
"x": 0,
"y": 0,
}, str(identify)
- assert identify[0]["image"].get("compression") == "Zip", str(identify)
assert (
identify[0]["image"].get("properties", {}).get("tiff:alpha") == "unspecified"
), str(identify)
@@ -2918,10 +3061,18 @@ def tiff_gray16_img(tmp_path_factory, tmp_gray16_png):
def tiff_multipage_img(tmp_path_factory, tmp_normal_png, tmp_inverse_png):
in_img = tmp_path_factory.mktemp("tiff_multipage_img") / "in.tiff"
subprocess.check_call(
- ["convert", str(tmp_normal_png), str(tmp_inverse_png), "-strip", str(in_img)]
+ CONVERT
+ + [
+ str(tmp_normal_png),
+ str(tmp_inverse_png),
+ "-strip",
+ "-compress",
+ "Zip",
+ str(in_img),
+ ]
)
identify = json.loads(
- subprocess.check_output(["convert", str(in_img) + "[0]", "json:"])
+ subprocess.check_output(CONVERT + [str(in_img) + "[0]", "json:"])
)
assert len(identify) == 1
# somewhere between imagemagick 6.9.7.4 and 6.9.9.34, the json output was
@@ -2931,9 +3082,6 @@ def tiff_multipage_img(tmp_path_factory, tmp_normal_png, tmp_inverse_png):
identify = [identify]
assert "image" in identify[0]
assert identify[0]["image"].get("format") == "TIFF", str(identify)
- assert (
- identify[0]["image"].get("formatDescription") == "Tagged Image File Format"
- ), str(identify)
assert identify[0]["image"].get("mimeType") == "image/tiff", str(identify)
assert identify[0]["image"].get("geometry") == {
"width": 60,
@@ -2943,7 +3091,8 @@ def tiff_multipage_img(tmp_path_factory, tmp_normal_png, tmp_inverse_png):
}, str(identify)
assert identify[0]["image"].get("colorspace") == "sRGB", str(identify)
assert identify[0]["image"].get("type") == "TrueColor", str(identify)
- assert identify[0]["image"].get("endianess") in ["Undefined", "LSB",], str(
+ endian = "endianess" if identify[0].get("version", "0") < "1.0" else "endianness"
+ assert identify[0]["image"].get(endian) in ["Undefined", "LSB",], str(
identify
) # FIXME: should be LSB
assert identify[0]["image"].get("depth") == 8, str(identify)
@@ -2953,7 +3102,6 @@ def tiff_multipage_img(tmp_path_factory, tmp_normal_png, tmp_inverse_png):
"x": 0,
"y": 0,
}, str(identify)
- assert identify[0]["image"].get("compression") == "Zip", str(identify)
assert (
identify[0]["image"].get("properties", {}).get("tiff:alpha") == "unspecified"
), str(identify)
@@ -2964,7 +3112,7 @@ def tiff_multipage_img(tmp_path_factory, tmp_normal_png, tmp_inverse_png):
identify[0]["image"].get("properties", {}).get("tiff:photometric") == "RGB"
), str(identify)
identify = json.loads(
- subprocess.check_output(["convert", str(in_img) + "[1]", "json:"])
+ subprocess.check_output(CONVERT + [str(in_img) + "[1]", "json:"])
)
assert len(identify) == 1
# somewhere between imagemagick 6.9.7.4 and 6.9.9.34, the json output was
@@ -2974,9 +3122,6 @@ def tiff_multipage_img(tmp_path_factory, tmp_normal_png, tmp_inverse_png):
identify = [identify]
assert "image" in identify[0]
assert identify[0]["image"].get("format") == "TIFF", str(identify)
- assert (
- identify[0]["image"].get("formatDescription") == "Tagged Image File Format"
- ), str(identify)
assert identify[0]["image"].get("mimeType") == "image/tiff", str(identify)
assert identify[0]["image"].get("geometry") == {
"width": 60,
@@ -2986,7 +3131,8 @@ def tiff_multipage_img(tmp_path_factory, tmp_normal_png, tmp_inverse_png):
}, str(identify)
assert identify[0]["image"].get("colorspace") == "sRGB", str(identify)
assert identify[0]["image"].get("type") == "TrueColor", str(identify)
- assert identify[0]["image"].get("endianess") in ["Undefined", "LSB",], str(
+ endian = "endianess" if identify[0].get("version", "0") < "1.0" else "endianness"
+ assert identify[0]["image"].get(endian) in ["Undefined", "LSB",], str(
identify
) # FIXME: should be LSB
assert identify[0]["image"].get("depth") == 8, str(identify)
@@ -2996,7 +3142,6 @@ def tiff_multipage_img(tmp_path_factory, tmp_normal_png, tmp_inverse_png):
"x": 0,
"y": 0,
}, str(identify)
- assert identify[0]["image"].get("compression") == "Zip", str(identify)
assert (
identify[0]["image"].get("properties", {}).get("tiff:alpha") == "unspecified"
), str(identify)
@@ -3014,8 +3159,10 @@ def tiff_multipage_img(tmp_path_factory, tmp_normal_png, tmp_inverse_png):
@pytest.fixture(scope="session")
def tiff_palette1_img(tmp_path_factory, tmp_palette1_png):
in_img = tmp_path_factory.mktemp("tiff_palette1_img") / "in.tiff"
- subprocess.check_call(["convert", str(tmp_palette1_png), str(in_img)])
- identify = json.loads(subprocess.check_output(["convert", str(in_img), "json:"]))
+ subprocess.check_call(
+ CONVERT + [str(tmp_palette1_png), "-compress", "Zip", str(in_img)]
+ )
+ identify = json.loads(subprocess.check_output(CONVERT + [str(in_img), "json:"]))
assert len(identify) == 1
# somewhere between imagemagick 6.9.7.4 and 6.9.9.34, the json output was
# put into an array, here we cater for the older version containing just
@@ -3024,9 +3171,6 @@ def tiff_palette1_img(tmp_path_factory, tmp_palette1_png):
identify = [identify]
assert "image" in identify[0]
assert identify[0]["image"].get("format") == "TIFF", str(identify)
- assert (
- identify[0]["image"].get("formatDescription") == "Tagged Image File Format"
- ), str(identify)
assert identify[0]["image"].get("mimeType") == "image/tiff", str(identify)
assert identify[0]["image"].get("geometry") == {
"width": 60,
@@ -3036,7 +3180,8 @@ def tiff_palette1_img(tmp_path_factory, tmp_palette1_png):
}, str(identify)
assert identify[0]["image"].get("colorspace") == "sRGB", str(identify)
assert identify[0]["image"].get("type") == "Palette", str(identify)
- assert identify[0]["image"].get("endianess") in ["Undefined", "LSB",], str(
+ endian = "endianess" if identify[0].get("version", "0") < "1.0" else "endianness"
+ assert identify[0]["image"].get(endian) in ["Undefined", "LSB",], str(
identify
) # FIXME: should be LSB
assert identify[0]["image"].get("depth") == 8, str(identify)
@@ -3048,7 +3193,6 @@ def tiff_palette1_img(tmp_path_factory, tmp_palette1_png):
"x": 0,
"y": 0,
}, str(identify)
- assert identify[0]["image"].get("compression") == "Zip", str(identify)
assert (
identify[0]["image"].get("properties", {}).get("tiff:alpha") == "unspecified"
), str(identify)
@@ -3065,8 +3209,10 @@ def tiff_palette1_img(tmp_path_factory, tmp_palette1_png):
@pytest.fixture(scope="session")
def tiff_palette2_img(tmp_path_factory, tmp_palette2_png):
in_img = tmp_path_factory.mktemp("tiff_palette2_img") / "in.tiff"
- subprocess.check_call(["convert", str(tmp_palette2_png), str(in_img)])
- identify = json.loads(subprocess.check_output(["convert", str(in_img), "json:"]))
+ subprocess.check_call(
+ CONVERT + [str(tmp_palette2_png), "-compress", "Zip", str(in_img)]
+ )
+ identify = json.loads(subprocess.check_output(CONVERT + [str(in_img), "json:"]))
assert len(identify) == 1
# somewhere between imagemagick 6.9.7.4 and 6.9.9.34, the json output was
# put into an array, here we cater for the older version containing just
@@ -3075,9 +3221,6 @@ def tiff_palette2_img(tmp_path_factory, tmp_palette2_png):
identify = [identify]
assert "image" in identify[0]
assert identify[0]["image"].get("format") == "TIFF", str(identify)
- assert (
- identify[0]["image"].get("formatDescription") == "Tagged Image File Format"
- ), str(identify)
assert identify[0]["image"].get("mimeType") == "image/tiff", str(identify)
assert identify[0]["image"].get("geometry") == {
"width": 60,
@@ -3087,7 +3230,8 @@ def tiff_palette2_img(tmp_path_factory, tmp_palette2_png):
}, str(identify)
assert identify[0]["image"].get("colorspace") == "sRGB", str(identify)
assert identify[0]["image"].get("type") == "Palette", str(identify)
- assert identify[0]["image"].get("endianess") in ["Undefined", "LSB",], str(
+ endian = "endianess" if identify[0].get("version", "0") < "1.0" else "endianness"
+ assert identify[0]["image"].get(endian) in ["Undefined", "LSB",], str(
identify
) # FIXME: should be LSB
assert identify[0]["image"].get("depth") == 8, str(identify)
@@ -3099,7 +3243,6 @@ def tiff_palette2_img(tmp_path_factory, tmp_palette2_png):
"x": 0,
"y": 0,
}, str(identify)
- assert identify[0]["image"].get("compression") == "Zip", str(identify)
assert (
identify[0]["image"].get("properties", {}).get("tiff:alpha") == "unspecified"
), str(identify)
@@ -3116,8 +3259,10 @@ def tiff_palette2_img(tmp_path_factory, tmp_palette2_png):
@pytest.fixture(scope="session")
def tiff_palette4_img(tmp_path_factory, tmp_palette4_png):
in_img = tmp_path_factory.mktemp("tiff_palette4_img") / "in.tiff"
- subprocess.check_call(["convert", str(tmp_palette4_png), str(in_img)])
- identify = json.loads(subprocess.check_output(["convert", str(in_img), "json:"]))
+ subprocess.check_call(
+ CONVERT + [str(tmp_palette4_png), "-compress", "Zip", str(in_img)]
+ )
+ identify = json.loads(subprocess.check_output(CONVERT + [str(in_img), "json:"]))
assert len(identify) == 1
# somewhere between imagemagick 6.9.7.4 and 6.9.9.34, the json output was
# put into an array, here we cater for the older version containing just
@@ -3126,9 +3271,6 @@ def tiff_palette4_img(tmp_path_factory, tmp_palette4_png):
identify = [identify]
assert "image" in identify[0]
assert identify[0]["image"].get("format") == "TIFF", str(identify)
- assert (
- identify[0]["image"].get("formatDescription") == "Tagged Image File Format"
- ), str(identify)
assert identify[0]["image"].get("mimeType") == "image/tiff", str(identify)
assert identify[0]["image"].get("geometry") == {
"width": 60,
@@ -3138,7 +3280,8 @@ def tiff_palette4_img(tmp_path_factory, tmp_palette4_png):
}, str(identify)
assert identify[0]["image"].get("colorspace") == "sRGB", str(identify)
assert identify[0]["image"].get("type") == "Palette", str(identify)
- assert identify[0]["image"].get("endianess") in ["Undefined", "LSB",], str(
+ endian = "endianess" if identify[0].get("version", "0") < "1.0" else "endianness"
+ assert identify[0]["image"].get(endian) in ["Undefined", "LSB",], str(
identify
) # FIXME: should be LSB
assert identify[0]["image"].get("depth") == 8, str(identify)
@@ -3150,7 +3293,6 @@ def tiff_palette4_img(tmp_path_factory, tmp_palette4_png):
"x": 0,
"y": 0,
}, str(identify)
- assert identify[0]["image"].get("compression") == "Zip", str(identify)
assert (
identify[0]["image"].get("properties", {}).get("tiff:alpha") == "unspecified"
), str(identify)
@@ -3167,8 +3309,10 @@ def tiff_palette4_img(tmp_path_factory, tmp_palette4_png):
@pytest.fixture(scope="session")
def tiff_palette8_img(tmp_path_factory, tmp_palette8_png):
in_img = tmp_path_factory.mktemp("tiff_palette8_img") / "in.tiff"
- subprocess.check_call(["convert", str(tmp_palette8_png), str(in_img)])
- identify = json.loads(subprocess.check_output(["convert", str(in_img), "json:"]))
+ subprocess.check_call(
+ CONVERT + [str(tmp_palette8_png), "-compress", "Zip", str(in_img)]
+ )
+ identify = json.loads(subprocess.check_output(CONVERT + [str(in_img), "json:"]))
assert len(identify) == 1
# somewhere between imagemagick 6.9.7.4 and 6.9.9.34, the json output was
# put into an array, here we cater for the older version containing just
@@ -3177,9 +3321,6 @@ def tiff_palette8_img(tmp_path_factory, tmp_palette8_png):
identify = [identify]
assert "image" in identify[0]
assert identify[0]["image"].get("format") == "TIFF", str(identify)
- assert (
- identify[0]["image"].get("formatDescription") == "Tagged Image File Format"
- ), str(identify)
assert identify[0]["image"].get("mimeType") == "image/tiff", str(identify)
assert identify[0]["image"].get("geometry") == {
"width": 60,
@@ -3189,7 +3330,8 @@ def tiff_palette8_img(tmp_path_factory, tmp_palette8_png):
}, str(identify)
assert identify[0]["image"].get("colorspace") == "sRGB", str(identify)
assert identify[0]["image"].get("type") == "Palette", str(identify)
- assert identify[0]["image"].get("endianess") in ["Undefined", "LSB",], str(
+ endian = "endianess" if identify[0].get("version", "0") < "1.0" else "endianness"
+ assert identify[0]["image"].get(endian) in ["Undefined", "LSB",], str(
identify
) # FIXME: should be LSB
assert identify[0]["image"].get("depth") == 8, str(identify)
@@ -3200,7 +3342,6 @@ def tiff_palette8_img(tmp_path_factory, tmp_palette8_png):
"x": 0,
"y": 0,
}, str(identify)
- assert identify[0]["image"].get("compression") == "Zip", str(identify)
assert (
identify[0]["image"].get("properties", {}).get("tiff:alpha") == "unspecified"
), str(identify)
@@ -3218,8 +3359,8 @@ def tiff_palette8_img(tmp_path_factory, tmp_palette8_png):
def tiff_ccitt_lsb_m2l_white_img(tmp_path_factory, tmp_gray1_png):
in_img = tmp_path_factory.mktemp("tiff_ccitt_lsb_m2l_white_img") / "in.tiff"
subprocess.check_call(
- [
- "convert",
+ CONVERT
+ + [
str(tmp_gray1_png),
"-compress",
"group4",
@@ -3229,10 +3370,12 @@ def tiff_ccitt_lsb_m2l_white_img(tmp_path_factory, tmp_gray1_png):
"tiff:fill-order=msb",
"-define",
"quantum:polarity=min-is-white",
+ "-compress",
+ "Group4",
str(in_img),
]
)
- identify = json.loads(subprocess.check_output(["convert", str(in_img), "json:"]))
+ identify = json.loads(subprocess.check_output(CONVERT + [str(in_img), "json:"]))
assert len(identify) == 1
# somewhere between imagemagick 6.9.7.4 and 6.9.9.34, the json output was
# put into an array, here we cater for the older version containing just
@@ -3241,9 +3384,6 @@ def tiff_ccitt_lsb_m2l_white_img(tmp_path_factory, tmp_gray1_png):
identify = [identify]
assert "image" in identify[0]
assert identify[0]["image"].get("format") == "TIFF", str(identify)
- assert (
- identify[0]["image"].get("formatDescription") == "Tagged Image File Format"
- ), str(identify)
assert identify[0]["image"].get("mimeType") == "image/tiff", str(identify)
assert identify[0]["image"].get("geometry") == {
"width": 60,
@@ -3253,7 +3393,8 @@ def tiff_ccitt_lsb_m2l_white_img(tmp_path_factory, tmp_gray1_png):
}, str(identify)
assert identify[0]["image"].get("colorspace") == "Gray", str(identify)
assert identify[0]["image"].get("type") == "Bilevel", str(identify)
- assert identify[0]["image"].get("endianess") in ["Undefined", "LSB",], str(
+ endian = "endianess" if identify[0].get("version", "0") < "1.0" else "endianness"
+ assert identify[0]["image"].get(endian) in ["Undefined", "LSB",], str(
identify
) # FIXME: should be LSB
assert identify[0]["image"].get("depth") == 1, str(identify)
@@ -3299,8 +3440,8 @@ def tiff_ccitt_lsb_m2l_white_img(tmp_path_factory, tmp_gray1_png):
def tiff_ccitt_msb_m2l_white_img(tmp_path_factory, tmp_gray1_png):
in_img = tmp_path_factory.mktemp("tiff_ccitt_msb_m2l_white_img") / "in.tiff"
subprocess.check_call(
- [
- "convert",
+ CONVERT
+ + [
str(tmp_gray1_png),
"-compress",
"group4",
@@ -3310,10 +3451,12 @@ def tiff_ccitt_msb_m2l_white_img(tmp_path_factory, tmp_gray1_png):
"tiff:fill-order=msb",
"-define",
"quantum:polarity=min-is-white",
+ "-compress",
+ "Group4",
str(in_img),
]
)
- identify = json.loads(subprocess.check_output(["convert", str(in_img), "json:"]))
+ identify = json.loads(subprocess.check_output(CONVERT + [str(in_img), "json:"]))
assert len(identify) == 1
# somewhere between imagemagick 6.9.7.4 and 6.9.9.34, the json output was
# put into an array, here we cater for the older version containing just
@@ -3322,9 +3465,6 @@ def tiff_ccitt_msb_m2l_white_img(tmp_path_factory, tmp_gray1_png):
identify = [identify]
assert "image" in identify[0]
assert identify[0]["image"].get("format") == "TIFF", str(identify)
- assert (
- identify[0]["image"].get("formatDescription") == "Tagged Image File Format"
- ), str(identify)
assert identify[0]["image"].get("mimeType") == "image/tiff", str(identify)
assert identify[0]["image"].get("geometry") == {
"width": 60,
@@ -3334,7 +3474,8 @@ def tiff_ccitt_msb_m2l_white_img(tmp_path_factory, tmp_gray1_png):
}, str(identify)
assert identify[0]["image"].get("colorspace") == "Gray", str(identify)
assert identify[0]["image"].get("type") == "Bilevel", str(identify)
- assert identify[0]["image"].get("endianess") in [
+ endian = "endianess" if identify[0].get("version", "0") < "1.0" else "endianness"
+ assert identify[0]["image"].get(endian) in [
"Undefined",
"MSB",
] # FIXME: should be MSB
@@ -3381,8 +3522,8 @@ def tiff_ccitt_msb_m2l_white_img(tmp_path_factory, tmp_gray1_png):
def tiff_ccitt_msb_l2m_white_img(tmp_path_factory, tmp_gray1_png):
in_img = tmp_path_factory.mktemp("tiff_ccitt_msb_l2m_white_img") / "in.tiff"
subprocess.check_call(
- [
- "convert",
+ CONVERT
+ + [
str(tmp_gray1_png),
"-compress",
"group4",
@@ -3392,10 +3533,12 @@ def tiff_ccitt_msb_l2m_white_img(tmp_path_factory, tmp_gray1_png):
"tiff:fill-order=lsb",
"-define",
"quantum:polarity=min-is-white",
+ "-compress",
+ "Group4",
str(in_img),
]
)
- identify = json.loads(subprocess.check_output(["convert", str(in_img), "json:"]))
+ identify = json.loads(subprocess.check_output(CONVERT + [str(in_img), "json:"]))
assert len(identify) == 1
# somewhere between imagemagick 6.9.7.4 and 6.9.9.34, the json output was
# put into an array, here we cater for the older version containing just
@@ -3404,9 +3547,6 @@ def tiff_ccitt_msb_l2m_white_img(tmp_path_factory, tmp_gray1_png):
identify = [identify]
assert "image" in identify[0]
assert identify[0]["image"].get("format") == "TIFF", str(identify)
- assert (
- identify[0]["image"].get("formatDescription") == "Tagged Image File Format"
- ), str(identify)
assert identify[0]["image"].get("mimeType") == "image/tiff", str(identify)
assert identify[0]["image"].get("geometry") == {
"width": 60,
@@ -3416,7 +3556,8 @@ def tiff_ccitt_msb_l2m_white_img(tmp_path_factory, tmp_gray1_png):
}, str(identify)
assert identify[0]["image"].get("colorspace") == "Gray", str(identify)
assert identify[0]["image"].get("type") == "Bilevel", str(identify)
- assert identify[0]["image"].get("endianess") in [
+ endian = "endianess" if identify[0].get("version", "0") < "1.0" else "endianness"
+ assert identify[0]["image"].get(endian) in [
"Undefined",
"MSB",
] # FIXME: should be MSB
@@ -3468,8 +3609,8 @@ def tiff_ccitt_lsb_m2l_black_img(tmp_path_factory, tmp_gray1_png):
# or at least 6.9.10-12 from Sep 7, 2018 (for the ImageMagick6 branch)
# also see: https://www.imagemagick.org/discourse-server/viewtopic.php?f=1&t=34605
subprocess.check_call(
- [
- "convert",
+ CONVERT
+ + [
str(tmp_gray1_png),
"-compress",
"group4",
@@ -3479,10 +3620,12 @@ def tiff_ccitt_lsb_m2l_black_img(tmp_path_factory, tmp_gray1_png):
"tiff:fill-order=msb",
"-define",
"quantum:polarity=min-is-black",
+ "-compress",
+ "Group4",
str(in_img),
]
)
- identify = json.loads(subprocess.check_output(["convert", str(in_img), "json:"]))
+ identify = json.loads(subprocess.check_output(CONVERT + [str(in_img), "json:"]))
assert len(identify) == 1
# somewhere between imagemagick 6.9.7.4 and 6.9.9.34, the json output was
# put into an array, here we cater for the older version containing just
@@ -3491,9 +3634,6 @@ def tiff_ccitt_lsb_m2l_black_img(tmp_path_factory, tmp_gray1_png):
identify = [identify]
assert "image" in identify[0]
assert identify[0]["image"].get("format") == "TIFF", str(identify)
- assert (
- identify[0]["image"].get("formatDescription") == "Tagged Image File Format"
- ), str(identify)
assert identify[0]["image"].get("mimeType") == "image/tiff", str(identify)
assert identify[0]["image"].get("geometry") == {
"width": 60,
@@ -3503,7 +3643,8 @@ def tiff_ccitt_lsb_m2l_black_img(tmp_path_factory, tmp_gray1_png):
}, str(identify)
assert identify[0]["image"].get("colorspace") == "Gray", str(identify)
assert identify[0]["image"].get("type") == "Bilevel", str(identify)
- assert identify[0]["image"].get("endianess") in ["Undefined", "LSB",], str(
+ endian = "endianess" if identify[0].get("version", "0") < "1.0" else "endianness"
+ assert identify[0]["image"].get(endian) in ["Undefined", "LSB",], str(
identify
) # FIXME: should be LSB
assert identify[0]["image"].get("depth") == 1, str(identify)
@@ -3549,8 +3690,8 @@ def tiff_ccitt_lsb_m2l_black_img(tmp_path_factory, tmp_gray1_png):
def tiff_ccitt_nometa1_img(tmp_path_factory, tmp_gray1_png):
in_img = tmp_path_factory.mktemp("tiff_ccitt_nometa1_img") / "in.tiff"
subprocess.check_call(
- [
- "convert",
+ CONVERT
+ + [
str(tmp_gray1_png),
"-compress",
"group4",
@@ -3560,6 +3701,8 @@ def tiff_ccitt_nometa1_img(tmp_path_factory, tmp_gray1_png):
"tiff:fill-order=msb",
"-define",
"quantum:polarity=min-is-white",
+ "-compress",
+ "Group4",
str(in_img),
]
)
@@ -3572,7 +3715,7 @@ def tiff_ccitt_nometa1_img(tmp_path_factory, tmp_gray1_png):
subprocess.check_call(
["tiffset", "-u", "277", str(in_img)]
) # remove SamplesPerPixel (277)
- identify = json.loads(subprocess.check_output(["convert", str(in_img), "json:"]))
+ identify = json.loads(subprocess.check_output(CONVERT + [str(in_img), "json:"]))
assert len(identify) == 1
# somewhere between imagemagick 6.9.7.4 and 6.9.9.34, the json output was
# put into an array, here we cater for the older version containing just
@@ -3581,9 +3724,6 @@ def tiff_ccitt_nometa1_img(tmp_path_factory, tmp_gray1_png):
identify = [identify]
assert "image" in identify[0]
assert identify[0]["image"].get("format") == "TIFF", str(identify)
- assert (
- identify[0]["image"].get("formatDescription") == "Tagged Image File Format"
- ), str(identify)
assert identify[0]["image"].get("mimeType") == "image/tiff", str(identify)
assert identify[0]["image"].get("geometry") == {
"width": 60,
@@ -3593,7 +3733,8 @@ def tiff_ccitt_nometa1_img(tmp_path_factory, tmp_gray1_png):
}, str(identify)
assert identify[0]["image"].get("colorspace") == "Gray", str(identify)
assert identify[0]["image"].get("type") == "Bilevel", str(identify)
- assert identify[0]["image"].get("endianess") in ["Undefined", "LSB",], str(
+ endian = "endianess" if identify[0].get("version", "0") < "1.0" else "endianness"
+ assert identify[0]["image"].get(endian) in ["Undefined", "LSB",], str(
identify
) # FIXME: should be LSB
assert identify[0]["image"].get("depth") == 1, str(identify)
@@ -3639,8 +3780,8 @@ def tiff_ccitt_nometa1_img(tmp_path_factory, tmp_gray1_png):
def tiff_ccitt_nometa2_img(tmp_path_factory, tmp_gray1_png):
in_img = tmp_path_factory.mktemp("tiff_ccitt_nometa2_img") / "in.tiff"
subprocess.check_call(
- [
- "convert",
+ CONVERT
+ + [
str(tmp_gray1_png),
"-compress",
"group4",
@@ -3650,13 +3791,15 @@ def tiff_ccitt_nometa2_img(tmp_path_factory, tmp_gray1_png):
"tiff:fill-order=msb",
"-define",
"quantum:polarity=min-is-white",
+ "-compress",
+ "Group4",
str(in_img),
]
)
subprocess.check_call(
["tiffset", "-u", "278", str(in_img)]
) # remove RowsPerStrip (278)
- identify = json.loads(subprocess.check_output(["convert", str(in_img), "json:"]))
+ identify = json.loads(subprocess.check_output(CONVERT + [str(in_img), "json:"]))
assert len(identify) == 1
# somewhere between imagemagick 6.9.7.4 and 6.9.9.34, the json output was
# put into an array, here we cater for the older version containing just
@@ -3665,9 +3808,6 @@ def tiff_ccitt_nometa2_img(tmp_path_factory, tmp_gray1_png):
identify = [identify]
assert "image" in identify[0]
assert identify[0]["image"].get("format") == "TIFF", str(identify)
- assert (
- identify[0]["image"].get("formatDescription") == "Tagged Image File Format"
- ), str(identify)
assert identify[0]["image"].get("mimeType") == "image/tiff", str(identify)
assert identify[0]["image"].get("geometry") == {
"width": 60,
@@ -3677,7 +3817,8 @@ def tiff_ccitt_nometa2_img(tmp_path_factory, tmp_gray1_png):
}, str(identify)
assert identify[0]["image"].get("units") == "PixelsPerInch", str(identify)
assert identify[0]["image"].get("type") == "Bilevel", str(identify)
- assert identify[0]["image"].get("endianess") in ["Undefined", "LSB",], str(
+ endian = "endianess" if identify[0].get("version", "0") < "1.0" else "endianness"
+ assert identify[0]["image"].get(endian) in ["Undefined", "LSB",], str(
identify
) # FIXME: should be LSB
assert identify[0]["image"].get("colorspace") == "Gray", str(identify)
@@ -3717,7 +3858,7 @@ def tiff_ccitt_nometa2_img(tmp_path_factory, tmp_gray1_png):
@pytest.fixture(scope="session")
def png_icc_img(tmp_icc_png):
in_img = tmp_icc_png
- identify = json.loads(subprocess.check_output(["convert", str(in_img), "json:"]))
+ identify = json.loads(subprocess.check_output(CONVERT + [str(in_img), "json:"]))
assert len(identify) == 1
# somewhere between imagemagick 6.9.7.4 and 6.9.9.34, the json output was
# put into an array, here we cater for the older version containing just
@@ -3726,9 +3867,6 @@ def png_icc_img(tmp_icc_png):
identify = [identify]
assert "image" in identify[0]
assert identify[0]["image"].get("format") == "PNG", str(identify)
- assert (
- identify[0]["image"].get("formatDescription") == "Portable Network Graphics"
- ), str(identify)
assert identify[0]["image"].get("mimeType") == "image/png", str(identify)
assert identify[0]["image"].get("geometry") == {
"width": 60,
@@ -3745,7 +3883,6 @@ def png_icc_img(tmp_icc_png):
"x": 0,
"y": 0,
}, str(identify)
- assert identify[0]["image"].get("compression") == "Zip", str(identify)
assert (
identify[0]["image"].get("properties", {}).get("png:IHDR.bit-depth-orig") == "8"
), str(identify)
@@ -3772,7 +3909,7 @@ def png_icc_img(tmp_icc_png):
###############################################################################
-@pytest.fixture(scope="session", params=["internal", "pikepdf", "pdfrw"])
+@pytest.fixture(scope="session", params=["internal", "pikepdf"])
def jpg_pdf(tmp_path_factory, jpg_img, request):
out_pdf = tmp_path_factory.mktemp("jpg_pdf") / "out.pdf"
subprocess.check_call(
@@ -3799,7 +3936,7 @@ def jpg_pdf(tmp_path_factory, jpg_img, request):
out_pdf.unlink()
-@pytest.fixture(scope="session", params=["internal", "pikepdf", "pdfrw"])
+@pytest.fixture(scope="session", params=["internal", "pikepdf"])
def jpg_rot_pdf(tmp_path_factory, jpg_rot_img, request):
out_pdf = tmp_path_factory.mktemp("jpg_rot_pdf") / "out.pdf"
subprocess.check_call(
@@ -3827,7 +3964,7 @@ def jpg_rot_pdf(tmp_path_factory, jpg_rot_img, request):
out_pdf.unlink()
-@pytest.fixture(scope="session", params=["internal", "pikepdf", "pdfrw"])
+@pytest.fixture(scope="session", params=["internal", "pikepdf"])
def jpg_cmyk_pdf(tmp_path_factory, jpg_cmyk_img, request):
out_pdf = tmp_path_factory.mktemp("jpg_cmyk_pdf") / "out.pdf"
subprocess.check_call(
@@ -3857,7 +3994,7 @@ def jpg_cmyk_pdf(tmp_path_factory, jpg_cmyk_img, request):
out_pdf.unlink()
-@pytest.fixture(scope="session", params=["internal", "pikepdf", "pdfrw"])
+@pytest.fixture(scope="session", params=["internal", "pikepdf"])
def jpg_2000_pdf(tmp_path_factory, jpg_2000_img, request):
out_pdf = tmp_path_factory.mktemp("jpg_2000_pdf") / "out.pdf"
subprocess.check_call(
@@ -3884,7 +4021,7 @@ def jpg_2000_pdf(tmp_path_factory, jpg_2000_img, request):
out_pdf.unlink()
-@pytest.fixture(scope="session", params=["internal", "pikepdf", "pdfrw"])
+@pytest.fixture(scope="session", params=["internal", "pikepdf"])
def png_rgb8_pdf(tmp_path_factory, png_rgb8_img, request):
out_pdf = tmp_path_factory.mktemp("png_rgb8_pdf") / "out.pdf"
subprocess.check_call(
@@ -3914,7 +4051,87 @@ def png_rgb8_pdf(tmp_path_factory, png_rgb8_img, request):
out_pdf.unlink()
-@pytest.fixture(scope="session", params=["internal", "pikepdf", "pdfrw"])
+@pytest.fixture(scope="session", params=["internal", "pikepdf"])
+def png_rgba8_pdf(tmp_path_factory, png_rgba8_img, request):
+ out_pdf = tmp_path_factory.mktemp("png_rgba8_pdf") / "out.pdf"
+ subprocess.check_call(
+ [
+ "src/img2pdf.py",
+ "--producer=",
+ "--nodate",
+ "--engine=" + request.param,
+ "--output=" + str(out_pdf),
+ str(png_rgba8_img),
+ ]
+ )
+ with pikepdf.open(str(out_pdf)) as p:
+ assert (
+ p.pages[0].Contents.read_bytes()
+ == b"q\n45.0000 0 0 45.0000 0.0000 0.0000 cm\n/Im0 Do\nQ"
+ )
+ assert p.pages[0].Resources.XObject.Im0.BitsPerComponent == 8
+ assert p.pages[0].Resources.XObject.Im0.ColorSpace == "/DeviceRGB"
+ assert p.pages[0].Resources.XObject.Im0.DecodeParms.BitsPerComponent == 8
+ assert p.pages[0].Resources.XObject.Im0.DecodeParms.Colors == 3
+ assert p.pages[0].Resources.XObject.Im0.DecodeParms.Predictor == 15
+ assert p.pages[0].Resources.XObject.Im0.Filter == "/FlateDecode"
+ assert p.pages[0].Resources.XObject.Im0.Height == 60
+ assert p.pages[0].Resources.XObject.Im0.Width == 60
+ assert p.pages[0].Resources.XObject.Im0.SMask is not None
+
+ assert p.pages[0].Resources.XObject.Im0.SMask.BitsPerComponent == 8
+ assert p.pages[0].Resources.XObject.Im0.SMask.ColorSpace == "/DeviceGray"
+ assert p.pages[0].Resources.XObject.Im0.SMask.DecodeParms.BitsPerComponent == 8
+ assert p.pages[0].Resources.XObject.Im0.SMask.DecodeParms.Colors == 1
+ assert p.pages[0].Resources.XObject.Im0.SMask.DecodeParms.Predictor == 15
+ assert p.pages[0].Resources.XObject.Im0.SMask.Filter == "/FlateDecode"
+ assert p.pages[0].Resources.XObject.Im0.SMask.Height == 60
+ assert p.pages[0].Resources.XObject.Im0.SMask.Width == 60
+ yield out_pdf
+ out_pdf.unlink()
+
+
+@pytest.fixture(scope="session", params=["internal", "pikepdf"])
+def gif_transparent_pdf(tmp_path_factory, gif_transparent_img, request):
+ out_pdf = tmp_path_factory.mktemp("gif_transparent_pdf") / "out.pdf"
+ subprocess.check_call(
+ [
+ "src/img2pdf.py",
+ "--producer=",
+ "--nodate",
+ "--engine=" + request.param,
+ "--output=" + str(out_pdf),
+ str(gif_transparent_img),
+ ]
+ )
+ with pikepdf.open(str(out_pdf)) as p:
+ assert (
+ p.pages[0].Contents.read_bytes()
+ == b"q\n45.0000 0 0 45.0000 0.0000 0.0000 cm\n/Im0 Do\nQ"
+ )
+ assert p.pages[0].Resources.XObject.Im0.BitsPerComponent == 8
+ assert p.pages[0].Resources.XObject.Im0.ColorSpace == "/DeviceRGB"
+ assert p.pages[0].Resources.XObject.Im0.DecodeParms.BitsPerComponent == 8
+ assert p.pages[0].Resources.XObject.Im0.DecodeParms.Colors == 3
+ assert p.pages[0].Resources.XObject.Im0.DecodeParms.Predictor == 15
+ assert p.pages[0].Resources.XObject.Im0.Filter == "/FlateDecode"
+ assert p.pages[0].Resources.XObject.Im0.Height == 60
+ assert p.pages[0].Resources.XObject.Im0.Width == 60
+ assert p.pages[0].Resources.XObject.Im0.SMask is not None
+
+ assert p.pages[0].Resources.XObject.Im0.SMask.BitsPerComponent == 8
+ assert p.pages[0].Resources.XObject.Im0.SMask.ColorSpace == "/DeviceGray"
+ assert p.pages[0].Resources.XObject.Im0.SMask.DecodeParms.BitsPerComponent == 8
+ assert p.pages[0].Resources.XObject.Im0.SMask.DecodeParms.Colors == 1
+ assert p.pages[0].Resources.XObject.Im0.SMask.DecodeParms.Predictor == 15
+ assert p.pages[0].Resources.XObject.Im0.SMask.Filter == "/FlateDecode"
+ assert p.pages[0].Resources.XObject.Im0.SMask.Height == 60
+ assert p.pages[0].Resources.XObject.Im0.SMask.Width == 60
+ yield out_pdf
+ out_pdf.unlink()
+
+
+@pytest.fixture(scope="session", params=["internal", "pikepdf"])
def png_rgb16_pdf(tmp_path_factory, png_rgb16_img, request):
out_pdf = tmp_path_factory.mktemp("png_rgb16_pdf") / "out.pdf"
subprocess.check_call(
@@ -3944,7 +4161,7 @@ def png_rgb16_pdf(tmp_path_factory, png_rgb16_img, request):
out_pdf.unlink()
-@pytest.fixture(scope="session", params=["internal", "pikepdf", "pdfrw"])
+@pytest.fixture(scope="session", params=["internal", "pikepdf"])
def png_interlaced_pdf(tmp_path_factory, png_interlaced_img, request):
out_pdf = tmp_path_factory.mktemp("png_interlaced_pdf") / "out.pdf"
subprocess.check_call(
@@ -3974,7 +4191,7 @@ def png_interlaced_pdf(tmp_path_factory, png_interlaced_img, request):
out_pdf.unlink()
-@pytest.fixture(scope="session", params=["internal", "pikepdf", "pdfrw"])
+@pytest.fixture(scope="session", params=["internal", "pikepdf"])
def png_gray1_pdf(tmp_path_factory, tmp_gray1_png, request):
out_pdf = tmp_path_factory.mktemp("png_gray1_pdf") / "out.pdf"
subprocess.check_call(
@@ -4004,7 +4221,7 @@ def png_gray1_pdf(tmp_path_factory, tmp_gray1_png, request):
out_pdf.unlink()
-@pytest.fixture(scope="session", params=["internal", "pikepdf", "pdfrw"])
+@pytest.fixture(scope="session", params=["internal", "pikepdf"])
def png_gray2_pdf(tmp_path_factory, tmp_gray2_png, request):
out_pdf = tmp_path_factory.mktemp("png_gray2_pdf") / "out.pdf"
subprocess.check_call(
@@ -4034,7 +4251,7 @@ def png_gray2_pdf(tmp_path_factory, tmp_gray2_png, request):
out_pdf.unlink()
-@pytest.fixture(scope="session", params=["internal", "pikepdf", "pdfrw"])
+@pytest.fixture(scope="session", params=["internal", "pikepdf"])
def png_gray4_pdf(tmp_path_factory, tmp_gray4_png, request):
out_pdf = tmp_path_factory.mktemp("png_gray4_pdf") / "out.pdf"
subprocess.check_call(
@@ -4064,7 +4281,7 @@ def png_gray4_pdf(tmp_path_factory, tmp_gray4_png, request):
out_pdf.unlink()
-@pytest.fixture(scope="session", params=["internal", "pikepdf", "pdfrw"])
+@pytest.fixture(scope="session", params=["internal", "pikepdf"])
def png_gray8_pdf(tmp_path_factory, tmp_gray8_png, request):
out_pdf = tmp_path_factory.mktemp("png_gray8_pdf") / "out.pdf"
subprocess.check_call(
@@ -4094,7 +4311,47 @@ def png_gray8_pdf(tmp_path_factory, tmp_gray8_png, request):
out_pdf.unlink()
-@pytest.fixture(scope="session", params=["internal", "pikepdf", "pdfrw"])
+@pytest.fixture(scope="session", params=["internal", "pikepdf"])
+def png_gray8a_pdf(tmp_path_factory, png_gray8a_img, request):
+ out_pdf = tmp_path_factory.mktemp("png_gray8a_pdf") / "out.pdf"
+ subprocess.check_call(
+ [
+ "src/img2pdf.py",
+ "--producer=",
+ "--nodate",
+ "--engine=" + request.param,
+ "--output=" + str(out_pdf),
+ str(png_gray8a_img),
+ ]
+ )
+ with pikepdf.open(str(out_pdf)) as p:
+ assert (
+ p.pages[0].Contents.read_bytes()
+ == b"q\n45.0000 0 0 45.0000 0.0000 0.0000 cm\n/Im0 Do\nQ"
+ )
+ assert p.pages[0].Resources.XObject.Im0.BitsPerComponent == 8
+ assert p.pages[0].Resources.XObject.Im0.ColorSpace == "/DeviceGray"
+ assert p.pages[0].Resources.XObject.Im0.DecodeParms.BitsPerComponent == 8
+ assert p.pages[0].Resources.XObject.Im0.DecodeParms.Colors == 1
+ assert p.pages[0].Resources.XObject.Im0.DecodeParms.Predictor == 15
+ assert p.pages[0].Resources.XObject.Im0.Filter == "/FlateDecode"
+ assert p.pages[0].Resources.XObject.Im0.Height == 60
+ assert p.pages[0].Resources.XObject.Im0.Width == 60
+ assert p.pages[0].Resources.XObject.Im0.SMask is not None
+
+ assert p.pages[0].Resources.XObject.Im0.SMask.BitsPerComponent == 8
+ assert p.pages[0].Resources.XObject.Im0.SMask.ColorSpace == "/DeviceGray"
+ assert p.pages[0].Resources.XObject.Im0.SMask.DecodeParms.BitsPerComponent == 8
+ assert p.pages[0].Resources.XObject.Im0.SMask.DecodeParms.Colors == 1
+ assert p.pages[0].Resources.XObject.Im0.SMask.DecodeParms.Predictor == 15
+ assert p.pages[0].Resources.XObject.Im0.SMask.Filter == "/FlateDecode"
+ assert p.pages[0].Resources.XObject.Im0.SMask.Height == 60
+ assert p.pages[0].Resources.XObject.Im0.SMask.Width == 60
+ yield out_pdf
+ out_pdf.unlink()
+
+
+@pytest.fixture(scope="session", params=["internal", "pikepdf"])
def png_gray16_pdf(tmp_path_factory, tmp_gray16_png, request):
out_pdf = tmp_path_factory.mktemp("png_gray16_pdf") / "out.pdf"
subprocess.check_call(
@@ -4248,8 +4505,8 @@ def png_palette8_pdf(tmp_path_factory, tmp_palette8_png, request):
out_pdf.unlink()
-@pytest.fixture(scope="session", params=["internal", "pikepdf", "pdfrw"])
-def png_icc_pdf(tmp_path_factory, tmp_icc_png, request):
+@pytest.fixture(scope="session", params=["internal", "pikepdf"])
+def png_icc_pdf(tmp_path_factory, tmp_icc_png, tmp_icc_profile, request):
out_pdf = tmp_path_factory.mktemp("png_icc_pdf") / "out.pdf"
subprocess.check_call(
[
@@ -4272,7 +4529,7 @@ def png_icc_pdf(tmp_path_factory, tmp_icc_png, request):
assert p.pages[0].Resources.XObject.Im0.ColorSpace[1].Alternate == "/DeviceRGB"
assert (
p.pages[0].Resources.XObject.Im0.ColorSpace[1].read_bytes()
- == pathlib.Path("/usr/share/color/icc/sRGB.icc").read_bytes()
+ == tmp_icc_profile.read_bytes()
)
assert p.pages[0].Resources.XObject.Im0.DecodeParms.BitsPerComponent == 8
assert p.pages[0].Resources.XObject.Im0.DecodeParms.Colors == 3
@@ -4448,7 +4705,7 @@ def gif_animation_pdf(tmp_path_factory, gif_animation_img, request):
out_pdf.unlink()
-@pytest.fixture(scope="session", params=["internal", "pikepdf", "pdfrw"])
+@pytest.fixture(scope="session", params=["internal", "pikepdf"])
def tiff_cmyk8_pdf(tmp_path_factory, tiff_cmyk8_img, request):
out_pdf = tmp_path_factory.mktemp("tiff_cmyk8_pdf") / "out.pdf"
subprocess.check_call(
@@ -4475,7 +4732,7 @@ def tiff_cmyk8_pdf(tmp_path_factory, tiff_cmyk8_img, request):
out_pdf.unlink()
-@pytest.fixture(scope="session", params=["internal", "pikepdf", "pdfrw"])
+@pytest.fixture(scope="session", params=["internal", "pikepdf"])
def tiff_rgb8_pdf(tmp_path_factory, tiff_rgb8_img, request):
out_pdf = tmp_path_factory.mktemp("tiff_rgb8_pdf") / "out.pdf"
subprocess.check_call(
@@ -4505,7 +4762,7 @@ def tiff_rgb8_pdf(tmp_path_factory, tiff_rgb8_img, request):
out_pdf.unlink()
-@pytest.fixture(scope="session", params=["internal", "pikepdf", "pdfrw"])
+@pytest.fixture(scope="session", params=["internal", "pikepdf"])
def tiff_gray1_pdf(tmp_path_factory, tiff_gray1_img, request):
out_pdf = tmp_path_factory.mktemp("tiff_gray1_pdf") / "out.pdf"
subprocess.check_call(
@@ -4536,7 +4793,7 @@ def tiff_gray1_pdf(tmp_path_factory, tiff_gray1_img, request):
out_pdf.unlink()
-@pytest.fixture(scope="session", params=["internal", "pikepdf", "pdfrw"])
+@pytest.fixture(scope="session", params=["internal", "pikepdf"])
def tiff_gray2_pdf(tmp_path_factory, tiff_gray2_img, request):
out_pdf = tmp_path_factory.mktemp("tiff_gray2_pdf") / "out.pdf"
subprocess.check_call(
@@ -4566,7 +4823,7 @@ def tiff_gray2_pdf(tmp_path_factory, tiff_gray2_img, request):
out_pdf.unlink()
-@pytest.fixture(scope="session", params=["internal", "pikepdf", "pdfrw"])
+@pytest.fixture(scope="session", params=["internal", "pikepdf"])
def tiff_gray4_pdf(tmp_path_factory, tiff_gray4_img, request):
out_pdf = tmp_path_factory.mktemp("tiff_gray4_pdf") / "out.pdf"
subprocess.check_call(
@@ -4596,7 +4853,7 @@ def tiff_gray4_pdf(tmp_path_factory, tiff_gray4_img, request):
out_pdf.unlink()
-@pytest.fixture(scope="session", params=["internal", "pikepdf", "pdfrw"])
+@pytest.fixture(scope="session", params=["internal", "pikepdf"])
def tiff_gray8_pdf(tmp_path_factory, tiff_gray8_img, request):
out_pdf = tmp_path_factory.mktemp("tiff_gray8_pdf") / "out.pdf"
subprocess.check_call(
@@ -4626,7 +4883,7 @@ def tiff_gray8_pdf(tmp_path_factory, tiff_gray8_img, request):
out_pdf.unlink()
-@pytest.fixture(scope="session", params=["internal", "pikepdf", "pdfrw"])
+@pytest.fixture(scope="session", params=["internal", "pikepdf"])
def tiff_multipage_pdf(tmp_path_factory, tiff_multipage_img, request):
tmpdir = tmp_path_factory.mktemp("tiff_multipage_pdf")
out_pdf = tmpdir / "out.pdf"
@@ -4789,7 +5046,7 @@ def tiff_palette8_pdf(tmp_path_factory, tiff_palette8_img, request):
out_pdf.unlink()
-@pytest.fixture(scope="session", params=["internal", "pikepdf", "pdfrw"])
+@pytest.fixture(scope="session", params=["internal", "pikepdf"])
def tiff_ccitt_lsb_m2l_white_pdf(
tmp_path_factory, tiff_ccitt_lsb_m2l_white_img, request
):
@@ -4822,7 +5079,7 @@ def tiff_ccitt_lsb_m2l_white_pdf(
out_pdf.unlink()
-@pytest.fixture(scope="session", params=["internal", "pikepdf", "pdfrw"])
+@pytest.fixture(scope="session", params=["internal", "pikepdf"])
def tiff_ccitt_msb_m2l_white_pdf(
tmp_path_factory, tiff_ccitt_msb_m2l_white_img, request
):
@@ -4855,7 +5112,7 @@ def tiff_ccitt_msb_m2l_white_pdf(
out_pdf.unlink()
-@pytest.fixture(scope="session", params=["internal", "pikepdf", "pdfrw"])
+@pytest.fixture(scope="session", params=["internal", "pikepdf"])
def tiff_ccitt_msb_l2m_white_pdf(
tmp_path_factory, tiff_ccitt_msb_l2m_white_img, request
):
@@ -4888,7 +5145,7 @@ def tiff_ccitt_msb_l2m_white_pdf(
out_pdf.unlink()
-@pytest.fixture(scope="session", params=["internal", "pikepdf", "pdfrw"])
+@pytest.fixture(scope="session", params=["internal", "pikepdf"])
def tiff_ccitt_lsb_m2l_black_pdf(
tmp_path_factory, tiff_ccitt_lsb_m2l_black_img, request
):
@@ -4921,7 +5178,7 @@ def tiff_ccitt_lsb_m2l_black_pdf(
out_pdf.unlink()
-@pytest.fixture(scope="session", params=["internal", "pikepdf", "pdfrw"])
+@pytest.fixture(scope="session", params=["internal", "pikepdf"])
def tiff_ccitt_nometa1_pdf(tmp_path_factory, tiff_ccitt_nometa1_img, request):
out_pdf = tmp_path_factory.mktemp("tiff_ccitt_nometa1_pdf") / "out.pdf"
subprocess.check_call(
@@ -4952,7 +5209,7 @@ def tiff_ccitt_nometa1_pdf(tmp_path_factory, tiff_ccitt_nometa1_img, request):
out_pdf.unlink()
-@pytest.fixture(scope="session", params=["internal", "pikepdf", "pdfrw"])
+@pytest.fixture(scope="session", params=["internal", "pikepdf"])
def tiff_ccitt_nometa2_pdf(tmp_path_factory, tiff_ccitt_nometa2_img, request):
out_pdf = tmp_path_factory.mktemp("tiff_ccitt_nometa2_pdf") / "out.pdf"
subprocess.check_call(
@@ -5033,7 +5290,7 @@ def test_jpg_rot(tmp_path_factory, jpg_rot_img, jpg_rot_pdf):
)
jpg_rot_png = tmpdir / "jpg_rot.png"
subprocess.check_call(
- ["convert", "-rotate", "90", str(jpg_rot_pnm), str(jpg_rot_png)]
+ CONVERT + ["-rotate", "90", str(jpg_rot_pnm), str(jpg_rot_png)]
)
jpg_rot_pnm.unlink()
compare_ghostscript(tmpdir, jpg_rot_png, jpg_rot_pdf)
@@ -5058,7 +5315,7 @@ def test_jpg_cmyk(tmp_path_factory, jpg_cmyk_img, jpg_cmyk_pdf):
@pytest.mark.skipif(
- sys.platform in ["darwin", "win32"],
+ sys.platform in ["win32"],
reason="test utilities not available on Windows and MacOS",
)
@pytest.mark.skipif(
@@ -5073,7 +5330,7 @@ def test_jpg_2000(tmp_path_factory, jpg_2000_img, jpg_2000_pdf):
@pytest.mark.skipif(
- sys.platform in ["darwin", "win32"],
+ sys.platform in ["win32"],
reason="test utilities not available on Windows and MacOS",
)
def test_png_rgb8(tmp_path_factory, png_rgb8_img, png_rgb8_pdf):
@@ -5085,7 +5342,7 @@ def test_png_rgb8(tmp_path_factory, png_rgb8_img, png_rgb8_pdf):
@pytest.mark.skipif(
- sys.platform in ["darwin", "win32"],
+ sys.platform in ["win32"],
reason="test utilities not available on Windows and MacOS",
)
def test_png_rgb16(tmp_path_factory, png_rgb16_img, png_rgb16_pdf):
@@ -5097,33 +5354,19 @@ def test_png_rgb16(tmp_path_factory, png_rgb16_img, png_rgb16_pdf):
@pytest.mark.skipif(
- sys.platform in ["darwin", "win32"],
+ sys.platform in ["win32"],
reason="test utilities not available on Windows and MacOS",
)
-@pytest.mark.parametrize("engine", ["internal", "pikepdf", "pdfrw"])
-def test_png_rgba8(tmp_path_factory, png_rgba8_img, engine):
- out_pdf = tmp_path_factory.mktemp("png_rgba8") / "out.pdf"
- assert (
- 0
- != subprocess.run(
- [
- "src/img2pdf.py",
- "--producer=",
- "--nodate",
- "--engine=" + engine,
- "--output=" + str(out_pdf),
- str(png_rgba8_img),
- ]
- ).returncode
- )
- out_pdf.unlink()
+def test_png_rgba8(tmp_path_factory, png_rgba8_img, png_rgba8_pdf):
+ tmpdir = tmp_path_factory.mktemp("png_rgba8")
+ compare_pdfimages_png(tmpdir, png_rgba8_img, png_rgba8_pdf)
@pytest.mark.skipif(
- sys.platform in ["darwin", "win32"],
+ sys.platform in ["win32"],
reason="test utilities not available on Windows and MacOS",
)
-@pytest.mark.parametrize("engine", ["internal", "pikepdf", "pdfrw"])
+@pytest.mark.parametrize("engine", ["internal", "pikepdf"])
def test_png_rgba16(tmp_path_factory, png_rgba16_img, engine):
out_pdf = tmp_path_factory.mktemp("png_rgba16") / "out.pdf"
assert (
@@ -5143,33 +5386,19 @@ def test_png_rgba16(tmp_path_factory, png_rgba16_img, engine):
@pytest.mark.skipif(
- sys.platform in ["darwin", "win32"],
+ sys.platform in ["win32"],
reason="test utilities not available on Windows and MacOS",
)
-@pytest.mark.parametrize("engine", ["internal", "pikepdf", "pdfrw"])
-def test_png_gray8a(tmp_path_factory, png_gray8a_img, engine):
- out_pdf = tmp_path_factory.mktemp("png_gray8a") / "out.pdf"
- assert (
- 0
- != subprocess.run(
- [
- "src/img2pdf.py",
- "--producer=",
- "--nodate",
- "--engine=" + engine,
- "--output=" + str(out_pdf),
- str(png_gray8a_img),
- ]
- ).returncode
- )
- out_pdf.unlink()
+def test_png_gray8a(tmp_path_factory, png_gray8a_img, png_gray8a_pdf):
+ tmpdir = tmp_path_factory.mktemp("png_gray8a")
+ compare_pdfimages_png(tmpdir, png_gray8a_img, png_gray8a_pdf)
@pytest.mark.skipif(
- sys.platform in ["darwin", "win32"],
+ sys.platform in ["win32"],
reason="test utilities not available on Windows and MacOS",
)
-@pytest.mark.parametrize("engine", ["internal", "pikepdf", "pdfrw"])
+@pytest.mark.parametrize("engine", ["internal", "pikepdf"])
def test_png_gray16a(tmp_path_factory, png_gray16a_img, engine):
out_pdf = tmp_path_factory.mktemp("png_gray16a") / "out.pdf"
assert (
@@ -5189,7 +5418,7 @@ def test_png_gray16a(tmp_path_factory, png_gray16a_img, engine):
@pytest.mark.skipif(
- sys.platform in ["darwin", "win32"],
+ sys.platform in ["win32"],
reason="test utilities not available on Windows and MacOS",
)
def test_png_interlaced(tmp_path_factory, png_interlaced_img, png_interlaced_pdf):
@@ -5201,7 +5430,7 @@ def test_png_interlaced(tmp_path_factory, png_interlaced_img, png_interlaced_pdf
@pytest.mark.skipif(
- sys.platform in ["darwin", "win32"],
+ sys.platform in ["win32"],
reason="test utilities not available on Windows and MacOS",
)
def test_png_gray1(tmp_path_factory, png_gray1_img, png_gray1_pdf):
@@ -5213,7 +5442,7 @@ def test_png_gray1(tmp_path_factory, png_gray1_img, png_gray1_pdf):
@pytest.mark.skipif(
- sys.platform in ["darwin", "win32"],
+ sys.platform in ["win32"],
reason="test utilities not available on Windows and MacOS",
)
def test_png_gray2(tmp_path_factory, png_gray2_img, png_gray2_pdf):
@@ -5225,7 +5454,7 @@ def test_png_gray2(tmp_path_factory, png_gray2_img, png_gray2_pdf):
@pytest.mark.skipif(
- sys.platform in ["darwin", "win32"],
+ sys.platform in ["win32"],
reason="test utilities not available on Windows and MacOS",
)
def test_png_gray4(tmp_path_factory, png_gray4_img, png_gray4_pdf):
@@ -5237,7 +5466,7 @@ def test_png_gray4(tmp_path_factory, png_gray4_img, png_gray4_pdf):
@pytest.mark.skipif(
- sys.platform in ["darwin", "win32"],
+ sys.platform in ["win32"],
reason="test utilities not available on Windows and MacOS",
)
def test_png_gray8(tmp_path_factory, png_gray8_img, png_gray8_pdf):
@@ -5249,7 +5478,7 @@ def test_png_gray8(tmp_path_factory, png_gray8_img, png_gray8_pdf):
@pytest.mark.skipif(
- sys.platform in ["darwin", "win32"],
+ sys.platform in ["win32"],
reason="test utilities not available on Windows and MacOS",
)
def test_png_gray16(tmp_path_factory, png_gray16_img, png_gray16_pdf):
@@ -5265,7 +5494,7 @@ def test_png_gray16(tmp_path_factory, png_gray16_img, png_gray16_pdf):
@pytest.mark.skipif(
- sys.platform in ["darwin", "win32"],
+ sys.platform in ["win32"],
reason="test utilities not available on Windows and MacOS",
)
def test_png_palette1(tmp_path_factory, png_palette1_img, png_palette1_pdf):
@@ -5277,7 +5506,7 @@ def test_png_palette1(tmp_path_factory, png_palette1_img, png_palette1_pdf):
@pytest.mark.skipif(
- sys.platform in ["darwin", "win32"],
+ sys.platform in ["win32"],
reason="test utilities not available on Windows and MacOS",
)
def test_png_palette2(tmp_path_factory, png_palette2_img, png_palette2_pdf):
@@ -5289,7 +5518,7 @@ def test_png_palette2(tmp_path_factory, png_palette2_img, png_palette2_pdf):
@pytest.mark.skipif(
- sys.platform in ["darwin", "win32"],
+ sys.platform in ["win32"],
reason="test utilities not available on Windows and MacOS",
)
def test_png_palette4(tmp_path_factory, png_palette4_img, png_palette4_pdf):
@@ -5301,7 +5530,7 @@ def test_png_palette4(tmp_path_factory, png_palette4_img, png_palette4_pdf):
@pytest.mark.skipif(
- sys.platform in ["darwin", "win32"],
+ sys.platform in ["win32"],
reason="test utilities not available on Windows and MacOS",
)
def test_png_palette8(tmp_path_factory, png_palette8_img, png_palette8_pdf):
@@ -5318,37 +5547,23 @@ def test_png_palette8(tmp_path_factory, png_palette8_img, png_palette8_pdf):
)
def test_png_icc(tmp_path_factory, png_icc_img, png_icc_pdf):
tmpdir = tmp_path_factory.mktemp("png_icc")
- compare_ghostscript(tmpdir, png_icc_img, png_icc_pdf, icc=True)
- # compare_poppler(tmpdir, png_icc_img, png_icc_pdf)
- # compare_mupdf(tmpdir, png_icc_img, png_icc_pdf)
- # compare_pdfimages_png(tmpdir, png_icc_img, png_icc_pdf)
+ compare_ghostscript(tmpdir, png_icc_img, png_icc_pdf, exact=False, icc=True)
+ compare_poppler(tmpdir, png_icc_img, png_icc_pdf, exact=False, icc=True)
+ # mupdf ignores the ICC profile in Debian (needs patched thirdparty liblcms2-art)
+ compare_pdfimages_png(tmpdir, png_icc_img, png_icc_pdf, exact=False, icc=True)
@pytest.mark.skipif(
- sys.platform in ["darwin", "win32"],
+ sys.platform in ["win32"],
reason="test utilities not available on Windows and MacOS",
)
-@pytest.mark.parametrize("engine", ["internal", "pikepdf", "pdfrw"])
-def test_gif_transparent(tmp_path_factory, gif_transparent_img, engine):
- out_pdf = tmp_path_factory.mktemp("gif_transparent") / "out.pdf"
- assert (
- 0
- != subprocess.run(
- [
- "src/img2pdf.py",
- "--producer=",
- "--nodate",
- "--engine=" + engine,
- "--output=" + str(out_pdf),
- str(gif_transparent_img),
- ]
- ).returncode
- )
- out_pdf.unlink()
+def test_gif_transparent(tmp_path_factory, gif_transparent_img, gif_transparent_pdf):
+ tmpdir = tmp_path_factory.mktemp("gif_transparent")
+ compare_pdfimages_png(tmpdir, gif_transparent_img, gif_transparent_pdf)
@pytest.mark.skipif(
- sys.platform in ["darwin", "win32"],
+ sys.platform in ["win32"],
reason="test utilities not available on Windows and MacOS",
)
def test_gif_palette1(tmp_path_factory, gif_palette1_img, gif_palette1_pdf):
@@ -5360,7 +5575,7 @@ def test_gif_palette1(tmp_path_factory, gif_palette1_img, gif_palette1_pdf):
@pytest.mark.skipif(
- sys.platform in ["darwin", "win32"],
+ sys.platform in ["win32"],
reason="test utilities not available on Windows and MacOS",
)
def test_gif_palette2(tmp_path_factory, gif_palette2_img, gif_palette2_pdf):
@@ -5372,7 +5587,7 @@ def test_gif_palette2(tmp_path_factory, gif_palette2_img, gif_palette2_pdf):
@pytest.mark.skipif(
- sys.platform in ["darwin", "win32"],
+ sys.platform in ["win32"],
reason="test utilities not available on Windows and MacOS",
)
def test_gif_palette4(tmp_path_factory, gif_palette4_img, gif_palette4_pdf):
@@ -5384,7 +5599,7 @@ def test_gif_palette4(tmp_path_factory, gif_palette4_img, gif_palette4_pdf):
@pytest.mark.skipif(
- sys.platform in ["darwin", "win32"],
+ sys.platform in ["win32"],
reason="test utilities not available on Windows and MacOS",
)
def test_gif_palette8(tmp_path_factory, gif_palette8_img, gif_palette8_pdf):
@@ -5396,7 +5611,7 @@ def test_gif_palette8(tmp_path_factory, gif_palette8_img, gif_palette8_pdf):
@pytest.mark.skipif(
- sys.platform in ["darwin", "win32"],
+ sys.platform in ["win32"],
reason="test utilities not available on Windows and MacOS",
)
def test_gif_animation(tmp_path_factory, gif_animation_img, gif_animation_pdf):
@@ -5423,7 +5638,7 @@ def test_gif_animation(tmp_path_factory, gif_animation_img, gif_animation_pdf):
sys.platform in ["darwin", "win32"],
reason="test utilities not available on Windows and MacOS",
)
-@pytest.mark.parametrize("engine", ["internal", "pikepdf", "pdfrw"])
+@pytest.mark.parametrize("engine", ["internal", "pikepdf"])
def test_tiff_float(tmp_path_factory, tiff_float_img, engine):
out_pdf = tmp_path_factory.mktemp("tiff_float") / "out.pdf"
assert (
@@ -5443,7 +5658,7 @@ def test_tiff_float(tmp_path_factory, tiff_float_img, engine):
@pytest.mark.skipif(
- sys.platform in ["darwin", "win32"],
+ sys.platform in ["win32"],
reason="test utilities not available on Windows and MacOS",
)
def test_tiff_cmyk8(tmp_path_factory, tiff_cmyk8_img, tiff_cmyk8_pdf):
@@ -5457,10 +5672,10 @@ def test_tiff_cmyk8(tmp_path_factory, tiff_cmyk8_img, tiff_cmyk8_pdf):
@pytest.mark.skipif(
- sys.platform in ["darwin", "win32"],
+ sys.platform in ["win32"],
reason="test utilities not available on Windows and MacOS",
)
-@pytest.mark.parametrize("engine", ["internal", "pikepdf", "pdfrw"])
+@pytest.mark.parametrize("engine", ["internal", "pikepdf"])
def test_tiff_cmyk16(tmp_path_factory, tiff_cmyk16_img, engine):
out_pdf = tmp_path_factory.mktemp("tiff_cmyk16") / "out.pdf"
# PIL is unable to read 16 bit CMYK images
@@ -5481,7 +5696,7 @@ def test_tiff_cmyk16(tmp_path_factory, tiff_cmyk16_img, engine):
@pytest.mark.skipif(
- sys.platform in ["darwin", "win32"],
+ sys.platform in ["win32"],
reason="test utilities not available on Windows and MacOS",
)
def test_tiff_rgb8(tmp_path_factory, tiff_rgb8_img, tiff_rgb8_pdf):
@@ -5493,10 +5708,10 @@ def test_tiff_rgb8(tmp_path_factory, tiff_rgb8_img, tiff_rgb8_pdf):
@pytest.mark.skipif(
- sys.platform in ["darwin", "win32"],
+ sys.platform in ["win32"],
reason="test utilities not available on Windows and MacOS",
)
-@pytest.mark.parametrize("engine", ["internal", "pikepdf", "pdfrw"])
+@pytest.mark.parametrize("engine", ["internal", "pikepdf"])
def test_tiff_rgb12(tmp_path_factory, tiff_rgb12_img, engine):
out_pdf = tmp_path_factory.mktemp("tiff_rgb12") / "out.pdf"
# PIL is unable to preserve more than 8 bits per sample
@@ -5517,10 +5732,10 @@ def test_tiff_rgb12(tmp_path_factory, tiff_rgb12_img, engine):
@pytest.mark.skipif(
- sys.platform in ["darwin", "win32"],
+ sys.platform in ["win32"],
reason="test utilities not available on Windows and MacOS",
)
-@pytest.mark.parametrize("engine", ["internal", "pikepdf", "pdfrw"])
+@pytest.mark.parametrize("engine", ["internal", "pikepdf"])
def test_tiff_rgb14(tmp_path_factory, tiff_rgb14_img, engine):
out_pdf = tmp_path_factory.mktemp("tiff_rgb14") / "out.pdf"
# PIL is unable to preserve more than 8 bits per sample
@@ -5541,10 +5756,10 @@ def test_tiff_rgb14(tmp_path_factory, tiff_rgb14_img, engine):
@pytest.mark.skipif(
- sys.platform in ["darwin", "win32"],
+ sys.platform in ["win32"],
reason="test utilities not available on Windows and MacOS",
)
-@pytest.mark.parametrize("engine", ["internal", "pikepdf", "pdfrw"])
+@pytest.mark.parametrize("engine", ["internal", "pikepdf"])
def test_tiff_rgb16(tmp_path_factory, tiff_rgb16_img, engine):
out_pdf = tmp_path_factory.mktemp("tiff_rgb16") / "out.pdf"
# PIL is unable to preserve more than 8 bits per sample
@@ -5565,10 +5780,10 @@ def test_tiff_rgb16(tmp_path_factory, tiff_rgb16_img, engine):
@pytest.mark.skipif(
- sys.platform in ["darwin", "win32"],
+ sys.platform in ["win32"],
reason="test utilities not available on Windows and MacOS",
)
-@pytest.mark.parametrize("engine", ["internal", "pikepdf", "pdfrw"])
+@pytest.mark.parametrize("engine", ["internal", "pikepdf"])
def test_tiff_rgba8(tmp_path_factory, tiff_rgba8_img, engine):
out_pdf = tmp_path_factory.mktemp("tiff_rgba8") / "out.pdf"
assert (
@@ -5588,10 +5803,10 @@ def test_tiff_rgba8(tmp_path_factory, tiff_rgba8_img, engine):
@pytest.mark.skipif(
- sys.platform in ["darwin", "win32"],
+ sys.platform in ["win32"],
reason="test utilities not available on Windows and MacOS",
)
-@pytest.mark.parametrize("engine", ["internal", "pikepdf", "pdfrw"])
+@pytest.mark.parametrize("engine", ["internal", "pikepdf"])
def test_tiff_rgba16(tmp_path_factory, tiff_rgba16_img, engine):
out_pdf = tmp_path_factory.mktemp("tiff_rgba16") / "out.pdf"
assert (
@@ -5611,7 +5826,7 @@ def test_tiff_rgba16(tmp_path_factory, tiff_rgba16_img, engine):
@pytest.mark.skipif(
- sys.platform in ["darwin", "win32"],
+ sys.platform in ["win32"],
reason="test utilities not available on Windows and MacOS",
)
def test_tiff_gray1(tmp_path_factory, tiff_gray1_img, tiff_gray1_pdf):
@@ -5623,7 +5838,7 @@ def test_tiff_gray1(tmp_path_factory, tiff_gray1_img, tiff_gray1_pdf):
@pytest.mark.skipif(
- sys.platform in ["darwin", "win32"],
+ sys.platform in ["win32"],
reason="test utilities not available on Windows and MacOS",
)
def test_tiff_gray2(tmp_path_factory, tiff_gray2_img, tiff_gray2_pdf):
@@ -5635,7 +5850,7 @@ def test_tiff_gray2(tmp_path_factory, tiff_gray2_img, tiff_gray2_pdf):
@pytest.mark.skipif(
- sys.platform in ["darwin", "win32"],
+ sys.platform in ["win32"],
reason="test utilities not available on Windows and MacOS",
)
def test_tiff_gray4(tmp_path_factory, tiff_gray4_img, tiff_gray4_pdf):
@@ -5647,7 +5862,7 @@ def test_tiff_gray4(tmp_path_factory, tiff_gray4_img, tiff_gray4_pdf):
@pytest.mark.skipif(
- sys.platform in ["darwin", "win32"],
+ sys.platform in ["win32"],
reason="test utilities not available on Windows and MacOS",
)
def test_tiff_gray8(tmp_path_factory, tiff_gray8_img, tiff_gray8_pdf):
@@ -5659,10 +5874,10 @@ def test_tiff_gray8(tmp_path_factory, tiff_gray8_img, tiff_gray8_pdf):
@pytest.mark.skipif(
- sys.platform in ["darwin", "win32"],
+ sys.platform in ["win32"],
reason="test utilities not available on Windows and MacOS",
)
-@pytest.mark.parametrize("engine", ["internal", "pikepdf", "pdfrw"])
+@pytest.mark.parametrize("engine", ["internal", "pikepdf"])
def test_tiff_gray16(tmp_path_factory, tiff_gray16_img, engine):
out_pdf = tmp_path_factory.mktemp("tiff_gray16") / "out.pdf"
assert (
@@ -5682,7 +5897,7 @@ def test_tiff_gray16(tmp_path_factory, tiff_gray16_img, engine):
@pytest.mark.skipif(
- sys.platform in ["darwin", "win32"],
+ sys.platform in ["win32"],
reason="test utilities not available on Windows and MacOS",
)
def test_tiff_multipage(tmp_path_factory, tiff_multipage_img, tiff_multipage_pdf):
@@ -5712,7 +5927,7 @@ def test_tiff_multipage(tmp_path_factory, tiff_multipage_img, tiff_multipage_pdf
reason="requires imagemagick with support for keeping the palette depth",
)
@pytest.mark.skipif(
- sys.platform in ["darwin", "win32"],
+ sys.platform in ["win32"],
reason="test utilities not available on Windows and MacOS",
)
def test_tiff_palette1(tmp_path_factory, tiff_palette1_img, tiff_palette1_pdf):
@@ -5728,7 +5943,7 @@ def test_tiff_palette1(tmp_path_factory, tiff_palette1_img, tiff_palette1_pdf):
reason="requires imagemagick with support for keeping the palette depth",
)
@pytest.mark.skipif(
- sys.platform in ["darwin", "win32"],
+ sys.platform in ["win32"],
reason="test utilities not available on Windows and MacOS",
)
def test_tiff_palette2(tmp_path_factory, tiff_palette2_img, tiff_palette2_pdf):
@@ -5744,7 +5959,7 @@ def test_tiff_palette2(tmp_path_factory, tiff_palette2_img, tiff_palette2_pdf):
reason="requires imagemagick with support for keeping the palette depth",
)
@pytest.mark.skipif(
- sys.platform in ["darwin", "win32"],
+ sys.platform in ["win32"],
reason="test utilities not available on Windows and MacOS",
)
def test_tiff_palette4(tmp_path_factory, tiff_palette4_img, tiff_palette4_pdf):
@@ -5756,7 +5971,7 @@ def test_tiff_palette4(tmp_path_factory, tiff_palette4_img, tiff_palette4_pdf):
@pytest.mark.skipif(
- sys.platform in ["darwin", "win32"],
+ sys.platform in ["win32"],
reason="test utilities not available on Windows and MacOS",
)
def test_tiff_palette8(tmp_path_factory, tiff_palette8_img, tiff_palette8_pdf):
@@ -5768,7 +5983,7 @@ def test_tiff_palette8(tmp_path_factory, tiff_palette8_img, tiff_palette8_pdf):
@pytest.mark.skipif(
- sys.platform in ["darwin", "win32"],
+ sys.platform in ["win32"],
reason="test utilities not available on Windows and MacOS",
)
def test_tiff_ccitt_lsb_m2l_white(
@@ -5789,7 +6004,7 @@ def test_tiff_ccitt_lsb_m2l_white(
@pytest.mark.skipif(
- sys.platform in ["darwin", "win32"],
+ sys.platform in ["win32"],
reason="test utilities not available on Windows and MacOS",
)
def test_tiff_ccitt_msb_m2l_white(
@@ -5810,7 +6025,7 @@ def test_tiff_ccitt_msb_m2l_white(
@pytest.mark.skipif(
- sys.platform in ["darwin", "win32"],
+ sys.platform in ["win32"],
reason="test utilities not available on Windows and MacOS",
)
def test_tiff_ccitt_msb_l2m_white(
@@ -5835,7 +6050,7 @@ def test_tiff_ccitt_msb_l2m_white(
reason="requires imagemagick with support for min-is-black",
)
@pytest.mark.skipif(
- sys.platform in ["darwin", "win32"],
+ sys.platform in ["win32"],
reason="test utilities not available on Windows and MacOS",
)
def test_tiff_ccitt_lsb_m2l_black(
@@ -5856,7 +6071,7 @@ def test_tiff_ccitt_lsb_m2l_black(
@pytest.mark.skipif(
- sys.platform in ["darwin", "win32"],
+ sys.platform in ["win32"],
reason="test utilities not available on Windows and MacOS",
)
def test_tiff_ccitt_nometa1(
@@ -5872,7 +6087,7 @@ def test_tiff_ccitt_nometa1(
@pytest.mark.skipif(
- sys.platform in ["darwin", "win32"],
+ sys.platform in ["win32"],
reason="test utilities not available on Windows and MacOS",
)
def test_tiff_ccitt_nometa2(
@@ -6318,7 +6533,7 @@ def general_input(request):
return request.param
-@pytest.mark.parametrize("engine", ["internal", "pikepdf", "pdfrw"])
+@pytest.mark.parametrize("engine", ["internal", "pikepdf"])
def test_general(general_input, engine):
inputf = os.path.join(os.path.dirname(__file__), "tests", "input", general_input)
outputf = os.path.join(
@@ -6330,10 +6545,6 @@ def test_general(general_input, engine):
engine = getattr(img2pdf.Engine, engine)
- # we do not test animation.gif with pdfrw because it doesn't support
- # saving hexadecimal palette data
- if f.endswith(os.path.sep + "animation.gif") and engine == img2pdf.Engine.pdfrw:
- return
with open(f, "rb") as inf:
orig_imgdata = inf.read()
output = img2pdf.convert(orig_imgdata, nodate=True, engine=engine)
@@ -6389,9 +6600,13 @@ def test_general(general_input, engine):
assert cur_page.Resources.XObject.keys() == {"/Im0"}
if engine != img2pdf.Engine.pikepdf:
assert cur_page.Contents.Length == len(cur_page.Contents.read_bytes())
- assert cur_page.Contents.read_bytes() == b"q\n%.4f 0 0 %.4f 0.0000 0.0000 cm\n/Im0 Do\nQ" % (
- pagewidth,
- pageheight,
+ assert (
+ cur_page.Contents.read_bytes()
+ == b"q\n%.4f 0 0 %.4f 0.0000 0.0000 cm\n/Im0 Do\nQ"
+ % (
+ pagewidth,
+ pageheight,
+ )
)
imgprops = cur_page.Resources.XObject.Im0
@@ -6493,10 +6708,57 @@ def test_general(general_input, engine):
raise Exception("unhandled: %s" % (type(obj)))
y = pikepdf.open(out)
- assert rec(x.Root) == rec(y.Root)
+ pydictx = rec(x.Root)
+ pydicty = rec(y.Root)
+ if f.endswith(os.path.sep + "animation.gif"):
+ # starting with PIL 8.2.0 the palette is half the size when encoding
+ # our test GIF image as PNG
+ #
+ # to still compare successfully, we truncate the expected palette
+ import PIL
+
+ if PIL.__version__ >= "8.2.0":
+ assert len(pydictx["/Pages"]["/Kids"]) == 2
+ for p in pydictx["/Pages"]["/Kids"]:
+ assert p["/Resources"]["/XObject"]["/Im0"]["/ColorSpace"][2] == 127
+ assert len(pydicty["/Pages"]["/Kids"]) == 2
+ for p in pydicty["/Pages"]["/Kids"]:
+ cs = p["/Resources"]["/XObject"]["/Im0"]["/ColorSpace"]
+ cs[2] = decimal.Decimal("127")
+ cs[3] = cs[3][:384]
+ else:
+ assert (
+ pydictx["/Pages"]["/Kids"][0]["/Resources"]["/XObject"]["/Im0"][
+ "/ColorSpace"
+ ][2]
+ == 255
+ )
+ assert pydictx == pydicty
# the python-pil version 2.3.0-1ubuntu3 in Ubuntu does not have the
# close() method
try:
orig_img.close()
except AttributeError:
pass
+
+
+def main():
+ normal16 = alpha_value()[:, :, 0:3]
+ pathlib.Path("test.icc").write_bytes(icc_profile())
+ write_png(
+ normal16 / 0xFFFF * 0xFF,
+ "icc.png",
+ 8,
+ 2,
+ iccp="test.icc",
+ )
+ write_png(
+ normal16 / 0xFFFF * 0xFF,
+ "normal.png",
+ 8,
+ 2,
+ )
+
+
+if __name__ == "__main__":
+ main()
diff --git a/test.sh b/test.sh
deleted file mode 100755
index f33e036..0000000
--- a/test.sh
+++ /dev/null
@@ -1,1631 +0,0 @@
-#!/bin/sh
-
-set -eu
-
-similar()
-{
- psnr=$(compare -metric PSNR "$1" "$2" null: 2>&1 || true)
- if [ -z "$psnr" ]; then
- echo "compare failed"
- return 1
- fi
-
- # PSNR of zero means that they are identical
- if [ "$psnr" = 0 ]; then
- echo "images are equal -- don't use similar() but require exactness"
- exit 2
- fi
-
- # The lower PSNR value, the fewer the similarities
- # The lowest (and worst) value is 1.0
- # head -n == --lines, but more portable (MacOS)
- min_psnr=50
- if [ "$min_psnr" != "$( printf "$psnr\n$min_psnr\n" | sort --general-numeric-sort | head -n1)" ]; then
- echo "pdf wrongly rendered"
- return 1
- fi
- return 0
-}
-
-compare_rendered()
-{
- pdf="$1"
- img="$2"
- gsdevice=png16m
- if [ "$#" -eq 3 ]; then
- gsdevice="$3"
- fi
-
- compare_ghostscript "$pdf" "$img" "$gsdevice"
-
- compare_poppler "$pdf" "$img"
-
- compare_mupdf "$pdf" "$img"
-}
-
-compare_ghostscript()
-{
- pdf="$1"
- img="$2"
- gsdevice="$3"
- gs -dQUIET -dNOPAUSE -dBATCH -sDEVICE="$gsdevice" -r96 -sOutputFile="$tempdir/gs-%00d.png" "$pdf"
- compare -metric AE "$img" "$tempdir/gs-1.png" null: 2>/dev/null
- rm "$tempdir/gs-1.png"
-}
-
-compare_poppler()
-{
- pdf="$1"
- img="$2"
- pdftocairo -r 96 -png "$pdf" "$tempdir/poppler"
- compare -metric AE "$img" "$tempdir/poppler-1.png" null: 2>/dev/null
- rm "$tempdir/poppler-1.png"
-}
-
-compare_mupdf()
-{
- pdf="$1"
- img="$2"
- mutool draw -o "$tempdir/mupdf.png" -r 96 "$pdf" 2>/dev/null
- if [ "$(uname)" != "Darwin" ]; then # mupdf is not pixel perfect on Darwin
- compare -metric AE "$img" "$tempdir/mupdf.png" null: 2>/dev/null
- fi
- rm "$tempdir/mupdf.png"
-}
-
-compare_pdfimages()
-{
- pdf="$1"
- img="$2"
- pdfimages -png "$pdf" "$tempdir/images"
- compare -metric AE "$img" "$tempdir/images-000.png" null: 2>/dev/null
- rm "$tempdir/images-000.png"
-}
-
-checkpdf()
-{
- python3 -c 'import pikepdf,sys; p=pikepdf.open(sys.argv[1]);exit(sum([not eval("p.pages[0]."+l) for l in sys.stdin]))' "$1"
-}
-
-error()
-{
- echo test $j failed
- echo intermediate data is left in $tempdir
- exit 1
-}
-
-# -d == --directory, -t == --template, but more portable (MacOS, FreeBSD)
-tempdir=$(mktemp -d -t img2pdf.XXXXXXXXXX)
-
-trap error EXIT
-
-# instead of using imagemagick to craft the test input, we use a custom python
-# script. This is because the output of imagemagick is not bit-by-bit identical
-# across versions and architectures.
-# See https://gitlab.mister-muffin.de/josch/img2pdf/issues/56
-python3 magick.py "$tempdir"
-
-if [ "$(uname)" = "Darwin" ]; then
- status_arg=
-else
- status_arg=--status
-fi
-
-cat << END | ( cd "$tempdir"; md5sum --check $status_arg - )
-cc611e80cde3b9b7adb7723801a4e5d4 alpha.png
-706175887af8ca1a33cfd93449f970df gray16.png
-ff4d9f18de39be879926be2e65990167 gray1.png
-d51900476658a1c9dd26a7b27db8a21f gray2.png
-722223ba74be9cba1af4a549076b70d3 gray4.png
-2320216faa5a10bf0f5f04ebce07f8e1 gray8.png
-35a47d6ae6de8c9d0b31aa0cda8648f3 inverse.png
-6ad810399058a87d8145d8d9a7734da5 normal16.png
-c8d2e1f116f31ecdeae050524efca7b6 normal.png
-18a3dfca369f976996ef93389ddfad61 palette1.png
-d38646afa6fa0714be9badef25ff9392 palette2.png
-e1c59e68a68fca3273b6dc164d526ed7 palette4.png
-50bf09eb3571901f0bf642b9a733038c palette8.png
-END
-
-# use img2pdfprog environment variable if it is set
-if [ -z ${img2pdfprog+x} ]; then
- img2pdfprog=src/img2pdf.py
-fi
-
-available_engines="internal"
-
-if python3 -c "import pdfrw" 2>/dev/null; then
- available_engines="$available_engines pdfrw"
-fi
-if python3 -c "import pikepdf" 2>/dev/null; then
- available_engines="$available_engines pikepdf"
-fi
-
-img2pdf()
-{
- $img2pdfprog --producer="" --nodate --engine="$1" "$2" > "$3" 2>/dev/null
-}
-
-tests=51 # number of tests
-j=1 # current test
-
-###############################################################################
-echo "Test $j/$tests JPEG"
-
-convert "$tempdir/normal.png" "$tempdir/normal.jpg"
-
-identify -verbose "$tempdir/normal.jpg" | grep --quiet '^ Format: JPEG (Joint Photographic Experts Group JFIF format)$'
-identify -verbose "$tempdir/normal.jpg" | grep --quiet '^ Mime type: image/jpeg$'
-identify -verbose "$tempdir/normal.jpg" | grep --quiet '^ Geometry: 60x60+0+0$'
-identify -verbose "$tempdir/normal.jpg" | grep --quiet '^ Colorspace: sRGB$'
-identify -verbose "$tempdir/normal.jpg" | grep --quiet '^ Type: TrueColor$'
-identify -verbose "$tempdir/normal.jpg" | grep --quiet '^ Depth: 8-bit$'
-identify -verbose "$tempdir/normal.jpg" | grep --quiet '^ Page geometry: 60x60+0+0$'
-identify -verbose "$tempdir/normal.jpg" | grep --quiet '^ Compression: JPEG$'
-
-for engine in $available_engines; do
-img2pdf $engine "$tempdir/normal.jpg" "$tempdir/out.pdf"
-
-# We have to use jpegtopnm with the original JPG before being able to compare
-# it with imagemagick because imagemagick will decode the JPG slightly
-# differently than ghostscript, poppler and mupdf do it.
-# We have to use jpegtopnm and cannot use djpeg because the latter produces
-# slightly different results as well when called like this:
-# djpeg -dct int -pnm "$tempdir/normal.jpg" > "$tempdir/normal.pnm"
-# An alternative way to compare the JPG would be to require a different DCT
-# method when decoding by setting -define jpeg:dct-method=ifast in the
-# compare command.
-jpegtopnm -dct int "$tempdir/normal.jpg" > "$tempdir/normal.pnm" 2>/dev/null
-
-compare_rendered "$tempdir/out.pdf" "$tempdir/normal.pnm"
-
-pdfimages -j "$tempdir/out.pdf" "$tempdir/images"
-cmp "$tempdir/normal.jpg" "$tempdir/images-000.jpg"
-rm "$tempdir/images-000.jpg"
-
-cat << 'END' | checkpdf "$tempdir/out.pdf"
-Contents.read_bytes() == b'q\n45.0000 0 0 45.0000 0.0000 0.0000 cm\n/Im0 Do\nQ'
-Resources.XObject.Im0.BitsPerComponent == 8
-Resources.XObject.Im0.ColorSpace == "/DeviceRGB"
-Resources.XObject.Im0.Filter == "/DCTDecode"
-Resources.XObject.Im0.Height == 60
-Resources.XObject.Im0.Width == 60
-END
-rm "$tempdir/out.pdf"
-done
-
-rm "$tempdir/normal.jpg" "$tempdir/normal.pnm"
-j=$((j+1))
-
-###############################################################################
-echo "Test $j/$tests JPEG (90° rotated)"
-
-convert "$tempdir/normal.png" "$tempdir/normal.jpg"
-exiftool -overwrite_original -all= "$tempdir/normal.jpg" -n >/dev/null
-exiftool -overwrite_original -Orientation=6 -XResolution=96 -YResolution=96 -n "$tempdir/normal.jpg" >/dev/null
-
-identify -verbose "$tempdir/normal.jpg" | grep --quiet '^ Format: JPEG (Joint Photographic Experts Group JFIF format)$'
-identify -verbose "$tempdir/normal.jpg" | grep --quiet '^ Mime type: image/jpeg$'
-identify -verbose "$tempdir/normal.jpg" | grep --quiet '^ Geometry: 60x60+0+0$'
-identify -verbose "$tempdir/normal.jpg" | grep --quiet '^ Resolution: 96x96$'
-identify -verbose "$tempdir/normal.jpg" | grep --quiet '^ Units: PixelsPerInch$'
-identify -verbose "$tempdir/normal.jpg" | grep --quiet '^ Colorspace: sRGB$'
-identify -verbose "$tempdir/normal.jpg" | grep --quiet '^ Type: TrueColor$'
-identify -verbose "$tempdir/normal.jpg" | grep --quiet '^ Depth: 8-bit$'
-identify -verbose "$tempdir/normal.jpg" | grep --quiet '^ Page geometry: 60x60+0+0$'
-identify -verbose "$tempdir/normal.jpg" | grep --quiet '^ Compression: JPEG$'
-identify -verbose "$tempdir/normal.jpg" | grep --quiet '^ Orientation: RightTop$'
-
-for engine in $available_engines; do
-img2pdf $engine "$tempdir/normal.jpg" "$tempdir/out.pdf"
-
-# We have to use jpegtopnm with the original JPG before being able to compare
-# it with imagemagick because imagemagick will decode the JPG slightly
-# differently than ghostscript, poppler and mupdf do it.
-# We have to use jpegtopnm and cannot use djpeg because the latter produces
-# slightly different results as well when called like this:
-# djpeg -dct int -pnm "$tempdir/normal.jpg" > "$tempdir/normal.pnm"
-# An alternative way to compare the JPG would be to require a different DCT
-# method when decoding by setting -define jpeg:dct-method=ifast in the
-# compare command.
-jpegtopnm -dct int "$tempdir/normal.jpg" > "$tempdir/normal.pnm" 2>/dev/null
-convert -rotate "90" "$tempdir/normal.pnm" "$tempdir/normal_rotated.png"
-#convert -rotate "0" "$tempdir/normal.pnm" "$tempdir/normal_rotated.png"
-
-compare_rendered "$tempdir/out.pdf" "$tempdir/normal_rotated.png"
-
-pdfimages -j "$tempdir/out.pdf" "$tempdir/images"
-cmp "$tempdir/normal.jpg" "$tempdir/images-000.jpg"
-rm "$tempdir/images-000.jpg"
-
-cat << 'END' | checkpdf "$tempdir/out.pdf"
-Contents.read_bytes() == b'q\n45.0000 0 0 45.0000 0.0000 0.0000 cm\n/Im0 Do\nQ'
-Resources.XObject.Im0.BitsPerComponent == 8
-Resources.XObject.Im0.ColorSpace == "/DeviceRGB"
-Resources.XObject.Im0.Filter == "/DCTDecode"
-Resources.XObject.Im0.Height == 60
-Resources.XObject.Im0.Width == 60
-Rotate == 90
-END
-rm "$tempdir/out.pdf"
-done
-
-rm "$tempdir/normal.jpg" "$tempdir/normal.pnm" "$tempdir/normal_rotated.png"
-j=$((j+1))
-
-###############################################################################
-echo "Test $j/$tests JPEG CMYK"
-
-convert "$tempdir/normal.png" -colorspace cmyk "$tempdir/normal.jpg"
-
-identify -verbose "$tempdir/normal.jpg" | grep --quiet '^ Format: JPEG (Joint Photographic Experts Group JFIF format)$'
-identify -verbose "$tempdir/normal.jpg" | grep --quiet '^ Mime type: image/jpeg$'
-identify -verbose "$tempdir/normal.jpg" | grep --quiet '^ Geometry: 60x60+0+0$'
-identify -verbose "$tempdir/normal.jpg" | grep --quiet '^ Colorspace: CMYK$'
-identify -verbose "$tempdir/normal.jpg" | grep --quiet '^ Type: ColorSeparation$'
-identify -verbose "$tempdir/normal.jpg" | grep --quiet '^ Depth: 8-bit$'
-identify -verbose "$tempdir/normal.jpg" | grep --quiet '^ Page geometry: 60x60+0+0$'
-identify -verbose "$tempdir/normal.jpg" | grep --quiet '^ Compression: JPEG$'
-
-for engine in $available_engines; do
-img2pdf $engine "$tempdir/normal.jpg" "$tempdir/out.pdf"
-
-gs -dQUIET -dNOPAUSE -dBATCH -sDEVICE=tiff32nc -r96 -sOutputFile="$tempdir/gs-%00d.tiff" "$tempdir/out.pdf"
-similar "$tempdir/normal.jpg" "$tempdir/gs-1.tiff"
-rm "$tempdir/gs-1.tiff"
-
-# not testing with poppler as it cannot write CMYK images
-
-mutool draw -o "$tempdir/mupdf.pam" -r 96 -c cmyk "$pdf" 2>/dev/null
-similar "$tempdir/normal.jpg" "$tempdir/mupdf.pam"
-rm "$tempdir/mupdf.pam"
-
-pdfimages -j "$tempdir/out.pdf" "$tempdir/images"
-cmp "$tempdir/normal.jpg" "$tempdir/images-000.jpg"
-rm "$tempdir/images-000.jpg"
-
-cat << 'END' | checkpdf "$tempdir/out.pdf"
-Contents.read_bytes() == b'q\n45.0000 0 0 45.0000 0.0000 0.0000 cm\n/Im0 Do\nQ'
-Resources.XObject.Im0.BitsPerComponent == 8
-Resources.XObject.Im0.ColorSpace == "/DeviceCMYK"
-Resources.XObject.Im0.Decode == pikepdf.Array([ 1, 0, 1, 0, 1, 0, 1, 0 ])
-Resources.XObject.Im0.Filter == "/DCTDecode"
-Resources.XObject.Im0.Height == 60
-Resources.XObject.Im0.Width == 60
-END
-rm "$tempdir/out.pdf"
-done
-
-rm "$tempdir/normal.jpg"
-j=$((j+1))
-
-###############################################################################
-echo "Test $j/$tests JPEG2000"
-
-convert "$tempdir/normal.png" "$tempdir/normal.jp2"
-
-identify -verbose "$tempdir/normal.jp2" | grep --quiet '^ Format: JP2 (JPEG-2000 File Format Syntax)$'
-identify -verbose "$tempdir/normal.jp2" | grep --quiet '^ Mime type: image/jp2$'
-identify -verbose "$tempdir/normal.jp2" | grep --quiet '^ Geometry: 60x60+0+0$'
-identify -verbose "$tempdir/normal.jp2" | grep --quiet '^ Colorspace: sRGB$'
-identify -verbose "$tempdir/normal.jp2" | grep --quiet '^ Type: TrueColor$'
-identify -verbose "$tempdir/normal.jp2" | grep --quiet '^ Depth: 8-bit$'
-identify -verbose "$tempdir/normal.jp2" | grep --quiet '^ Page geometry: 60x60+0+0$'
-identify -verbose "$tempdir/normal.jp2" | grep --quiet '^ Compression: JPEG2000$'
-
-for engine in $available_engines; do
-img2pdf $engine "$tempdir/normal.jp2" "$tempdir/out.pdf"
-
-compare_rendered "$tempdir/out.pdf" "$tempdir/normal.jp2"
-
-pdfimages -jp2 "$tempdir/out.pdf" "$tempdir/images"
-cmp "$tempdir/normal.jp2" "$tempdir/images-000.jp2"
-rm "$tempdir/images-000.jp2"
-
-cat << 'END' | checkpdf "$tempdir/out.pdf"
-Contents.read_bytes() == b'q\n45.0000 0 0 45.0000 0.0000 0.0000 cm\n/Im0 Do\nQ'
-Resources.XObject.Im0.BitsPerComponent == 8
-Resources.XObject.Im0.ColorSpace == "/DeviceRGB"
-Resources.XObject.Im0.Filter == "/JPXDecode"
-Resources.XObject.Im0.Height == 60
-Resources.XObject.Im0.Width == 60
-END
-rm "$tempdir/out.pdf"
-done
-
-rm "$tempdir/normal.jp2"
-j=$((j+1))
-
-###############################################################################
-#echo Test JPEG2000 CMYK
-#
-# cannot test because imagemagick does not support JPEG2000 CMYK
-
-###############################################################################
-echo "Test $j/$tests PNG RGB8"
-
-identify -verbose "$tempdir/normal.png" | grep --quiet '^ Format: PNG (Portable Network Graphics)$'
-identify -verbose "$tempdir/normal.png" | grep --quiet '^ Mime type: image/png$'
-identify -verbose "$tempdir/normal.png" | grep --quiet '^ Geometry: 60x60+0+0$'
-identify -verbose "$tempdir/normal.png" | grep --quiet '^ Colorspace: sRGB$'
-identify -verbose "$tempdir/normal.png" | grep --quiet '^ Type: TrueColor$'
-identify -verbose "$tempdir/normal.png" | grep --quiet '^ Depth: 8-bit$'
-identify -verbose "$tempdir/normal.png" | grep --quiet '^ Page geometry: 60x60+0+0$'
-identify -verbose "$tempdir/normal.png" | grep --quiet '^ Compression: Zip$'
-identify -verbose "$tempdir/normal.png" | grep --quiet '^ png:IHDR.bit-depth-orig: 8$'
-identify -verbose "$tempdir/normal.png" | grep --quiet '^ png:IHDR.bit_depth: 8$'
-identify -verbose "$tempdir/normal.png" | grep --quiet '^ png:IHDR.color-type-orig: 2$'
-identify -verbose "$tempdir/normal.png" | grep --quiet '^ png:IHDR.color_type: 2 (Truecolor)$'
-identify -verbose "$tempdir/normal.png" | grep --quiet '^ png:IHDR.interlace_method: 0 (Not interlaced)$'
-
-for engine in $available_engines; do
-img2pdf $engine "$tempdir/normal.png" "$tempdir/out.pdf"
-
-compare_rendered "$tempdir/out.pdf" "$tempdir/normal.png"
-
-compare_pdfimages "$tempdir/out.pdf" "$tempdir/normal.png"
-
-cat << 'END' | checkpdf "$tempdir/out.pdf"
-Contents.read_bytes() == b'q\n45.0000 0 0 45.0000 0.0000 0.0000 cm\n/Im0 Do\nQ'
-Resources.XObject.Im0.BitsPerComponent == 8
-Resources.XObject.Im0.ColorSpace == "/DeviceRGB"
-Resources.XObject.Im0.DecodeParms.BitsPerComponent == 8
-Resources.XObject.Im0.DecodeParms.Colors == 3
-Resources.XObject.Im0.DecodeParms.Predictor == 15
-Resources.XObject.Im0.Filter == "/FlateDecode"
-Resources.XObject.Im0.Height == 60
-Resources.XObject.Im0.Width == 60
-END
-rm "$tempdir/out.pdf"
-done
-
-j=$((j+1))
-
-###############################################################################
-echo "Test $j/$tests PNG RGB16"
-
-identify -verbose "$tempdir/normal16.png" | grep --quiet '^ Format: PNG (Portable Network Graphics)$'
-identify -verbose "$tempdir/normal16.png" | grep --quiet '^ Mime type: image/png$'
-identify -verbose "$tempdir/normal16.png" | grep --quiet '^ Geometry: 60x60+0+0$'
-identify -verbose "$tempdir/normal16.png" | grep --quiet '^ Colorspace: sRGB$'
-identify -verbose "$tempdir/normal16.png" | grep --quiet '^ Type: TrueColor$'
-identify -verbose "$tempdir/normal16.png" | grep --quiet '^ Depth: 16-bit$'
-identify -verbose "$tempdir/normal16.png" | grep --quiet '^ Page geometry: 60x60+0+0$'
-identify -verbose "$tempdir/normal16.png" | grep --quiet '^ Compression: Zip$'
-identify -verbose "$tempdir/normal16.png" | grep --quiet '^ png:IHDR.bit-depth-orig: 16$'
-identify -verbose "$tempdir/normal16.png" | grep --quiet '^ png:IHDR.bit_depth: 16$'
-identify -verbose "$tempdir/normal16.png" | grep --quiet '^ png:IHDR.color-type-orig: 2$'
-identify -verbose "$tempdir/normal16.png" | grep --quiet '^ png:IHDR.color_type: 2 (Truecolor)$'
-identify -verbose "$tempdir/normal16.png" | grep --quiet '^ png:IHDR.interlace_method: 0 (Not interlaced)$'
-
-for engine in $available_engines; do
-img2pdf $engine "$tempdir/normal16.png" "$tempdir/out.pdf"
-
-compare_ghostscript "$tempdir/out.pdf" "$tempdir/normal16.png" tiff48nc
-
-# poppler outputs 8-bit RGB so the comparison will not be exact
-pdftocairo -r 96 -png "$tempdir/out.pdf" "$tempdir/poppler"
-similar "$tempdir/normal16.png" "$tempdir/poppler-1.png"
-rm "$tempdir/poppler-1.png"
-
-# pdfimages is unable to write 16 bit output
-
-cat << 'END' | checkpdf "$tempdir/out.pdf"
-Contents.read_bytes() == b'q\n45.0000 0 0 45.0000 0.0000 0.0000 cm\n/Im0 Do\nQ'
-Resources.XObject.Im0.BitsPerComponent == 16
-Resources.XObject.Im0.ColorSpace == "/DeviceRGB"
-Resources.XObject.Im0.DecodeParms.BitsPerComponent == 16
-Resources.XObject.Im0.DecodeParms.Colors == 3
-Resources.XObject.Im0.DecodeParms.Predictor == 15
-Resources.XObject.Im0.Filter == "/FlateDecode"
-Resources.XObject.Im0.Height == 60
-Resources.XObject.Im0.Width == 60
-END
-rm "$tempdir/out.pdf"
-done
-
-j=$((j+1))
-
-###############################################################################
-echo "Test $j/$tests PNG RGBA8"
-
-convert "$tempdir/alpha.png" -depth 8 -strip "$tempdir/alpha8.png"
-
-identify -verbose "$tempdir/alpha8.png" | grep --quiet '^ Format: PNG (Portable Network Graphics)$'
-identify -verbose "$tempdir/alpha8.png" | grep --quiet '^ Mime type: image/png$'
-identify -verbose "$tempdir/alpha8.png" | grep --quiet '^ Geometry: 60x60+0+0$'
-identify -verbose "$tempdir/alpha8.png" | grep --quiet '^ Colorspace: sRGB$'
-identify -verbose "$tempdir/alpha8.png" | grep --quiet '^ Type: TrueColorAlpha$'
-identify -verbose "$tempdir/alpha8.png" | grep --quiet '^ Depth: 8-bit$'
-identify -verbose "$tempdir/alpha8.png" | grep --quiet '^ Page geometry: 60x60+0+0$'
-identify -verbose "$tempdir/alpha8.png" | grep --quiet '^ Compression: Zip$'
-identify -verbose "$tempdir/alpha8.png" | grep --quiet '^ png:IHDR.bit-depth-orig: 8$'
-identify -verbose "$tempdir/alpha8.png" | grep --quiet '^ png:IHDR.bit_depth: 8$'
-identify -verbose "$tempdir/alpha8.png" | grep --quiet '^ png:IHDR.color-type-orig: 6$'
-identify -verbose "$tempdir/alpha8.png" | grep --quiet '^ png:IHDR.color_type: 6 (RGBA)$'
-identify -verbose "$tempdir/alpha8.png" | grep --quiet '^ png:IHDR.interlace_method: 0 (Not interlaced)$'
-
-for engine in $available_engines; do
-img2pdf $engine "$tempdir/alpha8.png" /dev/null && rc=$? || rc=$?
-if [ "$rc" -eq 0 ]; then
- echo needs to fail here
- exit 1
-fi
-done
-
-rm "$tempdir/alpha8.png"
-j=$((j+1))
-
-###############################################################################
-echo "Test $j/$tests PNG RGBA16"
-
-identify -verbose "$tempdir/alpha.png" | grep --quiet '^ Format: PNG (Portable Network Graphics)$'
-identify -verbose "$tempdir/alpha.png" | grep --quiet '^ Mime type: image/png$'
-identify -verbose "$tempdir/alpha.png" | grep --quiet '^ Geometry: 60x60+0+0$'
-identify -verbose "$tempdir/alpha.png" | grep --quiet '^ Colorspace: sRGB$'
-identify -verbose "$tempdir/alpha.png" | grep --quiet '^ Type: TrueColorAlpha$'
-identify -verbose "$tempdir/alpha.png" | grep --quiet '^ Depth: 16-bit$'
-identify -verbose "$tempdir/alpha.png" | grep --quiet '^ Page geometry: 60x60+0+0$'
-identify -verbose "$tempdir/alpha.png" | grep --quiet '^ Compression: Zip$'
-identify -verbose "$tempdir/alpha.png" | grep --quiet '^ png:IHDR.bit-depth-orig: 16$'
-identify -verbose "$tempdir/alpha.png" | grep --quiet '^ png:IHDR.bit_depth: 16$'
-identify -verbose "$tempdir/alpha.png" | grep --quiet '^ png:IHDR.color-type-orig: 6$'
-identify -verbose "$tempdir/alpha.png" | grep --quiet '^ png:IHDR.color_type: 6 (RGBA)$'
-identify -verbose "$tempdir/alpha.png" | grep --quiet '^ png:IHDR.interlace_method: 0 (Not interlaced)$'
-
-for engine in $available_engines; do
-img2pdf $engine "$tempdir/alpha.png" /dev/null && rc=$? || rc=$?
-if [ "$rc" -eq 0 ]; then
- echo needs to fail here
- exit 1
-fi
-done
-
-j=$((j+1))
-
-###############################################################################
-echo "Test $j/$tests PNG Gray8 Alpha"
-
-convert "$tempdir/alpha.png" -colorspace Gray -dither FloydSteinberg -colors 256 -depth 8 -strip "$tempdir/alpha_gray8.png"
-
-identify -verbose "$tempdir/alpha_gray8.png" | grep --quiet '^ Format: PNG (Portable Network Graphics)$'
-identify -verbose "$tempdir/alpha_gray8.png" | grep --quiet '^ Mime type: image/png$'
-identify -verbose "$tempdir/alpha_gray8.png" | grep --quiet '^ Geometry: 60x60+0+0$'
-identify -verbose "$tempdir/alpha_gray8.png" | grep --quiet '^ Colorspace: Gray$'
-identify -verbose "$tempdir/alpha_gray8.png" | grep --quiet '^ Type: GrayscaleAlpha$'
-identify -verbose "$tempdir/alpha_gray8.png" | grep --quiet '^ Depth: 8-bit$'
-identify -verbose "$tempdir/alpha_gray8.png" | grep --quiet '^ Page geometry: 60x60+0+0$'
-identify -verbose "$tempdir/alpha_gray8.png" | grep --quiet '^ Compression: Zip$'
-identify -verbose "$tempdir/alpha_gray8.png" | grep --quiet '^ png:IHDR.bit-depth-orig: 8$'
-identify -verbose "$tempdir/alpha_gray8.png" | grep --quiet '^ png:IHDR.bit_depth: 8$'
-identify -verbose "$tempdir/alpha_gray8.png" | grep --quiet '^ png:IHDR.color-type-orig: 4$'
-identify -verbose "$tempdir/alpha_gray8.png" | grep --quiet '^ png:IHDR.color_type: 4 (GrayAlpha)$'
-identify -verbose "$tempdir/alpha_gray8.png" | grep --quiet '^ png:IHDR.interlace_method: 0 (Not interlaced)$'
-
-for engine in $available_engines; do
-img2pdf $engine "$tempdir/alpha_gray8.png" /dev/null && rc=$? || rc=$?
-if [ "$rc" -eq 0 ]; then
- echo needs to fail here
- exit 1
-fi
-done
-
-rm "$tempdir/alpha_gray8.png"
-j=$((j+1))
-
-###############################################################################
-echo "Test $j/$tests PNG Gray16 Alpha"
-
-convert "$tempdir/alpha.png" -colorspace Gray -depth 16 -strip "$tempdir/alpha_gray16.png"
-
-identify -verbose "$tempdir/alpha_gray16.png" | grep --quiet '^ Format: PNG (Portable Network Graphics)$'
-identify -verbose "$tempdir/alpha_gray16.png" | grep --quiet '^ Mime type: image/png$'
-identify -verbose "$tempdir/alpha_gray16.png" | grep --quiet '^ Geometry: 60x60+0+0$'
-identify -verbose "$tempdir/alpha_gray16.png" | grep --quiet '^ Colorspace: Gray$'
-identify -verbose "$tempdir/alpha_gray16.png" | grep --quiet '^ Type: GrayscaleAlpha$'
-identify -verbose "$tempdir/alpha_gray16.png" | grep --quiet '^ Depth: 16-bit$'
-identify -verbose "$tempdir/alpha_gray16.png" | grep --quiet '^ Page geometry: 60x60+0+0$'
-identify -verbose "$tempdir/alpha_gray16.png" | grep --quiet '^ Compression: Zip$'
-identify -verbose "$tempdir/alpha_gray16.png" | grep --quiet '^ png:IHDR.bit-depth-orig: 16$'
-identify -verbose "$tempdir/alpha_gray16.png" | grep --quiet '^ png:IHDR.bit_depth: 16$'
-identify -verbose "$tempdir/alpha_gray16.png" | grep --quiet '^ png:IHDR.color-type-orig: 4$'
-identify -verbose "$tempdir/alpha_gray16.png" | grep --quiet '^ png:IHDR.color_type: 4 (GrayAlpha)$'
-identify -verbose "$tempdir/alpha_gray16.png" | grep --quiet '^ png:IHDR.interlace_method: 0 (Not interlaced)$'
-
-for engine in $available_engines; do
-img2pdf $engine "$tempdir/alpha_gray16.png" /dev/null && rc=$? || rc=$?
-if [ "$rc" -eq 0 ]; then
- echo needs to fail here
- exit 1
-fi
-done
-
-rm "$tempdir/alpha_gray16.png"
-j=$((j+1))
-
-###############################################################################
-echo "Test $j/$tests PNG interlaced"
-
-convert "$tempdir/normal.png" -interlace PNG -strip "$tempdir/interlace.png"
-
-identify -verbose "$tempdir/interlace.png" | grep --quiet '^ Format: PNG (Portable Network Graphics)$'
-identify -verbose "$tempdir/interlace.png" | grep --quiet '^ Mime type: image/png$'
-identify -verbose "$tempdir/interlace.png" | grep --quiet '^ Geometry: 60x60+0+0$'
-identify -verbose "$tempdir/interlace.png" | grep --quiet '^ Colorspace: sRGB$'
-identify -verbose "$tempdir/interlace.png" | grep --quiet '^ Type: TrueColor$'
-identify -verbose "$tempdir/interlace.png" | grep --quiet '^ Depth: 8-bit$'
-identify -verbose "$tempdir/interlace.png" | grep --quiet '^ Page geometry: 60x60+0+0$'
-identify -verbose "$tempdir/interlace.png" | grep --quiet '^ Compression: Zip$'
-identify -verbose "$tempdir/interlace.png" | grep --quiet '^ png:IHDR.bit-depth-orig: 8$'
-identify -verbose "$tempdir/interlace.png" | grep --quiet '^ png:IHDR.bit_depth: 8$'
-identify -verbose "$tempdir/interlace.png" | grep --quiet '^ png:IHDR.color-type-orig: 2$'
-identify -verbose "$tempdir/interlace.png" | grep --quiet '^ png:IHDR.color_type: 2 (Truecolor)$'
-identify -verbose "$tempdir/interlace.png" | grep --quiet '^ png:IHDR.interlace_method: 1 (Adam7 method)$'
-
-for engine in $available_engines; do
-img2pdf $engine "$tempdir/interlace.png" "$tempdir/out.pdf"
-
-compare_rendered "$tempdir/out.pdf" "$tempdir/normal.png"
-
-compare_pdfimages "$tempdir/out.pdf" "$tempdir/normal.png"
-
-cat << 'END' | checkpdf "$tempdir/out.pdf"
-Contents.read_bytes() == b'q\n45.0000 0 0 45.0000 0.0000 0.0000 cm\n/Im0 Do\nQ'
-Resources.XObject.Im0.BitsPerComponent == 8
-Resources.XObject.Im0.ColorSpace == "/DeviceRGB"
-Resources.XObject.Im0.DecodeParms.BitsPerComponent == 8
-Resources.XObject.Im0.DecodeParms.Colors == 3
-Resources.XObject.Im0.DecodeParms.Predictor == 15
-Resources.XObject.Im0.Filter == "/FlateDecode"
-Resources.XObject.Im0.Height == 60
-Resources.XObject.Im0.Width == 60
-END
-rm "$tempdir/out.pdf"
-done
-
-rm "$tempdir/interlace.png"
-j=$((j+1))
-
-###############################################################################
-for i in 1 2 4 8; do
- echo "Test $j/$tests PNG Gray$i"
-
- identify -verbose "$tempdir/gray$i.png" | grep --quiet '^ Format: PNG (Portable Network Graphics)$'
- identify -verbose "$tempdir/gray$i.png" | grep --quiet '^ Mime type: image/png$'
- identify -verbose "$tempdir/gray$i.png" | grep --quiet '^ Geometry: 60x60+0+0$'
- identify -verbose "$tempdir/gray$i.png" | grep --quiet '^ Colorspace: Gray$'
- if [ "$i" -eq 1 ]; then
- identify -verbose "$tempdir/gray$i.png" | grep --quiet '^ Type: Bilevel$'
- else
- identify -verbose "$tempdir/gray$i.png" | grep --quiet '^ Type: Grayscale$'
- fi
- if [ "$i" -eq 8 ]; then
- identify -verbose "$tempdir/gray$i.png" | grep --quiet "^ Depth: 8-bit$"
- else
- identify -verbose "$tempdir/gray$i.png" | grep --quiet "^ Depth: 8/$i-bit$"
- fi
- identify -verbose "$tempdir/gray$i.png" | grep --quiet '^ Page geometry: 60x60+0+0$'
- identify -verbose "$tempdir/gray$i.png" | grep --quiet '^ Compression: Zip$'
- identify -verbose "$tempdir/gray$i.png" | grep --quiet "^ png:IHDR.bit-depth-orig: $i$"
- identify -verbose "$tempdir/gray$i.png" | grep --quiet "^ png:IHDR.bit_depth: $i$"
- identify -verbose "$tempdir/gray$i.png" | grep --quiet '^ png:IHDR.color-type-orig: 0$'
- identify -verbose "$tempdir/gray$i.png" | grep --quiet '^ png:IHDR.color_type: 0 (Grayscale)$'
- identify -verbose "$tempdir/gray$i.png" | grep --quiet '^ png:IHDR.interlace_method: 0 (Not interlaced)$'
-
- for engine in $available_engines; do
- img2pdf $engine "$tempdir/gray$i.png" "$tempdir/out.pdf"
-
- compare_rendered "$tempdir/out.pdf" "$tempdir/gray$i.png" pnggray
-
- compare_pdfimages "$tempdir/out.pdf" "$tempdir/gray$i.png"
-
- cat << END | checkpdf "$tempdir/out.pdf"
-Contents.read_bytes() == b'q\n45.0000 0 0 45.0000 0.0000 0.0000 cm\n/Im0 Do\nQ'
-Resources.XObject.Im0.BitsPerComponent == $i
-Resources.XObject.Im0.ColorSpace == "/DeviceGray"
-Resources.XObject.Im0.DecodeParms.BitsPerComponent == $i
-Resources.XObject.Im0.DecodeParms.Colors == 1
-Resources.XObject.Im0.DecodeParms.Predictor == 15
-Resources.XObject.Im0.Filter == "/FlateDecode"
-Resources.XObject.Im0.Height == 60
-Resources.XObject.Im0.Width == 60
-END
- rm "$tempdir/out.pdf"
- done
-
- j=$((j+1))
-done
-
-###############################################################################
-echo "Test $j/$tests PNG Gray16"
-
-identify -verbose "$tempdir/gray16.png" | grep --quiet '^ Format: PNG (Portable Network Graphics)$'
-identify -verbose "$tempdir/gray16.png" | grep --quiet '^ Mime type: image/png$'
-identify -verbose "$tempdir/gray16.png" | grep --quiet '^ Geometry: 60x60+0+0$'
-identify -verbose "$tempdir/gray16.png" | grep --quiet '^ Colorspace: Gray$'
-identify -verbose "$tempdir/gray16.png" | grep --quiet '^ Type: Grayscale$'
-identify -verbose "$tempdir/gray16.png" | grep --quiet '^ Depth: 16-bit$'
-identify -verbose "$tempdir/gray16.png" | grep --quiet '^ Page geometry: 60x60+0+0$'
-identify -verbose "$tempdir/gray16.png" | grep --quiet '^ Compression: Zip$'
-identify -verbose "$tempdir/gray16.png" | grep --quiet '^ png:IHDR.bit-depth-orig: 16$'
-identify -verbose "$tempdir/gray16.png" | grep --quiet '^ png:IHDR.bit_depth: 16$'
-identify -verbose "$tempdir/gray16.png" | grep --quiet '^ png:IHDR.color-type-orig: 0$'
-identify -verbose "$tempdir/gray16.png" | grep --quiet '^ png:IHDR.color_type: 0 (Grayscale)$'
-identify -verbose "$tempdir/gray16.png" | grep --quiet '^ png:IHDR.interlace_method: 0 (Not interlaced)$'
-
-for engine in $available_engines; do
-img2pdf $engine "$tempdir/gray16.png" "$tempdir/out.pdf"
-
-# ghostscript outputs 8-bit grayscale, so the comparison will not be exact
-gs -dQUIET -dNOPAUSE -dBATCH -sDEVICE=pnggray -r96 -sOutputFile="$tempdir/gs-%00d.png" "$tempdir/out.pdf"
-similar "$tempdir/gray16.png" "$tempdir/gs-1.png"
-rm "$tempdir/gs-1.png"
-
-# poppler outputs 8-bit grayscale so the comparison will not be exact
-pdftocairo -r 96 -png "$tempdir/out.pdf" "$tempdir/poppler"
-similar "$tempdir/gray16.png" "$tempdir/poppler-1.png"
-rm "$tempdir/poppler-1.png"
-
-# pdfimages outputs 8-bit grayscale so the comparison will not be exact
-pdfimages -png "$tempdir/out.pdf" "$tempdir/images"
-similar "$tempdir/gray16.png" "$tempdir/images-000.png"
-rm "$tempdir/images-000.png"
-
-cat << 'END' | checkpdf "$tempdir/out.pdf"
-Contents.read_bytes() == b'q\n45.0000 0 0 45.0000 0.0000 0.0000 cm\n/Im0 Do\nQ'
-Resources.XObject.Im0.BitsPerComponent == 16
-Resources.XObject.Im0.ColorSpace == "/DeviceGray"
-Resources.XObject.Im0.DecodeParms.BitsPerComponent == 16
-Resources.XObject.Im0.DecodeParms.Colors == 1
-Resources.XObject.Im0.DecodeParms.Predictor == 15
-Resources.XObject.Im0.Filter == "/FlateDecode"
-Resources.XObject.Im0.Height == 60
-Resources.XObject.Im0.Width == 60
-END
-rm "$tempdir/out.pdf"
-done
-
-j=$((j+1))
-
-###############################################################################
-for i in 1 2 4 8; do
- echo "Test $j/$tests PNG Palette$i"
-
- identify -verbose "$tempdir/palette$i.png" | grep --quiet '^ Format: PNG (Portable Network Graphics)$'
- identify -verbose "$tempdir/palette$i.png" | grep --quiet '^ Mime type: image/png$'
- identify -verbose "$tempdir/palette$i.png" | grep --quiet '^ Geometry: 60x60+0+0$'
- identify -verbose "$tempdir/palette$i.png" | grep --quiet '^ Colorspace: sRGB$'
- identify -verbose "$tempdir/palette$i.png" | grep --quiet '^ Type: Palette$'
- identify -verbose "$tempdir/palette$i.png" | grep --quiet '^ Depth: 8-bit$'
- identify -verbose "$tempdir/palette$i.png" | grep --quiet '^ Page geometry: 60x60+0+0$'
- identify -verbose "$tempdir/palette$i.png" | grep --quiet '^ Compression: Zip$'
- identify -verbose "$tempdir/palette$i.png" | grep --quiet "^ png:IHDR.bit-depth-orig: $i$"
- identify -verbose "$tempdir/palette$i.png" | grep --quiet "^ png:IHDR.bit_depth: $i$"
- identify -verbose "$tempdir/palette$i.png" | grep --quiet '^ png:IHDR.color-type-orig: 3$'
- identify -verbose "$tempdir/palette$i.png" | grep --quiet '^ png:IHDR.color_type: 3 (Indexed)$'
- identify -verbose "$tempdir/palette$i.png" | grep --quiet '^ png:IHDR.interlace_method: 0 (Not interlaced)$'
-
- for engine in $available_engines; do
- if [ $engine = "pdfrw" ]; then
- continue
- fi
- img2pdf $engine "$tempdir/palette$i.png" "$tempdir/out.pdf"
-
- compare_rendered "$tempdir/out.pdf" "$tempdir/palette$i.png"
-
- # pdfimages cannot export palette based images
-
- cat << END | checkpdf "$tempdir/out.pdf"
-Contents.read_bytes() == b'q\n45.0000 0 0 45.0000 0.0000 0.0000 cm\n/Im0 Do\nQ'
-Resources.XObject.Im0.BitsPerComponent == $i
-Resources.XObject.Im0.ColorSpace[0] == "/Indexed"
-Resources.XObject.Im0.ColorSpace[1] == "/DeviceRGB"
-Resources.XObject.Im0.DecodeParms.BitsPerComponent == $i
-Resources.XObject.Im0.DecodeParms.Colors == 1
-Resources.XObject.Im0.DecodeParms.Predictor == 15
-Resources.XObject.Im0.Filter == "/FlateDecode"
-Resources.XObject.Im0.Height == 60
-Resources.XObject.Im0.Width == 60
-END
- rm "$tempdir/out.pdf"
- done
-
- j=$((j+1))
-done
-
-###############################################################################
-echo "Test $j/$tests GIF transparent"
-
-convert "$tempdir/alpha.png" "$tempdir/alpha.gif"
-
-identify -verbose "$tempdir/alpha.gif" | grep --quiet '^ Format: GIF (CompuServe graphics interchange format)$'
-identify -verbose "$tempdir/alpha.gif" | grep --quiet '^ Mime type: image/gif$'
-identify -verbose "$tempdir/alpha.gif" | grep --quiet '^ Geometry: 60x60+0+0$'
-identify -verbose "$tempdir/alpha.gif" | grep --quiet '^ Colorspace: sRGB$'
-identify -verbose "$tempdir/alpha.gif" | grep --quiet '^ Type: PaletteAlpha$'
-identify -verbose "$tempdir/alpha.gif" | grep --quiet '^ Depth: 8-bit$'
-identify -verbose "$tempdir/alpha.gif" | grep --quiet '^ Colormap entries: 256$'
-identify -verbose "$tempdir/alpha.gif" | grep --quiet '^ Page geometry: 60x60+0+0$'
-identify -verbose "$tempdir/alpha.gif" | grep --quiet '^ Compression: LZW$'
-
-for engine in $available_engines; do
-img2pdf $engine "$tempdir/alpha.gif" /dev/null && rc=$? || rc=$?
-if [ "$rc" -eq 0 ]; then
- echo needs to fail here
- exit 1
-fi
-done
-
-rm "$tempdir/alpha.gif"
-j=$((j+1))
-
-###############################################################################
-for i in 1 2 4 8; do
- echo "Test $j/$tests GIF Palette$i"
-
- convert "$tempdir/palette$i.png" "$tempdir/palette$i.gif"
-
- identify -verbose "$tempdir/palette$i.gif" | grep --quiet '^ Format: GIF (CompuServe graphics interchange format)$'
- identify -verbose "$tempdir/palette$i.gif" | grep --quiet '^ Mime type: image/gif$'
- identify -verbose "$tempdir/palette$i.gif" | grep --quiet '^ Geometry: 60x60+0+0$'
- identify -verbose "$tempdir/palette$i.gif" | grep --quiet '^ Colorspace: sRGB$'
- identify -verbose "$tempdir/palette$i.gif" | grep --quiet '^ Type: Palette$'
- identify -verbose "$tempdir/palette$i.gif" | grep --quiet '^ Depth: 8-bit$'
- case $i in
- 1) identify -verbose "$tempdir/palette$i.gif" | grep --quiet '^ Colormap entries: 2$';;
- 2) identify -verbose "$tempdir/palette$i.gif" | grep --quiet '^ Colormap entries: 4$';;
- 4) identify -verbose "$tempdir/palette$i.gif" | grep --quiet '^ Colormap entries: 16$';;
- 8) identify -verbose "$tempdir/palette$i.gif" | grep --quiet '^ Colormap entries: 256$';;
- esac
- identify -verbose "$tempdir/palette$i.gif" | grep --quiet '^ Page geometry: 60x60+0+0$'
- identify -verbose "$tempdir/palette$i.gif" | grep --quiet '^ Compression: LZW$'
-
- for engine in $available_engines; do
- if [ $engine = "pdfrw" ]; then
- continue
- fi
- img2pdf $engine "$tempdir/palette$i.gif" "$tempdir/out.pdf"
-
- compare_rendered "$tempdir/out.pdf" "$tempdir/palette$i.png"
-
- # pdfimages cannot export palette based images
-
- cat << END | checkpdf "$tempdir/out.pdf"
-Contents.read_bytes() == b'q\n45.0000 0 0 45.0000 0.0000 0.0000 cm\n/Im0 Do\nQ'
-Resources.XObject.Im0.BitsPerComponent == $i
-Resources.XObject.Im0.ColorSpace[0] == "/Indexed"
-Resources.XObject.Im0.ColorSpace[1] == "/DeviceRGB"
-Resources.XObject.Im0.DecodeParms.BitsPerComponent == $i
-Resources.XObject.Im0.DecodeParms.Colors == 1
-Resources.XObject.Im0.DecodeParms.Predictor == 15
-Resources.XObject.Im0.Filter == "/FlateDecode"
-Resources.XObject.Im0.Height == 60
-Resources.XObject.Im0.Width == 60
-END
- rm "$tempdir/out.pdf"
- done
-
- rm "$tempdir/palette$i.gif"
- j=$((j+1))
-done
-
-###############################################################################
-echo "Test $j/$tests GIF animation"
-
-convert "$tempdir/normal.png" "$tempdir/inverse.png" -strip "$tempdir/animation.gif"
-
-identify -verbose "$tempdir/animation.gif[0]" | grep --quiet '^ Format: GIF (CompuServe graphics interchange format)$'
-identify -verbose "$tempdir/animation.gif[0]" | grep --quiet '^ Mime type: image/gif$'
-identify -verbose "$tempdir/animation.gif[0]" | grep --quiet '^ Geometry: 60x60+0+0$'
-identify -verbose "$tempdir/animation.gif[0]" | grep --quiet '^ Colorspace: sRGB$'
-identify -verbose "$tempdir/animation.gif[0]" | grep --quiet '^ Type: Palette$'
-identify -verbose "$tempdir/animation.gif[0]" | grep --quiet '^ Depth: 8-bit$'
-identify -verbose "$tempdir/animation.gif[0]" | grep --quiet '^ Colormap entries: 256$'
-identify -verbose "$tempdir/animation.gif[0]" | grep --quiet '^ Page geometry: 60x60+0+0$'
-identify -verbose "$tempdir/animation.gif[0]" | grep --quiet '^ Compression: LZW$'
-
-identify -verbose "$tempdir/animation.gif[1]" | grep --quiet '^ Format: GIF (CompuServe graphics interchange format)$'
-identify -verbose "$tempdir/animation.gif[1]" | grep --quiet '^ Mime type: image/gif$'
-identify -verbose "$tempdir/animation.gif[1]" | grep --quiet '^ Geometry: 60x60+0+0$'
-identify -verbose "$tempdir/animation.gif[1]" | grep --quiet '^ Colorspace: sRGB$'
-identify -verbose "$tempdir/animation.gif[1]" | grep --quiet '^ Type: Palette$'
-identify -verbose "$tempdir/animation.gif[1]" | grep --quiet '^ Depth: 8-bit$'
-identify -verbose "$tempdir/animation.gif[1]" | grep --quiet '^ Colormap entries: 256$'
-identify -verbose "$tempdir/animation.gif[1]" | grep --quiet '^ Page geometry: 60x60+0+0$'
-identify -verbose "$tempdir/animation.gif[1]" | grep --quiet '^ Compression: LZW$'
-identify -verbose "$tempdir/animation.gif[1]" | grep --quiet '^ Scene: 1$'
-
-for engine in $available_engines; do
-if [ $engine = "pdfrw" ]; then
- continue
-fi
-img2pdf $engine "$tempdir/animation.gif" "$tempdir/out.pdf"
-
-if [ "$(pdfinfo "$tempdir/out.pdf" | awk '/Pages:/ {print $2}')" != 2 ]; then
- echo "pdf does not have 2 pages"
- exit 1
-fi
-
-pdfseparate "$tempdir/out.pdf" "$tempdir/page-%d.pdf"
-rm "$tempdir/out.pdf"
-
-for page in 1 2; do
- compare_rendered "$tempdir/page-$page.pdf" "$tempdir/animation.gif[$((page-1))]"
-
- # pdfimages cannot export palette based images
-
- cat << END | checkpdf "$tempdir/page-$page.pdf"
-Contents.read_bytes() == b'q\n45.0000 0 0 45.0000 0.0000 0.0000 cm\n/Im0 Do\nQ'
-Resources.XObject.Im0.BitsPerComponent == 8
-Resources.XObject.Im0.ColorSpace[0] == "/Indexed"
-Resources.XObject.Im0.ColorSpace[1] == "/DeviceRGB"
-Resources.XObject.Im0.DecodeParms.BitsPerComponent == 8
-Resources.XObject.Im0.DecodeParms.Colors == 1
-Resources.XObject.Im0.DecodeParms.Predictor == 15
-Resources.XObject.Im0.Filter == "/FlateDecode"
-Resources.XObject.Im0.Height == 60
-Resources.XObject.Im0.Width == 60
-END
-
- rm "$tempdir/page-$page.pdf"
-done
-done
-
-rm "$tempdir/animation.gif"
-j=$((j+1))
-
-###############################################################################
-echo "Test $j/$tests TIFF float"
-
-convert "$tempdir/normal.png" -depth 32 -define quantum:format=floating-point "$tempdir/float.tiff"
-
-identify -verbose "$tempdir/float.tiff" | grep --quiet '^ Format: TIFF (Tagged Image File Format)$'
-identify -verbose "$tempdir/float.tiff" | grep --quiet '^ Mime type: image/tiff$'
-identify -verbose "$tempdir/float.tiff" | grep --quiet '^ Geometry: 60x60+0+0$'
-identify -verbose "$tempdir/float.tiff" | grep --quiet '^ Colorspace: sRGB$'
-identify -verbose "$tempdir/float.tiff" | grep --quiet '^ Type: TrueColor$'
-identify -verbose "$tempdir/float.tiff" | grep --quiet '^ Endiann\?ess: LSB$'
-identify -verbose "$tempdir/float.tiff" | grep --quiet '^ Depth: 32/\(8\|16\)-bit$' # imagemagick may produce a Depth: 32/8-bit or 32/16-bit image
-identify -verbose "$tempdir/float.tiff" | grep --quiet '^ Page geometry: 60x60+0+0$'
-identify -verbose "$tempdir/float.tiff" | grep --quiet '^ Compression: Zip$'
-identify -verbose "$tempdir/float.tiff" | grep --quiet '^ quantum:format: floating-point$'
-identify -verbose "$tempdir/float.tiff" | grep --quiet '^ tiff:alpha: unspecified$'
-identify -verbose "$tempdir/float.tiff" | grep --quiet '^ tiff:endian: lsb$'
-identify -verbose "$tempdir/float.tiff" | grep --quiet '^ tiff:photometric: RGB$'
-
-for engine in $available_engines; do
-img2pdf $engine "$tempdir/float.tiff" /dev/null && rc=$? || rc=$?
-if [ "$rc" -eq 0 ]; then
- echo needs to fail here
- exit 1
-fi
-done
-
-rm "$tempdir/float.tiff"
-j=$((j+1))
-
-###############################################################################
-echo "Test $j/$tests TIFF CMYK8"
-
-convert "$tempdir/normal.png" -colorspace cmyk "$tempdir/cmyk8.tiff"
-
-identify -verbose "$tempdir/cmyk8.tiff" | grep --quiet '^ Format: TIFF (Tagged Image File Format)$'
-identify -verbose "$tempdir/cmyk8.tiff" | grep --quiet '^ Mime type: image/tiff$'
-identify -verbose "$tempdir/cmyk8.tiff" | grep --quiet '^ Geometry: 60x60+0+0$'
-identify -verbose "$tempdir/cmyk8.tiff" | grep --quiet '^ Colorspace: CMYK$'
-identify -verbose "$tempdir/cmyk8.tiff" | grep --quiet '^ Type: ColorSeparation$'
-identify -verbose "$tempdir/cmyk8.tiff" | grep --quiet '^ Endiann\?ess: LSB$'
-identify -verbose "$tempdir/cmyk8.tiff" | grep --quiet '^ Depth: 8-bit$'
-identify -verbose "$tempdir/cmyk8.tiff" | grep --quiet '^ Page geometry: 60x60+0+0$'
-identify -verbose "$tempdir/cmyk8.tiff" | grep --quiet '^ Compression: Zip$'
-identify -verbose "$tempdir/cmyk8.tiff" | grep --quiet '^ tiff:alpha: unspecified$'
-identify -verbose "$tempdir/cmyk8.tiff" | grep --quiet '^ tiff:endian: lsb$'
-identify -verbose "$tempdir/cmyk8.tiff" | grep --quiet '^ tiff:photometric: separated$'
-
-for engine in $available_engines; do
-img2pdf $engine "$tempdir/cmyk8.tiff" "$tempdir/out.pdf"
-
-compare_ghostscript "$tempdir/out.pdf" "$tempdir/cmyk8.tiff" tiff32nc
-
-# not testing with poppler as it cannot write CMYK images
-
-mutool draw -o "$tempdir/mupdf.pam" -r 96 -c cmyk "$pdf" 2>/dev/null
-compare -metric AE "$tempdir/cmyk8.tiff" "$tempdir/mupdf.pam" null: 2>/dev/null
-rm "$tempdir/mupdf.pam"
-
-pdfimages -tiff "$tempdir/out.pdf" "$tempdir/images"
-compare -metric AE "$tempdir/cmyk8.tiff" "$tempdir/images-000.tif" null: 2>/dev/null
-rm "$tempdir/images-000.tif"
-
-cat << 'END' | checkpdf "$tempdir/out.pdf"
-Contents.read_bytes() == b'q\n45.0000 0 0 45.0000 0.0000 0.0000 cm\n/Im0 Do\nQ'
-Resources.XObject.Im0.BitsPerComponent == 8
-Resources.XObject.Im0.ColorSpace == "/DeviceCMYK"
-Resources.XObject.Im0.Filter == "/FlateDecode"
-Resources.XObject.Im0.Height == 60
-Resources.XObject.Im0.Width == 60
-END
-rm "$tempdir/out.pdf"
-done
-
-rm "$tempdir/cmyk8.tiff"
-j=$((j+1))
-
-###############################################################################
-echo "Test $j/$tests TIFF CMYK16"
-
-convert "$tempdir/normal.png" -depth 16 -colorspace cmyk "$tempdir/cmyk16.tiff"
-
-identify -verbose "$tempdir/cmyk16.tiff" | grep --quiet '^ Format: TIFF (Tagged Image File Format)$'
-identify -verbose "$tempdir/cmyk16.tiff" | grep --quiet '^ Mime type: image/tiff$'
-identify -verbose "$tempdir/cmyk16.tiff" | grep --quiet '^ Geometry: 60x60+0+0$'
-identify -verbose "$tempdir/cmyk16.tiff" | grep --quiet '^ Colorspace: CMYK$'
-identify -verbose "$tempdir/cmyk16.tiff" | grep --quiet '^ Type: ColorSeparation$'
-identify -verbose "$tempdir/cmyk16.tiff" | grep --quiet '^ Endiann\?ess: LSB$'
-identify -verbose "$tempdir/cmyk16.tiff" | grep --quiet '^ Depth: 16-bit$'
-identify -verbose "$tempdir/cmyk16.tiff" | grep --quiet '^ Page geometry: 60x60+0+0$'
-identify -verbose "$tempdir/cmyk16.tiff" | grep --quiet '^ Compression: Zip$'
-identify -verbose "$tempdir/cmyk16.tiff" | grep --quiet '^ tiff:alpha: unspecified$'
-identify -verbose "$tempdir/cmyk16.tiff" | grep --quiet '^ tiff:endian: lsb$'
-identify -verbose "$tempdir/cmyk16.tiff" | grep --quiet '^ tiff:photometric: separated$'
-
-# PIL is unable to read 16 bit CMYK images
-for engine in $available_engines; do
-img2pdf $engine "$tempdir/cmyk16.gif" /dev/null && rc=$? || rc=$?
-if [ "$rc" -eq 0 ]; then
- echo needs to fail here
- exit 1
-fi
-done
-
-rm "$tempdir/cmyk16.tiff"
-j=$((j+1))
-
-###############################################################################
-echo "Test $j/$tests TIFF RGB8"
-
-convert "$tempdir/normal.png" "$tempdir/normal.tiff"
-
-identify -verbose "$tempdir/normal.tiff" | grep --quiet '^ Format: TIFF (Tagged Image File Format)$'
-identify -verbose "$tempdir/normal.tiff" | grep --quiet '^ Mime type: image/tiff$'
-identify -verbose "$tempdir/normal.tiff" | grep --quiet '^ Geometry: 60x60+0+0$'
-identify -verbose "$tempdir/normal.tiff" | grep --quiet '^ Colorspace: sRGB$'
-identify -verbose "$tempdir/normal.tiff" | grep --quiet '^ Type: TrueColor$'
-identify -verbose "$tempdir/normal.tiff" | grep --quiet '^ Endiann\?ess: LSB$'
-identify -verbose "$tempdir/normal.tiff" | grep --quiet '^ Depth: 8-bit$'
-identify -verbose "$tempdir/normal.tiff" | grep --quiet '^ Page geometry: 60x60+0+0$'
-identify -verbose "$tempdir/normal.tiff" | grep --quiet '^ Compression: Zip$'
-identify -verbose "$tempdir/normal.tiff" | grep --quiet '^ tiff:alpha: unspecified$'
-identify -verbose "$tempdir/normal.tiff" | grep --quiet '^ tiff:endian: lsb$'
-identify -verbose "$tempdir/normal.tiff" | grep --quiet '^ tiff:photometric: RGB$'
-
-for engine in $available_engines; do
-img2pdf $engine "$tempdir/normal.tiff" "$tempdir/out.pdf"
-
-compare_rendered "$tempdir/out.pdf" "$tempdir/normal.tiff" tiff24nc
-
-compare_pdfimages "$tempdir/out.pdf" "$tempdir/normal.tiff"
-
-cat << 'END' | checkpdf "$tempdir/out.pdf"
-Contents.read_bytes() == b'q\n45.0000 0 0 45.0000 0.0000 0.0000 cm\n/Im0 Do\nQ'
-Resources.XObject.Im0.BitsPerComponent == 8
-Resources.XObject.Im0.ColorSpace == "/DeviceRGB"
-Resources.XObject.Im0.DecodeParms.BitsPerComponent == 8
-Resources.XObject.Im0.DecodeParms.Colors == 3
-Resources.XObject.Im0.DecodeParms.Predictor == 15
-Resources.XObject.Im0.Filter == "/FlateDecode"
-Resources.XObject.Im0.Height == 60
-Resources.XObject.Im0.Width == 60
-END
-rm "$tempdir/out.pdf"
-done
-
-rm "$tempdir/normal.tiff"
-j=$((j+1))
-
-###############################################################################
-echo "Test $j/$tests TIFF RGBA8"
-
-convert "$tempdir/alpha.png" -depth 8 -strip "$tempdir/alpha8.tiff"
-
-identify -verbose "$tempdir/alpha8.tiff" | grep --quiet '^ Format: TIFF (Tagged Image File Format)$'
-identify -verbose "$tempdir/alpha8.tiff" | grep --quiet '^ Mime type: image/tiff$'
-identify -verbose "$tempdir/alpha8.tiff" | grep --quiet '^ Geometry: 60x60+0+0$'
-identify -verbose "$tempdir/alpha8.tiff" | grep --quiet '^ Colorspace: sRGB$'
-identify -verbose "$tempdir/alpha8.tiff" | grep --quiet '^ Type: TrueColorAlpha$'
-identify -verbose "$tempdir/alpha8.tiff" | grep --quiet '^ Endiann\?ess: LSB$'
-identify -verbose "$tempdir/alpha8.tiff" | grep --quiet '^ Depth: 8-bit$'
-identify -verbose "$tempdir/alpha8.tiff" | grep --quiet '^ Page geometry: 60x60+0+0$'
-identify -verbose "$tempdir/alpha8.tiff" | grep --quiet '^ Compression: Zip$'
-identify -verbose "$tempdir/alpha8.tiff" | grep --quiet '^ tiff:alpha: unassociated$'
-identify -verbose "$tempdir/alpha8.tiff" | grep --quiet '^ tiff:endian: lsb$'
-identify -verbose "$tempdir/alpha8.tiff" | grep --quiet '^ tiff:photometric: RGB$'
-
-for engine in $available_engines; do
-img2pdf $engine "$tempdir/alpha8.tiff" /dev/null && rc=$? || rc=$?
-if [ "$rc" -eq 0 ]; then
- echo needs to fail here
- exit 1
-fi
-done
-
-rm "$tempdir/alpha8.tiff"
-j=$((j+1))
-
-###############################################################################
-echo "Test $j/$tests TIFF RGBA16"
-
-convert "$tempdir/alpha.png" -strip "$tempdir/alpha16.tiff"
-
-identify -verbose "$tempdir/alpha16.tiff" | grep --quiet '^ Format: TIFF (Tagged Image File Format)$'
-identify -verbose "$tempdir/alpha16.tiff" | grep --quiet '^ Mime type: image/tiff$'
-identify -verbose "$tempdir/alpha16.tiff" | grep --quiet '^ Geometry: 60x60+0+0$'
-identify -verbose "$tempdir/alpha16.tiff" | grep --quiet '^ Colorspace: sRGB$'
-identify -verbose "$tempdir/alpha16.tiff" | grep --quiet '^ Type: TrueColorAlpha$'
-identify -verbose "$tempdir/alpha16.tiff" | grep --quiet '^ Endiann\?ess: LSB$'
-identify -verbose "$tempdir/alpha16.tiff" | grep --quiet '^ Depth: 16-bit$'
-identify -verbose "$tempdir/alpha16.tiff" | grep --quiet '^ Page geometry: 60x60+0+0$'
-identify -verbose "$tempdir/alpha16.tiff" | grep --quiet '^ Compression: Zip$'
-identify -verbose "$tempdir/alpha16.tiff" | grep --quiet '^ tiff:alpha: unassociated$'
-identify -verbose "$tempdir/alpha16.tiff" | grep --quiet '^ tiff:endian: lsb$'
-identify -verbose "$tempdir/alpha16.tiff" | grep --quiet '^ tiff:photometric: RGB$'
-
-for engine in $available_engines; do
-img2pdf $engine "$tempdir/alpha16.tiff" /dev/null && rc=$? || rc=$?
-if [ "$rc" -eq 0 ]; then
- echo needs to fail here
- exit 1
-fi
-done
-
-rm "$tempdir/alpha16.tiff"
-j=$((j+1))
-
-###############################################################################
-echo "Test $j/$tests TIFF Gray1"
-
-convert "$tempdir/gray1.png" -depth 1 "$tempdir/gray1.tiff"
-
-identify -verbose "$tempdir/gray1.tiff" | grep --quiet '^ Format: TIFF (Tagged Image File Format)$'
-identify -verbose "$tempdir/gray1.tiff" | grep --quiet '^ Mime type: image/tiff$'
-identify -verbose "$tempdir/gray1.tiff" | grep --quiet '^ Geometry: 60x60+0+0$'
-identify -verbose "$tempdir/gray1.tiff" | grep --quiet '^ Colorspace: Gray$'
-identify -verbose "$tempdir/gray1.tiff" | grep --quiet '^ Type: Bilevel$'
-identify -verbose "$tempdir/gray1.tiff" | grep --quiet '^ Endiann\?ess: LSB$'
-identify -verbose "$tempdir/gray1.tiff" | grep --quiet '^ Depth: 1-bit$'
-identify -verbose "$tempdir/gray1.tiff" | grep --quiet '^ Page geometry: 60x60+0+0$'
-identify -verbose "$tempdir/gray1.tiff" | grep --quiet '^ Compression: Zip$'
-identify -verbose "$tempdir/gray1.tiff" | grep --quiet '^ tiff:alpha: unspecified$'
-identify -verbose "$tempdir/gray1.tiff" | grep --quiet '^ tiff:endian: lsb$'
-identify -verbose "$tempdir/gray1.tiff" | grep --quiet '^ tiff:photometric: min-is-black$'
-
-for engine in $available_engines; do
-img2pdf $engine "$tempdir/gray1.tiff" "$tempdir/out.pdf"
-
-compare_rendered "$tempdir/out.pdf" "$tempdir/gray1.png" pnggray
-
-compare_pdfimages "$tempdir/out.pdf" "$tempdir/gray1.png"
-
-cat << 'END' | checkpdf "$tempdir/out.pdf"
-Contents.read_bytes() == b'q\n45.0000 0 0 45.0000 0.0000 0.0000 cm\n/Im0 Do\nQ'
-Resources.XObject.Im0.BitsPerComponent == 1
-Resources.XObject.Im0.ColorSpace == "/DeviceGray"
-Resources.XObject.Im0.DecodeParms[0].BlackIs1 == True
-Resources.XObject.Im0.DecodeParms[0].Columns == 60
-Resources.XObject.Im0.DecodeParms[0].K == -1
-Resources.XObject.Im0.DecodeParms[0].Rows == 60
-Resources.XObject.Im0.Filter[0] == "/CCITTFaxDecode"
-Resources.XObject.Im0.Height == 60
-Resources.XObject.Im0.Width == 60
-END
-rm "$tempdir/out.pdf"
-done
-
-rm "$tempdir/gray1.tiff"
-j=$((j+1))
-
-###############################################################################
-for i in 2 4 8; do
- echo "Test $j/$tests TIFF Gray$i"
-
- convert "$tempdir/gray$i.png" -depth $i "$tempdir/gray$i.tiff"
-
- identify -verbose "$tempdir/gray$i.tiff" | grep --quiet '^ Format: TIFF (Tagged Image File Format)$'
- identify -verbose "$tempdir/gray$i.tiff" | grep --quiet '^ Mime type: image/tiff$'
- identify -verbose "$tempdir/gray$i.tiff" | grep --quiet '^ Geometry: 60x60+0+0$'
- identify -verbose "$tempdir/gray$i.tiff" | grep --quiet '^ Colorspace: Gray$'
- identify -verbose "$tempdir/gray$i.tiff" | grep --quiet '^ Type: Grayscale$'
- identify -verbose "$tempdir/gray$i.tiff" | grep --quiet '^ Endiann\?ess: LSB$'
- identify -verbose "$tempdir/gray$i.tiff" | grep --quiet "^ Depth: $i-bit$"
- identify -verbose "$tempdir/gray$i.tiff" | grep --quiet '^ Page geometry: 60x60+0+0$'
- identify -verbose "$tempdir/gray$i.tiff" | grep --quiet '^ Compression: Zip$'
- identify -verbose "$tempdir/gray$i.tiff" | grep --quiet '^ tiff:alpha: unspecified$'
- identify -verbose "$tempdir/gray$i.tiff" | grep --quiet '^ tiff:endian: lsb$'
- identify -verbose "$tempdir/gray$i.tiff" | grep --quiet '^ tiff:photometric: min-is-black$'
-
- for engine in $available_engines; do
- img2pdf $engine "$tempdir/gray$i.tiff" "$tempdir/out.pdf"
-
- compare_rendered "$tempdir/out.pdf" "$tempdir/gray$i.png" pnggray
-
- compare_pdfimages "$tempdir/out.pdf" "$tempdir/gray$i.png"
-
- # When saving a PNG, PIL will store it as 8-bit data
- cat << 'END' | checkpdf "$tempdir/out.pdf"
-Contents.read_bytes() == b'q\n45.0000 0 0 45.0000 0.0000 0.0000 cm\n/Im0 Do\nQ'
-Resources.XObject.Im0.BitsPerComponent == 8
-Resources.XObject.Im0.ColorSpace == "/DeviceGray"
-Resources.XObject.Im0.DecodeParms.BitsPerComponent == 8
-Resources.XObject.Im0.DecodeParms.Colors == 1
-Resources.XObject.Im0.DecodeParms.Predictor == 15
-Resources.XObject.Im0.Filter == "/FlateDecode"
-Resources.XObject.Im0.Height == 60
-Resources.XObject.Im0.Width == 60
-END
- rm "$tempdir/out.pdf"
- done
-
- rm "$tempdir/gray$i.tiff"
- j=$((j+1))
-done
-
-################################################################################
-echo "Test $j/$tests TIFF Gray16"
-
-convert "$tempdir/gray16.png" -depth 16 "$tempdir/gray16.tiff"
-
-identify -verbose "$tempdir/gray16.tiff" | grep --quiet '^ Format: TIFF (Tagged Image File Format)$'
-identify -verbose "$tempdir/gray16.tiff" | grep --quiet '^ Mime type: image/tiff$'
-identify -verbose "$tempdir/gray16.tiff" | grep --quiet '^ Geometry: 60x60+0+0$'
-identify -verbose "$tempdir/gray16.tiff" | grep --quiet '^ Colorspace: Gray$'
-identify -verbose "$tempdir/gray16.tiff" | grep --quiet '^ Type: Grayscale$'
-identify -verbose "$tempdir/gray16.tiff" | grep --quiet '^ Endiann\?ess: LSB$'
-identify -verbose "$tempdir/gray16.tiff" | grep --quiet "^ Depth: 16-bit$"
-identify -verbose "$tempdir/gray16.tiff" | grep --quiet '^ Page geometry: 60x60+0+0$'
-identify -verbose "$tempdir/gray16.tiff" | grep --quiet '^ Compression: Zip$'
-identify -verbose "$tempdir/gray16.tiff" | grep --quiet '^ tiff:alpha: unspecified$'
-identify -verbose "$tempdir/gray16.tiff" | grep --quiet '^ tiff:endian: lsb$'
-identify -verbose "$tempdir/gray16.tiff" | grep --quiet '^ tiff:photometric: min-is-black$'
-
-for engine in $available_engines; do
-img2pdf $engine "$tempdir/gray16.tiff" /dev/null && rc=$? || rc=$?
-if [ "$rc" -eq 0 ]; then
- echo needs to fail here
- exit 1
-fi
-done
-
-rm "$tempdir/gray16.tiff"
-j=$((j+1))
-
-###############################################################################
-echo "Test $j/$tests TIFF multipage"
-
-convert "$tempdir/normal.png" "$tempdir/inverse.png" -strip "$tempdir/multipage.tiff"
-
-identify -verbose "$tempdir/multipage.tiff[0]" | grep --quiet '^ Format: TIFF (Tagged Image File Format)$'
-identify -verbose "$tempdir/multipage.tiff[0]" | grep --quiet '^ Mime type: image/tiff$'
-identify -verbose "$tempdir/multipage.tiff[0]" | grep --quiet '^ Geometry: 60x60+0+0$'
-identify -verbose "$tempdir/multipage.tiff[0]" | grep --quiet '^ Colorspace: sRGB$'
-identify -verbose "$tempdir/multipage.tiff[0]" | grep --quiet '^ Type: TrueColor$'
-identify -verbose "$tempdir/multipage.tiff[0]" | grep --quiet '^ Endiann\?ess: LSB$'
-identify -verbose "$tempdir/multipage.tiff[0]" | grep --quiet '^ Depth: 8-bit$'
-identify -verbose "$tempdir/multipage.tiff[0]" | grep --quiet '^ Page geometry: 60x60+0+0$'
-identify -verbose "$tempdir/multipage.tiff[0]" | grep --quiet '^ Compression: Zip$'
-identify -verbose "$tempdir/multipage.tiff[0]" | grep --quiet '^ tiff:alpha: unspecified$'
-identify -verbose "$tempdir/multipage.tiff[0]" | grep --quiet '^ tiff:endian: lsb$'
-identify -verbose "$tempdir/multipage.tiff[0]" | grep --quiet '^ tiff:photometric: RGB$'
-
-identify -verbose "$tempdir/multipage.tiff[1]" | grep --quiet '^ Format: TIFF (Tagged Image File Format)$'
-identify -verbose "$tempdir/multipage.tiff[1]" | grep --quiet '^ Mime type: image/tiff$'
-identify -verbose "$tempdir/multipage.tiff[1]" | grep --quiet '^ Geometry: 60x60+0+0$'
-identify -verbose "$tempdir/multipage.tiff[1]" | grep --quiet '^ Colorspace: sRGB$'
-identify -verbose "$tempdir/multipage.tiff[1]" | grep --quiet '^ Type: TrueColor$'
-identify -verbose "$tempdir/multipage.tiff[1]" | grep --quiet '^ Endiann\?ess: LSB$'
-identify -verbose "$tempdir/multipage.tiff[1]" | grep --quiet '^ Depth: 8-bit$'
-identify -verbose "$tempdir/multipage.tiff[1]" | grep --quiet '^ Page geometry: 60x60+0+0$'
-identify -verbose "$tempdir/multipage.tiff[1]" | grep --quiet '^ Compression: Zip$'
-identify -verbose "$tempdir/multipage.tiff[1]" | grep --quiet '^ tiff:alpha: unspecified$'
-identify -verbose "$tempdir/multipage.tiff[1]" | grep --quiet '^ tiff:endian: lsb$'
-identify -verbose "$tempdir/multipage.tiff[1]" | grep --quiet '^ tiff:photometric: RGB$'
-identify -verbose "$tempdir/multipage.tiff[1]" | grep --quiet '^ Scene: 1$'
-
-for engine in $available_engines; do
-img2pdf $engine "$tempdir/multipage.tiff" "$tempdir/out.pdf"
-
-if [ "$(pdfinfo "$tempdir/out.pdf" | awk '/Pages:/ {print $2}')" != 2 ]; then
- echo "pdf does not have 2 pages"
- exit 1
-fi
-
-pdfseparate "$tempdir/out.pdf" "$tempdir/page-%d.pdf"
-rm "$tempdir/out.pdf"
-
-for page in 1 2; do
- compare_rendered "$tempdir/page-$page.pdf" "$tempdir/multipage.tiff[$((page-1))]"
-
- compare_pdfimages "$tempdir/page-$page.pdf" "$tempdir/multipage.tiff[$((page-1))]"
-
- cat << 'END' | checkpdf "$tempdir/page-$page.pdf"
-Contents.read_bytes() == b'q\n45.0000 0 0 45.0000 0.0000 0.0000 cm\n/Im0 Do\nQ'
-Resources.XObject.Im0.BitsPerComponent == 8
-Resources.XObject.Im0.ColorSpace == "/DeviceRGB"
-Resources.XObject.Im0.DecodeParms.BitsPerComponent == 8
-Resources.XObject.Im0.DecodeParms.Colors == 3
-Resources.XObject.Im0.DecodeParms.Predictor == 15
-Resources.XObject.Im0.Filter == "/FlateDecode"
-Resources.XObject.Im0.Height == 60
-Resources.XObject.Im0.Width == 60
-END
-
- rm "$tempdir/page-$page.pdf"
-done
-done
-
-rm "$tempdir/multipage.tiff"
-j=$((j+1))
-
-###############################################################################
-for i in 1 2 4 8; do
- echo "Test $j/$tests TIFF Palette$i"
-
- convert "$tempdir/palette$i.png" "$tempdir/palette$i.tiff"
-
- identify -verbose "$tempdir/palette$i.tiff" | grep --quiet '^ Format: TIFF (Tagged Image File Format)$'
- identify -verbose "$tempdir/palette$i.tiff" | grep --quiet '^ Mime type: image/tiff$'
- identify -verbose "$tempdir/palette$i.tiff" | grep --quiet '^ Geometry: 60x60+0+0$'
- identify -verbose "$tempdir/palette$i.tiff" | grep --quiet '^ Colorspace: sRGB$'
- identify -verbose "$tempdir/palette$i.tiff" | grep --quiet '^ Type: Palette$'
- identify -verbose "$tempdir/palette$i.tiff" | grep --quiet '^ Endiann\?ess: LSB$'
- if [ "$i" -eq 8 ]; then
- identify -verbose "$tempdir/palette$i.tiff" | grep --quiet "^ Depth: 8-bit$"
- else
- identify -verbose "$tempdir/palette$i.tiff" | grep --quiet "^ Depth: $i/8-bit$"
- fi
- case $i in
- 1) identify -verbose "$tempdir/palette$i.tiff" | grep --quiet '^ Colormap entries: 2$';;
- 2) identify -verbose "$tempdir/palette$i.tiff" | grep --quiet '^ Colormap entries: 4$';;
- 4) identify -verbose "$tempdir/palette$i.tiff" | grep --quiet '^ Colormap entries: 16$';;
- 8) identify -verbose "$tempdir/palette$i.tiff" | grep --quiet '^ Colormap entries: 256$';;
- esac
- identify -verbose "$tempdir/palette$i.tiff" | grep --quiet '^ Page geometry: 60x60+0+0$'
- identify -verbose "$tempdir/palette$i.tiff" | grep --quiet '^ Compression: Zip$'
- identify -verbose "$tempdir/palette$i.tiff" | grep --quiet '^ tiff:alpha: unspecified$'
- identify -verbose "$tempdir/palette$i.tiff" | grep --quiet '^ tiff:endian: lsb$'
- identify -verbose "$tempdir/palette$i.tiff" | grep --quiet '^ tiff:photometric: palette$'
-
- for engine in $available_engines; do
- if [ $engine = "pdfrw" ]; then
- continue
- fi
- img2pdf $engine "$tempdir/palette$i.tiff" "$tempdir/out.pdf"
-
- compare_rendered "$tempdir/out.pdf" "$tempdir/palette$i.png"
-
- # pdfimages cannot export palette based images
-
- cat << END | checkpdf "$tempdir/out.pdf"
-Contents.read_bytes() == b'q\n45.0000 0 0 45.0000 0.0000 0.0000 cm\n/Im0 Do\nQ'
-Resources.XObject.Im0.BitsPerComponent == $i
-Resources.XObject.Im0.ColorSpace[0] == "/Indexed"
-Resources.XObject.Im0.ColorSpace[1] == "/DeviceRGB"
-Resources.XObject.Im0.DecodeParms.BitsPerComponent == $i
-Resources.XObject.Im0.DecodeParms.Colors == 1
-Resources.XObject.Im0.DecodeParms.Predictor == 15
-Resources.XObject.Im0.Filter == "/FlateDecode"
-Resources.XObject.Im0.Height == 60
-Resources.XObject.Im0.Width == 60
-END
-
- rm "$tempdir/out.pdf"
- done
-
- rm "$tempdir/palette$i.tiff"
- j=$((j+1))
-done
-
-###############################################################################
-for i in 12 14 16; do
- echo "Test $j/$tests TIFF RGB$i"
-
- convert "$tempdir/normal16.png" -depth "$i" "$tempdir/normal$i.tiff"
-
- identify -verbose "$tempdir/normal$i.tiff" | grep --quiet '^ Format: TIFF (Tagged Image File Format)$'
- identify -verbose "$tempdir/normal$i.tiff" | grep --quiet '^ Mime type: image/tiff$'
- identify -verbose "$tempdir/normal$i.tiff" | grep --quiet '^ Geometry: 60x60+0+0$'
- identify -verbose "$tempdir/normal$i.tiff" | grep --quiet '^ Colorspace: sRGB$'
- identify -verbose "$tempdir/normal$i.tiff" | grep --quiet '^ Type: TrueColor$'
- identify -verbose "$tempdir/normal$i.tiff" | grep --quiet '^ Endiann\?ess: LSB$'
- if [ $i -eq 16 ]; then
- identify -verbose "$tempdir/normal$i.tiff" | grep --quiet "^ Depth: $i-bit$"
- else
- identify -verbose "$tempdir/normal$i.tiff" | egrep --quiet "^ Depth: $i(/16)?-bit$"
- fi
- identify -verbose "$tempdir/normal$i.tiff" | grep --quiet '^ Page geometry: 60x60+0+0$'
- identify -verbose "$tempdir/normal$i.tiff" | grep --quiet '^ Compression: Zip$'
- identify -verbose "$tempdir/normal$i.tiff" | grep --quiet '^ tiff:alpha: unspecified$'
- identify -verbose "$tempdir/normal$i.tiff" | grep --quiet '^ tiff:endian: lsb$'
- identify -verbose "$tempdir/normal$i.tiff" | grep --quiet '^ tiff:photometric: RGB$'
-
- for engine in $available_engines; do
- img2pdf $engine "$tempdir/normal$i.tiff" /dev/null && rc=$? || rc=$?
- if [ "$rc" -eq 0 ]; then
- echo needs to fail here
- exit 1
- fi
- done
-
- rm "$tempdir/normal$i.tiff"
- j=$((j+1))
-done
-
-###############################################################################
-echo "Test $j/$tests TIFF CCITT Group4, little endian, msb-to-lsb, min-is-white"
-
-convert "$tempdir/gray1.png" -compress group4 -define tiff:endian=lsb -define tiff:fill-order=msb -define quantum:polarity=min-is-white "$tempdir/group4.tiff"
-tiffinfo "$tempdir/group4.tiff" | grep --quiet 'Bits/Sample: 1'
-tiffinfo "$tempdir/group4.tiff" | grep --quiet 'Compression Scheme: CCITT Group 4'
-tiffinfo "$tempdir/group4.tiff" | grep --quiet 'Photometric Interpretation: min-is-white'
-tiffinfo "$tempdir/group4.tiff" | grep --quiet 'FillOrder: msb-to-lsb'
-tiffinfo "$tempdir/group4.tiff" | grep --quiet 'Samples/Pixel: 1'
-identify -verbose "$tempdir/group4.tiff" | grep --quiet 'Type: Bilevel'
-identify -verbose "$tempdir/group4.tiff" | grep --quiet 'Endian*ess: LSB'
-identify -verbose "$tempdir/group4.tiff" | grep --quiet 'Depth: 1-bit'
-identify -verbose "$tempdir/group4.tiff" | grep --quiet '[gG]ray: 1-bit'
-identify -verbose "$tempdir/group4.tiff" | grep --quiet 'Compression: Group4'
-identify -verbose "$tempdir/group4.tiff" | grep --quiet 'tiff:endian: lsb'
-identify -verbose "$tempdir/group4.tiff" | grep --quiet 'tiff:photometric: min-is-white'
-
-for engine in $available_engines; do
-img2pdf $engine "$tempdir/group4.tiff" "$tempdir/out.pdf"
-
-compare_rendered "$tempdir/out.pdf" "$tempdir/group4.tiff" pnggray
-
-compare_pdfimages "$tempdir/out.pdf" "$tempdir/group4.tiff"
-
-cat << 'END' | checkpdf "$tempdir/out.pdf"
-Contents.read_bytes() == b'q\n45.0000 0 0 45.0000 0.0000 0.0000 cm\n/Im0 Do\nQ'
-Resources.XObject.Im0.BitsPerComponent == 1
-Resources.XObject.Im0.ColorSpace == "/DeviceGray"
-Resources.XObject.Im0.DecodeParms[0].BlackIs1 == False
-Resources.XObject.Im0.DecodeParms[0].Columns == 60
-Resources.XObject.Im0.DecodeParms[0].K == -1
-Resources.XObject.Im0.DecodeParms[0].Rows == 60
-Resources.XObject.Im0.Filter[0] == "/CCITTFaxDecode"
-Resources.XObject.Im0.Height == 60
-Resources.XObject.Im0.Width == 60
-END
-rm "$tempdir/out.pdf"
-done
-
-rm "$tempdir/group4.tiff"
-j=$((j+1))
-
-###############################################################################
-echo "Test $j/$tests TIFF CCITT Group4, big endian, msb-to-lsb, min-is-white"
-
-convert "$tempdir/gray1.png" -compress group4 -define tiff:endian=msb -define tiff:fill-order=msb -define quantum:polarity=min-is-white "$tempdir/group4.tiff"
-tiffinfo "$tempdir/group4.tiff" | grep --quiet 'Bits/Sample: 1'
-tiffinfo "$tempdir/group4.tiff" | grep --quiet 'Compression Scheme: CCITT Group 4'
-tiffinfo "$tempdir/group4.tiff" | grep --quiet 'Photometric Interpretation: min-is-white'
-tiffinfo "$tempdir/group4.tiff" | grep --quiet 'FillOrder: msb-to-lsb'
-tiffinfo "$tempdir/group4.tiff" | grep --quiet 'Samples/Pixel: 1'
-identify -verbose "$tempdir/group4.tiff" | grep --quiet 'Type: Bilevel'
-identify -verbose "$tempdir/group4.tiff" | grep --quiet 'Endian*ess: MSB'
-identify -verbose "$tempdir/group4.tiff" | grep --quiet 'Depth: 1-bit'
-identify -verbose "$tempdir/group4.tiff" | grep --quiet '[gG]ray: 1-bit'
-identify -verbose "$tempdir/group4.tiff" | grep --quiet 'Compression: Group4'
-identify -verbose "$tempdir/group4.tiff" | grep --quiet 'tiff:endian: msb'
-identify -verbose "$tempdir/group4.tiff" | grep --quiet 'tiff:photometric: min-is-white'
-
-for engine in $available_engines; do
-img2pdf $engine "$tempdir/group4.tiff" "$tempdir/out.pdf"
-
-compare_rendered "$tempdir/out.pdf" "$tempdir/group4.tiff" pnggray
-
-compare_pdfimages "$tempdir/out.pdf" "$tempdir/group4.tiff"
-
-cat << 'END' | checkpdf "$tempdir/out.pdf"
-Contents.read_bytes() == b'q\n45.0000 0 0 45.0000 0.0000 0.0000 cm\n/Im0 Do\nQ'
-Resources.XObject.Im0.BitsPerComponent == 1
-Resources.XObject.Im0.ColorSpace == "/DeviceGray"
-Resources.XObject.Im0.DecodeParms[0].BlackIs1 == False
-Resources.XObject.Im0.DecodeParms[0].Columns == 60
-Resources.XObject.Im0.DecodeParms[0].K == -1
-Resources.XObject.Im0.DecodeParms[0].Rows == 60
-Resources.XObject.Im0.Filter[0] == "/CCITTFaxDecode"
-Resources.XObject.Im0.Height == 60
-Resources.XObject.Im0.Width == 60
-END
-rm "$tempdir/out.pdf"
-done
-
-rm "$tempdir/group4.tiff"
-j=$((j+1))
-
-###############################################################################
-echo "Test $j/$tests TIFF CCITT Group4, big endian, lsb-to-msb, min-is-white"
-
-convert "$tempdir/gray1.png" -compress group4 -define tiff:endian=msb -define tiff:fill-order=lsb -define quantum:polarity=min-is-white "$tempdir/group4.tiff"
-tiffinfo "$tempdir/group4.tiff" | grep --quiet 'Bits/Sample: 1'
-tiffinfo "$tempdir/group4.tiff" | grep --quiet 'Compression Scheme: CCITT Group 4'
-tiffinfo "$tempdir/group4.tiff" | grep --quiet 'Photometric Interpretation: min-is-white'
-tiffinfo "$tempdir/group4.tiff" | grep --quiet 'FillOrder: lsb-to-msb'
-tiffinfo "$tempdir/group4.tiff" | grep --quiet 'Samples/Pixel: 1'
-identify -verbose "$tempdir/group4.tiff" | grep --quiet 'Type: Bilevel'
-identify -verbose "$tempdir/group4.tiff" | grep --quiet 'Endian*ess: MSB'
-identify -verbose "$tempdir/group4.tiff" | grep --quiet 'Depth: 1-bit'
-identify -verbose "$tempdir/group4.tiff" | grep --quiet '[gG]ray: 1-bit'
-identify -verbose "$tempdir/group4.tiff" | grep --quiet 'Compression: Group4'
-identify -verbose "$tempdir/group4.tiff" | grep --quiet 'tiff:endian: msb'
-identify -verbose "$tempdir/group4.tiff" | grep --quiet 'tiff:photometric: min-is-white'
-
-for engine in $available_engines; do
-img2pdf $engine "$tempdir/group4.tiff" "$tempdir/out.pdf"
-
-compare_rendered "$tempdir/out.pdf" "$tempdir/group4.tiff" pnggray
-
-compare_pdfimages "$tempdir/out.pdf" "$tempdir/group4.tiff"
-
-cat << 'END' | checkpdf "$tempdir/out.pdf"
-Contents.read_bytes() == b'q\n45.0000 0 0 45.0000 0.0000 0.0000 cm\n/Im0 Do\nQ'
-Resources.XObject.Im0.BitsPerComponent == 1
-Resources.XObject.Im0.ColorSpace == "/DeviceGray"
-Resources.XObject.Im0.DecodeParms[0].BlackIs1 == False
-Resources.XObject.Im0.DecodeParms[0].Columns == 60
-Resources.XObject.Im0.DecodeParms[0].K == -1
-Resources.XObject.Im0.DecodeParms[0].Rows == 60
-Resources.XObject.Im0.Filter[0] == "/CCITTFaxDecode"
-Resources.XObject.Im0.Height == 60
-Resources.XObject.Im0.Width == 60
-END
-rm "$tempdir/out.pdf"
-done
-
-rm "$tempdir/group4.tiff"
-j=$((j+1))
-
-###############################################################################
-echo "Test $j/$tests TIFF CCITT Group4, little endian, msb-to-lsb, min-is-black"
-
-# We create a min-is-black group4 tiff with PIL because it creates these by
-# default (and without the option to do otherwise) whereas imagemagick only
-# became able to do it through commit 00730551f0a34328685c59d0dde87dd9e366103a
-# See https://www.imagemagick.org/discourse-server/viewtopic.php?f=1&t=34605
-python3 -c 'from PIL import Image;Image.open("'"$tempdir/gray1.png"'").save("'"$tempdir/group4.tiff"'",format="TIFF",compression="group4")'
-tiffinfo "$tempdir/group4.tiff" | grep --quiet 'Bits/Sample: 1'
-tiffinfo "$tempdir/group4.tiff" | grep --quiet 'Compression Scheme: CCITT Group 4'
-tiffinfo "$tempdir/group4.tiff" | grep --quiet 'Photometric Interpretation: min-is-black'
-# PIL doesn't set those
-#tiffinfo "$tempdir/group4.tiff" | grep --quiet 'FillOrder: msb-to-lsb'
-#tiffinfo "$tempdir/group4.tiff" | grep --quiet 'Samples/Pixel: 1'
-identify -verbose "$tempdir/group4.tiff" | grep --quiet 'Type: Bilevel'
-identify -verbose "$tempdir/group4.tiff" | grep --quiet 'Endian*ess: LSB'
-identify -verbose "$tempdir/group4.tiff" | grep --quiet 'Depth: 1-bit'
-identify -verbose "$tempdir/group4.tiff" | grep --quiet '[gG]ray: 1-bit'
-identify -verbose "$tempdir/group4.tiff" | grep --quiet 'Compression: Group4'
-identify -verbose "$tempdir/group4.tiff" | grep --quiet 'tiff:endian: lsb'
-identify -verbose "$tempdir/group4.tiff" | grep --quiet 'tiff:photometric: min-is-black'
-
-for engine in $available_engines; do
-img2pdf $engine "$tempdir/group4.tiff" "$tempdir/out.pdf"
-
-compare_rendered "$tempdir/out.pdf" "$tempdir/group4.tiff" pnggray
-
-compare_pdfimages "$tempdir/out.pdf" "$tempdir/group4.tiff"
-
-cat << 'END' | checkpdf "$tempdir/out.pdf"
-Contents.read_bytes() == b'q\n45.0000 0 0 45.0000 0.0000 0.0000 cm\n/Im0 Do\nQ'
-Resources.XObject.Im0.BitsPerComponent == 1
-Resources.XObject.Im0.ColorSpace == "/DeviceGray"
-Resources.XObject.Im0.DecodeParms[0].BlackIs1 == True
-Resources.XObject.Im0.DecodeParms[0].Columns == 60
-Resources.XObject.Im0.DecodeParms[0].K == -1
-Resources.XObject.Im0.DecodeParms[0].Rows == 60
-Resources.XObject.Im0.Filter[0] == "/CCITTFaxDecode"
-Resources.XObject.Im0.Height == 60
-Resources.XObject.Im0.Width == 60
-END
-rm "$tempdir/out.pdf"
-done
-
-rm "$tempdir/group4.tiff"
-j=$((j+1))
-
-###############################################################################
-echo "Test $j/$tests TIFF CCITT Group4, without fillorder, samples/pixel, bits/sample"
-
-convert "$tempdir/gray1.png" -compress group4 -define tiff:endian=lsb -define tiff:fill-order=msb -define quantum:polarity=min-is-white "$tempdir/group4.tiff"
-# remove BitsPerSample (258)
-tiffset -u 258 "$tempdir/group4.tiff"
-# remove FillOrder (266)
-tiffset -u 266 "$tempdir/group4.tiff"
-# remove SamplesPerPixel (277)
-tiffset -u 277 "$tempdir/group4.tiff"
-tiffinfo "$tempdir/group4.tiff" | grep --quiet 'Bits/Sample: 1' && exit 1
-tiffinfo "$tempdir/group4.tiff" | grep --quiet 'Compression Scheme: CCITT Group 4'
-tiffinfo "$tempdir/group4.tiff" | grep --quiet 'Photometric Interpretation: min-is-white'
-tiffinfo "$tempdir/group4.tiff" | grep --quiet 'FillOrder: msb-to-lsb' && exit 1
-tiffinfo "$tempdir/group4.tiff" | grep --quiet 'Samples/Pixel: 1' && exit 1
-identify -verbose "$tempdir/group4.tiff" | grep --quiet 'Type: Bilevel'
-identify -verbose "$tempdir/group4.tiff" | grep --quiet 'Endian*ess: LSB'
-identify -verbose "$tempdir/group4.tiff" | grep --quiet 'Depth: 1-bit'
-identify -verbose "$tempdir/group4.tiff" | grep --quiet '[gG]ray: 1-bit'
-identify -verbose "$tempdir/group4.tiff" | grep --quiet 'Compression: Group4'
-identify -verbose "$tempdir/group4.tiff" | grep --quiet 'tiff:endian: lsb'
-identify -verbose "$tempdir/group4.tiff" | grep --quiet 'tiff:photometric: min-is-white'
-
-for engine in $available_engines; do
-img2pdf $engine "$tempdir/group4.tiff" "$tempdir/out.pdf"
-
-compare_rendered "$tempdir/out.pdf" "$tempdir/group4.tiff" pnggray
-
-compare_pdfimages "$tempdir/out.pdf" "$tempdir/group4.tiff"
-
-cat << 'END' | checkpdf "$tempdir/out.pdf"
-Contents.read_bytes() == b'q\n45.0000 0 0 45.0000 0.0000 0.0000 cm\n/Im0 Do\nQ'
-Resources.XObject.Im0.BitsPerComponent == 1
-Resources.XObject.Im0.ColorSpace == "/DeviceGray"
-Resources.XObject.Im0.DecodeParms[0].BlackIs1 == False
-Resources.XObject.Im0.DecodeParms[0].Columns == 60
-Resources.XObject.Im0.DecodeParms[0].K == -1
-Resources.XObject.Im0.DecodeParms[0].Rows == 60
-Resources.XObject.Im0.Filter[0] == "/CCITTFaxDecode"
-Resources.XObject.Im0.Height == 60
-Resources.XObject.Im0.Width == 60
-END
-rm "$tempdir/out.pdf"
-done
-
-rm "$tempdir/group4.tiff"
-j=$((j+1))
-
-###############################################################################
-echo "Test $j/$tests TIFF CCITT Group4, without rows-per-strip"
-
-convert "$tempdir/gray1.png" -compress group4 -define tiff:endian=lsb -define tiff:fill-order=msb -define quantum:polarity=min-is-white -define tiff:rows-per-strip=4294967295 "$tempdir/group4.tiff"
-# remove RowsPerStrip (278)
-tiffset -u 278 "$tempdir/group4.tiff"
-tiffinfo "$tempdir/group4.tiff" | grep --quiet 'Bits/Sample: 1'
-tiffinfo "$tempdir/group4.tiff" | grep --quiet 'Compression Scheme: CCITT Group 4'
-tiffinfo "$tempdir/group4.tiff" | grep --quiet 'Photometric Interpretation: min-is-white'
-tiffinfo "$tempdir/group4.tiff" | grep --quiet 'FillOrder: msb-to-lsb'
-tiffinfo "$tempdir/group4.tiff" | grep --quiet 'Samples/Pixel: 1'
-tiffinfo "$tempdir/group4.tiff" | grep --quiet 'Rows/Strip:' && exit 1
-identify -verbose "$tempdir/group4.tiff" | grep --quiet 'Type: Bilevel'
-identify -verbose "$tempdir/group4.tiff" | grep --quiet 'Endian*ess: LSB'
-identify -verbose "$tempdir/group4.tiff" | grep --quiet 'Depth: 1-bit'
-identify -verbose "$tempdir/group4.tiff" | grep --quiet '[gG]ray: 1-bit'
-identify -verbose "$tempdir/group4.tiff" | grep --quiet 'Compression: Group4'
-identify -verbose "$tempdir/group4.tiff" | grep --quiet 'tiff:endian: lsb'
-identify -verbose "$tempdir/group4.tiff" | grep --quiet 'tiff:photometric: min-is-white'
-
-for engine in $available_engines; do
-img2pdf $engine "$tempdir/group4.tiff" "$tempdir/out.pdf"
-
-compare_rendered "$tempdir/out.pdf" "$tempdir/group4.tiff" pnggray
-
-compare_pdfimages "$tempdir/out.pdf" "$tempdir/group4.tiff"
-
-cat << 'END' | checkpdf "$tempdir/out.pdf"
-Contents.read_bytes() == b'q\n45.0000 0 0 45.0000 0.0000 0.0000 cm\n/Im0 Do\nQ'
-Resources.XObject.Im0.BitsPerComponent == 1
-Resources.XObject.Im0.ColorSpace == "/DeviceGray"
-Resources.XObject.Im0.DecodeParms[0].BlackIs1 == False
-Resources.XObject.Im0.DecodeParms[0].Columns == 60
-Resources.XObject.Im0.DecodeParms[0].K == -1
-Resources.XObject.Im0.DecodeParms[0].Rows == 60
-Resources.XObject.Im0.Filter[0] == "/CCITTFaxDecode"
-Resources.XObject.Im0.Height == 60
-Resources.XObject.Im0.Width == 60
-END
-rm "$tempdir/out.pdf"
-done
-
-rm "$tempdir/group4.tiff"
-j=$((j+1))
-
-rm "$tempdir/alpha.png" "$tempdir/normal.png" "$tempdir/inverse.png" "$tempdir/palette1.png" "$tempdir/palette2.png" "$tempdir/palette4.png" "$tempdir/palette8.png" "$tempdir/gray8.png" "$tempdir/normal16.png" "$tempdir/gray16.png" "$tempdir/gray4.png" "$tempdir/gray2.png" "$tempdir/gray1.png"
-rmdir "$tempdir"
-
-trap - EXIT