UNPKG

ply-js

Version:

A TypeScript port based on python-plyfile for reading and writing .ply files

73 lines (72 loc) 3.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.readBinaryPly = readBinaryPly; exports.writeBinaryPly = writeBinaryPly; const header_1 = require("./header"); const element_1 = require("./element"); const data_1 = require("./data"); const utils_1 = require("./utils"); /** * Read a binary or ASCII PLY from a Buffer and return a fully parsed PlyData. * This is the root-level implementation previously living under src/core. */ function readBinaryPly(buffer) { // Use a buffer-backed reader so we correctly locate the header end without relying on ascii search let offset = 0; const rawReader = { read(n) { if (offset >= buffer.length) return null; const end = Math.min(offset + n, buffer.length); const chunk = buffer.slice(offset, end); offset = end; return chunk; } }; const reader = { read(n) { const r = rawReader.read(n); return r === null ? '' : r; } }; const headerLines = []; // collect header lines using PlyHeaderLines // eslint-disable-next-line @typescript-eslint/no-var-requires const { PlyHeaderLines } = require('./header'); for (const l of new PlyHeaderLines(reader)) headerLines.push(l); const headerEnd = offset; // reader advanced past header // parser expects lines after the initial 'ply' line const parser = new header_1.PlyHeaderParser(headerLines); const elements = parser.elements.map(e => new element_1.PlyElement(e.name, e.properties, e.count, e.comments)); const pd = new data_1.PlyData(elements, parser.format === 'ascii', utils_1.byteOrderMap[parser.format] ?? '=', parser.comments, parser.objInfo); const dataBuf = buffer.subarray(headerEnd); let cursor = 0; for (const elt of pd.elements) { if (pd.text) { // ASCII: slice lines for this element const s = dataBuf.subarray(cursor).toString('utf8'); elt._read(Buffer.from(s, 'utf8'), true, pd.byteOrder, undefined, {}); // we don't advance cursor for ASCII (we passed full tail each time) } else { const bufSlice = dataBuf.subarray(cursor); const consumed = elt._read(bufSlice, false, pd.byteOrder, undefined, {}); if (typeof consumed !== 'number') throw new Error(`element ${elt.name} did not return consumed byte count`); cursor += consumed; } } return pd; } /** * Serialize a PlyData into a binary Buffer. If ply.text is true this will * still write an ASCII PLY; for binary output ensure ply.text === false. */ function writeBinaryPly(ply) { const header = ply.header + '\n'; const out = []; out.push(Buffer.from(header, 'ascii')); for (const elt of ply.elements) { const chunks = []; elt._write({ push: (b) => { chunks.push(typeof b === 'string' ? Buffer.from(b, 'utf8') : b); } }, ply.text, ply.byteOrder); for (const c of chunks) out.push(c); } return Buffer.concat(out); }