@privateid/ping-oidc-web-sdk-alpha
Version:
1,106 lines (954 loc) • 37.4 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');
let wasmPrivModule;
let apiUrl;
let publicKey;
let sessionToken;
let debugType;
let inputPtr;
let imageInputSize;
let barCodePtr;
let privid_wasm_result = null;
let wasmSession = null;
let isSimd;
let checkWasmLoaded = false;
let wasmPrivAntispoofModule;
let antispoofVersion;
const ModuleName = 'privid_fhe_oidc';
let useCdnLink = false;
const isLoad = (simd, session_token, public_key, url, timeout, debugLevel, originUrl, shouldRegenerateSession) =>
new Promise(async (resolve, reject) => {
apiUrl = url;
publicKey = public_key;
sessionToken = session_token;
if (debugLevel) {
debugType = debugLevel;
}
let timeoutSession = 5000;
if (timeout) {
timeoutSession = timeout;
}
isSimd = simd;
const modulePath = simd ? 'simd' : 'noSimd';
const moduleName = 'oidc';
const cachedModule = await readKey(moduleName);
const fetchdVersion = await (await fetch(`${originUrl}/wasm/${moduleName}/${modulePath}/version.json`)).json();
console.log('fetch?', fetchdVersion);
const cachedVestion = cachedModule?.version.toString();
console.log(
`check version` + cachedVestion + `fetched version:` +fetchdVersion?.version
);
if (cachedModule && cachedModule?.version.toString() === fetchdVersion?.version.toString()) {
if (!wasmPrivModule) {
const { cachedWasm, cachedScript } = cachedModule;
eval(cachedScript);
wasmPrivModule = await createTFLiteModule({ wasmBinary: cachedWasm });
// console.log('oidc module', wasmPrivModule);
if (!checkWasmLoaded) {
await initializeWasmSession(apiUrl, publicKey, sessionToken, timeoutSession, debugType);
checkWasmLoaded = true;
}
} else if (shouldRegenerateSession) {
wasmSession = null;
await initializeWasmSession(apiUrl, publicKey, sessionToken, timeoutSession, debugType);
}
resolve('Cache Loaded');
} else {
wasmPrivModule = await loadWasmModule(modulePath, ModuleName, fetchdVersion?.version);
// console.log('oidc module:', wasmPrivModule);
if (!checkWasmLoaded) {
await initializeWasmSession(apiUrl, publicKey, sessionToken, debugType);
checkWasmLoaded = true;
}
// console.log('WASM MODULES:', wasmPrivModule);
resolve('Loaded');
}
});
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;
}
async function deleteUUID(uuid, cb) {
privid_wasm_result = cb;
const encoder = new TextEncoder();
const uuid_bytes = encoder.encode(`${uuid}`);
const uuidInputSize = uuid.length;
const uuidInputPtr = wasmPrivModule._malloc(uuidInputSize);
wasmPrivModule.HEAP8.set(uuid_bytes, uuidInputPtr / uuid_bytes.BYTES_PER_ELEMENT);
wasmPrivModule._privid_user_delete(wasmSession, null, 0, uuidInputPtr, uuidInputSize, 0, 0);
wasmPrivModule._free(uuidInputPtr);
}
const isValidBarCode = async (imageInput, simd, cb, config, debug_type = 0) => {
privid_wasm_result = cb;
if (!wasmPrivModule) {
await isLoad(simd, apiUrl, apiKey, wasmModule, debugType);
}
configGlobal = config;
const { data: imageData } = imageInput;
const imageInputSize = imageData.length * imageData.BYTES_PER_ELEMENT;
if (!barCodePtr) {
barCodePtr = wasmPrivModule._malloc(imageInputSize);
}
wasmPrivModule.HEAP8.set(imageData, barCodePtr / imageData.BYTES_PER_ELEMENT);
// Cropped Document malloc
const croppedDocumentBufferFirstPtr = wasmPrivModule._malloc(Int32Array.BYTES_PER_ELEMENT);
const croppedDocumentBufferLenPtr = wasmPrivModule._malloc(Int32Array.BYTES_PER_ELEMENT);
// Cropped Barcode malloc
const croppedBarcodeBufferFirstPtr = wasmPrivModule._malloc(Int32Array.BYTES_PER_ELEMENT);
const croppedBarcodeBufferLenPtr = wasmPrivModule._malloc(Int32Array.BYTES_PER_ELEMENT);
const encoder = new TextEncoder();
const config_bytes = encoder.encode(`${config}`);
const configInputSize = config.length;
const configInputPtr = wasmPrivModule._malloc(configInputSize);
wasmPrivModule.HEAP8.set(config_bytes, configInputPtr / config_bytes.BYTES_PER_ELEMENT);
let result = null;
try {
result = wasmPrivModule._privid_doc_scan_barcode(
wasmSession,
configInputPtr,
configInputSize,
barCodePtr,
imageInput.width,
imageInput.height,
croppedDocumentBufferFirstPtr,
croppedDocumentBufferLenPtr,
croppedBarcodeBufferFirstPtr,
croppedBarcodeBufferLenPtr,
null,
0,
);
} catch (err) {
console.error('-----------_E_-----------', err);
}
// Document
const { outputBufferData: croppedDocument, outputBufferSize: croppedDocumentSize } = getBufferFromPtr(
croppedDocumentBufferFirstPtr,
croppedDocumentBufferLenPtr,
);
// Mugshot
const { outputBufferData: croppedBarcode, outputBufferSize: croppedBarcodeSize } = getBufferFromPtr(
croppedBarcodeBufferFirstPtr,
croppedBarcodeBufferLenPtr,
);
let imageBuffer = null;
if (croppedBarcodeSize && croppedDocumentSize) {
imageBuffer = getBufferFromPtrImage(barCodePtr, imageInputSize);
}
wasmPrivModule._free(barCodePtr);
barCodePtr = null;
wasmPrivModule._free(croppedDocumentBufferFirstPtr);
wasmPrivModule._free(croppedDocumentBufferLenPtr);
wasmPrivModule._free(croppedBarcodeBufferFirstPtr);
wasmPrivModule._free(croppedBarcodeBufferLenPtr);
wasmPrivModule._free(configInputPtr);
return { result, croppedDocument, croppedBarcode, imageData: imageBuffer };
};
const scanDocument = async (imageInput, simd, cb, doPredict, config, debug_type = 0) => {
privid_wasm_result = cb;
if (!wasmPrivModule) {
await isLoad(simd, apiUrl, apiKey, wasmModule, debugType);
}
configGlobal = config;
// const version = wasmPrivModule._get_version();
const encoder = new TextEncoder();
const config_bytes = encoder.encode(`${config}`);
const configInputSize = config.toString().length;
const configInputPtr = wasmPrivModule._malloc(configInputSize);
wasmPrivModule.HEAP8.set(config_bytes, configInputPtr / config_bytes.BYTES_PER_ELEMENT);
const { data: imageData } = imageInput;
const imageInputSize = imageData.length * imageData.BYTES_PER_ELEMENT;
if (!inputPtr) {
inputPtr = wasmPrivModule._malloc(imageInputSize);
}
wasmPrivModule.HEAP8.set(imageData, inputPtr / imageData.BYTES_PER_ELEMENT);
// Cropped Document malloc
const croppedDocumentBufferFirstPtr = wasmPrivModule._malloc(Int32Array.BYTES_PER_ELEMENT);
const croppedDocumentBufferLenPtr = wasmPrivModule._malloc(Int32Array.BYTES_PER_ELEMENT);
// Cropped Mugshot malloc
const croppedMugshotBufferFirstPtr = wasmPrivModule._malloc(Int32Array.BYTES_PER_ELEMENT);
const croppedMugshotBufferLenPtr = wasmPrivModule._malloc(Int32Array.BYTES_PER_ELEMENT);
let result = null;
try {
result = wasmPrivModule._privid_doc_scan_face(
wasmSession,
configInputPtr,
configInputSize,
inputPtr,
imageInput.width,
imageInput.height,
croppedDocumentBufferFirstPtr,
croppedDocumentBufferLenPtr,
croppedMugshotBufferFirstPtr,
croppedMugshotBufferLenPtr,
null,
0,
);
} catch (err) {
console.error('-----------------ERROR---------------', err);
return;
}
// Document
const { outputBufferData: croppedDocument, outputBufferSize: croppedDocumentSize } = getBufferFromPtr(
croppedDocumentBufferFirstPtr,
croppedDocumentBufferLenPtr,
);
// Mugshot
const { outputBufferData: croppedMugshot, outputBufferSize: croppedMugshotSize } = getBufferFromPtr(
croppedMugshotBufferFirstPtr,
croppedMugshotBufferLenPtr,
);
const imageBuffer = getBufferFromPtrImage(inputPtr, imageInputSize);
wasmPrivModule._free(croppedDocumentBufferFirstPtr);
wasmPrivModule._free(croppedDocumentBufferLenPtr);
wasmPrivModule._free(croppedMugshotBufferFirstPtr);
wasmPrivModule._free(croppedMugshotBufferLenPtr);
wasmPrivModule._free(configInputPtr);
wasmPrivModule._free(inputPtr);
inputPtr = null;
// eslint-disable-next-line consistent-return, no-param-reassign
return {
result,
croppedDocument,
croppedMugshot,
imageData: imageBuffer,
};
};
const getBufferFromPtr = (bufferPtr, bufferSize) => {
const [outputBufferSize] = new Uint32Array(wasmPrivModule.HEAPU8.buffer, bufferSize, 1);
let outputBufferSecPtr = null;
if (outputBufferSize > 0) {
[outputBufferSecPtr] = new Uint32Array(wasmPrivModule.HEAPU8.buffer, bufferPtr, 1);
}
const outputBufferPtr = new Uint8Array(wasmPrivModule.HEAPU8.buffer, outputBufferSecPtr, outputBufferSize);
const outputBuffer = Uint8ClampedArray.from(outputBufferPtr);
wasmPrivModule._privid_free_char_buffer(outputBufferSecPtr);
const outputBufferData = outputBufferSize > 0 ? outputBuffer : null;
return { outputBufferData, outputBufferSize };
};
const getBufferFromPtrImage = (bufferPtr, outputBufferSize) => {
const outputBufferPtr = new Uint8Array(wasmPrivModule.HEAPU8.buffer, bufferPtr, outputBufferSize);
const outputBuffer = Uint8ClampedArray.from(outputBufferPtr);
return outputBufferSize > 0 ? outputBuffer : null;
};
const FHE_enrollOnefa = async (imageData, simd, config, cb) => {
privid_wasm_result = cb;
if (!wasmPrivModule) {
await isLoad(isSimd, sessionToken, publicKey, apiUrl, timeout, debugType);
}
const imageInputSize = imageData.data.length * imageData.data.BYTES_PER_ELEMENT;
const imageInputPtr = wasmPrivModule._malloc(imageInputSize);
wasmPrivModule.HEAPU8.set(new Uint8Array(imageData.data), imageInputPtr);
const resultFirstPtr = wasmPrivModule._malloc(Int32Array.BYTES_PER_ELEMENT);
const resultLenPtr = wasmPrivModule._malloc(Int32Array.BYTES_PER_ELEMENT);
const encoder = new TextEncoder();
const config_bytes = encoder.encode(`${config}`);
const configInputSize = config_bytes.length;
const configInputPtr = wasmPrivModule._malloc(configInputSize);
const bestImageFirstPtr = wasmPrivModule._malloc(Int32Array.BYTES_PER_ELEMENT);
const bestImageLenPtr = wasmPrivModule._malloc(Int32Array.BYTES_PER_ELEMENT);
wasmPrivModule.HEAP8.set(config_bytes, configInputPtr / config_bytes.BYTES_PER_ELEMENT);
// console.log('Config:', config);
try {
wasmPrivModule._privid_enroll_onefa(
wasmSession /* session pointer */,
configInputPtr,
configInputSize,
imageInputPtr /* input images */,
1 /* number of input images */,
imageData.data.length /* size of one image */,
imageData.width /* width of one image */,
imageData.height /* height of one image */,
bestImageFirstPtr,
bestImageLenPtr,
resultFirstPtr /* operation result output buffer */,
resultLenPtr /* operation result buffer length */,
);
} catch (e) {
console.error('---------__E__-------', e);
}
let bestImage = null;
const [outputBufferSize] = new Uint32Array(wasmPrivModule.HEAPU8.buffer, bestImageLenPtr, 1);
if (outputBufferSize > 0) {
let outputBufferSecPtr = null;
[outputBufferSecPtr] = new Uint32Array(wasmPrivModule.HEAPU8.buffer, bestImageFirstPtr, 1);
const outputBufferPtr = new Uint8Array(wasmPrivModule.HEAPU8.buffer, outputBufferSecPtr, outputBufferSize);
const outputBuffer = Uint8ClampedArray.from(outputBufferPtr);
const outputBufferData = outputBufferSize > 0 ? outputBuffer : null;
bestImage = {
imageData: outputBufferData,
width: imageData.width,
height: imageData.height,
};
}
wasmPrivModule._free(imageInputPtr);
wasmPrivModule._free(resultFirstPtr);
wasmPrivModule._free(resultLenPtr);
wasmPrivModule._free(configInputPtr);
wasmPrivModule._free(bestImageFirstPtr);
wasmPrivModule._free(bestImageLenPtr);
// console.log('Best Image?', bestImage);
return bestImage;
};
const FHE_predictOnefa = async (originalImages, simd, config, cb) => {
privid_wasm_result = cb;
if (!wasmPrivModule) {
await isLoad(simd, sessionToken, publicKey, apiUrl, timeout, debugType);
}
const numImages = originalImages.length;
const imageInput = flatten(
originalImages.map((x) => x.data),
Uint8Array,
);
// const version = wasmPrivModule._get_version();
const encoder = new TextEncoder();
const config_bytes = encoder.encode(`${config}`);
const configInputSize = config.length;
const configInputPtr = wasmPrivModule._malloc(configInputSize);
wasmPrivModule.HEAP8.set(config_bytes, configInputPtr / config_bytes.BYTES_PER_ELEMENT);
const imageInputSize = imageInput.length * imageInput.BYTES_PER_ELEMENT;
const imageInputPtr = wasmPrivModule._malloc(imageInputSize);
wasmPrivModule.HEAP8.set(imageInput, imageInputPtr / imageInput.BYTES_PER_ELEMENT);
const resultFirstPtr = wasmPrivModule._malloc(Int32Array.BYTES_PER_ELEMENT);
// create a pointer to interger to hold the length of the output buffer
const resultLenPtr = wasmPrivModule._malloc(Int32Array.BYTES_PER_ELEMENT);
// console.log('Config:', config);
try {
await wasmPrivModule._privid_face_predict_onefa(
wasmSession /* session pointer */,
configInputPtr,
configInputSize,
imageInputPtr /* input images */,
numImages /* number of input images */,
originalImages[0].data.length /* size of one image */,
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);
}
wasmPrivModule._free(imageInputPtr);
wasmPrivModule._free(configInputPtr);
wasmPrivModule._free(resultFirstPtr);
wasmPrivModule._free(resultLenPtr);
};
const predictStatus = async (originalImages, simd, config, cb) => {
privid_wasm_result = cb;
if (!wasmPrivModule) {
await isLoad(simd, sessionToken, publicKey, apiUrl, timeout, debugType);
}
const numImages = originalImages.length;
const imageInput = flatten(
originalImages.map((x) => x.data),
Uint8Array,
);
// const version = wasmPrivModule._get_version();
const encoder = new TextEncoder();
const config_bytes = encoder.encode(`${config}`);
const configInputSize = config.length;
const configInputPtr = wasmPrivModule._malloc(configInputSize);
wasmPrivModule.HEAP8.set(config_bytes, configInputPtr / config_bytes.BYTES_PER_ELEMENT);
const imageInputSize = imageInput.length * imageInput.BYTES_PER_ELEMENT;
const imageInputPtr = wasmPrivModule._malloc(imageInputSize);
wasmPrivModule.HEAP8.set(imageInput, imageInputPtr / imageInput.BYTES_PER_ELEMENT);
const resultFirstPtr = wasmPrivModule._malloc(Int32Array.BYTES_PER_ELEMENT);
// create a pointer to interger to hold the length of the output buffer
const resultLenPtr = wasmPrivModule._malloc(Int32Array.BYTES_PER_ELEMENT);
// console.log('Config:', config);
console.log("Debug", config);
try {
await wasmPrivModule._privid_face_predict_status(
wasmSession /* session pointer */,
configInputPtr,
configInputSize,
imageInputPtr /* input images */,
numImages /* number of input images */,
originalImages[0].data.length /* size of one image */,
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);
}
wasmPrivModule._free(imageInputPtr);
wasmPrivModule._free(configInputPtr);
wasmPrivModule._free(resultFirstPtr);
wasmPrivModule._free(resultLenPtr);
};
const prividAgePredict = async (
data,
width,
height,
simd,
config = JSON.stringify({ input_image_format: 'rgba' }),
cb,
) => {
privid_wasm_result = cb;
if (!wasmPrivModule) {
await isLoad(simd, apiUrl, apiKey, wasmModule, debugType);
}
const imageSize = data.length * data.BYTES_PER_ELEMENT;
const isValidPtr = wasmPrivModule._malloc(imageSize);
wasmPrivModule.HEAP8.set(data, isValidPtr / data.BYTES_PER_ELEMENT);
const resultFirstPtr = wasmPrivModule._malloc(Int32Array.BYTES_PER_ELEMENT);
// create a pointer to interger to hold the length of the output buffer
const resultLenPtr = wasmPrivModule._malloc(Int32Array.BYTES_PER_ELEMENT);
const encoder = new TextEncoder();
const config_bytes = encoder.encode(`${config}`);
const configInputSize = config.length;
const configInputPtr = wasmPrivModule._malloc(configInputSize);
wasmPrivModule.HEAP8.set(config_bytes, configInputPtr / config_bytes.BYTES_PER_ELEMENT);
console.log('estimate age data:', {
wasmSession,
isValidPtr,
width,
height,
configInputPtr,
configInputSize,
resultFirstPtr,
resultLenPtr,
});
try {
await wasmPrivModule._privid_estimate_age(
wasmSession,
isValidPtr,
width,
height,
configInputPtr,
configInputSize,
resultFirstPtr,
resultLenPtr,
);
} catch (e) {
console.error('_____ PREDICT AGE: ', e);
}
wasmPrivModule._free(isValidPtr);
wasmPrivModule._free(configInputPtr);
wasmPrivModule._free(resultFirstPtr);
};
const isValidFrontDocument = async (imagePtr, width, height, simd, action, debug_type = 0, cb) => {
privid_wasm_result = cb;
if (!wasmPrivModule) {
await isLoad(simd, apiUrl, apiKey, wasmModule, debug_type);
}
const result = wasmPrivModule._is_valid(action, imagePtr, width, height, 0, 0, 0);
wasmPrivModule._free(imagePtr);
return result;
};
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);
}
};
};
});
}
/**
* @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 = wasmPrivModule._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 = wasmPrivModule._malloc(strInputSize);
wasmPrivModule.HEAP8.set(bytes, strInputtPtr / bytes.BYTES_PER_ELEMENT);
argsv = [strInputtPtr, strInputSize];
} while (false);
return argsv;
},
free: () => {
if (strInputtPtr) {
wasmPrivModule._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
* 'wasmPrivModule' 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 'wasmPrivModule' module use
* wasmPrivModule.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) {
wasmPrivModule._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 = wasmPrivModule._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(wasmPrivModule.HEAPU8.buffer, out_ptr, 1);
return in_ptr;
},
};
};
async function initializeWasmSession(url, publicKey, sessionToken, debugType) {
if (!wasmSession) {
console.log('api url', apiUrl);
const settings = {
collections: {
default: {
named_urls: {
base_url: url,
},
},
},
session_token: sessionToken,
public_key: publicKey,
debug_level: debugType ? parseInt(debugType) : 0,
};
// const initializationArgs = {
// named_urls: [{ url_name: 'base_url', url: apiUrl }],
// public_key: publicKey,
// session_token: sessionToken,
// debug_level: 0,
// };
// console.log('Args', initializationArgs);
console.log('Initialize Session Options:', settings);
const initializationArgsString = JSON.stringify(settings);
// console.log('STRING ARGS:', initializationArgsString);
const initArgs = buffer_args(initializationArgsString);
const session_out_ptr = output_ptr();
let s_result = '';
try {
s_result = await wasmPrivModule._privid_initialize_session(...initArgs.args(), session_out_ptr.outer_ptr());
} catch (e) {
console.log('Error:', e);
}
console.log('after initialize');
initArgs.free();
wasmPrivModule._free(session_out_ptr.inner_ptr);
if (s_result) {
console.log('[DEBUG] : session initialized successfully');
} else {
console.log('[DEBUG] : session initialized failed');
return;
}
// get our inner session created by wasm and free the outer container ptr
wasmSession = session_out_ptr.inner_ptr();
await wasmPrivModule._privid_set_default_configuration(wasmSession, 1);
} else {
console.log('Wasm session is available. Skipping creating session');
}
}
const scanDocumentNoFace = async (imageInput, simd, cb, config, debug_type = 0) => {
privid_wasm_result = cb;
if (!wasmPrivModule) {
await isLoad(simd, apiUrl, apiKey, wasmModule, debugType);
}
configGlobal = config;
const encoder = new TextEncoder();
const config_bytes = encoder.encode(`${config}`);
const configInputSize = config.length;
const configInputPtr = wasmPrivModule._malloc(configInputSize);
wasmPrivModule.HEAP8.set(config_bytes, configInputPtr / config_bytes.BYTES_PER_ELEMENT);
const { data: imageData } = imageInput;
const imageInputSize = imageData.length * imageData.BYTES_PER_ELEMENT;
if (!inputPtr) {
inputPtr = wasmPrivModule._malloc(imageInputSize);
}
wasmPrivModule.HEAP8.set(imageData, inputPtr / imageData.BYTES_PER_ELEMENT);
// Cropped Document malloc
const croppedDocumentBufferFirstPtr = wasmPrivModule._malloc(Int32Array.BYTES_PER_ELEMENT);
const croppedDocumentBufferLenPtr = wasmPrivModule._malloc(Int32Array.BYTES_PER_ELEMENT);
let result = null;
try {
result = wasmPrivModule._privid_scan_document_with_no_face(
wasmSession,
configInputPtr,
configInputSize,
inputPtr,
imageInput.width,
imageInput.height,
croppedDocumentBufferFirstPtr,
croppedDocumentBufferLenPtr,
null,
0,
);
} catch (err) {
console.error('-----------------ERROR---------------', err);
return;
}
// Document
const { outputBufferData: croppedDocument, outputBufferSize: croppedDocumentSize } = getBufferFromPtr(
croppedDocumentBufferFirstPtr,
croppedDocumentBufferLenPtr,
);
const imageBuffer = getBufferFromPtrImage(inputPtr, imageInputSize);
wasmPrivModule._free(croppedDocumentBufferFirstPtr);
wasmPrivModule._free(croppedDocumentBufferLenPtr);
wasmPrivModule._free(configInputPtr);
wasmPrivModule._free(inputPtr);
inputPtr = null;
return {
result,
croppedDocument,
imageData: imageBuffer,
};
};
const loadWasmModule = async (modulePath, moduleName, moduleVersion) => {
const wasm = await fetch(`../wasm/oidc/${modulePath}/${moduleVersion}/${moduleName}.wasm`);
const script = await fetch(`../wasm/oidc/${modulePath}/${moduleVersion}/${moduleName}.js`);
// const wasm = await fetch(`../wasm/face_mask/${modulePath}/${moduleName}.wasm`);
// const script = await fetch(`../wasm/face_mask/${modulePath}/${moduleName}.js`);
console.log({ wasm, script });
const scriptBuffer = await script.text();
const buffer = await wasm.arrayBuffer();
eval(scriptBuffer);
const module = await createTFLiteModule({ wasmBinary: buffer });
// if (saveCache) {
const version = module.UTF8ToString(module._privid_get_version());
await putKey('oidc', buffer, scriptBuffer, version);
// }
console.log('Script and module loaded!');
return module;
};
// privid_compare_mugshot_and_face(void* session_ptr, const char* user_config, const int user_config_length,
// const uint8_t* p_doc_image_in, const int doc_image_width, const int doc_image_height,
// const uint8_t* p_face_image_in, const int face_image_width, const int face_image_height,
// uint8_t** cropped_mughshot_out, int* cropped_mughshot_length,
// uint8_t** cropped_face_out, int* cropped_face_length,
// char** result_out, int* result_out_length);
const faceCompare = async (inputImageA, inputImageB, cb, config, debug_type = 0) => {
privid_wasm_result = cb;
if (!wasmPrivModule) {
await isLoad(simd, sessionToken, publicKey, apiUrl, timeout, debugType);
}
// const version = wasmPrivModule._get_version();
console.log('params:', { inputImageA, inputImageB, config });
const encoder = new TextEncoder();
const config_bytes = encoder.encode(`${config}`);
console.log("config before face compare:", config);
const configInputSize = config.length;
const configInputPtr = wasmPrivModule._malloc(configInputSize);
wasmPrivModule.HEAP8.set(config_bytes, configInputPtr / config_bytes.BYTES_PER_ELEMENT);
const imageInputASize = inputImageA.data.length * inputImageA.data.BYTES_PER_ELEMENT;
const imageInputAPtr = wasmPrivModule._malloc(imageInputASize);
wasmPrivModule.HEAP8.set(new Uint8Array(inputImageA.data), imageInputAPtr);
// const imageInputSize = imageData.data.length * imageData.data.BYTES_PER_ELEMENT;
// const imageInputPtr = wasmPrivModule._malloc(imageInputSize);
// wasmPrivModule.HEAPU8.set(new Uint8Array(imageData.data), imageInputPtr);
const imageInputBSize = inputImageB.data.length * inputImageB.data.BYTES_PER_ELEMENT;
const imageInputBPtr = wasmPrivModule._malloc(imageInputBSize);
wasmPrivModule.HEAP8.set(new Uint8Array(inputImageB.data), imageInputBPtr);
const resultFirstPtr = wasmPrivModule._malloc(Int32Array.BYTES_PER_ELEMENT);
// create a pointer to interger to hold the length of the output buffer
const resultLenPtr = wasmPrivModule._malloc(Int32Array.BYTES_PER_ELEMENT);
console.log({
configInputPtr,
configInputSize,
imageInputAPtr,
imageInputBPtr,
resultFirstPtr,
resultLenPtr,
inputImageA,
inputImageB,
});
try {
result = wasmPrivModule._privid_compare_mugshot_and_face(
wasmSession,
configInputPtr,
configInputSize,
imageInputAPtr,
inputImageA.width,
inputImageA.height,
imageInputBPtr,
inputImageB.width,
inputImageB.height,
null,
0,
null,
0,
resultFirstPtr,
resultLenPtr,
);
} catch (err) {
console.error('-----------------ERROR---------------', err);
return;
}
wasmPrivModule._free(configInputPtr);
wasmPrivModule._free(imageInputAPtr);
wasmPrivModule._free(imageInputBPtr);
wasmPrivModule._free(resultFirstPtr);
wasmPrivModule._free(resultLenPtr);
};
// void privid_encrypt_data(void* session_ptr, const unsigned char* buffer, const int buffer_length, char** result_out, int* result_out_length)
const pkiEnrcrypt = async (payload) => {
const encoder = new TextEncoder();
const payloadBytes = encoder.encode(`${payload}`);
const payloadInputSize = payloadBytes.length;
const payloadInputPtr = wasmPrivModule._malloc(payloadInputSize);
const resultFirstPtr = wasmPrivModule._malloc(Int32Array.BYTES_PER_ELEMENT);
// create a pointer to interger to hold the length of the output buffer
const resultLenPtr = wasmPrivModule._malloc(Int32Array.BYTES_PER_ELEMENT);
wasmPrivModule.HEAP8.set(payloadBytes, payloadInputPtr / payloadBytes.BYTES_PER_ELEMENT);
console.log('Payload:', payload);
let res = null;
try {
res = wasmPrivModule._privid_encrypt_data(
wasmSession /* session pointer */,
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(wasmPrivModule.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(wasmPrivModule.HEAPU8.buffer, resultLenPtr, 1)[0];
const outputBufferSecPtr = new Uint32Array(wasmPrivModule.HEAPU8.buffer, resultFirstPtr, 1)[0];
const outputBufferPtr = new Uint8Array(wasmPrivModule.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 confirmUserOnSwitch = async (originalImages, simd, config, cb) => {
privid_wasm_result = cb;
if (!wasmPrivModule) {
await isLoad(simd, sessionToken, publicKey, apiUrl, timeout, debugType);
}
const numImages = originalImages.length;
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 = wasmPrivModule._malloc(configInputSize);
wasmPrivModule.HEAP8.set(config_bytes, configInputPtr / config_bytes.BYTES_PER_ELEMENT);
const imageInputSize = imageInput.length * imageInput.BYTES_PER_ELEMENT;
const imageInputPtr = wasmPrivModule._malloc(imageInputSize);
wasmPrivModule.HEAP8.set(imageInput, imageInputPtr / imageInput.BYTES_PER_ELEMENT);
const bestImageFirstPtr = wasmPrivModule._malloc(Int32Array.BYTES_PER_ELEMENT);
const bestImageLenPtr = wasmPrivModule._malloc(Int32Array.BYTES_PER_ELEMENT);
try {
await wasmPrivModule._privid_confirm_user(
wasmSession /* session pointer */,
configInputPtr,
configInputSize,
imageInputPtr /* input images */,
// numImages /* number of input images */,
// originalImages[0].data.length /* size of one image */,
originalImages[0].width /* width of one image */,
originalImages[0].height /* height of one image */,
bestImageFirstPtr /* operation result output buffer */,
bestImageLenPtr /* operation result buffer length */,
null,
0,
);
} catch (e) {
console.error('---------__E__-------', e);
}
// enroll onefa
// if (outputBufferSize > 0) {
// let outputBufferSecPtr = null;
// [outputBufferSecPtr] = new Uint32Array(wasmPrivModule.HEAPU8.buffer, bestImageFirstPtr, 1);
// const outputBufferPtr = new Uint8Array(wasmPrivModule.HEAPU8.buffer, outputBufferSecPtr, outputBufferSize);
// const outputBuffer = Uint8ClampedArray.from(outputBufferPtr);
// const outputBufferData = outputBufferSize > 0 ? outputBuffer : null;
// bestImage = {
// imageData: outputBufferData,
// width: imageData.width,
// height: imageData.height,
// };
// }
// get buffer from pointer
// const [outputBufferSize] = new Uint32Array(wasmPrivModule.HEAPU8.buffer, bufferSize, 1);
// let outputBufferSecPtr = null;
// if (outputBufferSize > 0) {
// [outputBufferSecPtr] = new Uint32Array(wasmPrivModule.HEAPU8.buffer, bufferPtr, 1);
// }
// const outputBufferPtr = new Uint8Array(wasmPrivModule.HEAPU8.buffer, outputBufferSecPtr, outputBufferSize);
// const outputBuffer = Uint8ClampedArray.from(outputBufferPtr);
// wasmPrivModule._privid_free_char_buffer(outputBufferSecPtr);
// const outputBufferData = outputBufferSize > 0 ? outputBuffer : null;
// return { outputBufferData, outputBufferSize };
const outputBufferData = getBufferFromPtr(bestImageFirstPtr, bestImageLenPtr);
console.log({bestImageFirstPtr, imageInputSize, outputBufferData});
const bestImage = {
imageData: outputBufferData,
width: originalImages[0].width,
height: originalImages[0].height,
};
wasmPrivModule._free(imageInputPtr);
wasmPrivModule._free(configInputPtr);
wasmPrivModule._free(bestImageFirstPtr);
wasmPrivModule._free(bestImageLenPtr);
console.log('Best Image?', bestImage.imageData.length, bestImage.width * bestImage.height * 4);
return bestImage;
};
Comlink.expose({
FHE_enrollOnefa,
FHE_predictOnefa,
isLoad,
scanDocument,
scanDocumentNoFace,
isValidBarCode,
deleteUUID,
faceCompare,
pkiEnrcrypt,
confirmUserOnSwitch,
predictStatus,
prividAgePredict,
});