-
Notifications
You must be signed in to change notification settings - Fork 2
ZSO
ZSO is a compressed variant of the standard ISO disc image. OPL decompresses each sector on the fly using LZ4, so the PS2 sees a normal disc — but your storage device holds a smaller file. Support was added in OPL 1.2.0 and works across all storage backends that use OPL's built-in core.
ℹ Neutrino does not support ZSO
If a game is configured to launch via the Neutrino core but its image is a
.zso file, OPL shows an on-screen warning. For most backends (USB, MX4SIO, iLink, MMCE,
SMB, and the internal HDD) it then falls back to its own built-in core and the game still launches —
just via the OPL core instead of Neutrino. Exception: for games sourced from UDPBD or UDPFS
the launch is aborted entirely rather than falling back, because those network transports have no
built-in OPL core — Neutrino is their only launch path. To use Neutrino for a game on any backend you
must first decompress the image back to .iso (see below).
ZSO conversion is done on your PC before copying files to the PS2's storage device. You need:
- Python 3 — any recent 3.x release.
-
lz4 Python library — install once with
pip install lz4. -
ziso.py — included in the
pc/folder of the OPL source repository.
Pass -c 2 to compress. The 2 selects high-compression mode (LZ4 HC), which
gives the best ratio. Values 1–12 all compress; values above 1 use LZ4 high-compression. Compression
level 1 uses standard LZ4 (faster, slightly larger output).
python ziso.py -c 2 "input.iso" "output.zso"
The script prints a running percentage and a final summary showing the compressed size and compression ratio. Blocks that do not compress well (within 5% of the original size) are stored uncompressed inside the ZSO file automatically — no manual tuning needed.
| Flag | Default | Effect |
|---|---|---|
-c <1–12> |
required | Compression level. 1 = standard LZ4, 2–12 = LZ4 high-compression. |
-c 0 |
— | Decompress a ZSO back to ISO. |
-b <size> |
2048 | Block size in bytes. Must be a multiple of 2048. Default matches a CD/DVD sector. |
-m |
off | Enable multiprocessing — uses all CPU cores; significantly faster on large ISOs. |
-t <percent> |
95 | Compression threshold. If a compressed block is larger than this percentage of the original, it is stored uncompressed. |
-a <align> |
0 | Padding alignment. 0 = smallest output (slower seek). 6 = faster random access (slightly larger file). |
-h |
— | Print usage help. |
Pass -c 0 to decompress. This is the only way to use the image with Neutrino or any
other tool that does not understand the ZSO container.
python ziso.py -c 0 "input.zso" "output.iso"
Place the .zso file in the same folder as your ISOs — OPL scans for both
.iso and .zso extensions in the same directory sweep. No extra
configuration is required; OPL detects the ZSO magic header at launch time and initialises the
LZ4 decompressor automatically.
ℹ File naming
ZSO files follow the same naming conventions as ISO files. A game named
SLES_123.45.GameTitle.zso (OPL legacy GameID format) or a free-form name ending in
.zso are both recognised. The extension comparison is case-insensitive, so
.ZSO and .zso are treated identically by the file scanner.
Use the latest version of HDL-Dump to install a ZSO image to the internal HDD in the same way you would install a plain ISO. The APA partition will contain the compressed data; OPL reads the ZSO magic from the partition header and initialises the decompressor before any sector reads.
Copy the .zso file to the mass storage area of the exFAT drive exactly as you would
a plain ISO. OPL's BDM path scans for .iso and .zso together.
The Neutrino external core does not implement ZSO decompression. When a game is set to use
Neutrino in per-game settings and the image is a .zso file, OPL detects this before
launch and:
- Displays a brief on-screen warning.
- For USB, MX4SIO, iLink, MMCE, SMB, and the internal HDD: overrides the core selection back to the built-in OPL core for that launch.
- Launches the game normally using OPL — except for UDPBD/UDPFS games, where the launch is cancelled instead, since those transports have no built-in OPL core to fall back to.
The per-game Neutrino setting is not permanently changed — it will still show as enabled next
time you open per-game settings. To use Neutrino for the game permanently, decompress the image
to ISO first (see above), then copy the .iso in place of
the .zso.
The same fallback applies on the internal HDD: a ZSO partition that has Neutrino selected will fall back to OPL with a warning.
| Task | Command |
|---|---|
| Install dependency | pip install lz4 |
| Compress ISO → ZSO | python ziso.py -c 2 game.iso game.zso |
| Compress, multicore | python ziso.py -c 2 -m game.iso game.zso |
| Decompress ZSO → ISO | python ziso.py -c 0 game.zso game.iso |
| HDD install | Use HDL-Dump (same as ISO) |
How does the on-the-fly decompression work?
A ZSO file starts with a 24-byte header (magic ZISO, total uncompressed size,
block size, version, and alignment). Following the header is an index table — one 32-bit entry
per 2048-byte sector — that stores the file offset of each compressed block. The MSB of each
index entry is a "plain" flag: when set, that block is stored uncompressed (it did not meet the
compression threshold).
OPL's IOP-side ZSO module reads the header and index table at mount time. On every sector read request from cdvdman, it looks up the block offset in the index, reads the compressed bytes, and decompresses them with LZ4 into a per-sector buffer before handing the data to the EE. Because LZ4 decompression is fast, the impact on load times is typically small — and the smaller file size can reduce seek times on slower devices, partially offsetting the decompression cost.
For images larger than 2 GB, the script automatically sets the alignment field so that block offsets shifted by the alignment value still fit in the 31-bit non-flag portion of each index entry.
Source: zso.html @ fc2e13154e51. Read on the documentation website.
Start here
Storage and networking
- USB, MX4SIO and iLink
- MMCE
- Internal HDD: APA and exFAT
- SMB shares
- Network boot: UDPFS and UDPBD
- HTTP
- NBD server
Games and features
- Neutrino core
- PS1: POPStarter and Ember
- Per-game settings
- Virtual memory cards
- GSM video modes
- In-game reset
- Cheats
- PADEMU
- RetroAchievements
- Apps
Interface and customization
Help and reference
- Troubleshooting
- ZSO format
- Backward-compatible PS3
- Credits and sources
- Features in other forks
- Project overview
Detailed references
- Complete repository guide
- Rolling release reference
- APA hard disk safety and code 402
- Autolaunch and global settings
- Controls reference
- GSM reference
- HTTP reference
- In-game reset reference
- Folders, parental lock and audio
- Language maintenance
- MX4SIO launch reference
- Neutrino reference
- PADEMU reference
- RetroAchievements reference
- Theme engine: full authoring reference
- PS1/VCD reference
- HTTP server conformance tools
- APA recovery tool