Decode images in parallel
This commit is contained in:
parent
c968d9086d
commit
04f03b4efc
1 changed files with 27 additions and 5 deletions
32
src/main.rs
32
src/main.rs
|
|
@ -1,4 +1,5 @@
|
||||||
use clap::{Parser, ValueHint};
|
use clap::{Parser, ValueHint};
|
||||||
|
use image::DynamicImage;
|
||||||
use log::info;
|
use log::info;
|
||||||
use pdf_writer::{Content, Filter, Finish, Name, Pdf, Rect, Ref};
|
use pdf_writer::{Content, Filter, Finish, Name, Pdf, Rect, Ref};
|
||||||
use rayon::prelude::*;
|
use rayon::prelude::*;
|
||||||
|
|
@ -56,20 +57,37 @@ struct ImageFile {
|
||||||
pub data: Vec<u8>,
|
pub data: Vec<u8>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct DecodedImageFile {
|
||||||
|
pub name: String,
|
||||||
|
pub data: Vec<u8>,
|
||||||
|
pub image: DynamicImage,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&ImageFile> for DecodedImageFile {
|
||||||
|
fn from(value: &ImageFile) -> Self {
|
||||||
|
let image = image::load_from_memory(&value.data).unwrap();
|
||||||
|
Self {
|
||||||
|
name: value.name.clone(),
|
||||||
|
data: value.data.clone(),
|
||||||
|
image,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn convert_cbz(cbz_path: &Path, output_dir: &Path) -> Result<(), Box<dyn std::error::Error>> {
|
fn convert_cbz(cbz_path: &Path, output_dir: &Path) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
info!("Converting {:?}", cbz_path);
|
info!("Converting {:?}", cbz_path);
|
||||||
|
|
||||||
let a4 = Rect::new(0.0, 0.0, 595.0, 842.0);
|
let a4 = Rect::new(0.0, 0.0, 595.0, 842.0);
|
||||||
|
|
||||||
let mut zip = ZipArchive::new(File::open(cbz_path)?)?;
|
let mut zip = ZipArchive::new(File::open(cbz_path)?)?;
|
||||||
let mut images = Vec::new();
|
let mut files = Vec::new();
|
||||||
for i in 0..zip.len() {
|
for i in 0..zip.len() {
|
||||||
let mut file = zip.by_index(i)?;
|
let mut file = zip.by_index(i)?;
|
||||||
let mut image_data = Vec::new();
|
let mut image_data = Vec::new();
|
||||||
let name = file.enclosed_name().expect("Failed to read file name");
|
let name = file.enclosed_name().expect("Failed to read file name");
|
||||||
if name.extension() == Some(OsStr::new("jpg")) {
|
if name.extension() == Some(OsStr::new("jpg")) {
|
||||||
file.read_to_end(&mut image_data)?;
|
file.read_to_end(&mut image_data)?;
|
||||||
images.push(ImageFile {
|
files.push(ImageFile {
|
||||||
name: name
|
name: name
|
||||||
.file_name()
|
.file_name()
|
||||||
.expect("Failed to read file name")
|
.expect("Failed to read file name")
|
||||||
|
|
@ -80,6 +98,11 @@ fn convert_cbz(cbz_path: &Path, output_dir: &Path) -> Result<(), Box<dyn std::er
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut images = Vec::new();
|
||||||
|
files
|
||||||
|
.par_iter()
|
||||||
|
.map(|f| DecodedImageFile::from(f))
|
||||||
|
.collect_into_vec(&mut images);
|
||||||
images.par_sort_by_key(|img| img.name.clone());
|
images.par_sort_by_key(|img| img.name.clone());
|
||||||
|
|
||||||
let mut pdf = Pdf::new();
|
let mut pdf = Pdf::new();
|
||||||
|
|
@ -98,7 +121,6 @@ fn convert_cbz(cbz_path: &Path, output_dir: &Path) -> Result<(), Box<dyn std::er
|
||||||
pages.push(page_id);
|
pages.push(page_id);
|
||||||
let mut page = pdf.page(page_id);
|
let mut page = pdf.page(page_id);
|
||||||
let image_name = Name(b"Im1");
|
let image_name = Name(b"Im1");
|
||||||
let dynamic = image::load_from_memory(&image.data).unwrap();
|
|
||||||
|
|
||||||
page.media_box(a4);
|
page.media_box(a4);
|
||||||
page.parent(page_tree_id);
|
page.parent(page_tree_id);
|
||||||
|
|
@ -108,8 +130,8 @@ fn convert_cbz(cbz_path: &Path, output_dir: &Path) -> Result<(), Box<dyn std::er
|
||||||
|
|
||||||
let mut pdf_image = pdf.image_xobject(image_id, &image.data);
|
let mut pdf_image = pdf.image_xobject(image_id, &image.data);
|
||||||
pdf_image.filter(Filter::DctDecode);
|
pdf_image.filter(Filter::DctDecode);
|
||||||
pdf_image.width(dynamic.width() as i32);
|
pdf_image.width(image.image.width() as i32);
|
||||||
pdf_image.height(dynamic.height() as i32);
|
pdf_image.height(image.image.height() as i32);
|
||||||
pdf_image.color_space().device_rgb();
|
pdf_image.color_space().device_rgb();
|
||||||
pdf_image.bits_per_component(8);
|
pdf_image.bits_per_component(8);
|
||||||
pdf_image.finish();
|
pdf_image.finish();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue