@loaders.gl/pointclouds 0.0.0-stage → 5.0.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (511) hide show
  1. package/LAS-README.md +12 -0
  2. package/LICENSE +24 -0
  3. package/PCD-README.md +12 -0
  4. package/PLY-README.md +38 -0
  5. package/README.md +11 -2
  6. package/THIRD-PARTY-NOTICES.md +27 -0
  7. package/dist/dist.dev.js +30165 -0
  8. package/dist/dist.min.js +54 -0
  9. package/dist/index.cjs +61 -0
  10. package/dist/index.cjs.map +7 -0
  11. package/dist/index.d.ts +16 -0
  12. package/dist/index.d.ts.map +1 -0
  13. package/dist/index.js +13 -0
  14. package/dist/index.js.map +1 -0
  15. package/dist/las/bundled.cjs +72 -0
  16. package/dist/las/bundled.cjs.map +7 -0
  17. package/dist/las/bundled.d.ts +12 -0
  18. package/dist/las/bundled.d.ts.map +1 -0
  19. package/dist/las/bundled.js +12 -0
  20. package/dist/las/bundled.js.map +1 -0
  21. package/dist/las/index.cjs +78 -0
  22. package/dist/las/index.cjs.map +7 -0
  23. package/dist/las/index.d.ts +17 -0
  24. package/dist/las/index.d.ts.map +1 -0
  25. package/dist/las/index.js +15 -0
  26. package/dist/las/index.js.map +1 -0
  27. package/dist/las/las-copc-loader-types.cjs +49 -0
  28. package/dist/las/las-copc-loader-types.cjs.map +7 -0
  29. package/dist/las/las-copc-loader-types.d.ts +63 -0
  30. package/dist/las/las-copc-loader-types.d.ts.map +1 -0
  31. package/dist/las/las-copc-loader-types.js +14 -0
  32. package/dist/las/las-copc-loader-types.js.map +1 -0
  33. package/dist/las/las-copc-loader.cjs +57 -0
  34. package/dist/las/las-copc-loader.cjs.map +7 -0
  35. package/dist/las/las-copc-loader.d.ts +37 -0
  36. package/dist/las/las-copc-loader.d.ts.map +1 -0
  37. package/dist/las/las-copc-loader.js +40 -0
  38. package/dist/las/las-copc-loader.js.map +1 -0
  39. package/dist/las/las-format.cjs +44 -0
  40. package/dist/las/las-format.cjs.map +7 -0
  41. package/dist/las/las-format.d.ts +16 -0
  42. package/dist/las/las-format.d.ts.map +1 -0
  43. package/dist/las/las-format.js +19 -0
  44. package/dist/las/las-format.js.map +1 -0
  45. package/dist/las/las-loader-shared.cjs +82 -0
  46. package/dist/las/las-loader-shared.cjs.map +7 -0
  47. package/dist/las/las-loader-shared.d.ts +66 -0
  48. package/dist/las/las-loader-shared.d.ts.map +1 -0
  49. package/dist/las/las-loader-shared.js +58 -0
  50. package/dist/las/las-loader-shared.js.map +1 -0
  51. package/dist/las/las-loader-types.cjs +54 -0
  52. package/dist/las/las-loader-types.cjs.map +7 -0
  53. package/dist/las/las-loader-types.d.ts +104 -0
  54. package/dist/las/las-loader-types.d.ts.map +1 -0
  55. package/dist/las/las-loader-types.js +19 -0
  56. package/dist/las/las-loader-types.js.map +1 -0
  57. package/dist/las/las-loader.cjs +80 -0
  58. package/dist/las/las-loader.cjs.map +7 -0
  59. package/dist/las/las-loader.d.ts +45 -0
  60. package/dist/las/las-loader.d.ts.map +1 -0
  61. package/dist/las/las-loader.js +58 -0
  62. package/dist/las/las-loader.js.map +1 -0
  63. package/dist/las/las-writer.cjs +1054 -0
  64. package/dist/las/las-writer.cjs.map +7 -0
  65. package/dist/las/las-writer.d.ts +69 -0
  66. package/dist/las/las-writer.d.ts.map +1 -0
  67. package/dist/las/las-writer.js +994 -0
  68. package/dist/las/las-writer.js.map +1 -0
  69. package/dist/las/laz-rs-loader-types.cjs +49 -0
  70. package/dist/las/laz-rs-loader-types.cjs.map +7 -0
  71. package/dist/las/laz-rs-loader-types.d.ts +65 -0
  72. package/dist/las/laz-rs-loader-types.d.ts.map +1 -0
  73. package/dist/las/laz-rs-loader-types.js +16 -0
  74. package/dist/las/laz-rs-loader-types.js.map +1 -0
  75. package/dist/las/laz-rs-loader.cjs +272 -0
  76. package/dist/las/laz-rs-loader.cjs.map +7 -0
  77. package/dist/las/laz-rs-loader.d.ts +37 -0
  78. package/dist/las/laz-rs-loader.d.ts.map +1 -0
  79. package/dist/las/laz-rs-loader.js +38 -0
  80. package/dist/las/laz-rs-loader.js.map +1 -0
  81. package/dist/las/lazperf-loader-types.cjs +49 -0
  82. package/dist/las/lazperf-loader-types.cjs.map +7 -0
  83. package/dist/las/lazperf-loader-types.d.ts +67 -0
  84. package/dist/las/lazperf-loader-types.d.ts.map +1 -0
  85. package/dist/las/lazperf-loader-types.js +17 -0
  86. package/dist/las/lazperf-loader-types.js.map +1 -0
  87. package/dist/las/lazperf-loader.cjs +60 -0
  88. package/dist/las/lazperf-loader.cjs.map +7 -0
  89. package/dist/las/lazperf-loader.d.ts +39 -0
  90. package/dist/las/lazperf-loader.d.ts.map +1 -0
  91. package/dist/las/lazperf-loader.js +44 -0
  92. package/dist/las/lazperf-loader.js.map +1 -0
  93. package/dist/las/lib/copc/parse-las.cjs +177 -0
  94. package/dist/las/lib/copc/parse-las.cjs.map +7 -0
  95. package/dist/las/lib/copc/parse-las.d.ts +17 -0
  96. package/dist/las/lib/copc/parse-las.d.ts.map +1 -0
  97. package/dist/las/lib/copc/parse-las.js +215 -0
  98. package/dist/las/lib/copc/parse-las.js.map +1 -0
  99. package/dist/las/lib/get-las-schema.cjs +62 -0
  100. package/dist/las/lib/get-las-schema.cjs.map +7 -0
  101. package/dist/las/lib/get-las-schema.d.ts +16 -0
  102. package/dist/las/lib/get-las-schema.d.ts.map +1 -0
  103. package/dist/las/lib/get-las-schema.js +46 -0
  104. package/dist/las/lib/get-las-schema.js.map +1 -0
  105. package/dist/las/lib/las-compatibility.cjs +110 -0
  106. package/dist/las/lib/las-compatibility.cjs.map +7 -0
  107. package/dist/las/lib/las-compatibility.d.ts +40 -0
  108. package/dist/las/lib/las-compatibility.d.ts.map +1 -0
  109. package/dist/las/lib/las-compatibility.js +115 -0
  110. package/dist/las/lib/las-compatibility.js.map +1 -0
  111. package/dist/las/lib/las-extra-bytes.cjs +223 -0
  112. package/dist/las/lib/las-extra-bytes.cjs.map +7 -0
  113. package/dist/las/lib/las-extra-bytes.d.ts +35 -0
  114. package/dist/las/lib/las-extra-bytes.d.ts.map +1 -0
  115. package/dist/las/lib/las-extra-bytes.js +195 -0
  116. package/dist/las/lib/las-extra-bytes.js.map +1 -0
  117. package/dist/las/lib/las-types.cjs +19 -0
  118. package/dist/las/lib/las-types.cjs.map +7 -0
  119. package/dist/las/lib/las-types.d.ts +194 -0
  120. package/dist/las/lib/las-types.d.ts.map +1 -0
  121. package/dist/las/lib/las-types.js +5 -0
  122. package/dist/las/lib/las-types.js.map +1 -0
  123. package/dist/las/lib/las-waveform.cjs +196 -0
  124. package/dist/las/lib/las-waveform.cjs.map +7 -0
  125. package/dist/las/lib/las-waveform.d.ts +89 -0
  126. package/dist/las/lib/las-waveform.d.ts.map +1 -0
  127. package/dist/las/lib/las-waveform.js +193 -0
  128. package/dist/las/lib/las-waveform.js.map +1 -0
  129. package/dist/las/lib/laz-perf/laslaz-decoder.cjs +382 -0
  130. package/dist/las/lib/laz-perf/laslaz-decoder.cjs.map +7 -0
  131. package/dist/las/lib/laz-perf/laslaz-decoder.d.ts +129 -0
  132. package/dist/las/lib/laz-perf/laslaz-decoder.d.ts.map +1 -0
  133. package/dist/las/lib/laz-perf/laslaz-decoder.js +377 -0
  134. package/dist/las/lib/laz-perf/laslaz-decoder.js.map +1 -0
  135. package/dist/las/lib/laz-perf/parse-las.cjs +270 -0
  136. package/dist/las/lib/laz-perf/parse-las.cjs.map +7 -0
  137. package/dist/las/lib/laz-perf/parse-las.d.ts +24 -0
  138. package/dist/las/lib/laz-perf/parse-las.d.ts.map +1 -0
  139. package/dist/las/lib/laz-perf/parse-las.js +307 -0
  140. package/dist/las/lib/laz-perf/parse-las.js.map +1 -0
  141. package/dist/las/lib/laz-rs-wasm/laslaz-decoder.cjs +631 -0
  142. package/dist/las/lib/laz-rs-wasm/laslaz-decoder.cjs.map +7 -0
  143. package/dist/las/lib/laz-rs-wasm/laslaz-decoder.d.ts +129 -0
  144. package/dist/las/lib/laz-rs-wasm/laslaz-decoder.d.ts.map +1 -0
  145. package/dist/las/lib/laz-rs-wasm/laslaz-decoder.js +414 -0
  146. package/dist/las/lib/laz-rs-wasm/laslaz-decoder.js.map +1 -0
  147. package/dist/las/lib/laz-rs-wasm/parse-las.cjs +270 -0
  148. package/dist/las/lib/laz-rs-wasm/parse-las.cjs.map +7 -0
  149. package/dist/las/lib/laz-rs-wasm/parse-las.d.ts +24 -0
  150. package/dist/las/lib/laz-rs-wasm/parse-las.d.ts.map +1 -0
  151. package/dist/las/lib/laz-rs-wasm/parse-las.js +307 -0
  152. package/dist/las/lib/laz-rs-wasm/parse-las.js.map +1 -0
  153. package/dist/las/lib/typescript/parse-las.cjs +2767 -0
  154. package/dist/las/lib/typescript/parse-las.cjs.map +7 -0
  155. package/dist/las/lib/typescript/parse-las.d.ts +39 -0
  156. package/dist/las/lib/typescript/parse-las.d.ts.map +1 -0
  157. package/dist/las/lib/typescript/parse-las.js +2607 -0
  158. package/dist/las/lib/typescript/parse-las.js.map +1 -0
  159. package/dist/las/libs/laz-perf/laz-perf.cjs +18093 -0
  160. package/dist/las/libs/laz-perf/laz-perf.cjs.map +7 -0
  161. package/dist/las/libs/laz-perf/laz-perf.d.ts +2 -0
  162. package/dist/las/libs/laz-perf/laz-perf.d.ts.map +1 -0
  163. package/dist/las/libs/laz-perf/laz-perf.js +19003 -0
  164. package/dist/las/libs/laz-perf/laz-perf.js.map +1 -0
  165. package/dist/las/libs/laz-rs-wasm/laz_rs_wasm.d.ts +95 -0
  166. package/dist/las/libs/laz-rs-wasm/laz_rs_wasm.d.ts.map +1 -0
  167. package/dist/las/libs/laz-rs-wasm/laz_rs_wasm.js +442 -0
  168. package/dist/las/libs/laz-rs-wasm/laz_rs_wasm.js.map +1 -0
  169. package/dist/las/libs/laz-rs-wasm/laz_rs_wasm_bg.wasm +0 -0
  170. package/dist/las/libs/laz-rs-wasm/laz_rs_wasm_bg.wasm.d.ts +38 -0
  171. package/dist/las/unbundled.cjs +71 -0
  172. package/dist/las/unbundled.cjs.map +7 -0
  173. package/dist/las/unbundled.d.ts +11 -0
  174. package/dist/las/unbundled.d.ts.map +1 -0
  175. package/dist/las/unbundled.js +11 -0
  176. package/dist/las/unbundled.js.map +1 -0
  177. package/dist/las/workers/las-worker.cjs +23 -0
  178. package/dist/las/workers/las-worker.cjs.map +7 -0
  179. package/dist/las/workers/las-worker.d.ts +2 -0
  180. package/dist/las/workers/las-worker.d.ts.map +1 -0
  181. package/dist/las/workers/las-worker.js +23 -0
  182. package/dist/las/workers/las-worker.js.map +1 -0
  183. package/dist/las-copc-loader-types.cjs +51 -0
  184. package/dist/las-copc-loader-types.cjs.map +7 -0
  185. package/dist/las-copc-loader-types.d.ts +2 -0
  186. package/dist/las-copc-loader-types.d.ts.map +1 -0
  187. package/dist/las-copc-loader-types.js +2 -0
  188. package/dist/las-copc-loader-types.js.map +1 -0
  189. package/dist/las-copc-loader.cjs +59 -0
  190. package/dist/las-copc-loader.cjs.map +7 -0
  191. package/dist/las-copc-loader.d.ts +2 -0
  192. package/dist/las-copc-loader.d.ts.map +1 -0
  193. package/dist/las-copc-loader.js +2 -0
  194. package/dist/las-copc-loader.js.map +1 -0
  195. package/dist/las-loader-types.cjs +56 -0
  196. package/dist/las-loader-types.cjs.map +7 -0
  197. package/dist/las-loader-types.d.ts +2 -0
  198. package/dist/las-loader-types.d.ts.map +1 -0
  199. package/dist/las-loader-types.js +2 -0
  200. package/dist/las-loader-types.js.map +1 -0
  201. package/dist/las-loader.cjs +82 -0
  202. package/dist/las-loader.cjs.map +7 -0
  203. package/dist/las-loader.d.ts +2 -0
  204. package/dist/las-loader.d.ts.map +1 -0
  205. package/dist/las-loader.js +2 -0
  206. package/dist/las-loader.js.map +1 -0
  207. package/dist/las-worker.js +23169 -0
  208. package/dist/las-writer.cjs +1056 -0
  209. package/dist/las-writer.cjs.map +7 -0
  210. package/dist/las-writer.d.ts +2 -0
  211. package/dist/las-writer.d.ts.map +1 -0
  212. package/dist/las-writer.js +2 -0
  213. package/dist/las-writer.js.map +1 -0
  214. package/dist/laz-rs-loader-types.cjs +51 -0
  215. package/dist/laz-rs-loader-types.cjs.map +7 -0
  216. package/dist/laz-rs-loader-types.d.ts +2 -0
  217. package/dist/laz-rs-loader-types.d.ts.map +1 -0
  218. package/dist/laz-rs-loader-types.js +2 -0
  219. package/dist/laz-rs-loader-types.js.map +1 -0
  220. package/dist/laz-rs-loader.cjs +274 -0
  221. package/dist/laz-rs-loader.cjs.map +7 -0
  222. package/dist/laz-rs-loader.d.ts +2 -0
  223. package/dist/laz-rs-loader.d.ts.map +1 -0
  224. package/dist/laz-rs-loader.js +2 -0
  225. package/dist/laz-rs-loader.js.map +1 -0
  226. package/dist/lazperf-loader-types.cjs +51 -0
  227. package/dist/lazperf-loader-types.cjs.map +7 -0
  228. package/dist/lazperf-loader-types.d.ts +2 -0
  229. package/dist/lazperf-loader-types.d.ts.map +1 -0
  230. package/dist/lazperf-loader-types.js +2 -0
  231. package/dist/lazperf-loader-types.js.map +1 -0
  232. package/dist/lazperf-loader.cjs +62 -0
  233. package/dist/lazperf-loader.cjs.map +7 -0
  234. package/dist/lazperf-loader.d.ts +2 -0
  235. package/dist/lazperf-loader.d.ts.map +1 -0
  236. package/dist/lazperf-loader.js +2 -0
  237. package/dist/lazperf-loader.js.map +1 -0
  238. package/dist/pcd/bundled.cjs +33 -0
  239. package/dist/pcd/bundled.cjs.map +7 -0
  240. package/dist/pcd/bundled.d.ts +3 -0
  241. package/dist/pcd/bundled.d.ts.map +1 -0
  242. package/dist/pcd/bundled.js +5 -0
  243. package/dist/pcd/bundled.js.map +1 -0
  244. package/dist/pcd/index.cjs +40 -0
  245. package/dist/pcd/index.cjs.map +7 -0
  246. package/dist/pcd/index.d.ts +8 -0
  247. package/dist/pcd/index.d.ts.map +1 -0
  248. package/dist/pcd/index.js +10 -0
  249. package/dist/pcd/index.js.map +1 -0
  250. package/dist/pcd/lib/decompress-lzf.cjs +80 -0
  251. package/dist/pcd/lib/decompress-lzf.cjs.map +7 -0
  252. package/dist/pcd/lib/decompress-lzf.d.ts +7 -0
  253. package/dist/pcd/lib/decompress-lzf.d.ts.map +1 -0
  254. package/dist/pcd/lib/decompress-lzf.js +62 -0
  255. package/dist/pcd/lib/decompress-lzf.js.map +1 -0
  256. package/dist/pcd/lib/get-pcd-schema.cjs +70 -0
  257. package/dist/pcd/lib/get-pcd-schema.cjs.map +7 -0
  258. package/dist/pcd/lib/get-pcd-schema.d.ts +10 -0
  259. package/dist/pcd/lib/get-pcd-schema.d.ts.map +1 -0
  260. package/dist/pcd/lib/get-pcd-schema.js +53 -0
  261. package/dist/pcd/lib/get-pcd-schema.js.map +1 -0
  262. package/dist/pcd/lib/parse-pcd.cjs +354 -0
  263. package/dist/pcd/lib/parse-pcd.cjs.map +7 -0
  264. package/dist/pcd/lib/parse-pcd.d.ts +20 -0
  265. package/dist/pcd/lib/parse-pcd.d.ts.map +1 -0
  266. package/dist/pcd/lib/parse-pcd.js +341 -0
  267. package/dist/pcd/lib/parse-pcd.js.map +1 -0
  268. package/dist/pcd/lib/pcd-types.cjs +19 -0
  269. package/dist/pcd/lib/pcd-types.cjs.map +7 -0
  270. package/dist/pcd/lib/pcd-types.d.ts +31 -0
  271. package/dist/pcd/lib/pcd-types.d.ts.map +1 -0
  272. package/dist/pcd/lib/pcd-types.js +5 -0
  273. package/dist/pcd/lib/pcd-types.js.map +1 -0
  274. package/dist/pcd/pcd-format.cjs +42 -0
  275. package/dist/pcd/pcd-format.cjs.map +7 -0
  276. package/dist/pcd/pcd-format.d.ts +16 -0
  277. package/dist/pcd/pcd-format.d.ts.map +1 -0
  278. package/dist/pcd/pcd-format.js +19 -0
  279. package/dist/pcd/pcd-format.js.map +1 -0
  280. package/dist/pcd/pcd-loader-types.cjs +64 -0
  281. package/dist/pcd/pcd-loader-types.cjs.map +7 -0
  282. package/dist/pcd/pcd-loader-types.d.ts +105 -0
  283. package/dist/pcd/pcd-loader-types.d.ts.map +1 -0
  284. package/dist/pcd/pcd-loader-types.js +35 -0
  285. package/dist/pcd/pcd-loader-types.js.map +1 -0
  286. package/dist/pcd/pcd-loader.cjs +144 -0
  287. package/dist/pcd/pcd-loader.cjs.map +7 -0
  288. package/dist/pcd/pcd-loader.d.ts +44 -0
  289. package/dist/pcd/pcd-loader.d.ts.map +1 -0
  290. package/dist/pcd/pcd-loader.js +128 -0
  291. package/dist/pcd/pcd-loader.js.map +1 -0
  292. package/dist/pcd/pcd-writer.cjs +134 -0
  293. package/dist/pcd/pcd-writer.cjs.map +7 -0
  294. package/dist/pcd/pcd-writer.d.ts +37 -0
  295. package/dist/pcd/pcd-writer.d.ts.map +1 -0
  296. package/dist/pcd/pcd-writer.js +115 -0
  297. package/dist/pcd/pcd-writer.js.map +1 -0
  298. package/dist/pcd/unbundled.cjs +33 -0
  299. package/dist/pcd/unbundled.cjs.map +7 -0
  300. package/dist/pcd/unbundled.d.ts +3 -0
  301. package/dist/pcd/unbundled.d.ts.map +1 -0
  302. package/dist/pcd/unbundled.js +5 -0
  303. package/dist/pcd/unbundled.js.map +1 -0
  304. package/dist/pcd/workers/pcd-worker.cjs +23 -0
  305. package/dist/pcd/workers/pcd-worker.cjs.map +7 -0
  306. package/dist/pcd/workers/pcd-worker.d.ts +2 -0
  307. package/dist/pcd/workers/pcd-worker.d.ts.map +1 -0
  308. package/dist/pcd/workers/pcd-worker.js +23 -0
  309. package/dist/pcd/workers/pcd-worker.js.map +1 -0
  310. package/dist/pcd-loader-types.cjs +66 -0
  311. package/dist/pcd-loader-types.cjs.map +7 -0
  312. package/dist/pcd-loader-types.d.ts +2 -0
  313. package/dist/pcd-loader-types.d.ts.map +1 -0
  314. package/dist/pcd-loader-types.js +2 -0
  315. package/dist/pcd-loader-types.js.map +1 -0
  316. package/dist/pcd-loader.cjs +146 -0
  317. package/dist/pcd-loader.cjs.map +7 -0
  318. package/dist/pcd-loader.d.ts +2 -0
  319. package/dist/pcd-loader.d.ts.map +1 -0
  320. package/dist/pcd-loader.js +2 -0
  321. package/dist/pcd-loader.js.map +1 -0
  322. package/dist/pcd-worker.js +17655 -0
  323. package/dist/pcd-writer.cjs +136 -0
  324. package/dist/pcd-writer.cjs.map +7 -0
  325. package/dist/pcd-writer.d.ts +2 -0
  326. package/dist/pcd-writer.d.ts.map +1 -0
  327. package/dist/pcd-writer.js +2 -0
  328. package/dist/pcd-writer.js.map +1 -0
  329. package/dist/ply/bundled.cjs +33 -0
  330. package/dist/ply/bundled.cjs.map +7 -0
  331. package/dist/ply/bundled.d.ts +3 -0
  332. package/dist/ply/bundled.d.ts.map +1 -0
  333. package/dist/ply/bundled.js +5 -0
  334. package/dist/ply/bundled.js.map +1 -0
  335. package/dist/ply/index.cjs +40 -0
  336. package/dist/ply/index.cjs.map +7 -0
  337. package/dist/ply/index.d.ts +8 -0
  338. package/dist/ply/index.d.ts.map +1 -0
  339. package/dist/ply/index.js +11 -0
  340. package/dist/ply/index.js.map +1 -0
  341. package/dist/ply/lib/get-ply-schema.cjs +126 -0
  342. package/dist/ply/lib/get-ply-schema.cjs.map +7 -0
  343. package/dist/ply/lib/get-ply-schema.d.ts +10 -0
  344. package/dist/ply/lib/get-ply-schema.d.ts.map +1 -0
  345. package/dist/ply/lib/get-ply-schema.js +117 -0
  346. package/dist/ply/lib/get-ply-schema.js.map +1 -0
  347. package/dist/ply/lib/normalize-ply.cjs +96 -0
  348. package/dist/ply/lib/normalize-ply.cjs.map +7 -0
  349. package/dist/ply/lib/normalize-ply.d.ts +8 -0
  350. package/dist/ply/lib/normalize-ply.d.ts.map +1 -0
  351. package/dist/ply/lib/normalize-ply.js +89 -0
  352. package/dist/ply/lib/normalize-ply.js.map +1 -0
  353. package/dist/ply/lib/parse-ply-arrow.cjs +552 -0
  354. package/dist/ply/lib/parse-ply-arrow.cjs.map +7 -0
  355. package/dist/ply/lib/parse-ply-arrow.d.ts +25 -0
  356. package/dist/ply/lib/parse-ply-arrow.d.ts.map +1 -0
  357. package/dist/ply/lib/parse-ply-arrow.js +493 -0
  358. package/dist/ply/lib/parse-ply-arrow.js.map +1 -0
  359. package/dist/ply/lib/parse-ply-in-batches.cjs +607 -0
  360. package/dist/ply/lib/parse-ply-in-batches.cjs.map +7 -0
  361. package/dist/ply/lib/parse-ply-in-batches.d.ts +9 -0
  362. package/dist/ply/lib/parse-ply-in-batches.d.ts.map +1 -0
  363. package/dist/ply/lib/parse-ply-in-batches.js +625 -0
  364. package/dist/ply/lib/parse-ply-in-batches.js.map +1 -0
  365. package/dist/ply/lib/parse-ply.cjs +755 -0
  366. package/dist/ply/lib/parse-ply.cjs.map +7 -0
  367. package/dist/ply/lib/parse-ply.d.ts +69 -0
  368. package/dist/ply/lib/parse-ply.d.ts.map +1 -0
  369. package/dist/ply/lib/parse-ply.js +851 -0
  370. package/dist/ply/lib/parse-ply.js.map +1 -0
  371. package/dist/ply/lib/ply-types.cjs +19 -0
  372. package/dist/ply/lib/ply-types.cjs.map +7 -0
  373. package/dist/ply/lib/ply-types.d.ts +37 -0
  374. package/dist/ply/lib/ply-types.d.ts.map +1 -0
  375. package/dist/ply/lib/ply-types.js +2 -0
  376. package/dist/ply/lib/ply-types.js.map +1 -0
  377. package/dist/ply/ply-format.cjs +43 -0
  378. package/dist/ply/ply-format.cjs.map +7 -0
  379. package/dist/ply/ply-format.d.ts +18 -0
  380. package/dist/ply/ply-format.d.ts.map +1 -0
  381. package/dist/ply/ply-format.js +22 -0
  382. package/dist/ply/ply-format.js.map +1 -0
  383. package/dist/ply/ply-loader-types.cjs +65 -0
  384. package/dist/ply/ply-loader-types.cjs.map +7 -0
  385. package/dist/ply/ply-loader-types.d.ts +111 -0
  386. package/dist/ply/ply-loader-types.d.ts.map +1 -0
  387. package/dist/ply/ply-loader-types.js +38 -0
  388. package/dist/ply/ply-loader-types.js.map +1 -0
  389. package/dist/ply/ply-loader.cjs +134 -0
  390. package/dist/ply/ply-loader.cjs.map +7 -0
  391. package/dist/ply/ply-loader.d.ts +44 -0
  392. package/dist/ply/ply-loader.d.ts.map +1 -0
  393. package/dist/ply/ply-loader.js +121 -0
  394. package/dist/ply/ply-loader.js.map +1 -0
  395. package/dist/ply/ply-writer.cjs +175 -0
  396. package/dist/ply/ply-writer.cjs.map +7 -0
  397. package/dist/ply/ply-writer.d.ts +37 -0
  398. package/dist/ply/ply-writer.d.ts.map +1 -0
  399. package/dist/ply/ply-writer.js +140 -0
  400. package/dist/ply/ply-writer.js.map +1 -0
  401. package/dist/ply/unbundled.cjs +33 -0
  402. package/dist/ply/unbundled.cjs.map +7 -0
  403. package/dist/ply/unbundled.d.ts +3 -0
  404. package/dist/ply/unbundled.d.ts.map +1 -0
  405. package/dist/ply/unbundled.js +5 -0
  406. package/dist/ply/unbundled.js.map +1 -0
  407. package/dist/ply/workers/ply-worker.cjs +34 -0
  408. package/dist/ply/workers/ply-worker.cjs.map +7 -0
  409. package/dist/ply/workers/ply-worker.d.ts +2 -0
  410. package/dist/ply/workers/ply-worker.d.ts.map +1 -0
  411. package/dist/ply/workers/ply-worker.js +37 -0
  412. package/dist/ply/workers/ply-worker.js.map +1 -0
  413. package/dist/ply-loader-types.cjs +67 -0
  414. package/dist/ply-loader-types.cjs.map +7 -0
  415. package/dist/ply-loader-types.d.ts +2 -0
  416. package/dist/ply-loader-types.d.ts.map +1 -0
  417. package/dist/ply-loader-types.js +2 -0
  418. package/dist/ply-loader-types.js.map +1 -0
  419. package/dist/ply-loader.cjs +136 -0
  420. package/dist/ply-loader.cjs.map +7 -0
  421. package/dist/ply-loader.d.ts +2 -0
  422. package/dist/ply-loader.d.ts.map +1 -0
  423. package/dist/ply-loader.js +2 -0
  424. package/dist/ply-loader.js.map +1 -0
  425. package/dist/ply-worker.js +19308 -0
  426. package/dist/ply-writer.cjs +177 -0
  427. package/dist/ply-writer.cjs.map +7 -0
  428. package/dist/ply-writer.d.ts +2 -0
  429. package/dist/ply-writer.d.ts.map +1 -0
  430. package/dist/ply-writer.js +2 -0
  431. package/dist/ply-writer.js.map +1 -0
  432. package/package.json +237 -4
  433. package/src/index.ts +19 -0
  434. package/src/las/bundled.ts +39 -0
  435. package/src/las/index.ts +70 -0
  436. package/src/las/las-copc-loader-types.ts +18 -0
  437. package/src/las/las-copc-loader.ts +61 -0
  438. package/src/las/las-format.ts +21 -0
  439. package/src/las/las-loader-shared.ts +124 -0
  440. package/src/las/las-loader-types.ts +27 -0
  441. package/src/las/las-loader.ts +109 -0
  442. package/src/las/las-writer.ts +1473 -0
  443. package/src/las/laz-rs-loader-types.ts +21 -0
  444. package/src/las/laz-rs-loader.ts +53 -0
  445. package/src/las/lazperf-loader-types.ts +22 -0
  446. package/src/las/lazperf-loader.ts +65 -0
  447. package/src/las/lib/LASZIP-LICENSE +202 -0
  448. package/src/las/lib/LASZIP-NOTICE +4 -0
  449. package/src/las/lib/copc/parse-las.ts +265 -0
  450. package/src/las/lib/get-las-schema.ts +50 -0
  451. package/src/las/lib/las-compatibility.ts +178 -0
  452. package/src/las/lib/las-extra-bytes.ts +274 -0
  453. package/src/las/lib/las-types.ts +206 -0
  454. package/src/las/lib/las-waveform.ts +292 -0
  455. package/src/las/lib/laz-perf/laslaz-decoder.ts +443 -0
  456. package/src/las/lib/laz-perf/parse-las.ts +412 -0
  457. package/src/las/lib/laz-rs-wasm/laslaz-decoder.ts +488 -0
  458. package/src/las/lib/laz-rs-wasm/parse-las.ts +412 -0
  459. package/src/las/lib/typescript/parse-las.ts +3730 -0
  460. package/src/las/libs/laz-perf/laz-perf.ts +20615 -0
  461. package/src/las/libs/laz-rs-wasm/README.md +5 -0
  462. package/src/las/libs/laz-rs-wasm/laz_rs_wasm.d.ts +89 -0
  463. package/src/las/libs/laz-rs-wasm/laz_rs_wasm.js +497 -0
  464. package/src/las/libs/laz-rs-wasm/laz_rs_wasm_bg.wasm +0 -0
  465. package/src/las/libs/laz-rs-wasm/laz_rs_wasm_bg.wasm.d.ts +38 -0
  466. package/src/las/libs/laz-rs-wasm/package.json +25 -0
  467. package/src/las/unbundled.ts +38 -0
  468. package/src/las/workers/las-worker.ts +24 -0
  469. package/src/las-copc-loader-types.ts +1 -0
  470. package/src/las-copc-loader.ts +1 -0
  471. package/src/las-loader-types.ts +1 -0
  472. package/src/las-loader.ts +1 -0
  473. package/src/las-writer.ts +1 -0
  474. package/src/laz-rs-loader-types.ts +1 -0
  475. package/src/laz-rs-loader.ts +1 -0
  476. package/src/lazperf-loader-types.ts +1 -0
  477. package/src/lazperf-loader.ts +1 -0
  478. package/src/pcd/bundled.ts +9 -0
  479. package/src/pcd/index.ts +13 -0
  480. package/src/pcd/lib/decompress-lzf.ts +68 -0
  481. package/src/pcd/lib/get-pcd-schema.ts +66 -0
  482. package/src/pcd/lib/parse-pcd.ts +474 -0
  483. package/src/pcd/lib/pcd-types.ts +34 -0
  484. package/src/pcd/pcd-format.ts +21 -0
  485. package/src/pcd/pcd-loader-types.ts +53 -0
  486. package/src/pcd/pcd-loader.ts +179 -0
  487. package/src/pcd/pcd-writer.ts +152 -0
  488. package/src/pcd/unbundled.ts +6 -0
  489. package/src/pcd/workers/pcd-worker.ts +24 -0
  490. package/src/pcd-loader-types.ts +1 -0
  491. package/src/pcd-loader.ts +1 -0
  492. package/src/pcd-writer.ts +1 -0
  493. package/src/ply/bundled.ts +9 -0
  494. package/src/ply/index.ts +15 -0
  495. package/src/ply/lib/get-ply-schema.ts +133 -0
  496. package/src/ply/lib/normalize-ply.ts +110 -0
  497. package/src/ply/lib/parse-ply-arrow.ts +676 -0
  498. package/src/ply/lib/parse-ply-in-batches.ts +827 -0
  499. package/src/ply/lib/parse-ply.ts +1081 -0
  500. package/src/ply/lib/ply-types.ts +47 -0
  501. package/src/ply/ply-format.ts +24 -0
  502. package/src/ply/ply-loader-types.ts +61 -0
  503. package/src/ply/ply-loader.ts +185 -0
  504. package/src/ply/ply-writer.ts +215 -0
  505. package/src/ply/unbundled.ts +6 -0
  506. package/src/ply/workers/ply-worker.ts +40 -0
  507. package/src/ply-loader-types.ts +1 -0
  508. package/src/ply-loader.ts +1 -0
  509. package/src/ply-writer.ts +1 -0
  510. package/third-party-licenses/plasio-LICENSE +21 -0
  511. package/third-party-licenses/three-LICENSE +21 -0
@@ -0,0 +1,2767 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/las/lib/typescript/parse-las.ts
21
+ var parse_las_exports = {};
22
+ __export(parse_las_exports, {
23
+ LAS_1_4_HEADER_LENGTH: () => LAS_1_4_HEADER_LENGTH,
24
+ decodeLAZChunkToArrowTable: () => decodeLAZChunkToArrowTable,
25
+ decodeLAZFileInBatches: () => decodeLAZFileInBatches,
26
+ parseLAS: () => parseLAS,
27
+ parseLASChunkedIterator: () => parseLASChunkedIterator,
28
+ parseLASHeader: () => parseLASHeader,
29
+ parseLASInBatches: () => parseLASInBatches
30
+ });
31
+ module.exports = __toCommonJS(parse_las_exports);
32
+ var import_schema_utils = require("@loaders.gl/core/schema-utils");
33
+ var import_loader_utils = require("@loaders.gl/core/loader-utils");
34
+ var import_get_las_schema = require("../get-las-schema.cjs");
35
+ var import_las_compatibility = require("../las-compatibility.cjs");
36
+ var import_las_extra_bytes = require("../las-extra-bytes.cjs");
37
+ var DEFAULT_BATCH_SIZE = 1e3 * 100;
38
+ var LASF_SIGNATURE = 1179861324;
39
+ var LAS_14_HEADER_LENGTH = 375;
40
+ var COMPRESSED_POINT_FORMAT_MASK = 128;
41
+ var POINT_FORMAT_MASK = 63;
42
+ var LASZIP_USER_ID = "laszip encoded";
43
+ var LASZIP_RECORD_ID = 22204;
44
+ var VARIABLE_CHUNK_SIZE = 4294967295;
45
+ var LAZ_CHUNK_TABLE_POINTER_LENGTH = 8;
46
+ var LEGACY_LAZ_FEED_BLOCK_SIZE = 64 * 1024;
47
+ function createLAZChunkMetadata(header, laszip, pointCount) {
48
+ return {
49
+ pointDataRecordFormat: header.pointsFormatId,
50
+ pointDataRecordLength: header.pointsStructSize,
51
+ pointCount,
52
+ point10ItemVersion: laszip.items.find((item) => item.type === 6)?.version,
53
+ gpsTime11ItemVersion: laszip.items.find((item) => item.type === 7)?.version,
54
+ rgb12ItemVersion: laszip.items.find((item) => item.type === 8)?.version,
55
+ byteItemVersion: laszip.items.find((item) => item.type === 0)?.version,
56
+ point14ItemVersion: laszip.point14ItemVersion ?? void 0,
57
+ rgb14ItemVersion: laszip.rgb14ItemVersion ?? void 0,
58
+ wavePacketItemVersion: laszip.wavePacketItemVersion ?? void 0,
59
+ byte14ItemVersion: laszip.byte14ItemVersion ?? void 0
60
+ };
61
+ }
62
+ function parseLAS(arrayBuffer, options = {}) {
63
+ const header = parseLASHeader(arrayBuffer);
64
+ if (header.isCompressed) {
65
+ const bytes = new Uint8Array(arrayBuffer);
66
+ const laszip = parseLASZipVLR(bytes, header);
67
+ validateTypeScriptLAZSupport(header, laszip);
68
+ if (header.pointsFormatId <= 5 || header.pointsFormatId >= 6 && header.pointsFormatId <= 10) {
69
+ return parseCompleteLAZFileToArrowTable(bytes, header, laszip, options);
70
+ }
71
+ const rawPointData = decodeLAZFileToRawPointData(arrayBuffer, header, laszip);
72
+ const totalPointCount2 = header.pointsCount;
73
+ return parseLASArrowTableBatch(
74
+ rawPointData,
75
+ {
76
+ ...header,
77
+ pointsOffset: 0,
78
+ pointsCount: totalPointCount2,
79
+ totalToRead: totalPointCount2,
80
+ totalRead: totalPointCount2
81
+ },
82
+ options
83
+ );
84
+ }
85
+ const totalPointCount = header.pointsCount;
86
+ return parseLASArrowTableBatch(
87
+ arrayBuffer,
88
+ { ...header, totalToRead: totalPointCount, totalRead: totalPointCount },
89
+ options
90
+ );
91
+ }
92
+ function decodeLAZChunkToArrowTable(compressed, metadata, options) {
93
+ if (metadata.pointDataRecordFormat < 6 || metadata.pointDataRecordFormat > 8) {
94
+ throw new Error(
95
+ `LASLoader: standalone Arrow chunk decode supports PDRF 6-8; received ${metadata.pointDataRecordFormat}`
96
+ );
97
+ }
98
+ const pointCount = metadata.pointCount;
99
+ const header = {
100
+ pointsOffset: 0,
101
+ pointsFormatId: metadata.pointDataRecordFormat,
102
+ pointsStructSize: metadata.pointDataRecordLength,
103
+ pointsCount: pointCount,
104
+ scale: metadata.scale,
105
+ offset: metadata.offset,
106
+ maxs: [0, 0, 0],
107
+ mins: [0, 0, 0],
108
+ totalToRead: pointCount,
109
+ totalRead: pointCount,
110
+ hasColor: hasPointColor(metadata.pointDataRecordFormat),
111
+ versionAsString: "1.4",
112
+ isCompressed: true,
113
+ headerSize: LAS_14_HEADER_LENGTH,
114
+ vlrCount: 0
115
+ };
116
+ const state = createPointDataBatchState(pointCount, header, options);
117
+ if (state.waveforms || state.extraBytes || state.typedExtraBytes) {
118
+ throw new Error("LASLoader: standalone Arrow chunk decode only supports direct LAZ columns");
119
+ }
120
+ const cursor = (0, import_loader_utils.createLAZChunkDecoderCursor)(compressed, metadata);
121
+ const decodedPointCount = cursor.decodeIntoPointData(state.target, pointCount);
122
+ if (decodedPointCount !== pointCount) {
123
+ throw new Error(
124
+ `LASLoader: standalone LAZ chunk produced ${decodedPointCount} points; expected ${pointCount}`
125
+ );
126
+ }
127
+ return makePointDataStateArrowTable(header, state, pointCount, options, true);
128
+ }
129
+ function parseCompleteLAZFileToArrowTable(bytes, header, laszip, options) {
130
+ const pointCount = header.pointsCount;
131
+ const state = createPointDataBatchState(pointCount, header, options);
132
+ const chunkTable = readLAZFileChunks(bytes, header, laszip, options);
133
+ let decodedPointCount = 0;
134
+ let byteOffset = header.pointsOffset + (laszip.compressor === 1 ? 0 : LAZ_CHUNK_TABLE_POINTER_LENGTH);
135
+ for (const chunk of chunkTable) {
136
+ decodeCompleteLAZChunkToPointData(
137
+ bytes,
138
+ byteOffset,
139
+ chunk.byteLength,
140
+ chunk.pointCount,
141
+ header,
142
+ laszip,
143
+ state,
144
+ decodedPointCount
145
+ );
146
+ byteOffset += chunk.byteLength;
147
+ decodedPointCount += chunk.pointCount;
148
+ }
149
+ if (decodedPointCount !== pointCount) {
150
+ throw new Error(`LASLoader: decoded ${decodedPointCount} LAZ points; expected ${pointCount}`);
151
+ }
152
+ return makePointDataStateArrowTable(header, state, pointCount, options);
153
+ }
154
+ function makePointDataStateArrowTable(header, state, pointCount, options, preserveRawColors = false) {
155
+ const colors = preserveRawColors && state.rawColors ? state.rawColors : state.colors ? state.colors : state.rawColors ? convertRawColorsToUint8(state.rawColors, pointCount, options) : null;
156
+ return makeLASArrowTableFromAttributes(
157
+ { ...header, pointsOffset: 0, pointsCount: pointCount, totalRead: pointCount },
158
+ state.positions,
159
+ colors,
160
+ state.intensities,
161
+ state.classifications,
162
+ state.syntheticFlags,
163
+ state.keyPointFlags,
164
+ state.withheldFlags,
165
+ state.overlapFlags,
166
+ state.gpsTimes,
167
+ state.nir,
168
+ state.scanAngles,
169
+ state.userData,
170
+ state.pointSourceIds,
171
+ state.returnNumbers,
172
+ state.numberOfReturns,
173
+ state.scannerChannels,
174
+ state.scanDirectionFlags,
175
+ state.edgeOfFlightLines,
176
+ state.waveforms,
177
+ state.extraBytes,
178
+ state.typedExtraBytes
179
+ );
180
+ }
181
+ function decodeCompleteLAZChunkToPointData(bytes, byteOffset, byteLength, pointCount, header, laszip, state, targetPointOffset) {
182
+ const compressed = bytes.subarray(byteOffset, byteOffset + byteLength);
183
+ if (compressed.byteLength !== byteLength) {
184
+ throw new import_loader_utils.NeedsMoreData("LASLoader: truncated LAZ chunk");
185
+ }
186
+ const cursor = (0, import_loader_utils.createLAZChunkDecoderCursor)(
187
+ compressed,
188
+ createLAZChunkMetadata(header, laszip, pointCount)
189
+ );
190
+ state.target.pointOffset = targetPointOffset;
191
+ const decodedPointCount = cursor.decodeIntoPointData(state.target, pointCount);
192
+ if (decodedPointCount !== pointCount) {
193
+ throw new Error(
194
+ `LASLoader: decoded ${decodedPointCount} points from a ${pointCount}-point LAZ chunk`
195
+ );
196
+ }
197
+ populateDecodedTypedExtraBytes(state, targetPointOffset, pointCount);
198
+ }
199
+ async function* parseLASInBatches(arrayBufferIterator, options = {}) {
200
+ const batchSize = getBatchSize(options);
201
+ const inputIterator = toAsyncIterator(arrayBufferIterator);
202
+ let pending = new Uint8Array(0);
203
+ let absoluteOffset = 0;
204
+ let header = null;
205
+ let sourcePointIndex = 0;
206
+ let totalRead = 0;
207
+ while (true) {
208
+ const next = await inputIterator.next();
209
+ if (next.done) {
210
+ break;
211
+ }
212
+ const chunk = next.value;
213
+ pending = concatenateUint8Arrays(pending, toUint8Array(chunk));
214
+ if (!header) {
215
+ header = tryParseHeader(pending, absoluteOffset);
216
+ if (header) {
217
+ header.totalToRead = header.pointsCount;
218
+ }
219
+ }
220
+ if (!header) {
221
+ continue;
222
+ }
223
+ if (header.isCompressed) {
224
+ yield* parseLAZInBatches(pending, inputIterator, header, options);
225
+ return;
226
+ }
227
+ for (const batch of readAvailablePointBatches(
228
+ pending,
229
+ absoluteOffset,
230
+ header,
231
+ sourcePointIndex,
232
+ totalRead,
233
+ batchSize
234
+ )) {
235
+ sourcePointIndex = batch.sourcePointIndex;
236
+ totalRead = batch.totalRead;
237
+ pending = batch.pending;
238
+ absoluteOffset = batch.absoluteOffset;
239
+ yield parseLASArrowTableBatch(batch.arrayBuffer, batch.header, options);
240
+ }
241
+ }
242
+ if (!header) {
243
+ throw new Error("LASLoader: incomplete LAS header");
244
+ }
245
+ if (totalRead < header.totalToRead) {
246
+ throw new Error("LASLoader: truncated LAS point data");
247
+ }
248
+ }
249
+ function* parseLASChunkedIterator(arrayBuffer, batchSize = DEFAULT_BATCH_SIZE, options = {}) {
250
+ const header = parseLASHeader(arrayBuffer);
251
+ if (header.isCompressed) {
252
+ yield* parseLAZChunkedIterator(arrayBuffer, header, batchSize, void 0, options);
253
+ return;
254
+ }
255
+ const totalToRead = header.pointsCount;
256
+ let sourcePointIndex = 0;
257
+ let totalRead = 0;
258
+ while (sourcePointIndex < header.pointsCount && totalRead < totalToRead) {
259
+ const batchPointCount = Math.min(batchSize, header.pointsCount - sourcePointIndex);
260
+ const start = header.pointsOffset + sourcePointIndex * header.pointsStructSize;
261
+ const end = start + batchPointCount * header.pointsStructSize;
262
+ sourcePointIndex += batchPointCount;
263
+ totalRead += batchPointCount;
264
+ const batchHeader = {
265
+ ...header,
266
+ pointsOffset: 0,
267
+ pointsCount: batchPointCount,
268
+ totalToRead,
269
+ totalRead
270
+ };
271
+ yield {
272
+ arrayBuffer: arrayBuffer.slice(start, end),
273
+ header: batchHeader
274
+ };
275
+ }
276
+ }
277
+ async function* decodeLAZFileInBatches(arrayBufferIterator, options = {}) {
278
+ const inputIterator = toAsyncIterator(arrayBufferIterator);
279
+ let pending = new Uint8Array(0);
280
+ let header = null;
281
+ while (!header) {
282
+ const next = await inputIterator.next();
283
+ if (next.done) {
284
+ throw new Error("LASLoader: incomplete LAS header");
285
+ }
286
+ pending = concatenateUint8Arrays(pending, toUint8Array(next.value));
287
+ header = tryParseHeader(pending, 0);
288
+ }
289
+ if (!header.isCompressed) {
290
+ throw new Error("LASLoader: decodeLAZFileInBatches requires compressed LAZ input");
291
+ }
292
+ yield* decodePendingLAZFileInBatches(pending, inputIterator, header, options);
293
+ }
294
+ async function* decodePendingLAZFileInBatches(initialPending, inputIterator, header, options = {}) {
295
+ const { pending, laszip } = await readLASZipVLRFromInput(initialPending, inputIterator, header);
296
+ validateTypeScriptLAZSupport(header, laszip);
297
+ yield* decodeLAZFileWithParsedVLRInBatches(pending, inputIterator, header, laszip, options);
298
+ }
299
+ async function* decodeLAZFileWithParsedVLRInBatches(initialPending, inputIterator, header, laszip, options) {
300
+ if (laszip.variableChunks) {
301
+ const bytes = await collectRemainingInputBytes(initialPending, inputIterator);
302
+ yield* decodeLAZFileFromCompleteBytes(bytes, header, laszip, options);
303
+ return;
304
+ }
305
+ if (header.pointsFormatId <= 5) {
306
+ yield* decodePendingFixedLegacyLAZFileInBatches(
307
+ initialPending,
308
+ inputIterator,
309
+ header,
310
+ laszip,
311
+ options
312
+ );
313
+ return;
314
+ }
315
+ const outputHeader = { ...header, totalToRead: header.pointsCount };
316
+ const batchSize = getBatchSize(options);
317
+ const state = createRawPointBatchState(
318
+ batchSize,
319
+ header.pointsStructSize,
320
+ getLAZStreamingDecodeStats(options)
321
+ );
322
+ let sourcePointIndex = 0;
323
+ const chunkByteLengths = [];
324
+ const reader = new import_loader_utils.BinaryChunkReader();
325
+ reader.write(initialPending);
326
+ await readUntilAvailable(
327
+ reader,
328
+ inputIterator,
329
+ header.pointsOffset + LAZ_CHUNK_TABLE_POINTER_LENGTH,
330
+ "LASLoader: incomplete compressed LAZ point data"
331
+ );
332
+ reader.skip(header.pointsOffset);
333
+ const chunkTableOffset = readStreamedLAZChunkTableOffset(
334
+ reader.getDataView(LAZ_CHUNK_TABLE_POINTER_LENGTH)
335
+ );
336
+ while (sourcePointIndex < header.pointsCount) {
337
+ const chunkPointCount = Math.min(laszip.chunkSize, header.pointsCount - sourcePointIndex);
338
+ const metadata = createLAZChunkMetadata(header, laszip, chunkPointCount);
339
+ const chunkByteLength = await readLAZChunkByteLengthFromReader(reader, inputIterator, metadata);
340
+ chunkByteLengths.push(chunkByteLength);
341
+ recordReadBytesStats(reader, chunkByteLength, state.stats);
342
+ const compressedChunk = reader.readBytes(chunkByteLength);
343
+ if (options.las?.recoverMissingChunkTable && chunkTableOffset === header.pointsOffset) {
344
+ validateRecoveredLayeredPointCount(compressedChunk, metadata);
345
+ }
346
+ for (const batch of appendDecodedLAZChunk(compressedChunk, metadata, outputHeader, state)) {
347
+ yield batch;
348
+ }
349
+ sourcePointIndex += chunkPointCount;
350
+ }
351
+ await validateStreamedFixedLAZChunkTable(
352
+ reader,
353
+ inputIterator,
354
+ header,
355
+ laszip,
356
+ chunkTableOffset,
357
+ chunkByteLengths,
358
+ options
359
+ );
360
+ const finalBatch = flushRawPointBatch(outputHeader, state);
361
+ if (finalBatch) {
362
+ yield finalBatch;
363
+ }
364
+ }
365
+ async function* decodePendingFixedLegacyLAZFileInBatches(initialPending, inputIterator, header, laszip, options = {}) {
366
+ const outputHeader = { ...header, totalToRead: header.pointsCount };
367
+ const batchSize = getBatchSize(options);
368
+ const state = createRawPointBatchState(
369
+ batchSize,
370
+ header.pointsStructSize,
371
+ getLAZStreamingDecodeStats(options)
372
+ );
373
+ const chunkByteLengths = [];
374
+ const reader = new import_loader_utils.BinaryChunkReader();
375
+ reader.write(initialPending);
376
+ await readUntilAvailable(
377
+ reader,
378
+ inputIterator,
379
+ header.pointsOffset + (laszip.compressor === 1 ? 0 : LAZ_CHUNK_TABLE_POINTER_LENGTH),
380
+ "LASLoader: incomplete compressed LAZ point data"
381
+ );
382
+ reader.skip(header.pointsOffset);
383
+ const chunkTableOffset = laszip.compressor === 1 ? 0 : readStreamedLAZChunkTableOffset(reader.getDataView(LAZ_CHUNK_TABLE_POINTER_LENGTH));
384
+ let sourcePointIndex = 0;
385
+ while (sourcePointIndex < header.pointsCount) {
386
+ const chunkPointCount = laszip.compressor === 1 ? header.pointsCount : Math.min(laszip.chunkSize, header.pointsCount - sourcePointIndex);
387
+ const metadata = createLAZChunkMetadata(header, laszip, chunkPointCount);
388
+ const cursor = (0, import_loader_utils.createLAZChunkDecoderCursor)(new Uint8Array(0), metadata);
389
+ let fedByteLength = 0;
390
+ let consumedByteLength = 0;
391
+ let inputDone = false;
392
+ while (cursor.remainingPointCount > 0) {
393
+ const availableByteLength = reader.getAvailableByteLength();
394
+ const requestedByteLength = getLegacyLAZFeedByteLength(
395
+ availableByteLength,
396
+ fedByteLength,
397
+ cursor.requiredInputByteLength - consumedByteLength
398
+ );
399
+ if (requestedByteLength > fedByteLength) {
400
+ const checkpoint = reader.checkpoint();
401
+ reader.skip(fedByteLength);
402
+ const addedByteLength = requestedByteLength - fedByteLength;
403
+ recordReadBytesStats(reader, addedByteLength, state.stats);
404
+ cursor.feed(reader.readBytes(addedByteLength));
405
+ reader.restore(checkpoint);
406
+ fedByteLength = requestedByteLength;
407
+ }
408
+ const availableBatchPointCount = batchSize - state.batchPointCount;
409
+ const decodedPointCount = cursor.decodeAvailableInto(
410
+ state.rawBatch,
411
+ state.batchPointCount * header.pointsStructSize,
412
+ availableBatchPointCount,
413
+ inputDone
414
+ );
415
+ if (decodedPointCount > 0) {
416
+ if (laszip.compressor === 1) {
417
+ const decodedByteLength = cursor.compressedByteOffset - consumedByteLength;
418
+ reader.skip(decodedByteLength);
419
+ fedByteLength -= decodedByteLength;
420
+ consumedByteLength = cursor.compressedByteOffset;
421
+ cursor.discardConsumedInput();
422
+ }
423
+ state.batchPointCount += decodedPointCount;
424
+ if (state.batchPointCount === batchSize) {
425
+ const batch = flushRawPointBatch(outputHeader, state);
426
+ if (batch) {
427
+ yield batch;
428
+ }
429
+ }
430
+ continue;
431
+ }
432
+ if (inputDone) {
433
+ throw new import_loader_utils.NeedsMoreData(
434
+ `LASLoader: truncated legacy LAZ chunk after ${chunkPointCount - cursor.remainingPointCount} of ${chunkPointCount} points with ${availableByteLength} bytes available`
435
+ );
436
+ }
437
+ const next = await inputIterator.next();
438
+ if (next.done) {
439
+ inputDone = true;
440
+ } else {
441
+ reader.write(next.value);
442
+ }
443
+ }
444
+ reader.skip(cursor.compressedByteOffset - consumedByteLength);
445
+ chunkByteLengths.push(cursor.compressedByteOffset);
446
+ sourcePointIndex += chunkPointCount;
447
+ }
448
+ if (laszip.compressor !== 1) {
449
+ await validateStreamedFixedLAZChunkTable(
450
+ reader,
451
+ inputIterator,
452
+ header,
453
+ laszip,
454
+ chunkTableOffset,
455
+ chunkByteLengths,
456
+ options
457
+ );
458
+ }
459
+ const finalBatch = flushRawPointBatch(outputHeader, state);
460
+ if (finalBatch) {
461
+ yield finalBatch;
462
+ }
463
+ }
464
+ function getLegacyLAZFeedByteLength(availableByteLength, fedByteLength, requiredInputByteLength) {
465
+ return Math.min(
466
+ availableByteLength,
467
+ Math.max(requiredInputByteLength, fedByteLength + LEGACY_LAZ_FEED_BLOCK_SIZE)
468
+ );
469
+ }
470
+ async function* parseLAZInBatches(initialPending, inputIterator, header, options) {
471
+ const { pending, laszip } = await readLASZipVLRFromInput(initialPending, inputIterator, header);
472
+ validateTypeScriptLAZSupport(header, laszip);
473
+ if (!laszip.variableChunks && header.pointsFormatId <= 5) {
474
+ yield* parsePendingFixedLegacyLAZFileInArrowBatches(
475
+ pending,
476
+ inputIterator,
477
+ header,
478
+ laszip,
479
+ options
480
+ );
481
+ return;
482
+ }
483
+ if (!laszip.variableChunks && header.pointsFormatId >= 6 && header.pointsFormatId <= 10) {
484
+ yield* parsePendingLAZFileInArrowBatches(pending, inputIterator, header, laszip, options);
485
+ return;
486
+ }
487
+ for await (const batch of decodeLAZFileWithParsedVLRInBatches(
488
+ pending,
489
+ inputIterator,
490
+ header,
491
+ laszip,
492
+ options
493
+ )) {
494
+ yield parseLASArrowTableBatch(batch.arrayBuffer, batch.header, options);
495
+ }
496
+ }
497
+ async function* parsePendingFixedLegacyLAZFileInArrowBatches(initialPending, inputIterator, header, laszip, options) {
498
+ const outputHeader = { ...header, totalToRead: header.pointsCount };
499
+ const state = createPointDataBatchState(getBatchSize(options), header, options);
500
+ const stats = getLAZStreamingDecodeStats(options);
501
+ const chunkByteLengths = [];
502
+ const reader = new import_loader_utils.BinaryChunkReader();
503
+ reader.write(initialPending);
504
+ await readUntilAvailable(
505
+ reader,
506
+ inputIterator,
507
+ header.pointsOffset + (laszip.compressor === 1 ? 0 : LAZ_CHUNK_TABLE_POINTER_LENGTH),
508
+ "LASLoader: incomplete compressed LAZ point data"
509
+ );
510
+ reader.skip(header.pointsOffset);
511
+ const chunkTableOffset = laszip.compressor === 1 ? 0 : readStreamedLAZChunkTableOffset(reader.getDataView(LAZ_CHUNK_TABLE_POINTER_LENGTH));
512
+ let sourcePointIndex = 0;
513
+ while (sourcePointIndex < header.pointsCount) {
514
+ const chunkPointCount = laszip.compressor === 1 ? header.pointsCount : Math.min(laszip.chunkSize, header.pointsCount - sourcePointIndex);
515
+ const metadata = createLAZChunkMetadata(header, laszip, chunkPointCount);
516
+ const cursor = (0, import_loader_utils.createLAZChunkDecoderCursor)(new Uint8Array(0), metadata);
517
+ let fedByteLength = 0;
518
+ let consumedByteLength = 0;
519
+ let inputDone = false;
520
+ while (cursor.remainingPointCount > 0) {
521
+ const availableByteLength = reader.getAvailableByteLength();
522
+ const requestedByteLength = getLegacyLAZFeedByteLength(
523
+ availableByteLength,
524
+ fedByteLength,
525
+ cursor.requiredInputByteLength - consumedByteLength
526
+ );
527
+ if (requestedByteLength > fedByteLength) {
528
+ const checkpoint = reader.checkpoint();
529
+ reader.skip(fedByteLength);
530
+ const addedByteLength = requestedByteLength - fedByteLength;
531
+ recordReadBytesStats(reader, addedByteLength, stats);
532
+ cursor.feed(reader.readBytes(addedByteLength));
533
+ reader.restore(checkpoint);
534
+ fedByteLength = requestedByteLength;
535
+ }
536
+ state.target.pointOffset = state.batchPointCount;
537
+ const availableBatchPointCount = state.batchCapacity - state.batchPointCount;
538
+ const decodedPointCount = cursor.decodeAvailableIntoPointData(
539
+ state.target,
540
+ availableBatchPointCount,
541
+ inputDone
542
+ );
543
+ if (decodedPointCount > 0) {
544
+ if (laszip.compressor === 1) {
545
+ const decodedByteLength = cursor.compressedByteOffset - consumedByteLength;
546
+ reader.skip(decodedByteLength);
547
+ fedByteLength -= decodedByteLength;
548
+ consumedByteLength = cursor.compressedByteOffset;
549
+ cursor.discardConsumedInput();
550
+ }
551
+ populateDecodedTypedExtraBytes(state, state.batchPointCount, decodedPointCount);
552
+ state.batchPointCount += decodedPointCount;
553
+ if (state.batchPointCount === state.batchCapacity) {
554
+ const batch = flushPointDataBatch(outputHeader, state, options);
555
+ if (batch) {
556
+ yield batch;
557
+ }
558
+ }
559
+ continue;
560
+ }
561
+ if (inputDone) {
562
+ throw new import_loader_utils.NeedsMoreData(
563
+ `LASLoader: truncated legacy LAZ chunk after ${chunkPointCount - cursor.remainingPointCount} of ${chunkPointCount} points with ${availableByteLength} bytes available`
564
+ );
565
+ }
566
+ const next = await inputIterator.next();
567
+ if (next.done) {
568
+ inputDone = true;
569
+ } else {
570
+ reader.write(next.value);
571
+ }
572
+ }
573
+ reader.skip(cursor.compressedByteOffset - consumedByteLength);
574
+ chunkByteLengths.push(cursor.compressedByteOffset);
575
+ sourcePointIndex += chunkPointCount;
576
+ }
577
+ if (laszip.compressor !== 1) {
578
+ await validateStreamedFixedLAZChunkTable(
579
+ reader,
580
+ inputIterator,
581
+ header,
582
+ laszip,
583
+ chunkTableOffset,
584
+ chunkByteLengths,
585
+ options
586
+ );
587
+ }
588
+ const finalBatch = flushPointDataBatch(outputHeader, state, options);
589
+ if (finalBatch) {
590
+ yield finalBatch;
591
+ }
592
+ }
593
+ async function* parsePendingLAZFileInArrowBatches(initialPending, inputIterator, header, laszip, options) {
594
+ const outputHeader = { ...header, totalToRead: header.pointsCount };
595
+ const state = createPointDataBatchState(getBatchSize(options), header, options);
596
+ let sourcePointIndex = 0;
597
+ const chunkByteLengths = [];
598
+ const reader = new import_loader_utils.BinaryChunkReader();
599
+ reader.write(initialPending);
600
+ await readUntilAvailable(
601
+ reader,
602
+ inputIterator,
603
+ header.pointsOffset + LAZ_CHUNK_TABLE_POINTER_LENGTH,
604
+ "LASLoader: incomplete compressed LAZ point data"
605
+ );
606
+ reader.skip(header.pointsOffset);
607
+ const chunkTableOffset = readStreamedLAZChunkTableOffset(
608
+ reader.getDataView(LAZ_CHUNK_TABLE_POINTER_LENGTH)
609
+ );
610
+ while (sourcePointIndex < header.pointsCount) {
611
+ const chunkPointCount = Math.min(laszip.chunkSize, header.pointsCount - sourcePointIndex);
612
+ const metadata = createLAZChunkMetadata(header, laszip, chunkPointCount);
613
+ const chunkByteLength = yield* appendProgressiveLAZChunkToPointDataBatches(
614
+ reader,
615
+ inputIterator,
616
+ metadata,
617
+ outputHeader,
618
+ state,
619
+ options,
620
+ Boolean(options.las?.recoverMissingChunkTable && chunkTableOffset === header.pointsOffset)
621
+ );
622
+ chunkByteLengths.push(chunkByteLength);
623
+ sourcePointIndex += chunkPointCount;
624
+ }
625
+ await validateStreamedFixedLAZChunkTable(
626
+ reader,
627
+ inputIterator,
628
+ header,
629
+ laszip,
630
+ chunkTableOffset,
631
+ chunkByteLengths,
632
+ options
633
+ );
634
+ const finalBatch = flushPointDataBatch(outputHeader, state, options);
635
+ if (finalBatch) {
636
+ yield finalBatch;
637
+ }
638
+ }
639
+ async function* appendProgressiveLAZChunkToPointDataBatches(reader, inputIterator, metadata, header, state, options, validateRecoveryPointCount) {
640
+ const headerByteLength = (0, import_loader_utils.getLAZChunkHeaderByteLength)(metadata);
641
+ await readUntilAvailable(
642
+ reader,
643
+ inputIterator,
644
+ headerByteLength,
645
+ "LASLoader: incomplete layered LAZ chunk header"
646
+ );
647
+ const compressedHeader = reader.readBytes(headerByteLength);
648
+ if (validateRecoveryPointCount) validateRecoveredLayeredPointCount(compressedHeader, metadata);
649
+ const chunkByteLength = (0, import_loader_utils.getLAZChunkDeclaredByteLength)(compressedHeader, metadata);
650
+ const decoder = (0, import_loader_utils.createLAZChunkDecoder)(metadata);
651
+ decoder.feed(compressedHeader);
652
+ let fedByteLength = headerByteLength;
653
+ while (fedByteLength < chunkByteLength) {
654
+ yield* readAvailableLAZPointDataBatches(decoder, header, state, options);
655
+ if (reader.getAvailableByteLength() === 0) {
656
+ const next = await inputIterator.next();
657
+ if (next.done) {
658
+ throw new import_loader_utils.NeedsMoreData("LASLoader: incomplete layered LAZ chunk payload");
659
+ }
660
+ reader.write(next.value);
661
+ }
662
+ const byteLength = Math.min(reader.getAvailableByteLength(), chunkByteLength - fedByteLength);
663
+ decoder.feed(reader.readBytes(byteLength));
664
+ fedByteLength += byteLength;
665
+ }
666
+ decoder.close();
667
+ yield* readAvailableLAZPointDataBatches(decoder, header, state, options);
668
+ if (decoder.remainingPointCount !== 0) {
669
+ throw new import_loader_utils.NeedsMoreData(
670
+ `LASLoader: layered LAZ chunk produced ${metadata.pointCount - decoder.remainingPointCount} of ${metadata.pointCount} points`
671
+ );
672
+ }
673
+ return chunkByteLength;
674
+ }
675
+ function* readAvailableLAZPointDataBatches(decoder, header, state, options) {
676
+ while (decoder.remainingPointCount > 0) {
677
+ const batchRemainingPointCount = state.batchCapacity - state.batchPointCount;
678
+ state.target.pointOffset = state.batchPointCount;
679
+ const pointsDecoded = decoder.readPointDataBatch(state.target, batchRemainingPointCount);
680
+ if (!pointsDecoded) {
681
+ return;
682
+ }
683
+ populateDecodedTypedExtraBytes(state, state.batchPointCount, pointsDecoded);
684
+ state.batchPointCount += pointsDecoded;
685
+ if (state.batchPointCount === state.batchCapacity) {
686
+ const batch = flushPointDataBatch(header, state, options);
687
+ if (batch) {
688
+ yield batch;
689
+ }
690
+ }
691
+ }
692
+ }
693
+ function* parseLAZChunkedIterator(arrayBuffer, header, batchSize, parsedLASZipVLR, options = {}) {
694
+ const laszip = parsedLASZipVLR || parseLASZipVLR(new Uint8Array(arrayBuffer), header);
695
+ validateTypeScriptLAZSupport(header, laszip);
696
+ if (header.pointsFormatId <= 5 || laszip.variableChunks) {
697
+ yield* decodeLAZFileFromCompleteBytes(new Uint8Array(arrayBuffer), header, laszip, {
698
+ ...options,
699
+ batchSize
700
+ });
701
+ return;
702
+ }
703
+ const outputHeader = { ...header, totalToRead: header.pointsCount };
704
+ const state = createRawPointBatchState(batchSize, header.pointsStructSize);
705
+ const bytes = new Uint8Array(arrayBuffer);
706
+ const chunkTable = readLAZFileChunks(bytes, header, laszip, options);
707
+ let byteOffset = header.pointsOffset + (laszip.compressor === 1 ? 0 : LAZ_CHUNK_TABLE_POINTER_LENGTH);
708
+ for (const chunk of chunkTable) {
709
+ const metadata = createLAZChunkMetadata(header, laszip, chunk.pointCount);
710
+ const compressed = bytes.subarray(byteOffset, byteOffset + chunk.byteLength);
711
+ for (const batch of appendDecodedLAZChunk(compressed, metadata, outputHeader, state)) {
712
+ yield batch;
713
+ }
714
+ byteOffset += chunk.byteLength;
715
+ }
716
+ const finalBatch = flushRawPointBatch(outputHeader, state);
717
+ if (finalBatch) {
718
+ yield finalBatch;
719
+ }
720
+ }
721
+ function* decodeLAZFileFromCompleteBytes(bytes, header, laszip, options = {}) {
722
+ const batchSize = getBatchSize(options);
723
+ const outputHeader = { ...header, totalToRead: header.pointsCount };
724
+ const state = createRawPointBatchState(
725
+ batchSize,
726
+ header.pointsStructSize,
727
+ getLAZStreamingDecodeStats(options)
728
+ );
729
+ const chunkTable = readLAZFileChunks(bytes, header, laszip, options);
730
+ let byteOffset = header.pointsOffset + (laszip.compressor === 1 ? 0 : LAZ_CHUNK_TABLE_POINTER_LENGTH);
731
+ for (const chunk of chunkTable) {
732
+ const compressedChunk = bytes.subarray(byteOffset, byteOffset + chunk.byteLength);
733
+ if (compressedChunk.byteLength < chunk.byteLength) {
734
+ throw new import_loader_utils.NeedsMoreData("LASLoader: truncated legacy LAZ chunk");
735
+ }
736
+ const metadata = createLAZChunkMetadata(header, laszip, chunk.pointCount);
737
+ if (laszip.compressor === 1) {
738
+ yield* appendDecodedLAZChunk(compressedChunk, metadata, outputHeader, state);
739
+ } else {
740
+ const rawChunk = (0, import_loader_utils.decodeLAZChunk)(compressedChunk, metadata);
741
+ recordDecodedChunkAllocation(rawChunk.byteLength, state.stats);
742
+ yield* appendRawPointChunk(rawChunk, outputHeader, state);
743
+ }
744
+ byteOffset += chunk.byteLength;
745
+ }
746
+ const finalBatch = flushRawPointBatch(outputHeader, state);
747
+ if (finalBatch) {
748
+ yield finalBatch;
749
+ }
750
+ }
751
+ function decodeLAZFileToRawPointData(arrayBuffer, header, laszip) {
752
+ const totalPointCount = header.pointsCount;
753
+ const rawPointData = new Uint8Array(totalPointCount * header.pointsStructSize);
754
+ let byteOffset = 0;
755
+ for (const batch of parseLAZChunkedIterator(arrayBuffer, header, DEFAULT_BATCH_SIZE, laszip)) {
756
+ const source = new Uint8Array(batch.arrayBuffer);
757
+ rawPointData.set(source, byteOffset);
758
+ byteOffset += source.byteLength;
759
+ }
760
+ return rawPointData;
761
+ }
762
+ function parseLASHeader(arrayBuffer) {
763
+ const dataView = new DataView(arrayBuffer);
764
+ if (arrayBuffer.byteLength < 227 || dataView.getUint32(0, true) !== LASF_SIGNATURE) {
765
+ throw new Error("LASLoader: invalid LAS header");
766
+ }
767
+ const versionMajor = dataView.getUint8(24);
768
+ const versionMinor = dataView.getUint8(25);
769
+ if (versionMajor !== 1 || versionMinor > 5) {
770
+ throw new Error(`LASLoader: unsupported LAS version ${versionMajor}.${versionMinor}`);
771
+ }
772
+ const headerSize = dataView.getUint16(94, true);
773
+ const globalEncoding = dataView.getUint16(6, true);
774
+ const vlrCount = dataView.getUint32(100, true);
775
+ const pointFormatByte = dataView.getUint8(104);
776
+ const pointsFormatId = pointFormatByte & POINT_FORMAT_MASK;
777
+ const isCompressed = Boolean(pointFormatByte & COMPRESSED_POINT_FORMAT_MASK);
778
+ const legacyPointCount = dataView.getUint32(107, true);
779
+ const extendedPointCount = versionMajor > 1 || versionMinor >= 4 ? readUint64(dataView, 247) : legacyPointCount;
780
+ const pointsCount = extendedPointCount || legacyPointCount;
781
+ const pointsOffset = dataView.getUint32(96, true);
782
+ const pointsStructSize = dataView.getUint16(105, true);
783
+ if (versionMinor === 5) {
784
+ if (headerSize < 393) {
785
+ throw new Error("LASLoader: LAS 1.5 header must be at least 393 bytes");
786
+ }
787
+ if (pointsFormatId < 6 || pointsFormatId > 10) {
788
+ throw new Error(
789
+ `LASLoader: LAS 1.5 requires point data record formats 6-10; received ${pointsFormatId}`
790
+ );
791
+ }
792
+ if ((globalEncoding & 16) === 0) {
793
+ throw new Error("LASLoader: LAS 1.5 requires the WKT global encoding flag");
794
+ }
795
+ if ((globalEncoding & 65440) !== 0) {
796
+ throw new Error("LASLoader: LAS 1.5 Global Encoding contains reserved bits");
797
+ }
798
+ if ((globalEncoding & 64) !== 0 && (globalEncoding & 1) === 0) {
799
+ throw new Error("LASLoader: LAS 1.5 Time Offset Flag requires GPS Time Type");
800
+ }
801
+ const maxGpsTime = dataView.getFloat64(375, true);
802
+ const minGpsTime = dataView.getFloat64(383, true);
803
+ if (!Number.isFinite(maxGpsTime) || !Number.isFinite(minGpsTime) || maxGpsTime !== 0 && minGpsTime !== 0 && maxGpsTime < minGpsTime) {
804
+ throw new Error("LASLoader: LAS 1.5 GPS time range is invalid");
805
+ }
806
+ }
807
+ const scale = [
808
+ dataView.getFloat64(131, true),
809
+ dataView.getFloat64(139, true),
810
+ dataView.getFloat64(147, true)
811
+ ];
812
+ const offset = [
813
+ dataView.getFloat64(155, true),
814
+ dataView.getFloat64(163, true),
815
+ dataView.getFloat64(171, true)
816
+ ];
817
+ const maxs = [
818
+ dataView.getFloat64(179, true),
819
+ dataView.getFloat64(195, true),
820
+ dataView.getFloat64(211, true)
821
+ ];
822
+ const mins = [
823
+ dataView.getFloat64(187, true),
824
+ dataView.getFloat64(203, true),
825
+ dataView.getFloat64(219, true)
826
+ ];
827
+ const header = {
828
+ pointsOffset,
829
+ pointsFormatId,
830
+ pointsStructSize,
831
+ pointsCount,
832
+ scale,
833
+ offset,
834
+ maxs,
835
+ mins,
836
+ totalToRead: pointsCount,
837
+ totalRead: 0,
838
+ hasColor: hasPointColor(pointsFormatId),
839
+ versionAsString: `${versionMajor}.${versionMinor}`,
840
+ isCompressed,
841
+ headerSize,
842
+ vlrCount,
843
+ userHeaderData: versionMinor === 5 && headerSize > 393 ? new Uint8Array(arrayBuffer, 393, headerSize - 393).slice() : void 0
844
+ };
845
+ if (hasCompleteLASMetadata(arrayBuffer, header)) {
846
+ header.metadata = parseLASMetadata(arrayBuffer, header);
847
+ }
848
+ return header;
849
+ }
850
+ function hasCompleteLASMetadata(arrayBuffer, header) {
851
+ const vlrEnd = header.headerSize + header.vlrCount * 54;
852
+ return arrayBuffer.byteLength >= Math.max(vlrEnd, header.pointsOffset);
853
+ }
854
+ function parseLASMetadata(arrayBuffer, header) {
855
+ const dataView = new DataView(arrayBuffer);
856
+ const version = header.versionAsString || "1.0";
857
+ const versionParts = version.split(".").map(Number);
858
+ const isAtLeast14 = versionParts[0] > 1 || versionParts[0] === 1 && versionParts[1] >= 4;
859
+ const vlrs = parseLASVariableLengthRecords(dataView, header);
860
+ const evlrOffset = isAtLeast14 ? readUint64(dataView, 235) : 0;
861
+ const evlrCount = isAtLeast14 ? dataView.getUint32(243, true) : 0;
862
+ const evlrs = parseLASExtendedVariableLengthRecords(dataView, evlrOffset, evlrCount);
863
+ const metadata = {
864
+ fileSourceId: dataView.getUint16(4, true),
865
+ globalEncoding: dataView.getUint16(6, true),
866
+ waveformDataOffset: versionParts[0] > 1 || versionParts[0] === 1 && versionParts[1] >= 3 ? dataView.getBigUint64(227, true) : void 0,
867
+ projectId: formatLASProjectId(new Uint8Array(arrayBuffer, 8, 16)),
868
+ systemIdentifier: readLASString(new Uint8Array(arrayBuffer), 26, 32),
869
+ generatingSoftware: readLASString(new Uint8Array(arrayBuffer), 58, 32),
870
+ creationDayOfYear: dataView.getUint16(90, true),
871
+ creationYear: dataView.getUint16(92, true),
872
+ headerSize: header.headerSize,
873
+ userHeaderData: header.userHeaderData,
874
+ vlrCount: header.vlrCount,
875
+ evlrOffset: evlrOffset || void 0,
876
+ evlrCount: evlrCount || void 0,
877
+ maxGpsTime: versionParts[1] === 5 ? dataView.getFloat64(375, true) : void 0,
878
+ minGpsTime: versionParts[1] === 5 ? dataView.getFloat64(383, true) : void 0,
879
+ timeOffset: versionParts[1] === 5 ? dataView.getUint16(391, true) : void 0,
880
+ pointsByReturn: parsePointsByReturn(dataView, isAtLeast14),
881
+ vlrs,
882
+ evlrs,
883
+ extraBytes: [],
884
+ waveformPacketDescriptors: []
885
+ };
886
+ for (const record of vlrs.concat(
887
+ evlrs.map((evlr) => ({ ...evlr, data: evlr.data || new Uint8Array() }))
888
+ )) {
889
+ parseTypedLASMetadataRecord(record, metadata);
890
+ }
891
+ metadata.compatibility = (0, import_las_compatibility.getLASCompatibilityLayout)(header, metadata);
892
+ resolveLASGeoTIFFKeyDirectory(metadata);
893
+ return metadata;
894
+ }
895
+ function parseLASVariableLengthRecords(dataView, header) {
896
+ const bytes = new Uint8Array(dataView.buffer, dataView.byteOffset, dataView.byteLength);
897
+ const records = [];
898
+ let offset = header.headerSize;
899
+ for (let index = 0; index < header.vlrCount; index++) {
900
+ if (offset + 54 > bytes.byteLength) {
901
+ break;
902
+ }
903
+ const dataLength = dataView.getUint16(offset + 20, true);
904
+ const dataOffset = offset + 54;
905
+ if (dataOffset + dataLength > bytes.byteLength) {
906
+ break;
907
+ }
908
+ records.push({
909
+ reserved: dataView.getUint16(offset, true),
910
+ userId: readLASString(bytes, offset + 2, 16),
911
+ recordId: dataView.getUint16(offset + 18, true),
912
+ description: readLASString(bytes, offset + 22, 32),
913
+ offset,
914
+ data: bytes.slice(dataOffset, dataOffset + dataLength)
915
+ });
916
+ offset = dataOffset + dataLength;
917
+ }
918
+ return records;
919
+ }
920
+ function parseLASExtendedVariableLengthRecords(dataView, evlrOffset, evlrCount) {
921
+ if (!evlrOffset || !evlrCount || evlrOffset >= dataView.byteLength) {
922
+ return [];
923
+ }
924
+ const bytes = new Uint8Array(dataView.buffer, dataView.byteOffset, dataView.byteLength);
925
+ const records = [];
926
+ let offset = evlrOffset;
927
+ for (let index = 0; index < evlrCount; index++) {
928
+ if (offset + 60 > bytes.byteLength) {
929
+ break;
930
+ }
931
+ const dataLength = readUint64(dataView, offset + 20);
932
+ const dataOffset = offset + 60;
933
+ if (dataLength > bytes.byteLength - dataOffset) {
934
+ break;
935
+ }
936
+ records.push({
937
+ reserved: dataView.getUint16(offset, true),
938
+ userId: readLASString(bytes, offset + 2, 16),
939
+ recordId: dataView.getUint16(offset + 18, true),
940
+ description: readLASString(bytes, offset + 28, 32),
941
+ offset,
942
+ data: bytes.slice(dataOffset, dataOffset + dataLength),
943
+ dataOffset,
944
+ dataLength
945
+ });
946
+ offset = dataOffset + dataLength;
947
+ }
948
+ return records;
949
+ }
950
+ function parseTypedLASMetadataRecord(record, metadata) {
951
+ const data = record.data;
952
+ if (!data) {
953
+ return;
954
+ }
955
+ if (record.userId === "LASF_Spec" && record.recordId === 4) {
956
+ metadata.extraBytes.push(...(0, import_las_extra_bytes.parseLASExtraBytes)(data));
957
+ } else if (record.userId === "LASF_Spec" && record.recordId >= 100 && record.recordId <= 354) {
958
+ metadata.waveformPacketDescriptors.push(parseLASWaveformDescriptor(record.recordId, data));
959
+ } else if (record.userId === "LASF_Projection" && record.recordId === 2111) {
960
+ metadata.wktMathTransform = decodeLASString(data);
961
+ } else if (record.userId === "LASF_Projection" && record.recordId === 2112) {
962
+ metadata.wkt = decodeLASString(data);
963
+ } else if (record.userId === "LASF_Projection" && record.recordId === 34735) {
964
+ metadata.geotiff = { ...metadata.geotiff, keys: readUint16Array(data) };
965
+ } else if (record.userId === "LASF_Projection" && record.recordId === 34736) {
966
+ metadata.geotiff = { ...metadata.geotiff, doubles: readFloat64Array(data) };
967
+ } else if (record.userId === "LASF_Projection" && record.recordId === 34737) {
968
+ metadata.geotiff = { ...metadata.geotiff, ascii: decodeLASString(data) };
969
+ }
970
+ }
971
+ function resolveLASGeoTIFFKeyDirectory(metadata) {
972
+ const geotiff = metadata.geotiff;
973
+ const keys = geotiff?.keys;
974
+ if (!geotiff || !keys || keys.length < 4) {
975
+ return;
976
+ }
977
+ const declaredEntryCount = keys[3];
978
+ if (keys.length < 4 + declaredEntryCount * 4) {
979
+ return;
980
+ }
981
+ const entries = [];
982
+ for (let entryIndex = 0; entryIndex < declaredEntryCount; entryIndex++) {
983
+ const entryOffset = 4 + entryIndex * 4;
984
+ const entry = {
985
+ keyId: keys[entryOffset],
986
+ tiffTagLocation: keys[entryOffset + 1],
987
+ count: keys[entryOffset + 2],
988
+ valueOffset: keys[entryOffset + 3]
989
+ };
990
+ entry.value = resolveLASGeoTIFFKeyValue(entry, geotiff);
991
+ if (entry.value === void 0) {
992
+ delete entry.value;
993
+ }
994
+ entries.push(entry);
995
+ }
996
+ geotiff.keyDirectory = {
997
+ version: keys[0],
998
+ keyRevision: keys[1],
999
+ minorRevision: keys[2],
1000
+ entries
1001
+ };
1002
+ }
1003
+ function resolveLASGeoTIFFKeyValue(entry, geotiff) {
1004
+ if (entry.tiffTagLocation === 0) {
1005
+ return entry.valueOffset;
1006
+ }
1007
+ if (entry.tiffTagLocation === 34735 && geotiff.keys) {
1008
+ const values = geotiff.keys.slice(entry.valueOffset, entry.valueOffset + entry.count);
1009
+ return values.length === entry.count ? Array.from(values) : void 0;
1010
+ }
1011
+ if (entry.tiffTagLocation === 34736 && geotiff.doubles) {
1012
+ const values = geotiff.doubles.slice(entry.valueOffset, entry.valueOffset + entry.count);
1013
+ if (values.length !== entry.count) {
1014
+ return void 0;
1015
+ }
1016
+ return entry.count === 1 ? values[0] : Array.from(values);
1017
+ }
1018
+ if (entry.tiffTagLocation === 34737 && geotiff.ascii !== void 0) {
1019
+ const end = entry.valueOffset + entry.count;
1020
+ if (end > geotiff.ascii.length) {
1021
+ return void 0;
1022
+ }
1023
+ return geotiff.ascii.slice(entry.valueOffset, end).replace(/\|$/, "");
1024
+ }
1025
+ return void 0;
1026
+ }
1027
+ function parseLASWaveformDescriptor(recordId, data) {
1028
+ if (data.byteLength < 28) {
1029
+ throw new Error(`LASLoader: waveform descriptor VLR ${recordId} is truncated`);
1030
+ }
1031
+ const dataView = new DataView(data.buffer, data.byteOffset, data.byteLength);
1032
+ return {
1033
+ recordId,
1034
+ bitsPerSample: dataView.getUint8(2),
1035
+ compressionType: dataView.getUint8(3),
1036
+ numberOfSamples: dataView.getUint32(4, true),
1037
+ temporalSampleSpacing: dataView.getUint32(8, true),
1038
+ digitizerGain: dataView.getFloat64(12, true),
1039
+ digitizerOffset: dataView.getFloat64(20, true)
1040
+ };
1041
+ }
1042
+ function parsePointsByReturn(dataView, isAtLeast14) {
1043
+ const count = isAtLeast14 ? 15 : 5;
1044
+ const offset = isAtLeast14 ? 255 : 111;
1045
+ const values = [];
1046
+ for (let index = 0; index < count; index++) {
1047
+ values.push(
1048
+ isAtLeast14 ? readUint64(dataView, offset + index * 8) : dataView.getUint32(offset + index * 4, true)
1049
+ );
1050
+ }
1051
+ return values;
1052
+ }
1053
+ function readLASString(bytes, offset, length) {
1054
+ return decodeLASString(bytes.subarray(offset, offset + length));
1055
+ }
1056
+ function decodeLASString(bytes) {
1057
+ let end = bytes.length;
1058
+ while (end > 0 && bytes[end - 1] === 0) {
1059
+ end--;
1060
+ }
1061
+ return new TextDecoder().decode(bytes.subarray(0, end)).trim();
1062
+ }
1063
+ function formatLASProjectId(bytes) {
1064
+ const formatLittleEndian = (start, length) => Array.from(bytes.subarray(start, start + length), (byte) => byte.toString(16).padStart(2, "0")).reverse().join("");
1065
+ const formatBigEndian = (start, length) => Array.from(
1066
+ bytes.subarray(start, start + length),
1067
+ (byte) => byte.toString(16).padStart(2, "0")
1068
+ ).join("");
1069
+ return `${formatLittleEndian(0, 4)}-${formatLittleEndian(4, 2)}-${formatLittleEndian(6, 2)}-${formatBigEndian(8, 2)}${formatBigEndian(10, 6)}`;
1070
+ }
1071
+ function readUint16Array(bytes) {
1072
+ const dataView = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
1073
+ const values = new Uint16Array(Math.floor(bytes.byteLength / 2));
1074
+ for (let index = 0; index < values.length; index++) {
1075
+ values[index] = dataView.getUint16(index * 2, true);
1076
+ }
1077
+ return values;
1078
+ }
1079
+ function readFloat64Array(bytes) {
1080
+ const dataView = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
1081
+ const values = new Float64Array(Math.floor(bytes.byteLength / 8));
1082
+ for (let index = 0; index < values.length; index++) {
1083
+ values[index] = dataView.getFloat64(index * 8, true);
1084
+ }
1085
+ return values;
1086
+ }
1087
+ function parseLASArrowTableBatch(arrayBuffer, lasHeader, options = {}) {
1088
+ const batchSize = lasHeader.pointsCount;
1089
+ const PositionsType = options.las?.fp64 ? Float64Array : Float32Array;
1090
+ const positions = new PositionsType(batchSize * 3);
1091
+ const selection = getLASColumnSelection(options);
1092
+ const colors = lasHeader.hasColor && selection.color ? new Uint8Array(batchSize * 4) : null;
1093
+ const intensities = selection.intensity ? new Uint16Array(batchSize) : null;
1094
+ const classifications = selection.classification ? new Uint8Array(batchSize) : null;
1095
+ const syntheticFlags = selection.synthetic ? new Uint8Array(batchSize) : null;
1096
+ const keyPointFlags = selection.keyPoint ? new Uint8Array(batchSize) : null;
1097
+ const withheldFlags = selection.withheld ? new Uint8Array(batchSize) : null;
1098
+ const overlapFlags = selection.overlap ? new Uint8Array(batchSize) : null;
1099
+ const gpsTimes = selection.gpsTime && getGpsTimeOffset(lasHeader.pointsFormatId) >= 0 ? new Float64Array(batchSize) : null;
1100
+ const nir = selection.nir && (getNirOffset(lasHeader.pointsFormatId) >= 0 || options.las?.compatibilityMode !== "raw" && lasHeader.metadata?.compatibility?.nirByteOffset !== void 0) ? new Uint16Array(batchSize) : null;
1101
+ const scanAngles = selection.scanAngle ? new Int16Array(batchSize) : null;
1102
+ const userData = selection.userData ? new Uint8Array(batchSize) : null;
1103
+ const pointSourceIds = selection.pointSourceId ? new Uint16Array(batchSize) : null;
1104
+ const returnNumbers = selection.returnNumber ? new Uint8Array(batchSize) : null;
1105
+ const numberOfReturns = selection.numberOfReturns ? new Uint8Array(batchSize) : null;
1106
+ const scannerChannels = selection.scannerChannel ? new Uint8Array(batchSize) : null;
1107
+ const scanDirectionFlags = selection.scanDirectionFlag ? new Uint8Array(batchSize) : null;
1108
+ const edgeOfFlightLines = selection.edgeOfFlightLine ? new Uint8Array(batchSize) : null;
1109
+ const waveforms = selection.waveform && getWaveformOffset(lasHeader.pointsFormatId) >= 0 ? new Uint8Array(batchSize * 29) : null;
1110
+ const extraByteCount = Math.max(
1111
+ 0,
1112
+ lasHeader.pointsStructSize - getLAZPointDataRecordBaseLength(lasHeader.pointsFormatId)
1113
+ );
1114
+ const extraBytes = selection.extraBytes && options.las?.extraBytes !== "typed" && extraByteCount ? new Uint8Array(batchSize * extraByteCount) : null;
1115
+ const typedExtraBytes = selection.extraBytes && options.las?.extraBytes === "typed" ? createTypedExtraBytesAttributes(batchSize, lasHeader) : null;
1116
+ populateLASAttributesFromDataView(makeDataView(arrayBuffer), lasHeader, options, {
1117
+ positions,
1118
+ colors,
1119
+ intensities,
1120
+ classifications,
1121
+ syntheticFlags,
1122
+ keyPointFlags,
1123
+ withheldFlags,
1124
+ overlapFlags,
1125
+ gpsTimes,
1126
+ nir,
1127
+ scanAngles,
1128
+ userData,
1129
+ pointSourceIds,
1130
+ returnNumbers,
1131
+ numberOfReturns,
1132
+ scannerChannels,
1133
+ scanDirectionFlags,
1134
+ edgeOfFlightLines,
1135
+ waveforms,
1136
+ extraBytes,
1137
+ typedExtraBytes,
1138
+ pointOffset: 0,
1139
+ sourcePointIndex: 0,
1140
+ pointCount: batchSize
1141
+ });
1142
+ return makeLASArrowTableFromAttributes(
1143
+ lasHeader,
1144
+ positions,
1145
+ colors,
1146
+ intensities,
1147
+ classifications,
1148
+ syntheticFlags,
1149
+ keyPointFlags,
1150
+ withheldFlags,
1151
+ overlapFlags,
1152
+ gpsTimes,
1153
+ nir,
1154
+ scanAngles,
1155
+ userData,
1156
+ pointSourceIds,
1157
+ returnNumbers,
1158
+ numberOfReturns,
1159
+ scannerChannels,
1160
+ scanDirectionFlags,
1161
+ edgeOfFlightLines,
1162
+ waveforms,
1163
+ extraBytes,
1164
+ typedExtraBytes
1165
+ );
1166
+ }
1167
+ function makeLASArrowTableFromAttributes(lasHeader, positions, colors, intensities, classifications, syntheticFlags, keyPointFlags, withheldFlags, overlapFlags, gpsTimes, nir, scanAngles, userData, pointSourceIds, returnNumbers, numberOfReturns, scannerChannels, scanDirectionFlags, edgeOfFlightLines, waveforms, extraBytes, typedExtraBytes) {
1168
+ const attributes = {
1169
+ POSITION: { value: positions, size: 3 }
1170
+ };
1171
+ if (intensities) {
1172
+ attributes.intensity = { value: intensities, size: 1 };
1173
+ }
1174
+ if (classifications) {
1175
+ attributes.classification = { value: classifications, size: 1 };
1176
+ }
1177
+ if (syntheticFlags) {
1178
+ attributes.synthetic = { value: syntheticFlags, size: 1 };
1179
+ }
1180
+ if (keyPointFlags) {
1181
+ attributes.keyPoint = { value: keyPointFlags, size: 1 };
1182
+ }
1183
+ if (withheldFlags) {
1184
+ attributes.withheld = { value: withheldFlags, size: 1 };
1185
+ }
1186
+ if (overlapFlags) {
1187
+ attributes.overlap = { value: overlapFlags, size: 1 };
1188
+ }
1189
+ if (colors) {
1190
+ attributes.COLOR_0 = { value: colors, size: colors instanceof Uint16Array ? 3 : 4 };
1191
+ }
1192
+ if (gpsTimes) {
1193
+ attributes.GPS_TIME = { value: gpsTimes, size: 1 };
1194
+ }
1195
+ if (nir) {
1196
+ attributes.NIR = { value: nir, size: 1 };
1197
+ }
1198
+ if (scanAngles) {
1199
+ attributes.scanAngle = { value: scanAngles, size: 1 };
1200
+ }
1201
+ if (userData) {
1202
+ attributes.userData = { value: userData, size: 1 };
1203
+ }
1204
+ if (pointSourceIds) {
1205
+ attributes.pointSourceId = { value: pointSourceIds, size: 1 };
1206
+ }
1207
+ if (returnNumbers) {
1208
+ attributes.returnNumber = { value: returnNumbers, size: 1 };
1209
+ }
1210
+ if (numberOfReturns) {
1211
+ attributes.numberOfReturns = { value: numberOfReturns, size: 1 };
1212
+ }
1213
+ if (scannerChannels) {
1214
+ attributes.scannerChannel = { value: scannerChannels, size: 1 };
1215
+ }
1216
+ if (scanDirectionFlags) {
1217
+ attributes.scanDirectionFlag = { value: scanDirectionFlags, size: 1 };
1218
+ }
1219
+ if (edgeOfFlightLines) {
1220
+ attributes.edgeOfFlightLine = { value: edgeOfFlightLines, size: 1 };
1221
+ }
1222
+ if (waveforms) {
1223
+ attributes.WAVEFORM = { value: waveforms, size: 29 };
1224
+ }
1225
+ if (extraBytes) {
1226
+ attributes.EXTRA_BYTES = {
1227
+ value: extraBytes,
1228
+ size: extraBytes.length / Math.max(lasHeader.pointsCount, 1)
1229
+ };
1230
+ }
1231
+ if (typedExtraBytes) {
1232
+ for (const attribute of typedExtraBytes) {
1233
+ attributes[attribute.name] = { value: attribute.value, size: attribute.size };
1234
+ }
1235
+ }
1236
+ const numericAttributes = {};
1237
+ for (const [name, attribute] of Object.entries(attributes)) {
1238
+ if (!(attribute.value instanceof BigInt64Array) && !(attribute.value instanceof BigUint64Array)) {
1239
+ numericAttributes[name] = { ...attribute, value: attribute.value };
1240
+ }
1241
+ }
1242
+ const schema = (0, import_get_las_schema.getLASSchema)(lasHeader, numericAttributes);
1243
+ return {
1244
+ ...(0, import_schema_utils.makeMeshArrowTable)(attributes, {
1245
+ schema,
1246
+ topology: "point-list",
1247
+ mode: 0,
1248
+ boundingBox: getHeaderBoundingBox(lasHeader)
1249
+ }),
1250
+ loader: "las",
1251
+ loaderData: lasHeader,
1252
+ progress: lasHeader.totalRead / lasHeader.totalToRead
1253
+ };
1254
+ }
1255
+ function makeDataView(arrayBuffer) {
1256
+ if (ArrayBuffer.isView(arrayBuffer)) {
1257
+ return new DataView(arrayBuffer.buffer, arrayBuffer.byteOffset, arrayBuffer.byteLength);
1258
+ }
1259
+ return new DataView(arrayBuffer);
1260
+ }
1261
+ function populateLASAttributesFromDataView(dataView, lasHeader, options, target) {
1262
+ const {
1263
+ scale: [scaleX, scaleY, scaleZ],
1264
+ offset: [offsetX, offsetY, offsetZ]
1265
+ } = lasHeader;
1266
+ const pointsFormatId = lasHeader.pointsFormatId;
1267
+ const pointRecordLength = lasHeader.pointsStructSize;
1268
+ const colorOffset = target.colors ? getColorOffset(pointsFormatId) : -1;
1269
+ const twoByteColor = colorOffset >= 0 ? detectTwoByteColors(
1270
+ dataView,
1271
+ lasHeader,
1272
+ target.sourcePointIndex,
1273
+ target.pointCount,
1274
+ options.las?.colorDepth
1275
+ ) : false;
1276
+ const intensities = target.intensities;
1277
+ const classifications = target.classifications;
1278
+ const syntheticFlags = target.syntheticFlags;
1279
+ const keyPointFlags = target.keyPointFlags;
1280
+ const withheldFlags = target.withheldFlags;
1281
+ const overlapFlags = target.overlapFlags;
1282
+ const gpsTimes = target.gpsTimes;
1283
+ const nir = target.nir;
1284
+ const scanAngles = target.scanAngles;
1285
+ const userData = target.userData;
1286
+ const pointSourceIds = target.pointSourceIds;
1287
+ const returnNumbers = target.returnNumbers;
1288
+ const numberOfReturns = target.numberOfReturns;
1289
+ const scannerChannels = target.scannerChannels;
1290
+ const scanDirectionFlags = target.scanDirectionFlags;
1291
+ const edgeOfFlightLines = target.edgeOfFlightLines;
1292
+ const waveforms = target.waveforms;
1293
+ const extraBytes = target.extraBytes;
1294
+ const typedExtraBytes = target.typedExtraBytes;
1295
+ const gpsTimeOffset = gpsTimes ? getGpsTimeOffset(pointsFormatId) : -1;
1296
+ const nirOffset = nir ? getNirOffset(pointsFormatId) : -1;
1297
+ for (let pointIndex = 0; pointIndex < target.pointCount; pointIndex++) {
1298
+ const sourcePointIndex = target.sourcePointIndex + pointIndex;
1299
+ const pointOffset = lasHeader.pointsOffset + sourcePointIndex * pointRecordLength;
1300
+ const targetPointIndex = target.pointOffset + pointIndex;
1301
+ target.positions[targetPointIndex * 3] = dataView.getInt32(pointOffset, true) * scaleX + offsetX;
1302
+ target.positions[targetPointIndex * 3 + 1] = dataView.getInt32(pointOffset + 4, true) * scaleY + offsetY;
1303
+ target.positions[targetPointIndex * 3 + 2] = dataView.getInt32(pointOffset + 8, true) * scaleZ + offsetZ;
1304
+ if (intensities) {
1305
+ intensities[targetPointIndex] = dataView.getUint16(pointOffset + 12, true);
1306
+ }
1307
+ if (classifications) {
1308
+ classifications[targetPointIndex] = readClassification(dataView, pointOffset, pointsFormatId);
1309
+ }
1310
+ if (gpsTimes && gpsTimeOffset >= 0) {
1311
+ gpsTimes[targetPointIndex] = dataView.getFloat64(pointOffset + gpsTimeOffset, true);
1312
+ }
1313
+ if (nir && nirOffset >= 0) {
1314
+ nir[targetPointIndex] = dataView.getUint16(pointOffset + nirOffset, true);
1315
+ }
1316
+ if (scanAngles) {
1317
+ scanAngles[targetPointIndex] = pointsFormatId <= 5 ? dataView.getInt8(pointOffset + 16) : dataView.getInt16(pointOffset + 18, true);
1318
+ }
1319
+ if (userData) {
1320
+ userData[targetPointIndex] = dataView.getUint8(pointOffset + 17);
1321
+ }
1322
+ if (pointSourceIds) {
1323
+ pointSourceIds[targetPointIndex] = dataView.getUint16(
1324
+ pointOffset + (pointsFormatId <= 5 ? 18 : 20),
1325
+ true
1326
+ );
1327
+ }
1328
+ const returnFlags = dataView.getUint8(pointOffset + 14);
1329
+ const scanFlags = dataView.getUint8(pointOffset + 15);
1330
+ const classificationFlags = pointsFormatId <= 5 ? scanFlags >> 5 : scanFlags;
1331
+ if (syntheticFlags) {
1332
+ syntheticFlags[targetPointIndex] = classificationFlags & 1;
1333
+ }
1334
+ if (keyPointFlags) {
1335
+ keyPointFlags[targetPointIndex] = classificationFlags >> 1 & 1;
1336
+ }
1337
+ if (withheldFlags) {
1338
+ withheldFlags[targetPointIndex] = classificationFlags >> 2 & 1;
1339
+ }
1340
+ if (overlapFlags) {
1341
+ overlapFlags[targetPointIndex] = pointsFormatId <= 5 ? 0 : classificationFlags >> 3 & 1;
1342
+ }
1343
+ if (returnNumbers) {
1344
+ returnNumbers[targetPointIndex] = pointsFormatId <= 5 ? returnFlags & 7 : returnFlags & 15;
1345
+ }
1346
+ if (numberOfReturns) {
1347
+ numberOfReturns[targetPointIndex] = pointsFormatId <= 5 ? returnFlags >> 3 & 7 : returnFlags >> 4;
1348
+ }
1349
+ if (scannerChannels) {
1350
+ scannerChannels[targetPointIndex] = pointsFormatId <= 5 ? 0 : scanFlags >> 4 & 3;
1351
+ }
1352
+ if (scanDirectionFlags) {
1353
+ scanDirectionFlags[targetPointIndex] = pointsFormatId <= 5 ? returnFlags >> 6 & 1 : scanFlags >> 6 & 1;
1354
+ }
1355
+ if (edgeOfFlightLines) {
1356
+ edgeOfFlightLines[targetPointIndex] = pointsFormatId <= 5 ? returnFlags >> 7 & 1 : scanFlags >> 7 & 1;
1357
+ }
1358
+ if (waveforms) {
1359
+ const waveformOffset = getWaveformOffset(pointsFormatId);
1360
+ if (waveformOffset >= 0) {
1361
+ const waveformBytes = new Uint8Array(
1362
+ dataView.buffer,
1363
+ dataView.byteOffset + pointOffset + waveformOffset,
1364
+ 29
1365
+ );
1366
+ waveforms.set(waveformBytes, targetPointIndex * 29);
1367
+ }
1368
+ }
1369
+ if (extraBytes) {
1370
+ const extraByteOffset = getLAZPointDataRecordBaseLength(pointsFormatId);
1371
+ const extraByteCount = lasHeader.pointsStructSize - extraByteOffset;
1372
+ if (extraByteCount > 0) {
1373
+ extraBytes.set(
1374
+ new Uint8Array(
1375
+ dataView.buffer,
1376
+ dataView.byteOffset + pointOffset + extraByteOffset,
1377
+ extraByteCount
1378
+ ),
1379
+ targetPointIndex * extraByteCount
1380
+ );
1381
+ }
1382
+ }
1383
+ if (typedExtraBytes) {
1384
+ populateTypedExtraBytesFromDataView(
1385
+ dataView,
1386
+ pointOffset,
1387
+ pointsFormatId,
1388
+ targetPointIndex,
1389
+ typedExtraBytes
1390
+ );
1391
+ }
1392
+ if (options.las?.compatibilityMode !== "raw" && lasHeader.metadata?.compatibility) {
1393
+ (0, import_las_compatibility.populateLASCompatibilityPoint)(
1394
+ dataView,
1395
+ pointOffset + getLAZPointDataRecordBaseLength(pointsFormatId),
1396
+ targetPointIndex,
1397
+ lasHeader.metadata.compatibility,
1398
+ target
1399
+ );
1400
+ }
1401
+ if (colorOffset >= 0 && target.colors) {
1402
+ const red = dataView.getUint16(pointOffset + colorOffset, true);
1403
+ const green = dataView.getUint16(pointOffset + colorOffset + 2, true);
1404
+ const blue = dataView.getUint16(pointOffset + colorOffset + 4, true);
1405
+ target.colors[targetPointIndex * 4] = twoByteColor ? red / 256 : red;
1406
+ target.colors[targetPointIndex * 4 + 1] = twoByteColor ? green / 256 : green;
1407
+ target.colors[targetPointIndex * 4 + 2] = twoByteColor ? blue / 256 : blue;
1408
+ target.colors[targetPointIndex * 4 + 3] = 255;
1409
+ }
1410
+ }
1411
+ }
1412
+ function readClassification(dataView, pointOffset, pointsFormatId) {
1413
+ return pointsFormatId <= 5 ? dataView.getUint8(pointOffset + 15) & 31 : dataView.getUint8(pointOffset + 16);
1414
+ }
1415
+ function hasPointColor(pointsFormatId) {
1416
+ return getColorOffset(pointsFormatId) >= 0;
1417
+ }
1418
+ function getColorOffset(pointsFormatId) {
1419
+ switch (pointsFormatId) {
1420
+ case 2:
1421
+ return 20;
1422
+ case 3:
1423
+ return 28;
1424
+ case 5:
1425
+ return 28;
1426
+ case 7:
1427
+ case 8:
1428
+ case 10:
1429
+ return 30;
1430
+ default:
1431
+ return -1;
1432
+ }
1433
+ }
1434
+ function getWaveformOffset(pointsFormatId) {
1435
+ switch (pointsFormatId) {
1436
+ case 4:
1437
+ return 28;
1438
+ case 5:
1439
+ return 34;
1440
+ case 9:
1441
+ return 30;
1442
+ case 10:
1443
+ return 38;
1444
+ default:
1445
+ return -1;
1446
+ }
1447
+ }
1448
+ function getGpsTimeOffset(pointsFormatId) {
1449
+ return pointsFormatId === 1 || pointsFormatId === 3 || pointsFormatId === 4 || pointsFormatId === 5 ? 20 : pointsFormatId >= 6 && pointsFormatId <= 10 ? 22 : -1;
1450
+ }
1451
+ function getNirOffset(pointsFormatId) {
1452
+ return pointsFormatId === 8 || pointsFormatId === 10 ? 36 : -1;
1453
+ }
1454
+ function detectTwoByteColors(dataView, lasHeader, sourcePointIndex, batchSize, colorDepth) {
1455
+ if (colorDepth === 8) {
1456
+ return false;
1457
+ }
1458
+ if (colorDepth === 16) {
1459
+ return true;
1460
+ }
1461
+ if (colorDepth !== "auto") {
1462
+ return false;
1463
+ }
1464
+ const colorOffset = getColorOffset(lasHeader.pointsFormatId);
1465
+ if (colorOffset < 0) {
1466
+ return false;
1467
+ }
1468
+ for (let pointIndex = 0; pointIndex < batchSize; pointIndex++) {
1469
+ const pointOffset = lasHeader.pointsOffset + (sourcePointIndex + pointIndex) * lasHeader.pointsStructSize;
1470
+ if (dataView.getUint16(pointOffset + colorOffset, true) > 255 || dataView.getUint16(pointOffset + colorOffset + 2, true) > 255 || dataView.getUint16(pointOffset + colorOffset + 4, true) > 255) {
1471
+ return true;
1472
+ }
1473
+ }
1474
+ return false;
1475
+ }
1476
+ function getBatchSize(options) {
1477
+ const batchSize = options.batchSize ?? options.core?.batchSize;
1478
+ return typeof batchSize === "number" ? batchSize : DEFAULT_BATCH_SIZE;
1479
+ }
1480
+ function parseLASZipVLR(bytes, header) {
1481
+ const dataView = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
1482
+ let offset = header.headerSize || LAS_14_HEADER_LENGTH;
1483
+ const vlrCount = header.vlrCount || 0;
1484
+ for (let index = 0; index < vlrCount; index++) {
1485
+ if (offset + 54 > bytes.byteLength) {
1486
+ throw new import_loader_utils.NeedsMoreData("LASLoader: incomplete VLR header");
1487
+ }
1488
+ const userId = readNullTerminatedAscii(bytes, offset + 2, 16);
1489
+ const recordId = dataView.getUint16(offset + 18, true);
1490
+ const recordLength = dataView.getUint16(offset + 20, true);
1491
+ const dataOffset = offset + 54;
1492
+ if (dataOffset + recordLength > bytes.byteLength) {
1493
+ throw new import_loader_utils.NeedsMoreData("LASLoader: incomplete VLR data");
1494
+ }
1495
+ if (userId === LASZIP_USER_ID && recordId === LASZIP_RECORD_ID) {
1496
+ if (recordLength < 34) {
1497
+ throw new Error("LASLoader: malformed LASzip VLR");
1498
+ }
1499
+ const chunkSize = dataView.getUint32(dataOffset + 12, true);
1500
+ const itemCount = dataView.getUint16(dataOffset + 32, true);
1501
+ const itemDataByteLength = 34 + itemCount * 6;
1502
+ if (itemDataByteLength > recordLength) {
1503
+ throw new Error("LASLoader: malformed LASzip VLR item table");
1504
+ }
1505
+ let point14ItemVersion = null;
1506
+ let rgb14ItemVersion = null;
1507
+ let wavePacket13ItemVersion = null;
1508
+ let wavePacketItemVersion = null;
1509
+ let byte14ItemVersion = null;
1510
+ const items = [];
1511
+ for (let itemIndex = 0; itemIndex < itemCount; itemIndex++) {
1512
+ const itemOffset = dataOffset + 34 + itemIndex * 6;
1513
+ const itemType = dataView.getUint16(itemOffset, true);
1514
+ const itemSize = dataView.getUint16(itemOffset + 2, true);
1515
+ const itemVersion = dataView.getUint16(itemOffset + 4, true);
1516
+ items.push({ type: itemType, size: itemSize, version: itemVersion });
1517
+ if ([0, 6, 7, 8].includes(itemType)) {
1518
+ if (itemVersion !== 1 && itemVersion !== 2) {
1519
+ throw new Error(
1520
+ `LASLoader: unsupported legacy LASzip item type ${itemType} version ${itemVersion}`
1521
+ );
1522
+ }
1523
+ } else if (itemType === 9) {
1524
+ if (itemVersion !== 1) {
1525
+ throw new Error(`LASLoader: unsupported WavePacket13 item version ${itemVersion}`);
1526
+ }
1527
+ wavePacket13ItemVersion = itemVersion;
1528
+ } else if ([10, 11, 12, 14].includes(itemType)) {
1529
+ if (itemVersion !== 2 && itemVersion !== 3 && itemVersion !== 4) {
1530
+ throw new Error(
1531
+ `LASLoader: unsupported LAS 1.4 item type ${itemType} version ${itemVersion}`
1532
+ );
1533
+ }
1534
+ if (itemType === 10) {
1535
+ point14ItemVersion = itemVersion;
1536
+ } else if (itemType === 11 || itemType === 12) {
1537
+ rgb14ItemVersion = itemVersion;
1538
+ } else {
1539
+ byte14ItemVersion = itemVersion;
1540
+ }
1541
+ } else if (itemType === 13) {
1542
+ if (itemVersion !== 3 && itemVersion !== 4) {
1543
+ throw new Error(`LASLoader: unsupported WavePacket14 item version ${itemVersion}`);
1544
+ }
1545
+ wavePacketItemVersion = itemVersion;
1546
+ }
1547
+ }
1548
+ return {
1549
+ compressor: dataView.getUint16(dataOffset, true),
1550
+ coder: dataView.getUint16(dataOffset + 2, true),
1551
+ chunkSize,
1552
+ variableChunks: dataView.getUint16(dataOffset, true) !== 1 && (chunkSize === 0 || chunkSize === VARIABLE_CHUNK_SIZE),
1553
+ items,
1554
+ point14ItemVersion,
1555
+ rgb14ItemVersion,
1556
+ wavePacket13ItemVersion,
1557
+ wavePacketItemVersion,
1558
+ byte14ItemVersion
1559
+ };
1560
+ }
1561
+ offset = dataOffset + recordLength;
1562
+ }
1563
+ throw new Error("LASLoader: compressed LAZ file does not contain a LASzip VLR");
1564
+ }
1565
+ function validateTypeScriptLAZSupport(header, laszip) {
1566
+ if (![0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10].includes(header.pointsFormatId)) {
1567
+ throw new Error(
1568
+ `LASLoader: TypeScript LAZ streaming only supports point formats 0-10; received ${header.pointsFormatId}`
1569
+ );
1570
+ }
1571
+ if (header.pointsFormatId <= 5 && laszip.compressor !== 1 && laszip.compressor !== 2) {
1572
+ throw new Error(
1573
+ `LASLoader: legacy TypeScript LAZ decoding requires LASzip compressor 1 or 2; received ${laszip.compressor}`
1574
+ );
1575
+ }
1576
+ if (header.pointsFormatId >= 6 && laszip.compressor !== 3) {
1577
+ throw new Error(
1578
+ `LASLoader: LAS 1.4 TypeScript LAZ decoding requires LASzip compressor 3; received ${laszip.compressor}`
1579
+ );
1580
+ }
1581
+ if (laszip.coder !== 0) {
1582
+ throw new Error(
1583
+ `LASLoader: TypeScript LAZ decoding requires LASzip arithmetic coder 0; received ${laszip.coder}`
1584
+ );
1585
+ }
1586
+ validateLASZipItemLayout(header, laszip.items);
1587
+ if (header.pointsFormatId >= 6 && !laszip.point14ItemVersion) {
1588
+ throw new Error(
1589
+ `LASLoader: point format ${header.pointsFormatId} requires a Point14 LASzip item`
1590
+ );
1591
+ }
1592
+ if ((header.pointsFormatId === 4 || header.pointsFormatId === 5) && !laszip.wavePacket13ItemVersion) {
1593
+ throw new Error(
1594
+ `LASLoader: point format ${header.pointsFormatId} requires a WavePacket13 LASzip item`
1595
+ );
1596
+ }
1597
+ if ((header.pointsFormatId === 7 || header.pointsFormatId === 8 || header.pointsFormatId === 10) && !laszip.rgb14ItemVersion) {
1598
+ throw new Error(
1599
+ `LASLoader: point format ${header.pointsFormatId} requires an RGB14 or RGBNIR14 LASzip item`
1600
+ );
1601
+ }
1602
+ if (header.pointsFormatId >= 6 && header.pointsStructSize > getLAZPointDataRecordBaseLength(header.pointsFormatId) && !laszip.byte14ItemVersion) {
1603
+ throw new Error(
1604
+ `LASLoader: point format ${header.pointsFormatId} with Extra Bytes requires a Byte14 LASzip item`
1605
+ );
1606
+ }
1607
+ if ((header.pointsFormatId === 9 || header.pointsFormatId === 10) && !laszip.wavePacketItemVersion) {
1608
+ throw new Error(
1609
+ `LASLoader: point format ${header.pointsFormatId} requires a WavePacket14 LASzip item`
1610
+ );
1611
+ }
1612
+ }
1613
+ function validateLASZipItemLayout(header, actualItems) {
1614
+ const pointDataRecordFormat = header.pointsFormatId;
1615
+ const baseLength = getLAZPointDataRecordBaseLength(pointDataRecordFormat);
1616
+ const extraByteCount = header.pointsStructSize - baseLength;
1617
+ if (extraByteCount < 0) {
1618
+ throw new Error(
1619
+ `LASLoader: point format ${pointDataRecordFormat} record length ${header.pointsStructSize} is smaller than ${baseLength}`
1620
+ );
1621
+ }
1622
+ const expectedItems = [];
1623
+ switch (pointDataRecordFormat) {
1624
+ case 0:
1625
+ expectedItems.push({ type: 6, size: 20 });
1626
+ break;
1627
+ case 1:
1628
+ expectedItems.push({ type: 6, size: 20 }, { type: 7, size: 8 });
1629
+ break;
1630
+ case 2:
1631
+ expectedItems.push({ type: 6, size: 20 }, { type: 8, size: 6 });
1632
+ break;
1633
+ case 3:
1634
+ expectedItems.push({ type: 6, size: 20 }, { type: 7, size: 8 }, { type: 8, size: 6 });
1635
+ break;
1636
+ case 4:
1637
+ expectedItems.push({ type: 6, size: 20 }, { type: 7, size: 8 }, { type: 9, size: 29 });
1638
+ break;
1639
+ case 5:
1640
+ expectedItems.push(
1641
+ { type: 6, size: 20 },
1642
+ { type: 7, size: 8 },
1643
+ { type: 8, size: 6 },
1644
+ { type: 9, size: 29 }
1645
+ );
1646
+ break;
1647
+ case 6:
1648
+ expectedItems.push({ type: 10, size: 30 });
1649
+ break;
1650
+ case 7:
1651
+ expectedItems.push({ type: 10, size: 30 }, { type: 11, size: 6 });
1652
+ break;
1653
+ case 8:
1654
+ expectedItems.push({ type: 10, size: 30 }, { type: 12, size: 8 });
1655
+ break;
1656
+ case 9:
1657
+ expectedItems.push({ type: 10, size: 30 }, { type: 13, size: 29 });
1658
+ break;
1659
+ case 10:
1660
+ expectedItems.push({ type: 10, size: 30 }, { type: 12, size: 8 }, { type: 13, size: 29 });
1661
+ break;
1662
+ default:
1663
+ return;
1664
+ }
1665
+ if (extraByteCount > 0) {
1666
+ expectedItems.push({ type: pointDataRecordFormat <= 5 ? 0 : 14, size: extraByteCount });
1667
+ }
1668
+ if (actualItems.length !== expectedItems.length) {
1669
+ throw new Error(
1670
+ `LASLoader: point format ${pointDataRecordFormat} has ${actualItems.length} LASzip items; expected ${expectedItems.length}`
1671
+ );
1672
+ }
1673
+ for (let itemIndex = 0; itemIndex < expectedItems.length; itemIndex++) {
1674
+ const actualItem = actualItems[itemIndex];
1675
+ const expectedItem = expectedItems[itemIndex];
1676
+ if (actualItem.type !== expectedItem.type) {
1677
+ throw new Error(
1678
+ `LASLoader: LASzip item ${itemIndex} has type ${actualItem.type}; expected ${expectedItem.type} for point format ${pointDataRecordFormat}`
1679
+ );
1680
+ }
1681
+ if (actualItem.size !== expectedItem.size) {
1682
+ throw new Error(
1683
+ `LASLoader: LASzip item ${itemIndex} has size ${actualItem.size}; expected ${expectedItem.size} for point format ${pointDataRecordFormat}`
1684
+ );
1685
+ }
1686
+ }
1687
+ }
1688
+ async function readLASZipVLRFromInput(initialPending, inputIterator, header) {
1689
+ let pending = initialPending;
1690
+ while (true) {
1691
+ try {
1692
+ return { pending, laszip: parseLASZipVLR(pending, header) };
1693
+ } catch (error) {
1694
+ if (!(error instanceof import_loader_utils.NeedsMoreData)) {
1695
+ throw error;
1696
+ }
1697
+ }
1698
+ const next = await inputIterator.next();
1699
+ if (next.done) {
1700
+ throw new import_loader_utils.NeedsMoreData("LASLoader: incomplete LASzip VLR");
1701
+ }
1702
+ pending = concatenateUint8Arrays(pending, toUint8Array(next.value));
1703
+ }
1704
+ }
1705
+ async function collectRemainingInputBytes(initialPending, inputIterator) {
1706
+ const chunks = [initialPending];
1707
+ let totalByteLength = initialPending.byteLength;
1708
+ while (true) {
1709
+ const next = await inputIterator.next();
1710
+ if (next.done) {
1711
+ break;
1712
+ }
1713
+ const chunk = toUint8Array(next.value);
1714
+ chunks.push(chunk);
1715
+ totalByteLength += chunk.byteLength;
1716
+ }
1717
+ if (chunks.length === 1) {
1718
+ return initialPending;
1719
+ }
1720
+ const bytes = new Uint8Array(totalByteLength);
1721
+ let byteOffset = 0;
1722
+ for (const chunk of chunks) {
1723
+ bytes.set(chunk, byteOffset);
1724
+ byteOffset += chunk.byteLength;
1725
+ }
1726
+ return bytes;
1727
+ }
1728
+ async function validateStreamedFixedLAZChunkTable(reader, inputIterator, header, laszip, chunkTableOffset, decodedChunkByteLengths, options) {
1729
+ if (options.las?.recoverMissingChunkTable && chunkTableOffset === header.pointsOffset) {
1730
+ if (laszip.variableChunks)
1731
+ throw new Error("LASLoader: cannot recover a missing variable-size LAZ chunk table");
1732
+ while (true) {
1733
+ if (reader.getAvailableByteLength())
1734
+ throw new Error("LASLoader: unexpected bytes after recovered LAZ chunks");
1735
+ const next = await inputIterator.next();
1736
+ if (next.done) return;
1737
+ reader.write(next.value);
1738
+ }
1739
+ }
1740
+ const decodedPointDataByteLength = decodedChunkByteLengths.reduce(
1741
+ (total, byteLength) => total + byteLength,
1742
+ 0
1743
+ );
1744
+ const decodedPointDataEnd = header.pointsOffset + LAZ_CHUNK_TABLE_POINTER_LENGTH + decodedPointDataByteLength;
1745
+ const effectiveChunkTableOffset = chunkTableOffset === -1 ? decodedPointDataEnd : chunkTableOffset;
1746
+ if (!Number.isSafeInteger(effectiveChunkTableOffset) || effectiveChunkTableOffset < decodedPointDataEnd) {
1747
+ throw new Error("LASLoader: LAZ chunk table byte lengths overlap the chunk table");
1748
+ }
1749
+ const gapByteLength = effectiveChunkTableOffset - decodedPointDataEnd;
1750
+ await readUntilAvailable(
1751
+ reader,
1752
+ inputIterator,
1753
+ gapByteLength,
1754
+ "LASLoader: incomplete LAZ chunk table"
1755
+ );
1756
+ reader.skip(gapByteLength);
1757
+ const chunks = await readStreamedLAZChunkTable(reader, inputIterator, header, laszip);
1758
+ if (chunks.length !== decodedChunkByteLengths.length) {
1759
+ throw new Error(
1760
+ `LASLoader: LAZ chunk table contains ${chunks.length} chunks; decoded ${decodedChunkByteLengths.length}`
1761
+ );
1762
+ }
1763
+ for (let chunkIndex = 0; chunkIndex < chunks.length; chunkIndex++) {
1764
+ if (chunks[chunkIndex].byteLength !== decodedChunkByteLengths[chunkIndex]) {
1765
+ throw new Error(
1766
+ `LASLoader: LAZ chunk ${chunkIndex} has ${chunks[chunkIndex].byteLength} table bytes; decoded ${decodedChunkByteLengths[chunkIndex]}`
1767
+ );
1768
+ }
1769
+ }
1770
+ if (chunkTableOffset === -1) {
1771
+ await validateStreamedLAZChunkTableFooter(reader, inputIterator, effectiveChunkTableOffset);
1772
+ }
1773
+ }
1774
+ async function validateStreamedLAZChunkTableFooter(reader, inputIterator, expectedChunkTableOffset) {
1775
+ const footer = new Uint8Array(LAZ_CHUNK_TABLE_POINTER_LENGTH);
1776
+ let byteLength = 0;
1777
+ while (true) {
1778
+ const availableByteLength = reader.getAvailableByteLength();
1779
+ if (availableByteLength > 0) {
1780
+ const bytes = reader.readBytes(Math.min(availableByteLength, 64 * 1024));
1781
+ appendTrailingBytes(footer, bytes);
1782
+ byteLength += bytes.byteLength;
1783
+ continue;
1784
+ }
1785
+ const next = await inputIterator.next();
1786
+ if (next.done) {
1787
+ break;
1788
+ }
1789
+ reader.write(next.value);
1790
+ }
1791
+ if (byteLength < LAZ_CHUNK_TABLE_POINTER_LENGTH) {
1792
+ throw new import_loader_utils.NeedsMoreData("LASLoader: incomplete non-seekable LAZ chunk-table footer");
1793
+ }
1794
+ const footerOffset = readUint64(new DataView(footer.buffer), 0);
1795
+ if (!Number.isSafeInteger(footerOffset) || footerOffset !== expectedChunkTableOffset) {
1796
+ throw new Error(
1797
+ `LASLoader: non-seekable LAZ footer points to ${footerOffset}; expected ${expectedChunkTableOffset}`
1798
+ );
1799
+ }
1800
+ }
1801
+ function appendTrailingBytes(target, bytes) {
1802
+ if (bytes.byteLength >= target.byteLength) {
1803
+ target.set(bytes.subarray(bytes.byteLength - target.byteLength));
1804
+ return;
1805
+ }
1806
+ target.copyWithin(0, bytes.byteLength);
1807
+ target.set(bytes, target.byteLength - bytes.byteLength);
1808
+ }
1809
+ async function readStreamedLAZChunkTable(reader, inputIterator, header, laszip) {
1810
+ let candidateByteLength = 64;
1811
+ while (true) {
1812
+ const availableByteLength = reader.getAvailableByteLength();
1813
+ if (availableByteLength >= 8) {
1814
+ const checkpoint = reader.checkpoint();
1815
+ try {
1816
+ const bytes = reader.readBytes(Math.min(availableByteLength, candidateByteLength));
1817
+ const chunks = decodeAndValidateLAZChunkTable(bytes, header, laszip);
1818
+ reader.restore(checkpoint);
1819
+ return chunks;
1820
+ } catch (error) {
1821
+ reader.restore(checkpoint);
1822
+ if (!(error instanceof import_loader_utils.NeedsMoreData)) {
1823
+ throw error;
1824
+ }
1825
+ candidateByteLength *= 2;
1826
+ if (candidateByteLength <= availableByteLength) {
1827
+ continue;
1828
+ }
1829
+ }
1830
+ }
1831
+ const next = await inputIterator.next();
1832
+ if (next.done) {
1833
+ throw new import_loader_utils.NeedsMoreData("LASLoader: incomplete LAZ chunk table");
1834
+ }
1835
+ reader.write(next.value);
1836
+ }
1837
+ }
1838
+ async function readUntilAvailable(reader, inputIterator, byteLength, errorMessage) {
1839
+ while (!reader.hasAvailableBytes(byteLength)) {
1840
+ const next = await inputIterator.next();
1841
+ if (next.done) {
1842
+ throw new import_loader_utils.NeedsMoreData(errorMessage);
1843
+ }
1844
+ reader.write(next.value);
1845
+ }
1846
+ }
1847
+ async function readLAZChunkByteLengthFromReader(reader, inputIterator, metadata) {
1848
+ while (true) {
1849
+ const checkpoint = reader.checkpoint();
1850
+ let chunkByteLength;
1851
+ try {
1852
+ chunkByteLength = tryReadLAZChunkByteLengthFromReader(reader, metadata);
1853
+ } finally {
1854
+ reader.restore(checkpoint);
1855
+ }
1856
+ if (chunkByteLength !== null) {
1857
+ await readUntilAvailable(
1858
+ reader,
1859
+ inputIterator,
1860
+ chunkByteLength,
1861
+ "LASLoader: truncated LAZ chunk"
1862
+ );
1863
+ return chunkByteLength;
1864
+ }
1865
+ const next = await inputIterator.next();
1866
+ if (next.done) {
1867
+ throw new import_loader_utils.NeedsMoreData("LASLoader: truncated LAZ chunk");
1868
+ }
1869
+ reader.write(next.value);
1870
+ }
1871
+ }
1872
+ function tryReadLAZChunkByteLengthFromReader(reader, metadata) {
1873
+ if (metadata.pointDataRecordFormat < 6 || metadata.pointDataRecordFormat > 10) {
1874
+ return null;
1875
+ }
1876
+ const extraByteCount = metadata.pointDataRecordLength - getLAZPointDataRecordBaseLength(metadata.pointDataRecordFormat);
1877
+ if (extraByteCount < 0) {
1878
+ throw new Error(`Invalid point record length ${metadata.pointDataRecordLength}`);
1879
+ }
1880
+ const sizeHeaderCount = getLAZChunkSizeHeaderBaseCount(metadata.pointDataRecordFormat) + extraByteCount;
1881
+ const sizeHeaderOffset = metadata.pointDataRecordLength + 4;
1882
+ const sizeHeaderByteLength = sizeHeaderCount * 4;
1883
+ const minimumByteLength = sizeHeaderOffset + sizeHeaderByteLength;
1884
+ if (!reader.hasAvailableBytes(minimumByteLength)) {
1885
+ return null;
1886
+ }
1887
+ reader.skip(sizeHeaderOffset);
1888
+ let chunkByteLength = minimumByteLength;
1889
+ for (let index = 0; index < sizeHeaderCount; index++) {
1890
+ chunkByteLength += reader.readUint32LE();
1891
+ }
1892
+ return chunkByteLength;
1893
+ }
1894
+ function getLAZPointDataRecordBaseLength(pointDataRecordFormat) {
1895
+ switch (pointDataRecordFormat) {
1896
+ case 0:
1897
+ return 20;
1898
+ case 1:
1899
+ return 28;
1900
+ case 2:
1901
+ return 26;
1902
+ case 3:
1903
+ return 34;
1904
+ case 4:
1905
+ return 57;
1906
+ case 5:
1907
+ return 63;
1908
+ case 6:
1909
+ return 30;
1910
+ case 7:
1911
+ return 36;
1912
+ case 8:
1913
+ return 38;
1914
+ case 9:
1915
+ return 59;
1916
+ case 10:
1917
+ return 67;
1918
+ default:
1919
+ throw new Error(`Unsupported LAS point format ${pointDataRecordFormat}`);
1920
+ }
1921
+ }
1922
+ function getLAZChunkSizeHeaderBaseCount(pointDataRecordFormat) {
1923
+ switch (pointDataRecordFormat) {
1924
+ case 6:
1925
+ return 9;
1926
+ case 7:
1927
+ return 10;
1928
+ case 8:
1929
+ return 11;
1930
+ case 9:
1931
+ return 10;
1932
+ case 10:
1933
+ return 12;
1934
+ default:
1935
+ throw new Error(`Unsupported LAS 1.4 point format ${pointDataRecordFormat}`);
1936
+ }
1937
+ }
1938
+ function readLAZFileChunks(bytes, header, laszip, options) {
1939
+ if (laszip.compressor === 1) {
1940
+ return [{ pointCount: header.pointsCount, byteLength: bytes.byteLength - header.pointsOffset }];
1941
+ }
1942
+ const chunkTableOffset = readLAZChunkTableOffset(
1943
+ new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength),
1944
+ header.pointsOffset
1945
+ );
1946
+ return readLAZChunkTable(bytes, header, laszip, chunkTableOffset, options);
1947
+ }
1948
+ function readLAZChunkTable(bytes, header, laszip, chunkTableOffset, options) {
1949
+ if (options.las?.recoverMissingChunkTable && chunkTableOffset === header.pointsOffset) {
1950
+ return recoverFixedLAZChunkTable(bytes, header, laszip);
1951
+ }
1952
+ if (!Number.isSafeInteger(chunkTableOffset) || chunkTableOffset < 0 || chunkTableOffset + 8 > bytes.byteLength) {
1953
+ throw new import_loader_utils.NeedsMoreData("LASLoader: incomplete LAZ chunk table");
1954
+ }
1955
+ const chunks = decodeAndValidateLAZChunkTable(bytes.subarray(chunkTableOffset), header, laszip);
1956
+ const decodedByteLength = chunks.reduce((total, chunk) => total + chunk.byteLength, 0);
1957
+ if (header.pointsOffset + LAZ_CHUNK_TABLE_POINTER_LENGTH + decodedByteLength > chunkTableOffset) {
1958
+ throw new Error("LASLoader: LAZ chunk table byte lengths overlap the chunk table");
1959
+ }
1960
+ return chunks;
1961
+ }
1962
+ function recoverFixedLAZChunkTable(bytes, header, laszip) {
1963
+ if (laszip.variableChunks || !laszip.chunkSize) {
1964
+ throw new Error("LASLoader: cannot recover a missing variable-size LAZ chunk table");
1965
+ }
1966
+ const chunks = [];
1967
+ let byteOffset = header.pointsOffset + LAZ_CHUNK_TABLE_POINTER_LENGTH;
1968
+ let pointOffset = 0;
1969
+ while (pointOffset < header.pointsCount) {
1970
+ const pointCount = Math.min(laszip.chunkSize, header.pointsCount - pointOffset);
1971
+ const metadata = createLAZChunkMetadata(header, laszip, pointCount);
1972
+ const compressed = bytes.subarray(byteOffset);
1973
+ let byteLength;
1974
+ if (header.pointsFormatId <= 5) {
1975
+ const cursor = (0, import_loader_utils.createLAZChunkDecoderCursor)(compressed, metadata);
1976
+ const scratch = new Uint8Array(Math.min(pointCount, 256) * header.pointsStructSize);
1977
+ while (cursor.remainingPointCount) {
1978
+ cursor.decodeInto(scratch, 0, Math.min(cursor.remainingPointCount, 256));
1979
+ }
1980
+ byteLength = cursor.compressedByteOffset;
1981
+ } else {
1982
+ validateRecoveredLayeredPointCount(compressed, metadata);
1983
+ byteLength = (0, import_loader_utils.getLAZChunkDeclaredByteLength)(compressed, metadata);
1984
+ }
1985
+ if (!byteLength || byteOffset + byteLength > bytes.byteLength) {
1986
+ throw new import_loader_utils.NeedsMoreData("LASLoader: truncated LAZ chunk during table recovery");
1987
+ }
1988
+ chunks.push({ pointCount, byteLength });
1989
+ byteOffset += byteLength;
1990
+ pointOffset += pointCount;
1991
+ }
1992
+ if (byteOffset !== bytes.byteLength) {
1993
+ throw new Error("LASLoader: unexpected bytes after recovered LAZ chunks");
1994
+ }
1995
+ return chunks;
1996
+ }
1997
+ function validateRecoveredLayeredPointCount(compressed, metadata) {
1998
+ if (compressed.byteLength < metadata.pointDataRecordLength + 4) {
1999
+ throw new import_loader_utils.NeedsMoreData("LASLoader: truncated recovered layered LAZ chunk header");
2000
+ }
2001
+ const view = new DataView(compressed.buffer, compressed.byteOffset, compressed.byteLength);
2002
+ const pointCount = view.getUint32(metadata.pointDataRecordLength, true);
2003
+ if (pointCount !== metadata.pointCount) {
2004
+ throw new Error(
2005
+ `LASLoader: recovered layered LAZ chunk contains ${pointCount} points; expected ${metadata.pointCount}`
2006
+ );
2007
+ }
2008
+ }
2009
+ function decodeAndValidateLAZChunkTable(chunkTableBytes, header, laszip) {
2010
+ if (chunkTableBytes.byteLength < 8) {
2011
+ throw new import_loader_utils.NeedsMoreData("LASLoader: incomplete LAZ chunk table");
2012
+ }
2013
+ const dataView = new DataView(
2014
+ chunkTableBytes.buffer,
2015
+ chunkTableBytes.byteOffset,
2016
+ chunkTableBytes.byteLength
2017
+ );
2018
+ const version = dataView.getUint32(0, true);
2019
+ const chunkCount = dataView.getUint32(4, true);
2020
+ if (version !== 0) {
2021
+ throw new Error(`LASLoader: unsupported LAZ chunk table version ${version}`);
2022
+ }
2023
+ if (chunkCount === 0) {
2024
+ if (header.pointsCount !== 0) {
2025
+ throw new Error("LASLoader: missing LAZ chunk table");
2026
+ }
2027
+ return [];
2028
+ }
2029
+ const chunks = (0, import_loader_utils.decodeLAZChunkTable)(chunkTableBytes.subarray(8), {
2030
+ chunkCount,
2031
+ pointCount: header.pointsCount,
2032
+ chunkSize: laszip.chunkSize,
2033
+ variable: laszip.variableChunks
2034
+ });
2035
+ let decodedPointCount = 0;
2036
+ for (const chunk of chunks) {
2037
+ if (chunk.pointCount === 0 || chunk.byteLength === 0) {
2038
+ throw new Error("LASLoader: invalid empty LAZ chunk-table entry");
2039
+ }
2040
+ decodedPointCount += chunk.pointCount;
2041
+ }
2042
+ if (decodedPointCount !== header.pointsCount) {
2043
+ throw new Error(
2044
+ `LASLoader: LAZ chunk table contains ${decodedPointCount} points; expected ${header.pointsCount}`
2045
+ );
2046
+ }
2047
+ return chunks;
2048
+ }
2049
+ function createRawPointBatchState(batchSize, pointRecordLength, stats) {
2050
+ if (stats) {
2051
+ stats.rawBatchAllocations++;
2052
+ }
2053
+ return {
2054
+ rawBatch: new Uint8Array(batchSize * pointRecordLength),
2055
+ batchPointCount: 0,
2056
+ totalRead: 0,
2057
+ rawBatchAllocations: 1,
2058
+ stats
2059
+ };
2060
+ }
2061
+ function createPointDataBatchState(batchSize, header, options) {
2062
+ const PositionsType = options.las?.fp64 ? Float64Array : Float32Array;
2063
+ const positions = new PositionsType(batchSize * 3);
2064
+ const selection = getLASColumnSelection(options);
2065
+ const useRawColors = header.hasColor && selection.color && (options.las?.colorDepth === 16 || options.las?.colorDepth === "auto");
2066
+ const colors = header.hasColor && selection.color && !useRawColors ? new Uint8Array(batchSize * 4) : null;
2067
+ const rawColors = useRawColors ? new Uint16Array(batchSize * 3) : null;
2068
+ const intensities = selection.intensity ? new Uint16Array(batchSize) : null;
2069
+ const classifications = selection.classification ? new Uint8Array(batchSize) : null;
2070
+ const syntheticFlags = selection.synthetic ? new Uint8Array(batchSize) : null;
2071
+ const keyPointFlags = selection.keyPoint ? new Uint8Array(batchSize) : null;
2072
+ const withheldFlags = selection.withheld ? new Uint8Array(batchSize) : null;
2073
+ const overlapFlags = selection.overlap ? new Uint8Array(batchSize) : null;
2074
+ const gpsTimes = selection.gpsTime && getGpsTimeOffset(header.pointsFormatId) >= 0 ? new Float64Array(batchSize) : null;
2075
+ const nir = selection.nir && (getNirOffset(header.pointsFormatId) >= 0 || options.las?.compatibilityMode !== "raw" && header.metadata?.compatibility?.nirByteOffset !== void 0) ? new Uint16Array(batchSize) : null;
2076
+ const scanAngles = selection.scanAngle ? new Int16Array(batchSize) : null;
2077
+ const userData = selection.userData ? new Uint8Array(batchSize) : null;
2078
+ const pointSourceIds = selection.pointSourceId ? new Uint16Array(batchSize) : null;
2079
+ const returnNumbers = selection.returnNumber ? new Uint8Array(batchSize) : null;
2080
+ const numberOfReturns = selection.numberOfReturns ? new Uint8Array(batchSize) : null;
2081
+ const scannerChannels = selection.scannerChannel ? new Uint8Array(batchSize) : null;
2082
+ const scanDirectionFlags = selection.scanDirectionFlag ? new Uint8Array(batchSize) : null;
2083
+ const edgeOfFlightLines = selection.edgeOfFlightLine ? new Uint8Array(batchSize) : null;
2084
+ const waveforms = selection.waveform && getWaveformOffset(header.pointsFormatId) >= 0 ? new Uint8Array(batchSize * 29) : null;
2085
+ const extraByteCount = Math.max(
2086
+ 0,
2087
+ header.pointsStructSize - getLAZPointDataRecordBaseLength(header.pointsFormatId)
2088
+ );
2089
+ const extraBytes = selection.extraBytes && options.las?.extraBytes !== "typed" && extraByteCount ? new Uint8Array(batchSize * extraByteCount) : null;
2090
+ const typedExtraBytes = selection.extraBytes && options.las?.extraBytes === "typed" ? createTypedExtraBytesAttributes(batchSize, header) : null;
2091
+ const typedExtraBytesSource = typedExtraBytes?.length && extraByteCount ? new Uint8Array(batchSize * extraByteCount) : null;
2092
+ const reconstructColumns = selection.classification || selection.returnNumber || selection.numberOfReturns || selection.scanAngle || selection.overlap || selection.scannerChannel || selection.nir;
2093
+ const compatibilityLayout = options.las?.compatibilityMode === "raw" || !reconstructColumns ? null : header.metadata?.compatibility || null;
2094
+ const compatibilityExtraBytesSource = compatibilityLayout && !extraBytes && !typedExtraBytesSource ? new Uint8Array(batchSize * extraByteCount) : null;
2095
+ return {
2096
+ batchCapacity: batchSize,
2097
+ positions,
2098
+ colors,
2099
+ rawColors,
2100
+ intensities,
2101
+ classifications,
2102
+ syntheticFlags,
2103
+ keyPointFlags,
2104
+ withheldFlags,
2105
+ overlapFlags,
2106
+ gpsTimes,
2107
+ nir,
2108
+ scanAngles,
2109
+ userData,
2110
+ pointSourceIds,
2111
+ returnNumbers,
2112
+ numberOfReturns,
2113
+ scannerChannels,
2114
+ scanDirectionFlags,
2115
+ edgeOfFlightLines,
2116
+ waveforms,
2117
+ extraBytes,
2118
+ typedExtraBytes,
2119
+ typedExtraBytesSource,
2120
+ compatibilityLayout,
2121
+ compatibilityExtraBytesSource,
2122
+ target: {
2123
+ positions,
2124
+ intensities,
2125
+ classifications,
2126
+ syntheticFlags,
2127
+ keyPointFlags,
2128
+ withheldFlags,
2129
+ overlapFlags,
2130
+ gpsTimes,
2131
+ nir,
2132
+ scanAngles,
2133
+ userData,
2134
+ pointSourceIds,
2135
+ returnNumbers,
2136
+ numberOfReturns,
2137
+ scannerChannels,
2138
+ scanDirectionFlags,
2139
+ edgeOfFlightLines,
2140
+ waveforms,
2141
+ extraBytes: extraBytes || typedExtraBytesSource || compatibilityExtraBytesSource,
2142
+ colors,
2143
+ rawColors,
2144
+ pointOffset: 0,
2145
+ scale: header.scale,
2146
+ offset: header.offset
2147
+ },
2148
+ batchPointCount: 0,
2149
+ totalRead: 0
2150
+ };
2151
+ }
2152
+ function createTypedExtraBytesAttributes(batchSize, header) {
2153
+ const extraByteCount = header.pointsStructSize - getLAZPointDataRecordBaseLength(header.pointsFormatId);
2154
+ return (0, import_las_extra_bytes.createLASTypedExtraBytesAttributes)(
2155
+ batchSize,
2156
+ header.metadata?.extraBytes || [],
2157
+ extraByteCount
2158
+ );
2159
+ }
2160
+ function getExtraBytesScalarByteLength(dataType) {
2161
+ if (dataType <= 2) return 1;
2162
+ if (dataType <= 4) return 2;
2163
+ if (dataType <= 6 || dataType === 9) return 4;
2164
+ if (dataType === 7 || dataType === 8 || dataType === 10) return 8;
2165
+ return 0;
2166
+ }
2167
+ function populateTypedExtraBytesFromDataView(dataView, pointOffset, pointDataRecordFormat, targetPointIndex, attributes) {
2168
+ const extraByteBaseOffset = pointOffset + getLAZPointDataRecordBaseLength(pointDataRecordFormat);
2169
+ for (const attribute of attributes) {
2170
+ const targetOffset = targetPointIndex * attribute.size;
2171
+ const sourceOffset = extraByteBaseOffset + attribute.byteOffset;
2172
+ for (let componentIndex = 0; componentIndex < attribute.size; componentIndex++) {
2173
+ (0, import_las_extra_bytes.populateLASTypedExtraBytesComponent)(
2174
+ dataView,
2175
+ sourceOffset + componentIndex * getExtraBytesScalarByteLength(attribute.scalarDataType),
2176
+ attribute,
2177
+ targetOffset + componentIndex,
2178
+ componentIndex
2179
+ );
2180
+ }
2181
+ }
2182
+ }
2183
+ function populateTypedExtraBytesFromPacked(packedExtraBytes, extraByteCount, pointOffset, pointCount, attributes) {
2184
+ const dataView = new DataView(
2185
+ packedExtraBytes.buffer,
2186
+ packedExtraBytes.byteOffset,
2187
+ packedExtraBytes.byteLength
2188
+ );
2189
+ for (let pointIndex = 0; pointIndex < pointCount; pointIndex++) {
2190
+ const targetPointIndex = pointOffset + pointIndex;
2191
+ const sourceOffset = targetPointIndex * extraByteCount;
2192
+ for (const attribute of attributes) {
2193
+ const targetOffset = targetPointIndex * attribute.size;
2194
+ const scalarByteLength = getExtraBytesScalarByteLength(attribute.scalarDataType);
2195
+ for (let componentIndex = 0; componentIndex < attribute.size; componentIndex++) {
2196
+ (0, import_las_extra_bytes.populateLASTypedExtraBytesComponent)(
2197
+ dataView,
2198
+ sourceOffset + attribute.byteOffset + componentIndex * scalarByteLength,
2199
+ attribute,
2200
+ targetOffset + componentIndex,
2201
+ componentIndex
2202
+ );
2203
+ }
2204
+ }
2205
+ }
2206
+ }
2207
+ function populateDecodedTypedExtraBytes(state, pointOffset, pointCount) {
2208
+ const compatibilityBytes = state.extraBytes || state.typedExtraBytesSource || state.compatibilityExtraBytesSource;
2209
+ if (state.compatibilityLayout && compatibilityBytes && pointCount) {
2210
+ const view = new DataView(
2211
+ compatibilityBytes.buffer,
2212
+ compatibilityBytes.byteOffset,
2213
+ compatibilityBytes.byteLength
2214
+ );
2215
+ const extraByteCount = compatibilityBytes.length / state.batchCapacity;
2216
+ for (let pointIndex = pointOffset; pointIndex < pointOffset + pointCount; pointIndex++) {
2217
+ (0, import_las_compatibility.populateLASCompatibilityPoint)(
2218
+ view,
2219
+ pointIndex * extraByteCount,
2220
+ pointIndex,
2221
+ state.compatibilityLayout,
2222
+ state
2223
+ );
2224
+ }
2225
+ }
2226
+ if (!state.typedExtraBytesSource || !state.typedExtraBytes?.length || pointCount === 0) {
2227
+ return;
2228
+ }
2229
+ populateTypedExtraBytesFromPacked(
2230
+ state.typedExtraBytesSource,
2231
+ state.typedExtraBytesSource.length / state.batchCapacity,
2232
+ pointOffset,
2233
+ pointCount,
2234
+ state.typedExtraBytes
2235
+ );
2236
+ }
2237
+ function getLAZStreamingDecodeStats(options) {
2238
+ return options.las?.lazStreamingStats;
2239
+ }
2240
+ function recordReadBytesStats(reader, byteLength, stats) {
2241
+ if (!stats) {
2242
+ return;
2243
+ }
2244
+ const bufferOffsets = reader.findBufferOffsets(byteLength);
2245
+ if (bufferOffsets && bufferOffsets.length > 1) {
2246
+ stats.copiedBytes += byteLength;
2247
+ stats.chunkConcatenations++;
2248
+ }
2249
+ }
2250
+ function recordDecodedChunkAllocation(byteLength, stats) {
2251
+ if (stats) {
2252
+ stats.copiedBytes += byteLength;
2253
+ stats.decodedChunkAllocations++;
2254
+ }
2255
+ }
2256
+ function* appendDecodedLAZChunk(compressedChunk, metadata, header, state) {
2257
+ const pointRecordLength = header.pointsStructSize;
2258
+ const decoder = (0, import_loader_utils.createLAZChunkDecoderCursor)(compressedChunk, metadata);
2259
+ while (decoder.remainingPointCount > 0) {
2260
+ const batchCapacity = state.rawBatch.byteLength / pointRecordLength;
2261
+ const batchRemainingPointCount = batchCapacity - state.batchPointCount;
2262
+ const pointsDecoded = decoder.decodeInto(
2263
+ state.rawBatch,
2264
+ state.batchPointCount * pointRecordLength,
2265
+ batchRemainingPointCount
2266
+ );
2267
+ state.batchPointCount += pointsDecoded;
2268
+ if (state.batchPointCount === batchCapacity) {
2269
+ const batch = flushRawPointBatch(header, state);
2270
+ if (batch) {
2271
+ yield batch;
2272
+ }
2273
+ }
2274
+ }
2275
+ }
2276
+ function* appendRawPointChunk(rawChunk, header, state) {
2277
+ const pointRecordLength = header.pointsStructSize;
2278
+ const chunkPointCount = rawChunk.byteLength / pointRecordLength;
2279
+ for (let chunkPointIndex = 0; chunkPointIndex < chunkPointCount; chunkPointIndex++) {
2280
+ const sourceOffset = chunkPointIndex * pointRecordLength;
2281
+ const targetOffset = state.batchPointCount * pointRecordLength;
2282
+ state.rawBatch.set(
2283
+ rawChunk.subarray(sourceOffset, sourceOffset + pointRecordLength),
2284
+ targetOffset
2285
+ );
2286
+ state.batchPointCount++;
2287
+ if (state.batchPointCount === state.rawBatch.byteLength / pointRecordLength) {
2288
+ const batch = flushRawPointBatch(header, state);
2289
+ if (batch) {
2290
+ yield batch;
2291
+ }
2292
+ }
2293
+ }
2294
+ }
2295
+ function flushRawPointBatch(header, state) {
2296
+ if (state.batchPointCount === 0) {
2297
+ return null;
2298
+ }
2299
+ const byteLength = state.batchPointCount * header.pointsStructSize;
2300
+ const fullBatch = byteLength === state.rawBatch.byteLength;
2301
+ const arrayBuffer = fullBatch ? state.rawBatch.buffer : state.rawBatch.buffer.slice(0, byteLength);
2302
+ state.totalRead += state.batchPointCount;
2303
+ const batchHeader = {
2304
+ ...header,
2305
+ pointsOffset: 0,
2306
+ pointsCount: state.batchPointCount,
2307
+ totalRead: state.totalRead
2308
+ };
2309
+ state.batchPointCount = 0;
2310
+ if (fullBatch) {
2311
+ state.rawBatch = new Uint8Array(state.rawBatch.byteLength);
2312
+ state.rawBatchAllocations++;
2313
+ if (state.stats) {
2314
+ state.stats.rawBatchAllocations++;
2315
+ }
2316
+ }
2317
+ return { arrayBuffer, header: batchHeader };
2318
+ }
2319
+ function flushPointDataBatch(header, state, options) {
2320
+ if (state.batchPointCount === 0) {
2321
+ return null;
2322
+ }
2323
+ state.totalRead += state.batchPointCount;
2324
+ const batchHeader = {
2325
+ ...header,
2326
+ pointsOffset: 0,
2327
+ pointsCount: state.batchPointCount,
2328
+ totalRead: state.totalRead
2329
+ };
2330
+ const batchPointCount = state.batchPointCount;
2331
+ const fullBatch = batchPointCount === state.batchCapacity;
2332
+ const positions = fullBatch ? state.positions : state.positions.subarray(0, batchPointCount * 3);
2333
+ const intensities = state.intensities ? fullBatch ? state.intensities : state.intensities.subarray(0, batchPointCount) : null;
2334
+ const classifications = state.classifications ? fullBatch ? state.classifications : state.classifications.subarray(0, batchPointCount) : null;
2335
+ const syntheticFlags = state.syntheticFlags ? fullBatch ? state.syntheticFlags : state.syntheticFlags.subarray(0, batchPointCount) : null;
2336
+ const keyPointFlags = state.keyPointFlags ? fullBatch ? state.keyPointFlags : state.keyPointFlags.subarray(0, batchPointCount) : null;
2337
+ const withheldFlags = state.withheldFlags ? fullBatch ? state.withheldFlags : state.withheldFlags.subarray(0, batchPointCount) : null;
2338
+ const overlapFlags = state.overlapFlags ? fullBatch ? state.overlapFlags : state.overlapFlags.subarray(0, batchPointCount) : null;
2339
+ const colors = state.colors ? fullBatch ? state.colors : state.colors.subarray(0, batchPointCount * 4) : state.rawColors ? convertRawColorsToUint8(state.rawColors, batchPointCount, options) : null;
2340
+ const gpsTimes = state.gpsTimes ? fullBatch ? state.gpsTimes : state.gpsTimes.subarray(0, batchPointCount) : null;
2341
+ const nir = state.nir ? fullBatch ? state.nir : state.nir.subarray(0, batchPointCount) : null;
2342
+ const scanAngles = state.scanAngles ? fullBatch ? state.scanAngles : state.scanAngles.subarray(0, batchPointCount) : null;
2343
+ const userData = state.userData ? fullBatch ? state.userData : state.userData.subarray(0, batchPointCount) : null;
2344
+ const pointSourceIds = state.pointSourceIds ? fullBatch ? state.pointSourceIds : state.pointSourceIds.subarray(0, batchPointCount) : null;
2345
+ const returnNumbers = state.returnNumbers ? fullBatch ? state.returnNumbers : state.returnNumbers.subarray(0, batchPointCount) : null;
2346
+ const numberOfReturns = state.numberOfReturns ? fullBatch ? state.numberOfReturns : state.numberOfReturns.subarray(0, batchPointCount) : null;
2347
+ const scannerChannels = state.scannerChannels ? fullBatch ? state.scannerChannels : state.scannerChannels.subarray(0, batchPointCount) : null;
2348
+ const scanDirectionFlags = state.scanDirectionFlags ? fullBatch ? state.scanDirectionFlags : state.scanDirectionFlags.subarray(0, batchPointCount) : null;
2349
+ const edgeOfFlightLines = state.edgeOfFlightLines ? fullBatch ? state.edgeOfFlightLines : state.edgeOfFlightLines.subarray(0, batchPointCount) : null;
2350
+ const waveforms = state.waveforms ? fullBatch ? state.waveforms : state.waveforms.subarray(0, batchPointCount * 29) : null;
2351
+ const extraByteCount = state.extraBytes ? state.extraBytes.length / state.batchCapacity : 0;
2352
+ const extraBytes = state.extraBytes ? fullBatch ? state.extraBytes : state.extraBytes.subarray(0, batchPointCount * extraByteCount) : null;
2353
+ const typedExtraBytes = state.typedExtraBytes ? state.typedExtraBytes.map((attribute) => ({
2354
+ ...attribute,
2355
+ value: fullBatch ? attribute.value : attribute.value.subarray(0, batchPointCount * attribute.size)
2356
+ })) : null;
2357
+ const table = makeLASArrowTableFromAttributes(
2358
+ batchHeader,
2359
+ positions,
2360
+ colors,
2361
+ intensities,
2362
+ classifications,
2363
+ syntheticFlags,
2364
+ keyPointFlags,
2365
+ withheldFlags,
2366
+ overlapFlags,
2367
+ gpsTimes,
2368
+ nir,
2369
+ scanAngles,
2370
+ userData,
2371
+ pointSourceIds,
2372
+ returnNumbers,
2373
+ numberOfReturns,
2374
+ scannerChannels,
2375
+ scanDirectionFlags,
2376
+ edgeOfFlightLines,
2377
+ waveforms,
2378
+ extraBytes,
2379
+ typedExtraBytes
2380
+ );
2381
+ state.batchPointCount = 0;
2382
+ if (fullBatch) {
2383
+ const PositionsType = options.las?.fp64 ? Float64Array : Float32Array;
2384
+ state.positions = new PositionsType(state.positions.length);
2385
+ state.colors = state.colors ? new Uint8Array(state.colors.length) : null;
2386
+ state.rawColors = state.rawColors ? new Uint16Array(state.rawColors.length) : null;
2387
+ state.intensities = state.intensities ? new Uint16Array(state.intensities.length) : null;
2388
+ state.classifications = state.classifications ? new Uint8Array(state.classifications.length) : null;
2389
+ state.syntheticFlags = state.syntheticFlags ? new Uint8Array(state.syntheticFlags.length) : null;
2390
+ state.keyPointFlags = state.keyPointFlags ? new Uint8Array(state.keyPointFlags.length) : null;
2391
+ state.withheldFlags = state.withheldFlags ? new Uint8Array(state.withheldFlags.length) : null;
2392
+ state.overlapFlags = state.overlapFlags ? new Uint8Array(state.overlapFlags.length) : null;
2393
+ state.gpsTimes = state.gpsTimes ? new Float64Array(state.gpsTimes.length) : null;
2394
+ state.nir = state.nir ? new Uint16Array(state.nir.length) : null;
2395
+ state.scanAngles = state.scanAngles ? new Int16Array(state.scanAngles.length) : null;
2396
+ state.userData = state.userData ? new Uint8Array(state.userData.length) : null;
2397
+ state.pointSourceIds = state.pointSourceIds ? new Uint16Array(state.pointSourceIds.length) : null;
2398
+ state.returnNumbers = state.returnNumbers ? new Uint8Array(state.returnNumbers.length) : null;
2399
+ state.numberOfReturns = state.numberOfReturns ? new Uint8Array(state.numberOfReturns.length) : null;
2400
+ state.scannerChannels = state.scannerChannels ? new Uint8Array(state.scannerChannels.length) : null;
2401
+ state.scanDirectionFlags = state.scanDirectionFlags ? new Uint8Array(state.scanDirectionFlags.length) : null;
2402
+ state.edgeOfFlightLines = state.edgeOfFlightLines ? new Uint8Array(state.edgeOfFlightLines.length) : null;
2403
+ state.waveforms = state.waveforms ? new Uint8Array(state.waveforms.length) : null;
2404
+ state.extraBytes = state.extraBytes ? new Uint8Array(state.extraBytes.length) : null;
2405
+ state.typedExtraBytes = state.typedExtraBytes ? state.typedExtraBytes.map((attribute) => ({
2406
+ ...attribute,
2407
+ value: (0, import_las_extra_bytes.createLASTypedExtraBytesValue)(
2408
+ attribute.scalarDataType,
2409
+ attribute.value.length,
2410
+ attribute.outputFloat64
2411
+ )
2412
+ })) : null;
2413
+ state.typedExtraBytesSource = state.typedExtraBytesSource ? new Uint8Array(state.typedExtraBytesSource.length) : null;
2414
+ state.target.positions = state.positions;
2415
+ state.target.colors = state.colors;
2416
+ state.target.rawColors = state.rawColors;
2417
+ state.target.intensities = state.intensities;
2418
+ state.target.classifications = state.classifications;
2419
+ state.target.syntheticFlags = state.syntheticFlags;
2420
+ state.target.keyPointFlags = state.keyPointFlags;
2421
+ state.target.withheldFlags = state.withheldFlags;
2422
+ state.target.overlapFlags = state.overlapFlags;
2423
+ state.target.gpsTimes = state.gpsTimes;
2424
+ state.target.nir = state.nir;
2425
+ state.target.scanAngles = state.scanAngles;
2426
+ state.target.userData = state.userData;
2427
+ state.target.pointSourceIds = state.pointSourceIds;
2428
+ state.target.returnNumbers = state.returnNumbers;
2429
+ state.target.numberOfReturns = state.numberOfReturns;
2430
+ state.target.scannerChannels = state.scannerChannels;
2431
+ state.target.scanDirectionFlags = state.scanDirectionFlags;
2432
+ state.target.edgeOfFlightLines = state.edgeOfFlightLines;
2433
+ state.target.waveforms = state.waveforms;
2434
+ state.compatibilityExtraBytesSource = state.compatibilityExtraBytesSource ? new Uint8Array(state.compatibilityExtraBytesSource.length) : null;
2435
+ state.target.extraBytes = state.extraBytes || state.typedExtraBytesSource || state.compatibilityExtraBytesSource;
2436
+ }
2437
+ return table;
2438
+ }
2439
+ function getLASColumnSelection(options) {
2440
+ const columns = options.las?.columns;
2441
+ if (!columns) {
2442
+ return {
2443
+ intensity: true,
2444
+ classification: true,
2445
+ synthetic: true,
2446
+ keyPoint: true,
2447
+ withheld: true,
2448
+ overlap: true,
2449
+ color: true,
2450
+ gpsTime: true,
2451
+ nir: true,
2452
+ scanAngle: true,
2453
+ userData: true,
2454
+ pointSourceId: true,
2455
+ returnNumber: true,
2456
+ numberOfReturns: true,
2457
+ scannerChannel: true,
2458
+ scanDirectionFlag: true,
2459
+ edgeOfFlightLine: true,
2460
+ waveform: true,
2461
+ extraBytes: options.las?.extraBytes === "typed"
2462
+ };
2463
+ }
2464
+ let intensity = false;
2465
+ let classification = false;
2466
+ let synthetic = false;
2467
+ let keyPoint = false;
2468
+ let withheld = false;
2469
+ let overlap = false;
2470
+ let color = false;
2471
+ let gpsTime = false;
2472
+ let nir = false;
2473
+ let scanAngle = false;
2474
+ let userData = false;
2475
+ let pointSourceId = false;
2476
+ let returnNumber = false;
2477
+ let numberOfReturns = false;
2478
+ let scannerChannel = false;
2479
+ let scanDirectionFlag = false;
2480
+ let edgeOfFlightLine = false;
2481
+ let waveform = false;
2482
+ let extraBytes = false;
2483
+ for (const column of columns) {
2484
+ switch (column) {
2485
+ case "POSITION":
2486
+ break;
2487
+ case "intensity":
2488
+ intensity = true;
2489
+ break;
2490
+ case "classification":
2491
+ classification = true;
2492
+ break;
2493
+ case "synthetic":
2494
+ synthetic = true;
2495
+ break;
2496
+ case "keyPoint":
2497
+ keyPoint = true;
2498
+ break;
2499
+ case "withheld":
2500
+ withheld = true;
2501
+ break;
2502
+ case "overlap":
2503
+ overlap = true;
2504
+ break;
2505
+ case "COLOR_0":
2506
+ color = true;
2507
+ break;
2508
+ case "GPS_TIME":
2509
+ gpsTime = true;
2510
+ break;
2511
+ case "NIR":
2512
+ nir = true;
2513
+ break;
2514
+ case "scanAngle":
2515
+ scanAngle = true;
2516
+ break;
2517
+ case "userData":
2518
+ userData = true;
2519
+ break;
2520
+ case "pointSourceId":
2521
+ pointSourceId = true;
2522
+ break;
2523
+ case "returnNumber":
2524
+ returnNumber = true;
2525
+ break;
2526
+ case "numberOfReturns":
2527
+ numberOfReturns = true;
2528
+ break;
2529
+ case "scannerChannel":
2530
+ scannerChannel = true;
2531
+ break;
2532
+ case "scanDirectionFlag":
2533
+ scanDirectionFlag = true;
2534
+ break;
2535
+ case "edgeOfFlightLine":
2536
+ edgeOfFlightLine = true;
2537
+ break;
2538
+ case "WAVEFORM":
2539
+ waveform = true;
2540
+ break;
2541
+ case "EXTRA_BYTES":
2542
+ extraBytes = true;
2543
+ break;
2544
+ default:
2545
+ throw new Error(`LASLoader: unsupported column ${column}`);
2546
+ }
2547
+ }
2548
+ return {
2549
+ intensity,
2550
+ classification,
2551
+ synthetic,
2552
+ keyPoint,
2553
+ withheld,
2554
+ overlap,
2555
+ color,
2556
+ gpsTime,
2557
+ nir,
2558
+ scanAngle,
2559
+ userData,
2560
+ pointSourceId,
2561
+ returnNumber,
2562
+ numberOfReturns,
2563
+ scannerChannel,
2564
+ scanDirectionFlag,
2565
+ edgeOfFlightLine,
2566
+ waveform,
2567
+ extraBytes
2568
+ };
2569
+ }
2570
+ function convertRawColorsToUint8(rawColors, pointCount, options) {
2571
+ const colors = new Uint8Array(pointCount * 4);
2572
+ const packedColors = new Uint32Array(colors.buffer);
2573
+ const twoByteColor = detectTwoByteRawColors(rawColors, pointCount, options.las?.colorDepth);
2574
+ if (twoByteColor) {
2575
+ for (let pointIndex = 0; pointIndex < pointCount; pointIndex++) {
2576
+ const sourceOffset = pointIndex * 3;
2577
+ const red = rawColors[sourceOffset] >> 8 & 255;
2578
+ const green = rawColors[sourceOffset + 1] >> 8 & 255;
2579
+ const blue = rawColors[sourceOffset + 2] >> 8 & 255;
2580
+ packedColors[pointIndex] = 4278190080 | blue << 16 | green << 8 | red;
2581
+ }
2582
+ } else {
2583
+ for (let pointIndex = 0; pointIndex < pointCount; pointIndex++) {
2584
+ const sourceOffset = pointIndex * 3;
2585
+ const red = rawColors[sourceOffset] & 255;
2586
+ const green = rawColors[sourceOffset + 1] & 255;
2587
+ const blue = rawColors[sourceOffset + 2] & 255;
2588
+ packedColors[pointIndex] = 4278190080 | blue << 16 | green << 8 | red;
2589
+ }
2590
+ }
2591
+ return colors;
2592
+ }
2593
+ function detectTwoByteRawColors(rawColors, pointCount, colorDepth) {
2594
+ if (colorDepth === 8) {
2595
+ return false;
2596
+ }
2597
+ if (colorDepth === 16) {
2598
+ return true;
2599
+ }
2600
+ if (colorDepth !== "auto") {
2601
+ return false;
2602
+ }
2603
+ for (let index = 0; index < pointCount * 3; index++) {
2604
+ if (rawColors[index] > 255) {
2605
+ return true;
2606
+ }
2607
+ }
2608
+ return false;
2609
+ }
2610
+ function readNullTerminatedAscii(bytes, offset, length) {
2611
+ let end = offset;
2612
+ const maxEnd = offset + length;
2613
+ while (end < maxEnd && bytes[end] !== 0) {
2614
+ end++;
2615
+ }
2616
+ return String.fromCharCode(...bytes.subarray(offset, end));
2617
+ }
2618
+ function getHeaderBoundingBox(header) {
2619
+ const minimum = header.mins || [0, 0, 0];
2620
+ const maximum = header.maxs || [0, 0, 0];
2621
+ return [
2622
+ [minimum[0], minimum[1], minimum[2]],
2623
+ [maximum[0], maximum[1], maximum[2]]
2624
+ ];
2625
+ }
2626
+ function* readAvailablePointBatches(pending, absoluteOffset, header, sourcePointIndex, totalRead, batchSize) {
2627
+ while (sourcePointIndex < header.pointsCount && totalRead < header.totalToRead) {
2628
+ const batch = readAvailableContiguousPointBatch(
2629
+ pending,
2630
+ absoluteOffset,
2631
+ header,
2632
+ sourcePointIndex,
2633
+ totalRead,
2634
+ batchSize
2635
+ );
2636
+ if (!batch) {
2637
+ return;
2638
+ }
2639
+ pending = batch.pending;
2640
+ absoluteOffset = batch.absoluteOffset;
2641
+ sourcePointIndex = batch.sourcePointIndex;
2642
+ totalRead = batch.totalRead;
2643
+ yield batch;
2644
+ }
2645
+ }
2646
+ function readAvailableContiguousPointBatch(pending, absoluteOffset, header, sourcePointIndex, totalRead, batchSize) {
2647
+ const pointRecordLength = header.pointsStructSize;
2648
+ const pointAbsoluteOffset = header.pointsOffset + sourcePointIndex * pointRecordLength;
2649
+ const pointPendingOffset = pointAbsoluteOffset - absoluteOffset;
2650
+ if (pointPendingOffset < 0) {
2651
+ throw new Error("LASLoader: invalid streaming point offset");
2652
+ }
2653
+ if (pointPendingOffset + pointRecordLength > pending.byteLength) {
2654
+ return null;
2655
+ }
2656
+ const availablePointCount = Math.floor(
2657
+ (pending.byteLength - pointPendingOffset) / pointRecordLength
2658
+ );
2659
+ const batchPointCount = Math.min(
2660
+ batchSize,
2661
+ availablePointCount,
2662
+ header.pointsCount - sourcePointIndex,
2663
+ header.totalToRead - totalRead
2664
+ );
2665
+ if (batchPointCount <= 0) {
2666
+ return null;
2667
+ }
2668
+ sourcePointIndex += batchPointCount;
2669
+ totalRead += batchPointCount;
2670
+ const batchHeader = {
2671
+ ...header,
2672
+ pointsOffset: pending.byteOffset + pointPendingOffset,
2673
+ pointsCount: batchPointCount,
2674
+ totalRead
2675
+ };
2676
+ const nextPointOffset = header.pointsOffset + sourcePointIndex * pointRecordLength;
2677
+ const discardByteCount = Math.max(
2678
+ 0,
2679
+ Math.min(pending.byteLength, nextPointOffset - absoluteOffset)
2680
+ );
2681
+ return {
2682
+ arrayBuffer: pending.buffer,
2683
+ header: batchHeader,
2684
+ pending: pending.subarray(discardByteCount),
2685
+ absoluteOffset: absoluteOffset + discardByteCount,
2686
+ sourcePointIndex,
2687
+ totalRead
2688
+ };
2689
+ }
2690
+ function tryParseHeader(pending, absoluteOffset) {
2691
+ if (absoluteOffset !== 0 || pending.byteLength < 227) {
2692
+ return null;
2693
+ }
2694
+ const dataView = new DataView(pending.buffer, pending.byteOffset, pending.byteLength);
2695
+ if (dataView.getUint32(0, true) !== LASF_SIGNATURE) {
2696
+ throw new Error("LASLoader: invalid LAS header");
2697
+ }
2698
+ const headerLength = dataView.getUint32(96, true);
2699
+ if (pending.byteLength < Math.max(headerLength, 255)) {
2700
+ return null;
2701
+ }
2702
+ const header = parseLASHeader(
2703
+ pending.buffer.slice(pending.byteOffset, pending.byteOffset + pending.byteLength)
2704
+ );
2705
+ return header;
2706
+ }
2707
+ function concatenateUint8Arrays(first, second) {
2708
+ if (first.byteLength === 0) {
2709
+ return second;
2710
+ }
2711
+ const result = new Uint8Array(first.byteLength + second.byteLength);
2712
+ result.set(first);
2713
+ result.set(second, first.byteLength);
2714
+ return result;
2715
+ }
2716
+ function toUint8Array(data) {
2717
+ const source = ArrayBuffer.isView(data) ? new Uint8Array(data.buffer, data.byteOffset, data.byteLength) : new Uint8Array(data);
2718
+ const copy = new Uint8Array(source.byteLength);
2719
+ copy.set(source);
2720
+ return copy;
2721
+ }
2722
+ function toAsyncIterator(data) {
2723
+ if (Symbol.asyncIterator in data) {
2724
+ return data[Symbol.asyncIterator]();
2725
+ }
2726
+ const iterator = data[Symbol.iterator]();
2727
+ return {
2728
+ async next() {
2729
+ return iterator.next();
2730
+ }
2731
+ };
2732
+ }
2733
+ function readLAZChunkTableOffset(dataView, pointDataOffset) {
2734
+ if (isNegativeOneUint64(dataView, pointDataOffset)) {
2735
+ if (dataView.byteLength < LAZ_CHUNK_TABLE_POINTER_LENGTH) {
2736
+ return 0;
2737
+ }
2738
+ return readUint64(dataView, dataView.byteLength - LAZ_CHUNK_TABLE_POINTER_LENGTH);
2739
+ }
2740
+ return readUint64(dataView, pointDataOffset);
2741
+ }
2742
+ function readStreamedLAZChunkTableOffset(dataView) {
2743
+ return isNegativeOneUint64(dataView, 0) ? -1 : readUint64(dataView, 0);
2744
+ }
2745
+ function isNegativeOneUint64(dataView, byteOffset) {
2746
+ return dataView.byteLength >= byteOffset + 8 && dataView.getUint32(byteOffset, true) === 4294967295 && dataView.getUint32(byteOffset + 4, true) === 4294967295;
2747
+ }
2748
+ function readUint64(dataView, byteOffset) {
2749
+ if (dataView.byteLength < byteOffset + 8) {
2750
+ return 0;
2751
+ }
2752
+ const low = dataView.getUint32(byteOffset, true);
2753
+ const high = dataView.getUint32(byteOffset + 4, true);
2754
+ return high * 2 ** 32 + low;
2755
+ }
2756
+ var LAS_1_4_HEADER_LENGTH = LAS_14_HEADER_LENGTH;
2757
+ // Annotate the CommonJS export names for ESM import in node:
2758
+ 0 && (module.exports = {
2759
+ LAS_1_4_HEADER_LENGTH,
2760
+ decodeLAZChunkToArrowTable,
2761
+ decodeLAZFileInBatches,
2762
+ parseLAS,
2763
+ parseLASChunkedIterator,
2764
+ parseLASHeader,
2765
+ parseLASInBatches
2766
+ });
2767
+ //# sourceMappingURL=parse-las.cjs.map