@emdzej/itw-decoder 0.2.0 → 0.3.0

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.
package/README.md CHANGED
@@ -81,21 +81,6 @@ To test against a full GRAFIK corpus directory:
81
81
  ./node_modules/.bin/ts-node bulk_test.ts /path/to/GRAFIK
82
82
  ```
83
83
 
84
- ## Test results
85
-
86
- Tested against the full 47,660-file GRAFIK corpus:
87
-
88
- | Metric | Value |
89
- |--------|-------|
90
- | Success rate | **99.66%** (47,498 / 47,660) |
91
- | 0x0300 wavelet decoded | 35,587 |
92
- | 0x0400 entropy decoded | 11,911 |
93
- | Failures | 162 — all genuinely malformed/truncated source files |
94
-
95
- ### Encoder bug: 256-byte payload length overrun
96
-
97
- 586 wavelet (0x0300) files in the corpus declare a payload length exactly 256 bytes larger than the actual file data. This is a systematic bug in the original BMW ITW encoder — the payload data is complete, only the length field is wrong. The decoder tolerates this by allowing small overruns (up to 512 bytes) while still rejecting truly truncated files.
98
-
99
84
  ## Project structure
100
85
 
101
86
  ```
@@ -140,6 +140,11 @@ function buildHuffTree(leaves) {
140
140
  }
141
141
  // Priority queue: indices to merge
142
142
  let queue = leaves.map(l => l.id);
143
+ // The original C code stores weights as IEEE 754 float (32-bit).
144
+ // We must use float32 arithmetic for the sum so that internal-node
145
+ // weights land on the same values the original encoder used;
146
+ // float64 rounding can reorder nodes and produce a wrong tree.
147
+ const f32 = new Float32Array(1);
143
148
  while (queue.length > 1) {
144
149
  // Sort by weight ascending (float comparison as in original FUN_004b60c0)
145
150
  queue.sort((a, b) => nodes[a].weight - nodes[b].weight);
@@ -147,6 +152,7 @@ function buildHuffTree(leaves) {
147
152
  const rightId = queue.shift();
148
153
  const left = nodes[leftId];
149
154
  const right = nodes[rightId];
155
+ f32[0] = left.weight + right.weight;
150
156
  const parentNode = {
151
157
  isLeaf: 0,
152
158
  symbol: 0,
@@ -154,7 +160,7 @@ function buildHuffTree(leaves) {
154
160
  leftId: left.id,
155
161
  rightId: right.id,
156
162
  parentId: -1,
157
- weight: left.weight + right.weight,
163
+ weight: f32[0],
158
164
  };
159
165
  left.parentId = parentNode.id;
160
166
  right.parentId = parentNode.id;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@emdzej/itw-decoder",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "type": "commonjs",
5
5
  "description": "Decode BMW TIS .ITW proprietary image files to PNG",
6
6
  "license": "PolyForm-Noncommercial-1.0.0",