PyPVR is an unofficial, modern tool written in Python for encoding / decoding PowerVR2 images used by SEGA Dreamcast and SEGA Naomi.
Originally made for Blender NaomiLib addon, and used in translation projects such as SGGG and Shiren Gaiden, PyPVR is now a standalone tool designed for modders and developers alike.
Thanks to Rob2d for K-means idea, VQ compression algorithms can provide quality VQ encoding results.
VQ gradient image compression test:
WinPVR / PVRConv / PyPVR

Download
https://github.com/VincentNLOBJ/PyPVR
Main Features
- Python 3.9.12+ Windows application
- All texture modes, pixel formats, palettes and PVR variations used by SEGA's SDK are supported
- 2 VQ quality algorithms
- Drag & drop interface / Command line tool
- Binary container (.afs .bin .dat .pvm .tex) extraction / reimport
- [DEVS] Batch encoding chain via .txt
- [DEVS] Python module to integrate PyPVR
https://ko-fi.com/vincentnl
https://patreon.com/vincentnl
Credits
- Rob2d for K-means idea HQ VQ
- Egregiousguy for YUV420 decoding
- Kion for SmallVQ mipmaps data
- tvspelsfreak for SR conversion to normal map
- MetalliC for hardware knowledge
- Claude for Numpy code refactoring and optimization
- My daughter for logo design! ♥
- Esppiral
- Alexvgz
- PkR
- Derek (ateam)
- dakrk
- neSneSgB
- woofmute
- TVi
- Sappharad
PyPVR Drag & Drop - Quick Steps
Step 1 - Extraction:
Drag files into PyPVR (container or .PVR / .PVP)
Step 2 - Modify Images:
Use your preferred software (Photoshop or Gimp recommended)
Step 3 - Reimport:
Drag pvr_log.txt on PyPVR for quick reimport of all images.
-----------

PyPVR Command Line Tool - Table of Contents
- DECODE: PVR --> IMG
- DECODE OPTIONS
- ENCODE: IMG --> PVR
- ENCODE OPTIONS
- EXAMPLES
Convert one or more .PVR files to .PNG or .BMP.
If a matching .PVP exists, the palette is applied.
Usage:
Code: Select all
pypvr.py <infile1.PVR> -<options>
2. DECODE OPTIONS
Code: Select all
-fmt <img_format> Image format: png | bmp
-o <out_dir> Output directory
-flip Flip vertically
-silent No screen prints
-nolog Do not create pvr_info.txt
-dbg Debug mode
-usepal <pvp_file> Use external PVP
-act Convert PVP to ACT
-nopvp Skip PVP extraction
3. ENCODE: IMG --> PVR
Encode an image to .PVR/.PVP if palettized.
Usage:
Code: Select all
pypvr.py <infile> -<options>
4. ENCODE OPTIONS
Color Formats:
Code: Select all
-565 RGB
-1555 ARGB 1bit alpha
-4444 ARGB 4bit alpha
-8888 ARGB 8bit alpha
-yuv422 YUV422
-bump Normal Map
-555 PCX Format (Use 1555 instead)
-yuv420 For yuv converter, used in .SAN files
-p4bpp Palette 4bpp placeholder
-p8bpp Palette 8bpp placeholder
Code: Select all
-tw Square Twiddled
-twre Rectangular Twiddled
-re Rectangular
-st Stride
-twal Alias Twiddled
-pal4 16-color Palette
-pal8 256-color Palette
-vq Vector Quantized
-svq Small VQ
-bmp Bitmap
Code: Select all
-mm Mipmaps
-near Nearest resampling
-flip Flip vertically
-cla Clean alpha (improve VQ quality)
-gi <n> GBIX header
-gitrim Short GBIX
-pvptrim Trim palette
-pvpbank <n> PVP bank
-nopvp No PVP output
-vqa1 VQ Algorithm 1
-vqa2 VQ Algorithm 2
-vqi <n> VQ iterations
-vqs <n> VQ seed
5. EXAMPLES
Decode PVR to Image
Code: Select all
decode "file1.PVR" to "file1.png"
> pypvr.py "file1.PVR"
decode all pvr files to output folder
> pypvr.py "*.pvr" -o "c:\images"
decode "infile1.PVR" to "file1.png", vertical flip, output folder
> pypvr.py "infile1.PVR" -png -flip -o "c:\decoded"
Code: Select all
encode "test.png" to "test.PVR", auto settings.
> pypvr.py "test.png"
batch encode all images speicfied in log file
> pypvr.py "c:\image_dir\pvr_log.txt"
encode all .png files to output folder, auto settings.
> pypvr.py "*.png" -o "c:\pvr_dir"
encode "test.png" to "test.PVR", color format 1555 , twiddled, global index 0.
> pypvr.py "test.png" -1555 -tw -gi 0
encode "test.png" to "test.PVR", color format 565, VQ compress
> pypvr.py "test.png" -565 -vq
Code: Select all
scan and decode all valid PVR image files stored in the archive, creates a "pvr_log.txt" for reimport
> pypvr.py "unknown.DAT"
encodes modified images, and reimports back to the binary container
> pypvr.py "c:\myfolder\pvr_log.txt"
Developers Usage
Batch Encoding:
Create a pvr_log.txt file with images to be encoded, then feed it to pypvr.py
Code: Select all
IMAGE FILE : C:\Image1.png
TARGET DIR : C:\PVR
ENC PARAMS : -vq -565 -mm
---------------
IMAGE FILE : C:\Image2.png
TARGET DIR : C:\PVR
ENC PARAMS : -pal8 -1555 -mm
---------------
Code: Select all
pypvr.py "pvr_log.txt"
Encode and decode from / to PIL Image object
Code: Select all
image_buffer = Pypvr.Decode('-buffer', buff_pvr = data , buff_pvp = palette ).get_image_buffer()
pvr_buffer = Pypvr.Encode('-buffer -vq',PILImage).get_pvr_buffer()
pvp_buffer = Pypvr.Encode('-buffer',PILImage).get_pvp_buffer()
pvr_buffer = Pypvr.Encode('c:\filename.png -buffer').get_pvr_buffer()
pvp_buffer = Pypvr.Encode('c:\filename.png -buffer').get_pvp_buffer()