https://github.com/darkvision77/libcapt
Canon CAPT v1 protocol implementation
https://github.com/darkvision77/libcapt
canon capt driver printer printer-driver
Last synced: about 1 month ago
JSON representation
Canon CAPT v1 protocol implementation
- Host: GitHub
- URL: https://github.com/darkvision77/libcapt
- Owner: darkvision77
- License: bsd-2-clause
- Created: 2025-07-19T19:11:18.000Z (7 months ago)
- Default Branch: master
- Last Pushed: 2026-01-12T21:50:34.000Z (about 2 months ago)
- Last Synced: 2026-01-13T01:56:56.576Z (about 2 months ago)
- Topics: canon, capt, driver, printer, printer-driver
- Language: C++
- Homepage:
- Size: 50.3 MB
- Stars: 1
- Watchers: 1
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# libcapt
[](https://github.com/darkvision77/libcapt/actions/workflows/core-tests.yml)
[](https://github.com/darkvision77/libcapt/actions/workflows/compression-tests.yml)
Implementation of the Canon CAPT v1 protocol and SCoA compression based on reverse engineering of the original driver.
> [!IMPORTANT]
> This project is currently in an EXPERIMENTAL state.
**NOTE:** This is not a full-fledged driver that you can install into your system.
It is an implementation of the compression algorithm and protocol,
abstracted from any operating system or transmission channel.
## Target devices
Currently, the target devices are printers with `CNTblModel = 0` (see Canon's driver PPD).
| Model | Cartridge | PPM (A4) | Max Resolution | Year (approx.) |
|---------|---------------|----------|----------------|----------------|
| LBP800 | EP-22 | 8 | 600 dpi | 1999-2001 |
| LBP810 | EP-22 | 8 | 600 dpi | 2001-2002 |
| LBP1120 | EP-22 | 10 | 600 dpi | 2003-2004 |
| LBP1210 | EP-25 | 14 | 600 dpi | ~2002 |
| LBP3200 | EP-26/EP-27 | 18 | 600 dpi | 2004-2006 |
## Compilation
```sh
cmake -S. -B build
cmake --build build
```
### Dependencies
#### Compile-time
- gcc >= 11 or clang >= 16 or MSVC (tested on 19.44.35217.0)
- cmake >= 3.21
#### Testing
- gtest (+gmock)
##### For compression tests:
- gdb
- ghostscript
- poppler-utils (`pdfseparate`, `pdfinfo`, etc.)
- captfilter deps (`libpopt0:i386` on Debian)
## Testing
### Core tests
```sh
cmake -S. -B build -DLIBCAPT_BUILD_TESTS=ON
cmake --build build
ctest --test-dir build
```
### Compression tests
```sh
cmake -S. -B build -DLIBCAPT_BUILD_TESTS=ON -DLIBCAPT_COMPRESSION_TESTS=ON
cmake --build build
ctest --test-dir build
```
Compression test files are located at [`tests/Compression/data`](tests/Compression/data).
## Usage
There are several options if you want to print on your Canon LBP printer (except for the original driver):
- [darkvision77/captppd](https://github.com/darkvision77/captppd) — CUPS driver based on libcapt (CAPTv1 only)
- [UoWPrint](https://printserver.ink/) — print server that supports all Canon LBP models (and other printers)
- [mounaiban/captdriver](https://github.com/mounaiban/captdriver) — CUPS driver for the newer Canon LBP models (early alpha stage)
Also, the [`examples`](examples) folder contains an example program for printing PBM files. \
Keep in mind that this program does not implement all the features and is used only for printing testing.
```sh
cmake -S. -B build -DLIBCAPT_BUILD_EXAMPLES=ON
cmake --build build
./build/examples/printpbm /dev/usb/lp0 ./examples/data/example-1.pbm
```
To rasterize PDF files into PBM, you can use the [`pdf2pbm.sh`](scripts/pdf2pbm.sh) script. \
Also, you can find some test PBM files in the [`examples/data`](examples/data) folder.
## Decoder verification
The correct operation of the compressor can be verified using the decoder. \
But how can we ensure that the decoder itself is functioning correctly?
General principle:
1. The original PBM is converted to `filtered.bin` using Canon's `captfilter`, extracting its «command sequence log».
2. The decoder receives `filtered.bin`, decodes the raster, and writes the read commands to its command log.
3. If the command logs of the `captfilter` and decoder are equal, then the commands were correctly recognized.
4. The original raster is compared with the decoded one from `filtered.bin`.
Of course, the original `captfilter` does not write any logs. So...
### Fine-tuning Canon's `captfilter`
The `captfilter` is not being run directly.
Instead, it is run under a special [gdb python script](scripts/filter/wrap.py) that is responsible for:
1. **Command log:** the `captfilter` binary file contains some debug prints,
but the DebugPrint function is disabled in the release build,
so for each compression command there is a breakpoint that makes the corresponding entry in the log.
2. **Resolve «Buffer shift bug»:** there is a bug in `captfilter` related to the \*ThenRaw\* commands that affects the final raster. \
Let's say there is a buffer `rawData[256]`.
It can be represented as the following commands:
```c
char* rawData;
CopyThenRawLong(0, rawData, 255); // writes {1, 2, 3, ..., 255}
rawData += 255;
CopyThenRaw(0, rawData, 1); // writes {256}
```
But for some reason, there is no buffer offset, and the output is something like this:
```c
char* rawData;
CopyThenRawLong(0, rawData, 255); // writes {1, 2, 3, ..., 255}
// Oops...
CopyThenRaw(0, rawData, 1); // writes {1} again...
```
This bug can be found by compressing files with random data (see [`rand{A..F}.pbm`](tests/Compression/data)).
3. **Zero margins**: to prevent `captfilter` from resizing the raster,
you need to set the margins to zero. But since the printer does not support zero margins,
`captfilter` does not support them either. Therefore, we have to use the magic of gdb scripts.
## SAST Tools
[PVS-Studio](https://pvs-studio.com/pvs-studio/?utm_source=website&utm_medium=github&utm_campaign=open_source) — static analyzer for C, C++, C#, and Java code.
## License
libcapt is licensed under a 2-clause BSD license.