1extern crate image;
2extern crate num_cpus;
3extern crate rand;
4extern crate threadpool;
5
6mod core;
7mod model;
8mod scanline;
9mod shape;
10mod state;
11mod util;
12mod worker;
13
14pub use shape::ShapeType;
15
16use std::io::Write;
17use std::fs::File;
18
19use model::Model;
20
21const SIZE: usize = 256;
22
23pub fn run(config: Config) {
24let img = util::load_image(config.in_path.as_ref()).expect("couldn't load image");
27 let cpus = num_cpus::get_physical();
28 let mut model = Model::new(img, cpus, config.out_size);
29 for _ in 0..config.num_shapes {
30 model.step(config.shape_type, config.alpha, 1000, config.m);
31 }
32 if config.out_path.ends_with(".svg") {
33 let mut file = File::create(&config.out_path).unwrap();
34 file.write_all(model.svg().as_bytes()).unwrap();
35 } else {
36 model.save_rasterized(&config.out_path).expect("wtf");
37 }
38}
39
40#[derive(Debug)]
41pub struct Config {
42 pub in_path: String,
43 pub out_path: String,
44 pub num_shapes: u32,
45 pub shape_type: ShapeType,
46 pub out_size: usize,
47 pub alpha: u8,
48 pub m: u8,
49}
50
51#[cfg(target_os="android")]
52#[allow(non_snake_case)]
53pub mod android {
54 extern crate jni;
55
56 use super::*;
57 use self::jni::JNIEnv;
58 use self::jni::objects::{JClass, JString, JValue};
59 use self::jni::sys::{jstring, jint, jobject};
60
61 static mut CONFIG_OPT: Option<Config> = None;
62 static mut MODEL_OPT: Option<Model> = None;
63
64 #[no_mangle]
65 pub unsafe extern fn Java_com_github_larryng_primage_jni_Primg_jniInit(
66 env: JNIEnv, _: JClass, img_path: JString, shape_type: jint, m: jint) -> jobject {
67
68 let in_path: String = env.get_string(img_path).expect("wtf").into();
69 let out_path = String::from("");
70 let shape_type = match shape_type {
71 0 => ShapeType::Triangle,
72 1 => ShapeType::Ellipse,
73 2 => ShapeType::Rectangle,
74 3 => ShapeType::RotatedRectangle,
75 _ => unreachable!(),
76 };
77 let out_size = 512;
78 let alpha = 128;
79 let num_shapes = 42;
80 let m = m as u8;
81 let config = Config {
82 in_path,
83 out_path,
84 num_shapes,
85 shape_type,
86 out_size,
87 alpha,
88 m
89 };
90
91 let img = util::load_image(config.in_path.as_ref()).expect("couldn't load image");
92 let img = util::scaled_to_area(img, SIZE * SIZE);
93 let cpus = num_cpus::get_physical();
94
95 let model = Model::new(img, cpus, config.out_size);
96
97 let class = env.find_class("com/github/larryng/primage/jni/PrimgInitResult").expect("couldn't load class");
98 let constructor = env.get_method_id(class, "<init>", "(Ljava/lang/Object;III)V").expect("couldn't get constructor");
99 let debug: String = format!("cpus: get={}, physical={}", num_cpus::get(), num_cpus::get_physical());
100 let debug = JValue::Object(env.new_string(debug).unwrap().into());
101 let w = JValue::Int(model.w as i32);
102 let h = JValue::Int(model.h as i32);
103 let color = JValue::Int(model.bg.to_argb_i32());
104 let args = &[debug, w, h, color];
105 let obj = env.new_object_by_id(class, constructor, &args[..]).expect("couldn't make PrimgInitResult").into_inner();
106
107 MODEL_OPT = Some(model);
108 CONFIG_OPT = Some(config);
109
110 obj
111 }
112
113 #[no_mangle]
114 pub unsafe extern fn Java_com_github_larryng_primage_jni_Primg_jniStep(
115 env: JNIEnv, _: JClass) -> jstring {
116
117 let config = match CONFIG_OPT {
118 Some(ref c) => c,
119 None => unreachable!(),
120 };
121
122 let model = match MODEL_OPT {
123 Some(ref mut m) => m,
124 None => unreachable!(),
125 };
126
127 let (shape, color) = model.step(config.shape_type, config.alpha, 1000, config.m);
128
129 let s = format!("{}:{}", shape.serialize(), color.to_argb_i32());
130
131 env.new_string(s).unwrap().into_inner()
132 }
133}