Zint Barcode Generator and Zint Barcode Studio User Manual

5 Using the API

On this page

5. Using the API

Zint has been written using the C language and has an API for use with C/C++ language programs. A Qt interface (see Annex B. Qt Backend QZint) is available in the "backend_qt" sub-directory, and a Tcl interface is available in the "backend_tcl" sub-directory (see Annex C. Tcl Backend Binding).

The libzint API has been designed to be very similar to that used by the GNU Barcode package. This allows easy migration from GNU Barcode to Zint. Zint, however, uses none of the same function names or option names as GNU Barcode. This allows you to use both packages in your application without conflict if you wish.

5.1 Creating and Deleting Symbols

The symbols manipulated by Zint are held in a zint_symbol structure defined in "zint.h". These symbol structures are created with the ZBarcode_Create() function and deleted using the ZBarcode_Delete() function. For example the following code creates and then deletes a symbol:

#include <zint.h>
#include <stdio.h>
int main()
{
    struct zint_symbol *symbol;
    symbol = ZBarcode_Create();
    if (symbol != NULL) {
        printf("Symbol successfully created!\n");
        ZBarcode_Delete(symbol);
    }
    return 0;
}

When compiling this code it will need to be linked with the libzint library using the -lzint option:

gcc -o simple simple.c -lzint

5.2 Encoding and Saving to File

To encode data in a barcode use the ZBarcode_Encode() function. To write the symbol to a file use the ZBarcode_Print() function. For example the following code takes a string from the command line and outputs a Code 128 symbol to a PNG file named "out.png" (or a GIF file "out.gif" if libpng is not present) in the current working directory:

#include <zint.h>
int main(int argc, char **argv)
{
    struct zint_symbol *symbol;
    symbol = ZBarcode_Create();
    ZBarcode_Encode(symbol, argv[1], 0);
    ZBarcode_Print(symbol, 0);
    ZBarcode_Delete(symbol);
    return 0;
}

This can also be done in one stage using the ZBarcode_Encode_and_Print() function as shown in the next example:

#include <zint.h>
int main(int argc, char **argv)
{
    struct zint_symbol *symbol;
    symbol = ZBarcode_Create();
    ZBarcode_Encode_and_Print(symbol, argv[1], 0, 0);
    ZBarcode_Delete(symbol);
    return 0;
}

Note that when using the API, the input data is assumed to be 8-bit binary unless the input_mode member of the zint_symbol structure is set - see 5.11 Setting the Input Mode for details.

5.3 Encoding and Printing Functions in Depth

The functions for encoding and printing barcodes are defined as:

int ZBarcode_Encode(struct zint_symbol *symbol,
      const unsigned char *source, int length);

int ZBarcode_Encode_File(struct zint_symbol *symbol,
      const char *filename);

int ZBarcode_Print(struct zint_symbol *symbol, int rotate_angle);

int ZBarcode_Encode_and_Print(struct zint_symbol *symbol,
      const unsigned char *source, int length, int rotate_angle);

int ZBarcode_Encode_File_and_Print(struct zint_symbol *symbol,
      const char *filename, int rotate_angle);

In these definitions length can be used to set the length of the input string. This allows the encoding of NUL (ASCII 0) characters in those symbologies which allow this. A value of 0 (or less than 0) will disable this usage and Zint will encode data up to the first NUL character in the input string, which must be present.

The rotate_angle value can be used to rotate the image when outputting. Valid values are 0, 90, 180 and 270.

The ZBarcode_Encode_File() and ZBarcode_Encode_File_and_Print() functions can be used to encode data read directly from a text file where the filename is given in the NUL-terminated filename string. The special filename "-" (single hyphen) can be used to read from stdin. Note that on Windows, filenames are assumed to be UTF-8 encoded.

If printing more than one barcode, the zint_symbol structure may be re-used by calling the ZBarcode_Clear() function after each barcode to free any output buffers allocated. The zint_symbol input members must be reset. To fully restore zint_symbol to its default state, call ZBarcode_Reset() instead.

5.4 Buffering Symbols in Memory (raster)

In addition to saving barcode images to file Zint allows you to access a representation of the resulting bitmap image in memory. The following functions allow you to do this:

int ZBarcode_Buffer(struct zint_symbol *symbol, int rotate_angle);

int ZBarcode_Encode_and_Buffer(struct zint_symbol *symbol,
      const unsigned char *source, int length, int rotate_angle);

int ZBarcode_Encode_File_and_Buffer(struct zint_symbol *symbol,
      const char *filename, int rotate_angle);

The arguments here are the same as above, and rotation and colour options can be used with the buffer functions in the same way as when saving to a file. The difference is that instead of saving the image to a file it is placed in a byte (unsigned char) array pointed to by the bitmap member, with bitmap_width set to the number of columns and bitmap_height set to the number of rows.

The RGB channels are split into 3 consecutive red, green, blue bytes per pixel, and there are bitmap_width pixels per row and bitmap_height rows, so the total size of the bitmap array is 3 * bitmap_width * bitmap_height.

If the background and/or foreground are RGBA then the byte array alphamap will also be set, with a single alpha value for each pixel. Its total size will be bitmap_width * bitmap_height.

The pixel data can be extracted from the array (or arrays) by the method shown in the example below, where render_rgb() and render_rgba() are assumed to be functions for drawing an RGB and RGBA pixel on the screen implemented by the client application:

int row, col, i = 0, j = 0;

for (row = 0; row < symbol->bitmap_height; row++) {
     for (col = 0; col < symbol->bitmap_width; col++) {
          int red = (int) symbol->bitmap[i];
          int green = (int) symbol->bitmap[i + 1];
          int blue = (int) symbol->bitmap[i + 2];
          if (symbol->alphamap) {
              int alpha = (int) symbol->alphamap[j];
              render_rgba(row, col, red, green, blue, alpha);
              j++;
          } else {
              render_rgb(row, col, red, green, blue);
          }
          i += 3;
     }
}

Where speed is important, the buffer can be returned instead in a more compact intermediate form using the output option OUT_BUFFER_INTERMEDIATE. Here each byte is an ASCII value: '1' for foreground colour and '0' for background colour, except for Ultracode, which also uses colour codes: 'W' for white, 'C' for cyan, 'B' for blue, 'M' for magenta, 'R' for red, 'Y' for yellow, 'G' for green, and 'K' for black. Alpha values are not reported (alphamap will always be NULL). The loop for accessing the data is then:

int row, col, i = 0;

for (row = 0; row < symbol->bitmap_height; row++) {
     for (col = 0; col < symbol->bitmap_width; col++) {
          render_pixel(row, col, symbol->bitmap[i]);
          i++;
     }
}

5.5 Buffering Symbols in Memory (vector)

Symbols can also be saved to memory in a vector representation as well as a bitmap one. The following functions, exactly analogous to the ones above, allow you to do this:

int ZBarcode_Buffer_Vector(struct zint_symbol *symbol, int rotate_angle);

int ZBarcode_Encode_and_Buffer_Vector(struct zint_symbol *symbol,
      const unsigned char *source, int length, int rotate_angle);

int ZBarcode_Encode_File_and_Buffer_Vector(struct zint_symbol *symbol,
      const char *filename, int rotate_angle);

Here the vector member is set to point to a zint_vector header structure which contains pointers to lists of structures representing the various elements of the barcode: rectangles, hexagons, strings and circles. To draw the barcode, each of the element types is iterated in turn, and using the information stored is drawn by a rendering system. For instance, to draw a barcode using a rendering system with prepare_canvas(), draw_rect(), draw_hexagon(), draw_string(), and draw_circle() routines available:

struct zint_vector_rect *rect;
struct zint_vector_hexagon *hex;
struct zint_vector_string *string;
struct zint_vector_circle *circle;

prepare_canvas(symbol->vector->width, symbol->vector->height,
               symbol->scale, symbol->fgcolour, symbol->bgcolour,
               rotate_angle);

for (rect = symbol->vector->rectangles; rect; rect = rect->next) {
    draw_rect(rect->x, rect->y, rect->width, rect->height,
              rect->colour);
}
for (hex = symbol->vector->hexagons; hex; hex = hex->next) {
    draw_hexagon(hex->x, hex->y, hex->diameter, hex->rotation);
}
for (string = symbol->vector->strings; string; string = string->next) {
    draw_string(string->x, string->y, string->fsize,
                string->rotation, string->halign,
                string->text, string->length);
}
for (circle = symbol->vector->circles; circle; circle = circle->next) {
    draw_circle(circle->x, circle->y, circle->diameter, circle->width);
}

5.6 Buffering Symbols in Memory (memfile)

Symbols can also be stored as “in-memory” file buffers by giving the BARCODE_MEMORY_FILE option to the output_options member, which saves the print output to member memfile instead of to the output file outfile. The length of the buffer is given in memfile_size. For instance:

#include <zint.h>
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv)
{
    struct zint_symbol *symbol;
    symbol = ZBarcode_Create();
    symbol->output_options |= BARCODE_MEMORY_FILE;
    /* Only the extension is used, to determine output format */
    strcpy(symbol->outfile, "mem.svg");
    ZBarcode_Encode_and_Print(symbol, argv[1], 0, 0);
    /* `symbol->memfile` now contains the SVG output */
    fwrite(symbol->memfile, 1, symbol->memfile_size, stdout);
    ZBarcode_Delete(symbol);
    return 0;
}

will print the SVG output to stdout (the file "mem.svg" is not created). This is particularly useful for the textual formats EPS and SVG,12 allowing the output to be manipulated and processed by the client.

5.7 Setting Options

So far our application is not very useful unless we plan to only make Code 128 symbols and we don’t mind that they only save to "out.png" (or to memory, as above). As with the CLI program, of course, these options can be altered. The way this is done is by altering the contents of the zint_symbol structure between the creation and encoding stages. The zint_symbol structure consists of the following members:

Table 13: API Structure zint_symbol
Member NameTypeMeaningDefault Value
symbologyintegerSymbol to use - see 5.9 Specifying a Symbology.BARCODE_CODE128
heightfloatSymbol height in X-dimensions, excluding fixed width-to-height symbols.13Symbol dependent
scalefloatScale factor for adjusting size of image (sets X-dimension).1.0
whitespace_widthintegerHorizontal whitespace width in X-dimensions.0
whitespace_heightintegerVertical whitespace height in X-dimensions.0
border_widthintegerBorder width in X-dimensions.0
output_optionsintegerSet various output parameters - see 5.10 Adjusting Output Options.0 (none)
fgcolourcharacter stringForeground (ink) colour as RGB/RGBA hexadecimal string or "C,M,Y,K" decimal percentages string, with a terminating NUL."000000"
bgcolourcharacter stringBackground (paper) colour as RGB/RGBA hexadecimal string or "C,M,Y,K" decimal percentages string, with a terminating NUL."ffffff"
fgcolorpointerPoints to fgcolour allowing alternate spelling.
bgcolorpointerPoints to bgcolour allowing alternate spelling.
outfilecharacter stringContains the name of the file to output a resulting barcode symbol to. Must end in .png, .gif, .bmp, .emf, .eps, .pcx, .svg, .tif or .txt followed by a terminating NUL.14"out.png"
primarycharacter stringPrimary message data for more complex symbols, with a terminating NUL."" (empty)
option_1integerSymbol specific options.-1
option_2integerSymbol specific options.0
option_3integerSymbol specific options.0
show_hrtintegerSet to 0 to hide Human Readable Text (HRT).1
input_modeintegerSet encoding of input data - see 5.11 Setting the Input Mode.DATA_MODE
eciintegerExtended Channel Interpretation code.0 (none)
dpmmfloatResolution of output in dots per mm (BMP, EMF, PCX, PNG and TIF only).0 (none)
dot_sizefloatDiameter of dots used in dotty mode (in X-dimensions).0.8
text_gapfloatGap between barcode and text (HRT) in X-dimensions.1.0
guard_descentfloatHeight of guard bar descent (EAN/UPC only) in X-dimensions.5.0
structappStructured Append structureMark a symbol as part of a sequence of symbols.count 0 (disabled)
debugintegerDebugging flags.0
warn_levelintegerAffects error/warning value returned by Zint API - see 5.8 Handling Errors.WARN_DEFAULT
textunsigned character stringHuman Readable Text, which usually consists of input data plus one more check digit. Uses UTF-8 formatting, with a terminating NUL."" (empty) (output only)
text_lengthintegerLength of text in bytes.0 (output only)
rowsintegerNumber of rows used by the symbol.(output only)
widthintegerWidth of the generated symbol.(output only)
errtxtcharacter stringError message in the event that an error occurred, with a terminating NUL - see 5.8 Handling Errors.(output only)
bitmappointer to unsigned character arrayPointer to stored bitmap image - see 5.4 Buffering Symbols in Memory (raster).(output only)
bitmap_widthintegerWidth of stored bitmap image (in pixels) - see bitmap member.(output only)
bitmap_heightintegerHeight of stored bitmap image (in pixels) - see bitmap member.(output only)
alphamappointer to unsigned character arrayPointer to array representing alpha channel of stored bitmap image (or NULL if no alpha channel used) - see bitmap member.(output only)
vectorpointer to vector structurePointer to vector header containing pointers to vector elements - see 5.5 Buffering Symbols in Memory (vector).(output only)
memfilepointer to unsigned character arrayPointer to in-memory file buffer if BARCODE_MEMORY_FILE set in output_options - see 5.6 Buffering Symbols in Memory (memfile).(output only)
memfile_sizeintegerLength of in-memory file buffer.(output only)
content_segspointer to array of segmentsPointer to array of content segments if BARCODE_CONTENT_SEGS set in output_options - see 5.16 Feedback.(output only)
content_seg_countintegerNumber of content segments.(output only)
encoded_dataarray of unsigned character arraysRepresentation of the encoded data.(output only)
row_heightarray of floatsHeights of each row.(output only)

To alter these values use the syntax shown in the example below. This code has the same result as the previous example except the output is now taller and plotted in green.

#include <zint.h>
#include <string.h>
int main(int argc, char **argv)
{
    struct zint_symbol *symbol;
    symbol = ZBarcode_Create();
    strcpy(symbol->fgcolour, "00ff00");
    symbol->height = 400.0f;
    ZBarcode_Encode_and_Print(symbol, argv[1], 0, 0);
    ZBarcode_Delete(symbol);
    return 0;
}

Note that background removal for all outputs except BMP can be achieved by setting the background alpha to "00" where the values for R, G and B will be ignored:

    strcpy(symbol->bgcolour, "55555500");

This is what the CLI option --nobackground does - see 4.7 Using Colour.

5.8 Handling Errors

If errors occur during encoding a non-zero integer value is passed back to the calling application. In addition the errtxt member is set to a message detailing the nature of the error. The errors generated by Zint are:

Table 14: API Warning and Error Return Values
Return ValueMeaning
ZINT_WARN_HRT_TRUNCATEDThe Human Readable Text returned in text was truncated (maximum 255 bytes).
ZINT_WARN_INVALID_OPTIONOne of the values in zint_struct was set incorrectly but Zint has made a guess at what it should have been and generated a barcode accordingly.
ZINT_WARN_USES_ECIZint has automatically inserted an ECI character. The symbol may not be readable with some readers.
ZINT_WARN_NONCOMPLIANTThe symbol was created but is not compliant with certain standards set in its specification (e.g. height, GS1 AI data lengths).
ZINT_ERRORMarks the divide between warnings and errors. For return values greater than or equal to this no symbol (or only an incomplete symbol) is generated.
ZINT_ERROR_TOO_LONGThe input data is too long or too short for the selected symbology. No symbol has been generated.
ZINT_ERROR_INVALID_DATAThe data to be encoded includes characters which are not permitted by the selected symbology (e.g. alphabetic characters in an EAN symbol). No symbol has been generated.
ZINT_ERROR_INVALID_CHECKData with an incorrect check digit has been entered. No symbol has been generated.
ZINT_ERROR_INVALID_OPTIONOne of the values in zint_struct was set incorrectly and Zint was unable (or unwilling) to guess what it should have been. No symbol has been generated.
ZINT_ERROR_ENCODING_PROBLEMA problem has occurred during encoding of the data. This should never happen. Please contact the developer if you encounter this error.
ZINT_ERROR_FILE_ACCESSZint was unable to open the requested output file. This is usually a file permissions problem.
ZINT_ERROR_MEMORYZint ran out of memory. This should only be a problem with legacy systems.
ZINT_ERROR_FILE_WRITEZint failed to write all contents to the requested output file. This should only occur if the output device becomes full.
ZINT_ERROR_USES_ECIReturned if warn_level set to WARN_FAIL_ALL and ZINT_WARN_USES_ECI occurs.
ZINT_ERROR_NONCOMPLIANTReturned if warn_level set to WARN_FAIL_ALL and ZINT_WARN_NONCOMPLIANT occurs.
ZINT_ERROR_HRT_TRUNCATEDReturned if warn_level set to WARN_FAIL_ALL and ZINT_WARN_HRT_TRUNCATED occurs.

To catch errors use an integer variable as shown in the code below:

#include <zint.h>
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv)
{
    struct zint_symbol *symbol;
    int error;
    symbol = ZBarcode_Create();
    /* Set invalid foreground colour */
    strcpy(symbol->fgcolour, "nonsense");
    error = ZBarcode_Encode_and_Print(symbol, argv[1], 0, 0);
    if (error != 0) {
        /* Some warning or error occurred */
        printf("%s\n", symbol->errtxt);
        if (error >= ZINT_ERROR) {
            /* Stop now */
            ZBarcode_Delete(symbol);
            return 1;
        }
    }
    /* Otherwise carry on with the rest of the application */
    ZBarcode_Delete(symbol);
    return 0;
}

This code will exit with the appropriate message:

Error 881: Malformed foreground RGB colour 'nonsense' (hexadecimal only)

To treat all warnings as errors, set symbol->warn_level to WARN_FAIL_ALL.

5.9 Specifying a Symbology

Symbologies can be specified by number or by name as listed in Table 4: Barcode Types (Symbologies). For example

symbol->symbology = BARCODE_LOGMARS;

5.10 Adjusting Output Options

The output_options member can be used to adjust various aspects of the output file. To select more than one option from the table below simply OR them together when adjusting this value:

symbol->output_options |= BARCODE_BIND | READER_INIT;
Table 15: API output_options Values
ValueEffect
0No options selected.
BARCODE_BIND_TOPBoundary bar above the symbol only.15
BARCODE_BINDBoundary bars above and below the symbol and between rows if stacking multiple symbols.16
BARCODE_BOXAdd a box surrounding the symbol and whitespace.
BARCODE_STDOUTOutput the file to stdout.
READER_INITCreate as a Reader Initialisation (Programming) symbol.
SMALL_TEXTUse a smaller font for the Human Readable Text.
BOLD_TEXTEmbolden the Human Readable Text.
CMYK_COLOURSelect the CMYK colour space option for Encapsulated PostScript and TIF files.
BARCODE_DOTTY_MODEPlot a matrix symbol using dots rather than squares.
GS1_GS_SEPARATORUse GS (Group Separator) instead of FNC1 as GS1 separator (Data Matrix only).
OUT_BUFFER_INTERMEDIATEReturn the bitmap buffer as ASCII values instead of separate colour channels - see 5.4 Buffering Symbols in Memory (raster).
BARCODE_QUIET_ZONESAdd compliant quiet zones (additional to any specified whitespace).17
BARCODE_NO_QUIET_ZONESDisable quiet zones, notably those with defaults.
COMPLIANT_HEIGHTWarn if height specified not compliant, or use standard height (if any) as default.
EANUPC_GUARD_WHITESPACEAdd quiet zone indicators ("<" and/or ">") to HRT whitespace (EAN/UPC).
EMBED_VECTOR_FONTEmbed font in vector output - currently available for SVG output only.
BARCODE_MEMORY_FILEWrite output to in-memory buffer symbol->memfile instead of to outfile file.
BARCODE_CONTENT_SEGSWrite data encoded to content segment buffers symbol->contentsegs (see 5.16 Feedback).

5.11 Setting the Input Mode

The way in which the input data is encoded can be set using the input_mode member:

Table 16: API input_mode Values
ValueEffect
DATA_MODEUses full 8-bit range interpreted as binary data.
UNICODE_MODEUses UTF-8 input.
GS1_MODEEncodes GS1 data using FNC1 characters.
The above are exclusive, the following optional and OR-ed.
ESCAPE_MODEProcess input data for escape sequences.
GS1PARENS_MODEParentheses (round brackets) used in GS1 data instead of square brackets to delimit Application Identifiers (opening parentheses in the data must be escaped).
GS1NOCHECK_MODEDo not check GS1 data for validity, i.e. suppress checks for valid AIs and data lengths. Invalid characters (e.g. control characters, extended ASCII characters) are still checked for.
HEIGHTPERROW_MODEInterpret the height member as per-row rather than as overall height.
FAST_MODEUse faster if less optimal encodation or other shortcuts if available (affects AZTEC, DATAMATRIX, MICROPDF417, PDF417, QRCODE and UPNQR only).
EXTRA_ESCAPE_MODEProcess special symbology-specific escape sequences (CODE128 only).
GS1SYNTAXENGINE_MODEUse the GS1 Syntax Engine (if available) to strictly validate GS1 input.
GS1RAW_MODEProcess GS1 data literally (no AI delimiters), parsing Group Separators (GS, ASCII 29) as FNC1s.

The default mode is DATA_MODE (CLI option --binary). (Note that this differs from the default for the CLI and GUI, which is UNICODE_MODE.)

DATA_MODE, UNICODE_MODE and GS1_MODE are mutually exclusive, whereas ESCAPE_MODE, GS1PARENS_MODE, GS1NOCHECK_MODE, HEIGHTPERROW_MODE, FAST_MODE, EXTRA_ESCAPE_MODE, GS1SYNTAXENGINE_MODE and GS1RAW_MODE are optional. So, for example, you can set

symbol->input_mode = UNICODE_MODE | ESCAPE_MODE;

or

symbol->input_mode = GS1_MODE | GS1PARENS_MODE | GS1NOCHECK_MODE;

whereas

symbol->input_mode = DATA_MODE | GS1_MODE;

is not valid.

Permissible escape sequences (ESCAPE_MODE) are listed in Table 2: Escape Sequences, and the special Code 128-only EXTRA_ESCAPE_MODE escape sequences are given in 6.1.10.1 Standard Code 128 (ISO 15417).

The GS1 options GS1PARENS_MODE (CLI --gs1parens) , GS1NOCHECK_MODE (CLI --gs1nocheck), GS1SYNTAXENGINE_MODE (CLI --gs1strict) and GS1RAW_MODE (CLI --gs1raw) are described in 4.11.3 GS1 Data Entry and Options. Note that unlike the CLI options, they must be OR-ed with GS1_MODE to take effect.

For HEIGHTPERROW_MODE, see --heightperrow in section 4.4 Adjusting Height. The height member should be set to the desired per-row value on input (it will be set to the overall height on output).

FAST_MODE causes a less optimal encodation scheme to be used for Aztec Code, Data Matrix, MicroPDF417 and PDF417. For QR Code and UPNQR, it limits Zint’s automatic mask selection - see 6.6.3 QR Code (ISO 18004) for details.

5.12 Multiple Segments

For input data requiring multiple ECIs, the following functions may be used:

int ZBarcode_Encode_Segs(struct zint_symbol *symbol,
      const struct zint_seg segs[], const int seg_count);

int ZBarcode_Encode_Segs_and_Print(struct zint_symbol *symbol,
      const struct zint_seg segs[], const int seg_count, int rotate_angle);

int ZBarcode_Encode_Segs_and_Buffer(struct zint_symbol *symbol,
      const struct zint_seg segs[], const int seg_count, int rotate_angle);

int ZBarcode_Encode_Segs_and_Buffer_Vector(struct zint_symbol *symbol,
      const struct zint_seg segs[], const int seg_count, int rotate_angle);

These are direct analogues of the previously mentioned ZBarcode_Encode(), ZBarcode_Encode_and_Print(), ZBarcode_Encode_and_Buffer() and ZBarcode_Encode_and_Buffer_Vector() respectively, where instead of a pair consisting of "source, length", a pair consisting of "segs, seg_count" is given, with segs being an array of struct zint_seg segments and seg_count being the number of elements it contains. The zint_seg structure is of the form:

struct zint_seg {
    unsigned char *source; /* Data to encode */
    int length;            /* Length of `source`. If 0 or negative, `source`
                              must be NUL-terminated */
    int eci;               /* Extended Channel Interpretation */
};

The symbology must support ECIs (see Table 7: ECI-Aware Symbologies). For example:

#include <zint.h>
int main(int argc, char **argv)
{
    struct zint_seg segs[] = {
        { "Κείμενο", 0, 9 },
        { "Текст", 0, 7 },
        { "文章", 0, 20 }
    };
    struct zint_symbol *symbol;
    symbol = ZBarcode_Create();
    symbol->symbology = BARCODE_AZTEC;
    symbol->input_mode = UNICODE_MODE;
    ZBarcode_Encode_Segs(symbol, segs, 3);
    ZBarcode_Print(symbol, 0);
    ZBarcode_Delete(symbol);
    return 0;
}

A maximum of 256 segments may be specified. Use of multiple segments with GS1 data is not currently supported.

5.13 Scaling Helpers

To help with scaling the output, the following three function are available:

float ZBarcode_Default_Xdim(int symbol_id);

float ZBarcode_Scale_From_XdimDp(int symbol_id, float x_dim_mm, float dpmm,
        const char *filetype);

float ZBarcode_XdimDP_From_Scale(int symbol_id, float scale,
        float x_dim_mm_or_dpmm, const char *filetype);

The first ZBarcode_Default_Xdim() returns the default X-dimension suggested by Zint for symbology symbol_id.

The second ZBarcode_Scale_From_XdimDp() returns the scale to use to output to a file of type filetype with X-dimension x_dim_mm at dpmm dots per mm. The given X-dimension must be non-zero and less than or equal to 10mm, however dpmm may be zero and defaults to 12 dpmm, and filetype may be NULL or empty in which case a GIF filetype is assumed. For raster output (BMP/GIF/PCX/PNG/TIF) the scale is rounded to half-integer increments.

For example:

/* Royal Mail 4-State Customer Code */
symbol->symbology = BARCODE_RM4SCC;
symbol->dpmm = 600.0f / 25.4f; /* 600 dpi */
symbol->scale = ZBarcode_Scale_From_XdimDp(
                        symbol->symbology,
                        ZBarcode_Default_Xdim(symbol->symbology),
                        symbol->dpmm, "PNG"); /* Returns 7.5 */

The third function ZBarcode_XdimDP_From_Scale() is the “reverse” of ZBarcode_Scale_From_XdimDp(), returning the X-dimension (in mm) or the dot density (in dpmm) given a scale scale. Both scale and x_dim_mm_or_dpmm must be non-zero. The returned value is bound to the maximum value of dpmm (1000), so must be further bound to 10 on return if the X-dimension is sought.

Note that the X-dimension to use is application dependent, and varies not only due to the symbology, resolution and filetype but also due to the type of scanner used, the intended scanning distance, and what media (“substrates”) the barcode appears on.

5.14 Verifying Symbology Availability

An additional function available in the API is:

int ZBarcode_ValidID(int symbol_id);

which allows you to check whether a given symbology is available, returning a non-zero value if so. For example:

if (ZBarcode_ValidID(BARCODE_PDF417) != 0) {
    printf("PDF417 available\n");
} else {
    printf("PDF417 not available\n");
}

Another function that may be useful is:

int ZBarcode_BarcodeName(int symbol_id, char name[32]);

which copies the name of a symbology into the supplied name buffer, which should be 32 characters in length. The name is NUL-terminated, and zero is returned on success. For instance:

char name[32];
if (ZBarcode_BarcodeName(BARCODE_PDF417, name) == 0) {
    printf("%s\n", name);
}

will print “BARCODE_PDF417”.

5.15 Checking Symbology Capabilities

It can be useful for frontend programs to know the capabilities of a symbology. This can be determined using another additional function:

unsigned int ZBarcode_Cap(int symbol_id, unsigned int cap_flag);

by OR-ing the flags below in the cap_flag argument and checking the return to see which are set.

Table 17: API Capability Flags
ValueMeaning
ZINT_CAP_HRTCan the symbology print Human Readable Text?
ZINT_CAP_STACKABLEIs the symbology stackable? Note that stacked symbologies are not stackable.
ZINT_CAP_EANUPC18Is the symbology EAN/UPC?
ZINT_CAP_COMPOSITEDoes the symbology support composite data? (see 6.3 GS1 Composite Symbols (ISO 24723) below)
ZINT_CAP_ECIDoes the symbology support Extended Channel Interpretations?
ZINT_CAP_GS1Does the symbology support GS1 data?
ZINT_CAP_DOTTYCan the symbology be outputted as dots?
ZINT_CAP_QUIET_ZONESDoes the symbology have default quiet zones? Note that default quiet zones may be zero.
ZINT_CAP_FIXED_RATIODoes the symbology have a fixed width-to-height (aspect) ratio?
ZINT_CAP_READER_INITDoes the symbology support Reader Initialisation?
ZINT_CAP_FULL_MULTIBYTEIs the ZINT_FULL_MULTIBYTE option applicable?
ZINT_CAP_MASKIs mask selection applicable?
ZINT_CAP_STRUCTAPPDoes the symbology support Structured Append?
ZINT_CAP_COMPLIANT_HEIGHTDoes the symbology have a compliant height defined?
ZINT_CAP_BINDABLEDoes the symbology have row separators that can be set? Includes stacked symbologies and stackable linear symbologies.

For example:

unsigned int cap;
cap = ZBarcode_Cap(BARCODE_PDF417, ZINT_CAP_HRT | ZINT_CAP_ECI);
if (cap & ZINT_CAP_HRT) {
    printf("PDF417 supports HRT\n");
} else {
    printf("PDF417 does not support HRT\n");
}
if (cap & ZINT_CAP_ECI) {
    printf("PDF417 supports ECI\n");
} else {
    printf("PDF417 does not support ECI\n");
}

5.16 Feedback

On successful encodation (after using ZBarcode_Encode() etc.) the option_1, option_2 and option_3 members will be set to the values used by Zint to create the barcode. This is useful for feedback if the values were left as defaults or were overridden by Zint.

In particular for symbologies that have masks,19 option_3 will contain the mask used as (N + 1) << 8, N being the mask. Also Aztec Code will return the actual ECC percentage used in option_1 as P << 8, where P is the integer percentage, the low byte containing the values given in Table 40: Aztec Code Error Correction Modes (with the addition of 0 meaning less than 5% + 3 codewords and -1 meaning minimum 3 codewords). Micro PDF417 also will return the ECC percentage in option_1 as P << 8.

Detailed feedback on the data encoded may be requested by specifying the BARCODE_CONTENT_SEGS option in the output_options member, which will populate the content_segs member with an array of zint_seg structures (see 5.12 Multiple Segments for the format), one for each segment specified, the size of the array being set in content_seg_count - which will always be at least one.

The source, length and eci members of zint_seg will be set accordingly - the unconverted data in source, the data length in length, and the character set the data was converted to in eci. Any check characters encoded will be included,20 and for GS1 data any FNC1 separators will be represented as GS (ASCII 29) characters. UPC-A and UPC-E data will be expanded to EAN-13, as will EAN-8 but only if it has an add-on (otherwise it will remain at 8 digits), and any add-ons will follow the 13 digits directly (no separator). GS1 Composite data if any will be separated from the primary data (including any EAN/UPC add-ons) by a pipe (|) character.

The source member is not NUL-terminated, and is not converted: if input_mode is DATA_MODE, it remains in binary; otherwise it will be in UTF-8. The UTF-8 source may be converted to the character set of the corresponding eci member using the two helper functions discussed next.

5.17 UTF-8 to ECI convenience functions

As a convenience the conversion done by Zint from UTF-8 to ECIs is exposed in two helper functions (compatible with the libzueci21 functions zueci_utf8_to_eci() and zueci_dest_len_eci()):

int ZBarcode_UTF8_To_ECI(int eci, const unsigned char *source, int length,
      unsigned char dest[], int *p_dest_length);

int ZBarcode_Dest_Len_ECI(int eci, const unsigned char *source, int length,
      int *p_dest_length);

Call ZBarcode_Dest_Len_ECI() to get the size of buffer sufficient to accommodate the conversion, then call ZBarcode_UTF8_To_ECI() with an appropriately sized buffer to do the conversion. The final destination length, returned in p_dest_length, may be smaller than the estimate given by ZBarcode_Dest_Len_ECI(). If length is zero or less, source must be NUL-terminated. The destination buffer is not NUL-terminated. The obsolete ECIs 0, 1 and 2 are supported.

5.18 Zint Version

Whether the Zint library was built without PNG support may be determined with:

int ZBarcode_NoPng(void);

which returns 1 if PNG support is not available, else zero.

Similarly, but with opposite sense, whether the Zint library was built with GS1 Syntax Engine support may be determined with:

int ZBarcode_HaveGS1SyntaxEngine(void);

which returns 1 if GS1 Syntax Engine support is available, else zero.

Lastly, the version of the Zint library linked to is returned by:

int ZBarcode_Version(void);

The version parts are separated by hundreds. For instance, version "2.9.1" is returned as "20901".

5.19 Debug Info

Debugging information can be output to stdout by setting the debug member to ZINT_DEBUG_PRINT (1). Other values are used internally by the test suite and shouldn’t be set.