32

I'm looking for JavaScript implementation of string inflating algorithms. I want to compress on the server side (Java), and decompress on the client side (JavaScript).

I've found:

unzip strings in javascript
That one is marked as answered with an answer for different problem. Other answers are also for something else (unzipping files in ZIP format).

JavaScript inflate implementation (possibly FF 3.6 only)
This is closest to what I need. However I'd like to have some alternatives.

Suggestions?
Thanks, Ondra

Update: I have quite a specific use case, please don't answer "Don't do that in JavaScript." I am writing an "offline" reporting tool (once generated, it's put to a static store) and deflating may save megabytes for a single report. I am constrained by other apps so I can't store it as a zip file.

Community
  • 1
  • 1
Ondra Žižka
  • 36,997
  • 35
  • 184
  • 250
  • 3
    The main problem is going to be that JavaScript has no facilities for manipulating raw data. All numbers are floating-point, and all string values are kept as UTF-16 (2-byte characters). There's no "byte array" data type, so that makes implementation of compression/decompression much harder and much less efficient. – Pointy Feb 02 '11 at 13:49
  • 4
    Not true, there's support for binary data in recent JavaScript implementations, based on [Typed Array Specification](http://www.khronos.org/registry/typedarray/specs/latest/). – Ondra Žižka Jul 17 '11 at 10:08
  • yes that's true - that would certainly be helpful :-) – Pointy Jul 17 '11 at 11:27
  • The browser already uses a C / C++ implementation of what you need, find a way to access it through .js. I wrote a native .js version of JSON for fun, and it was about 100 times slower then the broswer's C / C++ implementation. – CS_2013 Jun 09 '12 at 16:37
  • Related: Here's Dean Edwards' packer: http://dean.edwards.name/packer/ – Ondra Žižka Dec 16 '12 at 21:25

7 Answers7

10

Take a look at this Stack Overflow question, the answers there contains references to multiple compressing engines implemented in javascript. Most of these are based on LZ77.

Community
  • 1
  • 1
Sean Kinsey
  • 35,601
  • 7
  • 49
  • 68
10

I don't know how you'd like that, but I like these implementations:

The first is fastest than second, We can usually ensure a fast server, however we don't know the performance of the client machine. Therefore I recommend you choose js-deflate and adjust your java (server side) to inflate.

https://github.com/dankogai/js-deflate

http://code.google.com/p/gzipjs/

  • 3
    The second url (gzipjs) doesn't have any code posted anywhere ... or am I missing something? – Tute Apr 19 '12 at 20:21
  • 1
    This should be the accepted answer dudes. – almosnow Oct 17 '12 at 15:56
  • I been searching around for hours now, I skipped past this answer the first time, but it really is very simple, and excellent solution. I have been benchmarking it against LZMA and it is coming up 10x faster, and with comparable compression! – Billy Moon Feb 04 '13 at 21:21
  • Isn't inflate actually expanding the data? – Jus12 Jul 07 '16 at 06:40
6

I created a working example using pako, modern and fast Zlib port. http://jsfiddle.net/9yH7M/2/

Redsandro
  • 10,080
  • 11
  • 64
  • 94
3

there's this graphing library that has as part of it, a zlib implementation in javascript. if you scroll down this page a bit, you'll see it as a separate download. http://jsxgraph.uni-bayreuth.de/wp/download/

Breton
  • 14,634
  • 3
  • 56
  • 75
2

This example: http://cheeso.members.winisp.net/srcview.aspx?dir=js-unzip shows how you can do ZIP files in Javascript. Now, I know you want ZLIB or DEFLATE compression, rather than ZIP. But, ZIP uses DEFLATE, and within the .js file for that example, there is an InflatingReader class that can INFLATE as it reads.

The class exposes these methods:

readByte()
   returns null when EOF is reached, or the value of the byte when successful.

readToEnd()
   returns an array of all bytes read, to EOF

beginReadToEnd(callback)
   async version of the above

readBytes(n)
   returns an array of n bytes read from the source.

beginReadBytes(n, callback)
   async version of the above

You can use that code unchanged if you want INFLATE.

If you want ZLIB (aka unzip), then there is a 2-byte signature that you need to read and validate before reading the compressed bytes and doing the INFLATE. Just modify the InflatingReader to read and dump 2 bytes, and it will do ZLIB just fine.

Cheeso
  • 180,104
  • 92
  • 446
  • 681
2

I found a working inflate implementation here:

http://www.onicos.com/staff/iz/amuse/javascript/expert/inflate.txt

If you want a slightly cleaner version that namespaces the algorithm, this one should work:

https://github.com/augustl/js-inflate

Keep in mind that gzipped "inflate" data is prefixed with a two-byte header, and suffixed with a four-byte checksum, which you will need to strip before passing to the algorithm.

Alexander Staubo
  • 2,492
  • 2
  • 23
  • 22
-4

Don't do that in JavaScript. It'd be slow and besides that JS doesn't do well with binary data.

Simply use gzip transfer encoding on the server side and your browser will take care of decompressing it.

ThiefMaster
  • 285,213
  • 77
  • 557
  • 610
  • 14
    I am not asking whether it's good or bad. I am looking for implementations. -1. – Ondra Žižka Feb 02 '11 at 13:38
  • 4
    It's very good advice, @Ondra. If you want to do something that is considered a "bad idea" by lots of people with expertise, you should explain your reasons. – Pointy Feb 02 '11 at 13:40
  • 4
    @Pointy: I don't agree. Of course you are right, but if someone is asking for something unorthodox it's probably not the best thing to just wave a wagging finger, regardless on the expertise. – jAndy Feb 02 '11 at 13:49
  • 4
    @jAndy the problem is that it's often impossible to tell *just* from the question whether the question-asker is a complete neophyte or an experienced programmer. Inexperienced coders may benefit considerably by this sort of advice; in fact in my opinion this sort of answer is the most useful thing on Stackoverflow. The original question contains almost no peripheral explanation of goals, so based on pure statistics the assumption that some basic advice is called for is a good assumption. – Pointy Feb 02 '11 at 13:55
  • @Pointy, you're right, but then it should NOT go to answers, but comments. – Ondra Žižka Feb 02 '11 at 18:26
  • Well that's certainly a good point, @Ondra. – Pointy Feb 02 '11 at 19:04
  • 3
    FYI, there's support for binary data in recent JavaScript implementations, based on [Typed Array Specification](http://www.khronos.org/registry/typedarray/specs/latest/). – Ondra Žižka May 22 '11 at 22:35
  • Not all recent browsers support it though. – ThiefMaster May 22 '11 at 23:09
  • 1
    I think this answer and its comments are a bit behind the times when it comes to javascript. I say this with utmost respect, go back to 2003. --- JS is not just a browser language, and it's not a toy language, it can handle binary data, and it's faster than python and ruby. – Breton Sep 26 '11 at 07:09
  • He explicitely said "decompress on the client side" so in his case he is using it in a browser where support for binary data is not always available. Besides that, browsers support gzip decompression natively (C/C++ implementation) so chances are extremely high that it'll be more efficient to use transfer-encoding instead of handling decompression manually. – ThiefMaster Sep 26 '11 at 07:43
  • 1. Go back to 2003. 2. That's not very helpful. – Breton Sep 26 '11 at 14:28
  • Again, why would you reimplement something that is already supported natively? – ThiefMaster Sep 26 '11 at 14:50
  • because the browser implementation isn't accessible from javascript. 1. You may not have access to the server to enable gzip. 2. you might be storing data in localstorage (which has cross browser polyfills), 3. maybe you want to compress what you send /from/ the browser. etc. etc. there's lots of reasons. 4. It's not actually slow. see here: http://jszip.stuartk.co.uk/ or here: http://www.bytestrom.eu/blog/2009/1120a_jpeg_encoder_for_javascript (it says 4 seconds on the page, but in today's browsers it's milliseconds) – Breton Sep 27 '11 at 05:05
  • If he uses Java on the server side chances are high that he has full control over the server - and if he just wants to reduce the size of the data being transferred he doesn't need to access both the compressed and uncompressed data in JS... – ThiefMaster Sep 27 '11 at 07:21
  • Java? That's a pretty random assumption. I wonder where you get that. "Just wants to reduce the size of data being transferred". where do you get that? I'll admit that there's not a lot of information in the original question, but the solution is to ask questions, not make assumptions. – Breton Sep 27 '11 at 14:09
  • "on the server side (Java)" - so it's not just an assumption. – ThiefMaster Sep 27 '11 at 14:26
  • Ah sorry. I missed that. – Breton Sep 29 '11 at 00:09
  • @Breton, yes I have a use case which uses LocalStorage to create a cross-browser offline-capable web app (roll on IndexedDB on Webkit), so I want to JSON-encode the data and compress it to make the most of the 5MB I'm allowed without getting the user to fiddle with their settings... – james-geldart May 29 '12 at 09:29