Github – Endesga/PEP: Prediction -encoded pixels – designed to compress pixel art as much as much as possible (by sacrificing a bit of time)

pep_logo

This format is specificly designed to be for low-color pixel art (<= 16 colors works best, up to 256 colors is supported).

It uses “Prediction by Partial Matching, Order-2” Compression, which is altar 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/PNG (And Multiple-Tems 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).


(This is currently in the experience!)


Use the c header like:

#define PEP_IMPLEMENTATION
#include "PEP.h"

Tree1

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

font

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

nz_scene

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 does not have a bmp loader, so this is specificly designed for setups where the color bytes alredy exist. You just feed it into pep_compress () with the correct in_format of the bytes, and then you alive to use it howyver you! 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 );

Thought a lot of this was bashed togeether with love and tweaked with brute-room, many undeerling structures we inspired/referenceed from these sources:

  1. Wikipedia: Prediction by Partial Matching.
  2. Clery, JG, & Witten, IH (1984): Data Compression Using Adaptive Coding and Partial String Matching. IEEEE transactions on Communications32 (4), 396–402.
  3. Moffat, A. (1990): Implementing the ppm data compression scheme. IEEEE transactions on Communications38 (11), 1917–1921.
  4. Cleary, JG, Teahan, WJ, & Witten, IH (1995): Unbounded length contexts for ppm. Proceedings DCC-95, IEEE COMPUTER Society Press52-61.
  5. Shkarin, d. (2002): PPM: One step to practice. Proceedings of Data Compression Conference 2002202-211.

Please contribute to make pep the best pixel art format there is!

-End :::.

Ramesh Ghorai is the founder of www.livenewsblogger.com, a platform dedicated to delivering exclusive live news from across the globe and the local market. With a passion for covering diverse topics, he ensures readers stay updated with the latest and most reliable information. Over the past two years, Ramesh has also specialized in writing top software reviews, partnering with various software companies to provide in-depth insights and unbiased evaluations. His mission is to combine news reporting with valuable technology reviews, helping readers stay informed and make smarter choices.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top