summaryrefslogtreecommitdiff
path: root/docs/handbook/genqrcode/architecture.md
blob: f03715bcba2e3bdbc766195859c4f345d37fc3ef (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
# genqrcode / libqrencode — Architecture

## High-Level Architecture

libqrencode is a layered C library that transforms input data into a QR Code bitmap through a pipeline of distinct modules. The architecture separates concerns cleanly: input management, bit stream encoding, error correction, frame construction, module placement, and masking are each handled by dedicated source files.

```
User Input
    │
    ▼
┌─────────────────────────────────────────┐
│  split.c — Input Splitter               │
│  Automatic mode detection & optimization│
└─────────────┬───────────────────────────┘
              │
              ▼
┌─────────────────────────────────────────┐
│  qrinput.c — Input Data Manager         │
│  QRinput linked list, mode encoders,    │
│  bit stream construction, padding       │
└─────────────┬───────────────────────────┘
              │
              ▼
┌─────────────────────────────────────────┐
│  bitstream.c — Bit Stream Class         │
│  Dynamic bit array with append ops      │
└─────────────┬───────────────────────────┘
              │
              ▼
┌─────────────────────────────────────────┐
│  qrencode.c — Core Encoder              │
│  QRRawCode / MQRRawCode, FrameFiller,   │
│  QRcode_encodeMask, interleaving        │
│                                         │
│  ┌──────────┐  ┌──────────────────────┐ │
│  │ rsecc.c  │  │ qrspec.c / mqrspec.c │ │
│  │ RS ECC   │  │ Spec tables & frames │ │
│  └──────────┘  └──────────────────────┘ │
└─────────────┬───────────────────────────┘
              │
              ▼
┌─────────────────────────────────────────┐
│  mask.c / mmask.c — Masking             │
│  8 patterns (QR) / 4 patterns (MQR),   │
│  penalty evaluation, mask selection     │
└─────────────┬───────────────────────────┘
              │
              ▼
         QRcode struct
    (version, width, data[])
```

---

## Module Dependency Graph

Each `.c` file includes specific headers. Here is the complete include dependency:

```
qrencode.c
├── qrencode.h
├── qrspec.h
├── mqrspec.h
├── bitstream.h
├── qrinput.h
├── rsecc.h
├── split.h
├── mask.h
└── mmask.h

qrinput.c
├── qrencode.h
├── qrspec.h
├── mqrspec.h
├── bitstream.h
└── qrinput.h

split.c
├── qrencode.h
├── qrinput.h
├── qrspec.h
└── split.h

mask.c
├── qrencode.h
├── qrspec.h
└── mask.h

mmask.c
├── qrencode.h
├── mqrspec.h
└── mmask.h

qrspec.c
├── qrspec.h
└── qrinput.h

mqrspec.c
└── mqrspec.h

rsecc.c
└── rsecc.h

bitstream.c
└── bitstream.h

qrenc.c (CLI tool)
└── qrencode.h
```

**Key insight:** `qrencode.c` is the integration point that pulls together all modules. The CLI tool (`qrenc.c`) only depends on `qrencode.h`, using exclusively the public API.

---

## Detailed Module Descriptions

### `qrencode.h` — Public API Header

This is the **only header that external consumers include**. It defines:

- `QRencodeMode` enum — All encoding modes (`QR_MODE_NUM`, `QR_MODE_AN`, `QR_MODE_8`, `QR_MODE_KANJI`, `QR_MODE_ECI`, `QR_MODE_FNC1FIRST`, `QR_MODE_FNC1SECOND`, plus internal `QR_MODE_NUL`, `QR_MODE_STRUCTURE`)
- `QRecLevel` enum — Error correction levels (`QR_ECLEVEL_L` through `QR_ECLEVEL_H`)
- `QRcode` struct — Output symbol (version, width, data array)
- `QRcode_List` struct — Singly-linked list of QRcode for structured append
- `QRinput` — Opaque typedef for input object
- `QRinput_Struct` — Opaque typedef for structured input set
- Version constants: `QRSPEC_VERSION_MAX` (40), `MQRSPEC_VERSION_MAX` (4)
- All `QRinput_*`, `QRcode_*`, and utility function declarations

The header uses `extern "C"` guards for C++ compatibility.

### `qrencode_inner.h` — Test-Only Internal Header

Exposes internal types and functions for the test suite:

```c
typedef struct {
    int dataLength;
    int eccLength;
    unsigned char *data;
    unsigned char *ecc;
} RSblock;

typedef struct {
    int version;
    int dataLength;
    int eccLength;
    unsigned char *datacode;
    unsigned char *ecccode;
    int b1;
    int blocks;
    RSblock *rsblock;
    int count;
} QRRawCode;

typedef struct {
    int version;
    int dataLength;
    int eccLength;
    unsigned char *datacode;
    unsigned char *ecccode;
    RSblock *rsblock;
    int oddbits;
    int count;
} MQRRawCode;
```

Exposed functions:
- `QRraw_new()`, `QRraw_getCode()`, `QRraw_free()`
- `MQRraw_new()`, `MQRraw_getCode()`, `MQRraw_free()`
- `FrameFiller_test()`, `FrameFiller_testMQR()`
- `QRcode_encodeMask()`, `QRcode_encodeMaskMQR()`
- `QRcode_new()`

### `qrencode.c` — Core Encoding Engine

This is the **central orchestrator** of the entire encoding process. It contains:

#### RSblock and QRRawCode

The `RSblock` struct represents one Reed-Solomon block:
```c
typedef struct {
    int dataLength;
    int eccLength;
    unsigned char *data;
    unsigned char *ecc;
} RSblock;
```

`QRRawCode` manages all RS blocks for a full QR Code:
```c
typedef struct {
    int version;
    int dataLength;
    int eccLength;
    unsigned char *datacode;   // merged data byte stream
    unsigned char *ecccode;    // merged ECC byte stream
    int b1;                    // number of type-1 blocks
    int blocks;                // total block count
    RSblock *rsblock;          // array of RS blocks
    int count;                 // iteration counter for getCode()
} QRRawCode;
```

`QRraw_new()` creates a QRRawCode from a QRinput:
1. Calls `QRinput_getByteStream()` to convert input to a padded byte stream
2. Retrieves the ECC specification via `QRspec_getEccSpec()`
3. Initializes RS blocks via `RSblock_init()`, which calls `RSECC_encode()` for each block
4. Sets up interleaving state (b1 records the count of type-1 blocks)

`QRraw_getCode()` implements data/ECC interleaving:
```c
STATIC_IN_RELEASE unsigned char QRraw_getCode(QRRawCode *raw)
{
    int col, row;
    unsigned char ret;

    if(raw->count < raw->dataLength) {
        row = raw->count % raw->blocks;
        col = raw->count / raw->blocks;
        if(col >= raw->rsblock[0].dataLength) {
            row += raw->b1;
        }
        ret = raw->rsblock[row].data[col];
    } else if(raw->count < raw->dataLength + raw->eccLength) {
        row = (raw->count - raw->dataLength) % raw->blocks;
        col = (raw->count - raw->dataLength) / raw->blocks;
        ret = raw->rsblock[row].ecc[col];
    } else {
        return 0;
    }
    raw->count++;
    return ret;
}
```

This interleaves by cycling through blocks row-by-row: the first byte from each block, then the second byte from each block, and so on. When type-1 blocks are exhausted (their data is shorter), it shifts to type-2 blocks by adding `b1` to the row index.

#### FrameFiller

The `FrameFiller` struct manages the zigzag placement of data modules:

```c
typedef struct {
    int width;
    unsigned char *frame;
    int x, y;     // current position
    int dir;      // direction: -1 (upward) or 1 (downward)
    int bit;      // 0 or 1 within a column pair
    int mqr;      // flag for Micro QR mode
} FrameFiller;
```

`FrameFiller_set()` initializes the filler at the bottom-right corner `(width-1, width-1)` with direction `-1` (upward).

`FrameFiller_next()` implements the QR Code module placement algorithm:
- Modules are placed in 2-column strips from right to left
- Within each strip, columns alternate right-left
- Direction alternates between upward and downward
- Column 6 (the vertical timing pattern) is skipped in full QR mode
- Modules already marked with bit 7 set (`0x80`) — function patterns — are skipped

#### QRcode_encodeMask()

The main encoding function for full QR Codes:

1. Validates input (not MQR, version in range, valid EC level)
2. Creates `QRRawCode` from input
3. Creates base frame via `QRspec_newFrame()`
4. Places data bits using `FrameFiller_next()`:
   - Data modules: `*p = ((bit & code) != 0)` — only LSB set
   - ECC modules: `*p = 0x02 | ((bit & code) != 0)` — bit 1 also set
   - Remainder bits: `*p = 0x02`
5. Applies masking:
   - `mask == -2`: debug mode, no masking
   - `mask < 0` (normal): `Mask_mask()` evaluates all 8 patterns
   - `mask >= 0`: `Mask_makeMask()` applies specific mask

#### QRcode_encodeMaskMQR()

The Micro QR variant:
- Validates MQR mode, version 1–4, EC level L through Q
- Uses `MQRRawCode` instead of `QRRawCode`
- Handles `oddbits` — the last data byte may have fewer than 8 significant bits
- Uses `MMask_mask()` / `MMask_makeMask()` for the 4-pattern MQR masking
- Sets FrameFiller's `mqr` flag to 1 (no column-6 skip)

#### High-Level Encoding Functions

`QRcode_encodeInput()` simply dispatches based on the `mqr` flag:
```c
QRcode *QRcode_encodeInput(QRinput *input)
{
    if(input->mqr) {
        return QRcode_encodeMaskMQR(input, -1);
    } else {
        return QRcode_encodeMask(input, -1);
    }
}
```

`QRcode_encodeStringReal()` is the shared implementation for `QRcode_encodeString()` and `QRcode_encodeStringMQR()`:
1. Creates a `QRinput` (MQR or standard)
2. Calls `Split_splitStringToQRinput()` for automatic mode optimization
3. Calls `QRcode_encodeInput()`

For MQR, `QRcode_encodeStringMQR()` tries each version from the minimum up to 4:
```c
for(i = version; i <= MQRSPEC_VERSION_MAX; i++) {
    QRcode *code = QRcode_encodeStringReal(string, i, level, 1, hint, casesensitive);
    if(code != NULL) return code;
}
```

#### Structured Append

`QRcode_encodeInputStructured()` encodes each `QRinput` in a `QRinput_Struct` and builds a `QRcode_List` linked list.

`QRcode_encodeStringStructured()` and variants auto-split the input, insert structured append headers, encode each part, and return the linked list.

---

### `qrinput.h` / `qrinput.c` — Input Data Management

This module manages the input data pipeline from raw user data to a padded byte stream ready for RS encoding.

#### Internal Structures

```c
// A linked list entry for one data chunk
struct _QRinput_List {
    QRencodeMode mode;     // encoding mode
    int size;              // data size in bytes
    unsigned char *data;   // data chunk
    BitStream *bstream;    // encoded bit stream (created during encoding)
    QRinput_List *next;    // next chunk
};

// The main input object
struct _QRinput {
    int version;
    QRecLevel level;
    QRinput_List *head;    // first data chunk
    QRinput_List *tail;    // last data chunk
    int mqr;               // 1 if Micro QR mode
    int fnc1;              // FNC1 mode flag
    unsigned char appid;   // FNC1 application ID
};

// Structured append management
struct _QRinput_Struct {
    int size;              // number of symbols
    int parity;            // parity byte
    QRinput_InputList *head;
    QRinput_InputList *tail;
};
```

#### Mode Encoding Functions

Each encoding mode has three functions in `qrinput.c`:

1. **Check function** — Validates input data for the mode
2. **Estimate function** — Estimates bit count without actually encoding
3. **Encode function** — Produces the actual bit stream

##### Numeric Mode (`QRinput_encodeModeNum`)

Encodes digits in groups:
- 3 digits → 10 bits (values 000–999)
- 2 remaining digits → 7 bits
- 1 remaining digit → 4 bits

```c
int QRinput_estimateBitsModeNum(int size)
{
    int w = size / 3;
    int bits = w * 10;
    switch(size - w * 3) {
        case 1: bits += 4; break;
        case 2: bits += 7; break;
    }
    return bits;
}
```

##### Alphanumeric Mode (`QRinput_encodeModeAn`)

Uses the 45-character lookup table `QRinput_anTable[128]`:
- Pairs → 11 bits (value = c1 × 45 + c2)
- Odd character → 6 bits

The table maps: 0-9 → 0-9, A-Z → 10-35, space → 36, $ → 37, % → 38, * → 39, + → 40, - → 41, . → 42, / → 43, : → 44.

The lookup macro:
```c
#define QRinput_lookAnTable(__c__) \
    ((__c__ & 0x80)?-1:QRinput_anTable[(int)__c__])
```

##### 8-Bit Mode (`QRinput_encodeMode8`)

Each byte → 8 bits, using `BitStream_appendBytes()`.

##### Kanji Mode (`QRinput_encodeModeKanji`)

Shift-JIS double-byte characters are compressed:
1. If code ≤ 0x9FFC: subtract 0x8140
2. If code > 0x9FFC: subtract 0xC140
3. High byte × 0xC0 + low byte → 13-bit value

Validation in `QRinput_checkModeKanji()`:
```c
if(val < 0x8140 || (val > 0x9ffc && val < 0xe040) || val > 0xebbf) {
    return -1;
}
```

##### ECI Mode (`QRinput_encodeModeECI`)

ECI indicator encoding (per JIS X0510:2004, Table 4):
- 0–127: 1 byte (8 bits)
- 128–16383: 2 bytes (16 bits, prefix 0x8000)
- 16384–999999: 3 bytes (24 bits, prefix 0xC0000)

##### Structured Append Header

20-bit header: 4 bits mode indicator + 4 bits symbol count + 4 bits symbol index + 8 bits parity.

##### FNC1 Second Position

4-bit mode indicator + 8-bit application ID.

#### Bit Stream Construction Pipeline

The conversion from input chunks to a byte stream follows this call chain:

```
QRinput_getByteStream()
    └── QRinput_getBitStream()
            ├── QRinput_convertData()    [for standard QR]
            │       ├── QRinput_estimateVersion()
            │       │       └── QRinput_estimateBitStreamSize()
            │       │               └── QRinput_estimateBitStreamSizeOfEntry() × N
            │       └── QRinput_createBitStream()
            │               └── QRinput_encodeBitStream() × N
            │                       └── QRinput_encodeMode{Num,An,8,Kanji,...}()
            ├── QRinput_appendPaddingBit()    [for standard QR]
            └── QRinput_appendPaddingBitMQR() [for Micro QR]
                    └── BitStream_toByte()
```

`QRinput_convertData()` handles version auto-selection with a convergence loop:
```c
for(;;) {
    BitStream_reset(bstream);
    bits = QRinput_createBitStream(input, bstream);
    ver = QRspec_getMinimumVersion((bits + 7) / 8, input->level);
    if(ver > QRinput_getVersion(input)) {
        QRinput_setVersion(input, ver);
    } else {
        break;
    }
}
```

`QRinput_encodeBitStream()` handles entry splitting when data exceeds `QRspec_maximumWords()`:
```c
if(words != 0 && entry->size > words) {
    st1 = QRinput_List_newEntry(entry->mode, words, entry->data);
    st2 = QRinput_List_newEntry(entry->mode, entry->size - words, &entry->data[words]);
    QRinput_encodeBitStream(st1, bstream, version, mqr);
    QRinput_encodeBitStream(st2, bstream, version, mqr);
}
```

Padding appends:
1. Terminator (up to 4 zero bits)
2. Byte-alignment zeros
3. Alternating pad codewords: `0xEC`, `0x11`, `0xEC`, `0x11`, ...

---

### `bitstream.h` / `bitstream.c` — Binary Sequence Class

A dynamic bit array class used throughout the encoding pipeline.

```c
typedef struct {
    size_t length;     // current number of bits
    size_t datasize;   // allocated buffer size
    unsigned char *data; // one byte per bit (0 or 1)
} BitStream;
```

**Critical design choice:** Each bit occupies one byte in memory. This simplifies bit manipulation at the cost of memory. The buffer starts at `DEFAULT_BUFSIZE` (128) and doubles on demand via `BitStream_expand()`.

Key operations:

| Function | Description |
|---|---|
| `BitStream_new()` | Allocate with 128-byte initial buffer |
| `BitStream_append(dst, src)` | Append another BitStream |
| `BitStream_appendNum(bs, bits, num)` | Append `bits` bits of integer `num` |
| `BitStream_appendBytes(bs, size, data)` | Append `size` bytes (8 bits each) |
| `BitStream_toByte(bs)` | Pack bit array into byte array |
| `BitStream_free(bs)` | Free all memory |

Macros:
```c
#define BitStream_size(__bstream__) (__bstream__->length)
#define BitStream_reset(__bstream__) (__bstream__->length = 0)
```

`BitStream_toByte()` packs the 1-byte-per-bit representation into a proper byte array:
```c
for(i = 0; i < bytes; i++) {
    v = 0;
    for(j = 0; j < 8; j++) {
        v = (unsigned char)(v << 1);
        v |= *p;
        p++;
    }
    data[i] = v;
}
```

---

### `qrspec.h` / `qrspec.c` — QR Code Specification Tables

Contains all specification-derived data tables and frame construction for full QR Codes.

#### Capacity Table

```c
typedef struct {
    int width;
    int words;
    int remainder;
    int ec[4];
} QRspec_Capacity;

static const QRspec_Capacity qrspecCapacity[QRSPEC_VERSION_MAX + 1];
```

Sourced from Table 1 (p.13) and Tables 12–16 (pp.30–36) of JIS X0510:2004.

#### Length Indicator Table

```c
static const int lengthTableBits[4][3] = {
    {10, 12, 14},  // Numeric
    { 9, 11, 13},  // Alphanumeric
    { 8, 16, 16},  // 8-bit
    { 8, 10, 12}   // Kanji
};
```

Three version ranges: 1–9, 10–26, 27–40.

#### ECC Block Specification Table

```c
static const int eccTable[QRSPEC_VERSION_MAX+1][4][2];
```

Each entry `eccTable[version][level]` gives `{type1_blocks, type2_blocks}`. Combined with `QRspec_getEccSpec()` to produce the 5-element spec array:

```c
void QRspec_getEccSpec(int version, QRecLevel level, int spec[5])
```

Where `spec` = `{num_type1_blocks, type1_data_codes, ecc_codes_per_block, num_type2_blocks, type2_data_codes}`.

Accessor macros:
```c
#define QRspec_rsBlockNum(__spec__)      (__spec__[0] + __spec__[3])
#define QRspec_rsBlockNum1(__spec__)     (__spec__[0])
#define QRspec_rsDataCodes1(__spec__)    (__spec__[1])
#define QRspec_rsEccCodes1(__spec__)     (__spec__[2])
#define QRspec_rsBlockNum2(__spec__)     (__spec__[3])
#define QRspec_rsDataCodes2(__spec__)    (__spec__[4])
#define QRspec_rsEccCodes2(__spec__)     (__spec__[2])
```

Note: type-1 and type-2 blocks share the same ECC code count.

#### Alignment Pattern Table

```c
static const int alignmentPattern[QRSPEC_VERSION_MAX+1][2];
```

From Table 1 in Appendix E (p.71). Stores the second and third alignment pattern positions; remaining positions are interpolated.

`QRspec_putAlignmentPattern()` places all alignment markers, computing positions from the stored two values and the inter-pattern distance.

#### Version Information Pattern

```c
static const unsigned int versionPattern[QRSPEC_VERSION_MAX - 6];
```

BCH-encoded version information for versions 7–40. From Appendix D (p.68).

#### Format Information

```c
static const unsigned int formatInfo[4][8];
```

BCH-encoded format information indexed by `[level][mask]`.

#### Frame Creation (`QRspec_createFrame`)

Builds the initial symbol frame for a given version:

1. Allocates `width × width` bytes, zeroed
2. Places **3 finder patterns** (7×7, `0xC1`/`0xC0` pattern) at corners
3. Places **separators** (1-module-wide white border around finders, `0xC0`)
4. Masks **format information area** (9+8 modules around finder, `0x84`)
5. Places **timing patterns** (alternating `0x91`/`0x90` along row 6 and column 6)
6. Places **alignment patterns** (5×5, `0xA1`/`0xA0` pattern)
7. For versions ≥ 7: places **version information** (6×3 blocks, `0x88`/`0x89`)
8. Sets the **dark module** at position `(8, width-8)` to `0x81`

All function pattern modules have bit 7 set (`0x80`), so the FrameFiller skips them during data placement.

---

### `mqrspec.h` / `mqrspec.c` — Micro QR Specification Tables

Parallel to `qrspec.c` but for Micro QR (versions M1–M4).

```c
typedef struct {
    int width;
    int ec[4];
} MQRspec_Capacity;

static const MQRspec_Capacity mqrspecCapacity[MQRSPEC_VERSION_MAX + 1] = {
    {  0, {0,  0,  0, 0}},
    { 11, {2,  0,  0, 0}},   // M1
    { 13, {5,  6,  0, 0}},   // M2
    { 15, {6,  8,  0, 0}},   // M3
    { 17, {8, 10, 14, 0}}    // M4
};
```

Notable difference: `MQRspec_getDataLengthBit()` returns data capacity in **bits** (not bytes), because Micro QR symbols can have non-byte-aligned data areas:
```c
int MQRspec_getDataLengthBit(int version, QRecLevel level)
{
    int w = mqrspecCapacity[version].width - 1;
    int ecc = mqrspecCapacity[version].ec[level];
    if(ecc == 0) return 0;
    return w * w - 64 - ecc * 8;
}
```

The data length in bytes rounds up: `(bits + 4) / 8`.

#### Micro QR Frame Creation

`MQRspec_createFrame()` is simpler than the full QR version:
- Only **1 finder pattern** (top-left)
- No alignment patterns
- No version information
- Timing patterns run along one row and one column from the finder

#### Format Info Type Table

```c
static const int typeTable[MQRSPEC_VERSION_MAX + 1][3] = {
    {-1, -1, -1},
    { 0, -1, -1},   // M1: only error detection
    { 1,  2, -1},   // M2: L, M
    { 3,  4, -1},   // M3: L, M
    { 5,  6,  7}    // M4: L, M, Q
};
```

Maps `(version, level)` → format info table index. Returns -1 for unsupported combinations.

---

### `rsecc.h` / `rsecc.c` — Reed-Solomon Error Correction

Contains the GF(2^8) arithmetic and RS encoding for QR Codes.

Single public function:
```c
int RSECC_encode(size_t data_length, size_t ecc_length,
                 const unsigned char *data, unsigned char *ecc);
```

Internal state:
- `alpha[256]` — Power-to-element mapping (logarithm table)
- `aindex[256]` — Element-to-power mapping (antilogarithm table)
- `generator[29][31]` — Cached generator polynomials for ECC lengths 2–30
- `generatorInitialized[29]` — Whether each generator has been computed

Lazy initialization via `RSECC_init()` and `generator_init()`, protected by `RSECC_mutex` when pthreads are available.

The primitive polynomial is `0x11d` = $x^8 + x^4 + x^3 + x^2 + 1$, per JIS X0510:2004 p.37.

See [reed-solomon.md](reed-solomon.md) for detailed implementation analysis.

---

### `split.h` / `split.c` — Input String Splitter

Automatically parses an input string and splits it into optimal encoding mode segments.

Entry point:
```c
int Split_splitStringToQRinput(const char *string, QRinput *input,
                               QRencodeMode hint, int casesensitive);
```

Key functions:
- `Split_identifyMode()` — Classifies a character: digit → `QR_MODE_NUM`, AN table match → `QR_MODE_AN`, Shift-JIS → `QR_MODE_KANJI`, else → `QR_MODE_8`
- `Split_eatNum()` — Consumes a run of numeric characters, considers switching to AN or 8-bit if more efficient
- `Split_eatAn()` — Consumes alphanumeric characters, embedded digit runs tested for mode-switch optimization
- `Split_eatKanji()` — Consumes pairs of Kanji bytes
- `Split_eat8()` — Consumes 8-bit characters, tests for switching to NUM or AN when sub-runs are encountered

The optimization logic compares bit costs: each `Split_eat*` function calculates `dif` — the bit savings of staying in the current mode vs. switching. Example from `Split_eatNum()`:

```c
dif = QRinput_estimateBitsModeNum(run) + 4 + ln
    + QRinput_estimateBitsMode8(1)
    - QRinput_estimateBitsMode8(run + 1);
if(dif > 0) {
    return Split_eat8(string, input, hint);
}
```

Case conversion (when `casesensitive=0`) is handled by `dupAndToUpper()`, which converts lowercase to uppercase while preserving Kanji double-byte sequences.

---

### `mask.h` / `mask.c` — QR Code Masking

Implements the 8 mask patterns for full QR Code and the penalty evaluation algorithm.

#### Mask Patterns

All 8 patterns are defined via the `MASKMAKER` macro:

```c
#define MASKMAKER(__exp__) \
    int x, y;\
    int b = 0;\
    for(y = 0; y < width; y++) {\
        for(x = 0; x < width; x++) {\
            if(*s & 0x80) {\
                *d = *s;\
            } else {\
                *d = *s ^ ((__exp__) == 0);\
            }\
            b += (int)(*d & 1);\
            s++; d++;\
        }\
    }\
    return b;
```

The 8 mask functions:

| Pattern | Function | Condition (dark if true) |
|---|---|---|
| 0 | `Mask_mask0` | `(x+y) % 2 == 0` |
| 1 | `Mask_mask1` | `y % 2 == 0` |
| 2 | `Mask_mask2` | `x % 3 == 0` |
| 3 | `Mask_mask3` | `(x+y) % 3 == 0` |
| 4 | `Mask_mask4` | `((y/2)+(x/3)) % 2 == 0` |
| 5 | `Mask_mask5` | `(x*y)%2 + (x*y)%3 == 0` |
| 6 | `Mask_mask6` | `((x*y)%2 + (x*y)%3) % 2 == 0` |
| 7 | `Mask_mask7` | `((x*y)%3 + (x+y)%2) % 2 == 0` |

Function pointer array: `static MaskMaker *maskMakers[8]`

#### Penalty Evaluation

`Mask_mask()` tries all 8 masks and selects the one with the lowest penalty:

```c
for(i = 0; i < maskNum; i++) {
    penalty = 0;
    blacks = maskMakers[i](width, frame, mask);
    blacks += Mask_writeFormatInformation(width, mask, i, level);
    bratio = (200 * blacks + w2) / w2 / 2;
    penalty = (abs(bratio - 50) / 5) * N4;
    penalty += Mask_evaluateSymbol(width, mask);
    if(penalty < minPenalty) {
        minPenalty = penalty;
        memcpy(bestMask, mask, w2);
    }
}
```

Penalty constants from JIS X0510:2004, Section 8.8.2:
```c
#define N1 (3)   // Run penalty base
#define N2 (3)   // 2×2 block penalty
#define N3 (40)  // Finder-like pattern penalty
#define N4 (10)  // Proportion penalty per 5% deviation
```

See [masking-algorithms.md](masking-algorithms.md) for detailed penalty calculation analysis.

---

### `mmask.h` / `mmask.c` — Micro QR Masking

Implements 4 mask patterns for Micro QR Code with a different evaluation algorithm.

The 4 patterns:

| Pattern | Condition |
|---|---|
| 0 | `y % 2 == 0` |
| 1 | `((y/2)+(x/3)) % 2 == 0` |
| 2 | `((x*y)%2 + (x*y)%3) % 2 == 0` |
| 3 | `((x+y)%2 + (x*y)%3) % 2 == 0` |

The Micro QR evaluation in `MMask_evaluateSymbol()` uses a completely different approach from full QR:
```c
STATIC_IN_RELEASE int MMask_evaluateSymbol(int width, unsigned char *frame)
{
    int x, y;
    unsigned char *p;
    int sum1 = 0, sum2 = 0;

    p = frame + width * (width - 1);
    for(x = 1; x < width; x++) {
        sum1 += (p[x] & 1);
    }

    p = frame + width * 2 - 1;
    for(y = 1; y < width; y++) {
        sum2 += (*p & 1);
        p += width;
    }

    return (sum1 <= sum2)?(sum1 * 16 + sum2):(sum2 * 16 + sum1);
}
```

Instead of penalties, it counts dark modules on the bottom row and right column, then selects the mask with the **highest** score (not lowest).

---

## Data Flow: Complete Encoding Pipeline

Here is the detailed function call chain for encoding a string:

```
QRcode_encodeString("Hello", 0, QR_ECLEVEL_M, QR_MODE_8, 1)
  │
  └── QRcode_encodeStringReal("Hello", 0, QR_ECLEVEL_M, 0, QR_MODE_8, 1)
        │
        ├── QRinput_new2(0, QR_ECLEVEL_M)
        │     └── allocate QRinput {version=0, level=M, mqr=0}
        │
        ├── Split_splitStringToQRinput("Hello", input, QR_MODE_8, 1)
        │     └── Split_splitString("Hello", input, QR_MODE_8)
        │           ├── Split_identifyMode("H") → QR_MODE_AN
        │           └── Split_eatAn("Hello", ...)
        │                 └── QRinput_append(input, QR_MODE_AN, 5, "Hello")
        │
        └── QRcode_encodeInput(input)
              │
              └── QRcode_encodeMask(input, -1)
                    │
                    ├── QRraw_new(input)
                    │     ├── QRinput_getByteStream(input)
                    │     │     ├── QRinput_convertData() — version auto-select
                    │     │     ├── QRinput_createBitStream() — encode each chunk
                    │     │     ├── QRinput_appendPaddingBit() — terminator + padding
                    │     │     └── BitStream_toByte() — pack bits to bytes
                    │     │
                    │     ├── QRspec_getEccSpec(version, level, spec)
                    │     └── RSblock_init() → RSECC_encode() per block
                    │
                    ├── QRspec_newFrame(version)
                    │     └── QRspec_createFrame() — finder, timing, alignment
                    │
                    ├── FrameFiller placement loop
                    │     └── FrameFiller_next() × (dataLength + eccLength) × 8
                    │
                    └── Mask_mask(width, frame, level)
                          ├── maskMakers[0..7]() — apply each pattern
                          ├── Mask_writeFormatInformation() — embed format info
                          ├── Mask_evaluateSymbol() — penalty calculation
                          │     ├── Mask_calcN2() — 2×2 blocks
                          │     ├── Mask_calcRunLengthH() — horizontal runs
                          │     ├── Mask_calcRunLengthV() — vertical runs
                          │     └── Mask_calcN1N3() — run + finder penalties
                          └── select minimum penalty mask
```

---

## STATIC_IN_RELEASE Pattern

The codebase uses the `STATIC_IN_RELEASE` macro to control visibility:

```c
// When WITH_TESTS is defined:
#define STATIC_IN_RELEASE

// When WITH_TESTS is not defined:
#define STATIC_IN_RELEASE static
```

Functions marked `STATIC_IN_RELEASE` (like `QRraw_new`, `QRcode_encodeMask`, `Mask_evaluateSymbol`) are `static` in release builds and externally visible in test builds. Similarly, `#ifdef WITH_TESTS` blocks expose additional test-only functions.

---

## Memory Management

The library follows a consistent pattern:
- All allocation uses `malloc()`/`calloc()`/`realloc()`
- Every `_new()` function has a corresponding `_free()` function
- On allocation failure, functions return `NULL` and set `errno`
- `QRcode_free()` frees both the `QRcode` struct and its internal `data` array
- `QRinput_free()` walks the linked list and frees each entry
- `BitStream_free()` frees the data buffer and the struct

No memory pools or custom allocators are used.

---

## Error Handling

Errors are reported via return values and `errno`:

| Error | Meaning |
|---|---|
| `EINVAL` | Invalid argument (bad version, level, mode, or data) |
| `ENOMEM` | Memory allocation failure |
| `ERANGE` | Input data too large for any supported version |

Functions returning pointers return `NULL` on error. Functions returning `int` return `-1` on error and `0` on success. The only exception is `QRraw_getCode()` which returns `0` when the code stream is exhausted.