or run

tessl search
Log in

Version

Workspace
tessl
Visibility
Public
Created
Last updated

docs

index.md
tile.json

tessl/github-zxing-cpp--zxing-cpp

tessl install tessl/github-zxing-cpp--zxing-cpp@2.3.0

Open-source, multi-format linear/matrix barcode image processing library implemented in C++

c-api.mddocs/reference/

C API

ZXing-C++ provides a complete C API wrapper (ZXingC.h) that exposes all C++ functionality through C-compatible functions. This enables use from C code and simplifies FFI (Foreign Function Interface) integration with other languages.

Overview

The C API wraps all major C++ types and functions:

  • All C++ classes become opaque pointer types
  • All methods become C functions with the type as first parameter
  • Memory management is explicit with _new() and _delete() functions
  • Enums and constants are exposed directly

Header

#include "ZXing/ZXingC.h"

The C API is available when the library is built with ZXING_C_API CMake option enabled.

Opaque Types

All C++ classes are wrapped as opaque pointer types:

// Core types
typedef struct ZXing_Barcode ZXing_Barcode;
typedef struct ZXing_Barcodes ZXing_Barcodes;
typedef struct ZXing_ImageView ZXing_ImageView;
typedef struct ZXing_Image ZXing_Image;
typedef struct ZXing_ReaderOptions ZXing_ReaderOptions;

// Experimental types (requires ZXING_EXPERIMENTAL_API)
#ifdef ZXING_EXPERIMENTAL_API
typedef struct ZXing_CreatorOptions ZXing_CreatorOptions;
typedef struct ZXing_WriterOptions ZXing_WriterOptions;
#endif

// Enums are used directly (same as C++)
typedef enum ZXing_BarcodeFormat ZXing_BarcodeFormat;
typedef enum ZXing_ImageFormat ZXing_ImageFormat;
typedef enum ZXing_ContentType ZXing_ContentType;
// ... etc

Reading Barcodes

Single Barcode

// Read single barcode
ZXing_Barcode* ZXing_ReadBarcode(
    const ZXing_ImageView* iv,
    const ZXing_ReaderOptions* opts
);

Example:

#include "ZXing/ZXingC.h"

void read_barcode(const uint8_t* data, int width, int height) {
    // Create ImageView
    ZXing_ImageView* iv = ZXing_ImageView_new(
        data, width, height, ZXing_ImageFormat_Lum, 0, 0
    );

    // Create options (NULL for defaults)
    ZXing_ReaderOptions* opts = ZXing_ReaderOptions_new();
    ZXing_ReaderOptions_setFormats(opts, ZXing_BarcodeFormat_QRCode);

    // Read barcode
    ZXing_Barcode* barcode = ZXing_ReadBarcode(iv, opts);

    // Check validity
    if (ZXing_Barcode_isValid(barcode)) {
        // Get text
        char* text = ZXing_Barcode_text(barcode);
        printf("Barcode: %s\n", text);
        free(text);  // Free returned string
    } else {
        // Get error
        char* errorMsg = ZXing_Barcode_errorMsg(barcode);
        printf("Error: %s\n", errorMsg);
        free(errorMsg);
    }

    // Cleanup
    ZXing_Barcode_delete(barcode);
    ZXing_ReaderOptions_delete(opts);
    ZXing_ImageView_delete(iv);
}

Multiple Barcodes

// Read multiple barcodes
ZXing_Barcodes* ZXing_ReadBarcodes(
    const ZXing_ImageView* iv,
    const ZXing_ReaderOptions* opts
);

// Get count of barcodes
int ZXing_Barcodes_size(const ZXing_Barcodes* barcodes);

// Get barcode at index
ZXing_Barcode* ZXing_Barcodes_at(const ZXing_Barcodes* barcodes, int index);

Example:

void read_multiple(const uint8_t* data, int width, int height) {
    ZXing_ImageView* iv = ZXing_ImageView_new(
        data, width, height, ZXing_ImageFormat_Lum, 0, 0
    );

    ZXing_ReaderOptions* opts = ZXing_ReaderOptions_new();

    // Read all barcodes
    ZXing_Barcodes* barcodes = ZXing_ReadBarcodes(iv, opts);

    // Iterate results
    int count = ZXing_Barcodes_size(barcodes);
    printf("Found %d barcodes\n", count);

    for (int i = 0; i < count; i++) {
        ZXing_Barcode* bc = ZXing_Barcodes_at(barcodes, i);

        if (ZXing_Barcode_isValid(bc)) {
            char* text = ZXing_Barcode_text(bc);
            printf("%d: %s\n", i + 1, text);
            free(text);
        }
    }

    // Cleanup
    ZXing_Barcodes_delete(barcodes);
    ZXing_ReaderOptions_delete(opts);
    ZXing_ImageView_delete(iv);
}

ImageView

Creating ImageView

// Create ImageView
ZXing_ImageView* ZXing_ImageView_new(
    const uint8_t* data,
    int width,
    int height,
    ZXing_ImageFormat format,
    int rowStride,
    int pixStride
);

// Create ImageView with size checking
ZXing_ImageView* ZXing_ImageView_new_checked(
    const uint8_t* data,
    int size,
    int width,
    int height,
    ZXing_ImageFormat format,
    int rowStride,
    int pixStride
);

// Delete ImageView
void ZXing_ImageView_delete(ZXing_ImageView* iv);

Example:

// Grayscale image
ZXing_ImageView* iv = ZXing_ImageView_new(
    data, width, height,
    ZXing_ImageFormat_Lum,
    0,  // Auto-calculate row stride
    0   // Auto-calculate pixel stride
);

// RGB image
ZXing_ImageView* iv_rgb = ZXing_ImageView_new(
    rgb_data, width, height,
    ZXing_ImageFormat_RGB,
    0, 0
);

ZXing_ImageView_delete(iv);
ZXing_ImageView_delete(iv_rgb);

ReaderOptions

Creating and Configuring

// Create options
ZXing_ReaderOptions* ZXing_ReaderOptions_new(void);

// Delete options
void ZXing_ReaderOptions_delete(ZXing_ReaderOptions* opts);

// Setters
void ZXing_ReaderOptions_setFormats(ZXing_ReaderOptions* opts,
                                     ZXing_BarcodeFormats formats);
void ZXing_ReaderOptions_setTryHarder(ZXing_ReaderOptions* opts, bool tryHarder);
void ZXing_ReaderOptions_setTryRotate(ZXing_ReaderOptions* opts, bool tryRotate);
void ZXing_ReaderOptions_setTryInvert(ZXing_ReaderOptions* opts, bool tryInvert);
void ZXing_ReaderOptions_setTryDownscale(ZXing_ReaderOptions* opts, bool try);
void ZXing_ReaderOptions_setBinarizer(ZXing_ReaderOptions* opts,
                                       ZXing_Binarizer binarizer);
void ZXing_ReaderOptions_setIsPure(ZXing_ReaderOptions* opts, bool isPure);
void ZXing_ReaderOptions_setMaxNumberOfSymbols(ZXing_ReaderOptions* opts,
                                                uint8_t n);
void ZXing_ReaderOptions_setTextMode(ZXing_ReaderOptions* opts,
                                      ZXing_TextMode mode);

// Getters
ZXing_BarcodeFormats ZXing_ReaderOptions_getFormats(const ZXing_ReaderOptions* opts);
bool ZXing_ReaderOptions_getTryHarder(const ZXing_ReaderOptions* opts);
// ... etc

Example:

ZXing_ReaderOptions* opts = ZXing_ReaderOptions_new();

// Configure options
ZXing_ReaderOptions_setFormats(opts,
    ZXing_BarcodeFormat_QRCode | ZXing_BarcodeFormat_DataMatrix);
ZXing_ReaderOptions_setTryHarder(opts, true);
ZXing_ReaderOptions_setTryRotate(opts, true);
ZXing_ReaderOptions_setMaxNumberOfSymbols(opts, 10);

// Use options
ZXing_Barcodes* barcodes = ZXing_ReadBarcodes(iv, opts);

// Cleanup
ZXing_ReaderOptions_delete(opts);

Barcode Results

Barcode Functions

// Delete barcode
void ZXing_Barcode_delete(ZXing_Barcode* barcode);

// Validity
bool ZXing_Barcode_isValid(const ZXing_Barcode* barcode);

// Content
char* ZXing_Barcode_text(const ZXing_Barcode* barcode);
uint8_t* ZXing_Barcode_bytes(const ZXing_Barcode* barcode, int* size);
char* ZXing_Barcode_ecLevel(const ZXing_Barcode* barcode);

// Format
ZXing_BarcodeFormat ZXing_Barcode_format(const ZXing_Barcode* barcode);

// Position (corners)
void ZXing_Barcode_position(const ZXing_Barcode* barcode,
                            ZXing_PointI* topLeft,
                            ZXing_PointI* topRight,
                            ZXing_PointI* bottomRight,
                            ZXing_PointI* bottomLeft);

// Orientation
int ZXing_Barcode_orientation(const ZXing_Barcode* barcode);

// Error
ZXing_ErrorType ZXing_Barcode_errorType(const ZXing_Barcode* barcode);
char* ZXing_Barcode_errorMsg(const ZXing_Barcode* barcode);

// Metadata
char* ZXing_Barcode_symbologyIdentifier(const ZXing_Barcode* barcode);
int ZXing_Barcode_sequenceSize(const ZXing_Barcode* barcode);
int ZXing_Barcode_sequenceIndex(const ZXing_Barcode* barcode);
bool ZXing_Barcode_isPartOfSequence(const ZXing_Barcode* barcode);

Memory Management for Strings

All string-returning functions allocate memory that must be freed:

// Get text - allocates string
char* text = ZXing_Barcode_text(barcode);
if (text) {
    printf("Text: %s\n", text);
    free(text);  // Must free!
}

// Get error message - allocates string
char* errorMsg = ZXing_Barcode_errorMsg(barcode);
if (errorMsg) {
    printf("Error: %s\n", errorMsg);
    free(errorMsg);  // Must free!
}

Position Example

ZXing_PointI tl, tr, br, bl;
ZXing_Barcode_position(barcode, &tl, &tr, &br, &bl);

printf("Corners:\n");
printf("  Top-Left:     (%d, %d)\n", tl.x, tl.y);
printf("  Top-Right:    (%d, %d)\n", tr.x, tr.y);
printf("  Bottom-Right: (%d, %d)\n", br.x, br.y);
printf("  Bottom-Left:  (%d, %d)\n", bl.x, bl.y);

Writing Barcodes (Experimental)

#ifdef ZXING_EXPERIMENTAL_API

// Create barcode from text
ZXing_Barcode* ZXing_CreateBarcodeFromText(
    const char* data,
    int size,
    const ZXing_CreatorOptions* opts
);

// Create barcode from bytes
ZXing_Barcode* ZXing_CreateBarcodeFromBytes(
    const uint8_t* data,
    int size,
    const ZXing_CreatorOptions* opts
);

// Write to SVG
char* ZXing_WriteBarcodeToSVG(
    const ZXing_Barcode* barcode,
    const ZXing_WriterOptions* opts
);

// Write to UTF-8 string
char* ZXing_WriteBarcodeToUtf8(
    const ZXing_Barcode* barcode,
    const ZXing_WriterOptions* opts
);

// Write to image
ZXing_Image* ZXing_WriteBarcodeToImage(
    const ZXing_Barcode* barcode,
    const ZXing_WriterOptions* opts
);

#endif

Example:

#ifdef ZXING_EXPERIMENTAL_API
void create_qr_code(const char* text) {
    // Create options
    ZXing_CreatorOptions* createOpts =
        ZXing_CreatorOptions_new(ZXing_BarcodeFormat_QRCode);
    ZXing_CreatorOptions_setEcLevel(createOpts, "H");

    // Create barcode
    ZXing_Barcode* barcode = ZXing_CreateBarcodeFromText(
        text, -1, createOpts
    );

    if (ZXing_Barcode_isValid(barcode)) {
        // Write to SVG
        ZXing_WriterOptions* writeOpts = ZXing_WriterOptions_new();
        ZXing_WriterOptions_setScale(writeOpts, 4);

        char* svg = ZXing_WriteBarcodeToSVG(barcode, writeOpts);

        printf("SVG:\n%s\n", svg);

        free(svg);
        ZXing_WriterOptions_delete(writeOpts);
    }

    ZXing_Barcode_delete(barcode);
    ZXing_CreatorOptions_delete(createOpts);
}
#endif

Utility Functions

// Get version
const char* ZXing_Version(void);

// Get supported formats (experimental)
#ifdef ZXING_EXPERIMENTAL_API
ZXing_BarcodeFormats ZXing_SupportedBarcodeFormats(ZXing_Operation op);
#endif

Example:

// Print version
printf("ZXing-C++ version: %s\n", ZXing_Version());

#ifdef ZXING_EXPERIMENTAL_API
// Check supported formats
ZXing_BarcodeFormats readFormats =
    ZXing_SupportedBarcodeFormats(ZXing_Operation_Read);

if (readFormats & ZXing_BarcodeFormat_QRCode) {
    printf("QR Code reading supported\n");
}
#endif

Enums and Constants

All C++ enums are available in C with the same values:

// BarcodeFormat
ZXing_BarcodeFormat_None
ZXing_BarcodeFormat_Aztec
ZXing_BarcodeFormat_Codabar
ZXing_BarcodeFormat_Code39
ZXing_BarcodeFormat_Code93
ZXing_BarcodeFormat_Code128
ZXing_BarcodeFormat_DataBar
ZXing_BarcodeFormat_DataBarExpanded
ZXing_BarcodeFormat_DataBarLimited
ZXing_BarcodeFormat_DataMatrix
ZXing_BarcodeFormat_EAN8
ZXing_BarcodeFormat_EAN13
ZXing_BarcodeFormat_ITF
ZXing_BarcodeFormat_MaxiCode
ZXing_BarcodeFormat_PDF417
ZXing_BarcodeFormat_QRCode
ZXing_BarcodeFormat_UPCA
ZXing_BarcodeFormat_UPCE
ZXing_BarcodeFormat_MicroQRCode
ZXing_BarcodeFormat_RMQRCode
ZXing_BarcodeFormat_DXFilmEdge
ZXing_BarcodeFormat_LinearCodes
ZXing_BarcodeFormat_MatrixCodes
ZXing_BarcodeFormat_Any

// ImageFormat
ZXing_ImageFormat_None
ZXing_ImageFormat_Lum
ZXing_ImageFormat_LumA
ZXing_ImageFormat_RGB
ZXing_ImageFormat_BGR
ZXing_ImageFormat_RGBA
ZXing_ImageFormat_ARGB
ZXing_ImageFormat_BGRA
ZXing_ImageFormat_ABGR

// TextMode
ZXing_TextMode_Plain
ZXing_TextMode_ECI
ZXing_TextMode_HRI
ZXing_TextMode_Hex
ZXing_TextMode_Escaped

// ErrorType
ZXing_ErrorType_None
ZXing_ErrorType_Format
ZXing_ErrorType_Checksum
ZXing_ErrorType_Unsupported

// Binarizer
ZXing_Binarizer_LocalAverage
ZXing_Binarizer_GlobalHistogram
ZXing_Binarizer_FixedThreshold
ZXing_Binarizer_BoolCast

Complete Example

#include "ZXing/ZXingC.h"
#include <stdio.h>
#include <stdlib.h>

void process_image(const uint8_t* data, int width, int height) {
    printf("Processing image: %dx%d\n", width, height);
    printf("ZXing-C++ version: %s\n", ZXing_Version());

    // Create ImageView
    ZXing_ImageView* iv = ZXing_ImageView_new(
        data, width, height,
        ZXing_ImageFormat_Lum,
        0, 0
    );

    if (!iv) {
        fprintf(stderr, "Failed to create ImageView\n");
        return;
    }

    // Create options
    ZXing_ReaderOptions* opts = ZXing_ReaderOptions_new();
    ZXing_ReaderOptions_setFormats(opts, ZXing_BarcodeFormat_Any);
    ZXing_ReaderOptions_setTryHarder(opts, true);
    ZXing_ReaderOptions_setTryRotate(opts, true);
    ZXing_ReaderOptions_setMaxNumberOfSymbols(opts, 255);

    // Read all barcodes
    ZXing_Barcodes* barcodes = ZXing_ReadBarcodes(iv, opts);

    int count = ZXing_Barcodes_size(barcodes);
    printf("Found %d barcode(s)\n", count);

    // Process each barcode
    for (int i = 0; i < count; i++) {
        ZXing_Barcode* bc = ZXing_Barcodes_at(barcodes, i);

        printf("\nBarcode %d:\n", i + 1);

        if (ZXing_Barcode_isValid(bc)) {
            // Get format
            ZXing_BarcodeFormat format = ZXing_Barcode_format(bc);
            printf("  Format: %d\n", format);

            // Get text
            char* text = ZXing_Barcode_text(bc);
            printf("  Text: %s\n", text);
            free(text);

            // Get position
            ZXing_PointI tl, tr, br, bl;
            ZXing_Barcode_position(bc, &tl, &tr, &br, &bl);
            printf("  Position: TL(%d,%d) TR(%d,%d) BR(%d,%d) BL(%d,%d)\n",
                   tl.x, tl.y, tr.x, tr.y, br.x, br.y, bl.x, bl.y);

            // Get orientation
            int orientation = ZXing_Barcode_orientation(bc);
            printf("  Orientation: %d degrees\n", orientation);

            // Check for structured append
            if (ZXing_Barcode_isPartOfSequence(bc)) {
                int index = ZXing_Barcode_sequenceIndex(bc);
                int size = ZXing_Barcode_sequenceSize(bc);
                printf("  Sequence: %d of %d\n", index + 1, size);
            }
        } else {
            // Get error
            ZXing_ErrorType errType = ZXing_Barcode_errorType(bc);
            char* errMsg = ZXing_Barcode_errorMsg(bc);
            printf("  Error (type %d): %s\n", errType, errMsg);
            free(errMsg);
        }
    }

    // Cleanup
    ZXing_Barcodes_delete(barcodes);
    ZXing_ReaderOptions_delete(opts);
    ZXing_ImageView_delete(iv);

    printf("\nDone\n");
}

int main(void) {
    // Load image data (example)
    int width = 640;
    int height = 480;
    uint8_t* data = load_image("barcode.png", &width, &height);

    if (data) {
        process_image(data, width, height);
        free(data);
    }

    return 0;
}

Building with C API

CMake

# Enable C API when building ZXing
set(ZXING_C_API ON)

add_executable(my_app main.c)
target_link_libraries(my_app ZXing::ZXing)

Compiler Flags

# Compile C code
gcc -c main.c -I/path/to/zxing/include

# Link with ZXing library
gcc -o my_app main.o -L/path/to/zxing/lib -lZXing -lstdc++

Note: You must link with C++ standard library even when using C API, as the implementation is C++.

Thread Safety

The C API has the same thread safety guarantees as the C++ API:

// These functions are thread-safe:
ZXing_ReadBarcode()
ZXing_ReadBarcodes()

// These objects should not be shared between threads without synchronization:
ZXing_ReaderOptions
ZXing_CreatorOptions
ZXing_WriterOptions

// Results (Barcode objects) can be read from multiple threads
// but should not be modified concurrently

Error Handling

C API uses return values and validity checks instead of exceptions:

// Always check validity
ZXing_Barcode* barcode = ZXing_ReadBarcode(iv, opts);

if (ZXing_Barcode_isValid(barcode)) {
    // Success - safe to use
    char* text = ZXing_Barcode_text(barcode);
    process_text(text);
    free(text);
} else {
    // Failure - check error
    char* errorMsg = ZXing_Barcode_errorMsg(barcode);
    fprintf(stderr, "Error: %s\n", errorMsg);
    free(errorMsg);
}

// Always cleanup
ZXing_Barcode_delete(barcode);

Best Practices

Always Free Returned Strings

// These functions allocate strings that must be freed:
char* text = ZXing_Barcode_text(barcode);
char* error = ZXing_Barcode_errorMsg(barcode);
char* ecLevel = ZXing_Barcode_ecLevel(barcode);
char* svg = ZXing_WriteBarcodeToSVG(barcode, opts);

// Always free after use
free(text);
free(error);
free(ecLevel);
free(svg);

Always Delete Objects

// Create
ZXing_ImageView* iv = ZXing_ImageView_new(...);
ZXing_ReaderOptions* opts = ZXing_ReaderOptions_new();
ZXing_Barcode* barcode = ZXing_ReadBarcode(...);

// Use...

// Delete
ZXing_ImageView_delete(iv);
ZXing_ReaderOptions_delete(opts);
ZXing_Barcode_delete(barcode);

Check NULL Returns

ZXing_Barcode* barcode = ZXing_ReadBarcode(iv, opts);

if (!barcode) {
    // Very rare - allocation failure or null input
    fprintf(stderr, "Failed to read barcode\n");
    return;
}

// Use barcode...

ZXing_Barcode_delete(barcode);

Use Stack Allocation for Structs

// Point structures can be on stack
ZXing_PointI topLeft, topRight, bottomRight, bottomLeft;
ZXing_Barcode_position(barcode, &topLeft, &topRight, &bottomRight, &bottomLeft);

// No need to free - automatic cleanup

Related

  • Barcode Reading - Reading concepts apply to C API
  • Barcode Results - Understanding result data
  • Images - Image format details
  • Reader Options - Configuration options