pub mod args;
#[cfg(feature = "ico")]
pub mod ico_runner;
#[cfg(feature = "mesh3d")]
pub mod mesh3d_render;
#[cfg(feature = "mesh3d")]
pub mod mesh3d_runner;
pub mod op;
pub mod pdf_runner;
pub mod ping;
pub mod pixel_xform;
pub mod plan_to_job;
pub mod probe;
pub mod raster_io;
pub mod suggest;
pub use op::{AlphaOp, ConvertPlan, Dither, Op, PrintfTemplate, ResizeMode};
use oxideav_core::{Error, RuntimeContext};
pub fn run(args: &[String], ctx: &RuntimeContext) -> Result<(), Error> {
let plan = args::parse(args)?;
if plan.ping {
return ping::run(&plan, ctx);
}
if plan.probe {
return probe::run(&plan, ctx);
}
if pdf_runner::is_pdf_input(&plan.input) {
return pdf_runner::run(&plan);
}
#[cfg(feature = "mesh3d")]
if mesh3d_runner::is_mesh3d_input(&plan.input) {
if plan.output_template.is_some() {
return Err(Error::invalid(format!(
"convert: output '{}' has a `%d` template but 3D scenes are single-document; remove the template",
plan.output
)));
}
if mesh3d_runner::is_mesh3d_output(&plan.output) {
if !plan.ops.is_empty() {
eprintln!(
"convert: note: raster ops ignored on 3D-asset conversion (stl/obj/gltf/glb/mtl/usdz have no pixel grid)"
);
}
return mesh3d_runner::run(&plan.input, &plan.output, &plan.mesh3d_options);
}
if matches!(
raster_io::classify_output(&plan.output),
Ok(raster_io::OutputClass::Raster(_))
) {
return mesh3d_render::run(&plan.input, &plan.output, &plan.ops, &plan.mesh3d_options);
}
let out_ext = plan.output.rsplit('.').next().unwrap_or("");
let hint = suggest::format_hint(out_ext, &["stl", "obj", "gltf", "glb", "mtl", "usdz"]);
return Err(Error::invalid(format!(
"convert: 3D input '{}' must pair with a 3D output (.stl/.obj/.gltf/.glb/.mtl/.usdz) OR a raster output (.png/.jpg/.bmp/.webp); got '{}'{hint}",
plan.input, plan.output
)));
}
#[cfg(feature = "ico")]
if ico_runner::is_ico_output(&plan.output) {
return ico_runner::run(&plan);
}
let job = plan_to_job::plan_to_job(&plan, ctx)?;
let stats = oxideav_pipeline::Executor::new(&job, ctx).run()?;
eprintln!(
"convert: {} packet(s) read, {} frame(s) decoded, {} frame(s) written",
stats.packets_read, stats.frames_decoded, stats.frames_written
);
Ok(())
}