nsZip - NSP compressor/decompressor to reduce storage

nsZip is an open source PC tool to lossless compress/decompress NSP files in order to save a lot of storage while all NCA files keep their exact same hash. [prebreak]1[/prebreak]
But it’s more than just a compression. A lot of data like NDV0 partitions or fragment NCA3 files will be removed while compressing and exactly recreated when decompressed which saves even more space especially on updates higher than v65536.
In addition, the NSZ format was designed with emulators in mind so adding NSZ support to Yuzu will be possible in the future and because NSZ contains decrypted NCAs no keys would be needed to only extract game files. As compression algorithm Zstandard is used to multithreaded compress 256 KB chunks while uncompressible chunks are stored uncompressed. That way NSPZ/XCIZ allows random read access. Zstandard has a 43MB/s compression and 7032MB/s decompression speed on an 8 threaded CPU at level 18 while having one of the best compression ratios compared to other compression algorithms.

How compressing works: NSP => extracted NSP => decrypted NCAs => trim fragments => compressing to NSZ => verify correctness => repacking NSPZ file
How decompressing works: NSPZ file => extracted NSPZ => decompress NSZ => untrim fragments => encrypt NCAs => verify correctness => repack as NSP

Check out my GitHub page to report bugs, follow this project, post your suggestions or contribute.
GitHub link: https://github.com/nicoboss/nsZip/releases

For the new homebrew compatible NSZ format please see https://github.com/nicoboss/nsz
NSZ thread: https://gbatemp.net/threads/nsz-homebrew-compatible-nsp-xci-compressor-decompressor.550556/
Until NSZ support is implemented in nsZip I don't see why you want to use it instead of NSZ

Block compressed NSZ is very similar to the beautiful NSPZ format just without all the unnecessarily complexity which made NSPZ unfeasible for other software to implement. I might remove NSPZ/XCIZ support in the future if I see that there's no point in keeping it to not confuse people.

Differences between NSZ and NSPZ:

NSPZ/XCIZ:
- GitHub Project: https://github.com/nicoboss/nsZip
- Always uses Block compression allowing random read access to play compressed games in the future
- Decrypts the whole NCA
- Trims NDV0 fragments to their header and reconstructs them
- Only supported by nsZip and unfortunately doesn't really have a future

NSZ/XCZ:
- GitHub Project: https://github.com/nicoboss/nsz
- Uses solid compression by default. Block compression can be enabled using the -B option. Block compression will be the default for XCZ
- Decrypts all sections while keeping the first 0x4000 bytes encrypted. Puts informations needed to encrypt inside the header.
- Deleted NDV0 fragments as they have no use for end users as they only exist to save CDN bandwidth
- Already widely used. Supported by Tinfoil, SX Installer v3.0.0 and probably a lot of other software in the future


nsZip v2.0.0 preview 2:
  • Fixed XCI to XCIZ compression
nsZip v2.0.0 preview 1:
  • New UI made using WPF instead of WinForms
  • Huge performance improvements
    • Directly decrypt the NSP without extracting it first
    • Directly decompressing NSPZ files without extracting them first
    • Huge encrypting speed increase
    • Huge SHA-256 verification speed increase
    • Enhanced compressing multithreading
    • Support for up to 400 CPU Cores
  • Improved game compatibility
  • Command Line support
  • More settings
Version 1.1.0 Changelog:
  • Added support for over multiple NCAs splitted NDV0 fragment trimming
Version 1.0.1 Changelog:
  • Let the user continue when detecting a yet unimplemented multifile NDV0 fragment. I'll add proper support for that unimplemented multifile NDV0 fragment format in the following days.
  • The compression level can now be changed (tradeoff between speed and compression ratio)
  • The block size can now be changed (tradeoff between random access time and compression ratio)
Future planes:
  • NSZ implementation
FAQ:
Q: It prod.keys not found!
A: Dump them using Lockpick and copy them to %userprofile%/.switch/prod.keys
Q: How much storage does this save?
A: It depends on the game. The compressed size is usually around 40-80% of the original size.
Q: What about XCI?
A: Compression to XCIZ is supported, but XCIZ to XCI recreation is still in development.
Q: The program throws an error or seems to behaves not as intended!
A: Open an issue on my GitHub page where you give me exact steps how to reproduce.
Q: Does this compress installed games?
A: Not now but it's planned for the far future.

Screenshot:

nsZip_Screenshot.png
 
Last edited by nicoboss,

nicoboss

Well-Known Member
OP
Member
Joined
Feb 1, 2019
Messages
132
Trophies
0
Age
26
XP
1,196
Country
Switzerland
Jaja i went to that link and to be honest i have no idea what i'm looking at, i read the (readme) and i see "requirements" but can't find any instructions on how exactly its done. Unless i'm looking at the wrong thing.
First install python from https://www.python.org/downloads/release/python-374/ and run "python -3 -m pip install -r requirements.txt" inside the main folder to install all the requirements. Then copy your dump and keys.txt into the compressor folder. Inside there execute something like "python nsz.py --level 17 -C dump.nsp"

I'm going to go through my code afterwork, to see if extra data at the very end will break clients. I know it will issue warnings, but it may still be successful. If so, we should move it to the very end of the file, and have a footer rather than a header so it can be read easily and existing clients can use the new format.

I'm digging through the zstandard protocol, it is possible to seek with a single flat stream, but it is indeed a pain in the butt. You are correct that it is probably best from a complexity standpoint to only support seeking with chunked content.

Are you sure you only want to support fixed size chunks? I do not care about seeking, so I will defer to your judgement call on that. I just think variable sized chunks would improve compression ratios at the expense of only a little added complexity. A Binary search would be fast.
With my currently implementation the NCZBLOCKS metadata is just after the NCZSECTN metadata. I have nothing against putting them at the end but kind of useless as the non-solid compressed files won't work with the current implementation of your homebrew anyways. With an updated version of your homebrew we could put them anywhere we want. With my current implementation non-solid compression is an optional future that can be enabled by specifying a block size over command line arguments. If no block size is specified the exact same file will be produced as your tool does it right now.
For the question regarding dynamic decompressed block size. It's would be quite hard to do such a thing on NCA layer as the actual files the game uses are one level deeper. Because of this game files can't be easily recognized as such. Generally, it's quite questionable if it is really worth it. ZStandard is quite good compressing small chunks and not much compression ratio is lost compared to a fully solid compression especially when choosing 512 KB instead of 256 KB as block size. The difference between static chunk and "intelligent" ones would be even lower. For the access time binary search indeed wouldn't be that bad as it's still O(log n) while n will be around 40000 on a 10 GB game resulting in only 14 compression required for it to find the block it needs which is basically nothing compared the I/O and decompression time. With NSZ type 2 I purposed such a non-static dynamic sized format but never implemented it as I just can't see any use of it. Maybe let’s just put an indicator inside NCZBLOCKS for meta version and type in case we ever want to add additional futures it but for now let’s keep the decompressed block size statically.
 
Last edited by nicoboss,

blawar

Developer
Developer
Joined
Nov 21, 2016
Messages
1,708
Trophies
1
Age
40
XP
4,311
Country
United States
First install python from https://www.python.org/downloads/release/python-374/ and run "python -3 -m pip install -r requirements.txt" inside the main folder to install all the requirements. Then compy yur dump and keys.txt into the compressor folder. Inside there execute something like "python nsz.py --level 17 -C tdump.nsp"


With my currently implementation the NCZBLOCKS metadata is just after the NCZSECTN metadata. I have nothing against putting them at the end but kind of useless as the non-solid compressed files won't work with the current implementation of your homebrew anyways. With an updated version of your homebrew we could put them anywhere we want. With my current implementation non-solid compression is an optional future that can be enabled by specifying a block size over command line arguments. If no block size is specified the exact same file will be produced as your tool does it right now.


For the question regarding dynamic decompressed block size. It's would be quite hard to do such a thing on NCA layer as the actual files the game uses are one level deeper. Because of this game files can't be easily recognized as such. Generally, it's quite questionable if it is really worth it. ZStandard is quite good compressing small chunks and not much compression ratio is lost compared to a fully solid compression especially when choosing 512 KB instead of 256 KB as block size. The difference between static chunk and "intelligent" ones would be even lower. For the access time binary search indeed wouldn't be that bad as it's still O(log n) while n will be around 40000 on a 10 GB game resulting in only 14 compression required for it to find the block it needs which is basically nothing compared the I/O and decompression time. With NSZ type 3 I purposed such a non-static dynamic sized format but never implemented it as I just can't see any use of it. Maybe let’s just put an indicator inside NCZBLOCKS for meta version and type in case we ever want to add additional futures it but for now let’s keep the decompressed block size statically.


Hello @nicoboss ,

Thats fine, i'll defer to your judgement, I just wanted to talk it out before we solidified the spec because I loathe changing specs later and breaking backwards compatibility. The spec looks good, with a few minor tweaks:

1) change the magic to 8 bytes (its currently 9) for alignment purposes.
2) change the block size field in the header to the number of bits (8 = 256 bytes, 16 = 65536 bytes etc) to enforce a power of two block size (again for alignment purposes)

I can update the clients this weekend. Unless there are any other changes you want.

Thanks,
-Blake

edit: also 4096 is much too small for a floor on the block size. The switch and the PC have plenty of ram, I would recommend a minimum block size of at least 16MB.
 
Last edited by blawar,

proffk

Well-Known Member
Member
Joined
Aug 14, 2013
Messages
575
Trophies
1
XP
1,082
Country
United Kingdom
Its quite difficult figuring out how to get to blawar script to work. I think a simple gui or tool would make things easier.
 

Mthodmn101

Well-Known Member
Member
Joined
Jan 31, 2008
Messages
650
Trophies
1
XP
1,730
Country
United States
I only asked a logical question. If your going to reply with an attitude like don't bother.

I see even reading my simple response was too difficult for you.

--------------------- MERGED ---------------------------

I see even reading my simple response was too difficult for you.

Hell, heres a stupid batch script. Rename a text with this to .bat and run

for %%i in (F:\*.nsp) do nsz.py --level 17 -C "%%i"

just change the F:\ to wherever ur nsps are
 

Halo69

Well-Known Member
Newcomer
Joined
Aug 6, 2019
Messages
58
Trophies
0
Age
46
XP
118
Country
United States
First install python from https://www.python.org/downloads/release/python-374/ and run "python -3 -m pip install -r requirements.txt" inside the main folder to install all the requirements. Then copy your dump and keys.txt into the compressor folder. Inside there execute something like "python nsz.py --level 17 -C dump.nsp"


With my currently implementation the NCZBLOCKS metadata is just after the NCZSECTN metadata. I have nothing against putting them at the end but kind of useless as the non-solid compressed files won't work with the current implementation of your homebrew anyways. With an updated version of your homebrew we could put them anywhere we want. With my current implementation non-solid compression is an optional future that can be enabled by specifying a block size over command line arguments. If no block size is specified the exact same file will be produced as your tool does it right now.
For the question regarding dynamic decompressed block size. It's would be quite hard to do such a thing on NCA layer as the actual files the game uses are one level deeper. Because of this game files can't be easily recognized as such. Generally, it's quite questionable if it is really worth it. ZStandard is quite good compressing small chunks and not much compression ratio is lost compared to a fully solid compression especially when choosing 512 KB instead of 256 KB as block size. The difference between static chunk and "intelligent" ones would be even lower. For the access time binary search indeed wouldn't be that bad as it's still O(log n) while n will be around 40000 on a 10 GB game resulting in only 14 compression required for it to find the block it needs which is basically nothing compared the I/O and decompression time. With NSZ type 2 I purposed such a non-static dynamic sized format but never implemented it as I just can't see any use of it. Maybe let’s just put an indicator inside NCZBLOCKS for meta version and type in case we ever want to add additional futures it but for now let’s keep the decompressed block size statically.
Ok so i installed python and also downloaded the embeddable zip, but not sure if you mean to run "python -3 -m pip install -r requirements.txt" thru a command promp (which i do but i get an error) or is something i need to find and run (which i cannot find)
 

Taorn

Well-Known Member
Member
Joined
May 27, 2017
Messages
257
Trophies
0
Age
53
XP
1,840
Country
United States
Ok so i installed python and also downloaded the embeddable zip, but not sure if you mean to run "python -3 -m pip install -r requirements.txt" thru a command promp (which i do but i get an error) or is something i need to find and run (which i cannot find)

Yes, you need to run it from a command line. What did the error say? Did you mark the option "add to path" when installing Python?
 

Halo69

Well-Known Member
Newcomer
Joined
Aug 6, 2019
Messages
58
Trophies
0
Age
46
XP
118
Country
United States
Hello @nicoboss ,

Thats fine, i'll defer to your judgement, I just wanted to talk it out before we solidified the spec because I loathe changing specs later and breaking backwards compatibility. The spec looks good, with a few minor tweaks:

1) change the magic to 8 bytes (its currently 9) for alignment purposes.
2) change the block size field in the header to the number of bits (8 = 256 bytes, 16 = 65536 bytes etc) to enforce a power of two block size (again for alignment purposes)

I can update the clients this weekend. Unless there are any other changes you want.

Thanks,
-Blake

edit: also 4096 is much too small for a floor on the block size. The switch and the PC have plenty of ram, I would recommend a minimum block size of at least 16MB.
@blawar i'm using NSC builder (NSB_093py) after compressing was done, why the NSZ file bigger then the NSP? NSP=606 KB NSZ=764KB but it did shrinked for zelda: NSP= 5.84gb NSZ=2.74gb
So this is basically only to save storage on PC and not on the switch? I installed the NSZ and when i checked the storage on the switch it installed the whole storage of 5.84gb
Yes, you need to run it from a command line. What did the error say? Did you mark the option "add to path" when installing Python?
Yes i marked that option but when i run that command i get syntax error
 
Last edited by Halo69,

Halo69

Well-Known Member
Newcomer
Joined
Aug 6, 2019
Messages
58
Trophies
0
Age
46
XP
118
Country
United States
@nicoboss hows that new release coming along where we'll be able to install nspz? Not sure if you going to have one but good to ask. Now im using NSC_builder to compress it to nsz but to be honest that doesnt seem to save to many storage, for example after compression:
NSP: 1.77gb NSZ: 1.61gb
NSP: 559 gb NSZ: 5:45 gb
NSP: 12.9 gb NSZ: 12.6 gb
With those compression sizes might as well just stay with NSP files, all that time it took to compress for barely any save storage. Am i right?
 

nicoboss

Well-Known Member
OP
Member
Joined
Feb 1, 2019
Messages
132
Trophies
0
Age
26
XP
1,196
Country
Switzerland
7eefODu.png


this is the error I get when doing astral chain did I do something wrong?
The latest pre-release of nsZip is extremely outdated. This error is probably fixed in master so either build master by your own, wait for a new build, ask me for a build and I will send you one or just the NSZ compressor python script from https://github.com/nicoboss/nsz instead and compress into the new NSZ file format. There’s now an option for NSZ to support block based compression and will most likely be the successor to nsZip's currently used NSPZ file format as it's much easier for homebrew developers to support and so is already compatible with blawar Tinfoil 5.00.

@nicoboss hows that new release coming along where we'll be able to install nspz? Not sure if you going to have one but good to ask. Now im using NSC_builder to compress it to nsz but to be honest that doesnt seem to save to many storage, for example after compression:
NSP: 1.77gb NSZ: 1.61gb
NSP: 559 gb NSZ: 5:45 gb
NSP: 12.9 gb NSZ: 12.6 gb
With those compression sizes might as well just stay with NSP files, all that time it took to compress for barely any save storage. Am i right?
NSPZ and NSZ booth use the same compression algorithm. If you use NSZ's default sulid compression method at level 18 you should get a better compression ratio then on nsZip at the default compression level "[Lv. 18] Great" if not please report it as in that case something with NSZ is probably wrong. What compression ratio you get highly depends on the game you compress so try some other games and you should see way better results. nsZip will probably switch to the NSZ format in the future so NSZ is probably the way to go.
 

Halo69

Well-Known Member
Newcomer
Joined
Aug 6, 2019
Messages
58
Trophies
0
Age
46
XP
118
Country
United States
The latest pre-release of nsZip is extremely outdated. This error is probably fixed in master so either build master by your own, wait for a new build, ask me for a build and I will send you one or just the NSZ compressor python script from https://github.com/nicoboss/nsz instead and compress into the new NSZ file format. There’s now an option for NSZ to support block based compression and will most likely be the successor to nsZip's currently used NSPZ file format as it's much easier for homebrew developers to support and so is already compatible with blawar Tinfoil 5.00.


NSPZ and NSZ booth use the same compression algorithm. If you use NSZ's default sulid compression method at level 18 you should get a better compression ratio then on nsZip at the default compression level "[Lv. 18] Great" if not please report it as in that case something with NSZ is probably wrong. What compression ratio you get highly depends on the game you compress so try some other games and you should see way better results. nsZip will probably switch to the NSZ format in the future so NSZ is probably the way to go.
Oh ok, imma try to switch it to lv 18 cause default is lv 17 and see the results. I kept the threads at 0 cause its the default, should i change that? Also is this only to save space on PC and not on the switch? When i installed a nsz file i saw it installed the actual size.
 

nicoboss

Well-Known Member
OP
Member
Joined
Feb 1, 2019
Messages
132
Trophies
0
Age
26
XP
1,196
Country
Switzerland
Oh ok, imma try to switch it to lv 18 cause default is lv 17 and see the results. I kept the threads at 0 cause its the default, should i change that? Also is this only to save space on PC and not on the switch? When i installed a nsz file i saw it installed the actual size.
Lv. 17 vs lv 18 won't make a huge difference but level 17 is dumb anyways as it’s compression speed for compression ratio is pretty bad. Some games just don't compress very well. Threads don't do anything on latest NSZ version. Multithreaded compression for block compression will be implemented in the following days. NSZ currently only saves storage on PC and increases transfer and installation speed. There will probably be NSZ Yuzu support in the future and maybe NSZ CFW integration.
 

nicoboss

Well-Known Member
OP
Member
Joined
Feb 1, 2019
Messages
132
Trophies
0
Age
26
XP
1,196
Country
Switzerland
Does this tool use the CPU and GPU for the operations?
CPU but the current solid compression algorithm is single core. Block compression will be multithreaded soon but will trade off compression ratio for random read access and multithreading. A solid Compression algorithm on GPU wouldn't make any sense as it could only use a single GPU core and so would be way slower than when using a single CPU core - not even sure if implementing zStandard on GPU would even be possible but definitely not something you want to do as GPUs are single instruction multiple data processors while CPUs are multiple instructions multiple data processors. Better use a tenser processing unit which is a multiple instructions single data streaming processor if you really want to use compression specialized hardware – only bad google only lets you rent but not buy them but feel free to implement zStandard on an FPGA board if you really want to. I would interface such specialized hardware in all my software if ever somebody bothers creating a specialized circuit for zStandard but I really don’t think it’s work it as CPUs are pretty good running compression algorithms.
 
Last edited by nicoboss,

Site & Scene News

Popular threads in this forum

General chit-chat
Help Users
  • No one is chatting at the moment.
    Veho @ Veho: Nope.