summaryrefslogtreecommitdiff
path: root/src/img2pdf_test.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/img2pdf_test.py')
-rwxr-xr-xsrc/img2pdf_test.py743
1 files changed, 570 insertions, 173 deletions
diff --git a/src/img2pdf_test.py b/src/img2pdf_test.py
index 80dd8e0..4882092 100755
--- a/src/img2pdf_test.py
+++ b/src/img2pdf_test.py
@@ -19,6 +19,8 @@ from packaging.version import parse as parse_version
import warnings
import json
import pathlib
+import itertools
+import xml.etree.ElementTree as ET
img2pdfprog = os.getenv("img2pdfprog", default="src/img2pdf.py")
@@ -37,6 +39,14 @@ for glob in ICC_PROFILE_PATHS:
ICC_PROFILE = path
break
+HAVE_FAKETIME = True
+try:
+ ver = subprocess.check_output(["faketime", "--version"])
+ if b"faketime: Version " not in ver:
+ HAVE_FAKETIME = False
+except FileNotFoundError:
+ HAVE_FAKETIME = False
+
HAVE_MUTOOL = True
try:
ver = subprocess.check_output(["mutool", "-v"], stderr=subprocess.STDOUT)
@@ -113,11 +123,36 @@ except subprocess.CalledProcessError:
if not HAVE_JP2:
warnings.warn("imagemagick has no jpeg 2000 support, skipping certain checks...")
+# the result of compare -metric PSNR is either just a floating point value or a
+# floating point value following by the same value multiplied by 0.01,
+# surrounded in parenthesis since ImagemMagick 7.1.0-48:
+# https://github.com/ImageMagick/ImageMagick/commit/751829cd4c911d7a42953a47c1f73068d9e7da2f
+psnr_re = re.compile(rb"((?:inf|(?:0|[1-9][0-9]*)(?:\.[0-9]+)?))(?: \([0-9.]+\))?")
+
###############################################################################
# HELPER FUNCTIONS #
###############################################################################
+# Interpret a datetime string in a given timezone and format it according to a
+# given format string in in UTC.
+# We avoid using the Python datetime module for this job because doing so would
+# just replicate the code we want to test for correctness.
+def tz2utcstrftime(string, fmt, timezone):
+ return (
+ subprocess.check_output(
+ [
+ "date",
+ "--utc",
+ f'--date=TZ="{timezone}" {string}',
+ f"+{fmt}",
+ ]
+ )
+ .decode("utf8")
+ .removesuffix("\n")
+ )
+
+
def find_closest_palette_color(color, palette):
if color.ndim == 0:
idx = (numpy.abs(palette - color)).argmin()
@@ -291,7 +326,7 @@ def write_png(data, path, bitdepth, colortype, palette=None, iccp=None):
for j in range(valsperbyte):
if x + j >= data.shape[1]:
break
- val |= (data[y, x + j].astype(">u2") & (2 ** bitdepth - 1)) << (
+ val |= (data[y, x + j].astype(">u2") & (2**bitdepth - 1)) << (
(valsperbyte - j - 1) * bitdepth
)
raw += struct.pack(">B", val)
@@ -310,9 +345,7 @@ def write_png(data, path, bitdepth, colortype, palette=None, iccp=None):
def compare(im1, im2, exact, icc, cmyk):
if exact:
- if cmyk:
- raise Exception("cmyk cannot be exact")
- elif icc:
+ if icc:
raise Exception("icc cannot be exact")
else:
subprocess.check_call(
@@ -320,6 +353,8 @@ def compare(im1, im2, exact, icc, cmyk):
+ [
"-metric",
"AE",
+ "-alpha",
+ "off",
im1,
im2,
"null:",
@@ -345,7 +380,10 @@ def compare(im1, im2, exact, icc, cmyk):
stderr=subprocess.PIPE,
).stderr
assert psnr != b"0"
- psnr = float(psnr.strip(b"0"))
+ assert psnr != b"0 (0)"
+ assert psnr_re.fullmatch(psnr) is not None, psnr
+ psnr = psnr_re.fullmatch(psnr).group(1)
+ psnr = float(psnr)
assert psnr != 0 # or otherwise we would use the exact variant
assert psnr > 50
@@ -501,7 +539,9 @@ def compare_pdfimages_png(tmpdir, img, pdf, exact=True, icc=False):
stderr=subprocess.PIPE,
).stderr
assert psnr != b"0"
- psnr = float(psnr.strip(b"0"))
+ assert psnr != b"0 (0)"
+ psnr = psnr_re.fullmatch(psnr).group(1)
+ psnr = float(psnr)
assert psnr != 0 # or otherwise we would use the exact variant
assert psnr > 50
(tmpdir / "images-000.png").unlink()
@@ -586,7 +626,7 @@ def alpha_value():
alpha = numpy.zeros((60, 60, 4), dtype=numpy.dtype("int64"))
# draw three circles
- for (xpos, ypos, color) in [
+ for xpos, ypos, color in [
(12, 3, [0xFFFF, 0, 0, 0xFFFF]),
(21, 21, [0, 0xFFFF, 0, 0xFFFF]),
(3, 21, [0, 0, 0xFFFF, 0xFFFF]),
@@ -1171,6 +1211,74 @@ def jpg_2000_img(tmp_path_factory, tmp_normal_png):
@pytest.fixture(scope="session")
+def jpg_2000_rgba8_img(tmp_path_factory, tmp_alpha_png):
+ in_img = tmp_path_factory.mktemp("jpg_2000_rgba8") / "in.jp2"
+ subprocess.check_call(CONVERT + [str(tmp_alpha_png), "-depth", "8", 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
+ # the bare dictionary
+ if "image" in identify:
+ identify = [identify]
+ assert "image" in identify[0]
+ assert identify[0]["image"].get("format") == "JP2", str(identify)
+ assert identify[0]["image"].get("mimeType") == "image/jp2", str(identify)
+ assert identify[0]["image"].get("geometry") == {
+ "width": 60,
+ "height": 60,
+ "x": 0,
+ "y": 0,
+ }, 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("depth") == 8, str(identify)
+ assert identify[0]["image"].get("pageGeometry") == {
+ "width": 60,
+ "height": 60,
+ "x": 0,
+ "y": 0,
+ }, str(identify)
+ assert identify[0]["image"].get("compression") == "JPEG2000", str(identify)
+ yield in_img
+ in_img.unlink()
+
+
+@pytest.fixture(scope="session")
+def jpg_2000_rgba16_img(tmp_path_factory, tmp_alpha_png):
+ in_img = tmp_path_factory.mktemp("jpg_2000_rgba16") / "in.jp2"
+ 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
+ # the bare dictionary
+ if "image" in identify:
+ identify = [identify]
+ assert "image" in identify[0]
+ assert identify[0]["image"].get("format") == "JP2", str(identify)
+ assert identify[0]["image"].get("mimeType") == "image/jp2", str(identify)
+ assert identify[0]["image"].get("geometry") == {
+ "width": 60,
+ "height": 60,
+ "x": 0,
+ "y": 0,
+ }, 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("depth") == 16, str(identify)
+ assert identify[0]["image"].get("pageGeometry") == {
+ "width": 60,
+ "height": 60,
+ "x": 0,
+ "y": 0,
+ }, str(identify)
+ assert identify[0]["image"].get("compression") == "JPEG2000", str(identify)
+ yield in_img
+ in_img.unlink()
+
+
+@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:"]))
@@ -1582,7 +1690,7 @@ def png_gray1_img(tmp_path_factory, tmp_gray1_png):
"y": 0,
}, 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("type") in ["Bilevel", "Grayscale"], str(identify)
assert identify[0]["image"].get("depth") == 1, str(identify)
assert identify[0]["image"].get("pageGeometry") == {
"width": 60,
@@ -2313,10 +2421,6 @@ 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)
- 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)
assert identify[0]["image"].get("baseDepth") == 32, str(identify)
assert identify[0]["image"].get("pageGeometry") == {
@@ -2332,9 +2436,6 @@ def tiff_float_img(tmp_path_factory, tmp_normal_png):
assert (
identify[0]["image"].get("properties", {}).get("tiff:alpha") == "unspecified"
), str(identify)
- assert identify[0]["image"].get("properties", {}).get("tiff:endian") == "lsb", str(
- identify
- )
assert (
identify[0]["image"].get("properties", {}).get("tiff:photometric") == "RGB"
), str(identify)
@@ -2374,10 +2475,6 @@ 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)
- 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)
assert identify[0]["image"].get("pageGeometry") == {
"width": 60,
@@ -2388,9 +2485,6 @@ def tiff_cmyk8_img(tmp_path_factory, tmp_normal_png):
assert (
identify[0]["image"].get("properties", {}).get("tiff:alpha") == "unspecified"
), str(identify)
- assert identify[0]["image"].get("properties", {}).get("tiff:endian") == "lsb", str(
- identify
- )
assert (
identify[0]["image"].get("properties", {}).get("tiff:photometric")
== "separated"
@@ -2433,10 +2527,6 @@ 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)
- 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)
assert identify[0]["image"].get("pageGeometry") == {
"width": 60,
@@ -2447,9 +2537,6 @@ def tiff_cmyk16_img(tmp_path_factory, tmp_normal_png):
assert (
identify[0]["image"].get("properties", {}).get("tiff:alpha") == "unspecified"
), str(identify)
- assert identify[0]["image"].get("properties", {}).get("tiff:endian") == "lsb", str(
- identify
- )
assert (
identify[0]["image"].get("properties", {}).get("tiff:photometric")
== "separated"
@@ -2482,10 +2569,6 @@ 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)
- 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)
assert identify[0]["image"].get("pageGeometry") == {
"width": 60,
@@ -2496,9 +2579,6 @@ def tiff_rgb8_img(tmp_path_factory, tmp_normal_png):
assert (
identify[0]["image"].get("properties", {}).get("tiff:alpha") == "unspecified"
), str(identify)
- assert identify[0]["image"].get("properties", {}).get("tiff:endian") == "lsb", str(
- identify
- )
assert (
identify[0]["image"].get("properties", {}).get("tiff:photometric") == "RGB"
), str(identify)
@@ -2538,14 +2618,6 @@ 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)
- 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
- 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,
@@ -2556,9 +2628,6 @@ def tiff_rgb12_img(tmp_path_factory, tmp_normal16_png):
assert (
identify[0]["image"].get("properties", {}).get("tiff:alpha") == "unspecified"
), str(identify)
- assert identify[0]["image"].get("properties", {}).get("tiff:endian") == "lsb", str(
- identify
- )
assert (
identify[0]["image"].get("properties", {}).get("tiff:photometric") == "RGB"
), str(identify)
@@ -2598,11 +2667,6 @@ 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)
- 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)
assert identify[0]["image"].get("baseDepth") == 14, str(identify)
assert identify[0]["image"].get("pageGeometry") == {
"width": 60,
@@ -2613,9 +2677,6 @@ def tiff_rgb14_img(tmp_path_factory, tmp_normal16_png):
assert (
identify[0]["image"].get("properties", {}).get("tiff:alpha") == "unspecified"
), str(identify)
- assert identify[0]["image"].get("properties", {}).get("tiff:endian") == "lsb", str(
- identify
- )
assert (
identify[0]["image"].get("properties", {}).get("tiff:photometric") == "RGB"
), str(identify)
@@ -2655,10 +2716,6 @@ 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)
- 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)
assert identify[0]["image"].get("pageGeometry") == {
"width": 60,
@@ -2669,9 +2726,6 @@ def tiff_rgb16_img(tmp_path_factory, tmp_normal16_png):
assert (
identify[0]["image"].get("properties", {}).get("tiff:alpha") == "unspecified"
), str(identify)
- assert identify[0]["image"].get("properties", {}).get("tiff:endian") == "lsb", str(
- identify
- )
assert (
identify[0]["image"].get("properties", {}).get("tiff:photometric") == "RGB"
), str(identify)
@@ -2712,10 +2766,6 @@ 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)
- 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)
assert identify[0]["image"].get("pageGeometry") == {
"width": 60,
@@ -2726,9 +2776,6 @@ def tiff_rgba8_img(tmp_path_factory, tmp_alpha_png):
assert (
identify[0]["image"].get("properties", {}).get("tiff:alpha") == "unassociated"
), str(identify)
- assert identify[0]["image"].get("properties", {}).get("tiff:endian") == "lsb", str(
- identify
- )
assert (
identify[0]["image"].get("properties", {}).get("tiff:photometric") == "RGB"
), str(identify)
@@ -2769,10 +2816,6 @@ 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)
- 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)
assert identify[0]["image"].get("pageGeometry") == {
"width": 60,
@@ -2783,9 +2826,6 @@ def tiff_rgba16_img(tmp_path_factory, tmp_alpha_png):
assert (
identify[0]["image"].get("properties", {}).get("tiff:alpha") == "unassociated"
), str(identify)
- assert identify[0]["image"].get("properties", {}).get("tiff:endian") == "lsb", str(
- identify
- )
assert (
identify[0]["image"].get("properties", {}).get("tiff:photometric") == "RGB"
), str(identify)
@@ -2825,10 +2865,6 @@ 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)
- 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)
assert identify[0]["image"].get("pageGeometry") == {
"width": 60,
@@ -2839,9 +2875,6 @@ def tiff_gray1_img(tmp_path_factory, tmp_gray1_png):
assert (
identify[0]["image"].get("properties", {}).get("tiff:alpha") == "unspecified"
), str(identify)
- assert identify[0]["image"].get("properties", {}).get("tiff:endian") == "lsb", str(
- identify
- )
assert (
identify[0]["image"].get("properties", {}).get("tiff:photometric")
== "min-is-black"
@@ -2882,10 +2915,6 @@ 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)
- 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)
assert identify[0]["image"].get("pageGeometry") == {
"width": 60,
@@ -2896,9 +2925,6 @@ def tiff_gray2_img(tmp_path_factory, tmp_gray2_png):
assert (
identify[0]["image"].get("properties", {}).get("tiff:alpha") == "unspecified"
), str(identify)
- assert identify[0]["image"].get("properties", {}).get("tiff:endian") == "lsb", str(
- identify
- )
assert (
identify[0]["image"].get("properties", {}).get("tiff:photometric")
== "min-is-black"
@@ -2939,10 +2965,6 @@ 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)
- 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)
assert identify[0]["image"].get("pageGeometry") == {
"width": 60,
@@ -2953,9 +2975,6 @@ def tiff_gray4_img(tmp_path_factory, tmp_gray4_png):
assert (
identify[0]["image"].get("properties", {}).get("tiff:alpha") == "unspecified"
), str(identify)
- assert identify[0]["image"].get("properties", {}).get("tiff:endian") == "lsb", str(
- identify
- )
assert (
identify[0]["image"].get("properties", {}).get("tiff:photometric")
== "min-is-black"
@@ -2996,10 +3015,6 @@ 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)
- 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)
assert identify[0]["image"].get("pageGeometry") == {
"width": 60,
@@ -3010,9 +3025,6 @@ def tiff_gray8_img(tmp_path_factory, tmp_gray8_png):
assert (
identify[0]["image"].get("properties", {}).get("tiff:alpha") == "unspecified"
), str(identify)
- assert identify[0]["image"].get("properties", {}).get("tiff:endian") == "lsb", str(
- identify
- )
assert (
identify[0]["image"].get("properties", {}).get("tiff:photometric")
== "min-is-black"
@@ -3053,10 +3065,6 @@ 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)
- 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)
assert identify[0]["image"].get("pageGeometry") == {
"width": 60,
@@ -3067,9 +3075,6 @@ def tiff_gray16_img(tmp_path_factory, tmp_gray16_png):
assert (
identify[0]["image"].get("properties", {}).get("tiff:alpha") == "unspecified"
), str(identify)
- assert identify[0]["image"].get("properties", {}).get("tiff:endian") == "lsb", str(
- identify
- )
assert (
identify[0]["image"].get("properties", {}).get("tiff:photometric")
== "min-is-black"
@@ -3112,10 +3117,6 @@ 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)
- 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)
assert identify[0]["image"].get("pageGeometry") == {
"width": 60,
@@ -3126,9 +3127,6 @@ def tiff_multipage_img(tmp_path_factory, tmp_normal_png, tmp_inverse_png):
assert (
identify[0]["image"].get("properties", {}).get("tiff:alpha") == "unspecified"
), str(identify)
- assert identify[0]["image"].get("properties", {}).get("tiff:endian") == "lsb", str(
- identify
- )
assert (
identify[0]["image"].get("properties", {}).get("tiff:photometric") == "RGB"
), str(identify)
@@ -3152,10 +3150,6 @@ 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)
- 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)
assert identify[0]["image"].get("pageGeometry") == {
"width": 60,
@@ -3166,9 +3160,6 @@ def tiff_multipage_img(tmp_path_factory, tmp_normal_png, tmp_inverse_png):
assert (
identify[0]["image"].get("properties", {}).get("tiff:alpha") == "unspecified"
), str(identify)
- assert identify[0]["image"].get("properties", {}).get("tiff:endian") == "lsb", str(
- identify
- )
assert (
identify[0]["image"].get("properties", {}).get("tiff:photometric") == "RGB"
), str(identify)
@@ -3201,10 +3192,6 @@ 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)
- 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)
assert identify[0]["image"].get("baseDepth") == 1, str(identify)
assert identify[0]["image"].get("colormapEntries") == 2, str(identify)
@@ -3217,9 +3204,6 @@ def tiff_palette1_img(tmp_path_factory, tmp_palette1_png):
assert (
identify[0]["image"].get("properties", {}).get("tiff:alpha") == "unspecified"
), str(identify)
- assert identify[0]["image"].get("properties", {}).get("tiff:endian") == "lsb", str(
- identify
- )
assert (
identify[0]["image"].get("properties", {}).get("tiff:photometric") == "palette"
), str(identify)
@@ -3251,10 +3235,6 @@ 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)
- 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)
assert identify[0]["image"].get("baseDepth") == 2, str(identify)
assert identify[0]["image"].get("colormapEntries") == 4, str(identify)
@@ -3267,9 +3247,6 @@ def tiff_palette2_img(tmp_path_factory, tmp_palette2_png):
assert (
identify[0]["image"].get("properties", {}).get("tiff:alpha") == "unspecified"
), str(identify)
- assert identify[0]["image"].get("properties", {}).get("tiff:endian") == "lsb", str(
- identify
- )
assert (
identify[0]["image"].get("properties", {}).get("tiff:photometric") == "palette"
), str(identify)
@@ -3301,10 +3278,6 @@ 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)
- 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)
assert identify[0]["image"].get("baseDepth") == 4, str(identify)
assert identify[0]["image"].get("colormapEntries") == 16, str(identify)
@@ -3317,9 +3290,6 @@ def tiff_palette4_img(tmp_path_factory, tmp_palette4_png):
assert (
identify[0]["image"].get("properties", {}).get("tiff:alpha") == "unspecified"
), str(identify)
- assert identify[0]["image"].get("properties", {}).get("tiff:endian") == "lsb", str(
- identify
- )
assert (
identify[0]["image"].get("properties", {}).get("tiff:photometric") == "palette"
), str(identify)
@@ -3351,10 +3321,6 @@ 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)
- 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)
assert identify[0]["image"].get("colormapEntries") == 256, str(identify)
assert identify[0]["image"].get("pageGeometry") == {
@@ -3366,9 +3332,6 @@ def tiff_palette8_img(tmp_path_factory, tmp_palette8_png):
assert (
identify[0]["image"].get("properties", {}).get("tiff:alpha") == "unspecified"
), str(identify)
- assert identify[0]["image"].get("properties", {}).get("tiff:endian") == "lsb", str(
- identify
- )
assert (
identify[0]["image"].get("properties", {}).get("tiff:photometric") == "palette"
), str(identify)
@@ -3415,9 +3378,10 @@ def tiff_ccitt_lsb_m2l_white_img(tmp_path_factory, tmp_gray1_png):
assert identify[0]["image"].get("colorspace") == "Gray", str(identify)
assert identify[0]["image"].get("type") == "Bilevel", str(identify)
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(endian) in [
+ "Undefined",
+ "LSB",
+ ], str(identify)
assert identify[0]["image"].get("depth") == 1, str(identify)
assert identify[0]["image"].get("pageGeometry") == {
"width": 60,
@@ -3665,9 +3629,10 @@ def tiff_ccitt_lsb_m2l_black_img(tmp_path_factory, tmp_gray1_png):
assert identify[0]["image"].get("colorspace") == "Gray", str(identify)
assert identify[0]["image"].get("type") == "Bilevel", str(identify)
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(endian) in [
+ "Undefined",
+ "LSB",
+ ], str(identify)
assert identify[0]["image"].get("depth") == 1, str(identify)
assert identify[0]["image"].get("pageGeometry") == {
"width": 60,
@@ -3755,9 +3720,10 @@ def tiff_ccitt_nometa1_img(tmp_path_factory, tmp_gray1_png):
assert identify[0]["image"].get("colorspace") == "Gray", str(identify)
assert identify[0]["image"].get("type") == "Bilevel", str(identify)
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(endian) in [
+ "Undefined",
+ "LSB",
+ ], str(identify)
assert identify[0]["image"].get("depth") == 1, str(identify)
assert identify[0]["image"].get("pageGeometry") == {
"width": 60,
@@ -3839,9 +3805,10 @@ def tiff_ccitt_nometa2_img(tmp_path_factory, tmp_gray1_png):
assert identify[0]["image"].get("units") == "PixelsPerInch", str(identify)
assert identify[0]["image"].get("type") == "Bilevel", str(identify)
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(endian) in [
+ "Undefined",
+ "LSB",
+ ], str(identify)
assert identify[0]["image"].get("colorspace") == "Gray", str(identify)
assert identify[0]["image"].get("depth") == 1, str(identify)
assert identify[0]["image"].get("compression") == "Group4", str(identify)
@@ -3877,6 +3844,127 @@ def tiff_ccitt_nometa2_img(tmp_path_factory, tmp_gray1_png):
@pytest.fixture(scope="session")
+def miff_cmyk8_img(tmp_path_factory, tmp_normal_png):
+ in_img = tmp_path_factory.mktemp("miff_cmyk8") / "in.miff"
+ subprocess.check_call(
+ CONVERT
+ + [
+ str(tmp_normal_png),
+ "-colorspace",
+ "cmyk",
+ 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
+ # the bare dictionary
+ if "image" in identify:
+ identify = [identify]
+ assert "image" in identify[0]
+ assert identify[0]["image"].get("format") == "MIFF", str(identify)
+ assert identify[0]["image"].get("class") == "DirectClass"
+ assert identify[0]["image"].get("type") == "ColorSeparation"
+ assert identify[0]["image"].get("geometry") == {
+ "width": 60,
+ "height": 60,
+ "x": 0,
+ "y": 0,
+ }, 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("depth") == 8, str(identify)
+ assert identify[0]["image"].get("pageGeometry") == {
+ "width": 60,
+ "height": 60,
+ "x": 0,
+ "y": 0,
+ }, str(identify)
+ yield in_img
+ in_img.unlink()
+
+
+@pytest.fixture(scope="session")
+def miff_cmyk16_img(tmp_path_factory, tmp_normal_png):
+ in_img = tmp_path_factory.mktemp("miff_cmyk16") / "in.miff"
+ subprocess.check_call(
+ CONVERT
+ + [
+ str(tmp_normal_png),
+ "-depth",
+ "16",
+ "-colorspace",
+ "cmyk",
+ 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
+ # the bare dictionary
+ if "image" in identify:
+ identify = [identify]
+ assert "image" in identify[0]
+ assert identify[0]["image"].get("format") == "MIFF", str(identify)
+ assert identify[0]["image"].get("class") == "DirectClass"
+ assert identify[0]["image"].get("type") == "ColorSeparation"
+ assert identify[0]["image"].get("geometry") == {
+ "width": 60,
+ "height": 60,
+ "x": 0,
+ "y": 0,
+ }, 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("depth") == 16, str(identify)
+ assert identify[0]["image"].get("baseDepth") == 16, str(identify)
+ assert identify[0]["image"].get("pageGeometry") == {
+ "width": 60,
+ "height": 60,
+ "x": 0,
+ "y": 0,
+ }, str(identify)
+ yield in_img
+ in_img.unlink()
+
+
+@pytest.fixture(scope="session")
+def miff_rgb8_img(tmp_path_factory, tmp_normal_png):
+ in_img = tmp_path_factory.mktemp("miff_rgb8") / "in.miff"
+ 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
+ # the bare dictionary
+ if "image" in identify:
+ identify = [identify]
+ assert "image" in identify[0]
+ assert identify[0]["image"].get("format") == "MIFF", str(identify)
+ assert identify[0]["image"].get("class") == "DirectClass"
+ assert identify[0]["image"].get("type") == "TrueColor"
+ assert identify[0]["image"].get("geometry") == {
+ "width": 60,
+ "height": 60,
+ "x": 0,
+ "y": 0,
+ }, 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("depth") == 8, str(identify)
+ assert identify[0]["image"].get("pageGeometry") == {
+ "width": 60,
+ "height": 60,
+ "x": 0,
+ "y": 0,
+ }, str(identify)
+ yield in_img
+ in_img.unlink()
+
+
+@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:"]))
@@ -4043,6 +4131,60 @@ def jpg_2000_pdf(tmp_path_factory, jpg_2000_img, request):
@pytest.fixture(scope="session", params=["internal", "pikepdf"])
+def jpg_2000_rgba8_pdf(tmp_path_factory, jpg_2000_rgba8_img, request):
+ out_pdf = tmp_path_factory.mktemp("jpg_2000_rgba8_pdf") / "out.pdf"
+ subprocess.check_call(
+ [
+ img2pdfprog,
+ "--producer=",
+ "--nodate",
+ "--engine=" + request.param,
+ "--output=" + str(out_pdf),
+ jpg_2000_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 not hasattr(p.pages[0].Resources.XObject.Im0, "ColorSpace")
+ assert p.pages[0].Resources.XObject.Im0.Filter == "/JPXDecode"
+ assert p.pages[0].Resources.XObject.Im0.Height == 60
+ assert p.pages[0].Resources.XObject.Im0.Width == 60
+ yield out_pdf
+ out_pdf.unlink()
+
+
+@pytest.fixture(scope="session", params=["internal", "pikepdf"])
+def jpg_2000_rgba16_pdf(tmp_path_factory, jpg_2000_rgba16_img, request):
+ out_pdf = tmp_path_factory.mktemp("jpg_2000_rgba16_pdf") / "out.pdf"
+ subprocess.check_call(
+ [
+ img2pdfprog,
+ "--producer=",
+ "--nodate",
+ "--engine=" + request.param,
+ "--output=" + str(out_pdf),
+ jpg_2000_rgba16_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 == 16
+ assert not hasattr(p.pages[0].Resources.XObject.Im0, "ColorSpace")
+ assert p.pages[0].Resources.XObject.Im0.Filter == "/JPXDecode"
+ assert p.pages[0].Resources.XObject.Im0.Height == 60
+ assert p.pages[0].Resources.XObject.Im0.Width == 60
+ yield out_pdf
+ out_pdf.unlink()
+
+
+@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(
@@ -4131,9 +4273,10 @@ def gif_transparent_pdf(tmp_path_factory, gif_transparent_img, request):
== 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.ColorSpace[0] == "/Indexed"
+ assert p.pages[0].Resources.XObject.Im0.ColorSpace[1] == "/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.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
@@ -5261,6 +5404,90 @@ def tiff_ccitt_nometa2_pdf(tmp_path_factory, tiff_ccitt_nometa2_img, request):
out_pdf.unlink()
+@pytest.fixture(scope="session", params=["internal", "pikepdf"])
+def miff_cmyk8_pdf(tmp_path_factory, miff_cmyk8_img, request):
+ out_pdf = tmp_path_factory.mktemp("miff_cmyk8_pdf") / "out.pdf"
+ subprocess.check_call(
+ [
+ img2pdfprog,
+ "--producer=",
+ "--nodate",
+ "--engine=" + request.param,
+ "--output=" + str(out_pdf),
+ str(miff_cmyk8_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 == "/DeviceCMYK"
+ 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
+ yield out_pdf
+ out_pdf.unlink()
+
+
+@pytest.fixture(scope="session", params=["internal", "pikepdf"])
+def miff_cmyk16_pdf(tmp_path_factory, miff_cmyk16_img, request):
+ out_pdf = tmp_path_factory.mktemp("miff_cmyk16_pdf") / "out.pdf"
+ subprocess.check_call(
+ [
+ img2pdfprog,
+ "--producer=",
+ "--nodate",
+ "--engine=" + request.param,
+ "--output=" + str(out_pdf),
+ str(miff_cmyk16_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 == 16
+ assert p.pages[0].Resources.XObject.Im0.ColorSpace == "/DeviceCMYK"
+ 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
+ yield out_pdf
+ out_pdf.unlink()
+
+
+@pytest.fixture(scope="session", params=["internal", "pikepdf"])
+def miff_rgb8_pdf(tmp_path_factory, miff_rgb8_img, request):
+ out_pdf = tmp_path_factory.mktemp("miff_rgb8_pdf") / "out.pdf"
+ subprocess.check_call(
+ [
+ img2pdfprog,
+ "--producer=",
+ "--nodate",
+ "--engine=" + request.param,
+ "--output=" + str(out_pdf),
+ str(miff_rgb8_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
+ yield out_pdf
+ out_pdf.unlink()
+
+
###############################################################################
# TEST CASES #
###############################################################################
@@ -5327,11 +5554,9 @@ def test_jpg_rot(tmp_path_factory, jpg_rot_img, jpg_rot_pdf):
)
def test_jpg_cmyk(tmp_path_factory, jpg_cmyk_img, jpg_cmyk_pdf):
tmpdir = tmp_path_factory.mktemp("jpg_cmyk")
- compare_ghostscript(
- tmpdir, jpg_cmyk_img, jpg_cmyk_pdf, gsdevice="tiff32nc", exact=False
- )
+ compare_ghostscript(tmpdir, jpg_cmyk_img, jpg_cmyk_pdf, gsdevice="tiff32nc")
# not testing with poppler as it cannot write CMYK images
- compare_mupdf(tmpdir, jpg_cmyk_img, jpg_cmyk_pdf, exact=False, cmyk=True)
+ compare_mupdf(tmpdir, jpg_cmyk_img, jpg_cmyk_pdf, cmyk=True)
compare_pdfimages_cmyk(tmpdir, jpg_cmyk_img, jpg_cmyk_pdf)
@@ -5354,6 +5579,45 @@ def test_jpg_2000(tmp_path_factory, jpg_2000_img, jpg_2000_pdf):
sys.platform in ["win32"],
reason="test utilities not available on Windows and MacOS",
)
+@pytest.mark.skipif(
+ not HAVE_JP2, reason="requires imagemagick with support for jpeg2000"
+)
+@pytest.mark.skipif(
+ True, reason="https://github.com/ImageMagick/ImageMagick6/issues/285"
+)
+def test_jpg_2000_rgba8(tmp_path_factory, jpg_2000_rgba8_img, jpg_2000_rgba8_pdf):
+ tmpdir = tmp_path_factory.mktemp("jpg_2000_rgba8")
+ compare_ghostscript(tmpdir, jpg_2000_rgba8_img, jpg_2000_rgba8_pdf)
+ compare_poppler(tmpdir, jpg_2000_rgba8_img, jpg_2000_rgba8_pdf)
+ # compare_mupdf(tmpdir, jpg_2000_rgba8_img, jpg_2000_rgba8_pdf)
+ compare_pdfimages_jp2(tmpdir, jpg_2000_rgba8_img, jpg_2000_rgba8_pdf)
+
+
+@pytest.mark.skipif(
+ sys.platform in ["win32"],
+ reason="test utilities not available on Windows and MacOS",
+)
+@pytest.mark.skipif(
+ not HAVE_JP2, reason="requires imagemagick with support for jpeg2000"
+)
+@pytest.mark.skipif(
+ True, reason="https://github.com/ImageMagick/ImageMagick6/issues/285"
+)
+def test_jpg_2000_rgba16(tmp_path_factory, jpg_2000_rgba16_img, jpg_2000_rgba16_pdf):
+ tmpdir = tmp_path_factory.mktemp("jpg_2000_rgba16")
+ compare_ghostscript(
+ tmpdir, jpg_2000_rgba16_img, jpg_2000_rgba16_pdf, gsdevice="tiff48nc"
+ )
+ # poppler outputs 8-bit RGB so the comparison will not be exact
+ # compare_poppler(tmpdir, jpg_2000_rgba16_img, jpg_2000_rgba16_pdf, exact=False)
+ # compare_mupdf(tmpdir, jpg_2000_rgba16_img, jpg_2000_rgba16_pdf)
+ compare_pdfimages_jp2(tmpdir, jpg_2000_rgba16_img, jpg_2000_rgba16_pdf)
+
+
+@pytest.mark.skipif(
+ 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):
tmpdir = tmp_path_factory.mktemp("png_rgb8")
compare_ghostscript(tmpdir, png_rgb8_img, png_rgb8_pdf)
@@ -5685,10 +5949,13 @@ def test_tiff_float(tmp_path_factory, tiff_float_img, engine):
def test_tiff_cmyk8(tmp_path_factory, tiff_cmyk8_img, tiff_cmyk8_pdf):
tmpdir = tmp_path_factory.mktemp("tiff_cmyk8")
compare_ghostscript(
- tmpdir, tiff_cmyk8_img, tiff_cmyk8_pdf, gsdevice="tiff32nc", exact=False
+ tmpdir,
+ tiff_cmyk8_img,
+ tiff_cmyk8_pdf,
+ gsdevice="tiff32nc",
)
# not testing with poppler as it cannot write CMYK images
- compare_mupdf(tmpdir, tiff_cmyk8_img, tiff_cmyk8_pdf, exact=False, cmyk=True)
+ compare_mupdf(tmpdir, tiff_cmyk8_img, tiff_cmyk8_pdf, cmyk=True)
compare_pdfimages_tiff(tmpdir, tiff_cmyk8_img, tiff_cmyk8_pdf)
@@ -6123,6 +6390,46 @@ def test_tiff_ccitt_nometa2(
compare_pdfimages_tiff(tmpdir, tiff_ccitt_nometa2_img, tiff_ccitt_nometa2_pdf)
+@pytest.mark.skipif(
+ sys.platform in ["win32"],
+ reason="test utilities not available on Windows and MacOS",
+)
+def test_miff_cmyk8(tmp_path_factory, miff_cmyk8_img, tiff_cmyk8_img, miff_cmyk8_pdf):
+ tmpdir = tmp_path_factory.mktemp("miff_cmyk8")
+ compare_ghostscript(tmpdir, tiff_cmyk8_img, miff_cmyk8_pdf, gsdevice="tiff32nc")
+ # not testing with poppler as it cannot write CMYK images
+ compare_mupdf(tmpdir, tiff_cmyk8_img, miff_cmyk8_pdf, cmyk=True)
+ compare_pdfimages_tiff(tmpdir, tiff_cmyk8_img, miff_cmyk8_pdf)
+
+
+@pytest.mark.skipif(
+ sys.platform in ["win32"],
+ reason="test utilities not available on Windows and MacOS",
+)
+def test_miff_cmyk16(
+ tmp_path_factory, miff_cmyk16_img, tiff_cmyk16_img, miff_cmyk16_pdf
+):
+ tmpdir = tmp_path_factory.mktemp("miff_cmyk16")
+ compare_ghostscript(
+ tmpdir, tiff_cmyk16_img, miff_cmyk16_pdf, gsdevice="tiff32nc", exact=False
+ )
+ # not testing with poppler as it cannot write CMYK images
+ compare_mupdf(tmpdir, tiff_cmyk16_img, miff_cmyk16_pdf, exact=False, cmyk=True)
+ # compare_pdfimages_tiff(tmpdir, tiff_cmyk16_img, miff_cmyk16_pdf)
+
+
+@pytest.mark.skipif(
+ sys.platform in ["win32"],
+ reason="test utilities not available on Windows and MacOS",
+)
+def test_miff_rgb8(tmp_path_factory, miff_rgb8_img, tiff_rgb8_img, miff_rgb8_pdf):
+ tmpdir = tmp_path_factory.mktemp("miff_rgb8")
+ compare_ghostscript(tmpdir, tiff_rgb8_img, miff_rgb8_pdf, gsdevice="tiff24nc")
+ compare_poppler(tmpdir, tiff_rgb8_img, miff_rgb8_pdf)
+ compare_mupdf(tmpdir, tiff_rgb8_img, miff_rgb8_pdf)
+ compare_pdfimages_tiff(tmpdir, tiff_rgb8_img, miff_rgb8_pdf)
+
+
# we define some variables so that the table below can be narrower
psl = (972, 504) # --pagesize landscape
psp = (504, 972) # --pagesize portrait
@@ -6554,6 +6861,96 @@ def general_input(request):
return request.param
+@pytest.mark.skipif(not HAVE_FAKETIME, reason="requires faketime")
+@pytest.mark.parametrize(
+ "engine,testdata,timezone,pdfa",
+ itertools.product(
+ ["internal", "pikepdf"],
+ ["2021-02-05 17:49:00"],
+ ["Europe/Berlin", "GMT+12"],
+ [True, False],
+ ),
+)
+def test_faketime(tmp_path_factory, jpg_img, engine, testdata, timezone, pdfa):
+ expected = tz2utcstrftime(testdata, "D:%Y%m%d%H%M%SZ", timezone)
+ out_pdf = tmp_path_factory.mktemp("faketime") / "out.pdf"
+ subprocess.check_call(
+ ["env", f"TZ={timezone}", "faketime", "-f", testdata, img2pdfprog]
+ + (["--pdfa"] if pdfa else [])
+ + [
+ "--producer=",
+ "--engine=" + engine,
+ "--output=" + str(out_pdf),
+ str(jpg_img),
+ ]
+ )
+ with pikepdf.open(str(out_pdf)) as p:
+ assert p.docinfo.CreationDate == expected
+ assert p.docinfo.ModDate == expected
+ if pdfa:
+ assert p.Root.Metadata.Subtype == "/XML"
+ assert p.Root.Metadata.Type == "/Metadata"
+ expected = tz2utcstrftime(testdata, "%Y-%m-%dT%H:%M:%SZ", timezone)
+ root = ET.fromstring(p.Root.Metadata.read_bytes())
+ for k in ["ModifyDate", "CreateDate"]:
+ assert (
+ root.find(
+ f".//xmp:{k}", {"xmp": "http://ns.adobe.com/xap/1.0/"}
+ ).text
+ == expected
+ )
+ out_pdf.unlink()
+
+
+@pytest.mark.parametrize(
+ "engine,testdata,timezone,pdfa",
+ itertools.product(
+ ["internal", "pikepdf"],
+ [
+ "2021-02-05 17:49:00",
+ "2021-02-05T17:49:00",
+ "Fri, 05 Feb 2021 17:49:00 +0100",
+ "last year 12:00",
+ ],
+ ["Europe/Berlin", "GMT+12"],
+ [True, False],
+ ),
+)
+def test_date(tmp_path_factory, jpg_img, engine, testdata, timezone, pdfa):
+ # we use the date utility to convert the timestamp from the local
+ # timezone into UTC with the format used by PDF
+ expected = tz2utcstrftime(testdata, "D:%Y%m%d%H%M%SZ", timezone)
+ out_pdf = tmp_path_factory.mktemp("faketime") / "out.pdf"
+ subprocess.check_call(
+ ["env", f"TZ={timezone}", img2pdfprog]
+ + (["--pdfa"] if pdfa else [])
+ + [
+ f"--moddate={testdata}",
+ f"--creationdate={testdata}",
+ "--producer=",
+ "--engine=" + engine,
+ "--output=" + str(out_pdf),
+ str(jpg_img),
+ ]
+ )
+ with pikepdf.open(str(out_pdf)) as p:
+ assert p.docinfo.CreationDate == expected
+ assert p.docinfo.ModDate == expected
+ if pdfa:
+ assert p.Root.Metadata.Subtype == "/XML"
+ assert p.Root.Metadata.Type == "/Metadata"
+ expected = tz2utcstrftime(testdata, "%Y-%m-%dT%H:%M:%SZ", timezone)
+ root = ET.fromstring(p.Root.Metadata.read_bytes())
+ for k in ["ModifyDate", "CreateDate"]:
+ assert (
+ root.find(
+ f".//xmp:{k}", {"xmp": "http://ns.adobe.com/xap/1.0/"}
+ ).text
+ == expected
+ )
+ out_pdf.unlink()
+
+
@pytest.mark.parametrize("engine", ["internal", "pikepdf"])
def test_general(general_input, engine):
inputf = os.path.join(os.path.dirname(__file__), "tests", "input", general_input)