UNPKG

@cleerlycode/cornerstone-wado-image-loader

Version:
156 lines (125 loc) 4.45 kB
function decodeJpx (imageFrame, pixelData) { const jpxImage = new JpxImage(); jpxImage.parse(pixelData); const tileCount = jpxImage.tiles.length; if (tileCount !== 1) { throw new Error(`JPEG2000 decoder returned a tileCount of ${tileCount}, when 1 is expected`); } imageFrame.columns = jpxImage.width; imageFrame.rows = jpxImage.height; imageFrame.pixelData = jpxImage.tiles[0].items; return imageFrame; } let openJPEG; function decodeOpenJPEG (data, bytesPerPixel, signed) { const dataPtr = openJPEG._malloc(data.length); openJPEG.writeArrayToMemory(data, dataPtr); // create param outpout const imagePtrPtr = openJPEG._malloc(4); const imageSizePtr = openJPEG._malloc(4); const imageSizeXPtr = openJPEG._malloc(4); const imageSizeYPtr = openJPEG._malloc(4); const imageSizeCompPtr = openJPEG._malloc(4); const t0 = new Date().getTime(); const ret = openJPEG.ccall('jp2_decode', 'number', ['number', 'number', 'number', 'number', 'number', 'number', 'number'], [dataPtr, data.length, imagePtrPtr, imageSizePtr, imageSizeXPtr, imageSizeYPtr, imageSizeCompPtr]); // add num vomp..etc if (ret !== 0) { console.log('[opj_decode] decoding failed!'); openJPEG._free(dataPtr); openJPEG._free(openJPEG.getValue(imagePtrPtr, '*')); openJPEG._free(imageSizeXPtr); openJPEG._free(imageSizeYPtr); openJPEG._free(imageSizePtr); openJPEG._free(imageSizeCompPtr); return; } const imagePtr = openJPEG.getValue(imagePtrPtr, '*'); const image = { length: openJPEG.getValue(imageSizePtr, 'i32'), sx: openJPEG.getValue(imageSizeXPtr, 'i32'), sy: openJPEG.getValue(imageSizeYPtr, 'i32'), nbChannels: openJPEG.getValue(imageSizeCompPtr, 'i32'), // hard coded for now perf_timetodecode: undefined, pixelData: undefined }; // Copy the data from the EMSCRIPTEN heap into the correct type array const length = image.sx * image.sy * image.nbChannels; const src32 = new Int32Array(openJPEG.HEAP32.buffer, imagePtr, length); if (bytesPerPixel === 1) { if (Uint8Array.from) { image.pixelData = Uint8Array.from(src32); } else { image.pixelData = new Uint8Array(length); for (let i = 0; i < length; i++) { image.pixelData[i] = src32[i]; } } } else if (signed) { if (Int16Array.from) { image.pixelData = Int16Array.from(src32); } else { image.pixelData = new Int16Array(length); for (let i = 0; i < length; i++) { image.pixelData[i] = src32[i]; } } } else if (Uint16Array.from) { image.pixelData = Uint16Array.from(src32); } else { image.pixelData = new Uint16Array(length); for (let i = 0; i < length; i++) { image.pixelData[i] = src32[i]; } } const t1 = new Date().getTime(); image.perf_timetodecode = t1 - t0; // free openJPEG._free(dataPtr); openJPEG._free(imagePtrPtr); openJPEG._free(imagePtr); openJPEG._free(imageSizePtr); openJPEG._free(imageSizeXPtr); openJPEG._free(imageSizeYPtr); openJPEG._free(imageSizeCompPtr); return image; } function decodeOpenJpeg2000 (imageFrame, pixelData) { const bytesPerPixel = imageFrame.bitsAllocated <= 8 ? 1 : 2; const signed = imageFrame.pixelRepresentation === 1; const image = decodeOpenJPEG(pixelData, bytesPerPixel, signed); imageFrame.columns = image.sx; imageFrame.rows = image.sy; imageFrame.pixelData = image.pixelData; if (image.nbChannels > 1) { imageFrame.photometricInterpretation = 'RGB'; } return imageFrame; } function initializeJPEG2000 (decodeConfig) { // check to make sure codec is loaded if (!decodeConfig.usePDFJS) { if (typeof OpenJPEG === 'undefined') { throw new Error('OpenJPEG decoder not loaded'); } } if (!openJPEG) { openJPEG = OpenJPEG(); if (!openJPEG || !openJPEG._jp2_decode) { throw new Error('OpenJPEG failed to initialize'); } } } function decodeJPEG2000 (imageFrame, pixelData, decodeConfig, options = {}) { initializeJPEG2000(decodeConfig); if (options.usePDFJS || decodeConfig.usePDFJS) { // OHIF image-JPEG2000 https://github.com/OHIF/image-JPEG2000 // console.log('PDFJS') return decodeJpx(imageFrame, pixelData); } // OpenJPEG2000 https://github.com/jpambrun/openjpeg // console.log('OpenJPEG') return decodeOpenJpeg2000(imageFrame, pixelData); } export default decodeJPEG2000; export { initializeJPEG2000 };