codarascan 0.1.2__tar.gz → 0.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. {codarascan-0.1.2 → codarascan-0.2.0}/CHANGELOG.md +18 -0
  2. {codarascan-0.1.2 → codarascan-0.2.0}/PKG-INFO +24 -16
  3. {codarascan-0.1.2 → codarascan-0.2.0}/README.md +23 -15
  4. {codarascan-0.1.2 → codarascan-0.2.0}/THIRD_PARTY_NOTICES.md +1 -1
  5. {codarascan-0.1.2 → codarascan-0.2.0}/docs/API.md +7 -4
  6. {codarascan-0.1.2 → codarascan-0.2.0}/docs/COMPATIBILITY.md +1 -1
  7. {codarascan-0.1.2 → codarascan-0.2.0}/docs/KNOWN_LIMITATIONS.md +2 -2
  8. {codarascan-0.1.2 → codarascan-0.2.0}/docs/RELEASE.md +13 -8
  9. codarascan-0.2.0/docs/RELEASE_EVIDENCE_0.1.2.md +141 -0
  10. {codarascan-0.1.2 → codarascan-0.2.0}/pyproject.toml +1 -1
  11. {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/__init__.py +1 -1
  12. {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/cli.py +3 -1
  13. {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/documents.py +1 -1
  14. {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/__init__.py +1 -1
  15. {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/catalog.py +7 -1
  16. {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/common/__init__.py +1 -1
  17. codarascan-0.2.0/src/codarascan/engines/panorama/__init__.py +6 -0
  18. codarascan-0.2.0/src/codarascan/engines/panorama/extraction.py +705 -0
  19. codarascan-0.2.0/src/codarascan/engines/panorama/reconciliation.py +689 -0
  20. {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/registry.py +4 -1
  21. {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/inputs.py +5 -0
  22. {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/models.py +38 -26
  23. {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/scanner.py +13 -7
  24. {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/schemas/result.decoded.example.json +2 -4
  25. {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/schemas/result.localized.example.json +2 -4
  26. {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/schemas/result.schema.json +3 -5
  27. {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/schemas/stream.example.json +2 -2
  28. {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/schemas/stream.schema.json +2 -2
  29. {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan.egg-info/PKG-INFO +24 -16
  30. {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan.egg-info/SOURCES.txt +4 -0
  31. {codarascan-0.1.2 → codarascan-0.2.0}/CONTRIBUTING.md +0 -0
  32. {codarascan-0.1.2 → codarascan-0.2.0}/LICENSE +0 -0
  33. {codarascan-0.1.2 → codarascan-0.2.0}/MANIFEST.in +0 -0
  34. {codarascan-0.1.2 → codarascan-0.2.0}/MIGRATION.md +0 -0
  35. {codarascan-0.1.2 → codarascan-0.2.0}/NOTICE +0 -0
  36. {codarascan-0.1.2 → codarascan-0.2.0}/SECURITY.md +0 -0
  37. {codarascan-0.1.2 → codarascan-0.2.0}/docs/RELEASE_EVIDENCE_0.1.0.md +0 -0
  38. {codarascan-0.1.2 → codarascan-0.2.0}/docs/WORKER_PROTOCOL.md +0 -0
  39. {codarascan-0.1.2 → codarascan-0.2.0}/setup.cfg +0 -0
  40. {codarascan-0.1.2 → codarascan-0.2.0}/setup.py +0 -0
  41. {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/core/__init__.py +0 -0
  42. {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/core/contracts.py +0 -0
  43. {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/common/base.py +0 -0
  44. {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/common/classical_2d.py +0 -0
  45. {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/common/classical_2d_extractor.py +0 -0
  46. {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/common/classical_2d_localizer.py +0 -0
  47. {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/common/classical_localizer.py +0 -0
  48. {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/common/detection_classical_2d.py +0 -0
  49. {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/common/detection_sttg.py +0 -0
  50. {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/common/extraction_classical_2d.py +0 -0
  51. {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/common/extraction_vendored.py +0 -0
  52. {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/common/linear_recovery.py +0 -0
  53. {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/common/linear_review_gate_v2.py +0 -0
  54. {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/common/linear_review_gate_v3.py +0 -0
  55. {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/common/native/__init__.py +0 -0
  56. {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/common/native/loader.py +0 -0
  57. {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/common/native/sttg_localizer.py +0 -0
  58. {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/common/native/sttg_native.cpp +0 -0
  59. {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/common/pdfium_pages.py +0 -0
  60. {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/common/recovery/__init__.py +0 -0
  61. {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/common/recovery/adaptive.py +0 -0
  62. {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/common/recovery/hybrid.py +0 -0
  63. {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/common/recovery/locator.py +0 -0
  64. {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/common/recovery/matrix.py +0 -0
  65. {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/common/recovery/runtime.py +0 -0
  66. {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/common/recovery/zxing.py +0 -0
  67. {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/common/review_gate.py +0 -0
  68. {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/common/tensor_decode.py +0 -0
  69. {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/common/tensor_decoder.py +0 -0
  70. {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/common/tensor_localizer.py +0 -0
  71. {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/common/vendored_decoder.py +0 -0
  72. {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/mosaic/__init__.py +0 -0
  73. {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/mosaic/detection.py +0 -0
  74. {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/mosaic/extraction.py +0 -0
  75. {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/tessera/__init__.py +0 -0
  76. {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/tessera/detection.py +0 -0
  77. {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/engines/tessera/extraction.py +0 -0
  78. {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/errors.py +0 -0
  79. {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/formats.py +0 -0
  80. {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/py.typed +0 -0
  81. {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/schemas/worker.schema.json +0 -0
  82. {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/serialization.py +0 -0
  83. {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan/worker.py +0 -0
  84. {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan.egg-info/dependency_links.txt +0 -0
  85. {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan.egg-info/entry_points.txt +0 -0
  86. {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan.egg-info/requires.txt +0 -0
  87. {codarascan-0.1.2 → codarascan-0.2.0}/src/codarascan.egg-info/top_level.txt +0 -0
@@ -3,6 +3,24 @@
3
3
  All notable changes are recorded here. CodaraScan follows semantic versioning
4
4
  after 1.0; during 0.x, breaking changes are identified explicitly.
5
5
 
6
+ ## 0.2.0 - 2026-09-07
7
+
8
+ - Add the Panorama high-recall extraction engine and public
9
+ `Scanner(mode="panorama")` API. Panorama reconciles complementary Tessera,
10
+ whole-page ZXing, split-guard, and failure-tolerant Mosaic results.
11
+ - Preserve `high-recall-extractor` as an input alias for
12
+ `panorama-extractor` while exposing only the new canonical identity.
13
+
14
+ ## 0.1.3 - 2026-08-10
15
+
16
+ - Remove Pillow's process-wide decompression-bomb pixel admission threshold
17
+ before normalizing image inputs, preserving CodaraScan's documented policy
18
+ that callers own resource quotas and admission control.
19
+ - Store analyzed `width` and `height` once on each image or PDF page result
20
+ instead of repeating `image_width` and `image_height` on every serialized
21
+ symbol. Constructor-only dimensions still validate geometry without being
22
+ stored on each `SymbolResult`.
23
+
6
24
  ## 0.1.2 - 2026-08-10
7
25
 
8
26
  - Restrict explicit CLI debug-output directories to mode `0700` and their
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: codarascan
3
- Version: 0.1.2
3
+ Version: 0.2.0
4
4
  Summary: Open-source, offline barcode detection, localization, and decoding for images and PDFs
5
5
  Author-email: Abderraouf FELLAHI <ma_fellahi@esi.dz>
6
6
  License-Expression: Apache-2.0
@@ -73,7 +73,7 @@ For teams looking for a universal barcode detection layer, CodaraScan provides o
73
73
  [Formats](#supported-barcode-formats) · [API reference](https://github.com/flh-raouf/codarascan/blob/main/docs/API.md) ·
74
74
  [PyPI](https://pypi.org/project/codarascan/)
75
75
 
76
- > **Alpha notice — CodaraScan 0.1.2 is alpha software.** Its APIs and schemas
76
+ > **Alpha notice — CodaraScan 0.2.0 is alpha software.** Its APIs and schemas
77
77
  > may change during 0.x. Pin an exact version and evaluate it against your own documents before
78
78
  > production use. See the [known limitations](https://github.com/flh-raouf/codarascan/blob/main/docs/KNOWN_LIMITATIONS.md)
79
79
  > and [release policy](https://github.com/flh-raouf/codarascan/blob/main/docs/RELEASE.md).
@@ -89,8 +89,8 @@ Most barcode libraries focus on decoding a clean, tightly cropped symbol. Docume
89
89
  | Barcode decoding | Returns Unicode text, exact raw payload bytes, and a canonical format name |
90
90
  | Document scanning | Reads selected PDF pages, preserves requested order, and supports bounded parallel work |
91
91
  | Batch processing | Scans complete or selected multi-page PDFs and can stream pages without accumulating them |
92
- | Format coverage | 40 selectable formats: 27 linear and 13 matrix selections in version 0.1.2 |
93
- | Recovery profiles | `fast` Tessera mode for lower latency; `robust` Mosaic mode for stronger recovery |
92
+ | Format coverage | 40 selectable formats: 27 linear and 13 matrix selections in version 0.2.0 |
93
+ | Recovery profiles | `fast` Tessera for lower latency; `robust` Mosaic for stronger recovery; `panorama` for maximum recall |
94
94
  | Local processing | No server, network request, telemetry, external executable, or runtime model download |
95
95
  | Integration | Typed Python API, deterministic JSON, CLI, schemas, and a private persistent worker protocol |
96
96
  | Deployment | Native wheels for supported Linux, macOS, and Windows targets; Python fallback for Tessera |
@@ -116,7 +116,7 @@ python -m pip install codarascan
116
116
  For reproducible alpha deployments, pin the current release:
117
117
 
118
118
  ```bash
119
- python -m pip install codarascan==0.1.2
119
+ python -m pip install codarascan==0.2.0
120
120
  ```
121
121
 
122
122
 
@@ -128,7 +128,7 @@ python -m pip install codarascan==0.1.2
128
128
  from codarascan import DecodedSymbolResult, Scanner
129
129
 
130
130
  scanner = Scanner(
131
- mode="fast", # "fast" (Tessera) or "robust" (Mosaic)
131
+ mode="fast", # "fast" (Tessera), "robust" (Mosaic), or "panorama"
132
132
  symbols="all", # "linear", "2d", or "all"
133
133
  decode=True,
134
134
  )
@@ -267,22 +267,25 @@ A difficult symbol may be localized without being decoded. CodaraScan keeps that
267
267
  | `localized` | Geometry-only result produced with `decode=False` |
268
268
  | `review_candidate` | A barcode-like region was found with weaker evidence and may require human review |
269
269
 
270
- Confidence is an engine-specific evidence score in `[0, 1]`, not a calibrated probability. It is not directly comparable between Tessera and Mosaic. Treat `status` as the primary semantic signal.
270
+ Confidence is an engine-specific evidence score in `[0, 1]`, not a calibrated probability. It is not directly comparable between Tessera, Mosaic, and Panorama. Treat `status` as the primary semantic signal.
271
271
 
272
- ## Fast vs. robust barcode scanning
272
+ ## Choosing a scanning engine
273
273
 
274
- CodaraScan makes the performance/recovery choice explicit. It does not switch engines automatically.
274
+ CodaraScan makes the performance/recovery choice explicit.
275
275
 
276
276
  | Mode | Engine | Best fit | Trade-off |
277
277
  |---|---|---|---|
278
278
  | `mode="fast"` | Tessera | Low-latency document scanning and common workflows | Less exhaustive recovery |
279
279
  | `mode="robust"` | Mosaic | Difficult inputs where stronger recovery is worth more work | Higher CPU time and latency |
280
+ | `mode="panorama"` | Panorama | Maximum-recall extraction and review workflows | Highest CPU time and latency; extraction only |
280
281
 
281
- Start with `fast`, measure on representative inputs, and choose `robust` where it materially improves your corpus. Avoid choosing a mode from synthetic benchmarks alone.
282
+ Start with `fast`, measure on representative inputs, and choose `robust` or
283
+ `panorama` where the additional recovery materially improves your corpus.
284
+ Avoid choosing a mode from synthetic benchmarks alone.
282
285
 
283
286
  ## Supported barcode formats
284
287
 
285
- CodaraScan 0.1.2 exposes **40 selectable barcode formats** generated from the installed ZXing-C++ readable catalog: **27 linear/1D selections** and **13 matrix/2D selections**.
288
+ CodaraScan 0.2.0 exposes **40 selectable barcode formats** generated from the installed ZXing-C++ readable catalog: **27 linear/1D selections** and **13 matrix/2D selections**.
286
289
 
287
290
  ### 1D and linear barcodes
288
291
 
@@ -331,8 +334,11 @@ Every symbol includes:
331
334
  - engine-specific `confidence` and contributing `sources`;
332
335
  - `quad`: four pixel-space points in top-left, top-right, bottom-right,
333
336
  bottom-left order;
334
- - `normalized_quad`: the same four points normalized by image width and height;
335
- - analyzed `image_width` and `image_height`.
337
+ - `normalized_quad`: the same four points normalized by image width and height.
338
+
339
+ Image dimensions are recorded once as `width` and `height` on the containing
340
+ image result. PDF page results record `page`, `width`, and `height` together;
341
+ symbols do not repeat those dimensions.
336
342
 
337
343
  A `DecodedSymbolResult` additionally includes `format`, `text`, its `value`
338
344
  alias, and exact `raw_bytes`.
@@ -380,7 +386,7 @@ Run `codarascan image --help` or `codarascan document --help` for every option.
380
386
 
381
387
  ## Platform support
382
388
 
383
- Official 0.1.2 wheels target:
389
+ Official 0.2.0 wheels target:
384
390
 
385
391
  | Operating system | Architectures | Python |
386
392
  |---|---|---|
@@ -424,12 +430,14 @@ Yes. Barcode detection, decoding, PDF rendering, the CLI, and the worker all run
424
430
 
425
431
  ### Is CodaraScan a universal barcode reader?
426
432
 
427
- It is a multi-format barcode detection layer with 40 selectable 1D and 2D formats in version 0.1.2. No honest scanner can guarantee every barcode under every capture condition, so CodaraScan publishes the exact catalog, evidence, and known limitations instead of making an unlimited compatibility claim.
433
+ It is a multi-format barcode detection layer with 40 selectable 1D and 2D formats in version 0.2.0. No honest scanner can guarantee every barcode under every capture condition, so CodaraScan publishes the exact catalog, evidence, and known limitations instead of making an unlimited compatibility claim.
428
434
 
429
435
 
430
436
  ### Which mode should I use?
431
437
 
432
- Begin with `mode="fast"` for lower latency. Evaluate `mode="robust"` when difficult inputs justify stronger recovery and extra computation. Benchmark both on your actual documents.
438
+ Begin with `mode="fast"` for lower latency. Evaluate `mode="robust"` for
439
+ difficult inputs and `mode="panorama"` when maximum recall justifies the extra
440
+ work. Benchmark the relevant modes on your actual documents.
433
441
 
434
442
  ### Is CodaraScan open source and usable commercially?
435
443
 
@@ -16,7 +16,7 @@ For teams looking for a universal barcode detection layer, CodaraScan provides o
16
16
  [Formats](#supported-barcode-formats) · [API reference](https://github.com/flh-raouf/codarascan/blob/main/docs/API.md) ·
17
17
  [PyPI](https://pypi.org/project/codarascan/)
18
18
 
19
- > **Alpha notice — CodaraScan 0.1.2 is alpha software.** Its APIs and schemas
19
+ > **Alpha notice — CodaraScan 0.2.0 is alpha software.** Its APIs and schemas
20
20
  > may change during 0.x. Pin an exact version and evaluate it against your own documents before
21
21
  > production use. See the [known limitations](https://github.com/flh-raouf/codarascan/blob/main/docs/KNOWN_LIMITATIONS.md)
22
22
  > and [release policy](https://github.com/flh-raouf/codarascan/blob/main/docs/RELEASE.md).
@@ -32,8 +32,8 @@ Most barcode libraries focus on decoding a clean, tightly cropped symbol. Docume
32
32
  | Barcode decoding | Returns Unicode text, exact raw payload bytes, and a canonical format name |
33
33
  | Document scanning | Reads selected PDF pages, preserves requested order, and supports bounded parallel work |
34
34
  | Batch processing | Scans complete or selected multi-page PDFs and can stream pages without accumulating them |
35
- | Format coverage | 40 selectable formats: 27 linear and 13 matrix selections in version 0.1.2 |
36
- | Recovery profiles | `fast` Tessera mode for lower latency; `robust` Mosaic mode for stronger recovery |
35
+ | Format coverage | 40 selectable formats: 27 linear and 13 matrix selections in version 0.2.0 |
36
+ | Recovery profiles | `fast` Tessera for lower latency; `robust` Mosaic for stronger recovery; `panorama` for maximum recall |
37
37
  | Local processing | No server, network request, telemetry, external executable, or runtime model download |
38
38
  | Integration | Typed Python API, deterministic JSON, CLI, schemas, and a private persistent worker protocol |
39
39
  | Deployment | Native wheels for supported Linux, macOS, and Windows targets; Python fallback for Tessera |
@@ -59,7 +59,7 @@ python -m pip install codarascan
59
59
  For reproducible alpha deployments, pin the current release:
60
60
 
61
61
  ```bash
62
- python -m pip install codarascan==0.1.2
62
+ python -m pip install codarascan==0.2.0
63
63
  ```
64
64
 
65
65
 
@@ -71,7 +71,7 @@ python -m pip install codarascan==0.1.2
71
71
  from codarascan import DecodedSymbolResult, Scanner
72
72
 
73
73
  scanner = Scanner(
74
- mode="fast", # "fast" (Tessera) or "robust" (Mosaic)
74
+ mode="fast", # "fast" (Tessera), "robust" (Mosaic), or "panorama"
75
75
  symbols="all", # "linear", "2d", or "all"
76
76
  decode=True,
77
77
  )
@@ -210,22 +210,25 @@ A difficult symbol may be localized without being decoded. CodaraScan keeps that
210
210
  | `localized` | Geometry-only result produced with `decode=False` |
211
211
  | `review_candidate` | A barcode-like region was found with weaker evidence and may require human review |
212
212
 
213
- Confidence is an engine-specific evidence score in `[0, 1]`, not a calibrated probability. It is not directly comparable between Tessera and Mosaic. Treat `status` as the primary semantic signal.
213
+ Confidence is an engine-specific evidence score in `[0, 1]`, not a calibrated probability. It is not directly comparable between Tessera, Mosaic, and Panorama. Treat `status` as the primary semantic signal.
214
214
 
215
- ## Fast vs. robust barcode scanning
215
+ ## Choosing a scanning engine
216
216
 
217
- CodaraScan makes the performance/recovery choice explicit. It does not switch engines automatically.
217
+ CodaraScan makes the performance/recovery choice explicit.
218
218
 
219
219
  | Mode | Engine | Best fit | Trade-off |
220
220
  |---|---|---|---|
221
221
  | `mode="fast"` | Tessera | Low-latency document scanning and common workflows | Less exhaustive recovery |
222
222
  | `mode="robust"` | Mosaic | Difficult inputs where stronger recovery is worth more work | Higher CPU time and latency |
223
+ | `mode="panorama"` | Panorama | Maximum-recall extraction and review workflows | Highest CPU time and latency; extraction only |
223
224
 
224
- Start with `fast`, measure on representative inputs, and choose `robust` where it materially improves your corpus. Avoid choosing a mode from synthetic benchmarks alone.
225
+ Start with `fast`, measure on representative inputs, and choose `robust` or
226
+ `panorama` where the additional recovery materially improves your corpus.
227
+ Avoid choosing a mode from synthetic benchmarks alone.
225
228
 
226
229
  ## Supported barcode formats
227
230
 
228
- CodaraScan 0.1.2 exposes **40 selectable barcode formats** generated from the installed ZXing-C++ readable catalog: **27 linear/1D selections** and **13 matrix/2D selections**.
231
+ CodaraScan 0.2.0 exposes **40 selectable barcode formats** generated from the installed ZXing-C++ readable catalog: **27 linear/1D selections** and **13 matrix/2D selections**.
229
232
 
230
233
  ### 1D and linear barcodes
231
234
 
@@ -274,8 +277,11 @@ Every symbol includes:
274
277
  - engine-specific `confidence` and contributing `sources`;
275
278
  - `quad`: four pixel-space points in top-left, top-right, bottom-right,
276
279
  bottom-left order;
277
- - `normalized_quad`: the same four points normalized by image width and height;
278
- - analyzed `image_width` and `image_height`.
280
+ - `normalized_quad`: the same four points normalized by image width and height.
281
+
282
+ Image dimensions are recorded once as `width` and `height` on the containing
283
+ image result. PDF page results record `page`, `width`, and `height` together;
284
+ symbols do not repeat those dimensions.
279
285
 
280
286
  A `DecodedSymbolResult` additionally includes `format`, `text`, its `value`
281
287
  alias, and exact `raw_bytes`.
@@ -323,7 +329,7 @@ Run `codarascan image --help` or `codarascan document --help` for every option.
323
329
 
324
330
  ## Platform support
325
331
 
326
- Official 0.1.2 wheels target:
332
+ Official 0.2.0 wheels target:
327
333
 
328
334
  | Operating system | Architectures | Python |
329
335
  |---|---|---|
@@ -367,12 +373,14 @@ Yes. Barcode detection, decoding, PDF rendering, the CLI, and the worker all run
367
373
 
368
374
  ### Is CodaraScan a universal barcode reader?
369
375
 
370
- It is a multi-format barcode detection layer with 40 selectable 1D and 2D formats in version 0.1.2. No honest scanner can guarantee every barcode under every capture condition, so CodaraScan publishes the exact catalog, evidence, and known limitations instead of making an unlimited compatibility claim.
376
+ It is a multi-format barcode detection layer with 40 selectable 1D and 2D formats in version 0.2.0. No honest scanner can guarantee every barcode under every capture condition, so CodaraScan publishes the exact catalog, evidence, and known limitations instead of making an unlimited compatibility claim.
371
377
 
372
378
 
373
379
  ### Which mode should I use?
374
380
 
375
- Begin with `mode="fast"` for lower latency. Evaluate `mode="robust"` when difficult inputs justify stronger recovery and extra computation. Benchmark both on your actual documents.
381
+ Begin with `mode="fast"` for lower latency. Evaluate `mode="robust"` for
382
+ difficult inputs and `mode="panorama"` when maximum recall justifies the extra
383
+ work. Benchmark the relevant modes on your actual documents.
376
384
 
377
385
  ### Is CodaraScan open source and usable commercially?
378
386
 
@@ -13,7 +13,7 @@ while the declared range remains authoritative for dependency resolution.
13
13
  | Pillow | `>=10,<13`; 12.3.0 | Encoded-image loading and EXIF orientation; https://python-pillow.org/ | Package metadata: MIT-CMU | External dependency, unmodified. Retain its permission notice; permissive terms are compatible with Apache-2.0 distribution. |
14
14
  | PDFium / `pypdfium2` | `>=4.30,<6`; 5.12.1 | Local PDF rendering; https://github.com/pypdfium2-team/pypdfium2 | Package metadata: BSD-3-Clause and Apache-2.0, with dependency license materials in its distribution | External dependency, unmodified. Preserve the dependency's bundled notices and licenses; the declared terms are compatible with Apache-2.0 distribution. |
15
15
  | Tessera native extension | repository source at `src/codarascan/engines/common/native/sttg_native.cpp`; 0.1.0 | Structure-tensor acceleration maintained in this repository | Authored project source, Apache-2.0 | Modified as part of the CodaraScan package/native-loader boundary. Distributed with SPDX identification, LICENSE, and NOTICE. |
16
- | Research-derived Tessera/Mosaic Python modules | repository history under `src/codarascan/engines`; 0.1.0 | Canonical engine implementation maintained in this repository | Authored project source, Apache-2.0 | Reorganized and adapted behind the public Scanner contract. No external corpus or confidential document is bundled. Distributed under the project LICENSE and NOTICE. |
16
+ | Research-derived Tessera/Mosaic/Panorama Python modules | repository history under `src/codarascan/engines`; 0.2.0 | Canonical engine implementation maintained in this repository | Authored project source, Apache-2.0 | Reorganized and adapted behind the public Scanner contract. No external corpus or confidential document is bundled. Distributed under the project LICENSE and NOTICE. |
17
17
 
18
18
  The `archive/`, benchmark datasets, reports, pinned third-party checkout, and
19
19
  ignored research material are not installed as package data. `tools/inspect_artifacts.py`
@@ -5,12 +5,13 @@
5
5
  `Scanner(mode="fast", symbols="all", formats=None, decode=True)` is immutable,
6
6
  hashable, lazily initialized, reusable, and safe to share across threads.
7
7
 
8
- - `mode`: `fast` selects Tessera; `robust` selects Mosaic. There is no `auto`
9
- mode or cross-engine fallback.
8
+ - `mode`: `fast` selects Tessera, `robust` selects Mosaic, and `panorama`
9
+ selects the high-recall Panorama composition. There is no `auto` mode.
10
10
  - `symbols`: `linear`, `2d`, or `all`.
11
11
  - `formats`: optional canonical names or accepted aliases. Contradictions with
12
12
  `symbols` and unknown names fail at construction.
13
- - `decode`: a strict boolean. False produces geometry-only public results.
13
+ - `decode`: a strict boolean. False produces geometry-only public results and
14
+ is supported by Tessera and Mosaic; Panorama is extraction-only.
14
15
 
15
16
  `warm()` performs the same idempotent initialization used on first scan.
16
17
 
@@ -62,7 +63,9 @@ Pixel coordinates use an origin at the orientation-corrected image's top-left,
62
63
  with x increasing right and y increasing down. Quads contain top-left,
63
64
  top-right, bottom-right, and bottom-left corners in clockwise, non-self-
64
65
  intersecting order. `normalized_quad` divides x by image width and y by image
65
- height. There is no stable bounding-box field.
66
+ height. Image results carry `width` and `height` once at the result level. PDF
67
+ page results carry `page`, `width`, and `height` together. Symbols do not repeat
68
+ their containing image dimensions. There is no stable bounding-box field.
66
69
 
67
70
  `DecodedSymbolResult` adds `text`, `value`, `raw_bytes`, and canonical `format`
68
71
  to the base geometry/status contract. `SymbolResult` used for localization-only,
@@ -2,7 +2,7 @@
2
2
 
3
3
  ## Interpreter and platform matrix
4
4
 
5
- CodaraScan 0.1.0 declares CPython 3.11, 3.12, 3.13, and 3.14. The official
5
+ CodaraScan 0.2.0 declares CPython 3.11, 3.12, 3.13, and 3.14. The official
6
6
  wheel target matrix is:
7
7
 
8
8
  | Platform | Architectures | Wheel expectation |
@@ -1,4 +1,4 @@
1
- # Known limitations in 0.1.0 alpha
1
+ # Known limitations in 0.2.0 alpha
2
2
 
3
3
  - Degraded-corpus validation is deepest for established QR Code, Data Matrix,
4
4
  and common linear workflows. Broader catalog blur, glare, perspective,
@@ -9,7 +9,7 @@
9
9
  structure-tensor linear localizer is tuned for document layouts and does not
10
10
  guarantee clean-crop localization for every linear family.
11
11
  - Confidence values are not calibrated probabilities and are not comparable
12
- between Tessera and Mosaic.
12
+ between Tessera, Mosaic, and Panorama.
13
13
  - Native and Python-reference Tessera geometry is tolerance-equivalent, not
14
14
  pixel-identical.
15
15
  - PDF support does not expose a password parameter in 0.1. Password-protected
@@ -7,7 +7,7 @@ Every 0.x release must:
7
7
  - pass Ruff, strict public-boundary mypy, unit/integration tests, and native
8
8
  fallback/parity checks;
9
9
  - build wheel and sdist artifacts and install them outside the source tree;
10
- - smoke fast/robust linear and matrix scans, PDFium PDF scanning, CLI JSON, and
10
+ - smoke Tessera/Mosaic linear and matrix scans, Panorama extraction, PDFium PDF scanning, CLI JSON, and
11
11
  framed worker output from installed artifacts;
12
12
  - include the native extension in official wheels and verify forced fallback;
13
13
  - include Apache-2.0 license, notice, attribution, schemas, and native source;
@@ -25,14 +25,19 @@ python -m pytest --cov=codarascan --cov-report=term-missing
25
25
  python -m build
26
26
  python tools/inspect_artifacts.py dist/*.whl dist/*.tar.gz
27
27
  python tools/dependency_manifest.py dist/*.whl --output dist/dependency-manifest.json
28
- python benchmarks/format_smoke.py --mode robust --repeats 3
28
+ python -m benchmarks.format_smoke --mode robust --repeats 3
29
29
  git diff --check
30
30
  ```
31
31
 
32
- The exact local pre-publication results for 0.1.0 are recorded in
33
- [RELEASE_EVIDENCE_0.1.0.md](RELEASE_EVIDENCE_0.1.0.md). Platform-matrix and
34
- publication results are appended only after the protected release workflow is
35
- explicitly approved and run.
32
+ Release records:
33
+
34
+ - [CodaraScan 0.1.2 release evidence](RELEASE_EVIDENCE_0.1.2.md) covers the
35
+ current PyPI release, security hardening, provenance, and Codara verification.
36
+ - [CodaraScan 0.1.0 release evidence](RELEASE_EVIDENCE_0.1.0.md) preserves the
37
+ original alpha-publication record.
38
+
39
+ Platform-matrix and publication results are recorded only after the protected
40
+ release workflow is explicitly approved and run.
36
41
 
37
42
  The release workflow builds CPython 3.11-3.14 wheels on Linux x86_64/ARM64,
38
43
  macOS Intel/Apple Silicon, and Windows x86_64. Artifact upload and PyPI trusted
@@ -42,7 +47,7 @@ publication authority.
42
47
 
43
48
  ## 1.0 blocking gates
44
49
 
45
- Stable 1.0 additionally requires frozen per-format Tessera/Mosaic accuracy,
50
+ Stable 1.0 additionally requires frozen per-format Tessera/Mosaic/Panorama accuracy,
46
51
  false-positive, zero-wrong-decode, duplicate, geometry, degraded-case, latency,
47
52
  throughput, and peak-memory thresholds; every input/status/error contract;
48
53
  native/reference and prior-Poppler/PDFium parity; all official wheels; schema
@@ -50,4 +55,4 @@ parity across Python/CLI/worker/Codara and any included Node wrapper; complete
50
55
  Codara package consumption without copied engines; and licensing, privacy,
51
56
  offline, upgrade, and artifact reviews.
52
57
 
53
- 0.1.0 does not claim these production gates.
58
+ No 0.x release claims these production gates.
@@ -0,0 +1,141 @@
1
+ # CodaraScan 0.1.2 release evidence
2
+
3
+ Date: 2026-08-10
4
+
5
+ Scope: documentation refresh, security hardening, public PyPI publication, and
6
+ Codara consumer verification for CodaraScan 0.1.2. This record distinguishes
7
+ completed package publication and downstream integration from the remaining
8
+ GitHub source-visibility gate.
9
+
10
+ ## Source and quality gates
11
+
12
+ Source commit: `826998bbb21c41ed7bfe4191380de72ef80fe518`
13
+
14
+ The release source passed the following local gates:
15
+
16
+ ```text
17
+ Ruff: passed
18
+ mypy: passed
19
+ pytest: 187 passed
20
+ wheel and sdist build: passed
21
+ artifact inspection: passed
22
+ git diff --check: passed
23
+ ```
24
+
25
+ GitHub CI run
26
+ [`31397915733`](https://github.com/flh-raouf/codarascan/actions/runs/31397915733)
27
+ passed the quality and distribution jobs, CPython 3.11-3.14 tests, and platform
28
+ smoke tests on Linux x86-64/ARM64, macOS Intel/Apple Silicon, and Windows
29
+ x86-64.
30
+
31
+ The 0.1.2 hardening changes make explicit CLI debug directories owner-only
32
+ (`0700`) and their warning/result files owner-readable and owner-writable only
33
+ (`0600`), including under a permissive process umask. All third-party GitHub
34
+ Actions in the package CI and release workflows are pinned to full commit
35
+ SHAs. A regression test rejects mutable action references, and repository
36
+ Actions policy also requires SHA-pinned actions.
37
+
38
+ ## Published artifacts and provenance
39
+
40
+ Release workflow run
41
+ [`31398141966`](https://github.com/flh-raouf/codarascan/actions/runs/31398141966)
42
+ completed successfully using PyPI Trusted Publishing. It built and inspected
43
+ the native-required source distribution and 20 wheels, then required a complete
44
+ 21-artifact manifest before publication.
45
+
46
+ PyPI exposes the release at
47
+ <https://pypi.org/project/codarascan/0.1.2/>. The published description is the
48
+ 0.1.2 README, including the installation, API, PDF/batch, format, platform,
49
+ privacy, FAQ, SEO/GEO, contact, and limitation sections. PyPI displays Sigstore
50
+ provenance for the artifacts and binds publication to the source commit and
51
+ `release.yml` workflow above.
52
+
53
+ The published source distribution is:
54
+
55
+ ```text
56
+ f58e35058f98a73a407ddf2f5b705c54f02f9d246709b4ba7962daeddb94bbc8 codarascan-0.1.2.tar.gz
57
+ ```
58
+
59
+ ## Independent registry verification
60
+
61
+ A new virtual environment outside the repository installed the exact version
62
+ from the public simple index with no wheel cache:
63
+
64
+ ```bash
65
+ python -m pip install --no-cache-dir --index-url https://pypi.org/simple \
66
+ codarascan==0.1.2
67
+ codarascan --version
68
+ # codarascan 0.1.2 (Apache-2.0)
69
+ ```
70
+
71
+ The imported module resolved from the environment's `site-packages`, not the
72
+ source checkout. The installed package also reproduced the owner-only debug
73
+ directory and file modes.
74
+
75
+ ## Codara consumer verification
76
+
77
+ Codara migration commit `031ee468f5f5addc7c549bb94413cd5b73276941`
78
+ pins `codarascan==0.1.2` and commits a registry-backed production lock. A clean
79
+ `uv --no-sources --locked` environment imported 0.1.2 from `site-packages` and
80
+ passed all 75 backend tests.
81
+
82
+ Codara CI run
83
+ [`31401474599`](https://github.com/flh-raouf/codara/actions/runs/31401474599)
84
+ passed backend checks, frontend typechecking/tests/build, and the production
85
+ container build from the neutral `codarascan-0.1.2-migration` branch. The five
86
+ migration commits were then merged into Codara `main` through
87
+ [Codara PR #3](https://github.com/flh-raouf/codara/pull/3) at merge commit
88
+ `cfb0aca331727b07f00f24c655526d66e5613218`.
89
+
90
+ Post-merge Codara CI/CD run
91
+ [`31404892126`](https://github.com/flh-raouf/codara/actions/runs/31404892126)
92
+ passed backend checks, frontend typechecking/tests/build, the production
93
+ container build, the OpenScaler deployment, and the public endpoint health
94
+ check.
95
+
96
+ ## Public-source safety gate
97
+
98
+ The distributable package and PyPI release are public. The GitHub repository is
99
+ intentionally private while GitHub Support removes three immutable pull-request
100
+ refs that still retain objects from before the sanitized history rewrite.
101
+ Normal branches and tags expose only the sanitized history. The source
102
+ repository must not be made public until GitHub confirms the server-side purge
103
+ and cached-view cleanup.
104
+
105
+ The preserved research tree also passed a targeted publication-residue scan:
106
+ it contains no personal filesystem paths, internal document names, `VN LOT`
107
+ labels, or assistant-environment cache names. Research notebook cache examples
108
+ now use the neutral `barcode-research` label, and private benchmark groups use
109
+ generic corpus names. All retained synthetic benchmark PDFs have an empty
110
+ Author field and only anonymous or generic dataset-generator Creator metadata.
111
+ The maintainer name and contact email remain intentionally public in package
112
+ metadata, the README, and the license notices.
113
+
114
+ GitHub Actions history was audited separately because workflow logs and
115
+ artifacts become externally visible with a public repository. All 18 retained
116
+ CodaraScan workflow logs were downloaded and scanned; no personal paths,
117
+ internal dossier or dataset names, research notebook names, or checkpoint paths
118
+ were present. All 25 retained artifact bundles were downloaded, yielding 60
119
+ wheel and source-distribution files across versions 0.1.0-0.1.2. Every file
120
+ passed the matching-version artifact inspector for forbidden content, local
121
+ paths, credentials, unsafe archive paths, license/SPDX coverage, and packaging
122
+ boundaries. One duplicate CI run records the branch label used before the
123
+ neutral branch rename, but contains no confidential data.
124
+
125
+ The GitHub Support payload has been derived and retained privately: repository
126
+ identity, three affected pull requests, the first-changed-commit mapping, and
127
+ confirmation that the rewrite reported no filtering problems, no LFS object
128
+ store exists, and GitHub reports zero forks. Sensitive object identifiers are
129
+ intentionally not reproduced in this public evidence file.
130
+
131
+ The repository's issue #3 was deleted. Main rejects force-pushes and deletions,
132
+ enforces administrators, linear history, resolved conversations, pull-request
133
+ flow, and the complete up-to-date CI matrix. Dependabot and automated security
134
+ updates are enabled. Code scanning, secret scanning, and push protection remain
135
+ platform/plan-dependent while the repository is private and should be enabled
136
+ immediately after the visibility gate is cleared.
137
+
138
+ The standard security review reported two medium findings; both were fixed in
139
+ 0.1.2 and their original reproductions no longer succeed. The environment did
140
+ not provide the managed read-only profile required by the deeper independent
141
+ scan, so this record does not claim that unavailable coverage.
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "codarascan"
7
- version = "0.1.2"
7
+ version = "0.2.0"
8
8
  description = "Open-source, offline barcode detection, localization, and decoding for images and PDFs"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11,<3.15"
@@ -1,7 +1,7 @@
1
1
  # SPDX-License-Identifier: Apache-2.0
2
2
  """CodaraScan public API."""
3
3
 
4
- __version__ = "0.1.2"
4
+ __version__ = "0.2.0"
5
5
 
6
6
  from .core.contracts import Roi
7
7
  from .documents import DocumentInput, DocumentStream, ErrorPolicy, WorkerCount
@@ -82,7 +82,9 @@ def _workers(value: str) -> int | str:
82
82
 
83
83
 
84
84
  def _add_scanner_options(parser: argparse.ArgumentParser) -> None:
85
- parser.add_argument("--mode", choices=("fast", "robust"), default="fast")
85
+ parser.add_argument(
86
+ "--mode", choices=("fast", "robust", "panorama"), default="fast"
87
+ )
86
88
  parser.add_argument("--symbols", choices=("linear", "2d", "all"), default="all")
87
89
  parser.add_argument("--formats", type=_formats)
88
90
  parser.add_argument("--no-decode", action="store_true")
@@ -60,7 +60,7 @@ def _document_source(value: DocumentInput) -> str | bytes:
60
60
  )
61
61
  if path.suffix.lower() != ".pdf":
62
62
  raise DocumentError(
63
- "the 0.1.0 document API supports PDF files only",
63
+ "the document API supports PDF files only",
64
64
  context={"path": str(path), "type": path.suffix.lower()},
65
65
  )
66
66
  return str(path)
@@ -48,7 +48,7 @@ def load_registry() -> Any:
48
48
  missing.startswith(f"{module}.") for module in engine_modules
49
49
  ):
50
50
  raise RuntimeError(
51
- "The Tessera/Mosaic runtime is unavailable because "
51
+ "The Tessera/Mosaic/Panorama runtime is unavailable because "
52
52
  f"{missing!r} is missing. Install the engine dependencies with "
53
53
  "`pip install -e .` before loading the registry."
54
54
  ) from exc
@@ -11,7 +11,7 @@ from dataclasses import dataclass
11
11
  from typing import Literal
12
12
 
13
13
  CapabilityName = Literal["detect", "decode"]
14
- Role = Literal["recommended", "base"]
14
+ Role = Literal["recommended", "base", "high-recall"]
15
15
 
16
16
 
17
17
  @dataclass(frozen=True)
@@ -50,4 +50,10 @@ ENGINE_CATALOG: tuple[EngineSpec, ...] = (
50
50
  role="base",
51
51
  source="src/codarascan/engines/mosaic/extraction.py",
52
52
  ),
53
+ EngineSpec(
54
+ name="Panorama",
55
+ capability="decode",
56
+ role="high-recall",
57
+ source="src/codarascan/engines/panorama/extraction.py",
58
+ ),
53
59
  )
@@ -1,5 +1,5 @@
1
1
  # SPDX-License-Identifier: Apache-2.0
2
- """Shared local implementation pieces used by Tessera and Mosaic."""
2
+ """Shared local implementation pieces used by Tessera, Mosaic, and Panorama."""
3
3
 
4
4
  from .base import (
5
5
  CONTEXT_MARGIN_PX,
@@ -0,0 +1,6 @@
1
+ # SPDX-License-Identifier: Apache-2.0
2
+ """Panorama high-recall extraction engine."""
3
+
4
+ from .extraction import ENGINE, PanoramaExtractor, PreparedPanoramaPage
5
+
6
+ __all__ = ["ENGINE", "PanoramaExtractor", "PreparedPanoramaPage"]