Skip to content

Commit 407e165

Browse files
committed
code refactoring and quadmind compress rate fixed
1 parent 22b2033 commit 407e165

9 files changed

Lines changed: 995 additions & 929 deletions

File tree

Cargo.toml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
11
[package]
22
name = "jpegview-rust"
3-
version = "0.2.0"
3+
version = "0.3.0"
44
authors = ["autergame"]
55

66
[dependencies]
77
native-dialog = "0.6.3"
88
miniz_oxide = "0.6.2"
99
threadpool = "1.8.1"
1010
bincode = "1.3.3"
11-
serde = { version = "1.0.147", features = ["derive"] }
12-
image = "0.24.3"
11+
serde = { version = "1.0.151", features = ["derive"] }
12+
image = "0.24.5"
1313
sha2 = "0.10.6"
1414

1515
gl = "0.14.0"
1616
glfw = { version = "0.47.0", default-features = false, features = ["glfw-sys"] }
1717

18-
imgui = { git = "https://github.com/autergame/imgui-rs", version = "0.8.1-alpha.0", features = ["docking"] }
18+
imgui = { version = "0.9.0", features = ["docking"] }
1919

20-
fast-generated-dct = { git = "https://github.com/autergame/Fast-DCT-Generator-Rust", version = "0.1.0" }
20+
fast-generated-dct = { git = "https://github.com/autergame/Fast-DCT-Generator-Rust", version = "0.1.0" }
2121

2222
[profile.dev.package.fast-generated-dct]
2323
opt-level = 3

assets/JpegView_image.png

-43.3 KB
Loading

assets/test.qmi

-161 KB
Binary file not shown.

src/imgui_layout.rs

Lines changed: 295 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,295 @@
1+
use crate::{jpeg::Jpeg, my_image::MyImage, quad_tree::QuadTree};
2+
3+
pub fn jpeg(
4+
ui: &imgui::Ui,
5+
column: f32,
6+
jpeg: &mut Jpeg,
7+
use_jpeg: &mut bool,
8+
use_threads: &mut bool,
9+
threads_available: bool,
10+
) {
11+
ui.align_text_to_frame_padding();
12+
ui.checkbox("Use Jpeg", use_jpeg);
13+
14+
indent_block(ui, || {
15+
ui.align_text_to_frame_padding();
16+
ui.bullet_text("Quality Factor:");
17+
ui.same_line();
18+
ui.set_next_item_width(column - ui.cursor_pos()[0]);
19+
ui.slider("##quality", 1.0f32, 100.0f32, &mut jpeg.quality);
20+
21+
ui.align_text_to_frame_padding();
22+
ui.bullet_text("Block Size:");
23+
ui.same_line();
24+
ui.set_next_item_width(column - ui.cursor_pos()[0]);
25+
if ui.combo_simple_string(
26+
"##block_size",
27+
&mut jpeg.block_size_index,
28+
&BLOCK_SIZE_ITEMS,
29+
) {
30+
jpeg.block_size = 1 << (jpeg.block_size_index + 1);
31+
}
32+
33+
ui.align_text_to_frame_padding();
34+
ui.checkbox("Use Generated Quantization Table", &mut jpeg.use_gen_qtable);
35+
36+
ui.align_text_to_frame_padding();
37+
ui.checkbox("Show Compression Rate", &mut jpeg.use_compression_rate);
38+
39+
indent_block(ui, || {
40+
ui.align_text_to_frame_padding();
41+
ui.bullet_text("Quality Start:");
42+
ui.same_line();
43+
ui.set_next_item_width(column - ui.cursor_pos()[0]);
44+
ui.slider("##quality_start", 1.0f32, 100.0f32, &mut jpeg.quality_start);
45+
});
46+
47+
ui.align_text_to_frame_padding();
48+
ui.checkbox("Use Fast DCT Algorithm", &mut jpeg.use_fast_dct);
49+
50+
ui.disabled(!threads_available, || {
51+
ui.align_text_to_frame_padding();
52+
ui.checkbox("Use Multi-Threading", use_threads);
53+
});
54+
});
55+
}
56+
57+
pub fn ycbcr(ui: &imgui::Ui, column: f32, use_ycbcr: &mut bool, subsampling_index: &mut usize) {
58+
ui.align_text_to_frame_padding();
59+
ui.checkbox("Use YCbCr Colors", use_ycbcr);
60+
61+
ui.align_text_to_frame_padding();
62+
ui.bullet_text("Chroma Subsampling:");
63+
ui.same_line();
64+
ui.set_next_item_width(column - ui.cursor_pos()[0]);
65+
ui.combo_simple_string("##subsampling", subsampling_index, &SUBSAMPLING_ITEMS);
66+
}
67+
68+
pub fn quad_tree(
69+
ui: &imgui::Ui,
70+
column: f32,
71+
quad_tree: &mut QuadTree,
72+
use_quad_tree: &mut bool,
73+
min_size_index: &mut usize,
74+
max_size_index: &mut usize,
75+
max_depth_max: &mut u32,
76+
threshold_error_max: &mut f32,
77+
) {
78+
ui.align_text_to_frame_padding();
79+
ui.checkbox("Use QuadTree", use_quad_tree);
80+
81+
indent_block(ui, || {
82+
ui.align_text_to_frame_padding();
83+
ui.bullet_text("Max Depth:");
84+
ui.same_line();
85+
ui.set_next_item_width(column - ui.cursor_pos()[0]);
86+
ui.slider("##max_depth", 1, *max_depth_max, &mut quad_tree.max_depth);
87+
88+
ui.align_text_to_frame_padding();
89+
ui.bullet_text("Error Threshold:");
90+
ui.same_line();
91+
ui.set_next_item_width(column - ui.cursor_pos()[0]);
92+
ui.slider(
93+
"##threshold_error",
94+
0.0f32,
95+
*threshold_error_max,
96+
&mut quad_tree.threshold_error,
97+
);
98+
99+
ui.align_text_to_frame_padding();
100+
ui.bullet_text("Min Quad Size:");
101+
ui.same_line();
102+
ui.set_next_item_width(column - ui.cursor_pos()[0]);
103+
if ui.combo_simple_string("##min_size", min_size_index, &BLOCK_SIZE_ITEMS) {
104+
quad_tree.min_size = 1 << (*min_size_index + 1);
105+
}
106+
107+
ui.align_text_to_frame_padding();
108+
ui.bullet_text("Max Quad Size:");
109+
ui.same_line();
110+
ui.set_next_item_width(column - ui.cursor_pos()[0]);
111+
if ui.combo_simple_string("##max_size", max_size_index, &BLOCK_SIZE_ITEMS) {
112+
quad_tree.max_size = 1 << (*max_size_index + 1);
113+
}
114+
115+
ui.align_text_to_frame_padding();
116+
ui.checkbox("Use Quad Size Power Of 2", &mut quad_tree.use_pow_2);
117+
118+
ui.align_text_to_frame_padding();
119+
ui.checkbox("Draw Quadrant Line", &mut quad_tree.use_draw_line);
120+
});
121+
122+
increase_max(&mut quad_tree.max_depth, max_depth_max, 2, 1);
123+
increase_max(
124+
&mut quad_tree.threshold_error,
125+
threshold_error_max,
126+
2.0f32,
127+
1.0f32,
128+
);
129+
}
130+
131+
pub fn zoom(
132+
ui: &imgui::Ui,
133+
column: f32,
134+
use_zoom: &mut bool,
135+
zoom: &mut f32,
136+
zoom_max: &mut f32,
137+
magnifier_size: &mut f32,
138+
magnifier_size_max: &mut f32,
139+
) {
140+
ui.align_text_to_frame_padding();
141+
ui.checkbox("Use Zoom", use_zoom);
142+
143+
indent_block(ui, || {
144+
ui.align_text_to_frame_padding();
145+
ui.bullet_text("Zoom:");
146+
ui.same_line();
147+
ui.set_next_item_width(column - ui.cursor_pos()[0]);
148+
ui.slider("##zoomv", 1.0f32, *zoom_max, zoom);
149+
150+
ui.align_text_to_frame_padding();
151+
ui.bullet_text("Lupe Size:");
152+
ui.same_line();
153+
ui.set_next_item_width(column - ui.cursor_pos()[0]);
154+
ui.slider(
155+
"##magnifier_size",
156+
10.0f32,
157+
*magnifier_size_max,
158+
magnifier_size,
159+
);
160+
});
161+
162+
increase_max(zoom, zoom_max, 2.0f32, 1.0f32);
163+
increase_max(magnifier_size, magnifier_size_max, 2.0f32, 1.0f32);
164+
}
165+
166+
pub fn zoom_layer(
167+
ui: &imgui::Ui,
168+
image_texture: gl::types::GLuint,
169+
my_image: &MyImage,
170+
zoom: &mut f32,
171+
magnifier_size: f32,
172+
width: i32,
173+
height: i32,
174+
) {
175+
let ui_io = ui.io();
176+
177+
if ui_io.mouse_wheel > 0.0f32 {
178+
*zoom *= 1.1f32;
179+
} else if ui_io.mouse_wheel < 0.0f32 {
180+
*zoom *= 0.9f32;
181+
}
182+
183+
if *zoom < 1.0f32 {
184+
*zoom = 1.0f32;
185+
}
186+
187+
let last_rect = unsafe { (*imgui::sys::igGetCurrentContext()).LastItemData.Rect };
188+
189+
let half_magnifier = magnifier_size / 2.0f32;
190+
let magnifier_zoom = half_magnifier / *zoom;
191+
192+
let last_rect_size_fixed_x = (last_rect.Max.x - 1.0f32) - (last_rect.Min.x + 1.0f32);
193+
let last_rect_size_fixed_y = (last_rect.Max.y - 1.0f32) - (last_rect.Min.y + 1.0f32);
194+
195+
let last_rect_fixed_x = last_rect_size_fixed_x / my_image.width as f32;
196+
let last_rect_fixed_y = last_rect_size_fixed_y / my_image.height as f32;
197+
198+
let center_x =
199+
my_image.width as f32 * ((ui_io.mouse_pos[0] - last_rect.Min.x) / last_rect_size_fixed_x);
200+
let center_y =
201+
my_image.height as f32 * ((ui_io.mouse_pos[1] - last_rect.Min.y) / last_rect_size_fixed_y);
202+
203+
let uv0_x = (center_x - (magnifier_zoom / last_rect_fixed_x)) / my_image.width as f32;
204+
let uv0_y = (center_y - (magnifier_zoom / last_rect_fixed_y)) / my_image.height as f32;
205+
let uv1_x = (center_x + (magnifier_zoom / last_rect_fixed_x)) / my_image.width as f32;
206+
let uv1_y = (center_y + (magnifier_zoom / last_rect_fixed_y)) / my_image.height as f32;
207+
208+
let mut cursor_box_pos = [
209+
ui_io.mouse_pos[0] - half_magnifier,
210+
ui_io.mouse_pos[1] - half_magnifier,
211+
];
212+
213+
if cursor_box_pos[0] < 0.0f32 {
214+
cursor_box_pos[0] = 0.0f32;
215+
} else if (ui_io.mouse_pos[0] + half_magnifier) > width as f32 {
216+
cursor_box_pos[0] = width as f32 - magnifier_size;
217+
}
218+
219+
if cursor_box_pos[1] < 0.0f32 {
220+
cursor_box_pos[1] = 0.0f32;
221+
} else if (ui_io.mouse_pos[1] + half_magnifier) > height as f32 {
222+
cursor_box_pos[1] = height as f32 - magnifier_size;
223+
}
224+
225+
set_next_window_pos(cursor_box_pos);
226+
227+
let style = ui.push_style_var(imgui::StyleVar::WindowPadding([0.0f32, 0.0f32]));
228+
let tooltip = ui.begin_tooltip();
229+
230+
image(
231+
ui,
232+
image_texture,
233+
[magnifier_size, magnifier_size],
234+
[uv0_x, uv0_y],
235+
[uv1_x, uv1_y],
236+
);
237+
238+
tooltip.end();
239+
style.pop();
240+
}
241+
242+
pub fn image(ui: &imgui::Ui, image_texture: u32, size: [f32; 2], uv0: [f32; 2], uv1: [f32; 2]) {
243+
imgui::Image::new(imgui::TextureId::new(image_texture as usize), size)
244+
.tint_col(TINT_COL)
245+
.border_col(BORDER_COL)
246+
.uv0(uv0)
247+
.uv1(uv1)
248+
.build(ui);
249+
}
250+
251+
pub fn set_next_window_pos(pos: [f32; 2]) {
252+
unsafe {
253+
imgui::sys::igSetNextWindowPos(
254+
pos.into(),
255+
imgui::Condition::Always as i32,
256+
[0.0f32, 0.0f32].into(),
257+
)
258+
};
259+
}
260+
261+
pub fn separator() {
262+
unsafe {
263+
imgui::sys::igSeparatorEx(
264+
imgui::sys::ImGuiSeparatorFlags_Horizontal as imgui::sys::ImGuiSeparatorFlags,
265+
)
266+
}
267+
}
268+
269+
fn indent_block<F>(ui: &imgui::Ui, f: F)
270+
where
271+
F: FnOnce(),
272+
{
273+
ui.indent();
274+
f();
275+
ui.unindent();
276+
}
277+
278+
fn increase_max<T>(value: &mut T, max: &mut T, inc: T, dec: T)
279+
where
280+
T: PartialOrd + std::ops::AddAssign + std::ops::SubAssign,
281+
{
282+
if *value >= *max {
283+
*max += inc;
284+
*value -= dec;
285+
}
286+
}
287+
288+
pub const UV_MIN: [f32; 2] = [0.0f32, 0.0f32];
289+
pub const UV_MAX: [f32; 2] = [1.0f32, 1.0f32];
290+
291+
const TINT_COL: [f32; 4] = [1.0f32, 1.0f32, 1.0f32, 1.0f32];
292+
const BORDER_COL: [f32; 4] = [0.5f32, 0.5f32, 0.5f32, 1.0f32];
293+
294+
const BLOCK_SIZE_ITEMS: [&str; 9] = ["2", "4", "8", "16", "32", "64", "128", "256", "512"];
295+
const SUBSAMPLING_ITEMS: [&str; 6] = ["4:4:4", "4:4:0", "4:2:2", "4:2:0", "4:1:1", "4:1:0"];

0 commit comments

Comments
 (0)