{"id":17632970,"url":"https://github.com/nolmoonen/jpeggpu","last_synced_at":"2026-03-03T11:37:17.940Z","repository":{"id":248545195,"uuid":"721278786","full_name":"nolmoonen/jpeggpu","owner":"nolmoonen","description":"Low-latency CUDA JPEG decoder by parallelizing Huffman decoding","archived":false,"fork":false,"pushed_at":"2024-11-03T10:22:59.000Z","size":3233,"stargazers_count":6,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-31T00:24:04.058Z","etag":null,"topics":["cuda","huffman","jpeg"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nolmoonen.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}},"created_at":"2023-11-20T18:15:45.000Z","updated_at":"2025-02-13T10:44:15.000Z","dependencies_parsed_at":"2024-07-15T17:55:39.899Z","dependency_job_id":"09076aa7-f970-48a4-a643-0a27b783d29f","html_url":"https://github.com/nolmoonen/jpeggpu","commit_stats":null,"previous_names":["nolmoonen/jpeggpu"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nolmoonen%2Fjpeggpu","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nolmoonen%2Fjpeggpu/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nolmoonen%2Fjpeggpu/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nolmoonen%2Fjpeggpu/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nolmoonen","download_url":"https://codeload.github.com/nolmoonen/jpeggpu/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252588483,"owners_count":21772687,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["cuda","huffman","jpeg"],"created_at":"2024-10-23T01:46:40.998Z","updated_at":"2026-03-03T11:37:17.840Z","avatar_url":"https://github.com/nolmoonen.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# JPEGGPU\n\nJPEGGPU is an experimental JPEG decoder implemented in CUDA. It works by decoding many sequences of the encoded stream in parallel, and then synchronizing these decoded sequences. This process is based on the paper _Accelerating JPEG Decompression on GPUs_[\u003csup\u003e1\u003c/sup\u003e](#references).\n\n## Features and aims\n\n- Implements DCT-based baseline JPEGs, see [JPEG Support](#jpeg-support) below for more details.\n- Flexible API: no implicit synchronization between host and device in the decoding process, explicit device memory management allowing reuse, thread safety, C99 compatible, and OS independent.\n- Simple library design: JPEG application segments are not interpreted, i.e. no attempt is made to interpret color space. No attempt is made to support non-standard JPEGs (no EOF marker, table index out of bounds, etc.).\n\n## Building\n\nBuild with CMake, for example:\n\n```shell\ncmake -S . -B build\ncmake --build build\n```\n\n## Example\n\n`example/example_tool.c` is built as `jpeggpu_example`. It demonstrates basic usage of jpeggpu and outputs some information about the file.\n\n```shell\n./build/jpeggpu_example in.jpg\nmarker Start of image\nmarker Define quantization table(s)\nmarker Define restart interval\n        restart_interval: 252\nmarker Baseline DCT\n        size_x: 4032, size_y: 3024, num_components: 3\n        c_id: 1, ssx: 2, ssy: 2, qi: 0\n        c_id: 2, ssx: 1, ssy: 1, qi: 1\n        c_id: 3, ssx: 1, ssy: 1, qi: 1\n...\nmarker End of image\nintra sync of 89 blocks of 256 subsequences\nintra sync of 1 blocks of 131072 subsequences\ngpu decode done\ndecoded image at: out.png\n```\n\n## Benchmark\n\n`benchmark/benchmark.cpp` builds `jpeggpu_benchmark` that compares performance with nvJPEG, decoding a single image at a time.\n\nPossible output with AMD Ryzen 5 2600 and NVIDIA GeForce RTX 2070, on images of [jpeg-test-images](https://github.com/nolmoonen/jpeg-test-images):\n\n```shell\n         throughput (image/s) | avg latency (ms) | max latency (ms)\n006mp-cathedral.jpg\n jpeggpu               440.92               2.27               2.50\n  nvJPEG               143.89               6.95               8.30\n012mp-bus.jpg\n jpeggpu               164.36               6.08               7.34\n  nvJPEG                66.97              14.93              15.30\n026mp-temple.jpg\n jpeggpu                58.64              17.05              21.00\n  nvJPEG                15.81              63.24              64.86\n028mp-tree.jpg\n jpeggpu               133.61               7.48              10.15\n  nvJPEG                33.63              29.74              30.66\n039mp-building.jpg\n jpeggpu               129.50               7.72              10.21\n  nvJPEG                34.33              29.13              46.60\n```\n\nNote that nvJPEG uses a hybrid (CPU+GPU) decoding, so nvJPEG has a throughput advantage when decoding multiple images in parallel.\n\n## Test\n\n`test/test.cpp` builds `jpeggpu_test` that compares output against nvJPEG. Helper script `test.sh` uses ImageMagick to convert an input image to a few different JPEG variations.\n\n```shell\n./build/jpeggpu_test test.jpg --write_out # writing out is optional\ncomponent 0 MSE: 0.23201 component 1 MSE: 0.198817 component 2 MSE: 0.199355\nwriting out to \"test.jpg.nvjpeg.png\" and \"test.jpg.jpeggpu.png\"\n\n./build/test.sh test.jpg # can also optionally pass --write_out\ncreating tmp file test.jpg.1x1.jpg..\ncomponent 0 MSE: 0.202032 component 1 MSE: 0.155791 component 2 MSE: 0.155672 \ncreating tmp file test.jpg.2x1.jpg..\n...\n```\n\n## JPEG support\n\nJPEGGPU implements the full baseline process (see Table 1[\u003csup\u003e2\u003c/sup\u003e](#references)), with the extension of allowing up to four Huffman tables of each type:\n\n- DCT-based process\n- 8-bit samples within each component\n- Sequential\n- Huffman coding: 4 AC and 4 DC tables\n- 1, 2, 3, or 4 components\n- Interleaved and non-interleaved scans\n\nCompared to nvJPEG, JPEGGPU does not support progressive JPEGs but has no restrictions on chroma subsampling. One estimate suggests 30% of JPEGs used in websites are progressive and 10% of JPEG photographs are progressive[\u003csup\u003e3\u003c/sup\u003e](#references). The parallel decoding method used in JPEGGPU is fundamentally incompatible with progressive JPEGs, specifically because of the AC refinement scan.\n\n## References\n\n1. [Accelerating JPEG Decompression on GPUs](https://arxiv.org/abs/2111.09219)\n2. [T.81 - DIGITAL COMPRESSION AND CODING OF CONTINUOUS-TONE STILL IMAGES - REQUIREMENTS AND GUIDELINES (JPEG specification)](https://www.w3.org/Graphics/JPEG/itu-t81.pdf)\n3. [Progressive JPEGs in the Wild: Implications for Information Hiding and Forensics](https://informationsecurity.uibk.ac.at/pdfs/HB2023_IHMMSEC.pdf)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnolmoonen%2Fjpeggpu","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnolmoonen%2Fjpeggpu","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnolmoonen%2Fjpeggpu/lists"}