@sweberdev/witness 0.1.0 → 0.2.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 +1 -1
- package/dist/ai-sdk.cjs.map +1 -1
- package/dist/ai-sdk.js +1 -1
- package/dist/bin.cjs +294 -6
- package/dist/bin.cjs.map +1 -1
- package/dist/bin.js +3 -2
- package/dist/bin.js.map +1 -1
- package/dist/chunk-F7OWVTCS.js +307 -0
- package/dist/chunk-F7OWVTCS.js.map +1 -0
- package/dist/{chunk-APXU3MTX.js → chunk-GXMGYIOK.js} +3 -1
- package/dist/chunk-GXMGYIOK.js.map +1 -0
- package/dist/{chunk-DHX7SNWE.js → chunk-O6TADCND.js} +10 -3
- package/dist/chunk-O6TADCND.js.map +1 -0
- package/dist/{chunk-UBRK4CTM.js → chunk-PT57EYD7.js} +14 -10
- package/dist/chunk-PT57EYD7.js.map +1 -0
- package/dist/cli.cjs +294 -6
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +3 -2
- package/dist/elements-auto.cjs +9 -2
- package/dist/elements-auto.cjs.map +1 -1
- package/dist/elements-auto.js +1 -1
- package/dist/elements.cjs +9 -2
- package/dist/elements.cjs.map +1 -1
- package/dist/elements.d.cts +1 -1
- package/dist/elements.d.ts +1 -1
- package/dist/elements.js +1 -1
- package/dist/index.cjs +297 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +45 -2
- package/dist/index.d.ts +45 -2
- package/dist/index.js +13 -1
- package/package.json +2 -2
- package/src/cli.ts +9 -7
- package/src/elements.ts +9 -2
- package/src/image.ts +4 -3
- package/src/index.ts +13 -0
- package/src/media.ts +460 -0
- package/dist/chunk-APXU3MTX.js.map +0 -1
- package/dist/chunk-DHX7SNWE.js.map +0 -1
- package/dist/chunk-UBRK4CTM.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -26,6 +26,7 @@ __export(index_exports, {
|
|
|
26
26
|
createDisclosure: () => createDisclosure,
|
|
27
27
|
createMarking: () => createMarking,
|
|
28
28
|
detectImageFormat: () => detectImageFormat,
|
|
29
|
+
detectMediaFormat: () => detectMediaFormat,
|
|
29
30
|
disclosureText: () => disclosureText,
|
|
30
31
|
escapeHtml: () => escapeHtml,
|
|
31
32
|
format: () => format,
|
|
@@ -36,7 +37,9 @@ __export(index_exports, {
|
|
|
36
37
|
isAiSourceType: () => isAiSourceType,
|
|
37
38
|
labelHtml: () => labelHtml,
|
|
38
39
|
labelText: () => labelText,
|
|
40
|
+
markFile: () => markFile,
|
|
39
41
|
markImage: () => markImage,
|
|
42
|
+
markMedia: () => markMedia,
|
|
40
43
|
markingAttributes: () => markingAttributes,
|
|
41
44
|
markingJsonLd: () => markingJsonLd,
|
|
42
45
|
markingMetaTags: () => markingMetaTags,
|
|
@@ -44,6 +47,8 @@ __export(index_exports, {
|
|
|
44
47
|
nextMetadata: () => nextMetadata,
|
|
45
48
|
parseSourceType: () => parseSourceType,
|
|
46
49
|
readImageMarking: () => readImageMarking,
|
|
50
|
+
readMarking: () => readMarking,
|
|
51
|
+
readMediaMarking: () => readMediaMarking,
|
|
47
52
|
readTextWatermark: () => readTextWatermark,
|
|
48
53
|
registerLocale: () => registerLocale,
|
|
49
54
|
registeredLocales: () => registeredLocales,
|
|
@@ -1182,6 +1187,293 @@ function unescapeXml(value) {
|
|
|
1182
1187
|
return value.replace(/"/g, '"').replace(/</g, "<").replace(/>/g, ">").replace(/'/g, "'").replace(/&/g, "&");
|
|
1183
1188
|
}
|
|
1184
1189
|
|
|
1190
|
+
// src/media.ts
|
|
1191
|
+
var XMP_UUID = hex("be7acfcb97a942e89c71999491e3afac");
|
|
1192
|
+
var C2PA_UUID = hex("d8fec3d61b0e483c92975828877ec481");
|
|
1193
|
+
function detectMediaFormat(bytes) {
|
|
1194
|
+
if (bytes.length >= 10 && ascii2(bytes, 0, 3) === "ID3") return "mp3";
|
|
1195
|
+
if (isMpegAudioFrame(bytes, 0)) return "mp3";
|
|
1196
|
+
if (bytes.length >= 12 && ascii2(bytes, 0, 4) === "RIFF" && ascii2(bytes, 8, 4) === "WAVE") {
|
|
1197
|
+
return "wav";
|
|
1198
|
+
}
|
|
1199
|
+
if (bytes.length >= 12 && ascii2(bytes, 4, 4) === "ftyp") return "mp4";
|
|
1200
|
+
return null;
|
|
1201
|
+
}
|
|
1202
|
+
function markMedia(bytes, input = {}, options = {}) {
|
|
1203
|
+
const format2 = detectMediaFormat(bytes);
|
|
1204
|
+
if (!format2) return { bytes, status: "unsupported", format: format2 };
|
|
1205
|
+
const parsed = parse(bytes, format2);
|
|
1206
|
+
if (!parsed) return { bytes, status: "unsupported", format: format2 };
|
|
1207
|
+
if (options.c2pa !== "overwrite" && parsed.c2pa) {
|
|
1208
|
+
return { bytes, status: "skipped-c2pa", format: format2 };
|
|
1209
|
+
}
|
|
1210
|
+
const marking = "sourceType" in input && "humanReviewed" in input ? input : createMarking(input);
|
|
1211
|
+
const xmp = buildXmp(marking, parsed.xmp);
|
|
1212
|
+
const out = format2 === "mp3" ? writeMp3(bytes, xmp) : format2 === "wav" ? writeWav(bytes, xmp) : writeMp4(bytes, xmp);
|
|
1213
|
+
if (!out) return { bytes, status: "unsupported", format: format2 };
|
|
1214
|
+
return { bytes: out, status: "marked", format: format2 };
|
|
1215
|
+
}
|
|
1216
|
+
function readMediaMarking(bytes) {
|
|
1217
|
+
const format2 = detectMediaFormat(bytes);
|
|
1218
|
+
const parsed = format2 ? parse(bytes, format2) : null;
|
|
1219
|
+
if (!format2 || !parsed) {
|
|
1220
|
+
return { format: format2, xmp: null, aiGenerated: false, witness: false, c2pa: false };
|
|
1221
|
+
}
|
|
1222
|
+
return describe(format2, parsed.xmp, parsed.c2pa);
|
|
1223
|
+
}
|
|
1224
|
+
function markFile(bytes, input = {}, options = {}) {
|
|
1225
|
+
if (detectImageFormat(bytes)) return markImage(bytes, input, options);
|
|
1226
|
+
return markMedia(bytes, input, options);
|
|
1227
|
+
}
|
|
1228
|
+
function readMarking(bytes) {
|
|
1229
|
+
if (detectImageFormat(bytes)) return readImageMarking(bytes);
|
|
1230
|
+
return readMediaMarking(bytes);
|
|
1231
|
+
}
|
|
1232
|
+
function describe(format2, xmp, c2pa) {
|
|
1233
|
+
const sourceType = xmp ? parseSourceType(xmpProperty(xmp, "Iptc4xmpExt:DigitalSourceType")) : void 0;
|
|
1234
|
+
const generator = xmp ? xmpProperty(xmp, "Iptc4xmpExt:AISystemUsed") ?? xmpProperty(xmp, "xmp:CreatorTool") : void 0;
|
|
1235
|
+
const info = {
|
|
1236
|
+
format: format2,
|
|
1237
|
+
xmp,
|
|
1238
|
+
aiGenerated: isAiSourceType(sourceType),
|
|
1239
|
+
witness: xmp?.includes(WITNESS_NS) ?? false,
|
|
1240
|
+
c2pa
|
|
1241
|
+
};
|
|
1242
|
+
if (sourceType) info.sourceType = sourceType;
|
|
1243
|
+
if (generator) info.generator = generator;
|
|
1244
|
+
return info;
|
|
1245
|
+
}
|
|
1246
|
+
function parse(bytes, format2) {
|
|
1247
|
+
if (format2 === "mp3") {
|
|
1248
|
+
const tag = readId3(bytes);
|
|
1249
|
+
if (tag === "unsupported") return null;
|
|
1250
|
+
if (!tag) return { xmp: null, c2pa: false };
|
|
1251
|
+
const xmpFrame = tag.frames.find((f) => f.id === "PRIV" && isXmpPriv(bytes, f));
|
|
1252
|
+
return {
|
|
1253
|
+
xmp: xmpFrame ? decode(bytes.subarray(xmpFrame.dataStart + 4, xmpFrame.end)) : null,
|
|
1254
|
+
c2pa: tag.frames.some(
|
|
1255
|
+
(f) => f.id === "GEOB" && ascii2(bytes, f.dataStart, Math.min(64, f.end - f.dataStart)).toLowerCase().includes("c2pa")
|
|
1256
|
+
)
|
|
1257
|
+
};
|
|
1258
|
+
}
|
|
1259
|
+
if (format2 === "wav") {
|
|
1260
|
+
const chunks = riffChunks(bytes);
|
|
1261
|
+
if (!chunks) return null;
|
|
1262
|
+
const xmp2 = chunks.find((c) => c.fourcc === "_PMX");
|
|
1263
|
+
return {
|
|
1264
|
+
xmp: xmp2 ? decode(bytes.subarray(xmp2.dataStart, xmp2.dataEnd)) : null,
|
|
1265
|
+
c2pa: chunks.some((c) => c.fourcc === "C2PA")
|
|
1266
|
+
};
|
|
1267
|
+
}
|
|
1268
|
+
const boxes = mp4Boxes(bytes);
|
|
1269
|
+
if (!boxes) return null;
|
|
1270
|
+
const xmp = boxes.find((b) => isUuidBox(bytes, b, XMP_UUID));
|
|
1271
|
+
return {
|
|
1272
|
+
xmp: xmp ? decode(bytes.subarray(xmp.dataStart + 16, xmp.end)) : null,
|
|
1273
|
+
c2pa: boxes.some((b) => isUuidBox(bytes, b, C2PA_UUID))
|
|
1274
|
+
};
|
|
1275
|
+
}
|
|
1276
|
+
function readId3(bytes) {
|
|
1277
|
+
if (ascii2(bytes, 0, 3) !== "ID3") return null;
|
|
1278
|
+
const version = bytes[3];
|
|
1279
|
+
const flags = bytes[5] ?? 0;
|
|
1280
|
+
if (version !== 3 && version !== 4) return "unsupported";
|
|
1281
|
+
if (flags & 128 || flags & 16) return "unsupported";
|
|
1282
|
+
const length = 10 + syncsafe(bytes, 6);
|
|
1283
|
+
if (length > bytes.length) return "unsupported";
|
|
1284
|
+
let offset = 10;
|
|
1285
|
+
if (flags & 64) {
|
|
1286
|
+
offset += version === 4 ? syncsafe(bytes, 10) : 4 + readU32BE2(bytes, 10);
|
|
1287
|
+
}
|
|
1288
|
+
const frames = [];
|
|
1289
|
+
while (offset + 10 <= length) {
|
|
1290
|
+
const id = ascii2(bytes, offset, 4);
|
|
1291
|
+
if (!/^[A-Z0-9]{4}$/.test(id)) break;
|
|
1292
|
+
const size = version === 4 ? syncsafe(bytes, offset + 4) : readU32BE2(bytes, offset + 4);
|
|
1293
|
+
const end = offset + 10 + size;
|
|
1294
|
+
if (end > length) return "unsupported";
|
|
1295
|
+
frames.push({ id, start: offset, dataStart: offset + 10, end });
|
|
1296
|
+
offset = end;
|
|
1297
|
+
}
|
|
1298
|
+
return { version, length, frames };
|
|
1299
|
+
}
|
|
1300
|
+
function isXmpPriv(bytes, frame) {
|
|
1301
|
+
return ascii2(bytes, frame.dataStart, 4) === "XMP\0";
|
|
1302
|
+
}
|
|
1303
|
+
function writeMp3(bytes, xmp) {
|
|
1304
|
+
const tag = readId3(bytes);
|
|
1305
|
+
if (tag === "unsupported") return null;
|
|
1306
|
+
const version = tag ? tag.version : 4;
|
|
1307
|
+
const kept = tag ? tag.frames.filter((f) => !(f.id === "PRIV" && isXmpPriv(bytes, f))).map((f) => bytes.subarray(f.start, f.end)) : [];
|
|
1308
|
+
const data = concat2(latin12("XMP\0"), utf82(xmp));
|
|
1309
|
+
const frame = new Uint8Array(10 + data.length);
|
|
1310
|
+
frame.set(latin12("PRIV"), 0);
|
|
1311
|
+
if (version === 4) writeSyncsafe(frame, 4, data.length);
|
|
1312
|
+
else writeU32BE2(frame, 4, data.length);
|
|
1313
|
+
frame.set(data, 10);
|
|
1314
|
+
const body = concat2(...kept, frame, new Uint8Array(64));
|
|
1315
|
+
const header = new Uint8Array(10);
|
|
1316
|
+
header.set(latin12("ID3"), 0);
|
|
1317
|
+
header[3] = version;
|
|
1318
|
+
writeSyncsafe(header, 6, body.length);
|
|
1319
|
+
return concat2(header, body, bytes.subarray(tag ? tag.length : 0));
|
|
1320
|
+
}
|
|
1321
|
+
function isMpegAudioFrame(bytes, offset) {
|
|
1322
|
+
const b1 = bytes[offset + 1] ?? 0;
|
|
1323
|
+
return bytes[offset] === 255 && (b1 & 224) === 224 && (b1 & 24) !== 8 && (b1 & 6) !== 0;
|
|
1324
|
+
}
|
|
1325
|
+
function syncsafe(b, o) {
|
|
1326
|
+
return ((b[o] ?? 0) & 127) << 21 | ((b[o + 1] ?? 0) & 127) << 14 | ((b[o + 2] ?? 0) & 127) << 7 | (b[o + 3] ?? 0) & 127;
|
|
1327
|
+
}
|
|
1328
|
+
function writeSyncsafe(b, o, v) {
|
|
1329
|
+
b[o] = v >>> 21 & 127;
|
|
1330
|
+
b[o + 1] = v >>> 14 & 127;
|
|
1331
|
+
b[o + 2] = v >>> 7 & 127;
|
|
1332
|
+
b[o + 3] = v & 127;
|
|
1333
|
+
}
|
|
1334
|
+
function riffChunks(bytes) {
|
|
1335
|
+
const chunks = [];
|
|
1336
|
+
const limit = Math.min(bytes.length, 8 + readU32LE2(bytes, 4));
|
|
1337
|
+
let offset = 12;
|
|
1338
|
+
while (offset + 8 <= limit) {
|
|
1339
|
+
const size = readU32LE2(bytes, offset + 4);
|
|
1340
|
+
const dataEnd = offset + 8 + size;
|
|
1341
|
+
if (dataEnd > bytes.length) return null;
|
|
1342
|
+
const end = Math.min(dataEnd + size % 2, bytes.length);
|
|
1343
|
+
chunks.push({
|
|
1344
|
+
fourcc: ascii2(bytes, offset, 4),
|
|
1345
|
+
start: offset,
|
|
1346
|
+
dataStart: offset + 8,
|
|
1347
|
+
dataEnd,
|
|
1348
|
+
end
|
|
1349
|
+
});
|
|
1350
|
+
offset = end;
|
|
1351
|
+
}
|
|
1352
|
+
return chunks;
|
|
1353
|
+
}
|
|
1354
|
+
function writeWav(bytes, xmp) {
|
|
1355
|
+
const chunks = riffChunks(bytes);
|
|
1356
|
+
if (!chunks) return null;
|
|
1357
|
+
const data = utf82(xmp);
|
|
1358
|
+
const chunk = new Uint8Array(8 + data.length + data.length % 2);
|
|
1359
|
+
chunk.set(latin12("_PMX"), 0);
|
|
1360
|
+
writeU32LE2(chunk, 4, data.length);
|
|
1361
|
+
chunk.set(data, 8);
|
|
1362
|
+
const body = concat2(
|
|
1363
|
+
...chunks.filter((c) => c.fourcc !== "_PMX").map((c) => bytes.subarray(c.start, c.end)),
|
|
1364
|
+
chunk
|
|
1365
|
+
);
|
|
1366
|
+
const out = concat2(bytes.subarray(0, 12), body);
|
|
1367
|
+
writeU32LE2(out, 4, out.length - 8);
|
|
1368
|
+
return out;
|
|
1369
|
+
}
|
|
1370
|
+
function mp4Boxes(bytes) {
|
|
1371
|
+
const boxes = [];
|
|
1372
|
+
let offset = 0;
|
|
1373
|
+
while (offset + 8 <= bytes.length) {
|
|
1374
|
+
const size = readU32BE2(bytes, offset);
|
|
1375
|
+
const type = ascii2(bytes, offset + 4, 4);
|
|
1376
|
+
let header = 8;
|
|
1377
|
+
let end;
|
|
1378
|
+
if (size === 1) {
|
|
1379
|
+
if (offset + 16 > bytes.length) return null;
|
|
1380
|
+
const high = readU32BE2(bytes, offset + 8);
|
|
1381
|
+
end = offset + high * 2 ** 32 + readU32BE2(bytes, offset + 12);
|
|
1382
|
+
header = 16;
|
|
1383
|
+
} else if (size === 0) {
|
|
1384
|
+
end = bytes.length;
|
|
1385
|
+
} else {
|
|
1386
|
+
end = offset + size;
|
|
1387
|
+
}
|
|
1388
|
+
if (end > bytes.length || end < offset + header) return null;
|
|
1389
|
+
boxes.push({ type, start: offset, dataStart: offset + header, end, open: size === 0 });
|
|
1390
|
+
offset = end;
|
|
1391
|
+
}
|
|
1392
|
+
return boxes;
|
|
1393
|
+
}
|
|
1394
|
+
function isUuidBox(bytes, box, uuid) {
|
|
1395
|
+
if (box.type !== "uuid" || box.end - box.dataStart < 16) return false;
|
|
1396
|
+
for (let i = 0; i < 16; i++) if (bytes[box.dataStart + i] !== uuid[i]) return false;
|
|
1397
|
+
return true;
|
|
1398
|
+
}
|
|
1399
|
+
function writeMp4(bytes, xmp) {
|
|
1400
|
+
const boxes = mp4Boxes(bytes);
|
|
1401
|
+
if (!boxes) return null;
|
|
1402
|
+
const last = boxes[boxes.length - 1];
|
|
1403
|
+
let head = bytes;
|
|
1404
|
+
let length = bytes.length;
|
|
1405
|
+
if (last && isUuidBox(bytes, last, XMP_UUID)) length = last.start;
|
|
1406
|
+
head = bytes.slice(0, length);
|
|
1407
|
+
for (const box2 of boxes) {
|
|
1408
|
+
if (box2.start < length && isUuidBox(bytes, box2, XMP_UUID)) {
|
|
1409
|
+
head.set(latin12("free"), box2.start + 4);
|
|
1410
|
+
}
|
|
1411
|
+
}
|
|
1412
|
+
const open = boxes.find((b) => b.open && b.start < length);
|
|
1413
|
+
if (open) {
|
|
1414
|
+
const size = length - open.start;
|
|
1415
|
+
if (size > 4294967295) return null;
|
|
1416
|
+
writeU32BE2(head, open.start, size);
|
|
1417
|
+
}
|
|
1418
|
+
const data = utf82(xmp);
|
|
1419
|
+
const box = new Uint8Array(8 + 16 + data.length);
|
|
1420
|
+
writeU32BE2(box, 0, box.length);
|
|
1421
|
+
box.set(latin12("uuid"), 4);
|
|
1422
|
+
box.set(XMP_UUID, 8);
|
|
1423
|
+
box.set(data, 24);
|
|
1424
|
+
return concat2(head, box);
|
|
1425
|
+
}
|
|
1426
|
+
function hex(value) {
|
|
1427
|
+
const out = new Uint8Array(value.length / 2);
|
|
1428
|
+
for (let i = 0; i < out.length; i++) out[i] = Number.parseInt(value.slice(i * 2, i * 2 + 2), 16);
|
|
1429
|
+
return out;
|
|
1430
|
+
}
|
|
1431
|
+
function decode(bytes) {
|
|
1432
|
+
return new TextDecoder().decode(bytes).replace(/\0+$/, "");
|
|
1433
|
+
}
|
|
1434
|
+
function ascii2(bytes, offset, length) {
|
|
1435
|
+
let out = "";
|
|
1436
|
+
for (let i = offset; i < offset + length && i < bytes.length; i++) {
|
|
1437
|
+
out += String.fromCharCode(bytes[i] ?? 0);
|
|
1438
|
+
}
|
|
1439
|
+
return out;
|
|
1440
|
+
}
|
|
1441
|
+
function latin12(text) {
|
|
1442
|
+
const out = new Uint8Array(text.length);
|
|
1443
|
+
for (let i = 0; i < text.length; i++) out[i] = text.charCodeAt(i) & 255;
|
|
1444
|
+
return out;
|
|
1445
|
+
}
|
|
1446
|
+
function utf82(text) {
|
|
1447
|
+
return new TextEncoder().encode(text);
|
|
1448
|
+
}
|
|
1449
|
+
function concat2(...parts) {
|
|
1450
|
+
const out = new Uint8Array(parts.reduce((sum, part) => sum + part.length, 0));
|
|
1451
|
+
let offset = 0;
|
|
1452
|
+
for (const part of parts) {
|
|
1453
|
+
out.set(part, offset);
|
|
1454
|
+
offset += part.length;
|
|
1455
|
+
}
|
|
1456
|
+
return out;
|
|
1457
|
+
}
|
|
1458
|
+
function readU32BE2(b, o) {
|
|
1459
|
+
return ((b[o] ?? 0) << 24 | (b[o + 1] ?? 0) << 16 | (b[o + 2] ?? 0) << 8 | (b[o + 3] ?? 0)) >>> 0;
|
|
1460
|
+
}
|
|
1461
|
+
function readU32LE2(b, o) {
|
|
1462
|
+
return ((b[o] ?? 0) | (b[o + 1] ?? 0) << 8 | (b[o + 2] ?? 0) << 16 | (b[o + 3] ?? 0) << 24) >>> 0;
|
|
1463
|
+
}
|
|
1464
|
+
function writeU32BE2(b, o, v) {
|
|
1465
|
+
b[o] = v >>> 24 & 255;
|
|
1466
|
+
b[o + 1] = v >>> 16 & 255;
|
|
1467
|
+
b[o + 2] = v >>> 8 & 255;
|
|
1468
|
+
b[o + 3] = v & 255;
|
|
1469
|
+
}
|
|
1470
|
+
function writeU32LE2(b, o, v) {
|
|
1471
|
+
b[o] = v & 255;
|
|
1472
|
+
b[o + 1] = v >>> 8 & 255;
|
|
1473
|
+
b[o + 2] = v >>> 16 & 255;
|
|
1474
|
+
b[o + 3] = v >>> 24 & 255;
|
|
1475
|
+
}
|
|
1476
|
+
|
|
1185
1477
|
// src/types.ts
|
|
1186
1478
|
var DISCLOSURE_KINDS = [
|
|
1187
1479
|
"chatbot",
|
|
@@ -1312,6 +1604,7 @@ function findInRun(bytes) {
|
|
|
1312
1604
|
createDisclosure,
|
|
1313
1605
|
createMarking,
|
|
1314
1606
|
detectImageFormat,
|
|
1607
|
+
detectMediaFormat,
|
|
1315
1608
|
disclosureText,
|
|
1316
1609
|
escapeHtml,
|
|
1317
1610
|
format,
|
|
@@ -1322,7 +1615,9 @@ function findInRun(bytes) {
|
|
|
1322
1615
|
isAiSourceType,
|
|
1323
1616
|
labelHtml,
|
|
1324
1617
|
labelText,
|
|
1618
|
+
markFile,
|
|
1325
1619
|
markImage,
|
|
1620
|
+
markMedia,
|
|
1326
1621
|
markingAttributes,
|
|
1327
1622
|
markingJsonLd,
|
|
1328
1623
|
markingMetaTags,
|
|
@@ -1330,6 +1625,8 @@ function findInRun(bytes) {
|
|
|
1330
1625
|
nextMetadata,
|
|
1331
1626
|
parseSourceType,
|
|
1332
1627
|
readImageMarking,
|
|
1628
|
+
readMarking,
|
|
1629
|
+
readMediaMarking,
|
|
1333
1630
|
readTextWatermark,
|
|
1334
1631
|
registerLocale,
|
|
1335
1632
|
registeredLocales,
|