--- title: libpngstore related: - "[flag.h](flag.h.md)" - "[cum.h](cum.h.md)" - "[passimg](passimg.md)" categories: - C libraries --- **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 ```c #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 - [Source code](https://github.com/hugoocoto/libpngstore)