Compress and decompress Racjin game archives (CFC.DIG / CDDATA.DIG)
Project description
racjin
Python implementation of the Racjin compression algorithm used in PS2/PSP/Wii game archives.
Handles CFC.DIG and CDDATA.DIG archive files found in games by Racjin and other Japanese studios.
If this helped you, consider buying me a coffee ☕
Supported Games
- Fullmetal Alchemist and the Broken Angel (PS2)
- Fullmetal Alchemist 2: Curse of the Crimson Elixir (PS2)
- Fullmetal Alchemist 3: Kami o Tsugu Shoujo (PS2)
- Naruto: Uzumaki Chronicles 1 & 2 (PS2)
- Bleach: Soul Carnival 2 (PSP)
- Naruto Shippuden: Legends: Akatsuki Rising (PSP)
- Naruto Shippuden: Ultimate Ninja Impact (PSP)
- Other titles using the same archive format
Installation
uv add racjin
Or with pip:
pip install racjin
For development:
uv sync
CLI Usage
Extract an entire archive
# Auto-detects format and endianness
racjin extract CDDATA.DIG output/
# Specify format explicitly
racjin extract CFC.DIG output/ --format cfc
# For Wii/GameCube (big-endian)
racjin extract CDDATA.DIG output/ --big-endian
Compress / decompress individual files
# Decompress (requires known decompressed size)
racjin decompress compressed.bin decompressed.bin --size 577152
# Compress
racjin compress input.bin compressed.bin
Python API
from racjin import compress, decompress
# Decompress
with open("compressed.bin", "rb") as f:
compressed_data = f.read()
decompressed = decompress(compressed_data, expected_size)
# Compress
with open("input.bin", "rb") as f:
original_data = f.read()
compressed = compress(original_data)
# Round-trip
assert decompress(compress(data), len(data)) == data
Algorithm
The Racjin compression uses 9-bit tokens packed into a bitstream:
- Bit 8 = 1: Literal byte (lower 8 bits stored directly)
- Bit 8 = 0: Back-reference using a context-sensitive sliding window
- Bits 3-7: 5-bit frequency index
- Bits 0-2: 3-bit length (actual length = value + 1, max 8 bytes)
- Window is a 8192-entry table indexed by
(freq_index + last_byte * 32)
Tokens are folded using a rotating bit shift (0-7), packing 8 tokens (72 bits) into 9 bytes.
Archive Formats
Three structure variants are supported:
| Format | Field Layout | Notes |
|---|---|---|
cfc |
offset, comp_size, section_count|flags, decomp_size | Most common (post-2005) |
cddata |
offset, decomp_size, section_count, comp_size | All sizes in sectors (2004-era) |
cddata-old |
offset, size, section_count | No compression (pre-2004) |
All offsets are in 2048-byte disc sectors.
Credits
Algorithm reverse-engineered by Raw-man (C++ implementation). This is a Python port.
License
GPL-3.0 (same as the reference implementation)
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file racjin-1.0.1.tar.gz.
File metadata
- Download URL: racjin-1.0.1.tar.gz
- Upload date:
- Size: 19.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b14ebe87bc6097b693df3c74b37d03281d9b96596e6aad10003625042b9ec0a4
|
|
| MD5 |
e915fa6666c12e5ddc595d7f6f050df7
|
|
| BLAKE2b-256 |
fba67d6f03f05dcb7fb747700ca9263135d93c99e69e8e217605a59f2eac4cb8
|
File details
Details for the file racjin-1.0.1-py3-none-any.whl.
File metadata
- Download URL: racjin-1.0.1-py3-none-any.whl
- Upload date:
- Size: 19.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f2f68334b8dc126ca1a70ed8c608288ebc2de9c9feb50fa3ae672e5a79acde59
|
|
| MD5 |
952f11ba871b0cabbc6364418955ab6e
|
|
| BLAKE2b-256 |
caca1e5b137f6adb20f2ea397f795a597335e7120ff6c7c5e5dd48ec6fe32123
|