extractXMP suggestion
Hello,
Thanks for this library it's really useful ! I'm working on porting it to vanilla javascript (no threejs) because I want to use it in my 3d engine. While doing that I rewrote the extractXMP function and wanted to share it here :
function extractXMP(input) {
const string = new TextDecoder().decode(input);
const start = string.indexOf('<x:xmpmeta');
const endTag = '</x:xmpmeta>';
const end = string.indexOf(endTag);
if (start === -1 || end === -1) return null;
const xml = string.slice(start, end + endTag.length);
const parsedXML = new DOMParser().parseFromString(xml, 'text/xml');
const description = parsedXML.getElementsByTagName('rdf:Description')[0];
const attributes = Array.from(description.attributes)
.map(n=>([n.name.split(':')[1],n.value]))
.map(([k,v])=>[k.substr(0,3).toLowerCase() + k.substr(3),v])
.map(([k,v])=>[k,isNaN(v) ? (v === 'True' || v === 'False' ? v === 'True' : v) : parseFloat(v)])
.slice(1);
return Object.fromEntries(attributes);
}
output :
{
"version": 1,
"gainMapMin": 0,
"gainMapMax": 15.9993,
"gamma": 1,
"offsetSDR": 0.015625,
"offsetHDR": 0.015625,
"hdrCapacityMin": 0,
"hdrCapacityMax": 15.9993,
"baseRenditionIsHDR": false
}
It's not cleaned yet I'll wait to debug it fully to remove useless variable, anyway bundlers tend to do that well. What do you think about using the DOMParser and functional approach to build the output ?
If you want I can share the end result when the whole thing is done. I want to support only decoding HDRJPG using the shaders, not the wasm, to have the smallest lib possible.
Regards
Now I used the function and found a mistake, I had forgotten the loop, I didn't get that there are multiple xml fragments to parse, here is the revised working version :
function extractXMP(input) {
const string = new TextDecoder().decode(input);
const startTag = '<x:xmpmeta';
let start = string.indexOf(startTag);
const endTag = '</x:xmpmeta>';
while (start !== -1) {
const end = string.indexOf(endTag, start);
if (start === -1 || end === -1) return null;
const xml = string.slice(start, end + endTag.length);
const parsedXML = new DOMParser().parseFromString(xml, 'text/xml');
const description = parsedXML.getElementsByTagName('rdf:Description')[0];
const attributes = Object.fromEntries(Array.from(description.attributes)
.map(n => ([n.name.split(':')[1], n.value]))
.map(([k, v]) => [k.substr(0, 3).toLowerCase() + k.substr(3), v])
.map(([k, v]) => [k, isNaN(v) ? (v === 'True' || v === 'False' ? v === 'True' : v) : parseFloat(v)])
.slice(1));
if(attributes.hdrCapacityMax != null){
return attributes;
}
start = string.indexOf(startTag, end);
}
return null;
}