Viewing is open to everyone. Downloading and starring need a GitHub sign-in.
Sign in with GitHub
CKey-Format-v0.28.0.md
v0.1.0-build.85
Latest
Commit ede38f5
Sign in with GitHub to download. Each download is recorded with your GitHub username.
| 1 | # CKey Format v0.28.0 — Profile 0.1: the print-robust layout |
| 2 | |
| 3 | Status: draft. Added alongside Profile 0 (Format 0.27), which is unchanged. |
| 4 | |
| 5 | Encoders emit frame format byte `0x1C` (decimal 28), profile byte `0x00`. The layout family is the print family (`CKEY_LAYOUT_PRINT`). |
| 6 | |
| 7 | ## Why this layout exists |
| 8 | |
| 9 | Profile 0's polar field is finer than its modules. Rays are 0.2 module wide, ring dots 0.4 module across, and ring slots are as little as 0.3 module apart on the inner rings. Printed small, those marks are the first to go: |
| 10 | |
| 11 | - **Dark ink on paper:** ink spread merges neighbouring ring dots. |
| 12 | - **Inked background:** spread closes the light rays. |
| 13 | |
| 14 | Profile 0.1 keeps every mark and every gap at **about one module or more**. The module can then shrink to whatever the printer and camera allow. In print simulations, the same payload prints at roughly half Profile 0's width (see "Measured" below). |
| 15 | |
| 16 | ## Differences from Format 0.27 |
| 17 | |
| 18 | Everything not listed here is identical to Format 0.27: the skeleton, frame, finders, Grid Key, version table G(v), safe-area rule, Reed–Solomon framing and levels, header layout, and interleaving. |
| 19 | |
| 20 | | | Format 0.27 (P0) | Format 0.28 (P0.1) | |
| 21 | |---|---|---| |
| 22 | | Ring radial pitch | 0.86p | **1.0p** | |
| 23 | | Rings R(v) | table in 0.27 | **2 3 3 3 4 4 4 5 5 6 7 7 8 8 9 10 11 12 13 14 15 16 17 19 20 22 24 25 27 29 32** (= ⌊(4.2 − 2.4p)/p⌋ + 1) | |
| 24 | | Slots per ring | one count S for all rings | **equal arc:** ring k at radius r gets 8·⌊2πr/(8p)⌋ slots, so dots are at least one module apart on every ring | |
| 25 | | Ring dot radius | 0.2p | **0.3p** | |
| 26 | | Dial slots | S (≈ 72/p) | **8·⌊2π·7.6/(8p)⌋** (≈ 48/p; rays at least one module apart) | |
| 27 | | Dial ray width | 0.2p | **0.35p** | |
| 28 | | Long / short ray | 2.2p / 1.0p | **2.4p** / 1.0p | |
| 29 | | Data ray outer ink (for the safe area) | 7.6 + 2.3p | 7.6 + 2.575p | |
| 30 | | Ray-Key bearings on rings | ring slots cleared on the three Ray Key slots | **not cleared**: rings have their own slot counts | |
| 31 | | Ring Key | 16 slots: dots K, K+2, K+6; run K+7.5…K+15.5 | **8 slots:** dots K, K+2; run K+3.5…K+7.5 | |
| 32 | | Grid Key, v1 | row 10 | **row 9**, giving the longer rays a pitch of clearance | |
| 33 | | Placement key / whitening seed | `0x434B5030` / `0x434B5730` + v | **`0x434B5031` / `0x434B5731` + v** | |
| 34 | | Frame format byte | `1B` | **`1C`** | |
| 35 | |
| 36 | **Normative and derived values:** |
| 37 | |
| 38 | - **The ring-count table is normative.** For some versions it lands exactly on an integer boundary, so implementations must use the table. |
| 39 | - **Slot counts are derived** and decided with at least 0.002 slack, so independent implementations agree. |
| 40 | |
| 41 | **Ink-to-ink gaps** in every version: ring dots at least 0.39p along and across rings, and dial rays at least 0.6p apart. The test suite checks both. |
| 42 | |
| 43 | ## Capacity (payload bytes) |
| 44 | |
| 45 | | v | Modules across | L | M | Q | H | |
| 46 | |---|---|---|---|---|---| |
| 47 | | 1 | 29 | 11 | 7 | 3 | 0 | |
| 48 | | 2 | 31 | 21 | 17 | 9 | 3 | |
| 49 | | 3 | 33 | 31 | 23 | 15 | 7 | |
| 50 | | 4 | 36 | 35 | 27 | 19 | 9 | |
| 51 | | 5 | 38 | 46 | 36 | 26 | 16 | |
| 52 | | 6 | 41 | 62 | 50 | 36 | 22 | |
| 53 | | 7 | 44 | 75 | 61 | 45 | 29 | |
| 54 | | 8 | 47 | 98 | 80 | 60 | 40 | |
| 55 | | 9 | 50 | 116 | 96 | 72 | 48 | |
| 56 | | 10 | 54 | 152 | 124 | 94 | 64 | |
| 57 | | 11 | 58 | 191 | 157 | 119 | 81 | |
| 58 | | 12 | 62 | 221 | 185 | 141 | 97 | |
| 59 | | 13 | 67 | 274 | 230 | 174 | 122 | |
| 60 | | 14 | 71 | 295 | 245 | 189 | 131 | |
| 61 | | 15 | 77 | 367 | 303 | 235 | 163 | |
| 62 | | 16 | 82 | 433 | 361 | 277 | 193 | |
| 63 | | 17 | 88 | 518 | 428 | 332 | 232 | |
| 64 | | 18 | 94 | 608 | 506 | 392 | 278 | |
| 65 | | 19 | 101 | 694 | 574 | 446 | 314 | |
| 66 | | 20 | 108 | 814 | 678 | 526 | 374 | |
| 67 | | 21 | 116 | 958 | 798 | 618 | 438 | |
| 68 | | 22 | 124 | 1076 | 900 | 696 | 496 | |
| 69 | | 23 | 133 | 1272 | 1056 | 816 | 588 | |
| 70 | | 24 | 143 | 1504 | 1266 | 978 | 692 | |
| 71 | | 25 | 153 | 1705 | 1423 | 1103 | 783 | |
| 72 | | 26 | 164 | 2017 | 1677 | 1299 | 919 | |
| 73 | | 27 | 176 | 2318 | 1944 | 1504 | 1064 | |
| 74 | | 28 | 188 | 2655 | 2235 | 1719 | 1225 | |
| 75 | | 29 | 202 | 3056 | 2576 | 1990 | 1420 | |
| 76 | | 30 | 216 | 3564 | 2986 | 2306 | 1648 | |
| 77 | | 31 | 232 | 4123 | 3453 | 2679 | 1919 | |
| 78 | |
| 79 | ## Reading |
| 80 | |
| 81 | The decoder tests both layout families' key patterns (Grid, Ring and Ray Keys at each version's own pitch), so the family is identified the same way the version is. The frame's format byte confirms it. In the test suite, all 31 Profile 0.1 versions decode at 6 px per module and are identified as Profile 0.1. |
| 82 | |
| 83 | ## Measured (simulation, informative) |
| 84 | |
| 85 | The print model is binary device dots, ink spread (dot gain), paper blur, then a camera of a given resolution, then the decoder. The table gives the smallest width that decodes reliably at level M, P0 → P0.1: |
| 86 | |
| 87 | | Payload | Old inkjet, plain paper | Inkjet, photo paper | Weaker camera (12 px/mm), plain paper | |
| 88 | |---|---|---|---| |
| 89 | | 8 B | 0.38 → 0.19 in | 0.21 → ≤ 0.15 in | 0.47 → 0.24 in | |
| 90 | | 30 B | 0.42 → 0.24 in | 0.29 → ≤ 0.15 in | 0.56 → 0.29 in | |
| 91 | | 120 B | 0.68 → 0.32 in | 0.38 → 0.21 in | 0.68 → 0.42 in | |
| 92 | | 400 B | 0.91 → 0.56 in | 0.62 → 0.38 in | 1.22 → 0.75 in | |
| 93 | | 1,200 B | 1.47 → 0.91 in | 1.11 → 0.56 in | 1.78 → 1.22 in | |
| 94 | | 2,400 B | 2.37 → 1.34 in | 1.34 → 0.83 in | 2.61 → 1.62 in | |
| 95 | |
| 96 | The model's parameters: |
| 97 | |
| 98 | - **Old inkjet, plain paper:** 600 dpi, 0.045 mm spread. |
| 99 | - **Photo paper:** 1,200 dpi, 0.015 mm spread. |
| 100 | - **Camera:** 23 px/mm with 0.7 px blur. |
| 101 | |
| 102 | These are estimates. `ckey print-sheet` produces the calibration ladder that replaces them with measurements. |
| 103 | |
| 104 | ## Conformance vectors |
| 105 | |
| 106 | FNV-1a-64 over every site in placement order of (identity little-endian, printed value), for payload `"CKey renderer test"` at level M: |
| 107 | |
| 108 | | Version | Hash | |
| 109 | |---|---| |
| 110 | | v3 | `1908543413F369B8` | |
| 111 | | v31 | `684C56624D3558A8` | |