/** * E57 binary-section decoder for a single Data3D scan. * * Walks DataPackets at `entry.binaryFileOffset` (in the LOGICAL * post-CRC view) and decodes per-record bytestreams as Float32 / * Float64 / Integer / ScaledInteger columns. ScaledInteger is a * bit-packed integer with a per-field scale + offset (E57 spec * §6.3.4) — common in Faro / Trimble / Leica exports. */ import type { DecodedPointChunk, PointCloudBBox } from '../types.js'; import { type Data3DEntry, type PrototypeField } from './e57-xml.js'; /** * Resolved prototype field set for one scan: the cartesian axes (always * present, validated) plus the optional colour / intensity / * classification channels and the predicates that decide which output * buffers to allocate. Shared by the whole-file (`decodeE57Scan`) and * the streaming (`E57StreamingSource`) decoders so both agree on which * channels a scan carries. */ export interface ScanFieldSet { xField: PrototypeField; yField: PrototypeField; zField: PrototypeField; rField?: PrototypeField; gField?: PrototypeField; bField?: PrototypeField; /** colorRed/Green/Blue all present → emit a colours buffer. */ hasRgb: boolean; iField?: PrototypeField; /** intensity present (any supported kind) → emit an intensities buffer. */ hasIntensity: boolean; cField?: PrototypeField; /** classification present as Integer/ScaledInteger → emit a class buffer. */ hasClassification: boolean; } /** * Validate + resolve a scan's prototype into a `ScanFieldSet`. Throws on * a missing or plain-Integer cartesian axis (only Float / ScaledInteger * cartesian is supported — see the inline note below). */ export declare function resolveScanFields(prototype: PrototypeField[]): ScanFieldSet; /** Lightweight 4-byte DataPacket header peek (type + total logical length). */ export interface PacketHeaderPeek { /** packetType: 1=data, 2=index, 3=empty. */ packetType: number; /** Total packet length in logical bytes (header field + 1). */ packetLength: number; } /** * Read a DataPacket's 4-byte header without decoding its payload. The * streaming reader uses this to learn a packet's length up front so it * can decide whether the packet fits in the current window before * committing to decode it. * * Packet header (4 bytes): * byte 0: packetType (1=data, 2=index, 3=empty) * byte 1: packetFlags (bit 0 = compressorRestart) * bytes 2-3: packetLogicalLength - 1 (LE u16; total packet bytes minus 1) */ export declare function peekPacketHeader(view: DataView, offset: number): PacketHeaderPeek; /** Result of decoding a single DataPacket. */ export interface DecodedPacket { /** packetType: 1=data (positions populated), 2/3=skip (take=0). */ packetType: number; /** Total packet length in logical bytes — advance the cursor by this. */ packetLength: number; /** Records decoded into the channel buffers (0 for non-data packets). */ take: number; /** take*3 cartesian floats (data packets only). */ positions?: Float32Array; /** take*3 colour floats when the scan carries RGB. */ colors?: Float32Array; /** take intensities when the scan carries intensity. */ intensities?: Uint16Array; /** take classifications when the scan carries them. */ classifications?: Uint8Array; } /** * Decode ONE DataPacket at `offset` in the logical-byte view `logical`. * * Non-data packets (index/empty) return `{ packetType, packetLength, * take: 0 }` so the caller can skip them by `packetLength`. Data packets * decode up to `maxRecords` consecutive records into freshly-allocated, * tightly-sized channel buffers — the caller owns striding, pose, and * concatenation. * * Callers must ensure `offset + 4 <= logical.length` (header readable) * before calling; this function then bounds-checks the full packet * against `logical.length` for data packets. */ export declare function decodeE57Packet(logical: Uint8Array, view: DataView, offset: number, fields: ScanFieldSet, prototype: PrototypeField[], maxRecords: number): DecodedPacket; /** * Decode the binary section starting at `entry.binaryFileOffset` in the * logical-bytes view. NOTE: `binaryFileOffset` here must already point * at the first DataPacket (i.e. AFTER the 32-byte CompressedVector * section header) — `decodeE57` does this conversion via * `resolveCompressedVectorDataOffset`. Callers passing the raw XML * offset directly will see a "bytestreamCount ≠ prototype length" * mismatch. * * Supports Float (single/double), ScaledInteger (bit-packed integer * with scale/offset), and Integer for cartesianX/Y/Z + colorRed/ * Green/Blue + intensity. Other prototype fields are honoured for * stride math but discarded. * * Whole-file path: holds the entire scan in memory. The streaming * `E57StreamingSource` shares the per-packet primitives above but reads * the binary section incrementally so multi-GB files don't allocate the * whole file at once. */ export declare function decodeE57Scan(logical: Uint8Array, entry: Data3DEntry): DecodedPointChunk; export declare function computeBBox(positions: Float32Array): PointCloudBBox; //# sourceMappingURL=e57-decode.d.ts.map