first define some test set - three characters, a and a - in total 5 characters (or bytes if you like to understand it that way). the second command "xxd" after the pipe symbol just prints the received data in a very compacted hexadecimal fashion - all chars convert to two digits of hexadecimal represenation:
$ echo "abc\0\r" | xxd -p 6162635c305c720a
as you can see each char beyond the quotes is taken literally and results in a two digit hex number. backslashes will result in "5c" hex number pairs. the "0" will result in hex "30" and an additional "0a" is in place.
$ echo -e "abc\0\r" | xxd -p 616263000d0a
now in above lines the option "-e" instructs the "echo" command to interpret regular expressions for the and the characters. as you can see they nicely translate to hex "00" and hex "0d".
$ echo -en "abc\0\r" | xxd -p 616263000d
with the final variant above the freshly added "-n" option even the former "0a" as appended by the echo command does disappear. the 5 characters from the test set are resulting in a print of 10 hexadecimal digits, each pair of two digit matches one of the input chars. thus proof that the echo command with options and the pipe symbol works as we would like it to work is achieved - at least for the test set.
now its up to you to hook in your data on the left side of the pipe and on the right side your worker.
$GIF, for a start, is not holding full-binary even before starting. However, to the exception of the NUL character, it is holding all the others. (as a ref: vaab.blog.kal.fr/2014/05/03/… )