Pick up Exif "SceneType" for camera detection

This commit is contained in:
N-Pex 2025-11-03 09:17:09 +01:00
parent c66602deb7
commit d26f72baec

View file

@ -148,6 +148,7 @@ const pathsC2PACreationDate = (): FlagValue[] => {
const pathsC2PACamera = (): FlagValue[] => { const pathsC2PACamera = (): FlagValue[] => {
return [ return [
{path: "integrity/c2pa/manifest_info/manifests[]/assertions[label=stds.exif]/data{exif:SceneType=1|directly photographed image}"},
{path: "integrity/c2pa/manifest_info/manifests[]/assertions[label=stds.exif]/data/exif:LensMake"}, {path: "integrity/c2pa/manifest_info/manifests[]/assertions[label=stds.exif]/data/exif:LensMake"},
{path: "integrity/c2pa/manifest_info/manifests[]/assertions[label=stds.exif]/data/exif:LensModel"}, {path: "integrity/c2pa/manifest_info/manifests[]/assertions[label=stds.exif]/data/exif:LensModel"},
]; ];
@ -155,6 +156,7 @@ const pathsC2PACamera = (): FlagValue[] => {
const pathsExifCamera = (): FlagValue[] => { const pathsExifCamera = (): FlagValue[] => {
return [ return [
{path: "integrity/exif{SceneType=1|directly photographed image}"},
{path: "integrity/exif/LensMake"}, {path: "integrity/exif/LensMake"},
{path: "integrity/exif/LensModel"}, {path: "integrity/exif/LensModel"},
]; ];
@ -263,69 +265,76 @@ const extractFlagValues = (flagPath: string, path: FlagMatchRulePathSegment[]):
path: FlagMatchRulePathSegment[] path: FlagMatchRulePathSegment[]
): FlagMatchRuleValue[] | undefined => { ): FlagMatchRuleValue[] | undefined => {
if (keys.length == 0 || path.length == 0) return undefined; if (keys.length == 0 || path.length == 0) return undefined;
const o = path[0].object; const o = path[0].object;
let key = keys[0]; let key = keys[0];
const lastBracket = key.lastIndexOf("[");
if (key === "..") { if (key === "..") {
return getValues(keys.slice(1), path.slice(1)); return getValues(keys.slice(1), path.slice(1));
} }
if (key.endsWith("]") && lastBracket > 0) {
const optionalConstraint = key.substring(lastBracket + 1, key.length - 1); const lastBracket = key.lastIndexOf("[");
const hasBracket = key.endsWith("]") && lastBracket > 0;
const lastBrace = key.lastIndexOf("{");
const hasBrace = key.endsWith("}") && lastBrace > 0;
let optionalConstraint: String | undefined = undefined;
if (hasBracket) {
optionalConstraint = key.substring(lastBracket + 1, key.length - 1);
key = key.substring(0, lastBracket); key = key.substring(0, lastBracket);
if (o[key] != undefined) { } else if (hasBrace) {
let opart: any[] = o[key]; optionalConstraint = key.substring(lastBrace + 1, key.length - 1);
if (!Array.isArray(opart)) { key = key.substring(0, lastBrace);
opart = Object.values(opart) ?? []; }
}
// Any constraints controlling what array object(s) to consider? let nextObject = o[key];
if (optionalConstraint) { let omatches: any[] = nextObject ? (Array.isArray(nextObject) ? nextObject : hasBracket ? Object.values(nextObject) : [nextObject]) : [];
if (optionalConstraint.startsWith("!!")) {
// Ignore this path in the tree if ANY of the values contain the constraint match.
const [prop, val] = optionalConstraint.substring(2).split("=");
if (opart.some((item) => item[prop] === val)) {
return undefined;
}
} else if (optionalConstraint.startsWith("!")) {
const [prop, val] = optionalConstraint.substring(1).split("=");
opart = opart.filter((item) => item[prop] !== val);
} else {
const [prop, val] = optionalConstraint.split("=");
let valarray = val.split("|");
opart = opart.filter((item) => valarray.includes(item[prop]));
}
}
if (keys.length == 1) { // Any constraints controlling what array object(s) to consider?
return opart.map((s, i) => { if (optionalConstraint) {
return { value: o, path: [{ object: s, path: key + "[" + i + "]"}, ... path] }; if (optionalConstraint.startsWith("!!")) {
}); // Ignore this path in the tree if ANY of the values contain the constraint match.
} else { const [prop, val] = optionalConstraint.substring(2).split("=");
return opart.reduce((res: FlagMatchRuleValue[] | undefined, oin: any, i: number) => { let valarray = val.split("|");
let matches = getValues(keys.slice(1), [ { object: oin, path: key + "[" + i + "]"}, ... path]); if (omatches.some((item) => valarray.includes(item[prop]))) {
if (matches) { omatches = [];
const r2 = res || [];
r2.push(...matches);
return r2;
}
return res;
}, undefined);
} }
} else if (optionalConstraint.startsWith("!")) {
const [prop, val] = optionalConstraint.substring(1).split("=");
let valarray = val.split("|");
omatches = omatches.filter((m) => {
return valarray.includes(m[prop]);
});
} else { } else {
return undefined; const [prop, val] = optionalConstraint.split("=");
let valarray = val.split("|");
omatches = omatches.filter((m) => {
return valarray.includes(m[prop]);
});
}
}
if (omatches.length > 0) {
if (keys.length == 1) {
return omatches.map((oin, i) => {
return { value: oin, path: [{ object: oin, path: key + (omatches.length > 1 ? `[${i}]` : "") }, ...path] };
});
} else if (omatches.length == 1) {
return getValues(keys.slice(1), [{object: omatches[0], path: key}, ...path]);
} else {
return omatches.reduce((res: FlagMatchRuleValue[] | undefined, oin: any, i: number) => {
let matches = getValues(keys.slice(1), [{ object: oin, path: key + "[" + i + "]" }, ...path]);
if (matches) {
const r2 = res || [];
r2.push(...matches);
return r2;
}
return res;
}, undefined);
} }
} else { } else {
if (o[key] != undefined) { return undefined;
if (keys.length == 1) {
return [{ value: o[key], path: [{object: o[key], path: key}, ...path] }];
} else {
return getValues(keys.slice(1), [{object: o[key], path: key}, ...path]);
}
} else {
return undefined;
}
} }
}; };