2025-08-25 07:05:00
github.com
This format is specifically designed to be for low-color pixel art (
It uses “Prediction by Partial Matching, Order-2” compression, which is able to compress packed-palette-indices smaller than GIF, PNG, and QOI, while sacrificing a bit of time.
It’s 2-10x slower than GIF/PNG/QOI (depending on the image), but often compresses the image 20-50% smaller than GIF/PNG (and multiple-times smaller than QOI).
If you care about compressed image size, this is for you. It’s somewhere between GIF and WEBP (.webp can compress better at times, but it’s painfully slow).
Use the C header like:
#define PEP_IMPLEMENTATION
#include "PEP.h"
112×96 : 4 colors
Format | Size (bytes) | Compression Ratio | Compression (ms) | Decompression (ms) |
---|---|---|---|---|
PEP | 901 | 0.021x | 0.383 | 0.412 |
PNG | 984 | 0.023x | ||
GIF | 1,047 | 0.024x | ||
QOI | 2,425 | 0.056x | 0.023 | 0.028 |
BMP | 43,130 | 1.00x |
192×144 : 2 colors
Format | Size (bytes) | Compression Ratio | Compression (ms) | Decompression (ms) |
---|---|---|---|---|
PNG | 1,318 | 0.368x | ||
PEP | 1,357 | 0.378x | 0.419 | 0.602 |
GIF | 1,919 | 0.535x | ||
BMP | 3,586 | 1.00x | ||
QOI | 6,669 | 1.860x | 0.071 | 0.078 |
640×200 : 251 colors
Format | Size (bytes) | Compression Ratio | Compression (ms) | Decompression (ms) |
---|---|---|---|---|
PEP | 73,542 | 0.407x | 25.652 | 32.121 |
PNG | 84,657 | 0.469x | ||
GIF | 96,997 | 0.751x | ||
BMP | 129,078 | 1.00x | ||
QOI | 180,533 | 1.399x | 1.03 | 1.004 |
PEP is designed for games too, so the compression outputs a structure that has useful elements. The PEP.data pointer ONLY contains the bytes for the pixels.
This library doesn’t have a BMP loader, so this is specifically designed for setups where the color bytes already exist.
You just feed it into pep_compress() with the correct in_format of the bytes, and then you’re able to use it however you like! Often you just use pep_save() after compressing, and then pep_load() + pep_decompress() to access the image data.
/*
pep_compress() parameters:
uint32_t* PIXEL_BYTES = raw RGBA/BGRA pixels
uint16_t WIDTH = width of the image
uint16_t HEIGHT = height of the image
pep_format IN_FORMAT = channel-order of PIXEL_BYTES, either pep_rgba or pep_bgra
pep_format OUT_FORMAT = channel-order of the new PEP, either pep_rgba or pep_bgra
returns:
a pep struct
*/
pep p = pep_compress( PIXEL_BYTES, WIDTH, HEIGHT, IN_FORMAT, OUT_FORMAT );
/*
pep_decompress() parameters:
pep* IN_PEP = pep struct-pointer to decompress
pep_format OUT_FORMAT = channel-order of the new pixels, either pep_rgba or pep_bgra
returns:
a uint32_t* with the uncompressed pixel data
*/
uint32_t* pixels = pep_decompress( IN_PEP, OUT_FORMAT );
/*
pep_free() parameters:
pep* IN_PEP = pep struct-pointer to free
note:
frees the internal bytes buffer and resets bytes_size to 0
*/
pep_free( IN_PEP );
/*
pep_serialize() parameters:
pep* IN_PEP = pep struct-pointer to serialize
uint32_t* OUT_SIZE = pointer to store the resulting byte array size
returns:
a uint8_t* byte array containing the serialized pep data
note:
caller must free() the returned byte array when done
*/
uint8_t* bytes = pep_serialize( IN_PEP, OUT_SIZE );
/*
pep_deserialize() parameters:
uint8_t* IN_BYTES = byte array containing serialized pep data
returns:
a pep struct reconstructed from the byte array
*/
pep p = pep_deserialize( IN_BYTES );
/*
pep_save() parameters:
pep* IN_PEP = pep struct-pointer to save
char* FILE_PATH = path to save the .pep file (e.g. "image.pep")
returns:
uint8_t - 1 on success, 0 on failure
*/
uint8_t success = pep_save( IN_PEP, FILE_PATH );
/*
pep_load() parameters:
char* FILE_PATH = path to the .pep file to load (e.g. "image.pep")
returns:
a pep struct loaded from the file
note:
returns an empty pep struct on failure
*/
pep p = pep_load( FILE_PATH );
Though a lot of this was bashed together with love and tweaked with brute-force, many underlying structures were inspired/referenced from these sources:
- Wikipedia: Prediction by Partial Matching.
- Cleary, J. G., & Witten, I. H. (1984): Data compression using adaptive coding and partial string matching. IEEE Transactions on Communications, 32(4), 396-402.
- Moffat, A. (1990): Implementing the PPM data compression scheme. IEEE Transactions on Communications, 38(11), 1917-1921.
- Cleary, J. G., Teahan, W. J., & Witten, I. H. (1995): Unbounded length contexts for PPM. Proceedings DCC-95, IEEE Computer Society Press, 52-61.
- Shkarin, D. (2002): PPM: One step to practicality. Proceedings of Data Compression Conference 2002, 202-211.
Please contribute to make PEP the best pixel art format there is!
-End :::.
Keep your files stored safely and securely with the SanDisk 2TB Extreme Portable SSD. With over 69,505 ratings and an impressive 4.6 out of 5 stars, this product has been purchased over 8K+ times in the past month. At only $129.99, this Amazon’s Choice product is a must-have for secure file storage.
Help keep private content private with the included password protection featuring 256-bit AES hardware encryption. Order now for just $129.99 on Amazon!
Help Power Techcratic’s Future – Scan To Support
If Techcratic’s content and insights have helped you, consider giving back by supporting the platform with crypto. Every contribution makes a difference, whether it’s for high-quality content, server maintenance, or future updates. Techcratic is constantly evolving, and your support helps drive that progress.
As a solo operator who wears all the hats, creating content, managing the tech, and running the site, your support allows me to stay focused on delivering valuable resources. Your support keeps everything running smoothly and enables me to continue creating the content you love. I’m deeply grateful for your support, it truly means the world to me! Thank you!
BITCOIN bc1qlszw7elx2qahjwvaryh0tkgg8y68enw30gpvge Scan the QR code with your crypto wallet app |
DOGECOIN D64GwvvYQxFXYyan3oQCrmWfidf6T3JpBA Scan the QR code with your crypto wallet app |
ETHEREUM 0xe9BC980DF3d985730dA827996B43E4A62CCBAA7a Scan the QR code with your crypto wallet app |
Please read the Privacy and Security Disclaimer on how Techcratic handles your support.
Disclaimer: As an Amazon Associate, Techcratic may earn from qualifying purchases.