pixelbomber 1.2.4

Insanely fast pixelflut client for images and animations
Documentation
use crate::manager::{load_from_video, manage_dynamic};
use manager::manage;
use pixelbomber::{
    feature_detection,
    image_handler::{self, BinaryFormat},
    service::{Host, Service, ServiceBuilder},
    Client,
};

mod arg_handler;
mod camera;
mod manager;

fn main() {
    env_logger::init();
    let mut args = arg_handler::parse();
    let mut image_config = image_handler::ImageConfig {
        width: args.width,
        height: args.height,
        x_offset: args.x,
        y_offset: args.y,
        offset_usage: args.offset,
        gray_usage: args.gray,
        alpha_usage: args.alpha,
        binary: None,
        shuffle: !args.shuffle,
        chunks: args.count.unwrap_or(4) as usize,
        resize: args.resize,
    };

    if args.test_green_screen {
        camera::test_green_screen(&args.image[0]);
        return;
    }

    let mut host = Host::new(
        &args.host,
        if args.listen_manager {None} else {args.bind_addr.take()}
    ).unwrap();
    if args.le_rgba {
        image_config.binary = Some(BinaryFormat::CoordLERGBA)
    }
    if !args.feature_detection && !args.listen_manager {
        let mut client = Client::new(host.new_stream().unwrap());
        let features = feature_detection::feature_detection(&mut client).unwrap();
        let max_width = features.width - args.x;
        image_config.width = Some(image_config.width.unwrap_or(max_width).min(max_width));
        let max_height = features.height - args.y;
        image_config.height = Some(image_config.height.unwrap_or(max_height).min(max_height));
        image_config.offset_usage = image_config.offset_usage || features.offset;
        image_config.gray_usage = image_config.gray_usage || features.px_gray;
        if image_config.binary.is_none() {
            image_config.binary = features.binary;
        }
        println!("Canvas size: {} x {}", features.width, features.height);
        if features.px_gray {
            println!("PX x y gg command supported")
        }
        if features.offset {
            println!("OFFSET command supported")
        }
        if features.binary.is_some() {
            println!("PBxyrgba command supported (binary pixel)")
        }
    }
    if args.image.is_empty() && !args.listen_manager {
        println!("Please specify at least one image path!");
        return;
    }
    let mut converter_threads = 0;
    let mut threads = args.count.unwrap_or(10) as usize;
    let mut closure: Box<dyn FnMut(&mut Service)> =
        if args.image.len() == 1 && (&args.image[0] == "-" || args.image[0] == "/dev/stdin") {
            converter_threads = args.workers;
            Box::new(manage_dynamic(args.continuous))
        } else if args.image.len() == 1 && args.image[0].starts_with("/dev/video") {
            converter_threads = args.workers;
            Box::new(camera::get_callback(
                &args.image[0],
                args.green_screen.clone(),
            ))
        } else if args.video {
            if !args.image.len() == 1 {
                println!("--video only works with exactly one input file");
                return;
            }
            let Some(images) = load_from_video(&args.image[0], image_config, args.workers as usize)
            else {
                return;
            };
            Box::new(manage(images, args.fps))
        }else if args.listen_manager {
            let server = pixelbomber::service::moderator::Client::new(host, args.bind_addr).unwrap();
            host = server.target_host.clone();
            threads = server.threads;
            Box::new(server.start())
        } else {
            let paths = args.image.iter().map(|v| v.as_str()).collect();
            let command_lib = image_handler::load(paths, image_config);
            Box::new(manage(command_lib, args.fps))
        };
    let mut service = ServiceBuilder::new(host)
        .channel_limit(10)
        .converter_threads(converter_threads as usize)
        .image_config(image_config)
        .threads(threads);
    if let Some(port) = args.serve_manager {
        service = service.listen_port(port);
    }
    let mut service = service.build();
    service.loop_callback(closure.as_mut());
    service.stop();
}