UNPKG

lcms-wasm

Version:
264 lines (243 loc) 7.32 kB
/* * Originally written by yoya: * 2018/03/06- (c) yoya@awm.jp * * With modifications by @mattdesl for ES6 and updated Emscripten */ Module.cmsOpenProfileFromMem = cwrap("cmsOpenProfileFromMem", "number", [ "array", "number", ]); Module.cmsCloseProfile = cwrap("cmsCloseProfile", undefined, ["number"]); Module.cmsCreate_sRGBProfile = cwrap("cmsCreate_sRGBProfile", "number", []); Module.cmsCreateXYZProfile = cwrap("cmsCreateXYZProfile", "number", [], []); Module.cmsGetHeaderRenderingIntent = cwrap( "cmsGetHeaderRenderingIntent", "number", ["number"] ); Module.cmsCreateLab4Profile = cmsCreateLab4Profile; function cmsCreateLab4Profile(wpArr) { var whitePoint = 0; if (wpArr) { whitePoint = _malloc(8 * 3); // cmsCIExyY* WhitePoint for (var i = 0; i < 3; i++) { setValue(whitePoint + i * 8, wpArr[i], "double"); } } var prof = ccall("cmsCreateLab4Profile", "number", ["number"], [whitePoint]); if (whitePoint) { _free(whitePoint); } return prof; } /* usage: hInput, cmsInfoDescription, "en", "US" */ Module.cmsGetProfileInfoASCII = cmsGetProfileInfoASCII; function cmsGetProfileInfoASCII(hProfile, info, languageCode, countryCode) { var len = ccall( "cmsGetProfileInfoASCII", "number", ["number", "number", "string", "string", "number", "number"], [hProfile, info, languageCode, countryCode, 0, 0] ); var ptr = _malloc(len); var len = ccall( "cmsGetProfileInfoASCII", "number", ["number", "number", "string", "string", "number", "number"], [hProfile, info, languageCode, countryCode, ptr, len] ); var text = UTF8ToString(ptr, len); _free(ptr); return text; } Module.cmsGetColorSpace = cwrap("cmsGetColorSpace", "number", ["number"]); Module.cmsGetColorSpaceASCII = (profile) => { const table = { /*cmsSigXYZData*/ 0x58595a20: "XYZ", /*cmsSigLabData*/ 0x4c616220: "Lab", /*cmsSigLuvData*/ 0x4c757620: "Luv", /*cmsSigYCbCrData*/ 0x59436272: "YCbr", /*cmsSigYxyData*/ 0x59787920: "Yxy", /*cmsSigRgbData*/ 0x52474220: "RGB", /*cmsSigGrayData*/ 0x47524159: "GRAY", /*cmsSigHsvData*/ 0x48535620: "HSV", /*cmsSigHlsData*/ 0x484c5320: "HLS", /*cmsSigCmykData*/ 0x434d594b: "CMYK", /*cmsSigCmyData*/ 0x434d5920: "CMY", }; const ret = Module.cmsGetColorSpace(profile); return table[ret] || null; }; Module.cmsFormatterForColorspaceOfProfile = cmsFormatterForColorspaceOfProfile; function cmsFormatterForColorspaceOfProfile(hProfile, nBytes, isFloat) { return ccall( "cmsFormatterForColorspaceOfProfile", "number", ["number", "number", "number"], [hProfile, nBytes, isFloat] ); } Module.cmsCreateTransform = cmsCreateTransform; function cmsCreateTransform( hInput, inputFormat, hOutput, outputFormat, intent, flags ) { return ccall( "cmsCreateTransform", "number", ["number", "number", "number", "number", "number", "number"], [hInput, inputFormat, hOutput, outputFormat, intent, flags] ); } Module.cmsCreateProofingTransform = cmsCreateProofingTransform; function cmsCreateProofingTransform( hInput, inputFormat, hOutput, outputFormat, proofing, intent, proofingIntent, flags ) { return ccall( "cmsCreateProofingTransform", "number", [ "number", "number", "number", "number", "number", "number", "number", "number", ], [ hInput, inputFormat, hOutput, outputFormat, proofing, intent, proofingIntent, flags, ] ); } Module.cmsDeleteTransform = cmsDeleteTransform; function cmsDeleteTransform(transform) { if (!transform) { throw new Error( "cmsDeleteTransform expects a non-false transform parameter" ); } ccall("cmsDeleteTransform", undefined, ["number"], [transform]); } Module.cmsGetTransformInputFormat = cmsGetTransformInputFormat; function cmsGetTransformInputFormat(transform) { return ccall("cmsGetTransformInputFormat", "number", ["number"], [transform]); } Module.cmsGetTransformOutputFormat = cmsGetTransformOutputFormat; function cmsGetTransformOutputFormat(transform) { return ccall( "cmsGetTransformOutputFormat", "number", ["number"], [transform] ); } function getArrayType(bytes, float) { // A quick test seems to indicate that only Uint8, 16, or Float32 work // Maybe this is something that could be fixed with some adjusting? if (float) { if (bytes == 8) throw new Error("Float64Array not supported by LittleCMS"); if (bytes == 2) throw new Error("Float16Array not supported by LittleCMS"); return Float32Array; } if (bytes === 4) throw new Error("Uint32Array not supported by LittleCMS"); if (bytes === 2) return Uint16Array; return Uint8Array; } Module.cmsDoTransform = cmsDoTransform; function cmsDoTransform(transform, inputArr, size) { var inputFormat = cmsGetTransformInputFormat(transform); var outputFormat = cmsGetTransformOutputFormat(transform); var inputIsFloat = Boolean(T_FLOAT(inputFormat)); // Float64 or Uint16 var outputIsFloat = Boolean(T_FLOAT(outputFormat)); var inputChannels = T_CHANNELS(inputFormat) + T_EXTRA(inputFormat); // 3(RGB) or 4(CMYK) var outputChannels = T_CHANNELS(outputFormat) + T_EXTRA(inputFormat); var inputBytes = T_BYTES(inputFormat); // Bytes per sample var outputBytes = T_BYTES(outputFormat); inputBytes = inputBytes < 1 ? 4 : inputBytes; outputBytes = outputBytes < 1 ? 4 : outputBytes; var inputLength = inputChannels * size; var inputBuffer = _malloc(inputLength * inputBytes); var dataOnHeap; const InputType = getArrayType(inputBytes, inputIsFloat); const OutputType = getArrayType(outputBytes, outputIsFloat); dataOnHeap = new InputType(Module.HEAPU8.buffer, inputBuffer, inputLength); dataOnHeap.set(inputArr); var outputLength = outputChannels * size; var outputBuffer = _malloc(outputLength * outputBytes); ccall( "cmsDoTransform", undefined, ["number", "number", "number", "number"], [transform, inputBuffer, outputBuffer, size] ); var outputArr = new OutputType( Module.HEAPU8.buffer, outputBuffer, outputLength ).slice(); _free(inputBuffer); _free(outputBuffer); return outputArr; } Module.cmsReadTag = cmsReadTag; function cmsReadTag(hProfile, sig) { var ptr = ccall( "cmsReadTag", undefined, ["number", "number"], [hProfile, sig] ); return ptr; } /* custom function */ Module.cmsReadTag_XYZ = cmsReadTag_XYZ; function cmsReadTag_XYZ(hProfile, sig) { var ptr = cmsReadTag(hProfile, sig); if (!ptr) { return null; } var xyz = new Float64Array(3); xyz[0] = getValue(ptr, "double"); xyz[1] = getValue(ptr + 8, "double"); xyz[2] = getValue(ptr + 16, "double"); return xyz; } Module.cmsXYZ2xyY = cmsXYZ2xyY; function cmsXYZ2xyY(xyz) { var srcPtr = _malloc(8 * 3); var dstPtr = _malloc(8 * 3); setValue(srcPtr, xyz[0], "double"); setValue(srcPtr + 8, xyz[1], "double"); setValue(srcPtr + 16, xyz[2], "double"); ccall("cmsXYZ2xyY", undefined, ["number", "number"], [dstPtr, srcPtr]); var xyY = new Float64Array(3); xyY[0] = getValue(dstPtr, "double"); xyY[1] = getValue(dstPtr + 8, "double"); xyY[2] = getValue(dstPtr + 16, "double"); _free(srcPtr); _free(dstPtr); return xyY; }