Add standalone media and remote downloads

This commit is contained in:
burnintuna 2026-07-21 21:18:36 +09:00
parent 8a213462e0
commit 5f9b5d9796
14 changed files with 683 additions and 86 deletions

View file

@ -70,16 +70,33 @@ pub fn decode_page(path: &Path, page: &ArchivePage) -> Result<DecodedPage> {
bail!("실제 압축 해제 크기가 제한을 초과합니다: {}", page.name);
}
let reader = ImageReader::new(Cursor::new(&encoded))
decode_image_bytes(&encoded, &page.name)
}
pub fn decode_image_file(path: &Path, display_name: &str) -> Result<DecodedPage> {
let file = File::open(path)
.with_context(|| format!("이미지 파일을 열 수 없습니다: {display_name}"))?;
let mut encoded = Vec::new();
file.take(MAX_ENTRY_SIZE + 1)
.read_to_end(&mut encoded)
.with_context(|| format!("이미지 파일을 읽을 수 없습니다: {display_name}"))?;
if encoded.len() as u64 > MAX_ENTRY_SIZE {
bail!("이미지 크기가 제한을 초과합니다: {display_name} (최대 256MB)");
}
decode_image_bytes(&encoded, display_name)
}
fn decode_image_bytes(encoded: &[u8], name: &str) -> Result<DecodedPage> {
let reader = ImageReader::new(Cursor::new(encoded))
.with_guessed_format()
.with_context(|| format!("이미지 형식을 확인할 수 없습니다: {}", page.name))?;
.with_context(|| format!("이미지 형식을 확인할 수 없습니다: {name}"))?;
let (width, height) = reader
.into_dimensions()
.with_context(|| format!("이미지 크기를 읽을 수 없습니다: {}", page.name))?;
validate_dimensions(width, height, &page.name)?;
.with_context(|| format!("이미지 크기를 읽을 수 없습니다: {name}"))?;
validate_dimensions(width, height, name)?;
let image = image::load_from_memory(&encoded)
.with_context(|| format!("이미지를 디코딩할 수 없습니다: {}", page.name))?;
let image = image::load_from_memory(encoded)
.with_context(|| format!("이미지를 디코딩할 수 없습니다: {name}"))?;
let rgba = image.into_rgba8();
Ok(DecodedPage {
@ -175,4 +192,16 @@ mod tests {
std::fs::remove_file(path).unwrap();
}
#[test]
fn decodes_a_standalone_image() {
let directory = tempfile::tempdir().unwrap();
let path = directory.path().join("photo.png");
let image = image::RgbaImage::from_pixel(4, 5, image::Rgba([1, 2, 3, 255]));
image.save(&path).unwrap();
let decoded = decode_image_file(&path, "photo.png").unwrap();
assert_eq!((decoded.width, decoded.height), (4, 5));
assert_eq!(decoded.rgba.len(), 4 * 5 * 4);
}
}