Skip to content

About

libjpeg-turbo C++23 modules for mcpp (import mcpplibs.mwrap.libjpeg_turbo;)

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

libjpeg-turbo

libjpeg-turbo's TurboJPEG API — JPEG compression, decompression and lossless transforms — through C++23 modules.

English · 简体中文 · Upstream · Releases · mcpp · Index

C++23 License mcpp-community CI

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.

Modules

  • 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

Getting started

mcpp new picture --template mcpplibs.mwrap.libjpeg_turbo@3.2.1
cd picture
mcpp run

The 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;
}

Macros and constants

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.x TJFLAG_*);
  • 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).

What is and is not wrapped

  • 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 and setjmp.
  • 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/include holds what upstream's build configures (jconfig.h, jconfigint.h, jversion.h), written out for GCC and Clang on Linux, macOS and Windows.

Verification

  • mcpp test: upstream's testorig.jpg decodes 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 what tools/surface.py derives from the header; nothing declared or defined there is left out.
  • python3 tools/test_template.py: mcpp new from an installed copy, a strict build, and a run of the generated project.
  • CI: Linux (GCC 16, LLVM 23), macOS and Windows (LLVM 23).

License

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.

About

libjpeg-turbo C++23 modules for mcpp (import mcpplibs.mwrap.libjpeg_turbo;)

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages