@intactfile/engines 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.
Files changed (65) hide show
  1. package/dist/detect/index.d.ts +1 -1
  2. package/dist/detect/index.d.ts.map +1 -1
  3. package/dist/detect/index.js +77 -0
  4. package/dist/detect/index.js.map +1 -1
  5. package/dist/heic/format.d.ts +87 -0
  6. package/dist/heic/format.d.ts.map +1 -0
  7. package/dist/heic/format.js +241 -0
  8. package/dist/heic/format.js.map +1 -0
  9. package/dist/index.d.ts +8 -0
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +9 -0
  12. package/dist/index.js.map +1 -1
  13. package/dist/office-legacy/diagnose.d.ts +24 -0
  14. package/dist/office-legacy/diagnose.d.ts.map +1 -0
  15. package/dist/office-legacy/diagnose.js +111 -0
  16. package/dist/office-legacy/diagnose.js.map +1 -0
  17. package/dist/office-legacy/format.d.ts +89 -0
  18. package/dist/office-legacy/format.d.ts.map +1 -0
  19. package/dist/office-legacy/format.js +281 -0
  20. package/dist/office-legacy/format.js.map +1 -0
  21. package/dist/office-legacy/index.d.ts +9 -0
  22. package/dist/office-legacy/index.d.ts.map +1 -0
  23. package/dist/office-legacy/index.js +18 -0
  24. package/dist/office-legacy/index.js.map +1 -0
  25. package/dist/office-legacy/rebuild.d.ts +8 -0
  26. package/dist/office-legacy/rebuild.d.ts.map +1 -0
  27. package/dist/office-legacy/rebuild.js +234 -0
  28. package/dist/office-legacy/rebuild.js.map +1 -0
  29. package/dist/office-legacy/repair.d.ts +40 -0
  30. package/dist/office-legacy/repair.d.ts.map +1 -0
  31. package/dist/office-legacy/repair.js +161 -0
  32. package/dist/office-legacy/repair.js.map +1 -0
  33. package/dist/psd/diagnose.d.ts +33 -0
  34. package/dist/psd/diagnose.d.ts.map +1 -0
  35. package/dist/psd/diagnose.js +176 -0
  36. package/dist/psd/diagnose.js.map +1 -0
  37. package/dist/psd/format.d.ts +106 -0
  38. package/dist/psd/format.d.ts.map +1 -0
  39. package/dist/psd/format.js +238 -0
  40. package/dist/psd/format.js.map +1 -0
  41. package/dist/psd/index.d.ts +8 -0
  42. package/dist/psd/index.d.ts.map +1 -0
  43. package/dist/psd/index.js +13 -0
  44. package/dist/psd/index.js.map +1 -0
  45. package/dist/psd/repair.d.ts +36 -0
  46. package/dist/psd/repair.d.ts.map +1 -0
  47. package/dist/psd/repair.js +451 -0
  48. package/dist/psd/repair.js.map +1 -0
  49. package/dist/raw/diagnose.d.ts +29 -0
  50. package/dist/raw/diagnose.d.ts.map +1 -0
  51. package/dist/raw/diagnose.js +95 -0
  52. package/dist/raw/diagnose.js.map +1 -0
  53. package/dist/raw/format.d.ts +47 -0
  54. package/dist/raw/format.d.ts.map +1 -0
  55. package/dist/raw/format.js +213 -0
  56. package/dist/raw/format.js.map +1 -0
  57. package/dist/raw/index.d.ts +7 -0
  58. package/dist/raw/index.d.ts.map +1 -0
  59. package/dist/raw/index.js +13 -0
  60. package/dist/raw/index.js.map +1 -0
  61. package/dist/raw/repair.d.ts +46 -0
  62. package/dist/raw/repair.d.ts.map +1 -0
  63. package/dist/raw/repair.js +94 -0
  64. package/dist/raw/repair.js.map +1 -0
  65. package/package.json +14 -2
@@ -0,0 +1,47 @@
1
+ export type RawContainer = "cr2" | "cr3" | "nef" | "arw" | "dng" | "raf" | "tiff";
2
+ export type ByteOrder = "le" | "be";
3
+ export declare const RAF_MAGIC = "FUJIFILMCCD-RAW ";
4
+ export interface RawId {
5
+ container: RawContainer;
6
+ order?: ByteOrder;
7
+ /** offset of the true start of the container (0 unless a garbage prefix). */
8
+ offset: number;
9
+ }
10
+ /** Is a TIFF/RAF/CR3 magic present at exactly this offset? */
11
+ export declare function rawIdAt(b: Uint8Array, offset?: number): RawId | null;
12
+ /** Find the RAW magic at offset 0, or scanned within a garbage-prefix window. */
13
+ export declare function findRawStart(b: Uint8Array, window?: number): RawId | null;
14
+ /** Endianness-aware unsigned readers. */
15
+ export declare function readers(order: ByteOrder): {
16
+ u16: (b: Uint8Array, o: number) => number;
17
+ u32: (b: Uint8Array, o: number) => number;
18
+ };
19
+ export interface TiffScan {
20
+ ok: boolean;
21
+ ifdCount: number;
22
+ entryTotal: number;
23
+ /** offsets (from offset tags / nextIFD / SubIFD) that point past EOF. */
24
+ dangling: number[];
25
+ /** largest end-of-data offset the IFDs reference (for truncation checks). */
26
+ maxRefEnd: number;
27
+ jpeg?: {
28
+ offset: number;
29
+ length: number;
30
+ };
31
+ notes: string[];
32
+ }
33
+ /**
34
+ * Walk the TIFF IFD chain from `ifd0`, following nextIFD, SubIFDs (0x014A) and
35
+ * the Exif IFD (0x8769). Records dangling offsets and the embedded-JPEG range
36
+ * (JPEGInterchangeFormat/Length). Bounded and tolerant of damage.
37
+ */
38
+ export declare function walkTiff(b: Uint8Array, order: ByteOrder, ifd0: number): TiffScan;
39
+ /**
40
+ * Universal preview salvage: the largest FFD8 FF … FFD9 span in the buffer.
41
+ * RAW previews are usually the biggest embedded JPEG (bigger than the thumbnail).
42
+ */
43
+ export declare function findLargestJpeg(b: Uint8Array): {
44
+ offset: number;
45
+ length: number;
46
+ } | null;
47
+ //# sourceMappingURL=format.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../src/raw/format.ts"],"names":[],"mappings":"AAWA,MAAM,MAAM,YAAY,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,MAAM,CAAC;AAClF,MAAM,MAAM,SAAS,GAAG,IAAI,GAAG,IAAI,CAAC;AAEpC,eAAO,MAAM,SAAS,qBAAqB,CAAC;AAgB5C,MAAM,WAAW,KAAK;IACpB,SAAS,EAAE,YAAY,CAAC;IACxB,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,6EAA6E;IAC7E,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,8DAA8D;AAC9D,wBAAgB,OAAO,CAAC,CAAC,EAAE,UAAU,EAAE,MAAM,SAAI,GAAG,KAAK,GAAG,IAAI,CAmB/D;AAED,iFAAiF;AACjF,wBAAgB,YAAY,CAAC,CAAC,EAAE,UAAU,EAAE,MAAM,SAAY,GAAG,KAAK,GAAG,IAAI,CAY5E;AAED,yCAAyC;AACzC,wBAAgB,OAAO,CAAC,KAAK,EAAE,SAAS;aAGzB,UAAU,KAAK,MAAM;aACrB,UAAU,KAAK,MAAM;EASnC;AAMD,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,OAAO,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,yEAAyE;IACzE,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,6EAA6E;IAC7E,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1C,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EAAE,UAAU,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,QAAQ,CAuEhF;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,UAAU,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAoBxF"}
@@ -0,0 +1,213 @@
1
+ /**
2
+ * Pure-TS format primitives for the RAW photo engine. RAW files are containers:
3
+ * CR2/NEF/ARW/DNG are TIFF (header + IFD chain + offset tags), CR3 is ISO-BMFF
4
+ * (ftyp "crx "), RAF is a Fujifilm big-endian container. All embed a full-size
5
+ * JPEG preview, which is our universal, deterministic recovery target.
6
+ *
7
+ * No WASM, no deps — byte arithmetic over a buffer. See docs/engineering/
8
+ * engine-raw-photo.md for the design.
9
+ */
10
+ import { matchAscii } from "../bytes-util.js";
11
+ export const RAF_MAGIC = "FUJIFILMCCD-RAW ";
12
+ const TIFF_LE = [0x49, 0x49, 0x2a, 0x00]; // "II" 42
13
+ const TIFF_BE = [0x4d, 0x4d, 0x00, 0x2a]; // "MM" 42
14
+ const eqAt = (b, o, sig) => sig.every((x, i) => b[o + i] === x);
15
+ const asciiWindow = (b, from, to) => {
16
+ let s = "";
17
+ for (let i = from; i < Math.min(to, b.length); i++) {
18
+ const c = b[i];
19
+ s += c >= 32 && c < 127 ? String.fromCharCode(c) : " ";
20
+ }
21
+ return s;
22
+ };
23
+ /** Is a TIFF/RAF/CR3 magic present at exactly this offset? */
24
+ export function rawIdAt(b, offset = 0) {
25
+ const o = offset;
26
+ if (eqAt(b, o, TIFF_LE) || eqAt(b, o, TIFF_BE)) {
27
+ const order = b[o] === 0x49 ? "le" : "be";
28
+ let container = "tiff";
29
+ if (b[o + 8] === 0x43 && b[o + 9] === 0x52)
30
+ container = "cr2"; // "CR" Canon ext
31
+ else {
32
+ const s = asciiWindow(b, o, Math.min(b.length, o + 8192));
33
+ if (/NIKON/i.test(s))
34
+ container = "nef";
35
+ else if (/SONY/i.test(s))
36
+ container = "arw";
37
+ else if (/DNG|Adobe|GXR|PENTAX|Leica/i.test(s))
38
+ container = "dng";
39
+ }
40
+ return { container, order, offset: o };
41
+ }
42
+ if (matchAscii(b, o, RAF_MAGIC))
43
+ return { container: "raf", offset: o };
44
+ if (b.length >= o + 12 && matchAscii(b, o + 4, "ftyp") && matchAscii(b, o + 8, "crx ")) {
45
+ return { container: "cr3", offset: o };
46
+ }
47
+ return null;
48
+ }
49
+ /** Find the RAW magic at offset 0, or scanned within a garbage-prefix window. */
50
+ export function findRawStart(b, window = 64 * 1024) {
51
+ const at0 = rawIdAt(b, 0);
52
+ if (at0)
53
+ return at0;
54
+ const limit = Math.min(b.length - 16, window);
55
+ for (let i = 1; i <= limit; i++) {
56
+ // cheap first-byte gate before the full check
57
+ if (b[i] === 0x49 || b[i] === 0x4d || b[i] === 0x46 || b[i + 4] === 0x66) {
58
+ const id = rawIdAt(b, i);
59
+ if (id)
60
+ return id;
61
+ }
62
+ }
63
+ return null;
64
+ }
65
+ /** Endianness-aware unsigned readers. */
66
+ export function readers(order) {
67
+ if (order === "le") {
68
+ return {
69
+ u16: (b, o) => ((b[o] ?? 0) | ((b[o + 1] ?? 0) << 8)) >>> 0,
70
+ u32: (b, o) => (((b[o] ?? 0) | ((b[o + 1] ?? 0) << 8) | ((b[o + 2] ?? 0) << 16) | ((b[o + 3] ?? 0) << 24)) >>> 0),
71
+ };
72
+ }
73
+ return {
74
+ u16: (b, o) => (((b[o] ?? 0) << 8) | (b[o + 1] ?? 0)) >>> 0,
75
+ u32: (b, o) => ((((b[o] ?? 0) << 24) | ((b[o + 1] ?? 0) << 16) | ((b[o + 2] ?? 0) << 8) | (b[o + 3] ?? 0)) >>> 0),
76
+ };
77
+ }
78
+ // Offset-bearing TIFF tags whose value points elsewhere in the file.
79
+ const OFFSET_TAGS = new Set([0x0111, 0x0117, 0x0144, 0x0145, 0x0201, 0x0202, 0x014a, 0x8769]);
80
+ const TYPE_SIZE = { 1: 1, 2: 1, 3: 2, 4: 4, 5: 8, 6: 1, 7: 1, 8: 2, 9: 4, 10: 8, 11: 4, 12: 8 };
81
+ /**
82
+ * Walk the TIFF IFD chain from `ifd0`, following nextIFD, SubIFDs (0x014A) and
83
+ * the Exif IFD (0x8769). Records dangling offsets and the embedded-JPEG range
84
+ * (JPEGInterchangeFormat/Length). Bounded and tolerant of damage.
85
+ */
86
+ export function walkTiff(b, order, ifd0) {
87
+ const { u16, u32 } = readers(order);
88
+ const scan = { ok: false, ifdCount: 0, entryTotal: 0, dangling: [], maxRefEnd: 0, notes: [] };
89
+ const seen = new Set();
90
+ const queue = [ifd0];
91
+ let jpegOff = 0;
92
+ let jpegLen = 0;
93
+ // Single-strip offset/length, paired after the walk for truncation checks.
94
+ let stripOff = 0;
95
+ let stripLen = 0;
96
+ while (queue.length && scan.ifdCount < 32) {
97
+ const off = queue.shift();
98
+ if (off <= 0 || seen.has(off))
99
+ continue;
100
+ if (off + 2 > b.length) {
101
+ scan.dangling.push(off);
102
+ continue;
103
+ }
104
+ seen.add(off);
105
+ const n = u16(b, off);
106
+ if (n === 0 || n > 512) {
107
+ scan.notes.push(`implausible IFD entry count ${n} at ${off}`);
108
+ continue;
109
+ }
110
+ const base = off + 2;
111
+ if (base + n * 12 + 4 > b.length) {
112
+ scan.dangling.push(off);
113
+ continue;
114
+ }
115
+ scan.ifdCount++;
116
+ scan.entryTotal += n;
117
+ for (let e = 0; e < n; e++) {
118
+ const eo = base + e * 12;
119
+ const tag = u16(b, eo);
120
+ const type = u16(b, eo + 2);
121
+ const count = u32(b, eo + 4);
122
+ const size = (TYPE_SIZE[type] ?? 1) * count;
123
+ const valOff = size <= 4 ? eo + 8 : u32(b, eo + 8);
124
+ if (OFFSET_TAGS.has(tag)) {
125
+ if (tag === 0x014a || tag === 0x8769) {
126
+ // SubIFD(s) / Exif IFD: value(s) are IFD offsets to follow
127
+ if (size <= 4)
128
+ queue.push(u32(b, eo + 8));
129
+ else if (valOff + count * 4 <= b.length)
130
+ for (let k = 0; k < Math.min(count, 16); k++)
131
+ queue.push(u32(b, valOff + k * 4));
132
+ else
133
+ scan.dangling.push(valOff);
134
+ }
135
+ else if (tag === 0x0201) {
136
+ jpegOff = size <= 4 ? u32(b, eo + 8) : valOff;
137
+ }
138
+ else if (tag === 0x0202) {
139
+ jpegLen = size <= 4 ? u32(b, eo + 8) : valOff;
140
+ }
141
+ else if (tag === 0x0111 || tag === 0x0144) {
142
+ // StripOffsets / TileOffsets: dangling if the value (or first elem) is past EOF
143
+ const first = size <= 4 ? (type === 4 ? u32(b, eo + 8) : u16(b, eo + 8)) : valOff;
144
+ if (first > b.length)
145
+ scan.dangling.push(first);
146
+ else {
147
+ stripOff = stripOff || first;
148
+ scan.maxRefEnd = Math.max(scan.maxRefEnd, first);
149
+ }
150
+ }
151
+ else if (tag === 0x0117 || tag === 0x0145) {
152
+ // StripByteCounts / TileByteCounts: a length, not an offset (single-value only)
153
+ if (size <= 4 && count === 1)
154
+ stripLen = type === 4 ? u32(b, eo + 8) : u16(b, eo + 8);
155
+ }
156
+ }
157
+ }
158
+ const next = u32(b, base + n * 12);
159
+ if (next)
160
+ queue.push(next);
161
+ }
162
+ // Pair single-strip offset+length: a strip declared past EOF means truncation.
163
+ if (stripOff > 0 && stripLen > 0) {
164
+ const end = stripOff + stripLen;
165
+ if (end > b.length)
166
+ scan.dangling.push(end);
167
+ else
168
+ scan.maxRefEnd = Math.max(scan.maxRefEnd, end);
169
+ }
170
+ if (jpegOff > 0 && jpegLen > 0 && jpegOff + jpegLen <= b.length && b[jpegOff] === 0xff && b[jpegOff + 1] === 0xd8) {
171
+ scan.jpeg = { offset: jpegOff, length: jpegLen };
172
+ }
173
+ else if (jpegOff > 0 && jpegOff + 2 <= b.length && b[jpegOff] === 0xff && b[jpegOff + 1] === 0xd8) {
174
+ scan.jpeg = { offset: jpegOff, length: Math.max(0, Math.min(jpegLen, b.length - jpegOff)) };
175
+ if (jpegOff + jpegLen > b.length)
176
+ scan.dangling.push(jpegOff + jpegLen);
177
+ }
178
+ else if (jpegOff > b.length) {
179
+ scan.dangling.push(jpegOff);
180
+ }
181
+ scan.ok = scan.ifdCount > 0;
182
+ return scan;
183
+ }
184
+ /**
185
+ * Universal preview salvage: the largest FFD8 FF … FFD9 span in the buffer.
186
+ * RAW previews are usually the biggest embedded JPEG (bigger than the thumbnail).
187
+ */
188
+ export function findLargestJpeg(b) {
189
+ let best = null;
190
+ let i = 0;
191
+ const n = b.length - 3;
192
+ while (i < n) {
193
+ if (b[i] === 0xff && b[i + 1] === 0xd8 && b[i + 2] === 0xff) {
194
+ let end = -1;
195
+ for (let j = i + 2; j < b.length - 1; j++) {
196
+ if (b[j] === 0xff && b[j + 1] === 0xd9) {
197
+ end = j + 2;
198
+ break;
199
+ }
200
+ }
201
+ if (end > 0) {
202
+ const len = end - i;
203
+ if (!best || len > best.length)
204
+ best = { offset: i, length: len };
205
+ i = end;
206
+ continue;
207
+ }
208
+ }
209
+ i++;
210
+ }
211
+ return best;
212
+ }
213
+ //# sourceMappingURL=format.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format.js","sourceRoot":"","sources":["../../src/raw/format.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export declare const repairRaw: (src: import("../byte-source.js").ByteSource) => Promise<import("./repair.js").RawRepairResult>;
2
+ export { repairRawBytes } from "./repair.js";
3
+ export type { RawRepairOutcome, RawRepairStrategy, RawRepairReport, RawRepairResult, } from "./repair.js";
4
+ export { diagnoseRaw, diagnoseRawBytes } from "./diagnose.js";
5
+ export type { RawDiagnosis, RawDamageClass, RawPreview } from "./diagnose.js";
6
+ export type { RawContainer, ByteOrder } from "./format.js";
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/raw/index.ts"],"names":[],"mappings":"AAUA,eAAO,MAAM,SAAS,iGAAmB,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,YAAY,EACV,gBAAgB,EAChB,iBAAiB,EACjB,eAAe,EACf,eAAe,GAChB,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAC9D,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC9E,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * RAW photo engine subpath export (`@intactfile/engines/raw`). Pure-TS
3
+ * structural repair for TIFF-family RAW (CR2/NEF/ARW/DNG), CR3 and RAF:
4
+ * strip-prefix, fix-header, validate, and embedded-preview recovery. No LibRaw,
5
+ * no mosaic development. Kept out of the root barrel so bundles that don't
6
+ * repair RAW stay lean; diagnosis is pure byte-scanning and exported from root.
7
+ */
8
+ import { gate } from "../license.js";
9
+ import { repairRaw as _repairRaw } from "./repair.js";
10
+ export const repairRaw = gate(_repairRaw);
11
+ export { repairRawBytes } from "./repair.js";
12
+ export { diagnoseRaw, diagnoseRawBytes } from "./diagnose.js";
13
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/raw/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AACrC,OAAO,EAAE,SAAS,IAAI,UAAU,EAAE,MAAM,aAAa,CAAC;AAEtD,MAAM,CAAC,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAQ7C,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Honest RAW *container* repair (docs/engineering/engine-raw-photo.md). Like the
3
+ * JPEG engine, this repairs structure — it never develops the mosaic sensor data
4
+ * (no LibRaw) and never invents pixels.
5
+ *
6
+ * Ladder, applied in order and re-validated:
7
+ * 1. strip-prefix — drop a garbage prefix so the TIFF/RAF/CR3 magic sits at 0;
8
+ * 2. fix-header — restore a corrupt TIFF "42" magic when the II/MM mark
9
+ * survived;
10
+ * 3. validate — if the container now walks clean, emit it as the repair;
11
+ * 4. preview-recover— when the IFD index/payload is unrecoverable in v1
12
+ * (truncated / bad offsets), extract the embedded full-size
13
+ * JPEG preview as an honest partial recovery.
14
+ *
15
+ * Outcome is `success` only when a structurally valid container is produced;
16
+ * a preview-only salvage is reported as `partial`; otherwise `failed`.
17
+ */
18
+ import type { ByteSource } from "../byte-source.js";
19
+ import { type RawDamageClass } from "./diagnose.js";
20
+ import { type ByteOrder, type RawContainer } from "./format.js";
21
+ export type RawRepairOutcome = "success" | "partial" | "failed";
22
+ export type RawRepairStrategy = "strip-prefix" | "fix-header" | "validated" | "preview-recover";
23
+ export interface RawRepairReport {
24
+ outcome: RawRepairOutcome;
25
+ damageClass: RawDamageClass;
26
+ container: RawContainer | "unknown";
27
+ order?: ByteOrder;
28
+ /** Winning strategy, or null when nothing worked. */
29
+ strategy: RawRepairStrategy | null;
30
+ /** Human-readable list of what was actually recovered. */
31
+ salvaged: string[];
32
+ notes: string[];
33
+ bytesIn: number;
34
+ bytesOut: number;
35
+ previewSource: "tiff-tag" | "scan" | null;
36
+ }
37
+ export interface RawRepairResult {
38
+ /** A structurally valid RAW container, when one could be produced. */
39
+ image?: Uint8Array;
40
+ /** The embedded JPEG preview — the honest fallback when the RAW can't be rebuilt. */
41
+ preview?: Uint8Array;
42
+ report: RawRepairReport;
43
+ }
44
+ export declare function repairRawBytes(input: Uint8Array): RawRepairResult;
45
+ export declare function repairRaw(src: ByteSource): Promise<RawRepairResult>;
46
+ //# sourceMappingURL=repair.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repair.d.ts","sourceRoot":"","sources":["../../src/raw/repair.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEpD,OAAO,EAAoB,KAAK,cAAc,EAAE,MAAM,eAAe,CAAC;AACtE,OAAO,EAAmB,KAAK,SAAS,EAAE,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAEjF,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAC;AAChE,MAAM,MAAM,iBAAiB,GAAG,cAAc,GAAG,YAAY,GAAG,WAAW,GAAG,iBAAiB,CAAC;AAEhG,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,gBAAgB,CAAC;IAC1B,WAAW,EAAE,cAAc,CAAC;IAC5B,SAAS,EAAE,YAAY,GAAG,SAAS,CAAC;IACpC,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,qDAAqD;IACrD,QAAQ,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACnC,0DAA0D;IAC1D,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,UAAU,GAAG,MAAM,GAAG,IAAI,CAAC;CAC3C;AAED,MAAM,WAAW,eAAe;IAC9B,sEAAsE;IACtE,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,qFAAqF;IACrF,OAAO,CAAC,EAAE,UAAU,CAAC;IACrB,MAAM,EAAE,eAAe,CAAC;CACzB;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,UAAU,GAAG,eAAe,CA+FjE;AAED,wBAAsB,SAAS,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,eAAe,CAAC,CAEzE"}
@@ -0,0 +1,94 @@
1
+ import { readAll } from "../bytes-util.js";
2
+ import { diagnoseRawBytes } from "./diagnose.js";
3
+ import { findLargestJpeg } from "./format.js";
4
+ export function repairRawBytes(input) {
5
+ const bytesIn = input.length;
6
+ const salvaged = [];
7
+ const notes = [];
8
+ const diag = diagnoseRawBytes(input);
9
+ notes.push(...diag.notes);
10
+ const build = (outcome, strategy, out) => ({
11
+ image: out.image,
12
+ preview: out.preview,
13
+ report: {
14
+ outcome,
15
+ damageClass: diag.damageClass,
16
+ container: diag.container,
17
+ order: diag.order,
18
+ strategy,
19
+ salvaged,
20
+ notes,
21
+ bytesIn,
22
+ bytesOut: out.image?.length ?? out.preview?.length ?? 0,
23
+ previewSource: out.previewSource ?? null,
24
+ },
25
+ });
26
+ if (diag.damageClass === "not-raw") {
27
+ notes.push("input is not recognizable as a RAW photo; nothing to repair");
28
+ return build("failed", null, {});
29
+ }
30
+ // 1 + 2: produce a working buffer with the prefix stripped and the header fixed.
31
+ let work = input;
32
+ let acted = null;
33
+ if (diag.prefixBytes > 0) {
34
+ work = input.slice(diag.prefixBytes);
35
+ acted = "strip-prefix";
36
+ salvaged.push(`stripped ${diag.prefixBytes} garbage byte(s) before the RAW header`);
37
+ }
38
+ if (diag.damageClass === "header-damage" && diag.order) {
39
+ work = work === input ? input.slice() : work; // ensure a mutable copy
40
+ if (diag.order === "le") {
41
+ work[2] = 0x2a;
42
+ work[3] = 0x00;
43
+ }
44
+ else {
45
+ work[2] = 0x00;
46
+ work[3] = 0x2a;
47
+ }
48
+ acted = "fix-header";
49
+ salvaged.push("restored the corrupt TIFF 42 magic in the header");
50
+ }
51
+ // 3: re-validate the working buffer.
52
+ const post = diagnoseRawBytes(work);
53
+ if (post.damageClass === "none") {
54
+ if (acted)
55
+ return build("success", acted, { image: work });
56
+ notes.push("container is structurally valid; nothing to repair");
57
+ return build("success", "validated", { image: work });
58
+ }
59
+ // 4: preview recovery. Prefer the TIFF-tag preview, fall back to the largest
60
+ // embedded JPEG found by scanning.
61
+ let chosen = null;
62
+ let source = null;
63
+ if (post.preview &&
64
+ post.preview.length > 3 &&
65
+ post.preview.offset + post.preview.length <= work.length &&
66
+ work[post.preview.offset] === 0xff &&
67
+ work[post.preview.offset + 1] === 0xd8) {
68
+ chosen = { offset: post.preview.offset, length: post.preview.length };
69
+ source = post.preview.source;
70
+ }
71
+ const scan = findLargestJpeg(work);
72
+ if (scan && (!chosen || scan.length > chosen.length)) {
73
+ chosen = scan;
74
+ source = "scan";
75
+ }
76
+ if (chosen && chosen.length > 3) {
77
+ const preview = work.slice(chosen.offset, chosen.offset + chosen.length);
78
+ salvaged.push(`recovered the embedded JPEG preview (${preview.length} bytes)`);
79
+ notes.push("the RAW mosaic/index could not be rebuilt (v1 repairs container structure only); " +
80
+ "the embedded full-size JPEG preview is the honest recovery");
81
+ return build("partial", "preview-recover", { preview, previewSource: source ?? "scan" });
82
+ }
83
+ // Stripped a prefix but couldn't validate and found no preview: still cleaner.
84
+ if (acted === "strip-prefix") {
85
+ notes.push("removed a garbage prefix but could not validate the container or find a preview");
86
+ return build("partial", "strip-prefix", { image: work });
87
+ }
88
+ notes.push("no deterministic repair produced a valid container or a recoverable preview");
89
+ return build("failed", null, {});
90
+ }
91
+ export async function repairRaw(src) {
92
+ return repairRawBytes(await readAll(src));
93
+ }
94
+ //# sourceMappingURL=repair.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repair.js","sourceRoot":"","sources":["../../src/raw/repair.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@intactfile/engines",
3
- "version": "0.2.0",
4
- "description": "IntactFile repair engines (SDK): repair corrupted video, ZIP/Office, PDF, JPEG, PNG, SQLite and RAR/7z entirely in-process. Runs in the browser and in Node — files never leave the machine.",
3
+ "version": "0.3.0",
4
+ "description": "IntactFile repair engines (SDK): repair corrupted video, ZIP/Office, PDF, JPEG, PNG, RAW photo, PSD, audio (WAV/MP3), SQLite and RAR/7z entirely in-process. Runs in the browser and in Node — files never leave the machine.",
5
5
  "private": false,
6
6
  "type": "module",
7
7
  "license": "UNLICENSED",
@@ -42,6 +42,18 @@
42
42
  "./audio": {
43
43
  "types": "./dist/audio/index.d.ts",
44
44
  "default": "./dist/audio/index.js"
45
+ },
46
+ "./raw": {
47
+ "types": "./dist/raw/index.d.ts",
48
+ "default": "./dist/raw/index.js"
49
+ },
50
+ "./psd": {
51
+ "types": "./dist/psd/index.d.ts",
52
+ "default": "./dist/psd/index.js"
53
+ },
54
+ "./office-legacy": {
55
+ "types": "./dist/office-legacy/index.d.ts",
56
+ "default": "./dist/office-legacy/index.js"
45
57
  }
46
58
  },
47
59
  "files": [