libjpeg-turbo's TurboJPEG API — JPEG compression, decompression and lossless transforms — through C++23 modules.
English · 简体中文 · Upstream · Releases · mcpp · Index
The upstream C API is unchanged: every enumeration, enumerator, structure and
function of <turbojpeg.h> is the upstream global. The library is vendored byte
for byte from the 3.2.1 release and built from the sources upstream's TurboJPEG
static library is built from, with three choices: the C code without the SIMD
extensions, libspng against the index's zlib (compat.zlib; upstream's
WITH_SYSTEM_ZLIB) instead of the in-tree copy, and floating-point contraction
off. The default path is whole numbers throughout, so a file decodes to the
same pixels, and a picture compresses to the same bytes, on every platform.
import mcpplibs.mwrap.libjpeg_turbo;: the TurboJPEG 3 API (tj3Init,tj3Set/tj3Get,tj3DecompressHeader,tj3Decompress8/12/16,tj3Compress8/12/16, the YUV functions,tj3Transform,tj3LoadImage8/12/16,tj3SaveImage8/12/16) and the 2.x functions upstream still declares: 7 enumerations, 68 enumerators, 4 types, 80 functions
More Modules API -> upstream's README and the comments of turbojpeg.h
mcpp new picture --template mcpplibs.mwrap.libjpeg_turbo@3.2.1
cd picture
mcpp runThe default template compresses a small picture in memory, reads its size and
sampling back, and decodes it to RGB; mcpp run -- <file.jpg> reads a JPEG of
your own.
[dependencies]
mcpplibs.mwrap.libjpeg_turbo = "3.2.1"import std;
import mcpplibs.mwrap.libjpeg_turbo;
namespace jpeg = mcpplibs::mwrap::libjpeg_turbo;
std::vector<unsigned char> rgb_of(std::span<const unsigned char> file, int& width, int& height) {
std::vector<unsigned char> pixels;
tjhandle decoder = jpeg::tj3Init(TJINIT_DECOMPRESS);
if (tj3DecompressHeader(decoder, file.data(), file.size()) == 0) {
width = tj3Get(decoder, TJPARAM_JPEGWIDTH);
height = tj3Get(decoder, TJPARAM_JPEGHEIGHT);
pixels.resize(static_cast<std::size_t>(width) * height * jpeg::tjPixelSize[TJPF_RGB]);
if (tj3Decompress8(decoder, file.data(), file.size(), pixels.data(), 0, TJPF_RGB) != 0) pixels.clear();
}
tj3Destroy(decoder);
return pixels;
}A module cannot export a macro, nor a constant the header defines static.
Each is adapted under its own name in mcpplibs::mwrap::libjpeg_turbo, with the
header's value (55 in all, written by tools/surface.py from the header):
- the constant macros as
inline constexpr int(TJ_NUMPF,TJ_NUMSAMP,TJXOPT_*,TURBOJPEG_VERSION_NUMBER, the 2.xTJFLAG_*); - the tables and values (
tjPixelSize,tjRedOffset,tjGreenOffset,tjBlueOffset,tjAlphaOffset,tjMCUWidth,tjMCUHeight,TJUNSCALED,TJUNCROPPED); - the macros that take arguments as functions:
tj3Init(initType),TJSCALED(dimension, scalingFactor),TJPAD(width).
- Wrapped: every name of
<turbojpeg.h>(159 exported, 55 adapted). - The libjpeg API (
<jpeglib.h>,jpeg_*) is built and linked — TurboJPEG is written on it — and its headers are on the include path, but it is not exported as a module: it is used through macros andsetjmp. - A translation unit that also includes
<turbojpeg.h>sees the same entities (tests/header_mix_test.cpp). - Not here: the SIMD extensions (x86 assembly needs NASM; the C code gives the same pixels on the default path, more slowly), the command-line programs (
cjpeg,djpeg,jpegtran,tjbench), the Java bindings, upstream's test suite. port/includeholds what upstream's build configures (jconfig.h,jconfigint.h,jversion.h), written out for GCC and Clang on Linux, macOS and Windows.
mcpp test: upstream'stestorig.jpgdecodes to the MD5 upstream's own regression test expects (MD5_PPM_EXAMPLE_DECOMPRESS,dea1d7bbc37e39adf628342c86096641); a picture compressed, its bytes and its decoded pixels pinned; scaled decoding into another pixel format; a quarter turn and back without decoding gives the same pixels; what is no JPEG is refused; the adapted constants against the header's.python3 tools/check_exports.py: the module is exactly whattools/surface.pyderives from the header; nothing declared or defined there is left out.python3 tools/test_template.py:mcpp newfrom an installed copy, a strict build, and a run of the generated project.- CI: Linux (GCC 16, LLVM 23), macOS and Windows (LLVM 23).
The wrapper is Apache-2.0 (mcpp-community). libjpeg-turbo is under the IJG
License and the Modified (3-clause) BSD License (zlib License for parts); this
software is based in part on the work of the Independent JPEG Group. libspng is
BSD 2-Clause. Their README and license files are kept in
upstream/libjpeg-turbo/ and deployed with a program's licenses. Provenance:
upstream/documents.json.