use guara_core::jpegscan::*; fn photo(w: u16, h: u16) -> Vec { // Synthetic natural-looking test image: smooth gradients + texture + geometric edges. let mut rgb = Vec::with_capacity(w as usize * h as usize * 3); let mut x = 0x9E3779B97F4A7C15u64; for yy in 0..h as i32 { for xx in 0..w as i32 { x ^= x << 13; x ^= x >> 7; x ^= x << 17; let noise = ((x >> 40) & 31) as i32; let base = 90 + (xx * 90 / w as i32) + (yy * 60 / h as i32); let blob = if ((xx - 200).pow(2) + (yy - 150).pow(2)) < 3600 { 70 } else { 0 }; let v = (base + blob + noise).clamp(0, 255) as u8; rgb.extend_from_slice(&[v, v.saturating_sub(20), (v as i32 / 2 + noise) as u8]); } } let mut out = vec![]; let enc = jpeg_encoder::Encoder::new(&mut out, 92); enc.encode(&rgb, w, h, jpeg_encoder::ColorType::Rgb) .unwrap(); out } #[test] fn decodes_whole_image_and_ends_at_eoi() { let j = photo(1024, 768); let h = parse_header(&j).expect("cabeçalho"); assert_eq!((h.width, h.height), (1024, 768)); let d = decode(&h, &j, State::start(&h), u32::MAX, 0); assert_eq!(d.stop, Stop::Done); assert_eq!(d.dc.len() as u32, h.total_mcus()); // Only the 2-byte EOI marker (`FF D9`) remains after decoding all MCUs. let tail = &j[d.state.pos.min(j.len())..]; assert!( tail.windows(2).any(|w| w == [0xFF, 0xD9]), "sem EOI depois do último MCU" ); assert!(first_discontinuity(&h, &d.dc).is_none()); } #[test] fn detects_break_and_resumes_with_the_right_continuation() { let j = photo(1024, 768); let h = parse_header(&j).unwrap(); let cut = 12 * 4096; // simulate a fragmentation break on a 4 KiB cluster boundary assert!(j.len() > cut + 8192, "imagem pequena demais: {}", j.len()); // Splice foreign pseudo-random bytes (without `0xFF` markers) after the cut point. let mut x = 12345u64; let junk: Vec = (0..40_000) .map(|_| { x ^= x << 13; x ^= x >> 7; x ^= x << 17; (x >> 24) as u8 }) .collect(); let mut broken = j[..cut].to_vec(); broken.extend_from_slice(&junk); let d = decode(&h, &broken, State::start(&h), u32::MAX, 512); assert_ne!(d.stop, Stop::Done); // Decoding continues into the foreign cluster briefly, then triggers a Huffman error or DC jump. let mcu_break = first_discontinuity(&h, &d.dc); // Last valid checkpoint at the end of the first fragment (`cut`). let good = d .snaps .iter() .rfind(|s| s.pos <= cut) .expect("snapshot antes da quebra") .clone(); // Resuming from that checkpoint with the true second fragment reconstructs the entire image. let mut joined = j[..cut].to_vec(); joined.extend_from_slice(&j[cut..]); let r = decode(&h, &joined, good.clone(), u32::MAX, 0); assert_eq!(r.stop, Stop::Done); assert_eq!(good.mcu as usize + r.dc.len(), h.total_mcus() as usize); let _ = mcu_break; }