All checks were successful
Checking Renovate configuration / validate (pull_request) Successful in 1m5s
Build and test / Clippy (pull_request) Successful in 3m25s
Checking yaml / Run yamllint (pull_request) Successful in 11s
Build and test / Tests (pull_request) Successful in 4m12s
Build and test / Build AMD64 (pull_request) Successful in 4m12s
Build and test / Generate Documentation (pull_request) Successful in 3m52s
53 lines
1.5 KiB
Rust
53 lines
1.5 KiB
Rust
use std::ffi::OsStr;
|
|
use std::fs::File;
|
|
use std::io::Read;
|
|
use std::path::Path;
|
|
|
|
use anyhow::Result;
|
|
use rayon::prelude::*;
|
|
use zip::ZipArchive;
|
|
|
|
use crate::model::{Document, ImagePage};
|
|
|
|
use super::FormatReader;
|
|
|
|
pub struct CbzReader;
|
|
|
|
impl FormatReader for CbzReader {
|
|
fn read(&self, input: &Path) -> Result<Document> {
|
|
let mut zip = ZipArchive::new(File::open(input)?)?;
|
|
let mut files: Vec<(String, Vec<u8>)> = Vec::new();
|
|
for i in 0..zip.len() {
|
|
let mut file = zip.by_index(i)?;
|
|
let mut image_data = Vec::new();
|
|
let name = file
|
|
.enclosed_name()
|
|
.expect("Failed to read file name")
|
|
.to_owned();
|
|
if name.extension() == Some(OsStr::new("jpg")) {
|
|
file.read_to_end(&mut image_data)?;
|
|
files.push((
|
|
name.file_name()
|
|
.expect("Failed to read file name")
|
|
.to_string_lossy()
|
|
.to_string(),
|
|
image_data,
|
|
));
|
|
}
|
|
}
|
|
|
|
let mut pages: Vec<ImagePage> = Vec::new();
|
|
files
|
|
.par_iter()
|
|
.map(|(name, data)| ImagePage {
|
|
name: name.clone(),
|
|
image: image::load_from_memory(data).expect("Failed to decode image"),
|
|
jpeg_dct: Some(data.clone()),
|
|
})
|
|
.collect_into_vec(&mut pages);
|
|
|
|
pages.par_sort_by_key(|p| p.name.clone());
|
|
|
|
Ok(Document::new(pages))
|
|
}
|
|
}
|