Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
194ca699a8 | ||
|
|
175b743ffe | ||
|
|
080b73e7c0 | ||
|
|
df6079c06d | ||
|
|
45cf92f40b | ||
|
|
5b1900beec | ||
|
|
c0208f0da1 | ||
|
|
61163c2aa9 | ||
|
|
332369f1b0 | ||
|
|
7ea940a3a6 | ||
|
|
8a784d6052 | ||
|
|
5cf86a7c2e | ||
|
|
3beabf55e7 | ||
|
|
6f6448f286 |
@@ -273,7 +273,7 @@ jobs:
|
||||
path: dist
|
||||
|
||||
- name: Sign the dists with Sigstore
|
||||
uses: sigstore/gh-action-sigstore-python@v3.0.0
|
||||
uses: sigstore/gh-action-sigstore-python@v3.0.1
|
||||
with:
|
||||
inputs: |
|
||||
./dist/*.tar.gz
|
||||
|
||||
@@ -25,6 +25,16 @@ about a forthcoming release that has not been tagged yet. A release is only
|
||||
official when it's tagged and posted to PyPI.
|
||||
:::
|
||||
|
||||
## v16.10.4
|
||||
|
||||
- Corrected build errors in Python 3.13.3 and 3.13.4.
|
||||
|
||||
## v16.10.3 (not released)
|
||||
|
||||
- Blocked optimization of images with pre-blended soft masks. {issue}`1536`
|
||||
- Fixed warning from hypothesis on running tests.
|
||||
- Release incomplete due to new test failures in Python 3.13.3 and 3.13.4.
|
||||
|
||||
## v16.10.2
|
||||
|
||||
- Blacklist pikepdf 9.8.0 due to an incompatible change.
|
||||
|
||||
+2
-3
@@ -16,8 +16,8 @@ dependencies = [
|
||||
"img2pdf>=0.5",
|
||||
"packaging>=20",
|
||||
"pdfminer.six>=20220319",
|
||||
"pi-heif", # Heif image format - maintainers: if this is removed, it will NOT break
|
||||
"pikepdf>=8.10.1, != 9.8.0",
|
||||
"pi-heif", # Heif image format - maintainers: if this is removed, it will NOT break
|
||||
"pikepdf>=8.10.1,!=9.8.0",
|
||||
"Pillow>=10.0.1",
|
||||
"pluggy>=1",
|
||||
"rich>=13",
|
||||
@@ -102,7 +102,6 @@ exclude_lines = [
|
||||
|
||||
[tool.pytest.ini_options]
|
||||
minversion = "6.0"
|
||||
norecursedirs = ["lib", ".pc", ".git", "venv", "output", "cache", "resources"]
|
||||
testpaths = ["tests"]
|
||||
addopts = "-n auto"
|
||||
markers = ["slow"]
|
||||
|
||||
@@ -78,6 +78,7 @@ def run(args=None):
|
||||
|
||||
if __name__ == '__main__':
|
||||
multiprocessing.freeze_support()
|
||||
if os.name == 'posix':
|
||||
multiprocessing.set_start_method('forkserver')
|
||||
if sys.platform not in ('win32', 'darwin'):
|
||||
with suppress(RuntimeError):
|
||||
multiprocessing.set_start_method('forkserver')
|
||||
sys.exit(run())
|
||||
|
||||
@@ -126,6 +126,13 @@ def extract_image_filter(
|
||||
if Name.Decode in image:
|
||||
log.debug(f"xref {xref}: skipping image with Decode table")
|
||||
return None # Don't mess with custom Decode tables
|
||||
if image.get(Name.SMask, Dictionary()).get(Name.Matte, None) is not None:
|
||||
# https://github.com/ocrmypdf/OCRmyPDF/issues/1536
|
||||
# Do not attempt to optimize images that have a SMask with a Matte.
|
||||
# That means alpha channel pre-blending is used, and we're not prepared
|
||||
# to deal with the complexities of that.
|
||||
log.debug(f"xref {xref}: skipping image whose SMask has Matte")
|
||||
return None
|
||||
|
||||
return pim, filtdp
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ from __future__ import annotations
|
||||
import logging
|
||||
import secrets
|
||||
import subprocess
|
||||
import sys
|
||||
from decimal import Decimal
|
||||
from unittest.mock import patch
|
||||
|
||||
@@ -165,6 +166,10 @@ class TestDuplicateFilter:
|
||||
logger.addFilter(DuplicateFilter(logger))
|
||||
return logger
|
||||
|
||||
@pytest.mark.xfail(
|
||||
(3, 13, 3) <= sys.version_info[:3] <= (3, 13, 5),
|
||||
reason="https://github.com/python/cpython/pull/135858",
|
||||
)
|
||||
def test_filter_duplicate_messages(self, duplicate_filter_logger, caplog):
|
||||
log = duplicate_filter_logger
|
||||
log.error("test error message")
|
||||
@@ -194,6 +199,10 @@ class TestDuplicateFilter:
|
||||
assert caplog.records[1].msg == "another error message"
|
||||
assert caplog.records[2].msg == "yet another error message"
|
||||
|
||||
@pytest.mark.xfail(
|
||||
(3, 13, 3) <= sys.version_info[:3] <= (3, 13, 5),
|
||||
reason="https://github.com/python/cpython/pull/135858",
|
||||
)
|
||||
def test_filter_alt_messages(self, duplicate_filter_logger, caplog):
|
||||
log = duplicate_filter_logger
|
||||
log.error("test error message")
|
||||
|
||||
+32
-9
@@ -6,7 +6,7 @@ from __future__ import annotations
|
||||
from io import BytesIO
|
||||
from os import fspath
|
||||
from pathlib import Path
|
||||
from unittest.mock import MagicMock, patch
|
||||
from unittest.mock import patch
|
||||
|
||||
import img2pdf
|
||||
import pikepdf
|
||||
@@ -220,7 +220,7 @@ def test_find_formx(resources):
|
||||
|
||||
|
||||
def test_extract_image_filter_with_pdf_image():
|
||||
image = MagicMock()
|
||||
image = Dictionary()
|
||||
image.Subtype = Name.Image
|
||||
image.Length = 200
|
||||
image.Width = 10
|
||||
@@ -235,20 +235,20 @@ def test_extract_image_filter_with_pdf_image():
|
||||
|
||||
|
||||
def test_extract_image_filter_with_non_image():
|
||||
image = MagicMock()
|
||||
image = Dictionary()
|
||||
image.Subtype = Name.Form
|
||||
assert extract_image_filter(image, None) is None
|
||||
|
||||
|
||||
def test_extract_image_filter_with_small_stream_size():
|
||||
image = MagicMock()
|
||||
image = Dictionary()
|
||||
image.Subtype = Name.Image
|
||||
image.Length = 50
|
||||
assert extract_image_filter(image, None) is None
|
||||
|
||||
|
||||
def test_extract_image_filter_with_small_dimensions():
|
||||
image = MagicMock()
|
||||
image = Dictionary()
|
||||
image.Subtype = Name.Image
|
||||
image.Length = 200
|
||||
image.Width = 5
|
||||
@@ -257,7 +257,7 @@ def test_extract_image_filter_with_small_dimensions():
|
||||
|
||||
|
||||
def test_extract_image_filter_with_multiple_compression_filters():
|
||||
image = MagicMock()
|
||||
image = Dictionary()
|
||||
image.Subtype = Name.Image
|
||||
image.Length = 200
|
||||
image.Width = 10
|
||||
@@ -268,7 +268,7 @@ def test_extract_image_filter_with_multiple_compression_filters():
|
||||
|
||||
|
||||
def test_extract_image_filter_with_wide_gamut_image():
|
||||
image = MagicMock()
|
||||
image = Dictionary()
|
||||
image.Subtype = Name.Image
|
||||
image.Length = 200
|
||||
image.Width = 10
|
||||
@@ -296,7 +296,7 @@ def test_extract_image_filter_with_jpeg2000_image():
|
||||
|
||||
|
||||
def test_extract_image_filter_with_ccitt_group_3_image():
|
||||
image = MagicMock()
|
||||
image = Dictionary()
|
||||
image.Subtype = Name.Image
|
||||
image.Length = 200
|
||||
image.Width = 10
|
||||
@@ -309,7 +309,7 @@ def test_extract_image_filter_with_ccitt_group_3_image():
|
||||
|
||||
# Triggers pikepdf bug
|
||||
# def test_extract_image_filter_with_decode_table():
|
||||
# image = MagicMock()
|
||||
# image = Dictionary()
|
||||
# image.Subtype = Name.Image
|
||||
# image.Length = 200
|
||||
# image.Width = 10
|
||||
@@ -319,3 +319,26 @@ def test_extract_image_filter_with_ccitt_group_3_image():
|
||||
# image.ColorSpace = Name.DeviceGray
|
||||
# image.Decode = [42, 0]
|
||||
# assert extract_image_filter(image, None) is None
|
||||
|
||||
|
||||
def test_extract_image_filter_with_rgb_smask_matte():
|
||||
image = Dictionary()
|
||||
image.Subtype = Name.Image
|
||||
image.Length = 200
|
||||
image.Width = 10
|
||||
image.Height = 10
|
||||
image.Filter = Name.FlateDecode
|
||||
image.BitsPerComponent = 8
|
||||
image.ColorSpace = Name.DeviceRGB
|
||||
image.SMask = Dictionary(
|
||||
Type=Name.Image,
|
||||
Subtype=Name.Image,
|
||||
Length=200,
|
||||
Width=10,
|
||||
Height=10,
|
||||
Filter=Name.FlateDecode,
|
||||
BitsPerComponent=8,
|
||||
ColorSpace=Name.DeviceGray,
|
||||
Matte=Array([1, 2, 3]),
|
||||
)
|
||||
assert extract_image_filter(image, None) is None
|
||||
|
||||
Reference in New Issue
Block a user