QR Code Generator Library

Technical Analysis and Code Reference

Table of Contents

1. Primary Purpose

The QR Code Generator library is a comprehensive implementation of the ISO/IEC 18004 international standard for QR code generation. It provides complete functionality for encoding data into QR codes with professional-grade features including all error correction levels, version support, and multiple output formats.

Core Capabilities
  • Full Standard Compliance: Implements ISO/IEC 18004 specification completely
  • Version Support: All 40 QR code versions (21×21 to 177×177 modules)
  • Error Correction: All four levels (L=7%, M=15%, Q=25%, H=30%)
  • Encoding Modes: Numeric, Alphanumeric, and 8-bit Byte modes
  • Automatic Optimization: Selects minimum version and optimal mask pattern
  • Multiple Outputs: LiveCode image objects, PNG files, or raw PNG data

Technical Scope

This library handles the complete QR code generation pipeline from data encoding through error correction to final image rendering. It includes sophisticated algorithms for Reed-Solomon error correction, mask pattern evaluation, and PNG compression.

2. Key Functionality

Data Encoding

Error Correction

QR Code Structure

Mask Pattern Optimization

Image Generation

3. Reusable Code Snippets

The following code examples demonstrate the most useful patterns and techniques from this library that can be applied to other projects.

3.1 Basic QR Code Generation
Use Case
Generate a QR code with automatic optimization. The library automatically selects the smallest version that can hold the data and chooses the optimal mask pattern for readability.
-- Basic QR code generation with medium error correction
command generateBasicQRCode pImageName, pData
   local tResult
   
   -- Generate QR code with Medium error correction and size 3
   qrCreate pImageName, pData, "M", 3
   put the result into tResult
   
   -- Check for errors
   if tResult begins with "Error" then
      answer "Failed to generate QR code:" && tResult
      exit generateBasicQRCode
   end if
   
   -- Parse result: version, ECC, mode, mask, size
   local tVersion, tECC, tMode, tMask, tSize
   put item 1 of tResult into tVersion
   put item 2 of tResult into tECC
   put item 3 of tResult into tMode
   put item 4 of tResult into tMask
   put item 5 of tResult into tSize
   
   answer "QR Code created: Version" && tVersion && "(" & tMode && "mode)"
end generateBasicQRCode
Parameters Explained
  • pImageName: Name of image control to populate
  • pData: Data to encode (automatic mode detection)
  • "M": Error correction level (L/M/Q/H)
  • 3: Module size multiplier for scaling
3.2 Controlled Version Generation
Use Case
Generate QR codes with specific version constraints. Useful when you need consistent QR code sizes or want to control the density of the pattern.
-- Generate QR with specific version range and mask pattern
command generateControlledQRCode pImageName, pData
   local tECC, tSize, tMask, tMinVersion, tMaxVersion
   
   put "H" into tECC          -- High error correction (30%)
   put 5 into tSize              -- 5x module size
   put 7 into tMask              -- Specific mask pattern
   put 10 into tMinVersion      -- Minimum QR version
   put 20 into tMaxVersion      -- Maximum QR version
   
   -- Create QR with full control
   qrCreate pImageName, pData, tECC, tSize, tMask, tMinVersion, tMaxVersion
   
   local tResult
   put the result into tResult
   
   if tResult begins with "Error" then
      answer "Generation failed:" && tResult
   else
      answer "Created version" && item 1 of tResult && "with mask" && item 4 of tResult
   end if
end generateControlledQRCode
Version Constraints

Version ranges allow you to balance QR code size against data density. Lower versions (1-10) produce smaller codes but have limited capacity. Higher versions (20-40) can hold more data but create larger, denser patterns.

3.3 Custom Color QR Codes
Use Case
Create branded QR codes with custom colors. Essential for maintaining design consistency while ensuring adequate contrast for reliable scanning.
-- Generate QR code with custom brand colors
command generateBrandedQRCode pImageName, pData, pForeColor, pBackColor
   local tResult
   
   -- Set custom colors before generation
   qrSetColors pForeColor, pBackColor
   
   -- Generate QR code
   qrCreate pImageName, pData, "M", 4
   put the result into tResult
   
   if tResult begins with "Error" then
      answer "Color QR generation failed:" && tResult
   else
      answer "Branded QR code created successfully"
   end if
end generateBrandedQRCode

-- Example usage with different color formats
command demonstrateColorFormats
   -- Using color names
   qrSetColors "Navy", "LightYellow"
   
   -- Using RGB triplets
   qrSetColors "25,25,112", "255,255,224"
   
   -- Reset to default black and white
   qrSetColors "Black", "White"
end demonstrateColorFormats
Color Contrast Requirements

For reliable QR code scanning, maintain high contrast between foreground and background colors. The foreground (data modules) should be significantly darker than the background. Poor contrast can make QR codes unscannable.

3.4 PNG File Generation
Use Case
Generate QR codes as PNG files for web applications, email attachments, or printing. The special "!" parameter returns raw PNG data for server-side applications.
-- Generate QR code as PNG file
command generateQRCodePNGFile pFilePath, pData
   local tResult
   
   -- Create PNG file directly
   qrCreate pFilePath, pData, "M", 3
   put the result into tResult
   
   if tResult begins with "Error" then
      return "Failed:" && tResult
   else
      return "PNG file created:" && pFilePath
   end if
end generateQRCodePNGFile

-- Generate QR code as raw PNG data (for web servers)
function generateQRCodePNGData pData
   local tResult, tPNGData
   
   -- Use "!" to get raw PNG data in result
   qrCreate "!", pData, "M", 3
   put the result into tResult
   
   if tResult begins with "Error" then
      return empty
   end if
   
   -- First line is metadata, remaining lines are PNG data
   delete line 1 of tResult
   put tResult into tPNGData
   
   return tPNGData
end generateQRCodePNGData

-- Example: Create base64-encoded image for HTML
function generateQRCodeHTMLImage pData
   local tPNGData, tBase64
   
   put generateQRCodePNGData(pData) into tPNGData
   put base64Encode(tPNGData) into tBase64
   replace return with empty in tBase64
   
   return "<img src='data:image/png;base64," & tBase64 & "'/>"
end generateQRCodeHTMLImage
Server-Side Usage

The "!" parameter is specifically designed for LiveCode Server applications. It returns the complete PNG binary data in the result, allowing you to dynamically generate QR codes in web responses without creating temporary files.

3.5 Binary Number Formatting
Use Case
Format binary numbers with leading zeros. Essential for bit manipulation, data encoding, and when working with fixed-width binary fields.
-- Format binary numbers with leading zeros
private function _format pData, pLen
   local tPad
   put pLen - length(pData) into tPad
   
   if tPad > 0 then
      repeat tPad
         put "0" before pData
      end repeat
   end if
   
   return pData
end _format

-- Practical examples of binary formatting
command demonstrateBinaryFormatting
   local tValue, tBinary, tFormatted
   
   -- Convert decimal to 8-bit binary
   put 42 into tValue
   put baseConvert(tValue, 10, 2) into tBinary
   put _format(tBinary, 8) into tFormatted
   -- Result: "00101010"
   
   -- Create 4-bit character count indicator
   put 15 into tValue
   put _format(baseConvert(tValue, 10, 2), 4) into tFormatted
   -- Result: "1111"
   
   -- Format version information (6 bits)
   put 7 into tValue
   put _format(baseConvert(tValue, 10, 2), 6) into tFormatted
   -- Result: "000111"
end demonstrateBinaryFormatting
Reusable Pattern

This formatting function is universally applicable for any situation requiring fixed-width binary representation, such as network protocols, file formats, or data serialization.

3.6 Galois Field Mathematics
Use Case
Implement Galois Field GF(256) arithmetic for error correction codes. Essential for Reed-Solomon encoding, AES encryption, and other cryptographic applications.
-- Lookup integer in GF(256) table and return exponent (alpha)
private function _alpha pInt
   -- Returns alpha exponent for given integer value
   return item 3 of line pInt of sGF256List
end _alpha

-- Lookup exponent in GF(256) table and return integer
private function _int pAlpha
   -- Special case: alpha^0 = 1
   if pAlpha = 0 then return 1
   
   -- Returns integer value for given alpha exponent
   return item 2 of line pAlpha of sGF256List
end _int

-- Galois Field multiplication example
function gfMultiply pA, pB
   -- Multiply two numbers in GF(256)
   -- In Galois Field: multiply = add exponents, mod 255
   local tAlphaA, tAlphaB, tResult
   
   -- Handle zero cases
   if pA = 0 or pB = 0 then return 0
   
   -- Convert to alpha form
   put _alpha(pA) into tAlphaA
   put _alpha(pB) into tAlphaB
   
   -- Add exponents with modulo 255
   put _int((tAlphaA + tAlphaB) mod 255) into tResult
   
   return tResult
end gfMultiply

-- Galois Field division example
function gfDivide pA, pB
   -- Divide two numbers in GF(256)
   -- In Galois Field: divide = subtract exponents, mod 255
   local tAlphaA, tAlphaB, tExp
   
   if pB = 0 then return 0  -- Division by zero
   if pA = 0 then return 0
   
   put _alpha(pA) into tAlphaA
   put _alpha(pB) into tAlphaB
   
   -- Subtract exponents with modulo 255
   put (tAlphaA - tAlphaB) mod 255 into tExp
   if tExp < 0 then add 255 to tExp
   
   return _int(tExp)
end gfDivide
Galois Field GF(256)

Galois Field arithmetic is fundamental to error correction. GF(256) operates on 8-bit values where addition is XOR and multiplication uses logarithm tables. This enables efficient polynomial operations required by Reed-Solomon codes.

3.7 Reed-Solomon Error Correction
Use Case
Generate Reed-Solomon error correction codes for any data stream. Applicable to data transmission, storage systems, and any application requiring error detection and correction.
-- Generate Reed-Solomon error correction codes
private function _errorCodes pByteStream, pNumErrorCodes
   local tNumDataCodes, tTotalCodes, tRefExp, tExp
   local tErrorCodeA, tMsgPolyA
   
   put length(pByteStream) into tNumDataCodes
   put tNumDataCodes + pNumErrorCodes into tTotalCodes
   put tTotalCodes - 1 into tRefExp
   put tRefExp into tExp
   
   -- Initialize error code array with data polynomial coefficients
   repeat with i = 1 to tNumDataCodes
      put charToNum(char i of pByteStream) into tErrorCodeA[tExp]
      subtract 1 from tExp
   end repeat
   
   -- Zero-fill remaining coefficients
   repeat with i = tExp to 0 step -1
      put 0 into tErrorCodeA[i]
   end repeat
   
   -- Get generator polynomial exponents for error correction level
   local tLine, tGenData, tGenExp, tGenExpCount
   put lineOffset(LF & pNumErrorCodes, LF & sGenPolyAlphaExpList) into tLine
   put line tLine of sGenPolyAlphaExpList into tGenData
   put item 2 to -1 of tGenData into tGenExp
   put the num of items in tGenExp into tGenExpCount
   
   -- Polynomial division algorithm
   local tSanity
   put 0 into tSanity
   repeat until the num of lines in the keys of tErrorCodeA = pNumErrorCodes or tSanity > 1000
      add 1 to tSanity
      
      -- Get first coefficient alpha value
      local tRefAlpha
      put _alpha(tErrorCodeA[tRefExp]) into tRefAlpha
      
      -- Apply generator polynomial
      repeat with i = 1 to tGenExpCount
         local tECIndex, tGenAlpha
         put tRefExp - i + 1 into tECIndex
         put item i of tGenExp into tGenAlpha
         
         -- Galois Field multiplication and XOR
         put _int((tRefAlpha + tGenAlpha) mod 255) bitXor tErrorCodeA[tECIndex] \
               into tErrorCodeA[tECIndex]
      end repeat
      
      -- Remove leading zero coefficients
      repeat with i = tRefExp to 0 step -1
         if tErrorCodeA[i] = 0 then
            delete variable tErrorCodeA[i]
            subtract 1 from tRefExp
         else
            exit repeat
         end if
      end repeat
   end repeat
   
   -- Convert error codes to byte stream
   local tKeys, tErrorBytes
   put the keys of tErrorCodeA into tKeys
   sort lines of tKeys descending numeric
   
   repeat for each line tKey in tKeys
      put numToChar(tErrorCodeA[tKey]) after tErrorBytes
   end repeat
   
   return tErrorBytes
end _errorCodes
Reed-Solomon Algorithm

Reed-Solomon error correction treats data as polynomials in GF(256). The algorithm divides the message polynomial by the generator polynomial to produce remainder coefficients, which become the error correction codes. These codes enable detection and correction of multiple byte errors.

3.8 CRC32 Checksum Calculation
Use Case
Calculate CRC32 checksums for data integrity verification. Used in PNG files, ZIP archives, network protocols, and any application requiring reliable data validation.
-- Initialize CRC lookup table (call once at startup)
private command _crcMakeTable
   put empty into sCrcTableA
   
   repeat with tIndex = 0 to 255
      local tVal
      put tIndex into tVal
      
      -- Process each bit
      repeat with tBit = 0 to 7
         if (tVal bitAnd 1) > 0 then
            -- CRC32 polynomial: 0xEDB88320
            put 3988292384 bitXor (tVal div 2) into tVal
         else
            put tVal div 2 into tVal
         end if
      end repeat
      
      put tVal into sCrcTableA[tIndex]
   end repeat
   
   put true into sCrcTableCreated
end _crcMakeTable

-- Update CRC value with new data
private function _crcUpdate pCrc, @pData
   if sCrcTableCreated <> true then _crcMakeTable
   
   local tLen
   put length(pData) into tLen
   
   repeat with tIndex = 1 to tLen
      put sCrcTableA[(pCrc bitXor charToNum(char tIndex of pData)) bitAnd 255] \
            bitXor (pCrc div 256) into pCrc
   end repeat
   
   return pCrc
end _crcUpdate

-- Calculate final CRC32 checksum
private function _crc32 pData
   local tResult, tBytes
   
   -- Initial CRC value: 0xFFFFFFFF
   put _crcUpdate(4294967295, pData) bitXor 4294967295 into tResult
   
   -- Convert to byte string (big-endian)
   repeat until tResult = 0
      put numToChar(tResult bitAnd 255) before tBytes
      put tResult div 256 into tResult
   end repeat
   
   return tBytes
end _crc32

-- Practical example: Verify data integrity
function verifyDataWithCRC pData, pExpectedCRC
   local tCalculatedCRC
   put _crc32(pData) into tCalculatedCRC
   return (tCalculatedCRC = pExpectedCRC)
end verifyDataWithCRC
CRC32 Applications

CRC32 is widely used for data integrity checks in file formats (PNG, ZIP, GZIP), network protocols (Ethernet, TCP/IP), and storage systems. It provides fast error detection with minimal computational overhead.

3.9 Data Compression (Deflate)
Use Case
Create properly formatted DEFLATE compressed data with Adler-32 checksums. Essential for generating valid PNG files, ZIP archives, or any ZLIB-compatible compressed data.
-- Create DEFLATE compressed data with ZLIB wrapper
private function _deflate pData
   local tComp
   
   -- Compress using LiveCode's compress function
   put compress(pData) into tComp
   
   -- Remove gzip header (10 bytes) and trailer (8 bytes)
   delete char 1 to 10 of tComp
   delete char -8 to -1 of tComp
   
   -- Calculate Adler-32 checksum
   local tA, tB, tVal
   put 1 into tA
   put 0 into tB
   
   repeat for each char tChar in pData
      put charToNum(tChar) into tVal
      add tVal to tA
      if tA > 65521 then subtract 65521 from tA
      add tA to tB
      if tB > 65521 then subtract 65521 from tB
   end repeat
   
   -- Convert checksum to bytes (big-endian)
   local tA1, tA2, tB1, tB2
   put numToChar((tA bitAnd 65280) / 256) into tA1
   put numToChar(tA bitAnd 255) into tA2
   put numToChar((tB bitAnd 65280) / 256) into tB1
   put numToChar(tB bitAnd 255) into tB2
   
   -- Add ZLIB header and Adler-32 trailer
   put numToChar(120) & numToChar(156) before tComp
   put tB1 & tB2 & tA1 & tA2 after tComp
   
   return tComp
end _deflate

-- Example: Create compressed data block for PNG
function createCompressedImageData pImageData
   local tCompressed
   
   -- Compress the image data
   put _deflate(pImageData) into tCompressed
   
   -- Return compressed data with proper ZLIB format
   return tCompressed
end createCompressedImageData
ZLIB Format

The ZLIB format wraps DEFLATE compressed data with a 2-byte header (compression method and flags) and a 4-byte Adler-32 checksum trailer. This format is required for PNG IDAT chunks and many other compressed data formats.

3.10 Byte Stream Manipulation
Use Case
Convert between different representations of binary data. Essential for working with file formats, network protocols, and binary data structures.
-- Convert comma-separated byte values to binary string
private function _numsToBytes pData
   local tResult
   
   repeat for each item tCode in pData
      put numToChar(tCode) after tResult
   end repeat
   
   return tResult
end _numsToBytes

-- Convert hex string to binary
private function _hexToBytes pData
   local tHex, tResult
   
   repeat until pData = empty
      put char 1 to 2 of pData into tHex
      put numToChar("0x" & tHex) after tResult
      delete char 1 to 2 of pData
   end repeat
   
   return tResult
end _hexToBytes

-- Convert binary string to comma-separated values
private function _byteValues pData
   local tVals
   
   repeat for each char tChar in pData
      put charToNum(tChar) & comma after tVals
   end repeat
   
   delete char -1 of tVals
   return tVals
end _byteValues

-- Practical examples of byte stream manipulation
command demonstrateByteOperations
   local tBytes, tValues, tHexString
   
   -- Create PNG signature bytes
   put _numsToBytes("137,80,78,71,13,10,26,10") into tBytes
   
   -- Convert hex color to RGB bytes
   put _hexToBytes("FF6347") into tBytes  -- Tomato color
   
   -- Extract byte values from binary data
   put _byteValues(tBytes) into tValues
   -- Result: "255,99,71"
   
   -- Create 32-bit integer in big-endian format
   local tNumber
   put 1024 into tNumber
   put _hexToBytes(format("%08x", tNumber)) into tBytes
   -- Result: 4-byte big-endian representation
end demonstrateByteOperations
Binary Data Handling

These utility functions are essential for working with binary file formats. They provide clean conversion between human-readable representations and binary data, making it easier to construct file headers, network packets, and other structured binary data.

4. Architectural Patterns

Script Library Pattern

The library uses LiveCode's backscript mechanism for global availability:

Data Table Pattern

Extensive use of lookup tables for QR code specifications:

Pipeline Architecture

QR code generation follows a clear multi-stage pipeline:

  1. Data Analysis: Determine mode and minimum version
  2. Encoding: Convert data to bit stream with mode indicators
  3. Error Correction: Generate Reed-Solomon codes
  4. Structure Placement: Draw finder patterns, timing, alignment
  5. Data Placement: Fill symbol with interleaved data and error codes
  6. Masking: Apply and evaluate mask patterns
  7. Format Encoding: Add format and version information
  8. Image Generation: Convert to pixel data or PNG

State Machine Pattern

The data placement algorithm uses a state machine:

Strategy Pattern

Multiple encoding modes implemented as strategies:

Builder Pattern

PNG generation builds complex structures incrementally:

5. Notable Design Decisions

Script-Local Variables for Performance

Design Choice

All lookup tables and working data are stored in script-local variables (sAlignPosList, sCapacityList, etc.) rather than being loaded from external files or calculated on demand.

Benefits:

  • Extremely fast access during QR code generation
  • No file I/O overhead
  • Data remains in memory for duration of application
  • Guaranteed availability regardless of file system state

Dual Image Output Systems

Design Choice

Two completely separate rendering paths: direct LiveCode imageData manipulation and full PNG encoder implementation.

Rationale:

  • ImageData Path: Fastest for in-app display, direct memory manipulation
  • PNG Path: Required for file export and server-side usage
  • Flexibility: Allows optimal output for each use case
  • Independence: PNG encoder doesn't rely on LiveCode image objects

Mask Pattern Optimization

Algorithm Design

The library implements full mask pattern evaluation rather than using a simple default.

Four Evaluation Rules:

  1. Penalty for consecutive same-color modules (reduces scanning errors)
  2. Penalty for 2×2 blocks of same color (improves pattern distribution)
  3. Penalty for patterns resembling finder patterns (prevents false positives)
  4. Penalty for imbalanced dark/light ratio (optimizes for scanners)

This ensures generated QR codes are optimally scannable across different devices and conditions.

Version Constraint Parameters

User Control

Allows specification of minimum and maximum QR code versions rather than just automatic selection.

Use Cases:

  • Force consistent QR code sizes for design purposes
  • Prevent generation of overly large codes
  • Ensure minimum size for printing requirements
  • Control data density for specific scanner capabilities

Block Interleaving Strategy

Error Recovery Enhancement

Data and error correction codes are interleaved across multiple blocks rather than placed sequentially.

Benefits:

  • Localized damage affects multiple blocks minimally
  • Better recovery from burst errors
  • Distributes error correction capability evenly
  • Improves resilience to partial obscuration

Quiet Zone Implementation

Standard Compliance

Automatically adds 4-module quiet zone (white border) around all QR codes.

Importance:

  • Required by ISO/IEC 18004 specification
  • Essential for reliable scanner detection
  • Prevents interference from adjacent patterns
  • Transparent to user - handled automatically

Custom Color Support

Branding Capability

Supports custom colors through qrSetColors command while maintaining scan reliability.

Implementation:

  • Accepts color names or RGB triplets
  • Validates color format before application
  • Maintains separate pixel constants for both image systems
  • Documentation warns about contrast requirements

Comprehensive Error Handling

Robustness

Extensive validation and error reporting throughout the generation process:

  • Parameter validation (ECC level, version range, image target)
  • Data capacity checking before generation
  • Error messages returned via result for programmatic handling
  • Graceful degradation when possible
  • Clear error descriptions for troubleshooting

6. Data Structure Organization

Lookup Tables

The library uses several large lookup tables for QR code specifications:

Table Name Purpose Key Format
sAlignPosList Alignment pattern positions for each version Version number
sCapacityList Total codewords and error correction capacity Version number
sECCDataList Error correction block structure details Version-ECC combination
sCCIList Character count indicator bit lengths Version range
sGF256List Galois Field log/antilog table Index (1-255)
sGenPolyAlphaExpList Generator polynomial coefficients Error code count
sFormatList Format information bit patterns ECC-Mask combination
sVersionList Version information encoding Version number (7-40)
sColorNames Named colors to RGB mappings Color name

Symbol Maps

Three parallel data structures track the QR code symbol state:

Map Name Purpose Format
sSymbolMap Tracks used/available modules String of "0" (free) or "1" (used)
sBlankMap Saves symbol structure before data Copy of sSymbolMap after structure placement
sDataMap Stores actual data module values String of "0" (light) or "1" (dark)

Working Data Streams

Data transformation flows through these streams:

Stream Format Contents
sBitStream String of "0" and "1" Encoded data with mode indicators and padding
sByteStream Binary string 8-bit codewords with interleaved error codes
sImgData Binary string ARGB pixel data for LiveCode image

Array Structures

Arrays are used for block-based processing:

7. Algorithm Phases

Phase 1: Data Analysis and Mode Selection

Input Processing

Steps:

  1. Analyze input data to determine encoding mode:
    • All digits → Numeric mode
    • Alphanumeric characters only → Alphanumeric mode
    • Any other data → Byte mode
  2. Calculate data length
  3. Iterate through versions to find minimum that fits data
  4. Consider ECC level and mode when calculating capacity
  5. Fail if data exceeds version 40 capacity

Phase 2: Bit Stream Generation

Data Encoding

Numeric Mode:

  • Add mode indicator (0001)
  • Add character count indicator
  • Group digits in triplets, convert to 10-bit binary
  • Handle remaining 1-2 digits with 4 or 7 bits

Alphanumeric Mode:

  • Add mode indicator (0010)
  • Add character count indicator
  • Group characters in pairs: value = char1 × 45 + char2
  • Convert to 11-bit binary
  • Handle remaining character with 6 bits

Byte Mode:

  • Add mode indicator (0100)
  • Add character count indicator
  • Convert each byte to 8-bit binary

Finalization:

  • Add terminator (0000) if space permits
  • Pad to 8-bit boundary with zeros
  • Fill remaining capacity with alternating bytes (11101100, 00010001)

Phase 3: Error Correction Code Generation

Reed-Solomon Encoding

Process:

  1. Determine block structure from ECC data list
  2. Split byte stream into multiple blocks
  3. For each block:
    • Convert data bytes to polynomial coefficients
    • Retrieve generator polynomial for ECC level
    • Perform polynomial division in GF(256)
    • Store remainder as error correction codes
  4. Interleave data blocks byte-by-byte
  5. Interleave error code blocks byte-by-byte
  6. Append any remainder bits

Phase 4: Symbol Structure Placement

Fixed Pattern Drawing

Drawing Order:

  1. Position Detection Patterns: Three 7×7 patterns in corners
  2. Timing Patterns: Alternating modules in row 7 and column 7
  3. Separators: White borders around position patterns
  4. Alignment Patterns: 5×5 patterns at specified coordinates (versions 2+)
  5. Format Information Areas: Reserve space around position patterns
  6. Version Information Areas: Reserve 3×6 blocks (versions 7+)
  7. Dark Module: Single black module at (9, 4×version + 10)

All placements update the symbol map to mark modules as used.

Phase 5: Data Module Placement

Zigzag Placement Algorithm

Placement Pattern:

  1. Start at bottom-right corner
  2. Move in 2-column groups from right to left
  3. Within each group, fill right column then left
  4. Alternate between upward and downward movement
  5. Skip column 7 (timing pattern)
  6. Skip all modules marked as used in symbol map
  7. Place data bits sequentially into available modules

This placement ensures optimal distribution of data and error codes.

Phase 6: Mask Pattern Application and Selection

Optimization Process

Pattern Generation:

  1. Generate all 8 mask patterns using formula-based generation
  2. Store each pattern efficiently (only unique lines)

Pattern Evaluation:

  1. Apply each mask to data modules (XOR operation)
  2. Calculate penalty score using four rules:
    • Rule 1: Consecutive same-color modules (horizontal and vertical)
    • Rule 2: 2×2 blocks of same color
    • Rule 3: Patterns resembling finder patterns
    • Rule 4: Overall dark/light balance
  3. Select mask with lowest total penalty
  4. Apply chosen mask to image data

Phase 7: Format and Version Information Encoding

Metadata Encoding

Format Information:

  • Encode ECC level and mask pattern into 5 bits
  • Apply BCH error correction (15 bits total)
  • XOR with mask pattern (101010000010010)
  • Place in two locations for redundancy

Version Information (versions 7-40):

  • Encode version number into 6 bits
  • Apply BCH error correction (18 bits total)
  • Place in two 3×6 blocks for redundancy

Phase 8: Image Generation

Output Rendering

LiveCode Image Path:

  1. Convert symbol map to ARGB pixel data
  2. Apply color values (default or custom)
  3. Add quiet zone (4 modules of background color)
  4. Scale to requested module size
  5. Set imageData property of target image

PNG File Path:

  1. Create PNG header and IHDR chunk
  2. Create 1-bit palette (PLTE chunk)
  3. Convert symbol map to indexed pixel data
  4. Add filter bytes (0 = no filtering)
  5. Compress using DEFLATE with ZLIB wrapper
  6. Create IDAT chunk with compressed data
  7. Add CRC32 checksums to all chunks
  8. Create IEND chunk
  9. Write complete PNG to file or return as data

Summary

The QR Code Generator library is a comprehensive, production-ready implementation of the ISO/IEC 18004 standard. It demonstrates sophisticated algorithms including Reed-Solomon error correction, Galois Field mathematics, mask pattern optimization, and complete PNG encoding with compression.

The library is particularly valuable for its reusable components: the Reed-Solomon encoder, CRC32 implementation, DEFLATE compression wrapper, and binary data manipulation utilities can all be extracted and applied to other projects requiring these capabilities.

Key strengths include automatic optimization (version and mask selection), comprehensive error handling, support for all standard features, and dual output paths (image objects and PNG files) that cover both interactive and server-side use cases.

QR Code Generator Library Analysis • Generated November 4, 2025

This document provides technical analysis for developers working with LiveCode