Core barcode encoding/decoding library supporting 17 formats including QR Code, Data Matrix, Aztec, PDF 417, and various 1D barcodes
—
Efficient bit-level data structures for representing barcode data and images. BitMatrix provides 2D bit arrays with transformation operations (rotation, flipping), while BitArray provides 1D bit arrays with bit manipulation operations. BitSource reads bits sequentially from byte arrays. These structures are fundamental to all barcode encoding and decoding operations in ZXing.
Two-dimensional array of bits (boolean values) for representing 2D barcodes and binary images. Provides efficient storage (8 bits per byte) and transformation operations.
/**
* Two-dimensional bit matrix.
* Efficient bit-level storage for 2D barcodes and binary images.
* Bits are packed into int arrays for memory efficiency.
* Coordinate system: (0,0) is top-left, x increases right, y increases down.
*/
public final class BitMatrix {
/**
* Creates a square bit matrix.
*
* @param dimension Width and height in bits
*/
public BitMatrix(int dimension);
/**
* Creates a rectangular bit matrix.
*
* @param width Width in bits
* @param height Height in bits
*/
public BitMatrix(int width, int height);
/**
* Gets the bit value at specified coordinates.
*
* @param x X coordinate (0-based from left)
* @param y Y coordinate (0-based from top)
* @return true if bit is set (black), false if unset (white)
*/
public boolean get(int x, int y);
/**
* Sets the bit at specified coordinates to true (black).
*
* @param x X coordinate
* @param y Y coordinate
*/
public void set(int x, int y);
/**
* Sets the bit at specified coordinates to false (white).
*
* @param x X coordinate
* @param y Y coordinate
*/
public void unset(int x, int y);
/**
* Flips the bit at specified coordinates (true->false, false->true).
*
* @param x X coordinate
* @param y Y coordinate
*/
public void flip(int x, int y);
/**
* Flips all bits in the matrix.
*/
public void flip();
/**
* XORs this matrix with another matrix.
* Matrices must have the same dimensions.
*
* @param mask BitMatrix to XOR with
* @throws IllegalArgumentException If dimensions don't match
*/
public void xor(BitMatrix mask);
/**
* Clears all bits to false (white).
*/
public void clear();
/**
* Sets all bits in a rectangular region to true (black).
*
* @param left Left coordinate
* @param top Top coordinate
* @param width Width of region
* @param height Height of region
*/
public void setRegion(int left, int top, int width, int height);
/**
* Gets a single row as a BitArray.
*
* @param y Row index
* @param row Optional BitArray to reuse (may be null)
* @return BitArray containing the row
*/
public BitArray getRow(int y, BitArray row);
/**
* Sets an entire row from a BitArray.
*
* @param y Row index
* @param row BitArray containing new row data
*/
public void setRow(int y, BitArray row);
/**
* Rotates the matrix by specified degrees.
* Only supports 90, 180, and 270 degrees.
*
* @param degrees Rotation angle (90, 180, or 270)
* @throws IllegalArgumentException If degrees is not 90, 180, or 270
*/
public void rotate(int degrees);
/**
* Rotates the matrix 90 degrees clockwise.
*/
public void rotate90();
/**
* Rotates the matrix 180 degrees.
*/
public void rotate180();
/**
* Gets the smallest rectangle containing all set bits.
*
* @return int array {left, top, width, height} or null if all bits are unset
*/
public int[] getEnclosingRectangle();
/**
* Gets coordinates of top-left-most set bit.
*
* @return int array {x, y} or null if all bits are unset
*/
public int[] getTopLeftOnBit();
/**
* Gets coordinates of bottom-right-most set bit.
*
* @return int array {x, y} or null if all bits are unset
*/
public int[] getBottomRightOnBit();
/**
* Gets the width of the matrix.
*
* @return Width in bits
*/
public int getWidth();
/**
* Gets the height of the matrix.
*
* @return Height in bits
*/
public int getHeight();
/**
* Gets the row size in 32-bit ints.
*
* @return Number of ints per row
*/
public int getRowSize();
/**
* Parses a string representation into a BitMatrix.
* Useful for testing and debugging.
*
* @param stringRepresentation String with rows separated by newlines
* @param setString Character representing set bits (e.g., "X", "1")
* @param unsetString Character representing unset bits (e.g., " ", "0")
* @return Parsed BitMatrix
*/
public static BitMatrix parse(String stringRepresentation, String setString, String unsetString);
/**
* Parses a boolean array into a BitMatrix.
*
* @param image 2D boolean array (true = set, false = unset)
* @return BitMatrix representation
*/
public static BitMatrix parse(boolean[][] image);
/**
* Creates a deep copy of this BitMatrix.
*
* @return Independent copy with same contents
*/
public BitMatrix clone();
}Usage Example:
import com.google.zxing.common.BitMatrix;
// Create and manipulate BitMatrix
BitMatrix matrix = new BitMatrix(100, 100);
// Set individual bits
matrix.set(10, 10);
matrix.set(20, 20);
// Set rectangular region
matrix.setRegion(30, 30, 20, 20); // Solid 20x20 square
// Rotate 90 degrees clockwise
matrix.rotate90();
// Find bounding box of set bits
int[] rect = matrix.getEnclosingRectangle();
System.out.println("Bounding box: " + Arrays.toString(rect));
// Convert to image pixels (black and white)
int width = matrix.getWidth();
int height = matrix.getHeight();
int[] pixels = new int[width * height];
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
pixels[y * width + x] = matrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF;
}
}One-dimensional array of bits for representing 1D barcodes and bit sequences. Provides bit manipulation operations and efficient packing.
/**
* One-dimensional bit array.
* Efficient bit-level storage for 1D barcodes and bit sequences.
* Bits are packed into int arrays for memory efficiency.
*/
public final class BitArray {
/**
* Creates an empty BitArray (size will grow as needed).
*/
public BitArray();
/**
* Creates a BitArray with specified initial size.
*
* @param size Initial size in bits
*/
public BitArray(int size);
/**
* Gets the current size of the array.
*
* @return Size in bits
*/
public int getSize();
/**
* Gets the size in bytes (rounded up).
*
* @return Size in bytes
*/
public int getSizeInBytes();
/**
* Gets the bit value at specified index.
*
* @param i Index (0-based)
* @return true if bit is set, false if unset
*/
public boolean get(int i);
/**
* Sets the bit at specified index to true.
*
* @param i Index
*/
public void set(int i);
/**
* Flips the bit at specified index.
*
* @param i Index
*/
public void flip(int i);
/**
* Gets the index of the next set bit starting from specified position.
*
* @param from Starting index (inclusive)
* @return Index of next set bit, or size if no more set bits
*/
public int getNextSet(int from);
/**
* Gets the index of the next unset bit starting from specified position.
*
* @param from Starting index (inclusive)
* @return Index of next unset bit, or size if no more unset bits
*/
public int getNextUnset(int from);
/**
* Sets multiple bits at once using a bit pattern.
*
* @param i Starting index
* @param newBits Bits to set (LSB first)
*/
public void setBulk(int i, int newBits);
/**
* Sets a range of bits to true.
*
* @param start Starting index (inclusive)
* @param end Ending index (exclusive)
*/
public void setRange(int start, int end);
/**
* Clears all bits to false.
*/
public void clear();
/**
* Checks if a range of bits all have the same value.
*
* @param start Starting index (inclusive)
* @param end Ending index (exclusive)
* @param value Expected value (true or false)
* @return true if all bits in range equal value
*/
public boolean isRange(int start, int end, boolean value);
/**
* Appends a single bit to the end of the array.
*
* @param bit Bit value to append
*/
public void appendBit(boolean bit);
/**
* Appends multiple bits from an integer value.
*
* @param value Integer containing bits (LSB first)
* @param numBits Number of bits to append (1-32)
*/
public void appendBits(int value, int numBits);
/**
* Appends all bits from another BitArray.
*
* @param other BitArray to append
*/
public void appendBitArray(BitArray other);
/**
* XORs this array with another array.
* Arrays must have the same size.
*
* @param other BitArray to XOR with
* @throws IllegalArgumentException If sizes don't match
*/
public void xor(BitArray other);
/**
* Converts bits to bytes.
*
* @param bitOffset Starting bit offset
* @param array Destination byte array
* @param offset Starting byte offset in destination
* @param numBytes Number of bytes to write
*/
public void toBytes(int bitOffset, byte[] array, int offset, int numBytes);
/**
* Gets the underlying int array storing the bits.
*
* @return Internal int array (do not modify directly)
*/
public int[] getBitArray();
/**
* Reverses all bits in the array.
*/
public void reverse();
/**
* Creates a deep copy of this BitArray.
*
* @return Independent copy with same contents
*/
public BitArray clone();
}Usage Example:
import com.google.zxing.common.BitArray;
// Create and manipulate BitArray
BitArray bits = new BitArray(32);
// Set individual bits
bits.set(0);
bits.set(5);
bits.set(10);
// Append bits
bits.appendBit(true);
bits.appendBits(0b1010, 4); // Append 4 bits: 1010
// Find next set bit
int nextSet = bits.getNextSet(0);
System.out.println("First set bit at: " + nextSet);
// Check if range is all zeros
boolean allZeros = bits.isRange(20, 25, false);
// Reverse the array
bits.reverse();Sequential bit reader for byte arrays. Used in barcode decoders to read variable-length bit sequences from encoded data.
/**
* Sequential bit reader for byte arrays.
* Reads bits in order from byte array, maintaining current position.
* Used by decoders to parse encoded barcode data.
*/
public final class BitSource {
/**
* Creates a bit source from byte array.
*
* @param bytes Source byte array
*/
public BitSource(byte[] bytes);
/**
* Reads specified number of bits as an integer.
* Bits are read MSB first.
*
* @param numBits Number of bits to read (1-32)
* @return Integer value of the bits read
* @throws IllegalArgumentException If not enough bits available
*/
public int readBits(int numBits);
/**
* Gets the number of bits still available to read.
*
* @return Number of remaining bits
*/
public int available();
/**
* Gets the current byte offset in the source array.
*
* @return Current byte position
*/
public int getByteOffset();
}Usage Example:
import com.google.zxing.common.BitSource;
// Read variable-length data from encoded bytes
byte[] encodedData = new byte[] {(byte)0b10110101, (byte)0b11001100};
BitSource source = new BitSource(encodedData);
// Read 3 bits
int value1 = source.readBits(3); // Reads 101
// Read 5 bits
int value2 = source.readBits(5); // Reads 10111
// Check remaining bits
int remaining = source.available(); // Should be 8 bits left// Writer creates BitMatrix
Writer writer = new QRCodeWriter();
BitMatrix matrix = writer.encode("Data", BarcodeFormat.QR_CODE, 300, 300);
// Convert to BufferedImage (Java desktop)
BufferedImage image = new BufferedImage(matrix.getWidth(), matrix.getHeight(),
BufferedImage.TYPE_INT_RGB);
for (int y = 0; y < matrix.getHeight(); y++) {
for (int x = 0; x < matrix.getWidth(); x++) {
image.setRGB(x, y, matrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF);
}
}// Reader scans rows using BitArray
BinaryBitmap bitmap = ...;
int height = bitmap.getHeight();
BitArray row = new BitArray(bitmap.getWidth());
for (int y = 0; y < height; y++) {
row = bitmap.getBlackRow(y, row); // Reuse BitArray
// Try to decode this row
// OneDReader implementations scan these rows
}// Encoder builds bit sequence
BitArray bits = new BitArray();
// Append mode indicator (4 bits)
bits.appendBits(0b0100, 4);
// Append character count (8 bits)
bits.appendBits(data.length(), 8);
// Append data bits
for (char c : data.toCharArray()) {
bits.appendBits(c, 8);
}
// Convert to bytes for encoding
byte[] bytes = new byte[bits.getSizeInBytes()];
bits.toBytes(0, bytes, 0, bytes.length);Memory Efficiency:
Performance:
Coordinate Systems:
Bit Ordering: