libjpeg-turbo

Language: C

Graphics / Image Processing

libjpeg-turbo was created to provide faster JPEG encoding and decoding than the standard libjpeg library. It maintains full ABI and API compatibility with libjpeg, making it easy to replace in existing projects while gaining significant performance improvements.

libjpeg-turbo is a high-speed version of the standard JPEG image codec library, using SIMD instructions (MMX, SSE2, NEON, AltiVec) to accelerate JPEG compression and decompression.

Installation

linux: sudo apt install libjpeg-turbo8-dev
mac: brew install libjpeg-turbo
windows: Download prebuilt binaries from https://libjpeg-turbo.org/ or build from source

Usage

libjpeg-turbo provides functions to read, write, and manipulate JPEG images efficiently. It supports standard JPEG features, including color spaces, sampling factors, and progressive JPEGs. Applications often use it for image viewers, editors, and servers requiring fast JPEG processing.

Reading a JPEG image

#include <stdio.h>
#include <jpeglib.h>
int main() {
    FILE *infile = fopen("image.jpg", "rb");
    struct jpeg_decompress_struct cinfo;
    struct jpeg_error_mgr jerr;

    cinfo.err = jpeg_std_error(&jerr);
    jpeg_create_decompress(&cinfo);
    jpeg_stdio_src(&cinfo, infile);
    jpeg_read_header(&cinfo, TRUE);
    jpeg_start_decompress(&cinfo);

    int row_stride = cinfo.output_width * cinfo.output_components;
    JSAMPARRAY buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr)&cinfo, JPOOL_IMAGE, row_stride, 1);

    while (cinfo.output_scanline < cinfo.output_height) {
        jpeg_read_scanlines(&cinfo, buffer, 1);
        // Process buffer[0] here
    }

    jpeg_finish_decompress(&cinfo);
    jpeg_destroy_decompress(&cinfo);
    fclose(infile);
    return 0;
}

Reads a JPEG image from file using libjpeg-turbo and iterates over scanlines for processing.

Writing a JPEG image

#include <stdio.h>
#include <jpeglib.h>
int main() {
    FILE *outfile = fopen("output.jpg", "wb");
    struct jpeg_compress_struct cinfo;
    struct jpeg_error_mgr jerr;

    cinfo.err = jpeg_std_error(&jerr);
    jpeg_create_compress(&cinfo);
    jpeg_stdio_dest(&cinfo, outfile);

    cinfo.image_width = 100;
    cinfo.image_height = 100;
    cinfo.input_components = 3;
    cinfo.in_color_space = JCS_RGB;

    jpeg_set_defaults(&cinfo);
    jpeg_start_compress(&cinfo, TRUE);

    JSAMPROW row_pointer[1];
    unsigned char row[100*3]; // Fill row with pixel data
    while(cinfo.next_scanline < cinfo.image_height) {
        row_pointer[0] = row;
        jpeg_write_scanlines(&cinfo, row_pointer, 1);
    }

    jpeg_finish_compress(&cinfo);
    jpeg_destroy_compress(&cinfo);
    fclose(outfile);
    return 0;
}

Writes a simple 100x100 RGB JPEG image to disk using libjpeg-turbo.

Using TurboJPEG API for faster processing

#include <turbojpeg.h>
tjhandle handle = tjInitDecompress();
int width, height, jpegSubsamp;
unsigned char *jpegBuf;
tjDecompressHeader3(handle, jpegBuf, jpegSize, &width, &height, &jpegSubsamp);
unsigned char *dstBuf = malloc(width*height*3);
tjDecompress2(handle, jpegBuf, jpegSize, dstBuf, width, 0, height, TJPF_RGB, TJFLAG_FASTDCT);
tjDestroy(handle);

Demonstrates using the TurboJPEG API for extremely fast JPEG decompression with SIMD acceleration.

Compressing image with TurboJPEG

tjhandle handle = tjInitCompress();
tjCompress2(handle, srcBuf, width, 0, height, TJPF_RGB, &jpegBuf, &jpegSize, TJSAMP_420, 90, TJFLAG_FASTDCT);
tjDestroy(handle);

Compresses an RGB image buffer into JPEG format efficiently using TurboJPEG.

Error Handling

JPEG error during decompression: Ensure input JPEG data is valid and `jpeg_std_error` is set for proper error handling.
Memory allocation failure: Check available memory and properly free buffers after use.

Best Practices

Use the TurboJPEG API for performance-critical JPEG encoding/decoding.

Always free buffers and destroy handles to prevent memory leaks.

Leverage SIMD-optimized flags for faster computation.

Validate image dimensions and color formats before processing.

Use libjpeg-turbo in place of libjpeg where speed is essential.