
Pack arbitrary files into PNG and access them using JavaScript - pierrec
https://github.com/haxorplatform/web-bundle
======
jjarmoc
I first learned about this technique from Cody Brocious' post
([http://daeken.com/superpacking-js-demos](http://daeken.com/superpacking-js-
demos)) about his WebGL demo 'Magister'
([http://demoseen.com/windowpane/magister.html](http://demoseen.com/windowpane/magister.html)).
That file has a .html extension, but it's also a valid PNG. In his post, he
discusses this technique as well as others.

Cody's goal was to compress already minified WebGL code and achieve some
pretty impressive results from a ridiculously small file for a demo contest.
He also put the JS loader (which is much smaller than the linked decoder) in a
custom chunk on the PNG itself. By doing it that way, you can have a PNG that
when renamed also contains a web page and/or more Javascript.

It's an interesting technique, for sure, but I've never been able to find a
real use for it beyond the compression. With a content-type sniffing
vulnerability or something, it could be an interesting way to deliver content
to browsers, but otherwise it's really just a curiosity as best I can tell.

~~~
prewett
This is really clever. Unfortunately, the linked page doesn't seem to have the
bootstrap code that has the magic of getting from a PNG to a web page. Is this
around somewhere? (I could download the demo PNG and extract it myself, but
I'm hoping not to have to do that...)

~~~
jjarmoc
Right, just rung strings on the demo and you'll see the custom PNG chunk:

``` jawh<img
onload=with(document.createElement('canvas'))p=width=4968,(c=getContext('2d')).drawImage(this,e='',0);while(p)e+=String.fromCharCode(c.getImageData(0,0,p,1).data[p-=4]);(t=top).eval(e)
src=#> ```

------
mnutt
This is pretty great. I also built something similar a while back that would
let you post torrents to message boards as images:

[https://github.com/mnutt/hid.im/blob/master/public/firefox-e...](https://github.com/mnutt/hid.im/blob/master/public/firefox-
extension/screenshot-1.png?raw=true)

------
kqr2
I guess this would be useful with Amazon's free unlimited cloud photo storage.

~~~
stephen272
Only if they leave the photo as a losslessly compressed png. They might
convert to a lossy JPEG on upload, which means your data is toast.

~~~
isomorphic
Two can play at that game. You can store data in JPEG that can even survive
recompression with lower quality. If it's worth it to you to go to all that
trouble, that is.

~~~
Intermernet
Interesting paper: Bypassing Cloud Providers’ Data Validation to Store
Arbitrary Data [1]

>JPG & PNG Steganography Encoder (JPG-PNGStega). The purpose of this encoder
is to inject data (hiding it) in JPG and PNG files. It takes a File Format
Sample (JPG or PNG) and, for each pixel, it injects 3 bits of data in the LSBs
(Least Significant Bit). There are more sophisticated image steganography
methods already widely discussed. However, the use of this encoder shows that
even basic meth- ods of JPG and PNG steganography are possible in SaaS
applications, and the exploitation of such method may bring impacts

[http://arxiv.org/ftp/arxiv/papers/1404/1404.2637.pdf](http://arxiv.org/ftp/arxiv/papers/1404/1404.2637.pdf)

------
DiThi
The only use I see for this is for compressing files uploaded to a hosting
where you can't enable gzip encoding. I already use static gzip encoding in
all my deployments and I got less problems with cross-origin requests from
custom-coded binary files than from images.

~~~
smt88
Most people won't find any real-world use for this, but it's cool/clever
enough by itself that it's worth the author's time and effort.

~~~
DiThi
Definitely. In fact it's one of the first things I considered when I started
moving the mesh format of my engine from JSON to binary.

------
CyberShadow
I'm not sure what the use case for this is, but you can also add arbitrary
data to PNG files by adding a custom chunk. As long as the chunk is marked as
ancillary (the first letter of the chunk type is in lower case), it will not
affect image decoding.

~~~
pierrec
Contrarily to the appending trick that you mention, this allows you to apply
PNG compression to your arbitrary data, and then make use of the browser's
decompression capabilities on it.

Though that's still kind of an odd use case, since we have gzip encoding for
that.

------
jsprogrammer
Any ideas why I would want to do this?

~~~
A_COMPUTER
Circumventing censorship; need to move arbitrary data, but only convenient
transport is image format.

~~~
grandalf
Imagine if lots of sites added a 1MB image that contained the information that
various governments want censored.

------
amelius
Nice, how large can the archives become? I guess there is a size limit, which
may be different for different browsers.

Also, I wonder how difficult it would be to port a decompression library to
asm.js.

~~~
eduardo-costa
Author here!

The need appeared when I was doing my WebGL game engine and wanted to
pack/compress mesh, texture, xml and any other stuff that would bloat my
loading time with tons of HTTP requests!

Also the browser's native PNG decompression would be faster than any external
JS lib for lossless decompression.

I limited it to a 16k x 16k PNG (but I think modern browsers can take more
than that), allowing 1GB of data.

------
hobarrera
> Significantly reduce the number of HTTP requests allowing fast page loads

I wonder how true this holds with HTTP/2.0, where resources are loaded in
parallel over a single TCP connection.

