use crate::util::OmError;
use crate::xcassets::appiconset::AppIconSet;
use std::fs::File;
use resize::{Pixel, Type};
use rgb::FromSlice;
pub struct Xcassets {
}
impl Xcassets {
pub fn generate(
input: &str,
mode: &str,
output: &str
) -> Result<u32, OmError>{
let content_json_filename = format!("{}/Contents.json", output);
let mut app_icon_set = match AppIconSet::load( &content_json_filename ) {
Ok( ais ) => ais,
Err( e ) => {
println!("ERROR: AppIconSet::load failed with {:?}", e);
return Err( OmError::Generic( "problem with output file".to_string() ) );
},
};
let decoder = png::Decoder::new(File::open(&input).unwrap());
let mut reader = decoder.read_info().unwrap();
let info = reader.info();
println!("{:#?}", info);
let width = info.width;
let height = info.height;
let mut src = vec![0; reader.output_buffer_size()];
reader.next_frame(&mut src).unwrap();
let src = src;
let basename = "icon";
let suffix = ".png";
let mut number_of_changes = 0;
let force = mode == "force";
for mut ie in app_icon_set.images.iter_mut() {
let do_update = force;
if !do_update {
}
if do_update {
let scale = match &ie.scale[..] {
"1x" => 1.0,
"2x" => 2.0,
"3x" => 3.0,
_ => return Err( OmError::Generic( "Unsupported scale".to_string() ) ),
};
let size = ie.size.split("x").collect::<Vec<&str>>();
let (w,h) = (size[0],size[1]);
let w: f32 = w.parse::<f32>().expect("");
let h: f32 = h.parse::<f32>().expect("");
println!("scale: {:?}, size: {:?} x {:?}", scale, w, h);
let sw = ( w * scale ) as usize;
let sh = ( h * scale ) as usize;
let name = format!("{}-{}x{}@{}x{}", basename, sw, sh, scale, suffix);
println!("{} <= scale: {:?}, size: {:?} x {:?}", name, scale, sw, sh);
let mut dst = vec![0; 3 * sw * sh];
let mut resizer = match resize::new(
width as usize, height as usize,
sw, sh,
Pixel::RGB8,
Type::Lanczos3,
) {
Ok( r ) => r,
Err( e ) => {
return Err( OmError::Generic("Error creating resizer".to_string()) );
},
};
match resizer.resize(
src.as_rgb(),
dst.as_rgb_mut()
) {
Ok( r ) => r,
Err( e ) => {
return Err( OmError::Generic("Error resizing".to_string()) );
},
};
let scaled_filename = format!("{}/{}", output, name);
let outfh = File::create(scaled_filename).unwrap();
let mut encoder = png::Encoder::new(outfh, sw as u32, sh as u32);
encoder.set_color(png::ColorType::Rgb);
encoder.set_depth(png::BitDepth::Eight);
encoder.write_header().unwrap().write_image_data(&dst).unwrap();
ie.filename = Some(name);
number_of_changes += 1;
}
}
if number_of_changes > 0 {
match app_icon_set.save( &content_json_filename ) {
Ok( _ ) => {},
Err( _e ) => return Err( OmError::Generic("Error saving app icon set".to_string()) ),
}
}
Ok( number_of_changes )
}
}