{"id":38215954,"url":"https://github.com/darkvision77/libcapt","last_synced_at":"2026-01-17T00:47:48.231Z","repository":{"id":308922111,"uuid":"1022762006","full_name":"darkvision77/libcapt","owner":"darkvision77","description":"Canon CAPT v1 protocol implementation","archived":false,"fork":false,"pushed_at":"2026-01-12T21:50:34.000Z","size":52738,"stargazers_count":1,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2026-01-13T01:56:56.576Z","etag":null,"topics":["canon","capt","driver","printer","printer-driver"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-2-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/darkvision77.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-07-19T19:11:18.000Z","updated_at":"2026-01-12T21:50:57.000Z","dependencies_parsed_at":"2025-10-16T11:44:32.015Z","dependency_job_id":null,"html_url":"https://github.com/darkvision77/libcapt","commit_stats":null,"previous_names":["darkvision77/libcapt"],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/darkvision77/libcapt","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/darkvision77%2Flibcapt","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/darkvision77%2Flibcapt/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/darkvision77%2Flibcapt/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/darkvision77%2Flibcapt/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/darkvision77","download_url":"https://codeload.github.com/darkvision77/libcapt/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/darkvision77%2Flibcapt/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28490573,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-16T23:55:29.509Z","status":"ssl_error","status_checked_at":"2026-01-16T23:55:29.108Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["canon","capt","driver","printer","printer-driver"],"created_at":"2026-01-17T00:47:48.150Z","updated_at":"2026-01-17T00:47:48.218Z","avatar_url":"https://github.com/darkvision77.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# libcapt\n[![Core tests](https://github.com/darkvision77/libcapt/actions/workflows/core-tests.yml/badge.svg)](https://github.com/darkvision77/libcapt/actions/workflows/core-tests.yml)\n[![Compression tests](https://github.com/darkvision77/libcapt/actions/workflows/compression-tests.yml/badge.svg)](https://github.com/darkvision77/libcapt/actions/workflows/compression-tests.yml)\n\nImplementation of the Canon CAPT v1 protocol and SCoA compression based on reverse engineering of the original driver.\n\n\u003e [!IMPORTANT]\n\u003e This project is currently in an EXPERIMENTAL state.\n\n**NOTE:** This is not a full-fledged driver that you can install into your system.\n    It is an implementation of the compression algorithm and protocol,\n    abstracted from any operating system or transmission channel.\n\n## Target devices\nCurrently, the target devices are printers with `CNTblModel = 0` (see Canon's driver PPD).\n\n| Model   | Cartridge     | PPM (A4) | Max Resolution | Year (approx.) |\n|---------|---------------|----------|----------------|----------------|\n| LBP800  | EP-22         | 8        | 600 dpi        | 1999-2001      |\n| LBP810  | EP-22         | 8        | 600 dpi        | 2001-2002      |\n| LBP1120 | EP-22         | 10       | 600 dpi        | 2003-2004      |\n| LBP1210 | EP-25         | 14       | 600 dpi        | ~2002          |\n| LBP3200 | EP-26/EP-27   | 18       | 600 dpi        | 2004-2006      |\n\n## Compilation\n```sh\ncmake -S. -B build\ncmake --build build\n```\n### Dependencies\n#### Compile-time\n- gcc \u003e= 11 or clang \u003e= 16 or MSVC (tested on 19.44.35217.0)\n- cmake \u003e= 3.21\n\n#### Testing\n- gtest (+gmock)\n\n##### For compression tests:\n- gdb\n- ghostscript\n- poppler-utils (`pdfseparate`, `pdfinfo`, etc.)\n- captfilter deps (`libpopt0:i386` on Debian)\n\n## Testing\n### Core tests\n```sh\ncmake -S. -B build -DLIBCAPT_BUILD_TESTS=ON\ncmake --build build\nctest --test-dir build\n```\n### Compression tests\n```sh\ncmake -S. -B build -DLIBCAPT_BUILD_TESTS=ON -DLIBCAPT_COMPRESSION_TESTS=ON\ncmake --build build\nctest --test-dir build\n```\nCompression test files are located at [`tests/Compression/data`](tests/Compression/data).\n\n## Usage\nThere are several options if you want to print on your Canon LBP printer (except for the original driver):\n- [darkvision77/captppd](https://github.com/darkvision77/captppd) — CUPS driver based on libcapt (CAPTv1 only)\n- [UoWPrint](https://printserver.ink/) — print server that supports all Canon LBP models (and other printers)\n- [mounaiban/captdriver](https://github.com/mounaiban/captdriver) — CUPS driver for the newer Canon LBP models (early alpha stage)\n\nAlso, the [`examples`](examples) folder contains an example program for printing PBM files. \\\nKeep in mind that this program does not implement all the features and is used only for printing testing.\n```sh\ncmake -S. -B build -DLIBCAPT_BUILD_EXAMPLES=ON\ncmake --build build\n./build/examples/printpbm /dev/usb/lp0 ./examples/data/example-1.pbm\n```\nTo rasterize PDF files into PBM, you can use the [`pdf2pbm.sh`](scripts/pdf2pbm.sh) script. \\\nAlso, you can find some test PBM files in the [`examples/data`](examples/data) folder.\n\n## Decoder verification\nThe correct operation of the compressor can be verified using the decoder. \\\nBut how can we ensure that the decoder itself is functioning correctly?\n\nGeneral principle:\n1. The original PBM is converted to `filtered.bin` using Canon's `captfilter`, extracting its «command sequence log».\n2. The decoder receives `filtered.bin`, decodes the raster, and writes the read commands to its command log.\n3. If the command logs of the `captfilter` and decoder are equal, then the commands were correctly recognized.\n4. The original raster is compared with the decoded one from `filtered.bin`.\n\nOf course, the original `captfilter` does not write any logs. So...\n\n### Fine-tuning Canon's `captfilter`\nThe `captfilter` is not being run directly.\nInstead, it is run under a special [gdb python script](scripts/filter/wrap.py) that is responsible for:\n1. **Command log:** the `captfilter` binary file contains some debug prints,\n    but the DebugPrint function is disabled in the release build,\n    so for each compression command there is a breakpoint that makes the corresponding entry in the log.\n2. **Resolve «Buffer shift bug»:** there is a bug in `captfilter` related to the \\*ThenRaw\\* commands that affects the final raster. \\\n    Let's say there is a buffer `rawData[256]`.\n    It can be represented as the following commands:\n    ```c\n    char* rawData;\n    CopyThenRawLong(0, rawData, 255); // writes {1, 2, 3, ..., 255}\n    rawData += 255;\n    CopyThenRaw(0, rawData, 1); // writes {256}\n    ```\n    But for some reason, there is no buffer offset, and the output is something like this:\n    ```c\n    char* rawData;\n    CopyThenRawLong(0, rawData, 255); // writes {1, 2, 3, ..., 255}\n    // Oops...\n    CopyThenRaw(0, rawData, 1); // writes {1} again...\n    ```\n    This bug can be found by compressing files with random data (see [`rand{A..F}.pbm`](tests/Compression/data)).\n3. **Zero margins**: to prevent `captfilter` from resizing the raster,\n    you need to set the margins to zero. But since the printer does not support zero margins,\n    `captfilter` does not support them either. Therefore, we have to use the magic of gdb scripts.\n\n## SAST Tools\n[PVS-Studio](https://pvs-studio.com/pvs-studio/?utm_source=website\u0026utm_medium=github\u0026utm_campaign=open_source) — static analyzer for C, C++, C#, and Java code.\n\n## License\nlibcapt is licensed under a 2-clause BSD license.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdarkvision77%2Flibcapt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdarkvision77%2Flibcapt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdarkvision77%2Flibcapt/lists"}