feat: implement cbz writing and pdf reading
This commit is contained in:
		
							parent
							
								
									034f0b142c
								
							
						
					
					
						commit
						e8287d0c6e
					
				
					 10 changed files with 644 additions and 57 deletions
				
			
		
							
								
								
									
										96
									
								
								tests/cbz_writer_tests.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								tests/cbz_writer_tests.rs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,96 @@
 | 
			
		|||
use std::fs::File;
 | 
			
		||||
use std::io::Read;
 | 
			
		||||
 | 
			
		||||
use cbz2pdf::formats::cbz::CbzWriter;
 | 
			
		||||
use cbz2pdf::formats::FormatWriter;
 | 
			
		||||
use cbz2pdf::model::{Document, ImagePage};
 | 
			
		||||
 | 
			
		||||
fn make_tiny_jpeg() -> (Vec<u8>, image::DynamicImage) {
 | 
			
		||||
    let img = image::DynamicImage::new_rgb8(1, 1).to_rgb8();
 | 
			
		||||
    let mut buf = Vec::new();
 | 
			
		||||
    {
 | 
			
		||||
        let mut cursor = std::io::Cursor::new(&mut buf);
 | 
			
		||||
        let mut enc = image::codecs::jpeg::JpegEncoder::new_with_quality(&mut cursor, 80);
 | 
			
		||||
        enc.encode(&img, 1, 1, image::ColorType::Rgb8.into())
 | 
			
		||||
            .unwrap();
 | 
			
		||||
    }
 | 
			
		||||
    let decoded = image::load_from_memory(&buf).unwrap();
 | 
			
		||||
    (buf, decoded)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[test]
 | 
			
		||||
fn cbz_writer_preserves_dct_and_renames_non_jpg() {
 | 
			
		||||
    // Prepare a page with original JPEG DCT data but a non-jpg name.
 | 
			
		||||
    let (jpeg_dct, decoded) = make_tiny_jpeg();
 | 
			
		||||
    let page = ImagePage {
 | 
			
		||||
        name: "cover.png".to_string(),
 | 
			
		||||
        image: decoded,
 | 
			
		||||
        jpeg_dct: Some(jpeg_dct.clone()),
 | 
			
		||||
    };
 | 
			
		||||
    let doc = Document::new(vec![page]);
 | 
			
		||||
 | 
			
		||||
    let temp_dir = tempfile::tempdir().expect("create temp dir");
 | 
			
		||||
    let cbz_path = temp_dir.path().join("out.cbz");
 | 
			
		||||
 | 
			
		||||
    let writer = CbzWriter;
 | 
			
		||||
    writer.write(&doc, &cbz_path).expect("write cbz");
 | 
			
		||||
 | 
			
		||||
    // Open the CBZ and verify it contains 001.jpg with the exact JPEG data.
 | 
			
		||||
    let f = File::open(&cbz_path).unwrap();
 | 
			
		||||
    let mut zip = zip::ZipArchive::new(f).unwrap();
 | 
			
		||||
 | 
			
		||||
    // There should be exactly one file named 001.jpg
 | 
			
		||||
    let mut found = false;
 | 
			
		||||
    for i in 0..zip.len() {
 | 
			
		||||
        let mut file = zip.by_index(i).unwrap();
 | 
			
		||||
        let name = file.enclosed_name().unwrap().to_owned();
 | 
			
		||||
        if name.file_name().unwrap() == "001.jpg" {
 | 
			
		||||
            let mut data = Vec::new();
 | 
			
		||||
            file.read_to_end(&mut data).unwrap();
 | 
			
		||||
            assert_eq!(
 | 
			
		||||
                data, jpeg_dct,
 | 
			
		||||
                "writer should preserve original JPEG DCT bytes"
 | 
			
		||||
            );
 | 
			
		||||
            found = true;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    assert!(found, "001.jpg not found in zip");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[test]
 | 
			
		||||
fn cbz_writer_keeps_jpg_name() {
 | 
			
		||||
    // If the page already has a .jpg name, the writer should keep it.
 | 
			
		||||
    let (jpeg_dct, decoded) = make_tiny_jpeg();
 | 
			
		||||
    let page = ImagePage {
 | 
			
		||||
        name: "page01.jpg".to_string(),
 | 
			
		||||
        image: decoded,
 | 
			
		||||
        jpeg_dct: Some(jpeg_dct),
 | 
			
		||||
    };
 | 
			
		||||
    let doc = Document::new(vec![page]);
 | 
			
		||||
 | 
			
		||||
    let temp_dir = tempfile::tempdir().expect("create temp dir");
 | 
			
		||||
    let cbz_path = temp_dir.path().join("out.cbz");
 | 
			
		||||
 | 
			
		||||
    let writer = CbzWriter;
 | 
			
		||||
    writer.write(&doc, &cbz_path).expect("write cbz");
 | 
			
		||||
 | 
			
		||||
    let f = File::open(&cbz_path).unwrap();
 | 
			
		||||
    let mut zip = zip::ZipArchive::new(f).unwrap();
 | 
			
		||||
 | 
			
		||||
    let mut names = Vec::new();
 | 
			
		||||
    for i in 0..zip.len() {
 | 
			
		||||
        let file = zip.by_index(i).unwrap();
 | 
			
		||||
        let name = file
 | 
			
		||||
            .enclosed_name()
 | 
			
		||||
            .unwrap()
 | 
			
		||||
            .file_name()
 | 
			
		||||
            .unwrap()
 | 
			
		||||
            .to_owned();
 | 
			
		||||
        names.push(name.to_string_lossy().to_string());
 | 
			
		||||
    }
 | 
			
		||||
    assert_eq!(
 | 
			
		||||
        names,
 | 
			
		||||
        vec!["page01.jpg"],
 | 
			
		||||
        "existing .jpg name should be kept"
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue