mirror of
https://github.com/storytold/craft-libs.git
synced 2026-11-14 06:22:24 +00:00
* craft-aep: a flat read-only tree index, borrowed text documents, fewer allocations The container part of storytold/effectcraft#3302: - `TreeIndex`: the chunk tree as one flat array in depth-first order, borrowed from the input, for readers that only look. Same chunks counted against the same limits and the same errors as `parse`. An `.aepx` is indexed by `index_aepx` into one buffer. The typed view reads through either tree (`Node`, `Root`, `Project::from_index`). - Chunk parser: each list of siblings is counted, then reserved once. `.aepx`: hex decoded into an output sized once, attribute values without an entity borrowed. `write` reserves the exact output size. - Text documents are parsed into a tree that borrows from the body; the style and paragraph defaults are built once. - Layer markers and Source Text are read where they are stored instead of searched for. - Container accessors that only tests used are removed. What the importer and exporter in EffectCraft reach across the crate boundary is public here: `Root`, `Draft`, `AepxDrafts`, `index_aepx`, `TreeIndex::from_drafts`, `Project::of`, `ProjectSettings::of`, `Node::marker_list`, `Root::file_version` and `saved_by_version`, `StyleRun::SAMPLED`. `TimeBase::NTSC` holds the rates as plain numerator and denominator instead of an EffectCraft type. * craft-aep: one decoder for an effect parameter definition (`Pard`) The container part of storytold/effectcraft#3319: the fields of a `pard` record (type code, name, default, valid range, slider range, popup item count) are read by one type, `Pard`, which `EffectParam` now reads through. It is public so that an exporter's tests can read back what they encode instead of keeping a second decoder. The rest of that PR (import and export bounds, loss reports) is in EffectCraft's importer and exporter. --------- Co-authored-by: vangel76 <vangel1976@googlemail.com>
66 lines
3.1 KiB
Rust
66 lines
3.1 KiB
Rust
//! After Effects project (`.aep`, `.aepx`) container reader and writer.
|
|
//!
|
|
//! An `.aep` is a `RIFX` container (big-endian RIFF) with form type `Egg!`. This crate reads it
|
|
//! into a lossless chunk tree ([`AepFile`]) and writes it back byte for byte. The XML form of a
|
|
//! project (`.aepx`) is read into the same tree by [`read_aepx`]; [`parse_any`] picks the reader
|
|
//! by content. See
|
|
//! `docs/aep-format.md` for the observed format and how it was established (clean room: only
|
|
//! files we generated ourselves, one change per file).
|
|
//!
|
|
//! [`Project::new`] opens a typed, read-only view over the tree: items, compositions
|
|
//! ([`CompHeader`]), layers ([`LayerHeader`], [`Transform`], effects, masks, text documents,
|
|
//! markers), properties, keyframes and footage. Only fields whose layout was verified against the
|
|
//! values the test files were made with are decoded; every accessor returns `None` (or an empty
|
|
//! list) on damaged data instead of failing.
|
|
|
|
#![deny(clippy::unwrap_used, clippy::expect_used, clippy::panic, clippy::unimplemented, clippy::todo, clippy::unreachable)]
|
|
// Ranges and borrowed bytes are passed around as plain tuples, as in EffectCraft, which allows this lint.
|
|
#![allow(clippy::type_complexity)]
|
|
|
|
mod aepx;
|
|
mod arbitrary;
|
|
mod bytes;
|
|
mod camera;
|
|
mod chunk;
|
|
mod effects;
|
|
mod error;
|
|
mod footage;
|
|
mod header;
|
|
pub mod index;
|
|
mod keys;
|
|
mod masks;
|
|
mod matte;
|
|
mod read;
|
|
mod settings;
|
|
mod shapes;
|
|
mod textdoc;
|
|
mod typed;
|
|
mod values;
|
|
mod version;
|
|
mod write;
|
|
|
|
pub use aepx::{AepxDrafts, index_aepx, is_aepx, parse_any, read_aepx, read_aepx_with_limits};
|
|
pub use arbitrary::{
|
|
CURVE_IDENTITY, CryptomatteData, CurvesData, ExtractorChannels, HueSaturationData, LevelsData, MeshData, curve_lut, identifier_channel_type,
|
|
};
|
|
pub use camera::{CameraPosition, DEFAULT_CAMERA_ZOOM};
|
|
pub use chunk::{AepFile, Body, Chunk, LIST, NESTED_IDS, Walk};
|
|
pub use effects::{DefinitionSource, Effect, EffectDefinitions, EffectParam, LayerRef, ParamKind, ParamValue, Pard};
|
|
pub use error::AepError;
|
|
pub use footage::{Footage, PsdLayer, SequenceInfo};
|
|
pub use header::{BlendMode, CompHeader, LayerHeader, LayerType, LightType, Quality, Rational, Renderer};
|
|
pub use index::{Draft, Node, NodeWalk, Nodes, Root, TreeIndex};
|
|
pub use keys::{ExpressionFlags, Interpolation, KeyEase, KeyframeKind, SpatialKey};
|
|
pub use masks::{Mask, MaskAtom, MaskMode, PathVertex, ShapePath};
|
|
pub use matte::{MatteMode, TrackMatte};
|
|
pub use read::{Limits, parse, parse_with_limits};
|
|
pub use settings::{ProjectSettings, TimeDisplay, WorkingSpace};
|
|
pub use shapes::{GradientType, PolystarType, ShapeDetail, ShapeGroup, ShapeItem, Stroke, StrokeCap, StrokeJoin};
|
|
pub use textdoc::{
|
|
AutoKern, Caps, CueType, FontBaseline, Justification, KernRun, Marker, ParagraphRun, StyleRun, TextBox, TextDocument, TextValue, parse_text_dict,
|
|
};
|
|
pub use typed::{Comp, Item, ItemKind, KeyLayout, KeyList, Keyframe, Layer, ListHeader, Project, PropEntry, PropGroup, PropNode, Property, TimeBase};
|
|
pub use values::{Orientation, OrientationKey, TimeRemap, TimeRemapKey, Tracked, Transform, ValueSource};
|
|
pub use version::AeVersion;
|
|
pub use write::{write, write_to};
|