{"version":3,"file":"NRRDLoader.cjs","sources":["../../src/loaders/NRRDLoader.js"],"sourcesContent":["import { FileLoader, Loader, Matrix4, Vector3 } from 'three'\nimport { gunzipSync } from 'fflate'\nimport { Volume } from '../misc/Volume'\n\nclass NRRDLoader extends Loader {\n  constructor(manager) {\n    super(manager)\n  }\n\n  load(url, onLoad, onProgress, onError) {\n    const scope = this\n\n    const loader = new FileLoader(scope.manager)\n    loader.setPath(scope.path)\n    loader.setResponseType('arraybuffer')\n    loader.setRequestHeader(scope.requestHeader)\n    loader.setWithCredentials(scope.withCredentials)\n    loader.load(\n      url,\n      function (data) {\n        try {\n          onLoad(scope.parse(data))\n        } catch (e) {\n          if (onError) {\n            onError(e)\n          } else {\n            console.error(e)\n          }\n\n          scope.manager.itemError(url)\n        }\n      },\n      onProgress,\n      onError,\n    )\n  }\n\n  parse(data) {\n    // this parser is largely inspired from the XTK NRRD parser : https://github.com/xtk/X\n\n    let _data = data\n\n    let _dataPointer = 0\n\n    const _nativeLittleEndian = new Int8Array(new Int16Array([1]).buffer)[0] > 0\n\n    const _littleEndian = true\n\n    const headerObject = {}\n\n    function scan(type, chunks) {\n      if (chunks === undefined || chunks === null) {\n        chunks = 1\n      }\n\n      let _chunkSize = 1\n      let _array_type = Uint8Array\n\n      switch (type) {\n        // 1 byte data types\n        case 'uchar':\n          break\n        case 'schar':\n          _array_type = Int8Array\n          break\n        // 2 byte data types\n        case 'ushort':\n          _array_type = Uint16Array\n          _chunkSize = 2\n          break\n        case 'sshort':\n          _array_type = Int16Array\n          _chunkSize = 2\n          break\n        // 4 byte data types\n        case 'uint':\n          _array_type = Uint32Array\n          _chunkSize = 4\n          break\n        case 'sint':\n          _array_type = Int32Array\n          _chunkSize = 4\n          break\n        case 'float':\n          _array_type = Float32Array\n          _chunkSize = 4\n          break\n        case 'complex':\n          _array_type = Float64Array\n          _chunkSize = 8\n          break\n        case 'double':\n          _array_type = Float64Array\n          _chunkSize = 8\n          break\n      }\n\n      // increase the data pointer in-place\n      let _bytes = new _array_type(_data.slice(_dataPointer, (_dataPointer += chunks * _chunkSize)))\n\n      // if required, flip the endianness of the bytes\n      if (_nativeLittleEndian != _littleEndian) {\n        // we need to flip here since the format doesn't match the native endianness\n        _bytes = flipEndianness(_bytes, _chunkSize)\n      }\n\n      if (chunks == 1) {\n        // if only one chunk was requested, just return one value\n        return _bytes[0]\n      }\n\n      // return the byte array\n      return _bytes\n    }\n\n    //Flips typed array endianness in-place. Based on https://github.com/kig/DataStream.js/blob/master/DataStream.js.\n\n    function flipEndianness(array, chunkSize) {\n      const u8 = new Uint8Array(array.buffer, array.byteOffset, array.byteLength)\n      for (let i = 0; i < array.byteLength; i += chunkSize) {\n        for (let j = i + chunkSize - 1, k = i; j > k; j--, k++) {\n          const tmp = u8[k]\n          u8[k] = u8[j]\n          u8[j] = tmp\n        }\n      }\n\n      return array\n    }\n\n    //parse the header\n    function parseHeader(header) {\n      let data, field, fn, i, l, m, _i, _len\n      const lines = header.split(/\\r?\\n/)\n      for (_i = 0, _len = lines.length; _i < _len; _i++) {\n        l = lines[_i]\n        if (l.match(/NRRD\\d+/)) {\n          headerObject.isNrrd = true\n        } else if (l.match(/^#/)) {\n        } else if ((m = l.match(/(.*):(.*)/))) {\n          field = m[1].trim()\n          data = m[2].trim()\n          fn = _fieldFunctions[field]\n          if (fn) {\n            fn.call(headerObject, data)\n          } else {\n            headerObject[field] = data\n          }\n        }\n      }\n\n      if (!headerObject.isNrrd) {\n        throw new Error('Not an NRRD file')\n      }\n\n      if (headerObject.encoding === 'bz2' || headerObject.encoding === 'bzip2') {\n        throw new Error('Bzip is not supported')\n      }\n\n      if (!headerObject.vectors) {\n        //if no space direction is set, let's use the identity\n        headerObject.vectors = [new Vector3(1, 0, 0), new Vector3(0, 1, 0), new Vector3(0, 0, 1)]\n        //apply spacing if defined\n        if (headerObject.spacings) {\n          for (i = 0; i <= 2; i++) {\n            if (!isNaN(headerObject.spacings[i])) {\n              headerObject.vectors[i].multiplyScalar(headerObject.spacings[i])\n            }\n          }\n        }\n      }\n    }\n\n    //parse the data when registred as one of this type : 'text', 'ascii', 'txt'\n    function parseDataAsText(data, start, end) {\n      let number = ''\n      start = start || 0\n      end = end || data.length\n      let value\n      //length of the result is the product of the sizes\n      const lengthOfTheResult = headerObject.sizes.reduce(function (previous, current) {\n        return previous * current\n      }, 1)\n\n      let base = 10\n      if (headerObject.encoding === 'hex') {\n        base = 16\n      }\n\n      const result = new headerObject.__array(lengthOfTheResult)\n      let resultIndex = 0\n      let parsingFunction = parseInt\n      if (headerObject.__array === Float32Array || headerObject.__array === Float64Array) {\n        parsingFunction = parseFloat\n      }\n\n      for (let i = start; i < end; i++) {\n        value = data[i]\n        //if value is not a space\n        if ((value < 9 || value > 13) && value !== 32) {\n          number += String.fromCharCode(value)\n        } else {\n          if (number !== '') {\n            result[resultIndex] = parsingFunction(number, base)\n            resultIndex++\n          }\n\n          number = ''\n        }\n      }\n\n      if (number !== '') {\n        result[resultIndex] = parsingFunction(number, base)\n        resultIndex++\n      }\n\n      return result\n    }\n\n    const _bytes = scan('uchar', data.byteLength)\n    const _length = _bytes.length\n    let _header = null\n    let _data_start = 0\n    let i\n    for (i = 1; i < _length; i++) {\n      if (_bytes[i - 1] == 10 && _bytes[i] == 10) {\n        // we found two line breaks in a row\n        // now we know what the header is\n        _header = this.parseChars(_bytes, 0, i - 2)\n        // this is were the data starts\n        _data_start = i + 1\n        break\n      }\n    }\n\n    // parse the header\n    parseHeader(_header)\n\n    _data = _bytes.subarray(_data_start) // the data without header\n    if (headerObject.encoding.substring(0, 2) === 'gz') {\n      // we need to decompress the datastream\n      // here we start the unzipping and get a typed Uint8Array back\n      _data = gunzipSync(new Uint8Array(_data))\n    } else if (\n      headerObject.encoding === 'ascii' ||\n      headerObject.encoding === 'text' ||\n      headerObject.encoding === 'txt' ||\n      headerObject.encoding === 'hex'\n    ) {\n      _data = parseDataAsText(_data)\n    } else if (headerObject.encoding === 'raw') {\n      //we need to copy the array to create a new array buffer, else we retrieve the original arraybuffer with the header\n      const _copy = new Uint8Array(_data.length)\n\n      for (let i = 0; i < _data.length; i++) {\n        _copy[i] = _data[i]\n      }\n\n      _data = _copy\n    }\n\n    // .. let's use the underlying array buffer\n    _data = _data.buffer\n\n    const volume = new Volume()\n    volume.header = headerObject\n    //\n    // parse the (unzipped) data to a datastream of the correct type\n    //\n    volume.data = new headerObject.__array(_data)\n    // get the min and max intensities\n    const min_max = volume.computeMinMax()\n    const min = min_max[0]\n    const max = min_max[1]\n    // attach the scalar range to the volume\n    volume.windowLow = min\n    volume.windowHigh = max\n\n    // get the image dimensions\n    volume.dimensions = [headerObject.sizes[0], headerObject.sizes[1], headerObject.sizes[2]]\n    volume.xLength = volume.dimensions[0]\n    volume.yLength = volume.dimensions[1]\n    volume.zLength = volume.dimensions[2]\n    // spacing\n    const spacingX = new Vector3(\n      headerObject.vectors[0][0],\n      headerObject.vectors[0][1],\n      headerObject.vectors[0][2],\n    ).length()\n    const spacingY = new Vector3(\n      headerObject.vectors[1][0],\n      headerObject.vectors[1][1],\n      headerObject.vectors[1][2],\n    ).length()\n    const spacingZ = new Vector3(\n      headerObject.vectors[2][0],\n      headerObject.vectors[2][1],\n      headerObject.vectors[2][2],\n    ).length()\n    volume.spacing = [spacingX, spacingY, spacingZ]\n\n    // Create IJKtoRAS matrix\n    volume.matrix = new Matrix4()\n\n    let _spaceX = 1\n    let _spaceY = 1\n    const _spaceZ = 1\n\n    if (headerObject.space == 'left-posterior-superior') {\n      _spaceX = -1\n      _spaceY = -1\n    } else if (headerObject.space === 'left-anterior-superior') {\n      _spaceX = -1\n    }\n\n    if (!headerObject.vectors) {\n      volume.matrix.set(_spaceX, 0, 0, 0, 0, _spaceY, 0, 0, 0, 0, _spaceZ, 0, 0, 0, 0, 1)\n    } else {\n      const v = headerObject.vectors\n\n      volume.matrix.set(\n        _spaceX * v[0][0],\n        _spaceX * v[1][0],\n        _spaceX * v[2][0],\n        0,\n        _spaceY * v[0][1],\n        _spaceY * v[1][1],\n        _spaceY * v[2][1],\n        0,\n        _spaceZ * v[0][2],\n        _spaceZ * v[1][2],\n        _spaceZ * v[2][2],\n        0,\n        0,\n        0,\n        0,\n        1,\n      )\n    }\n\n    volume.inverseMatrix = new Matrix4()\n    volume.inverseMatrix.copy(volume.matrix).invert()\n    volume.RASDimensions = new Vector3(volume.xLength, volume.yLength, volume.zLength)\n      .applyMatrix4(volume.matrix)\n      .round()\n      .toArray()\n      .map(Math.abs)\n\n    // .. and set the default threshold\n    // only if the threshold was not already set\n    if (volume.lowerThreshold === -Infinity) {\n      volume.lowerThreshold = min\n    }\n\n    if (volume.upperThreshold === Infinity) {\n      volume.upperThreshold = max\n    }\n\n    return volume\n  }\n\n  parseChars(array, start, end) {\n    // without borders, use the whole array\n    if (start === undefined) {\n      start = 0\n    }\n\n    if (end === undefined) {\n      end = array.length\n    }\n\n    let output = ''\n    // create and append the chars\n    let i = 0\n    for (i = start; i < end; ++i) {\n      output += String.fromCharCode(array[i])\n    }\n\n    return output\n  }\n}\n\nconst _fieldFunctions = {\n  type: function (data) {\n    switch (data) {\n      case 'uchar':\n      case 'unsigned char':\n      case 'uint8':\n      case 'uint8_t':\n        this.__array = Uint8Array\n        break\n      case 'signed char':\n      case 'int8':\n      case 'int8_t':\n        this.__array = Int8Array\n        break\n      case 'short':\n      case 'short int':\n      case 'signed short':\n      case 'signed short int':\n      case 'int16':\n      case 'int16_t':\n        this.__array = Int16Array\n        break\n      case 'ushort':\n      case 'unsigned short':\n      case 'unsigned short int':\n      case 'uint16':\n      case 'uint16_t':\n        this.__array = Uint16Array\n        break\n      case 'int':\n      case 'signed int':\n      case 'int32':\n      case 'int32_t':\n        this.__array = Int32Array\n        break\n      case 'uint':\n      case 'unsigned int':\n      case 'uint32':\n      case 'uint32_t':\n        this.__array = Uint32Array\n        break\n      case 'float':\n        this.__array = Float32Array\n        break\n      case 'double':\n        this.__array = Float64Array\n        break\n      default:\n        throw new Error('Unsupported NRRD data type: ' + data)\n    }\n\n    return (this.type = data)\n  },\n\n  endian: function (data) {\n    return (this.endian = data)\n  },\n\n  encoding: function (data) {\n    return (this.encoding = data)\n  },\n\n  dimension: function (data) {\n    return (this.dim = parseInt(data, 10))\n  },\n\n  sizes: function (data) {\n    let i\n    return (this.sizes = (function () {\n      const _ref = data.split(/\\s+/)\n      const _results = []\n\n      for (let _i = 0, _len = _ref.length; _i < _len; _i++) {\n        i = _ref[_i]\n        _results.push(parseInt(i, 10))\n      }\n\n      return _results\n    })())\n  },\n\n  space: function (data) {\n    return (this.space = data)\n  },\n\n  'space origin': function (data) {\n    return (this.space_origin = data.split('(')[1].split(')')[0].split(','))\n  },\n\n  'space directions': function (data) {\n    let f, v\n    const parts = data.match(/\\(.*?\\)/g)\n    return (this.vectors = (function () {\n      const _results = []\n\n      for (let _i = 0, _len = parts.length; _i < _len; _i++) {\n        v = parts[_i]\n        _results.push(\n          (function () {\n            const _ref = v.slice(1, -1).split(/,/)\n            const _results2 = []\n\n            for (let _j = 0, _len2 = _ref.length; _j < _len2; _j++) {\n              f = _ref[_j]\n              _results2.push(parseFloat(f))\n            }\n\n            return _results2\n          })(),\n        )\n      }\n\n      return _results\n    })())\n  },\n\n  spacings: function (data) {\n    let f\n    const parts = data.split(/\\s+/)\n    return (this.spacings = (function () {\n      const _results = []\n\n      for (let _i = 0, _len = parts.length; _i < _len; _i++) {\n        f = parts[_i]\n        _results.push(parseFloat(f))\n      }\n\n      return _results\n    })())\n  },\n}\n\nexport { NRRDLoader }\n"],"names":["Loader","FileLoader","_bytes","i","data","Vector3","gunzipSync","Volume","Matrix4"],"mappings":"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"}