From 246ae4f902a738a728999a6a643e519bace3d01d Mon Sep 17 00:00:00 2001 From: Filipe Rodrigues Date: Sat, 29 May 2021 20:03:34 +0100 Subject: [PATCH] Fixed `img::DeserializeError::SizePixelsMismatch` being checked wrong. Now using `Tis` in `file-editor`. --- dcb-tim/Cargo.toml | 1 + dcb-tim/src/bpp.rs | 5 +++ dcb-tim/src/img.rs | 12 +++++-- dcb-tim/src/img/error.rs | 17 ++++++++-- dcb-tools/dcb-file-editor/src/main.rs | 45 ++++++--------------------- 5 files changed, 39 insertions(+), 41 deletions(-) diff --git a/dcb-tim/Cargo.toml b/dcb-tim/Cargo.toml index bb53699..573e180 100644 --- a/dcb-tim/Cargo.toml +++ b/dcb-tim/Cargo.toml @@ -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" diff --git a/dcb-tim/src/bpp.rs b/dcb-tim/src/bpp.rs index 9c59307..4c0106e 100644 --- a/dcb-tim/src/bpp.rs +++ b/dcb-tim/src/bpp.rs @@ -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, } diff --git a/dcb-tim/src/img.rs b/dcb-tim/src/img.rs index f9a5ccd..51cb8d6 100644 --- a/dcb-tim/src/img.rs +++ b/dcb-tim/src/img.rs @@ -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 diff --git a/dcb-tim/src/img/error.rs b/dcb-tim/src/img/error.rs index 53b084a..27e5cd3 100644 --- a/dcb-tim/src/img/error.rs +++ b/dcb-tim/src/img/error.rs @@ -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")] diff --git a/dcb-tools/dcb-file-editor/src/main.rs b/dcb-tools/dcb-file-editor/src/main.rs index 0589c66..7bea52e 100644 --- a/dcb-tools/dcb-file-editor/src/main.rs +++ b/dcb-tools/dcb-file-editor/src/main.rs @@ -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::().context("Unable to read magic")?; - - if magic != 0x7054 { - Err(anyhow::anyhow!("Magic {:#06x} was wrong", magic))?; - } - - let entries_len: u16 = - file.read_u16::().context("Unable to read entries len")?; - - let entries = (0..entries_len) - .map(|idx| { - file.read_u32::() - .with_context(|| format!("Unable to read entry {idx}")) - }) - .collect::, _>>()?; - - // 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| {