-
Notifications
You must be signed in to change notification settings - Fork 0
Library
packPNG ships as a library — static (.a) and shared (.so / .dll) —
with a small C API, so other programs (archivers, asset pipelines) can embed the
codec. Multithreading is ON by default. Verified byte-exact on Linux and Windows.
make lib # Linux: libpackpng.a + libpackpng.so + packpng.h
make lib-win # Windows: libpackpng-win.a + packpng.dll + libpackpng.dll.a + packpng.def + packpng.hBoth static archives are self-contained fat archives (packPNG + packJPG +
kanzi + preflate merged); the shared libraries bundle the same. The consumer
links only system libraries. Prebuilt SDK bundles are attached to each
release (*-lib.tar.gz / *-lib.zip).
typedef enum {
PACKPNG_TCIP = 0, /* default: preflate + WebP-lossless */
PACKPNG_TVCP = 1, /* fast: kanzi + zstd */
PACKPNG_TMCP = 2, /* archival: preflate + kanzi-TPAQX */
PACKPNG_TPCL = 3 /* legacy: preflate + LZMA2 */
} packpng_backend;
/* File → file */
int packpng_compress_file(const char* in_path, const char* out_path, packpng_backend backend);
int packpng_decompress_file(const char* in_path, const char* out_dir); /* auto-detects magic */
/* In-memory (buffer → buffer) — for archivers / embedding.
* On success returns 0 and sets *out to a heap buffer of *out_len bytes
* (free with packpng_free). On error returns nonzero, leaves *out NULL. */
int packpng_compress_mem(const unsigned char* in, size_t in_len, const char* name_hint,
unsigned char** out, size_t* out_len, packpng_backend backend);
int packpng_decompress_mem(const unsigned char* in, size_t in_len,
unsigned char** out, size_t* out_len);
void packpng_free(unsigned char* p);
void packpng_set_threads(int n); /* 0 = auto = default (hardware threads) */
const char* packpng_last_error(void); /* thread-local, valid until next call */
const char* packpng_version(void); /* e.g. "2.0a" */The *_file and *_mem calls return 0 on success, nonzero on error (message via
packpng_last_error). The image type is detected from the input bytes, not the
name — name_hint (may be NULL) is just the original filename stored in the
container. JNG/MNG inputs ignore backend and use their format codec.
#include "packpng.h"
#include <stdio.h>
int main(void) {
if (packpng_compress_file("image.png", "image.ppg", PACKPNG_TCIP))
{ printf("error: %s\n", packpng_last_error()); return 1; }
packpng_decompress_file("image.ppg", "out/"); /* → out/image.png, byte-exact */
return 0;
}#include "packpng.h"
#include <stdlib.h>
/* png/png_len already hold a PNG read into memory. */
unsigned char* ppg; size_t ppg_len;
if (packpng_compress_mem(png, png_len, "image.png", &ppg, &ppg_len, PACKPNG_TCIP) == 0) {
/* ... store the ppg/ppg_len blob in your archive ... */
packpng_free(ppg);
}
/* Later, restore the byte-identical original: */
unsigned char* orig; size_t orig_len;
if (packpng_decompress_mem(ppg, ppg_len, &orig, &orig_len) == 0) {
/* orig/orig_len == the original PNG, same SHA-256 */
packpng_free(orig);
}packpng_set_threads(0) (the default) auto-sizes the worker pool to the hardware;
pass a positive n to cap it.
# Linux
gcc app.c libpackpng.a -lzstd -llzma -lz -lpthread -ldl -lm -lstdc++ -o app
# Windows (mingw)
x86_64-w64-mingw32-gcc app.c libpackpng-win.a -L vendor/mingw-deps/lib \
-lzstd -llzma -lz -lws2_32 -luserenv -lbcrypt -lntdll -static -lstdc++ -o app.exe# Linux — run with libpackpng.so on the loader path (LD_LIBRARY_PATH / rpath)
gcc app.c -L. -lpackpng -o app
# Windows — link the import lib, ship packpng.dll alongside app.exe
x86_64-w64-mingw32-gcc app.c -L. -lpackpng -o app.exeFor MSVC, build an import lib from the provided packpng.def
(lib /def:packpng.def /machine:x64) and link against packpng.dll.