diff --git a/pypdf/filters.py b/pypdf/filters.py index a95b96a54..4d01b7552 100644 --- a/pypdf/filters.py +++ b/pypdf/filters.py @@ -38,6 +38,7 @@ import struct import zlib from base64 import a85decode +from dataclasses import dataclass from io import BytesIO from typing import Any, Dict, List, Optional, Tuple, Union, cast @@ -477,17 +478,17 @@ def decode( return data +@dataclass class CCITParameters: """§7.4.6, optional parameters for the CCITTFaxDecode filter.""" - def __init__(self, K: int = 0, columns: int = 0, rows: int = 0) -> None: - self.K = K - self.EndOfBlock = None - self.EndOfLine = None - self.EncodedByteAlign = None - self.columns = columns # width - self.rows = rows # height - self.DamagedRowsBeforeError = None + K: int = 0 + columns: int = 0 + rows: int = 0 + EndOfBlock: Union[int, None] = None + EndOfLine: Union[int, None] = None + EncodedByteAlign: Union[int, None] = None + DamagedRowsBeforeError: Union[int, None] = None @property def group(self) -> int: @@ -513,7 +514,7 @@ class CCITTFaxDecode: @staticmethod def _get_parameters( parameters: Union[None, ArrayObject, DictionaryObject, IndirectObject], - rows: int, + rows: Union[int, IndirectObject], ) -> CCITParameters: # §7.4.6, optional parameters for the CCITTFaxDecode filter k = 0 @@ -525,16 +526,16 @@ def _get_parameters( if isinstance(parameters_unwrapped, ArrayObject): for decode_parm in parameters_unwrapped: if CCITT.COLUMNS in decode_parm: - columns = decode_parm[CCITT.COLUMNS] + columns = decode_parm[CCITT.COLUMNS].get_object() if CCITT.K in decode_parm: - k = decode_parm[CCITT.K] + k = decode_parm[CCITT.K].get_object() else: if CCITT.COLUMNS in parameters_unwrapped: - columns = parameters_unwrapped[CCITT.COLUMNS] # type: ignore + columns = parameters_unwrapped[CCITT.COLUMNS].get_object() # type: ignore if CCITT.K in parameters_unwrapped: - k = parameters_unwrapped[CCITT.K] # type: ignore + k = parameters_unwrapped[CCITT.K].get_object() # type: ignore - return CCITParameters(k, columns, rows) + return CCITParameters(K=k, columns=columns, rows=int(rows)) @staticmethod def decode( diff --git a/pypdf/generic/_base.py b/pypdf/generic/_base.py index ebc2d5763..e2695b8d1 100644 --- a/pypdf/generic/_base.py +++ b/pypdf/generic/_base.py @@ -396,6 +396,10 @@ def __float__(self) -> str: # in this case we are looking for the pointed data return self.get_object().__float__() # type: ignore + def __int__(self) -> int: + # in this case we are looking for the pointed data + return self.get_object().__int__() # type: ignore + def __str__(self) -> str: # in this case we are looking for the pointed data return self.get_object().__str__() diff --git a/tests/test_filters.py b/tests/test_filters.py index 90a119844..91674814f 100644 --- a/tests/test_filters.py +++ b/tests/test_filters.py @@ -18,7 +18,7 @@ CCITTFaxDecode, FlateDecode, ) -from pypdf.generic import ArrayObject, DictionaryObject, NameObject, NumberObject +from pypdf.generic import ArrayObject, DictionaryObject, IndirectObject, NameObject, NumberObject from . import PILContext, get_data_from_url from .test_encryption import HAS_AES @@ -196,7 +196,7 @@ def test_ccitparameters(): ("parameters", "expected_k"), [ (None, 0), - (ArrayObject([{"/K": 1}, {"/Columns": 13}]), 1), + (ArrayObject([{"/K": NumberObject(1)}, {"/Columns": NumberObject(13)}]), 1), ], ) def test_ccitt_get_parameters(parameters, expected_k): @@ -204,6 +204,17 @@ def test_ccitt_get_parameters(parameters, expected_k): assert parameters.K == expected_k # noqa: SIM300 +def test_ccitt_get_parameters__indirect_object(): + class Pdf: + def get_object(self, reference) -> NumberObject: + return NumberObject(42) + + parameters = CCITTFaxDecode._get_parameters( + parameters=None, rows=IndirectObject(13, 1, Pdf()) + ) + assert parameters.rows == 42 + + def test_ccitt_fax_decode(): data = b"" parameters = DictionaryObject(