Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- use image::Rgba;
- use ping::dgramsock::ping;
- use std::{
- env,
- net::{IpAddr, Ipv6Addr},
- path::Path,
- sync::Arc,
- thread::{self},
- };
- fn parse_args() -> Result<(String, u16, u16, u8), &'static str> {
- let args: Vec<_> = env::args().collect();
- if args.len() != 4 && args.len() != 5 {
- return Err("Usage: pinger <path> <X> <Y> <thread count>");
- }
- let path = args[1].to_string();
- if !Path::new(&path).exists() {
- return Err("File does not exist");
- }
- let x = args[2].parse::<u16>();
- let y = args[3].parse::<u16>();
- if x.is_err() | y.is_err() {
- return Err("Invalid coordinates");
- }
- let thread_c = if args.len() == 5 {
- args[4].parse().unwrap_or(1)
- } else {
- 1
- };
- Ok((path, x.unwrap(), y.unwrap(), thread_c))
- }
- fn ping_pixel(x: u16, y: u16, r: u8, g: u8, b: u8, a: u8) {
- let addr =
- IpAddr::V6(Ipv6Addr::new(
- 0x2A01,0x4F8,0x1C1E,0x85CD, //address
- x,y, // X, Y
- (r as u16) << 8 | g as u16, // RG
- (b as u16) << 8 | a as u16, // BA
- ));
- // dbg!(addr);
- let _ = ping(addr, None, None, None, None, None);
- }
- fn ping_chunk(
- origin_x: u16,
- origin_y: u16,
- chunk: Arc<Vec<(u32, u32, Rgba<u8>)>>,
- beg: usize,
- end: usize,
- ) {
- for (x, y, pix) in &chunk[beg..end] {
- ping_pixel(
- origin_x + *x as u16,
- origin_y + *y as u16,
- pix[0],
- pix[1],
- pix[2],
- pix[3],
- );
- }
- }
- fn main() {
- let (image, x, y, n) = match parse_args() {
- Ok(tup) => tup,
- Err(msg) => {
- println!("Error: {msg}");
- std::process::exit(1)
- }
- };
- let pixels: Vec<(u32, u32, Rgba<u8>)> = image::open(image)
- .expect("Failed to open the image")
- .to_rgba8()
- .enumerate_pixels()
- .map(|(x, y, p)| (x, y, *p))
- .collect();
- let (chunk, leftover): (u64, u64) = (
- pixels.len() as u64 / n as u64,
- pixels.len() as u64 % n as u64,
- );
- let pixels = Arc::new(pixels);
- let mut threads = Vec::with_capacity(n as usize);
- for i in 0..n as u64 {
- let beg = i * chunk;
- let end = if i != n as u64 - 1 {
- beg + chunk
- } else {
- beg + chunk + leftover
- };
- let pixels = Arc::clone(&pixels);
- threads.push(thread::spawn(move || {
- ping_chunk(x, y, pixels, beg as usize, end as usize);
- }));
- }
- for t in threads {
- let _ = t.join();
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement