#![allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)]
mod accessors;
mod extract;
mod read_header;
use std::fs::File;
use std::io::{BufReader, Read, Seek, SeekFrom};
use std::path::Path;
use super::gts::GtsFile;
use super::types::GtpHeader;
use crate::error::{Error, Result};
pub struct GtpFile<R: Read + Seek> {
reader: BufReader<R>,
pub(crate) header: GtpHeader,
pub(crate) chunk_offsets: Vec<Vec<u32>>,
page_size: u32,
tile_width: i32,
tile_height: i32,
}
impl GtpFile<File> {
pub fn open<P: AsRef<Path>>(path: P, gts: &GtsFile) -> Result<Self> {
let file = File::open(path.as_ref())?;
Self::new(file, gts)
}
}
impl<R: Read + Seek> GtpFile<R> {
pub fn new(reader: R, gts: &GtsFile) -> Result<Self> {
let mut reader = BufReader::new(reader);
let file_size = reader.seek(SeekFrom::End(0))?;
reader.seek(SeekFrom::Start(0))?;
let header = read_header::read_header(&mut reader)?;
if header.magic != GtpHeader::MAGIC {
return Err(Error::InvalidGtpMagic);
}
let page_size = gts.header.page_size;
let num_pages = (file_size / u64::from(page_size)) as usize;
let chunk_offsets = read_header::read_chunk_offsets(&mut reader, page_size, num_pages)?;
Ok(Self {
reader,
header,
chunk_offsets,
page_size,
tile_width: gts.header.tile_width,
tile_height: gts.header.tile_height,
})
}
}