Вопрос

I'm working on a JavaScript application that can generate animated GIF images. GIF images use the LZW compression algorithm, and as such I need to implement it in JavaScript.

So far, I've got this code that can compress a string (binary or not) to an array of integers, then decompress it all right. See the pastebin link for the full code (if you think it's necessary), but here's what I get running this snippet, which should demonstrate that the compression and decompression itself works all right:

var lzw = new LZW(8);
var input = "TOBEORNOTTOBEORTOBEORNOT#";
var compressed = lzw.compress(input);

console.log(input);
// "TOBEORNOTTOBEORTOBEORNOT#"

console.log(compressed);
// [84, 79, 66, 69, 79, 82, 78, 79, 84, 256, 258, 260, 265, 259, 261, 263, 35]

console.log(lzw.decompress(compressed));
// "TOBEORNOTTOBEORTOBEORNOT#"

The problem, now, is that I don't know how to do the binary packing. If I understand correctly the LZW algorithm, only the first bit pattern from compressed can be fit neatly on 8-bit boundaries, the rest needs to be on 9-bit boundaries.

I went through Wikipedia's article on Lempel-Ziv-Welch, and it seems that for GIF image data, I would always align the least significant bits of a compressed pattern with the least significant bits of a byte; but I tried it and my GIFs don't work, and GIF parsers aren't very explicit about failures, so I'm not sure if it's because of the compression or something else. To me it also looks like a huge waste of bits, so it only makes the approach more dubious.

Can anyone point me in the right direction?

Это было полезно?

Решение

GIF packs data into the file as a "bit stream" -- for instance, the first eight bits of the first 9-bit value go into one byte and the last bit goes into the second byte; the second 9-bit value fills up the rest of the second byte and two bits of the third, and so on. Plan on lots of bit shifting.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top