Jump to content

libpngstore

From Hugo's wiki

libpngstore reads, edits and writes PNG files, and stores arbitrary data inside them: in the pixels, where the image looks the same, or in a chunk that viewers ignore. It is a C library and a command-line tool, pngstore.

Where the data goes

Where How Works on
Pixels the 2 low bits of every sample 8 and 16 bit images, not palette ones
Section a private ancillary chunk before IEND any image

A 3000×2000 RGBA picture holds about 6 MB in its pixels: 2 bits from each of its 24 million samples. pngstore --capacity tells you for a given image.

Installation

It needs zlib.

$ git clone https://github.com/hugoocoto/libpngstore
$ cd libpngstore
$ make

That builds ./pngstore, and the library as build/lib/libpngstore.a and build/lib/libpngstore.so.

Usage

With no options, pngstore prints the header of each png.

$ pngstore image.png                              # header info
$ pngstore -c --capacity -p 10,10 image.png       # chunks, capacity, a pixel
$ pngstore -e secret.bin -o out.png image.png     # hide a file in the pixels
$ pngstore -x secret.bin out.png                  # get it back
$ pngstore -e notes.txt -s note -o out.png image.png   # in a chunk instead
$ pngstore -x notes.txt -s note out.png
$ pngstore --set-pixel 10,10=255,0,0,255 -o out.png image.png
$ pngstore -r -o out.png image.png                # re-encode the pixels

Options

Option Description
-c, --chunks List the chunks
--capacity Print how many bytes --embed can store
-p, --pixel X,Y Print the samples of a pixel
--set-pixel X,Y=V[,V...] Set a pixel
-r, --reencode Decode and compress the pixels again
-e, --embed FILE Store the contents of a file
-x, --extract FILE Write the stored data to a file
-s, --section NAME Use a chunk with this 4-letter name instead of the pixels
-o, --output FILE The png to write; alone, it rewrites the png
-v, --verbose Print what is going on
Note A section's name is stored with the letter cases that mark a PNG chunk as ancillary, private and safe to copy, so that viewers skip it: note is written as noTe.

Library

#include "libpngstore.h"

PNG png = png_read(fopen("image.png", "rb"));
png_add_section(&png, "note", data, len);
png_embed(&png, secret, secret_len);
png_write(png, fopen("out.png", "wb"));
png_free(png);

Functions return non-zero on error, and png_strerror(png) describes it. png_get_image and png_set_image give and take the decoded pixels, which image_get and image_set read and write one sample at a time.

See also