use crate::{ImageFormat, ImageInfo, ImageInfoError, ImageInfoResult, ImageSize, ReadInterface};
use std::io::{BufRead, Seek};
pub fn try_jpeg2000<R>(ri: &mut ReadInterface<R>, length: usize) -> ImageInfoResult<ImageInfo>
where
R: BufRead + Seek,
{
if length < 8 {
return Err(ImageInfoError::UnrecognizedFormat);
}
let buffer = ri.read(0, 8)?;
if !buffer.cmp(4, 4, b"jP ") {
return Err(ImageInfoError::UnrecognizedFormat);
}
let signature_length = buffer.read_u32_be(0) as usize;
let mut offset = signature_length;
if length < offset + 12 {
return Err(ImageInfoError::UnrecognizedFormat);
}
let buffer = ri.read(offset, 12)?;
if !buffer.cmp(4, 4, b"ftyp") {
return Err(ImageInfoError::UnrecognizedFormat);
}
let mut ret =
if buffer.cmp(8, 4, b"jp2 ") {
ImageInfo {
format: ImageFormat::JP2,
ext: "jp2",
full_ext: "jp2",
mimetype: "image/jp2",
size: ImageSize {
width: 0,
height: 0,
},
entry_sizes: vec![],
}
}
else if buffer.cmp(8, 4, b"jph ") {
ImageInfo {
format: ImageFormat::JPH,
ext: "jph",
full_ext: "jph",
mimetype: "image/jph",
size: ImageSize {
width: 0,
height: 0,
},
entry_sizes: vec![],
}
}
else if buffer.cmp(8, 4, b"jpx ") {
ImageInfo {
format: ImageFormat::JPX,
ext: "jpx",
full_ext: "jpx",
mimetype: "image/jpx",
size: ImageSize {
width: 0,
height: 0,
},
entry_sizes: vec![],
}
}
else {
return Err(ImageInfoError::UnrecognizedFormat);
};
let ftyp_length = buffer.read_u32_be(0) as usize;
offset += ftyp_length;
while offset + 24 <= length {
let buffer = ri.read(offset, 24)?;
if buffer.cmp(4, 4, b"jp2h") {
if buffer.cmp(12, 4, b"ihdr") {
ret.size.width = buffer.read_u32_be(20) as i64;
ret.size.height = buffer.read_u32_be(16) as i64;
return Ok(ret);
} else {
return Err(ImageInfoError::UnrecognizedFormat);
}
}
let box_length = buffer.read_u32_be(0) as usize;
offset += box_length;
}
Err(ImageInfoError::UnrecognizedFormat)
}