Fixed img::DeserializeError::SizePixelsMismatch being checked wrong.

Now using `Tis` in `file-editor`.
This commit is contained in:
Filipe Rodrigues 2021-05-29 20:03:34 +01:00
parent 7a3b6a77e7
commit 246ae4f902
5 changed files with 39 additions and 41 deletions

View File

@ -17,6 +17,7 @@ log = "0.4.13"
byteorder = "1.4.2"
bitmatch = "0.1.1"
int-conv = "0.1.4"
derive_more = "0.99.14"
# Derives
thiserror = "1.0.23"

View File

@ -2,17 +2,22 @@
/// Bits per pixel
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
#[derive(derive_more::Display)]
pub enum BitsPerPixel {
/// 4-bit indexed
#[display(fmt = "4-bit")]
Index4Bit,
/// 8-bit indexed
#[display(fmt = "8-bit")]
Index8Bit,
/// 16-bit color
#[display(fmt = "16-bit")]
Color16Bit,
/// 24-bit color
#[display(fmt = "24-bit")]
Color24Bit,
}

View File

@ -36,10 +36,16 @@ impl Img {
let header: Header = Header::from_bytes(&header_bytes).into_ok();
// If the width and height don't match the length, return Err
// Note: The unscaled width should the one used to check the length, not the scaled
let pixels_len = header.length - 0xc;
let [scaled_width, scaled_height] = bpp.scale_size(header.size);
if pixels_len != usize::from(scaled_width) * usize::from(scaled_height) {
return Err(DeserializeError::SizePixelsMismatch);
let [width, height] = header.size;
if pixels_len != usize::from(width) * usize::from(height) * 2 {
return Err(DeserializeError::SizePixelsMismatch {
width,
height,
bpp,
pixels_len,
});
}
// Then decode the pixels

View File

@ -1,6 +1,7 @@
//! Errors
// Imports
use crate::BitsPerPixel;
use std::io;
/// Error type for [`Img::deserialize`](super::Img::deserialize)
@ -11,8 +12,20 @@ pub enum DeserializeError {
ReadHeader(#[source] io::Error),
/// Image size didn't match pixels
#[error("Size didn't match pixels length")]
SizePixelsMismatch,
#[error("Size didn't match pixels length {width}x{height}@{bpp} != {pixels_len}")]
SizePixelsMismatch {
/// Width
width: u16,
/// Height
height: u16,
/// Bpp
bpp: BitsPerPixel,
/// Pixels len
pixels_len: usize,
},
/// Unable to read colors
#[error("Unable to read colors")]

View File

@ -16,21 +16,15 @@ pub mod tree;
// Imports
use anyhow::Context;
use byteorder::{LittleEndian, ReadBytesExt};
use dcb_cdrom_xa::CdRomCursor;
use dcb_io::{game_file::Path, GameFile};
use dcb_tim::Tim;
use dcb_tim::{Tim, Tis};
use eframe::{
egui::{self, Color32, TextureId},
epi, NativeOptions,
};
use native_dialog::{FileDialog, MessageDialog, MessageType};
use std::{
fs,
io::{Seek, SeekFrom, Write},
mem,
path::PathBuf,
};
use std::{fs, io::Write, mem, path::PathBuf};
use tree::FsTree;
fn main() {
@ -238,39 +232,18 @@ impl epi::App for FileEditor {
},
path if path.ends_with(".TIS") => {
try {
// Deserialize the tim
// Deserialize the tis
let path = Path::from_ascii(&path).context("Unable to create path")?;
let mut file =
loaded_game.game_file.open_file(path).context("Unable to open file")?;
let images: Tis = Tis::deserialize(&mut file).context("Unable to parse file")?;
let magic = file.read_u16::<LittleEndian>().context("Unable to read magic")?;
if magic != 0x7054 {
Err(anyhow::anyhow!("Magic {:#06x} was wrong", magic))?;
}
let entries_len: u16 =
file.read_u16::<LittleEndian>().context("Unable to read entries len")?;
let entries = (0..entries_len)
.map(|idx| {
file.read_u32::<LittleEndian>()
.with_context(|| format!("Unable to read entry {idx}"))
})
.collect::<Result<Vec<_>, _>>()?;
// Then read all tim files
let images = entries
// Then create all textures
let images = images
.tims
.into_iter()
.map(|entry| {
let pos = 4 * entry;
file.seek(SeekFrom::Start(u64::from(pos)))
.context("Unable to seek to image")?;
let image = Tim::deserialize(&mut file)
.with_context(|| format!("Unable to parse file at {pos:#x}"))?;
// Then create a texture with it
.map(|image| {
// Create a texture with it
let [width, height] = image.size();
let textures = (0..image.pallettes())
.map(|pallette| {