aboutsummaryrefslogtreecommitdiffstats
path: root/env/lib/python3.10/site-packages/pikepdf/jbig2.py
diff options
context:
space:
mode:
authorLibravatarLibravatar Biswakalyan Bhuyan <biswa@surgot.in> 2022-11-13 23:46:45 +0530
committerLibravatarLibravatar Biswakalyan Bhuyan <biswa@surgot.in> 2022-11-13 23:46:45 +0530
commit9468226a9e2e2ab8cdd599f1d8538e860ca86120 (patch)
tree0a77ada226d6db80639f96b438bf83e4e756edb5 /env/lib/python3.10/site-packages/pikepdf/jbig2.py
downloadidcard-9468226a9e2e2ab8cdd599f1d8538e860ca86120.tar.gz
idcard-9468226a9e2e2ab8cdd599f1d8538e860ca86120.tar.bz2
idcard-9468226a9e2e2ab8cdd599f1d8538e860ca86120.zip
id card generator
Diffstat (limited to 'env/lib/python3.10/site-packages/pikepdf/jbig2.py')
-rw-r--r--env/lib/python3.10/site-packages/pikepdf/jbig2.py108
1 files changed, 108 insertions, 0 deletions
diff --git a/env/lib/python3.10/site-packages/pikepdf/jbig2.py b/env/lib/python3.10/site-packages/pikepdf/jbig2.py
new file mode 100644
index 0000000..28c596b
--- /dev/null
+++ b/env/lib/python3.10/site-packages/pikepdf/jbig2.py
@@ -0,0 +1,108 @@
+# SPDX-FileCopyrightText: 2022 James R. Barlow
+# SPDX-License-Identifier: MPL-2.0
+
+"""Integrate JBIG2 image decoding.
+
+Requires third-party JBIG2 decoder in the form of an external program, like
+jbig2dec.
+"""
+
+from __future__ import annotations
+
+import os
+from abc import ABC, abstractmethod
+from pathlib import Path
+from subprocess import DEVNULL, PIPE, CalledProcessError, run
+from tempfile import TemporaryDirectory
+
+from packaging.version import Version
+from PIL import Image
+
+from pikepdf._exceptions import DependencyError
+
+
+def _extract_jbig2_bytes(jbig2: bytes, jbig2_globals: bytes) -> bytes:
+ with TemporaryDirectory(prefix='pikepdf-', suffix='.jbig2') as tmpdir:
+ image_path = Path(tmpdir) / "image"
+ global_path = Path(tmpdir) / "global"
+ output_path = Path(tmpdir) / "outfile"
+
+ args = [
+ "jbig2dec",
+ "--embedded",
+ "--format",
+ "png",
+ "--output",
+ os.fspath(output_path),
+ ]
+
+ # Get the raw stream, because we can't decode im_obj - that is why we are here
+ # (Strictly speaking we should remove any non-JBIG2 filters if double encoded)
+ image_path.write_bytes(jbig2)
+
+ if len(jbig2_globals) > 0:
+ global_path.write_bytes(jbig2_globals)
+ args.append(os.fspath(global_path))
+
+ args.append(os.fspath(image_path))
+
+ run(args, stdout=DEVNULL, check=True)
+ with Image.open(output_path) as im:
+ return im.tobytes()
+
+
+class JBIG2DecoderInterface(ABC):
+ """pikepdf's C++ expects this Python interface to be available for JBIG2."""
+
+ @abstractmethod
+ def check_available(self) -> None:
+ """Check if decoder is available. Throws DependencyError if not."""
+
+ @abstractmethod
+ def decode_jbig2(self, jbig2: bytes, jbig2_globals: bytes) -> bytes:
+ """Decode JBIG2 from jbig2 and globals, returning decoded bytes."""
+
+ def available(self) -> bool:
+ """Return True if decoder is available."""
+ try:
+ self.check_available()
+ except DependencyError:
+ return False
+ else:
+ return True
+
+
+class JBIG2Decoder(JBIG2DecoderInterface):
+ """JBIG2 decoder implementation."""
+
+ def check_available(self) -> None:
+ """Check if jbig2dec is installed and usable."""
+ version = self._version()
+ if version < Version('0.15'):
+ raise DependencyError("jbig2dec is too old (older than version 0.15)")
+
+ def decode_jbig2(self, jbig2: bytes, jbig2_globals: bytes) -> bytes:
+ """Decode JBIG2 from binary data, returning decode bytes."""
+ return _extract_jbig2_bytes(jbig2, jbig2_globals)
+
+ def _version(self) -> Version:
+ try:
+ proc = run(
+ ['jbig2dec', '--version'], stdout=PIPE, check=True, encoding='ascii'
+ )
+ except (CalledProcessError, FileNotFoundError) as e:
+ raise DependencyError("jbig2dec - not installed or not found") from e
+ else:
+ result = proc.stdout
+ version_str = result.replace(
+ 'jbig2dec', ''
+ ).strip() # returns "jbig2dec 0.xx"
+ return Version(version_str)
+
+
+_jbig2_decoder = JBIG2Decoder()
+
+
+def get_decoder() -> JBIG2DecoderInterface:
+ """Return an instance of a JBIG2 decoder."""
+ return _jbig2_decoder