mirror of
https://github.com/storytold/pdfcraft.git
synced 2026-11-06 18:52:36 +00:00
Review fix from #6087. tess_3d charged one element per triangle, but each triangle also holds its normal-slot corners and one corner triple per texture set any face of the mesh uses, up to eight. Faces reusing one index range could so allocate well past the 128 MiB the element ceiling documents. Each face's triangles are now charged in 8-byte elements for everything they hold (corners, normal slots, texture triples, style) before the face is triangulated. Tests, each shown failing with the fix reverted: reused_textured_faces_are_charged_for_every_corner_array, faces_reusing_one_index_range_are_charged_for_each_triangle_they_make. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SqmHYx8FiWM5PcsoiErgp9
pdfcraft-prc
A reader for PRC (ISO 14739-1), the 3D model format a PDF /3D stream of /Subtype /PRC carries (ISO 32000-2 §13.6.3).
- Layer: L0, standalone. No dependency on any other PdfCraft crate.
- Licence: MIT OR Apache-2.0. Inflation through
flate2with the pure-Rustminiz_oxidebackend. #![forbid(unsafe_code)]. Never panics on input: inflated bytes, decoded elements, schema steps and walk depth are capped, and damage returnsPrcError.
API
PrcFile::parse(data) -> Result<PrcFile, PrcError> // header, file structures, model file
PrcFile::parse_with_limit(data, max_inflated) -> Result<PrcFile, PrcError>
FileStructure::section(SectionKind) -> &[u8] // inflated globals / tree / tessellation / geometry / extra geometry
FileStructure::schema() -> Result<Schema, PrcError> // the globals section's leading schema
FileStructure::tessellations() -> Result<Vec<Tessellation>, PrcError> // meshes, wires, markups, compressed meshes
PrcFile::placements() / placements_with(StyleAlpha, EntityOverrides) -> Result<Vec<Placement>, PrcError>
PrcFile::model_tree() -> Result<Vec<ModelNode>, PrcError> // the assembly tree as a model-tree panel lists it
Placement::triangle_colours(&TriangleMesh) -> Option<Vec<Option<Rgba>>>
TriangleMesh::transformed(&Matrix) -> TriangleMesh
Schema::read(&mut BitReader) / Schema::skip_added_fields(entity_type, &mut BitReader)
BitReader: bit, bits, character, unsigned_integer, integer, integer_vbn, double_vbn, nbits_then_unsigned, string, float_as_bytes, double
MAX_INFLATED_BYTES(512 MiB) bounds every section together;TooLargereports the limit hit.MAX_DECODED_ELEMENTS(2^24) bounds the array elements one pass decodes (a tree walk, or onetessellationscall), since a single bit can decode to a 4-8 byte element;TooManyElementsreports it.- Schema programs (how a newer producer describes fields it added) run under a nesting ceiling (64) and
MAX_SCHEMA_STEPS(2^22), shared likeMAX_DECODED_ELEMENTSby every program one pass runs. Unsupportednames constructs the reader cannot step over (schema pointer fields,Value_CurveIs3D).Tessellation::Meshis aTriangleMesh: positions, triangles, one triangle range per face, the stored normals and texture coordinates with each triangle's corner indices into them, and per-triangle line-attribute styles.Wireis polylines;Markupis read past.Tessellation::Compressedis read to its end so later entities decode; its triangles are not rebuilt yet.- A face may carry at most 8 texture-coordinate sets; more is
Malformed. Optimised vertex colours areUnsupported. - The product tree: each drawable tessellation placed by its occurrence path's locations and the item's coordinate
systems (a 4x4
Matrix), coloured by the style inheritance rules, with occurrences' entity references applied (EntityOverrides: subtree, everywhere or ignored) and style transparency combined with material alpha byStyleAlpha. A prototype's part is coloured by its own file structure's styles. EachModelNodelists its name, where the name came from, its visibility and the range of placements it drew. - Occurrence and prototype cycles are
Malformed; the walk is capped at depth 64, 2^20 visits andMAX_PLACEMENTS. - A tree's markups (PMI), views, scene lights and clipping planes are read past, not modelled; so are textures.
- Not yet in the crate: rebuilding compressed meshes, textures.
- The
Doublecode table's rows come from prc-rs (MIT); its notice is insrc/acof/table.rs. A few reading choices also follow prc-rs; each is marked// prc-rs:in the source.