A simple, fast Python wrapper for Markus Kuhn's jbig-kit C library, providing functions for encoding and decoding JBIG1 image data (supported file types include .jbg, .jbig).
This library compiles the necessary C source files into a Python C extension, enabling direct, high-performance interaction without needing to have a pre-compiled .dll or .so file on your system. It is designed to be cross-platform, working on both Windows and Linux/macOS.
The primary goal of this wrapper is to convert between raw JBIG1 bytestreams and raw bitmap data, making it easy to integrate with other libraries like Pillow.
- Decode JBIG1 image data into a raw bitmap, width, and height.
- Encode a raw bitmap, width, and height into a JBIG1 bytestream.
- No external library dependencies are needed at runtime (the C code is compiled into the extension).
- Cross-platform build process for Windows, macOS, and Linux.
You will need a C compiler set up on your system.
- On Windows: You'll need the "C++ build tools" from the Visual Studio Installer.
- On Linux: You'll need
gccand the Python development headers (e.g.,sudo apt install build-essential python3-dev). - On macOS: You'll need Xcode Command Line Tools.
You can install the package directly from GitHub using pip:
pip install git+https://github.com/ReedGraff/jbigkitpy.gitThe library provides two main functions: decode and encode.
jbigkitpy.decode(jbig_data: bytes) -> tuple[bytes, int, int]jbigkitpy.encode(bitmap_data: bytes, width: int, height: int) -> bytes
Important Note on Pixel Format:
The jbig-kit library uses the PBM (Portable Bitmap) convention where a 1 bit represents black and a 0 bit represents white. However, libraries like Pillow use the opposite convention for their '1' mode images.
- When encoding data from Pillow, you must invert the bits first.
- When decoding data to be used in Pillow, you must invert the bits after decoding.
The following script (example.py) demonstrates a full round-trip conversion. It takes a standard image (e.g., a PNG), encodes it to JBIG, saves it, then decodes it back and saves the result.
You will need Pillow to run this example:
pip install Pillow# example.py
from PIL import Image, ImageOps
import jbigkitpy as jbig
def run_example():
"""
Demonstrates a full encode -> decode cycle.
"""
input_image_path = 'input.png' # Your source image (PNG, JPEG, etc.)
jbig_output_path = 'output.jbg'
final_image_path = 'decoded_output.png'
# --- 1. ENCODING ---
print(f"Encoding '{input_image_path}' to '{jbig_output_path}'...")
try:
# Open with Pillow and convert to 1-bit black and white
with Image.open(input_image_path) as img:
img_bw = img.convert('1')
width, height = img_bw.size
# Get the raw bitmap data from Pillow. Pillow uses 1 for white, 0 for black.
pillow_bitmap = img_bw.tobytes()
# Invert the bitmap data for jbig-kit, which expects 1 for black, 0 for white.
jbig_bitmap = bytes(b ^ 0xFF for b in pillow_bitmap)
# Call our C extension to encode the data
jbig_data = jbig.encode(jbig_bitmap, width, height)
# Write the resulting JBIG file
with open(jbig_output_path, 'wb') as f:
f.write(jbig_data)
print(f"Successfully encoded and saved to '{jbig_output_path}'.")
except Exception as e:
print(f"An error occurred during encoding: {e}")
return
# --- 2. DECODING ---
print(f"\nDecoding '{jbig_output_path}' to '{final_image_path}'...")
try:
# Read the JBIG file we just created
with open(jbig_output_path, 'rb') as f:
jbig_file_data = f.read()
# Call our C extension to decode the data
bitmap_data, width, height = jbig.decode(jbig_file_data)
# Load the raw bitmap into a Pillow Image object.
# Since the raw data is in the PBM format (1=black), we create the
# image and then invert it to display correctly.
img_from_raw = Image.frombytes('1', (width, height), bitmap_data)
img_final = ImageOps.invert(img_from_raw)
# Save the final decoded image
img_final.save(final_image_path)
print(f"Successfully decoded and saved to '{final_image_path}'.")
except Exception as e:
print(f"An error occurred during decoding: {e}")
if __name__ == '__main__':
# You will need to create a sample 'input.png' file for this script to work.
try:
run_example()
except FileNotFoundError:
print("\nError: 'input.png' not found.")
print("Please create a sample image named 'input.png' in this directory to run the example.")This wrapper is available under the GNU General Public License (GPLv2), the same license as the underlying jbig-kit library. See the COPYING file for more details.
This package is a wrapper around the jbig-kit C library, created and maintained by Markus Kuhn. All credit for the compression and decompression logic belongs to him.
jbig-kithomepage: http://www.cl.cam.ac.uk/~mgk25/jbigkit/