Skip to content

Commit cb26f42

Browse files
AngheloAlfethteck
andauthored
Checks for texture sizes (#498)
* Errors for textures and palette sizes * fmt * Change palette rom size being larger than given size to a hard error instead of a warning * version bump --------- Co-authored-by: Ethan Roseman <ethteck@gmail.com>
1 parent 6f98fc2 commit cb26f42

File tree

7 files changed

+33
-5
lines changed

7 files changed

+33
-5
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# splat Release Notes
22

3+
### 0.36.4
4+
5+
* Add more checks for texture and palette segments to have a correct size in their yaml entries, ensuring their `width`/`height` or `size` attributes match the sizes relative to other segments.
36
* Fix `gfx` segments sometimes not picking up properly the corresponding typed reference.
47

58
### 0.36.3

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ The brackets corresponds to the optional dependencies to install while installin
2121
If you use a `requirements.txt` file in your repository, then you can add this library with the following line:
2222

2323
```txt
24-
splat64[mips]>=0.36.3,<1.0.0
24+
splat64[mips]>=0.36.4,<1.0.0
2525
```
2626

2727
### Optional dependencies

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[project]
22
name = "splat64"
33
# Should be synced with src/splat/__init__.py
4-
version = "0.36.3"
4+
version = "0.36.4"
55
description = "A binary splitting tool to assist with decompilation and modding projects"
66
readme = "README.md"
77
license = {file = "LICENSE"}

src/splat/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
__package_name__ = __name__
22

33
# Should be synced with pyproject.toml
4-
__version__ = "0.36.3"
4+
__version__ = "0.36.4"
55
__author__ = "ethteck"
66

77
from . import util as util

src/splat/segtypes/n64/ci.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ def out_path_pal(self, pal_name) -> Path:
4848
return options.opts.asset_path / self.dir / f"{out_name}{type_extension}.png"
4949

5050
def split(self, rom_bytes):
51+
self.check_len()
52+
5153
assert self.palettes is not None
5254
if len(self.palettes) == 0:
5355
# TODO: output with blank palette

src/splat/segtypes/n64/img.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,10 @@ def check_len(self) -> None:
6464
log.error(
6565
f"Error: {self.name} should end at 0x{self.rom_start + expected_len:X}, but it ends at 0x{self.rom_end:X}\n(hint: add a 'bin' segment after it)"
6666
)
67+
elif actual_len < expected_len:
68+
log.error(
69+
f"Error: {self.name} should end at 0x{self.rom_start + expected_len:X}, but it ends at 0x{self.rom_end:X}"
70+
)
6771

6872
def out_path(self) -> Path:
6973
type_extension = f".{self.type}" if self.image_type_in_extension else ""

src/splat/segtypes/n64/palette.py

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,21 @@ def __init__(self, *args, **kwargs):
2323
f"segment {self.name} needs to know where it ends; add a position marker [0xDEADBEEF] after it"
2424
)
2525

26-
if not isinstance(self.yaml, dict) or "size" not in self.yaml:
26+
if isinstance(self.yaml, dict) and "size" in self.yaml:
27+
yaml_size: int = self.yaml["size"]
28+
if isinstance(self.rom_start, int) and isinstance(self.rom_end, int):
29+
rom_len = self.rom_end - self.rom_start
30+
if rom_len < yaml_size:
31+
log.error(
32+
f"Error: {self.name} has a `size` value of 0x{yaml_size:X}, but this is smaller than the actual rom size of the palette (0x{rom_len:X}, start: 0x{self.rom_start:X}, end: 0x{self.rom_end:X})"
33+
)
34+
elif rom_len > yaml_size:
35+
log.error(
36+
f"Warning: {self.name} has a `size` value of 0x{yaml_size:X}, but this is larger than the end of the palette (0x{rom_len:X}, start: 0x{self.rom_start:X}, end: 0x{self.rom_end:X})\n(hint add a 'bin' segment after this palette with address 0x{self.rom_end:X})",
37+
)
38+
39+
size = yaml_size
40+
else:
2741
assert self.rom_end is not None
2842
assert self.rom_start is not None
2943
actual_len = self.rom_end - self.rom_start
@@ -39,7 +53,11 @@ def __init__(self, *args, **kwargs):
3953
log.error(
4054
f"Error: {self.name} (0x{actual_len:X} bytes) is not a valid palette size ({', '.join(hex(s) for s in VALID_SIZES)})\n{hint_msg}"
4155
)
56+
size = actual_len
57+
else:
58+
size = 0
4259

60+
self.palette_size: int = size
4361
self.global_id: Optional[str] = (
4462
self.yaml.get("global_id") if isinstance(self.yaml, dict) else None
4563
)
@@ -61,7 +79,8 @@ def iter_in_groups(iterable, n, fillvalue=None):
6179
return palette
6280

6381
def parse_palette(self, rom_bytes) -> List[Tuple[int, int, int, int]]:
64-
data = rom_bytes[self.rom_start : self.rom_end]
82+
assert self.rom_start is not None
83+
data = rom_bytes[self.rom_start : self.rom_start + self.palette_size]
6584

6685
return N64SegPalette.parse_palette_bytes(data)
6786

0 commit comments

Comments
 (0)