png-stash-mux
v1.0.0
Published
Hide data in the least significant bits of PNGs. Takes an arbitrary set of PNGs and presents a mutable single sequence of bytes.
Downloads
3
Readme
png-stash-mux
A multiplexing wrapper over png-stash
, this low level tool can read
and write data in the least significant bits of a series of PNG
images.
Takes a list of PNG files and exposes an array-like-ish data structure to read and write buffers and bytes.
Quick Example 1: Write Data
var pngStashMux = require('png-stash-mux');
var stash = pngStashMux(['steve.png', 'benny.png'], function(err, stash) {
if (err) throw new Error(err);
stash.write("Itsa mee! Ontario!", function(err) {
if (err) throw new Error(err);
stash.save(finished);
});
function finished(err) {
if (err) throw new Error(err);
console.log("Message stored!");
});
});
Quick Example 2: Read Data
var pngStashMux = require('png-stash-mux');
var stash = pngStashMux(['steve.png', 'benny.png'], function(err, stash) {
if (err) throw new Error(err);
stash.read(0, 18, // 18 is length of message from example 1.
function(err, message) {
if (err) throw new Error(err);
console.log(message);
});
});
npm install png-stash-mux
Documentation
Constructor
Instance Functions
Scans and indexes the specified PNG files, and and yields a reader-writer object with the following properties:
- length - Total number of bytes that can be hidden in the PNG files.
- getByte()
- setByte()
- write()
- read()
- save()
See below for documentation of the read-write functions.
Arguments
- pngFileNames - An array of file paths. Each file path must be for an existing valid PNG file.
- callback -
function(err, stash)
. If the PNGs file were successfully indexed,err
will beundefined
.stash
will be reader-writer object mentioned in description above.
Example
var pngStashMux = require('png-stash-mux');
pngStashMux(["test1.png", "test2.png"], function(err, stash) {
console.log("Available bytes: " + stash.length);
});
Reads a single byte from the "invisible" bits of the PNG files.
May trigger a save()
of previously changed data. See "Notes" below.
Arguments
- index - Position among all bytes composed by the PNGs' "invisible" bits. Must be less than the
pngStashMux
instance'slength
property. - callback -
function(err, byte)
.err
will beundefined
if read was successful. Otherwise it will represent an error.byte
is the read value.
Example
var pngStashMux = require('png-stash-mux');
pngStashMux(["frame0.png", "frame1.png", "frame2.png"], function(err, stash) {
stash.getByte(1000, function(err, b1) {
stash.getByte(2000, function(err, b2) {
stash.getByte(3000, function(err, b3) {
if (b1 == 0xaa && b2 == 0x44 && b3 == 0xff) {
console.log("Watermark detected!");
} else {
console.log("No watermark detected.");
}
})})});
});
Writes a single byte to the "invisible" bits of the PNGs, but does not
immediately save it to disk. To save, call save()
.
May trigger a save()
of previously changed data. See "Notes" below.
Arguments
- index - Position among all bytes composed by the PNGs' "invisible" bits. Must be less than the
pngStash
instance'slength
property. - value - Byte to store. Must be an integer in the 8-bit range (
0 < value < 256
). - callback -
function(err)
.err
will beundefined
if save was successful. Otherwise it will represent an error.
Example
var pngStashMux = require('png-stash-mux');
pngStashMux(["frame0.png", "frame1.png", "frame2.png"], function(err, stash) {
stash.setByte(1000, 0xaa);
stash.setByte(2000, 0x44);
stash.setByte(3000, 0xff);
stash.save(function(err) {
console.log(err || "Watermark inserted.");
});
});
Reads a sequence of bytes from the PNGs' "invisible" bits, and returns
them as a Buffer
.
May trigger a save()
of previously changed data. See "Notes" below.
Arguments
- offset - default=
0
. At which byte position to start reading from. - length - default=
stash.length
. How many bytes to read. - callback -
function(err, data)
.err
will beundefined
if save was successful. Otherwise it will represent an error.data
is all requested bytes in aBuffer
.
Example
var pngStashMux = require('png-stash-mux');
pngStashMux(["bunny.png", "kitten.png"], function(err, stash) {
var messageLength = stash.getByte(0) * 65536
+ stash.getByte(1) * 256
+ stash.getByte(2);
var message = stash.read(messageLength, 3);
console.log("Found message: " + message);
});
Writes a sequence of bytes to the PNGs' "invisible" bits, but does not
save to disk. To save to disk, call save()
.
May trigger a save()
of previously changed data. See "Notes" below.
Arguments
- data - Bytes to store in the PNGs. Must be string or Buffer. If string, will be UTF-8 encoded.
- offset - default=
0
. At which byte position to start writing to. - length - default=all. How many bytes from
data
to write. Be aware that the.length
of a string may not correspond to the number of bytes in its resulting UTF-8 representation. - callback -
function(err)
.err
will beundefined
if save was successful. Otherwise it will represent an error.
Example
var pngStashMux = require('png-stash-mux');
pngStash(["bunny.png", "kitten.png"], function(err, stash) {
var message = new Buffer("Hello there!");
stash.setByte(0, message.length >> 16 & 0xff);
stash.setByte(1, message.length >> 8 & 0xff);
stash.setByte(2, message.length >> 0 & 0xff);
stash.write(message, 3);
});
Stores the PNG data back into the files. You want to call this
function after writing data to the stash
instance.
May be triggered sproadically as a result of other operations. See "Notes" below for details.
Arguments
- callback -
function(err)
.err
will beundefined
if save was successful. Otherwise it will represent an error.
Example
// See examples for stash.write()
and stash.setByte()
.
Notes
Will automatically save changes if an operation needs to cross file
boundaries. This means that if you do not save()
before shutting
down, you are likely to end up with a half-stored state.