CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-zxing--library

TypeScript port of ZXing multi-format 1D/2D barcode image processing library

Overview
Eval results
Files

types-and-enums.mddocs/reference/

Types and Enums

Core type definitions and enumerations used throughout @zxing/library for barcode format identification, decoder/encoder configuration, result metadata, and error handling.

Package Information

  • Package Name: @zxing/library
  • Package Type: npm
  • Language: TypeScript
  • Installation: npm install @zxing/library
  • Type Definitions: Included (no separate @types package needed)

Core Imports

import {
  // Format identification
  BarcodeFormat,
  
  // Configuration hints
  DecodeHintType,
  EncodeHintType,
  
  // Result metadata
  ResultMetadataType,
  
  // Exceptions
  Exception,
  ReaderException,
  NotFoundException,
  FormatException,
  ChecksumException,
  WriterException,
  IllegalArgumentException,
  IllegalStateException,
  ArgumentException,
  ArithmeticException,
  ReedSolomonException,
  UnsupportedOperationException,
} from "@zxing/library";

Enumerations

BarcodeFormat

Enumerates all barcode formats supported by the library. Used to specify which format to encode or to identify the format of a decoded barcode.

/**
 * Barcode format enumeration
 * Identifies specific barcode symbology types
 */
enum BarcodeFormat {
  /** Aztec 2D barcode format */
  AZTEC = 0,
  
  /** CODABAR 1D format */
  CODABAR = 1,
  
  /** Code 39 1D format */
  CODE_39 = 2,
  
  /** Code 93 1D format */
  CODE_93 = 3,
  
  /** Code 128 1D format */
  CODE_128 = 4,
  
  /** Data Matrix 2D barcode format */
  DATA_MATRIX = 5,
  
  /** EAN-8 1D format (8 digits) */
  EAN_8 = 6,
  
  /** EAN-13 1D format (13 digits) */
  EAN_13 = 7,
  
  /** ITF (Interleaved Two of Five) 1D format */
  ITF = 8,
  
  /** MaxiCode 2D barcode format (not implemented) */
  MAXICODE = 9,
  
  /** PDF417 2D format */
  PDF_417 = 10,
  
  /** QR Code 2D barcode format */
  QR_CODE = 11,
  
  /** RSS 14 (GS1 DataBar) */
  RSS_14 = 12,
  
  /** RSS EXPANDED (experimental) */
  RSS_EXPANDED = 13,
  
  /** UPC-A 1D format (12 digits) */
  UPC_A = 14,
  
  /** UPC-E 1D format (8 digits, zero-suppressed) */
  UPC_E = 15,
  
  /** UPC/EAN extension format (not a stand-alone format) */
  UPC_EAN_EXTENSION = 16,
}

Format Descriptions

1D Barcodes (Linear):

  • CODABAR: Self-checking numeric barcode

    • Characters: 0-9, -, $, :, /, ., +
    • Start/Stop: A, B, C, or D
    • Use: Libraries, blood banks, FedEx airbills
    • Variable length
  • CODE_39: Alphanumeric barcode

    • Characters: 0-9, A-Z, space, -, ., $, /, +, %
    • Start/Stop: * (asterisk)
    • Use: Automotive, defense, inventory
    • Optional check digit, extended ASCII mode available
  • CODE_93: High-density alphanumeric barcode

    • Characters: Full ASCII via shift characters
    • Automatic check digits (2)
    • Use: Logistics, postal services
    • ~25% more compact than Code 39
  • CODE_128: High-density ASCII barcode

    • Characters: Full ASCII 128-character set
    • Code sets: A (ASCII 00-95), B (ASCII 32-127), C (numeric pairs)
    • Use: Shipping, packaging, distribution, GS1-128
    • Most versatile 1D format
  • EAN_8: 8-digit product code

    • Structure: Country + Product + Check digit
    • Use: Small packages (compact version of EAN-13)
    • Global standard
  • EAN_13: 13-digit product code

    • Structure: Country + Manufacturer + Product + Check digit
    • Use: Retail products worldwide
    • Most common retail barcode globally
  • ITF: Interleaved Two of Five

    • Characters: Numeric only (0-9)
    • Interleaving: Digit pairs (bars encode first, spaces encode second)
    • Use: Distribution, warehousing, ITF-14 (GTIN-14)
    • Even length required
  • RSS_14: Reduced Space Symbology (GS1 DataBar)

    • Data: 14 digits (GTIN-14)
    • Use: Small items, fresh food, coupons
    • Omnidirectional scanning
    • More compact than UPC/EAN
  • RSS_EXPANDED: Variable-length RSS

    • Data: Up to 74 numeric or 41 alphanumeric
    • Use: Variable data (weight, price, date)
    • Status: Experimental - not production-ready
  • UPC_A: 12-digit North American product code

    • Structure: Number system + Manufacturer + Product + Check digit
    • Use: Retail products (primarily North America)
    • Equivalent to EAN-13 with leading 0
  • UPC_E: 8-digit compressed UPC code

    • Zero-suppressed version of UPC-A
    • Use: Small packages
    • Can be expanded to UPC-A
  • UPC_EAN_EXTENSION: 2 or 5 digit supplement

    • Not stand-alone - extends UPC/EAN barcodes
    • 2 digits: Issue number (periodicals)
    • 5 digits: Suggested retail price

2D Barcodes (Matrix):

  • AZTEC: 2D matrix with bulls-eye finder

    • Bulls-eye: Distinctive concentric square rings at center
    • Formats: Compact (1-4 layers, 5-ring) and Full (1-32 layers, 7-ring)
    • Capacity: Up to ~3,832 numeric digits or ~3,067 alphanumeric
    • Use: Transport tickets, identification documents
    • Error correction: 23-90% configurable
  • DATA_MATRIX: 2D matrix barcode

    • Pattern: L-shaped finder pattern (solid borders on 2 sides)
    • Shapes: Square and rectangular
    • Capacity: Up to 2,335 alphanumeric or 3,116 numeric
    • Use: Electronics manufacturing, healthcare, logistics
    • Error correction: ECC200 (Reed-Solomon)
  • MAXICODE: Fixed-size 2D with circular finder

    • Size: Always 1 inch × 1 inch (1000 dots)
    • Finder: Circular bulls-eye
    • Use: UPS package tracking
    • Status: Not implemented in this library (enum value exists but no reader/writer)
  • PDF_417: Stacked linear barcode

    • Rows: 3-90 rows of codewords
    • Capacity: Up to 1,850 text characters or 2,710 digits
    • Use: Transport, ID cards, inventory
    • Error correction: 9 levels (0-8)
    • Structured append: Multi-symbol messages
  • QR_CODE: Quick Response code

    • Pattern: 3 finder patterns in corners
    • Versions: 1-40 (21×21 to 177×177 modules)
    • Capacity: Up to 2,953 bytes or 7,089 numeric digits
    • Use: Mobile payments, marketing, product tracking
    • Error correction: L (~7%), M (~15%), Q (~25%), H (~30%)
    • Most popular 2D barcode format

Usage Examples:

import {
  BarcodeFormat,
  MultiFormatWriter,
  MultiFormatReader,
  DecodeHintType,
  BitMatrix,
  Result
} from "@zxing/library";

// Encode a QR code
const writer = new MultiFormatWriter();
const qrMatrix: BitMatrix = writer.encode(
  "Hello World",
  BarcodeFormat.QR_CODE,
  200,
  200,
  new Map()
);

// Specify multiple formats for decoding
const hints = new Map<DecodeHintType, any>();
hints.set(DecodeHintType.POSSIBLE_FORMATS, [
  BarcodeFormat.QR_CODE,
  BarcodeFormat.DATA_MATRIX,
  BarcodeFormat.AZTEC,
  BarcodeFormat.EAN_13,
  BarcodeFormat.CODE_128,
]);

const reader = new MultiFormatReader();
reader.setHints(hints);

// Check decoded format
const result: Result = reader.decode(binaryBitmap);
const format: BarcodeFormat = result.getBarcodeFormat();

console.log("Decoded format:", format);

if (format === BarcodeFormat.QR_CODE) {
  console.log("Decoded QR Code:", result.getText());
} else if (format === BarcodeFormat.EAN_13) {
  console.log("Decoded EAN-13:", result.getText());
} else if (format === BarcodeFormat.CODE_128) {
  console.log("Decoded Code 128:", result.getText());
}

// Format grouping
const formats2D = [
  BarcodeFormat.QR_CODE,
  BarcodeFormat.DATA_MATRIX,
  BarcodeFormat.AZTEC,
  BarcodeFormat.PDF_417
];

const formats1D = [
  BarcodeFormat.EAN_13,
  BarcodeFormat.EAN_8,
  BarcodeFormat.UPC_A,
  BarcodeFormat.UPC_E,
  BarcodeFormat.CODE_128,
  BarcodeFormat.CODE_39,
  BarcodeFormat.CODE_93,
  BarcodeFormat.ITF,
  BarcodeFormat.CODABAR,
  BarcodeFormat.RSS_14
];

function is2DFormat(format: BarcodeFormat): boolean {
  return formats2D.includes(format);
}

function is1DFormat(format: BarcodeFormat): boolean {
  return formats1D.includes(format);
}

console.log("QR_CODE is 2D:", is2DFormat(BarcodeFormat.QR_CODE)); // true
console.log("EAN_13 is 1D:", is1DFormat(BarcodeFormat.EAN_13)); // true

DecodeHintType

Configuration hints passed to barcode readers to optimize decoding behavior. These hints help readers decode faster or more accurately by providing context about the image or expected barcode format.

/**
 * Decode hint type enumeration
 * Used as keys in hints Map<DecodeHintType, any> passed to decode() methods
 * Allows fine-tuning of decoder behavior for specific scenarios
 */
enum DecodeHintType {
  /**
   * OTHER: any
   * Unspecified, application-specific hint
   */
  OTHER = 0,

  /**
   * PURE_BARCODE: boolean
   * Image is a pure monochrome image of a barcode (no borders, no rotation)
   * Enables faster extraction without detection phase
   * Set to true for images containing only the barcode with no surrounding content
   */
  PURE_BARCODE = 1,

  /**
   * POSSIBLE_FORMATS: BarcodeFormat[]
   * Image is known to be of one of a few possible formats
   * Limits decoder attempts to specified formats (improves performance)
   * Example: [BarcodeFormat.QR_CODE, BarcodeFormat.EAN_13]
   */
  POSSIBLE_FORMATS = 2,

  /**
   * TRY_HARDER: boolean
   * Spend more time to try to find a barcode
   * Optimize for accuracy, not speed
   * Enables: more thorough scanning, rotation attempts, extended search patterns
   */
  TRY_HARDER = 3,

  /**
   * CHARACTER_SET: string
   * Specifies what character encoding to use when decoding
   * Examples: "UTF-8", "ISO-8859-1", "Shift_JIS", "GB2312", "Windows-1252"
   * Applies where applicable (QR Code, Data Matrix, etc.)
   */
  CHARACTER_SET = 4,

  /**
   * ALLOWED_LENGTHS: Int32Array
   * Allowed lengths of encoded data -- reject anything else
   * Primarily for ITF barcodes
   * Example: new Int32Array([14, 16]) for ITF-14 and ITF-16
   */
  ALLOWED_LENGTHS = 5,

  /**
   * ASSUME_CODE_39_CHECK_DIGIT: boolean
   * Assume Code 39 codes employ a check digit
   * If true, validates and removes check digit from result
   */
  ASSUME_CODE_39_CHECK_DIGIT = 6,

  /**
   * ENABLE_CODE_39_EXTENDED_MODE: boolean
   * Enable extended mode for Code 39 codes (supports full ASCII)
   * Decodes special character pairs like "+A" as lowercase 'a'
   */
  ENABLE_CODE_39_EXTENDED_MODE = 7,

  /**
   * ASSUME_GS1: boolean
   * Assume the barcode is being processed as a GS1 barcode
   * Modifies behavior as needed (e.g., FNC1 handling for Code 128 / GS1-128)
   */
  ASSUME_GS1 = 8,

  /**
   * RETURN_CODABAR_START_END: boolean
   * Return the start and end digits in a Codabar barcode
   * If false (default), strips start/stop characters (A/B/C/D)
   * If true, includes them in result
   */
  RETURN_CODABAR_START_END = 9,

  /**
   * NEED_RESULT_POINT_CALLBACK: ResultPointCallback
   * Caller needs to be notified via callback when a possible ResultPoint is found
   * Used for tracking detection progress (finder patterns, corners, etc.)
   */
  NEED_RESULT_POINT_CALLBACK = 10,

  /**
   * ALLOWED_EAN_EXTENSIONS: Int32Array
   * Allowed extension lengths for EAN or UPC barcodes
   * Other formats will ignore this hint
   * Values: new Int32Array([2]), new Int32Array([5]), or new Int32Array([2, 5])
   * If set and no extension found, no result will be returned
   */
  ALLOWED_EAN_EXTENSIONS = 11,
}

Usage Examples:

import {
  MultiFormatReader,
  DecodeHintType,
  BarcodeFormat,
  ResultPointCallback,
  ResultPoint,
  Result,
  BinaryBitmap
} from "@zxing/library";

// Basic hints for faster decoding
const hints = new Map<DecodeHintType, any>();
hints.set(DecodeHintType.POSSIBLE_FORMATS, [
  BarcodeFormat.QR_CODE,
  BarcodeFormat.EAN_13,
]);

const reader = new MultiFormatReader();
reader.setHints(hints);
const result: Result = reader.decode(binaryBitmap);

// Pure barcode image (faster, no detection needed)
const pureHints = new Map<DecodeHintType, any>();
pureHints.set(DecodeHintType.PURE_BARCODE, true);
const pureResult: Result = reader.decode(pureBitmap, pureHints);

// Maximum accuracy mode (slower)
const accuracyHints = new Map<DecodeHintType, any>();
accuracyHints.set(DecodeHintType.TRY_HARDER, true);
accuracyHints.set(DecodeHintType.POSSIBLE_FORMATS, [BarcodeFormat.QR_CODE]);
const accurateResult: Result = reader.decode(binaryBitmap, accuracyHints);

// Character encoding specification
const encodingHints = new Map<DecodeHintType, any>();
encodingHints.set(DecodeHintType.CHARACTER_SET, "UTF-8");
const encodedResult: Result = reader.decode(binaryBitmap, encodingHints);

// Code 39 with extended mode and check digit
const code39Hints = new Map<DecodeHintType, any>();
code39Hints.set(DecodeHintType.ASSUME_CODE_39_CHECK_DIGIT, true);
code39Hints.set(DecodeHintType.ENABLE_CODE_39_EXTENDED_MODE, true);
code39Hints.set(DecodeHintType.POSSIBLE_FORMATS, [BarcodeFormat.CODE_39]);
const code39Result: Result = reader.decode(binaryBitmap, code39Hints);

// GS1 format handling (Code 128 as GS1-128)
const gs1Hints = new Map<DecodeHintType, any>();
gs1Hints.set(DecodeHintType.ASSUME_GS1, true);
gs1Hints.set(DecodeHintType.POSSIBLE_FORMATS, [BarcodeFormat.CODE_128]);
const gs1Result: Result = reader.decode(binaryBitmap, gs1Hints);

// Result point callback for tracking finder patterns
const callback: ResultPointCallback = {
  foundPossibleResultPoint: (point: ResultPoint) => {
    console.log(`Found point at (${point.getX()}, ${point.getY()})`);
    // Could draw marker on canvas or update UI
  },
};

const callbackHints = new Map<DecodeHintType, any>();
callbackHints.set(DecodeHintType.NEED_RESULT_POINT_CALLBACK, callback);
const trackedResult: Result = reader.decode(binaryBitmap, callbackHints);

// UPC/EAN with specific extension requirements
const extensionHints = new Map<DecodeHintType, any>();
extensionHints.set(DecodeHintType.ALLOWED_EAN_EXTENSIONS, new Int32Array([2, 5]));
extensionHints.set(DecodeHintType.POSSIBLE_FORMATS, [
  BarcodeFormat.EAN_13,
  BarcodeFormat.UPC_A
]);
const extendedResult: Result = reader.decode(binaryBitmap, extensionHints);

// ITF with allowed lengths (e.g., ITF-14 only)
const itfHints = new Map<DecodeHintType, any>();
itfHints.set(DecodeHintType.ALLOWED_LENGTHS, new Int32Array([14]));
itfHints.set(DecodeHintType.POSSIBLE_FORMATS, [BarcodeFormat.ITF]);
const itfResult: Result = reader.decode(binaryBitmap, itfHints);

// Codabar with start/stop characters
const codabarHints = new Map<DecodeHintType, any>();
codabarHints.set(DecodeHintType.RETURN_CODABAR_START_END, true);
codabarHints.set(DecodeHintType.POSSIBLE_FORMATS, [BarcodeFormat.CODABAR]);
const codabarResult: Result = reader.decode(binaryBitmap, codabarHints);

EncodeHintType

Configuration hints passed to barcode writers to control encoding behavior. These hints specify error correction levels, character encoding, dimensions, and format-specific options.

/**
 * Encode hint type enumeration
 * Used as keys in hints Map<EncodeHintType, any> passed to encode() methods
 * Controls encoding behavior and barcode properties
 */
enum EncodeHintType {
  /**
   * ERROR_CORRECTION: varies by format
   * Specifies degree of error correction to use
   * Type varies by format:
   *   - QR Code: ErrorCorrectionLevel (L, M, Q, H) or string ("L"|"M"|"Q"|"H")
   *   - Aztec: number (percentage 0-100, recommended 23-50)
   *   - PDF417: number (0-8, where higher = more correction)
   *   - Data Matrix: not applicable (uses ECC200 automatically)
   */
  ERROR_CORRECTION = 0,

  /**
   * CHARACTER_SET: string
   * Specifies character encoding to use where applicable
   * Examples: "UTF-8", "ISO-8859-1", "Shift_JIS", "GB2312", "Windows-1252"
   * Affects text encoding in QR Code, Data Matrix, Aztec
   */
  CHARACTER_SET = 1,

  /**
   * DATA_MATRIX_SHAPE: SymbolShapeHint
   * Specifies the matrix shape for Data Matrix
   * Values: FORCE_NONE (auto), FORCE_SQUARE, FORCE_RECTANGLE
   */
  DATA_MATRIX_SHAPE = 2,

  /**
   * DATA_MATRIX_COMPACT: boolean
   * Whether to use compact mode for Data Matrix
   * true: Use MinimalEncoder for better compression
   * false: Use HighLevelEncoder (default, faster)
   * Compact mode supports non-ISO-8859-1 characters via ECIs and GS1-FNC1
   * Mutually exclusive with FORCE_C40
   */
  DATA_MATRIX_COMPACT = 3,

  /**
   * MIN_SIZE: Dimension
   * Specifies a minimum barcode size
   * @deprecated Use width/height parameters in encode() instead
   */
  MIN_SIZE = 4,

  /**
   * MAX_SIZE: Dimension
   * Specifies a maximum barcode size
   * @deprecated No replacement - use symbol size constraints per format
   */
  MAX_SIZE = 5,

  /**
   * MARGIN: number
   * Specifies margin (quiet zone) in pixels to use when generating barcode
   * Meaning varies by format:
   *   - QR Code: margin in modules (default: 4)
   *   - Data Matrix: border width in modules
   *   - 1D barcodes: horizontal margin in modules
   */
  MARGIN = 6,

  /**
   * PDF417_COMPACT: boolean
   * Whether to use compact mode for PDF417
   * Compact mode reduces size slightly but may affect scanning reliability
   */
  PDF417_COMPACT = 7,

  /**
   * PDF417_COMPACTION: Compaction
   * Specifies what compaction mode to use for PDF417
   * Values: AUTO, TEXT, BYTE, NUMERIC
   */
  PDF417_COMPACTION = 8,

  /**
   * PDF417_DIMENSIONS: Dimensions
   * Specifies the minimum and maximum number of rows and columns for PDF417
   */
  PDF417_DIMENSIONS = 9,

  /**
   * AZTEC_LAYERS: number
   * Specifies the required number of layers for an Aztec code
   * Values:
   *   - Negative (-1, -2, -3, -4): compact Aztec with specified layers
   *   - 0: minimum layers / auto-select (default)
   *   - Positive (1, 2, ..., 32): normal Aztec with specified layers
   */
  AZTEC_LAYERS = 10,

  /**
   * QR_VERSION: number
   * Specifies the exact version of QR code to be encoded
   * Values: 1-40
   * Version N has dimensions (17 + 4*N) × (17 + 4*N) modules
   * If data doesn't fit, encoding fails
   */
  QR_VERSION = 11,

  /**
   * GS1_FORMAT: boolean
   * Whether data should be encoded to the GS1 standard
   * Adds FNC1 character for Application Identifier format
   * Supported by: Code 128 (GS1-128), Data Matrix
   */
  GS1_FORMAT = 12,

  /**
   * FORCE_C40: boolean
   * Forces C40 encoding for Data Matrix
   * C40 optimized for uppercase text and numbers
   * Mutually exclusive with DATA_MATRIX_COMPACT
   */
  FORCE_C40 = 13,
}

Usage Examples:

import {
  MultiFormatWriter,
  BarcodeFormat,
  EncodeHintType,
  QRCodeDecoderErrorCorrectionLevel,
  SymbolShapeHint,
  BitMatrix
} from "@zxing/library";

const writer = new MultiFormatWriter();

// QR Code with high error correction and UTF-8 encoding
const qrHints = new Map<EncodeHintType, any>();
qrHints.set(EncodeHintType.ERROR_CORRECTION, QRCodeDecoderErrorCorrectionLevel.H);
qrHints.set(EncodeHintType.CHARACTER_SET, "UTF-8");
qrHints.set(EncodeHintType.MARGIN, 2);

const qrMatrix: BitMatrix = writer.encode(
  "Hello 世界",
  BarcodeFormat.QR_CODE,
  200,
  200,
  qrHints
);

// QR Code with specific version
const versionHints = new Map<EncodeHintType, any>();
versionHints.set(EncodeHintType.QR_VERSION, 10); // Version 10 (57×57 modules)
versionHints.set(EncodeHintType.ERROR_CORRECTION, "M");

try {
  const versionMatrix: BitMatrix = writer.encode(
    "Data for version 10",
    BarcodeFormat.QR_CODE,
    300,
    300,
    versionHints
  );
} catch (error) {
  console.error("Data too large for version 10:", error);
}

// Data Matrix with square shape
const dmHints = new Map<EncodeHintType, any>();
dmHints.set(EncodeHintType.DATA_MATRIX_SHAPE, SymbolShapeHint.FORCE_SQUARE);
dmHints.set(EncodeHintType.CHARACTER_SET, "ISO-8859-1");

const dmMatrix: BitMatrix = writer.encode(
  "12345",
  BarcodeFormat.DATA_MATRIX,
  100,
  100,
  dmHints
);

// Data Matrix in compact mode (MinimalEncoder)
const compactHints = new Map<EncodeHintType, any>();
compactHints.set(EncodeHintType.DATA_MATRIX_COMPACT, true);

const compactMatrix: BitMatrix = writer.encode(
  "Compact encoding",
  BarcodeFormat.DATA_MATRIX,
  100,
  100,
  compactHints
);

// Data Matrix with GS1 format
const gs1Hints = new Map<EncodeHintType, any>();
gs1Hints.set(EncodeHintType.GS1_FORMAT, true);
gs1Hints.set(EncodeHintType.DATA_MATRIX_COMPACT, true);

const gs1Matrix: BitMatrix = writer.encode(
  "01034531200000111719112510ABCD1234",
  BarcodeFormat.DATA_MATRIX,
  150,
  150,
  gs1Hints
);

// Data Matrix with forced C40 encoding
const c40Hints = new Map<EncodeHintType, any>();
c40Hints.set(EncodeHintType.FORCE_C40, true);

const c40Matrix: BitMatrix = writer.encode(
  "UPPERCASE TEXT 123",
  BarcodeFormat.DATA_MATRIX,
  120,
  120,
  c40Hints
);

// Aztec with specific layer count
const aztecHints = new Map<EncodeHintType, any>();
aztecHints.set(EncodeHintType.AZTEC_LAYERS, -3); // Compact, 3 layers
aztecHints.set(EncodeHintType.ERROR_CORRECTION, 33); // 33% error correction

const aztecMatrix: BitMatrix = writer.encode(
  "Aztec compact",
  BarcodeFormat.AZTEC,
  150,
  150,
  aztecHints
);

// Code 128 with custom margin
const code128Hints = new Map<EncodeHintType, any>();
code128Hints.set(EncodeHintType.MARGIN, 20); // 20-pixel horizontal margin
code128Hints.set(EncodeHintType.CHARACTER_SET, "UTF-8");

const code128Matrix: BitMatrix = writer.encode(
  "CODE128",
  BarcodeFormat.CODE_128,
  250,
  80,
  code128Hints
);

// GS1-128 (Code 128 with GS1 format)
const gs1_128Hints = new Map<EncodeHintType, any>();
gs1_128Hints.set(EncodeHintType.GS1_FORMAT, true);

const gs1_128Matrix: BitMatrix = writer.encode(
  "01034531200000111719112510ABC",
  BarcodeFormat.CODE_128,
  300,
  100,
  gs1_128Hints
);

ResultMetadataType

Metadata types that can be attached to decode results. Provides additional information about the decoded barcode beyond the text content.

/**
 * Result metadata type enumeration
 * Used as keys in result.getResultMetadata() map
 * Provides supplementary information about decoded barcodes
 */
enum ResultMetadataType {
  /**
   * OTHER: Object
   * Unspecified, application-specific metadata
   */
  OTHER = 0,

  /**
   * ORIENTATION: number
   * Likely approximate orientation of barcode in the image
   * Given as degrees rotated clockwise from normal, upright orientation
   * Range: 0-360
   * Example: 1D barcode read top-to-bottom would have orientation 90
   */
  ORIENTATION = 1,

  /**
   * BYTE_SEGMENTS: Uint8Array[]
   * Raw bytes from the byte segments in the barcode
   * 2D barcodes can encode binary data in byte mode segments
   * List of byte arrays in order they appear
   */
  BYTE_SEGMENTS = 2,

  /**
   * ERROR_CORRECTION_LEVEL: string
   * Error correction level used, if applicable
   * Format-specific values:
   *   - QR Code: "L", "M", "Q", or "H"
   *   - Aztec: percentage as string
   *   - PDF417: "0" through "8"
   */
  ERROR_CORRECTION_LEVEL = 3,

  /**
   * ISSUE_NUMBER: number
   * Issue number for periodicals (from UPC/EAN extension)
   * Typically from 2-digit extension
   */
  ISSUE_NUMBER = 4,

  /**
   * SUGGESTED_PRICE: string
   * Suggested retail price in the barcode
   * Typically from 5-digit UPC/EAN extension
   * Format varies by country
   */
  SUGGESTED_PRICE = 5,

  /**
   * POSSIBLE_COUNTRY: string
   * Possible country of manufacture or origin
   * From EAN/UPC country prefix
   * May be multiple countries: "US/CA"
   */
  POSSIBLE_COUNTRY = 6,

  /**
   * UPC_EAN_EXTENSION: string
   * Extension text for UPC/EAN products
   * 2 or 5 digit extension value
   */
  UPC_EAN_EXTENSION = 7,

  /**
   * PDF417_EXTRA_METADATA: PDF417ResultMetadata
   * PDF417-specific metadata object
   * Contains: segment info, file transfer data, structured append details
   */
  PDF417_EXTRA_METADATA = 8,

  /**
   * STRUCTURED_APPEND_SEQUENCE: number
   * Sequence number if code is part of a structured append
   * Zero-based index of this symbol in the sequence
   */
  STRUCTURED_APPEND_SEQUENCE = 9,

  /**
   * STRUCTURED_APPEND_PARITY: number
   * Parity data if code is part of a structured append
   * Used to verify all symbols belong to same message
   */
  STRUCTURED_APPEND_PARITY = 10,
}

Usage Examples:

import {
  MultiFormatReader,
  ResultMetadataType,
  PDF417ResultMetadata,
  Result,
  BarcodeFormat
} from "@zxing/library";

const reader = new MultiFormatReader();
const result: Result = reader.decode(binaryBitmap);

// Access metadata
const metadata = result.getResultMetadata();

// Check barcode orientation
if (metadata && metadata.has(ResultMetadataType.ORIENTATION)) {
  const orientation: number = metadata.get(ResultMetadataType.ORIENTATION) as number;
  console.log(`Barcode rotated ${orientation}° clockwise`);
  
  if (orientation === 0) console.log("Normal orientation");
  else if (orientation === 90) console.log("Rotated 90° (vertical)");
  else if (orientation === 180) console.log("Upside down");
  else if (orientation === 270) console.log("Rotated 270°");
}

// Access error correction level
if (metadata && metadata.has(ResultMetadataType.ERROR_CORRECTION_LEVEL)) {
  const ecLevel: string = metadata.get(ResultMetadataType.ERROR_CORRECTION_LEVEL) as string;
  console.log(`Error correction level: ${ecLevel}`);
  
  if (result.getBarcodeFormat() === BarcodeFormat.QR_CODE) {
    console.log("QR Code EC level:", ecLevel); // "L", "M", "Q", or "H"
  }
}

// Access byte segments (binary data from barcode)
if (metadata && metadata.has(ResultMetadataType.BYTE_SEGMENTS)) {
  const byteSegments: Uint8Array[] = metadata.get(ResultMetadataType.BYTE_SEGMENTS) as Uint8Array[];
  console.log(`Found ${byteSegments.length} byte segments`);
  
  byteSegments.forEach((segment, index) => {
    console.log(`Segment ${index}: ${segment.length} bytes`);
    console.log(`  First bytes: ${Array.from(segment.slice(0, 10))}`);
  });
}

// Check for UPC/EAN extension
if (metadata && metadata.has(ResultMetadataType.UPC_EAN_EXTENSION)) {
  const extension: string = metadata.get(ResultMetadataType.UPC_EAN_EXTENSION) as string;
  console.log(`Extension: ${extension}`);
  
  if (extension.length === 2) {
    console.log("2-digit extension (issue number):", extension);
  } else if (extension.length === 5) {
    console.log("5-digit extension (price):", extension);
    
    // Parse price (US format)
    const firstDigit = extension.charAt(0);
    if (firstDigit === '0') {
      console.log(`Price: $${extension.substring(1, 3)}.${extension.substring(3)}`);
    }
  }
}

// Check for suggested retail price
if (metadata && metadata.has(ResultMetadataType.SUGGESTED_PRICE)) {
  const price: string = metadata.get(ResultMetadataType.SUGGESTED_PRICE) as string;
  console.log(`Suggested price: ${price}`);
}

// Check for country of origin
if (metadata && metadata.has(ResultMetadataType.POSSIBLE_COUNTRY)) {
  const country: string = metadata.get(ResultMetadataType.POSSIBLE_COUNTRY) as string;
  console.log(`Possible country: ${country}`);
}

// Handle structured append (multi-part barcodes)
if (metadata && metadata.has(ResultMetadataType.STRUCTURED_APPEND_SEQUENCE)) {
  const sequence: number = metadata.get(ResultMetadataType.STRUCTURED_APPEND_SEQUENCE) as number;
  const parity: number = metadata.get(ResultMetadataType.STRUCTURED_APPEND_PARITY) as number;
  
  console.log(`Part ${sequence + 1} of structured append`);
  console.log(`Parity: ${parity}`);
  
  // Collect all parts with same parity to reconstruct complete message
}

// PDF417-specific metadata
if (metadata && metadata.has(ResultMetadataType.PDF417_EXTRA_METADATA)) {
  const pdf417Meta = metadata.get(ResultMetadataType.PDF417_EXTRA_METADATA);
  
  if (pdf417Meta instanceof PDF417ResultMetadata) {
    console.log("PDF417 segment index:", pdf417Meta.getSegmentIndex());
    console.log("PDF417 segment count:", pdf417Meta.getSegmentCount());
    console.log("PDF417 file ID:", pdf417Meta.getFileId());
    console.log("PDF417 is last:", pdf417Meta.isLastSegment());
    
    const fileName = pdf417Meta.getFileName();
    if (fileName) {
      console.log("File name:", fileName);
      console.log("File size:", pdf417Meta.getFileSize(), "bytes");
    }
  }
}

// Extract issue number from periodical
if (metadata && metadata.has(ResultMetadataType.ISSUE_NUMBER)) {
  const issueNumber: number = metadata.get(ResultMetadataType.ISSUE_NUMBER) as number;
  console.log("Magazine issue:", issueNumber);
}

Exception Classes

All exception classes extend from the base Exception class and are used throughout the library to signal specific error conditions during barcode reading and writing operations.

Exception Hierarchy

/**
 * Complete exception hierarchy
 */

/**
 * Base exception class that all other exceptions extend
 */
class Exception extends CustomError {
  static readonly kind: string = "Exception";
  
  /**
   * Create exception with optional message
   * @param message - string: optional error message
   */
  constructor(message?: string);
  
  /**
   * Get the kind/type of this exception
   * @returns string: exception kind identifier
   */
  getKind(): string;
}

/**
 * Base exception for all barcode reading errors
 */
class ReaderException extends Exception {
  static readonly kind: string = "ReaderException";
}

/**
 * Thrown when no barcode is found in the provided image
 * Most common exception when scanning images without barcodes or with poor quality
 */
class NotFoundException extends ReaderException {
  static readonly kind: string = "NotFoundException";
  
  /**
   * Get singleton instance (optimization to avoid allocation)
   * @returns NotFoundException: shared instance
   */
  static getNotFoundInstance(): NotFoundException;
}

/**
 * Thrown when barcode is found but cannot be decoded due to format violations
 * Indicates the barcode structure is invalid, corrupted, or unsupported
 */
class FormatException extends ReaderException {
  static readonly kind: string = "FormatException";
  
  /**
   * Get singleton instance (optimization)
   * @returns FormatException: shared instance
   */
  static getFormatInstance(): FormatException;
}

/**
 * Thrown when barcode checksum validation fails
 * Indicates the barcode was read but contains errors that couldn't be corrected
 */
class ChecksumException extends ReaderException {
  static readonly kind: string = "ChecksumException";
  
  /**
   * Get singleton instance (optimization)
   * @returns ChecksumException: shared instance
   */
  static getChecksumInstance(): ChecksumException;
}

/**
 * Base exception for all barcode writing/encoding errors
 */
class WriterException extends Exception {
  static readonly kind: string = "WriterException";
}

/**
 * Thrown when an illegal or inappropriate argument is passed to a method
 */
class IllegalArgumentException extends Exception {
  static readonly kind: string = "IllegalArgumentException";
}

/**
 * Thrown when a method is called at an inappropriate time
 * or when an object is in an invalid state for the requested operation
 */
class IllegalStateException extends Exception {
  static readonly kind: string = "IllegalStateException";
}

/**
 * General exception for argument-related errors
 * Similar to IllegalArgumentException but more general purpose
 */
class ArgumentException extends Exception {
  static readonly kind: string = "ArgumentException";
}

/**
 * Thrown when an arithmetic operation fails or produces invalid result
 * Rare in normal usage, typically indicates mathematical computation errors
 */
class ArithmeticException extends Exception {
  static readonly kind: string = "ArithmeticException";
}

/**
 * Thrown when Reed-Solomon error correction fails
 * Indicates the barcode has too many errors to be corrected
 */
class ReedSolomonException extends Exception {
  static readonly kind: string = "ReedSolomonException";
}

/**
 * Thrown when an operation is not supported or not yet implemented
 * Indicates the requested functionality is not available
 */
class UnsupportedOperationException extends Exception {
  static readonly kind: string = "UnsupportedOperationException";
}

Complete Exception Hierarchy:

Exception (base)
├── ReaderException (reading errors)
│   ├── NotFoundException (no barcode found)
│   ├── FormatException (invalid format)
│   └── ChecksumException (checksum validation failed)
├── WriterException (encoding errors)
├── IllegalArgumentException (invalid arguments)
├── IllegalStateException (invalid state)
├── ArgumentException (general argument errors)
├── ArithmeticException (math errors)
├── ReedSolomonException (error correction failed)
└── UnsupportedOperationException (unsupported operation)

Usage Examples:

import {
  MultiFormatReader,
  MultiFormatWriter,
  BarcodeFormat,
  NotFoundException,
  FormatException,
  ChecksumException,
  ReaderException,
  WriterException,
  IllegalArgumentException,
  UnsupportedOperationException,
  ReedSolomonException,
  BinaryBitmap,
  BitMatrix
} from "@zxing/library";

// Reading error handling
function safeDecode(binaryBitmap: BinaryBitmap): string | null {
  const reader = new MultiFormatReader();

  try {
    const result = reader.decode(binaryBitmap);
    return result.getText();
  } catch (e) {
    // Handle specific exceptions from most specific to least specific
    if (e instanceof NotFoundException) {
      console.log("No barcode detected in image");
      // Image may not contain a barcode, or barcode is too damaged/small
      // Action: Check image quality, try different preprocessing
      return null;
    } else if (e instanceof ChecksumException) {
      console.log("Barcode detected but validation failed");
      // Barcode found but contains uncorrectable errors
      // Action: Retry with TRY_HARDER, improve image quality
      return null;
    } else if (e instanceof FormatException) {
      console.log("Barcode format is invalid or corrupted");
      // Barcode structure doesn't match expected format
      // Action: Check if barcode is partially obscured
      return null;
    } else if (e instanceof ReaderException) {
      console.log("General reading error:", e.message);
      // Catch-all for other reading errors
      return null;
    } else {
      // Unexpected error - re-throw
      console.error("Unexpected error:", e);
      throw e;
    }
  }
}

// Writing error handling
function safeEncode(contents: string, format: BarcodeFormat): BitMatrix | null {
  const writer = new MultiFormatWriter();

  try {
    const matrix: BitMatrix = writer.encode(
      contents,
      format,
      200,
      200,
      new Map()
    );
    return matrix;
  } catch (e) {
    if (e instanceof WriterException) {
      console.error("Encoding failed:", e.message);
      // Data may be incompatible with format or too large
      return null;
    } else if (e instanceof IllegalArgumentException) {
      console.error("Invalid parameters:", e.message);
      // Check dimensions, format, or hint values
      return null;
    } else if (e instanceof UnsupportedOperationException) {
      console.error("Format not supported for encoding:", e.message);
      // Some formats don't have writers (MaxiCode, RSS_EXPANDED)
      return null;
    } else {
      console.error("Unexpected error:", e);
      throw e;
    }
  }
}

// Advanced error handling with retry logic
async function decodeWithRetry(
  binaryBitmap: BinaryBitmap,
  maxRetries: number = 3
): Promise<string | null> {
  const reader = new MultiFormatReader();
  let lastError: Error | null = null;

  for (let attempt = 0; attempt < maxRetries; attempt++) {
    try {
      // Increase aggressiveness with each retry
      const hints = new Map<DecodeHintType, any>();
      
      if (attempt > 0) {
        hints.set(DecodeHintType.TRY_HARDER, true);
      }

      const result = reader.decode(binaryBitmap, hints);
      console.log(`Success on attempt ${attempt + 1}`);
      return result.getText();
    } catch (e) {
      lastError = e as Error;

      if (e instanceof NotFoundException) {
        // No point retrying if no barcode found
        console.error("No barcode found, aborting retries");
        return null;
      } else if (e instanceof ChecksumException || e instanceof FormatException) {
        // These might succeed with TRY_HARDER, so retry
        console.log(`Attempt ${attempt + 1} failed, retrying...`);
        continue;
      } else {
        // Unexpected error, don't retry
        throw e;
      }
    }
  }

  console.error("All retry attempts failed:", lastError);
  return null;
}

// Exception type checking
function classifyError(error: Error): string {
  if (error instanceof NotFoundException) {
    return "No barcode found";
  } else if (error instanceof ChecksumException) {
    return "Checksum validation failed";
  } else if (error instanceof FormatException) {
    return "Invalid barcode format";
  } else if (error instanceof WriterException) {
    return "Encoding failed";
  } else if (error instanceof ReedSolomonException) {
    return "Error correction failed";
  } else if (error instanceof IllegalArgumentException) {
    return "Invalid argument";
  } else if (error instanceof UnsupportedOperationException) {
    return "Operation not supported";
  } else {
    return "Unknown error";
  }
}

// Using singleton instances (optimization)
throw NotFoundException.getNotFoundInstance();
throw FormatException.getFormatInstance();
throw ChecksumException.getChecksumInstance();

Exception Handling Best Practices

import {
  MultiFormatReader,
  NotFoundException,
  FormatException,
  ChecksumException,
  ReaderException,
  DecodeHintType,
  BarcodeFormat,
  BinaryBitmap,
  Result
} from "@zxing/library";

/**
 * Production-ready decoder with comprehensive error handling
 */
function productionDecode(binaryBitmap: BinaryBitmap): {
  success: boolean;
  text?: string;
  format?: BarcodeFormat;
  error?: string;
  errorType?: string;
} {
  const reader = new MultiFormatReader();

  try {
    const result: Result = reader.decode(binaryBitmap);
    
    return {
      success: true,
      text: result.getText(),
      format: result.getBarcodeFormat()
    };
  } catch (e) {
    let errorType: string;
    let errorMessage: string;

    if (e instanceof NotFoundException) {
      errorType = "NOT_FOUND";
      errorMessage = "No barcode detected in image";
    } else if (e instanceof ChecksumException) {
      errorType = "CHECKSUM_FAILED";
      errorMessage = "Barcode checksum validation failed";
    } else if (e instanceof FormatException) {
      errorType = "INVALID_FORMAT";
      errorMessage = "Barcode format is invalid or corrupted";
    } else if (e instanceof ReaderException) {
      errorType = "READER_ERROR";
      errorMessage = "General barcode reading error";
    } else {
      errorType = "UNKNOWN";
      errorMessage = "Unexpected error occurred";
    }

    return {
      success: false,
      error: errorMessage,
      errorType
    };
  }
}

// Usage
const decodeResult = productionDecode(bitmap);

if (decodeResult.success) {
  console.log("Success:", decodeResult.text);
  console.log("Format:", decodeResult.format);
} else {
  console.error("Failed:", decodeResult.error);
  console.error("Type:", decodeResult.errorType);
  
  // Take action based on error type
  switch (decodeResult.errorType) {
    case "NOT_FOUND":
      // Try different image preprocessing or inform user
      break;
    case "CHECKSUM_FAILED":
      // Retry with TRY_HARDER or improve image quality
      break;
    case "INVALID_FORMAT":
      // Barcode is damaged, try different region
      break;
  }
}

Type Utilities

Dimension

/**
 * Dimension type for specifying width and height
 * Used in size constraints for encoding
 */
interface Dimension {
  /**
   * Width in pixels or modules
   */
  width: number;
  
  /**
   * Height in pixels or modules
   */
  height: number;
}

Usage:

import { Dimension, EncodeHintType, DataMatrixWriter, BarcodeFormat } from "@zxing/library";

const minSize: Dimension = { width: 10, height: 10 };
const maxSize: Dimension = { width: 48, height: 48 };

const hints = new Map<EncodeHintType, any>();
hints.set(EncodeHintType.MIN_SIZE, minSize);
hints.set(EncodeHintType.MAX_SIZE, maxSize);

const writer = new DataMatrixWriter();
const matrix = writer.encode("Data", BarcodeFormat.DATA_MATRIX, 200, 200, hints);

Related Documentation

  • Core API - Reader/Writer interfaces and Result
  • QR Code - QR Code specific types
  • Data Matrix - Data Matrix specific types
  • Aztec - Aztec specific types
  • PDF417 - PDF417 specific types and metadata
  • 1D Barcodes - 1D format details
  • Image Processing - Image processing exceptions
  • Error Correction - Reed-Solomon exceptions

Format Support Matrix

FormatReadWriteError CorrectionMax CapacityTypical Use
QR_CODEL/M/Q/H (~7-30%)2,953 bytesGeneral purpose, mobile
DATA_MATRIXECC2002,335 charsManufacturing, healthcare
AZTEC23-90% configurable3,832 digitsTransport, ID documents
PDF_4179 levels (0-8)1,850 charsID cards, transport
EAN_13Check digit13 digitsRetail products
EAN_8Check digit8 digitsSmall packages
UPC_ACheck digit12 digitsNorth American retail
UPC_ECheck digit8 digitsSmall packages (compressed)
CODE_128Check digitVariableShipping, logistics
CODE_39Optional checkVariableIndustrial, automotive
CODE_932 check digitsVariablePostal, logistics
ITFOptional checkEven lengthDistribution, ITF-14
CODABARSelf-checkingVariableLibraries, blood banks
RSS_14Check digit14 digitsSmall items, fresh food
RSS_EXPANDEDCheck digitVariableVariable data (experimental)
MAXICODEBuilt-inFixedUPS (not implemented)
UPC_EAN_EXTENSIONN/A2 or 5 digitsSupplement only

Legend:

  • ✓ = Fully supported
  • ✗ = Not supported
  • Read = Decoding capability
  • Write = Encoding capability

Hint Reference

Common Decode Hints

// Optimize for speed
const fastHints = new Map<DecodeHintType, any>();
fastHints.set(DecodeHintType.POSSIBLE_FORMATS, [BarcodeFormat.QR_CODE]);

// Optimize for accuracy
const accurateHints = new Map<DecodeHintType, any>();
accurateHints.set(DecodeHintType.TRY_HARDER, true);

// Pure barcode (fastest)
const pureHints = new Map<DecodeHintType, any>();
pureHints.set(DecodeHintType.PURE_BARCODE, true);

// International text
const intlHints = new Map<DecodeHintType, any>();
intlHints.set(DecodeHintType.CHARACTER_SET, "UTF-8");

Common Encode Hints

// Maximum error correction (QR Code)
const maxECHints = new Map<EncodeHintType, any>();
maxECHints.set(EncodeHintType.ERROR_CORRECTION, "H");

// UTF-8 encoding
const utf8Hints = new Map<EncodeHintType, any>();
utf8Hints.set(EncodeHintType.CHARACTER_SET, "UTF-8");

// Minimal margin
const minMarginHints = new Map<EncodeHintType, any>();
minMarginHints.set(EncodeHintType.MARGIN, 1);

// Auto-size Aztec
const aztecHints = new Map<EncodeHintType, any>();
aztecHints.set(EncodeHintType.AZTEC_LAYERS, 0);
aztecHints.set(EncodeHintType.ERROR_CORRECTION, 33);

// Square Data Matrix
const squareDMHints = new Map<EncodeHintType, any>();
squareDMHints.set(EncodeHintType.DATA_MATRIX_SHAPE, SymbolShapeHint.FORCE_SQUARE);

Best Practices

Error Handling Strategy

  1. Specific to General: Catch specific exceptions before general ones
  2. Graceful Degradation: Return null or default values instead of crashing
  3. User Feedback: Provide actionable error messages
  4. Logging: Log errors for debugging but don't spam console
  5. Retry Logic: Implement retry with progressive hints for robustness

Hint Usage

  1. Performance: Use POSSIBLE_FORMATS to limit format attempts
  2. Accuracy: Enable TRY_HARDER for difficult barcodes
  3. Compatibility: Specify CHARACTER_SET for international text
  4. Optimization: Use PURE_BARCODE for clean barcode images

Format Selection

  1. Data Type: Choose format based on content type (numeric vs text vs binary)
  2. Capacity: Ensure format supports required data size
  3. Environment: Consider printing/scanning environment
  4. Standards: Use industry-standard formats where applicable
  5. Error Resilience: Select appropriate error correction level

Related Documentation

Install with Tessl CLI

npx tessl i tessl/npm-zxing--library@0.21.14

docs

index.md

tile.json