@privateid/ultra-web-sdk-alpha
Version:
CryptoNets WebAssembly SDK
862 lines (762 loc) • 30.6 kB
JavaScript
/* eslint-disable no-eval */
/* eslint-disable default-param-last */
/* eslint-disable no-undef */
/* eslint-disable no-underscore-dangle */
// importScripts('https://unpkg.com/comlink/dist/umd/comlink.js');
importScripts('./comlink.min.js');
var wasmPrivModules;
let apiUrl;
let sesstionToken;
let publicKey;
let debugType;
let inputPtr;
let imageInputSize;
let barCodePtr;
let privid_wasm_result = null;
let privid_wasm_error = null;
let wasmSession = null;
let setCache = true;
let checkWasmLoaded = false;
let antispoofVersion;
const ModuleName = 'ultra';
const cdnUrl = 'https://ultra-wasm.devel.privateid.com'; //Devel
// const cdnUrl = 'https://ultra-wasm.privateid.com/wasm'; // Prod
let useCdnLink = true;
const createImageArguments = (imageData, width, height) => {};
const createStringArguments = () => {};
const isLoad = (
simd,
url,
session_token,
public_key,
debug_type,
cacheConfig = true,
timeout = 5000,
useCdn = false,
shouldRegenerateSession,
failureCb,
usageScenario,
) =>
new Promise(async (resolve, reject) => {
apiUrl = url;
sesstionToken = session_token;
publicKey = public_key;
useCdnLink = useCdn;
privid_wasm_error = failureCb;
if (debug_type) {
debugType = debug_type;
}
let timeoutSession = 5000;
if (timeout) {
timeoutSession = timeout;
}
setCache = cacheConfig;
console.log('data', { simd, url, session_token, public_key, debug_type });
const modulePath = simd ? 'simd' : 'nosimd';
const moduleName = 'privid_fhe_uber';
const cachedModule = await readKey(ModuleName);
// const fetchdVersion = await fetchdWasmVersion.json();
const fetchdWasmVersion = await (await fetch(`../wasm/${ModuleName}/${modulePath}/version.json`)).json();
// console.log(
// `${cdnUrl}/wasm/${ModuleName}/${modulePath}/version.json`,
// `../wasm/${ModuleName}/${modulePath}/version.json`,
// );
// console.log(
// `check version ${`${
// cachedModule ? cachedModule?.version.toString() : 'no cached version'
// } - ${fetchdWasmVersion?.version.toString()}`}`,
// );
// const fetchdWasmVersion = await fetchResource(
// // `${cdnUrl}/wasm/${ModuleName}/${modulePath}/version.json`,
// `../wasm/${ModuleName}/${}/${modulePath}/version.json`,
// `../wasm/${ModuleName}/${modulePath}/version.json`,
// );
console.log(
'versions: cached:' +
`${cachedModule ? cachedModule?.version.toString() : 'no cached wasm'}` +
' fetched:' +
`${fetchdWasmVersion ? fetchdWasmVersion.version.toString() : 'no fetched version'}`,
);
const loadFromPackage = async () => {
console.log('fetched version?:', fetchdWasmVersion);
wasmPrivModules = await loadWasmModule(modulePath, moduleName, true, `${fetchdWasmVersion.version}`);
console.log('ULTRA MODULE', wasmPrivModules);
if (!checkWasmLoaded) {
await initializeWasmSession(url, sesstionToken, publicKey, debugType, timeoutSession, usageScenario);
checkWasmLoaded = true;
}
// console.log('WASM MODULES:', wasmPrivModules);
resolve('Loaded');
};
if (
cachedModule &&
cachedModule.version &&
fetchdWasmVersion &&
fetchdWasmVersion.version &&
cachedModule.version.toString() === fetchdWasmVersion?.version.toString()
) {
console.log('same version confirmed');
console.log('IS PRIVMODULES LOADED?', wasmPrivModules);
if (!wasmPrivModules) {
const { cachedWasm, cachedScript } = cachedModule;
if (cachedWasm && cachedScript) {
eval(cachedScript);
wasmPrivModules = await createTFLiteModule({ wasmBinary: cachedWasm });
console.log('ULTRA MODULE', wasmPrivModules);
if (!checkWasmLoaded) {
await initializeWasmSession(url, sesstionToken, publicKey, debugType, timeoutSession, usageScenario);
checkWasmLoaded = true;
}
console.log('WASM MODULES:', wasmPrivModules);
} else {
await loadFromPackage();
}
} else if (wasmPrivModules && shouldRegenerateSession) {
wasmSession = null;
await initializeWasmSession(url, sesstionToken, publicKey, debugType, timeoutSession, usageScenario);
} else {
console.log('----------->line 106 <---------------');
await loadFromPackage();
}
resolve('Cache Loaded');
} else {
await loadFromPackage();
}
});
function flatten(arrays, TypedArray) {
const arr = new TypedArray(arrays.reduce((n, a) => n + a.length, 0));
let i = 0;
arrays.forEach((a) => {
arr.set(a, i);
i += a.length;
});
return arr;
}
const getBufferFromPtr = (bufferPtr, bufferSize) => {
const [outputBufferSize] = new Uint32Array(wasmPrivModules.HEAPU8.buffer, bufferSize, 1);
let outputBufferSecPtr = null;
if (outputBufferSize > 0) {
[outputBufferSecPtr] = new Uint32Array(wasmPrivModules.HEAPU8.buffer, bufferPtr, 1);
}
const outputBufferPtr = new Uint8Array(wasmPrivModules.HEAPU8.buffer, outputBufferSecPtr, outputBufferSize);
const outputBuffer = Uint8ClampedArray.from(outputBufferPtr);
wasmPrivModules._privid_free_char_buffer(outputBufferSecPtr);
const outputBufferData = outputBufferSize > 0 ? outputBuffer : null;
return { outputBufferData, outputBufferSize };
};
const getBufferFromPtrImage = (bufferPtr, outputBufferSize) => {
const outputBufferPtr = new Uint8Array(wasmPrivModules.HEAPU8.buffer, bufferPtr, outputBufferSize);
const outputBuffer = Uint8ClampedArray.from(outputBufferPtr);
return outputBufferSize > 0 ? outputBuffer : null;
};
const ultraEnroll = async (imageData, simd, config, cb) => {
privid_wasm_result = cb;
if (!wasmPrivModules) {
await isLoad(simd, apiUrl, sesstionToken, publicKey, debugType);
}
const imageInputSize = imageData.data.length * imageData.data.BYTES_PER_ELEMENT;
const imageInputPtr = wasmPrivModules._malloc(imageInputSize);
wasmPrivModules.HEAPU8.set(new Uint8Array(imageData.data), imageInputPtr);
const resultFirstPtr = wasmPrivModules._malloc(Int32Array.BYTES_PER_ELEMENT);
const resultLenPtr = wasmPrivModules._malloc(Int32Array.BYTES_PER_ELEMENT);
const encoder = new TextEncoder();
const config_bytes = encoder.encode(`${config}`);
const configInputSize = config_bytes.length;
const configInputPtr = wasmPrivModules._malloc(configInputSize);
const bestImageFirstPtr = wasmPrivModules._malloc(Int32Array.BYTES_PER_ELEMENT);
const bestImageLenPtr = wasmPrivModules._malloc(Int32Array.BYTES_PER_ELEMENT);
wasmPrivModules.HEAP8.set(config_bytes, configInputPtr / config_bytes.BYTES_PER_ELEMENT);
console.log(config);
try {
wasmPrivModules._privid_user_enroll(
wasmSession /* session pointer */,
configInputPtr,
configInputSize,
imageInputPtr /* input images */,
imageData.width /* width of one image */,
imageData.height /* height of one image */,
resultFirstPtr /* operation result output buffer */,
resultLenPtr /* operation result buffer length */,
);
} catch (e) {
console.error('---------__E__-------', e);
}
// let bestImage = null;
// const [outputBufferSize] = new Uint32Array(wasmPrivModules.HEAPU8.buffer, bestImageLenPtr, 1);
// if (outputBufferSize > 0) {
// let outputBufferSecPtr = null;
// [outputBufferSecPtr] = new Uint32Array(wasmPrivModules.HEAPU8.buffer, bestImageFirstPtr, 1);
// const outputBufferPtr = new Uint8Array(wasmPrivModules.HEAPU8.buffer, outputBufferSecPtr, outputBufferSize);
// const outputBuffer = Uint8ClampedArray.from(outputBufferPtr);
// const outputBufferData = outputBufferSize > 0 ? outputBuffer : null;
// bestImage = { imageData: outputBufferData, width: imageData.width, height: imageData.height };
// wasmPrivModules._free(outputBufferPtr);
// }
wasmPrivModules._free(imageInputPtr);
wasmPrivModules._free(resultFirstPtr);
wasmPrivModules._free(resultLenPtr);
wasmPrivModules._free(configInputPtr);
wasmPrivModules._free(bestImageFirstPtr);
wasmPrivModules._free(bestImageLenPtr);
// return bestImage;
};
const ultraAgeEstimate = async (originalImages, simd, config, cb) => {
privid_wasm_result = cb;
if (!wasmPrivModules) {
await isLoad(simd, apiUrl, sesstionToken, publicKey, debugType);
}
const imageInput = flatten(
originalImages.map((x) => x.data),
Uint8Array,
);
const encoder = new TextEncoder();
const config_bytes = encoder.encode(`${config}`);
const configInputSize = config.length;
const configInputPtr = wasmPrivModules._malloc(configInputSize);
wasmPrivModules.HEAP8.set(config_bytes, configInputPtr / config_bytes.BYTES_PER_ELEMENT);
const imageInputSize = imageInput.length * imageInput.BYTES_PER_ELEMENT;
const imageInputPtr = wasmPrivModules._malloc(imageInputSize);
wasmPrivModules.HEAP8.set(imageInput, imageInputPtr / imageInput.BYTES_PER_ELEMENT);
const resultFirstPtr = wasmPrivModules._malloc(Int32Array.BYTES_PER_ELEMENT);
// create a pointer to interger to hold the length of the output buffer
const resultLenPtr = wasmPrivModules._malloc(Int32Array.BYTES_PER_ELEMENT);
console.log('Config:', config);
try {
await wasmPrivModules._privid_estimate_age(
wasmSession /* session pointer */,
configInputPtr,
configInputSize,
imageInputPtr /* input images */,
originalImages[0].width /* width of one image */,
originalImages[0].height /* height of one image */,
resultFirstPtr /* operation result output buffer */,
resultLenPtr /* operation result buffer length */,
);
} catch (e) {
console.error('---------__E__-------', e);
}
wasmPrivModules._free(imageInputPtr);
wasmPrivModules._free(configInputPtr);
wasmPrivModules._free(resultFirstPtr);
wasmPrivModules._free(resultLenPtr);
};
const ultraPredict = async (originalImages, simd, config, cb) => {
privid_wasm_result = cb;
if (!wasmPrivModules) {
await isLoad(simd, apiUrl, sesstionToken, publicKey, debugType);
}
const numImages = originalImages.length;
const imageInput = flatten(
originalImages.map((x) => x.data),
Uint8Array,
);
// const version = wasmPrivModules._get_version();
const encoder = new TextEncoder();
const config_bytes = encoder.encode(`${config}`);
const configInputSize = config.length;
const configInputPtr = wasmPrivModules._malloc(configInputSize);
wasmPrivModules.HEAP8.set(config_bytes, configInputPtr / config_bytes.BYTES_PER_ELEMENT);
const imageInputSize = imageInput.length * imageInput.BYTES_PER_ELEMENT;
const imageInputPtr = wasmPrivModules._malloc(imageInputSize);
wasmPrivModules.HEAP8.set(imageInput, imageInputPtr / imageInput.BYTES_PER_ELEMENT);
const resultFirstPtr = wasmPrivModules._malloc(Int32Array.BYTES_PER_ELEMENT);
// create a pointer to interger to hold the length of the output buffer
const resultLenPtr = wasmPrivModules._malloc(Int32Array.BYTES_PER_ELEMENT);
console.log('Config:', config);
try {
await wasmPrivModules._privid_user_predict(
wasmSession /* session pointer */,
configInputPtr,
configInputSize,
imageInputPtr /* input images */,
originalImages[0].width /* width of one image */,
originalImages[0].height /* height of one image */,
resultFirstPtr /* operation result output buffer */,
resultLenPtr /* operation result buffer length */,
);
} catch (e) {
console.error('---------__E__-------', e);
}
wasmPrivModules._free(imageInputPtr);
wasmPrivModules._free(configInputPtr);
wasmPrivModules._free(resultFirstPtr);
wasmPrivModules._free(resultLenPtr);
};
function readKey(key) {
if (!indexedDB) return Promise.reject(new Error('IndexedDB not available'));
return new Promise((resolve, reject) => {
const open = indexedDB.open('/privid-wasm', 21);
open.onerror = function () {
resolve(false);
};
open.onupgradeneeded = function () {
open.result.createObjectStore('/privid-wasm');
};
open.onsuccess = function () {
const db = open.result;
const tx = db.transaction('/privid-wasm', 'readwrite');
const store = tx.objectStore('/privid-wasm');
const getKey = store.get(key);
getKey.onsuccess = function () {
resolve(getKey.result);
};
tx.onerror = function () {
reject(tx.error);
};
tx.oncomplete = function () {
try {
db.close();
} catch (e) {
//
console.error('readKey', e);
}
};
};
});
}
function putKey(key, cachedWasm, cachedScript, version) {
if (!indexedDB) return Promise.reject(new Error('IndexedDB not available'));
return new Promise((resolve, reject) => {
const open = indexedDB.open('/privid-wasm', 21);
open.onerror = function () {
resolve(false);
};
open.onupgradeneeded = function () {
open.result.createObjectStore('/privid-wasm');
};
open.onsuccess = function () {
const db = open.result;
const tx = db.transaction('/privid-wasm', 'readwrite');
const store = tx.objectStore('/privid-wasm');
const getKey = store.put({ cachedWasm, cachedScript, version }, key);
getKey.onsuccess = function () {
resolve('saved');
};
tx.onerror = function () {
reject(tx.error);
};
tx.oncomplete = function () {
try {
db.close();
} catch (e) {
//
console.error('putKey', e);
}
};
};
});
}
async function setCacheConfiguration() {
const db = indexedDB.open('test');
db.onerror = function () {
console.error('Private browser no cache');
};
db.onsuccess = async function () {
const cacheObj = JSON.stringify({ cache_type: setCache ? 'basic' : 'nocache' });
const encoder = new TextEncoder();
const cache_config_bytes = encoder.encode(`${cacheObj}`);
const cacheInputSize = cacheObj.length;
const cacheInputPtr = wasmPrivModules._malloc(cacheInputSize);
wasmPrivModules.HEAP8.set(cache_config_bytes, cacheInputPtr / cache_config_bytes.BYTES_PER_ELEMENT);
await wasmPrivModules._privid_set_configuration(wasmSession, cacheInputPtr, cacheInputSize);
wasmPrivModules._free(cacheInputPtr);
};
}
/**
* @brief A closure to create a string buffer arguments that can be used with wasm calls
* for a given javascript value.
* This is suitable for native calls that have string input arguments represented with contigious
* string_buffer,sizeofbuffer arguments.
* If the 'text' argument is null or undefined or NaN then the arguments generated are [null,0]
* @usage
*
var url_args= buffer_args(url);
var key_args= buffer_args(key);
var session_out_ptr = output_ptr();
const s_result = wasmPrivModules._privid_initialize_session(
...key_args.args(),
...url_args.args(),
debug_type,
session_out_ptr.outer_ptr(),
);
url_args.free();
key_args.free();
//get
var session = session_out_ptr.inner_ptr();
*
* when .free() is called the closure can be reused to create a buffer for the same string with which, it was created with
* over and over again.
*/
const buffer_args = function (text) {
let strInputtPtr = null;
let strInputSize = 0;
let argsv = [];
return {
args: () => {
do {
if (argsv.length > 0) break;
argsv = [null, 0];
if (text === null) break;
if (text === undefined) break;
// eslint-disable-next-line use-isnan
if (text === NaN) break;
const str = `${text}`;
const encoder = new TextEncoder();
const bytes = encoder.encode(str);
strInputSize = bytes.length * bytes.BYTES_PER_ELEMENT;
strInputtPtr = wasmPrivModules._malloc(strInputSize);
wasmPrivModules.HEAP8.set(bytes, strInputtPtr / bytes.BYTES_PER_ELEMENT);
argsv = [strInputtPtr, strInputSize];
} while (false);
return argsv;
},
free: () => {
if (strInputtPtr) {
wasmPrivModules._free(strInputtPtr);
strInputtPtr = null;
strInputSize = 0;
argsv = [];
}
},
};
};
/**
* @brief A closure to create an output 32bits pointer closure.
* This is usefull for allocating a native address and pass it to the
* 'wasmPrivModules' so it can return in the address of a buffer (or an object like session)
* that was allocated inside the wasm. This typically, correspond to
* an argument of type void** (marked output argument) to pass to a native wasm
* call.
* @usage var myoutput_ptr = output_ptr();
* when passing the output pointer to the 'wasmPrivModules' module use
* wasmPrivModules.nativecall(myoutput_ptr.outer_ptr());
* Then pull out the the allocated buffer by the wasm call this way:
* @code
* my_buffer_or_structure = myoutput_ptr.inner_ptr();
* @note It is the responsability of the caller to free the pointer returned by this inner_ptr()
*/
const output_ptr = function () {
let out_ptr = null;
let in_ptr = null;
const free_ptr = (ptr) => {
if (ptr) {
wasmPrivModules._free(ptr);
// eslint-disable-next-line no-param-reassign
ptr = null;
}
};
return {
/**
* @brief Allocates a pointer to contain the result and return it,
* if the container is already created it will be returned
*/
outer_ptr: () => {
// TODO: may be used SharedArrayBuffer() instead
// allocate memory the expected pointer (outer pointer or container)
if (!out_ptr) out_ptr = wasmPrivModules._malloc(Int32Array.BYTES_PER_ELEMENT);
return out_ptr;
},
/**
* @brief Creates a javascript Uint32Array pointer to contain the result pointed by outer_ptr and return it,
* It is the responsability of the caller to free the pointer returned by this function
*/
inner_ptr: () => {
// If we did not allocate yet the output buffer return null
if (!out_ptr) return null;
// if we already have our inner pointer for this closure return it
if (in_ptr) return in_ptr;
// Access the outer pointer as an arry of uint32 which conatin a single cell
// whose value is the pointer allocated in the wasm module (inner pointer of the output param)
// and return it
[in_ptr] = new Uint32Array(wasmPrivModules.HEAPU8.buffer, out_ptr, 1);
return in_ptr;
},
};
};
async function ultraCompareEmbeddings(encryptedEmbeddingsA, encryptedEmbeddingsB, config, cb) {
try {
privid_wasm_result = cb;
if (!wasmPrivModules) {
await isLoad(simd, apiUrl, sesstionToken, publicKey, debugType);
}
const encoder = new TextEncoder();
const config_bytes = encoder.encode(`${config}`);
const configInputSize = config.length;
const configInputPtr = wasmPrivModules._malloc(configInputSize);
wasmPrivModules.HEAP8.set(config_bytes, configInputPtr / config_bytes.BYTES_PER_ELEMENT);
const embeddingA_bytes = encoder.encode(`${encryptedEmbeddingsA}`);
const embeddingOneSize = encryptedEmbeddingsA.length;
const embeddingOnePtr = wasmPrivModules._malloc(embeddingOneSize);
wasmPrivModules.HEAP8.set(embeddingA_bytes, embeddingOnePtr / embeddingA_bytes.BYTES_PER_ELEMENT);
const embeddingB_bytes = encoder.encode(`${encryptedEmbeddingsB}`);
const embeddingTwoSize = encryptedEmbeddingsB.length;
const embeddingTwoPtr = wasmPrivModules._malloc(embeddingTwoSize);
wasmPrivModules.HEAP8.set(embeddingB_bytes, embeddingTwoPtr / embeddingB_bytes.BYTES_PER_ELEMENT);
const resultFirstPtr = wasmPrivModules._malloc(Int32Array.BYTES_PER_ELEMENT);
// create a pointer to interger to hold the length of the output buffer
const resultLenPtr = wasmPrivModules._malloc(Int32Array.BYTES_PER_ELEMENT);
const result = await wasmPrivModules._privid_compare_embeddings(
wasmSession /* session pointer */,
configInputPtr,
configInputSize,
embeddingOnePtr /* 1st embedding (encrypted string) */,
embeddingOneSize /* 1st embedding size */,
embeddingTwoPtr /* 2nd embedding (encrypted string) */,
embeddingTwoSize /* 2nd embedding size */,
resultFirstPtr /* operation result output buffer */,
resultLenPtr /* operation result buffer length */,
);
wasmPrivModules._free(embeddingOnePtr);
wasmPrivModules._free(embeddingTwoPtr);
wasmPrivModules._free(configInputPtr);
wasmPrivModules._free(resultFirstPtr);
wasmPrivModules._free(resultLenPtr);
return result;
} catch (e) {
console.log('compare embeddings:', e);
}
}
async function initializeWasmSession(url, session_token, public_key, debug_type, timeout = 5000, usageScenario) {
if (!wasmSession) {
console.log('initSession:', { url, session_token, public_key });
const session_out_ptr = output_ptr();
const settings = {
...url,
session_token,
public_key,
debug_level: debug_type ? parseInt(debugType) : 0,
custom_settings: { usage_scenario: usageScenario },
};
console.log('Settings:', settings);
const settings_args = buffer_args(JSON.stringify(settings));
const s_result = wasmPrivModules._privid_initialize_session(...settings_args.args(), session_out_ptr.outer_ptr());
settings_args.free();
const isLoadedModels = wasmPrivModules._privid_check_models();
console.log('Loaded Models?', isLoadedModels);
if (s_result) {
console.log('[DEBUG ISLOAD] : session initialized successfully');
} else {
console.log('[DEBUG ISLOADED] : session initialized failed');
return;
}
wasmSession = session_out_ptr.inner_ptr();
console.log('wasm session?', wasmSession);
// await wasmPrivModules._privid_set_default_configuration(wasmSession, 1);
if (setCache) {
await setCacheConfiguration();
}
} else {
// console.log('Wasm session is available. Skipping creating session');
}
}
const loadWasmModule = async (modulePath, moduleName, saveCache, version) => {
const wasm = await fetchResource(
`${cdnUrl}/${ModuleName}/${modulePath}/${version}/${moduleName}.wasm`,
`../wasm/${ModuleName}/${modulePath}/${version}/${moduleName}.wasm`,
);
const script = await fetchResource(
`${cdnUrl}/${ModuleName}/${modulePath}/${version}/${moduleName}.js`,
`../wasm/${ModuleName}/${modulePath}/${version}/${moduleName}.js`,
);
// const wasm = await fetch(`../wasm/face_mask/${modulePath}/${moduleName}.wasm`);
// const script = await fetch(`../wasm/face_mask/${modulePath}/${moduleName}.js`);
const scriptBuffer = await script.text();
const buffer = await wasm.arrayBuffer();
console.log('SCRIPT. BUFFER', {
scriptBuffer,
buffer,
});
eval(scriptBuffer);
const module = await createTFLiteModule({ wasmBinary: buffer });
console.log('Module:', module);
if (saveCache) {
const version = module.UTF8ToString(module._privid_get_version());
await putKey('ultra', buffer, scriptBuffer, version);
}
return module;
};
async function fetchResource(cdnUrl, localUrl) {
try {
console.log('LOADING RESOURCE!!');
if (useCdnLink) {
const response = await fetch(cdnUrl);
console.log('response?', response);
return response;
} else {
const response = await fetch(localUrl);
return response;
}
} catch (error) {
console.error(`Error fetching resource from CDN. Falling back to local path. Error: ${error}`);
return fetch(localUrl);
}
}
const pkiEncrypt = async (payload, config = JSON.stringify({})) => {
const encoder = new TextEncoder();
const payloadBytes = encoder.encode(`${payload}`);
const payloadInputSize = payloadBytes.length;
const payloadInputPtr = wasmPrivModules._malloc(payloadInputSize);
const resultFirstPtr = wasmPrivModules._malloc(Int32Array.BYTES_PER_ELEMENT);
// create a pointer to interger to hold the length of the output buffer
const resultLenPtr = wasmPrivModules._malloc(Int32Array.BYTES_PER_ELEMENT);
wasmPrivModules.HEAP8.set(payloadBytes, payloadInputPtr / payloadBytes.BYTES_PER_ELEMENT);
console.log('Payload:', payload);
let res = null;
const config_bytes = encoder.encode(`${config}`);
const configInputSize = config.length;
const configInputPtr = wasmPrivModules._malloc(configInputSize);
wasmPrivModules.HEAP8.set(config_bytes, configInputPtr / config_bytes.BYTES_PER_ELEMENT);
try {
res = wasmPrivModules._privid_encrypt_payload(
wasmSession /* session pointer */,
configInputPtr,
configInputSize,
payloadInputPtr,
payloadInputSize,
resultFirstPtr /* operation result output buffer */,
resultLenPtr /* operation result buffer length */,
);
} catch (e) {
console.error('---------__E__-------', e);
}
console.log('Result?', res);
const [outputBufferSizes] = new Uint32Array(wasmPrivModules.HEAPU8.buffer, resultLenPtr, 1);
if (outputBufferSizes > 0) {
// de-reference & copy the data from pointer to integer in integer array of one element
const outputBufferSize = new Uint32Array(wasmPrivModules.HEAPU8.buffer, resultLenPtr, 1)[0];
const outputBufferSecPtr = new Uint32Array(wasmPrivModules.HEAPU8.buffer, resultFirstPtr, 1)[0];
const outputBufferPtr = new Uint8Array(wasmPrivModules.HEAPU8.buffer, outputBufferSecPtr, outputBufferSize);
var decoder = new TextDecoder('utf8');
var dec = decoder.decode(outputBufferPtr);
console.log('len:', dec.length);
dec.replace(/\0/g, '');
dec.replace(' ', '');
console.log('test:', dec.length);
function removeNullBytes(str) {
return str
.split('')
.filter((char) => char.codePointAt(0))
.join('');
}
let parsedDec = JSON.stringify(removeNullBytes(dec));
console.log('parsed:', parsedDec);
let isObject = JSON.parse(parsedDec);
console.log('is object?', isObject);
return JSON.parse(isObject);
}
return { error: true };
};
const ultraScanFrontDocument = async (imageInput, simd, config, cb) => {
privid_wasm_result = cb;
if (!wasmPrivModules) {
await isLoad(simd, apiUrl, sesstionToken, publicKey, debugType);
}
const encoder = new TextEncoder();
const config_bytes = encoder.encode(`${config}`);
const configInputSize = config.length;
const configInputPtr = wasmPrivModules._malloc(configInputSize);
wasmPrivModules.HEAP8.set(config_bytes, configInputPtr / config_bytes.BYTES_PER_ELEMENT);
const imageInputSize = imageInput.data.length * imageInput.data.BYTES_PER_ELEMENT;
const imageInputPtr = wasmPrivModules._malloc(imageInputSize);
wasmPrivModules.HEAPU8.set(new Uint8Array(imageInput.data), imageInputPtr);
// wasmPrivModules.HEAP8.set(imageInput, imageInputPtr / imageInput.BYTES_PER_ELEMENT);
const resultFirstPtr = wasmPrivModules._malloc(Int32Array.BYTES_PER_ELEMENT);
// create a pointer to interger to hold the length of the output buffer
const resultLenPtr = wasmPrivModules._malloc(Int32Array.BYTES_PER_ELEMENT);
console.log('Config:', {
wasmSession /* session pointer */,
configInputPtr,
configInputSize,
imageInputPtr /* input images */,
width: imageInput.width /* width of one image */,
height: imageInput.height /* height of one image */,
resultFirstPtr /* operation result output buffer */,
resultLenPtr,
});
try {
await wasmPrivModules._privid_doc_scan_front(
wasmSession /* session pointer */,
configInputPtr,
configInputSize,
imageInputPtr /* input images */,
imageInput.width /* width of one image */,
imageInput.height /* height of one image */,
resultFirstPtr /* operation result output buffer */,
resultLenPtr /* operation result buffer length */,
);
} catch (e) {
console.error('---------__E__-------', e);
}
wasmPrivModules._free(imageInputPtr);
wasmPrivModules._free(configInputPtr);
wasmPrivModules._free(resultFirstPtr);
wasmPrivModules._free(resultLenPtr);
};
const ultraScanBackDocument = async (imageInput, simd, config, cb) => {
privid_wasm_result = cb;
if (!wasmPrivModules) {
await isLoad(simd, apiUrl, sesstionToken, publicKey, debugType);
}
console.log('extra config:', config);
const encoder = new TextEncoder();
const config_bytes = encoder.encode(`${config}`);
const configInputSize = config.length;
const configInputPtr = wasmPrivModules._malloc(configInputSize);
wasmPrivModules.HEAP8.set(config_bytes, configInputPtr / config_bytes.BYTES_PER_ELEMENT);
console.log('image Input', imageInput);
const imageInputSize = imageInput?.data?.length * imageInput?.data?.BYTES_PER_ELEMENT;
const imageInputPtr = wasmPrivModules._malloc(imageInputSize);
console.log('Input image Size:', imageInputSize);
wasmPrivModules.HEAPU8.set(new Uint8Array(imageInput.data), imageInputPtr);
// wasmPrivModules.HEAP8.set(imageInput, imageInputPtr / imageInput?.data?.BYTES_PER_ELEMENT);
const resultFirstPtr = wasmPrivModules._malloc(Int32Array.BYTES_PER_ELEMENT);
// create a pointer to interger to hold the length of the output buffer
const resultLenPtr = wasmPrivModules._malloc(Int32Array.BYTES_PER_ELEMENT);
console.log('Config:', {
configInputPtr,
configInputSize,
imageInputPtr /* input images */,
width: imageInput.width /* width of one image */,
height: imageInput.height /* height of one image */,
resultFirstPtr /* operation result output buffer */,
resultLenPtr /* operation result buffer length */,
});
try {
await wasmPrivModules._privid_doc_scan_back(
wasmSession /* session pointer */,
configInputPtr,
configInputSize,
imageInputPtr /* input images */,
imageInput.width /* width of one image */,
imageInput.height /* height of one image */,
resultFirstPtr /* operation result output buffer */,
resultLenPtr /* operation result buffer length */,
);
} catch (e) {
console.error('---------__E__-------', e);
}
wasmPrivModules._free(imageInputPtr);
wasmPrivModules._free(configInputPtr);
wasmPrivModules._free(resultFirstPtr);
wasmPrivModules._free(resultLenPtr);
};
const checkIfModelsLoaded = () => {
try {
const isLoaded = wasmPrivModules._privid_check_models();
return isLoaded;
} catch (e) {
console.log(e);
return 0;
}
};
Comlink.expose({
ultraEnroll,
ultraPredict,
ultraAgeEstimate,
ultraCompareEmbeddings,
isLoad,
pkiEncrypt,
checkIfModelsLoaded,
ultraScanBackDocument,
ultraScanFrontDocument,
});