mirror of
https://github.com/0x5eal/rbxts-pako.git
synced 2025-04-14 17:03:53 +01:00
add adler32 algoritm
implementation of deflate init methods
This commit is contained in:
parent
ff0a4c0c50
commit
b4919faf9a
4 changed files with 215 additions and 15 deletions
65
lib/zlib/adler32.js
Normal file
65
lib/zlib/adler32.js
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var BASE = 65521; /* largest prime smaller than 65536 */
|
||||||
|
var NMAX = 5552;
|
||||||
|
|
||||||
|
function adler32(adler, buf, len)
|
||||||
|
{
|
||||||
|
var i = 0;
|
||||||
|
/* split Adler-32 into component sums */
|
||||||
|
var sum2 = (adler >> 16) & 0xffff;
|
||||||
|
adler &= 0xffff;
|
||||||
|
|
||||||
|
/* in case user likes doing a byte at a time, keep it fast */
|
||||||
|
if (len == 1) {
|
||||||
|
adler += buf[0];
|
||||||
|
if (adler >= BASE)
|
||||||
|
adler -= BASE;
|
||||||
|
sum2 += adler;
|
||||||
|
if (sum2 >= BASE)
|
||||||
|
sum2 -= BASE;
|
||||||
|
return (adler | (sum2 << 16)) >>> 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* in case short lengths are provided, keep it somewhat fast */
|
||||||
|
if (len < 16) {
|
||||||
|
for(i=0;i<len;i++) {
|
||||||
|
adler += buf[i];
|
||||||
|
sum2 += adler;
|
||||||
|
}
|
||||||
|
if (adler >= BASE)
|
||||||
|
adler -= BASE;
|
||||||
|
sum2 %= BASE; /* only added so many BASE's */
|
||||||
|
return (adler | (sum2 << 16)) >>> 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
var cursor = 0;
|
||||||
|
/* do length NMAX blocks -- requires just one modulo operation */
|
||||||
|
while (len >= NMAX) {
|
||||||
|
len -= NMAX;
|
||||||
|
var next_cursor = cursor + NMAX;
|
||||||
|
for (i=cursor;i<next_cursor;i++) {
|
||||||
|
adler += buf[i];
|
||||||
|
sum2 += adler;
|
||||||
|
}
|
||||||
|
|
||||||
|
adler %= BASE;
|
||||||
|
sum2 %= BASE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* do remaining bytes (less than NMAX, still just one modulo) */
|
||||||
|
if (len) { /* avoid modulos if none remaining */
|
||||||
|
for (i=cursor;i<len;i++) {
|
||||||
|
adler += buf[i];
|
||||||
|
sum2 += adler;
|
||||||
|
}
|
||||||
|
|
||||||
|
adler %= BASE;
|
||||||
|
sum2 %= BASE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* return recombined sums */
|
||||||
|
return (adler | (sum2 << 16)) >>> 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = adler32;
|
|
@ -29,5 +29,15 @@ module.exports = {
|
||||||
Z_HUFFMAN_ONLY: 2,
|
Z_HUFFMAN_ONLY: 2,
|
||||||
Z_RLE: 3,
|
Z_RLE: 3,
|
||||||
Z_FIXED: 4,
|
Z_FIXED: 4,
|
||||||
Z_DEFAULT_STRATEGY: 0
|
Z_DEFAULT_STRATEGY: 0,
|
||||||
|
|
||||||
|
Z_BINARY: 0,
|
||||||
|
Z_TEXT: 1,
|
||||||
|
Z_ASCII: 1, // = Z_TEXT
|
||||||
|
Z_UNKNOWN: 2,
|
||||||
|
/* Possible values of the data_type field (though see inflate()) */
|
||||||
|
|
||||||
|
Z_DEFLATED: 8,
|
||||||
|
/* The deflate compression method */
|
||||||
|
Z_NULL: 0
|
||||||
}
|
}
|
|
@ -1,18 +1,71 @@
|
||||||
var consts = require('constants');
|
var c = require('./constants');
|
||||||
|
var adler32 = require('./adler32');
|
||||||
|
|
||||||
function internal_state() {
|
var FASTEST = true;
|
||||||
|
|
||||||
|
var Z_NULL = c.Z_NULL;
|
||||||
|
|
||||||
|
var MAX_WBITS = 15; /* 32K LZ77 window */
|
||||||
|
var DEF_MEM_LEVEL = 8;
|
||||||
|
|
||||||
|
var MIN_MATCH = 3;
|
||||||
|
var MAX_MATCH = 258;
|
||||||
|
var MIN_LOOKAHEAD = (MAX_MATCH + MIN_MATCH + 1);
|
||||||
|
|
||||||
|
var INIT_STATE = 42;
|
||||||
|
var EXTRA_STATE = 69;
|
||||||
|
var NAME_STATE = 73;
|
||||||
|
var COMMENT_STATE = 91;
|
||||||
|
var HCRC_STATE = 103;
|
||||||
|
var BUSY_STATE = 113;
|
||||||
|
var FINISH_STATE = 666;
|
||||||
|
|
||||||
|
var config = function(good_length,max_lazy,nice_length,max_chain,func) {
|
||||||
|
this.good_length = good_length;
|
||||||
|
this.max_lazy = max_lazy;
|
||||||
|
this.nice_length = nice_length;
|
||||||
|
this.max_chain = max_chain;
|
||||||
|
this.func = func;
|
||||||
|
}
|
||||||
|
|
||||||
|
var configuration_table;
|
||||||
|
|
||||||
|
if (FASTEST) {
|
||||||
|
configuration_table = [
|
||||||
|
/* good lazy nice chain */
|
||||||
|
/* 0 */ new config(0, 0, 0, 0, deflate_stored), /* store only */
|
||||||
|
/* 1 */ new config(4, 4, 8, 4, deflate_fast) /* max speed, no lazy matches */
|
||||||
|
]
|
||||||
|
} else {
|
||||||
|
configuration_table = [
|
||||||
|
/* good lazy nice chain */
|
||||||
|
/* 0 */ new config(0, 0, 0, 0, deflate_stored), /* store only */
|
||||||
|
/* 1 */ new config(4, 4, 8, 4, deflate_fast), /* max speed, no lazy matches */
|
||||||
|
/* 2 */ new config(4, 5, 16, 8, deflate_fast),
|
||||||
|
/* 3 */ new config(4, 6, 32, 32, deflate_fast),
|
||||||
|
|
||||||
|
/* 4 */ new config(4, 4, 16, 16, deflate_slow), /* lazy matches */
|
||||||
|
/* 5 */ new config(8, 16, 32, 32, deflate_slow),
|
||||||
|
/* 6 */ new config(8, 16, 128, 128, deflate_slow),
|
||||||
|
/* 7 */ new config(8, 32, 128, 256, deflate_slow),
|
||||||
|
/* 8 */ new config(32, 128, 258, 1024, deflate_slow),
|
||||||
|
/* 9 */ new config(32, 258, 258, 4096, deflate_slow) /* max compression */
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
function deflate_state() {
|
||||||
this.status = 0; /* as the name implies */
|
this.status = 0; /* as the name implies */
|
||||||
this.pending_buf = -1; /* output still pending */
|
this.pending_buf = Z_NULL; /* output still pending */
|
||||||
this.pending_buf_size = 0; /* size of pending_buf */
|
this.pending_buf_size = 0; /* size of pending_buf */
|
||||||
this.pending_out = -1; /* next pending byte to output to the stream */
|
this.pending_out = Z_NULL; /* next pending byte to output to the stream */
|
||||||
this.pending = 0; /* nb of bytes in the pending buffer */
|
this.pending = 0; /* nb of bytes in the pending buffer */
|
||||||
this.last_flush = -1; /* value of flush param for previous deflate call */
|
this.last_flush = Z_NULL; /* value of flush param for previous deflate call */
|
||||||
|
|
||||||
this.w_size = 0; /* LZ77 window size (32K by default) */
|
this.w_size = 0; /* LZ77 window size (32K by default) */
|
||||||
this.w_bits = 0; /* log2(w_size) (8..16) */
|
this.w_bits = 0; /* log2(w_size) (8..16) */
|
||||||
this.w_mask = 0; /* w_size - 1 */
|
this.w_mask = 0; /* w_size - 1 */
|
||||||
|
|
||||||
this.window = -1;
|
this.window = Z_NULL;
|
||||||
/* Sliding window. Input bytes are read into the second half of the window,
|
/* Sliding window. Input bytes are read into the second half of the window,
|
||||||
* and move to the first half later to keep a dictionary of at least wSize
|
* and move to the first half later to keep a dictionary of at least wSize
|
||||||
* bytes. With this organization, matches are limited to a distance of
|
* bytes. With this organization, matches are limited to a distance of
|
||||||
|
@ -25,13 +78,13 @@ function internal_state() {
|
||||||
* is directly used as sliding window.
|
* is directly used as sliding window.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
this.prev = -1;
|
this.prev = Z_NULL;
|
||||||
/* Link to older string with same hash index. To limit the size of this
|
/* Link to older string with same hash index. To limit the size of this
|
||||||
* array to 64K, this link is maintained only for the last 32K strings.
|
* array to 64K, this link is maintained only for the last 32K strings.
|
||||||
* An index in this array is thus a window index modulo 32K.
|
* An index in this array is thus a window index modulo 32K.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
this.head = -1; /* Heads of the hash chains or NIL. */
|
this.head = Z_NULL; /* Heads of the hash chains or NIL. */
|
||||||
|
|
||||||
this.ins_h = 0; /* hash index of string to be inserted */
|
this.ins_h = 0; /* hash index of string to be inserted */
|
||||||
this.hash_size = 0; /* number of elements in hash table */
|
this.hash_size = 0; /* number of elements in hash table */
|
||||||
|
@ -89,11 +142,49 @@ function internal_state() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function deflateInit (strm, level) {
|
function deflateInit (strm, level) {
|
||||||
|
return deflateInit2(strm, level, c.Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL,c.Z_DEFAULT_STRATEGY);
|
||||||
}
|
}
|
||||||
|
|
||||||
function deflateInit2 (strm, level, method, windowBits, memLevel, strategy) {
|
function deflateInit2 (strm, level, method, windowBits, memLevel, strategy) {
|
||||||
|
if (strm == Z_NULL) return c.Z_STREAM_ERROR;
|
||||||
|
|
||||||
|
if(FASTEST) {
|
||||||
|
if (level != 0) level = 1;
|
||||||
|
} else {
|
||||||
|
if (level == c.Z_DEFAULT_COMPRESSION) level = 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (windowBits < 0) { /* suppress zlib wrapper */
|
||||||
|
wrap = 0;
|
||||||
|
windowBits = -windowBits;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */
|
||||||
|
|
||||||
|
var s = new deflate_state();
|
||||||
|
|
||||||
|
strm.state = s;
|
||||||
|
s.strm = strm;
|
||||||
|
|
||||||
|
s.wrap = wrap;
|
||||||
|
s.gzhead = Z_NULL;
|
||||||
|
s.w_bits = windowBits;
|
||||||
|
s.w_size = 1 << s.w_bits;
|
||||||
|
s.w_mask = s.w_size - 1;
|
||||||
|
|
||||||
|
s.hash_bits = memLevel + 7;
|
||||||
|
s.hash_size = 1 << s.hash_bits;
|
||||||
|
s.hash_mask = s.hash_size - 1;
|
||||||
|
s.hash_shift = ((s.hash_bits+MIN_MATCH-1)/MIN_MATCH);
|
||||||
|
|
||||||
|
s.high_water = 0; /* nothing written to s->window yet */
|
||||||
|
s.lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
|
||||||
|
|
||||||
|
s.level = level;
|
||||||
|
s.strategy = strategy;
|
||||||
|
s.method = method;
|
||||||
|
|
||||||
|
return deflateReset(strm);
|
||||||
}
|
}
|
||||||
|
|
||||||
function deflateSetDictionary (strm, dictionary, dictLength) {
|
function deflateSetDictionary (strm, dictionary, dictLength) {
|
||||||
|
@ -101,11 +192,28 @@ function deflateSetDictionary (strm, dictionary, dictLength) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function deflateResetKeep (strm) {
|
function deflateResetKeep (strm) {
|
||||||
|
strm.total_in = strm.total_out = 0;
|
||||||
|
strm.data_type = c.Z_UNKNOWN;
|
||||||
|
|
||||||
|
var s = strm.state;
|
||||||
|
s.pending = 0;
|
||||||
|
s.pending_out = s.pending_buf;
|
||||||
|
|
||||||
|
if (s.wrap < 0) {
|
||||||
|
s.wrap = -s.wrap; /* was made negative by deflate(..., Z_FINISH); */
|
||||||
|
}
|
||||||
|
s.status = s.wrap ? INIT_STATE : BUSY_STATE;
|
||||||
|
strm.adler = adler32(0, Z_NULL, 0);
|
||||||
|
s.last_flush = c.Z_NO_FLUSH;
|
||||||
|
//_tr_init(s);
|
||||||
|
return c.Z_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
function deflateReset (strm) {
|
function deflateReset (strm) {
|
||||||
|
var ret = deflateResetKeep(strm);
|
||||||
|
if (ret == c.Z_OK)
|
||||||
|
lm_init(strm.state);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
function deflateParams (strm,level,strategy) {
|
function deflateParams (strm,level,strategy) {
|
||||||
|
@ -173,7 +281,22 @@ function read_buf(strm, buf, size) {
|
||||||
* Initialize the "longest match" routines for a new zlib stream
|
* Initialize the "longest match" routines for a new zlib stream
|
||||||
*/
|
*/
|
||||||
function lm_init (s) {
|
function lm_init (s) {
|
||||||
|
s.window_size = 2* s.w_size;
|
||||||
|
|
||||||
|
/* Set the default configuration parameters:
|
||||||
|
*/
|
||||||
|
s.max_lazy_match = configuration_table[s.level].max_lazy;
|
||||||
|
s.good_match = configuration_table[s.level].good_length;
|
||||||
|
s.nice_match = configuration_table[s.level].nice_length;
|
||||||
|
s.max_chain_length = configuration_table[s.level].max_chain;
|
||||||
|
|
||||||
|
s.strstart = 0;
|
||||||
|
s.block_start = 0;
|
||||||
|
s.lookahead = 0;
|
||||||
|
s.insert = 0;
|
||||||
|
s.match_length = s.prev_length = MIN_MATCH-1;
|
||||||
|
s.match_available = 0;
|
||||||
|
s.ins_h = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ===========================================================================
|
/* ===========================================================================
|
||||||
|
|
|
@ -1,20 +1,22 @@
|
||||||
|
var c = require('constants');
|
||||||
|
|
||||||
function ZStream() {
|
function ZStream() {
|
||||||
/* next input byte */
|
/* next input byte */
|
||||||
this.next_in = -1;
|
this.next_in = c.Z_NULL;
|
||||||
/* number of bytes available at next_in */
|
/* number of bytes available at next_in */
|
||||||
this.avail_in = 0;
|
this.avail_in = 0;
|
||||||
/* total number of input bytes read so far */
|
/* total number of input bytes read so far */
|
||||||
this.total_in = 0;
|
this.total_in = 0;
|
||||||
/* next output byte should be put there */
|
/* next output byte should be put there */
|
||||||
this.next_out = -1;
|
this.next_out = c.Z_NULL;
|
||||||
/* remaining free space at next_out */
|
/* remaining free space at next_out */
|
||||||
this.avail_out = 0;
|
this.avail_out = 0;
|
||||||
/* total number of bytes output so far */
|
/* total number of bytes output so far */
|
||||||
this.total_out = 0;
|
this.total_out = 0;
|
||||||
/* last error message, NULL if no error */
|
/* last error message, NULL if no error */
|
||||||
this.msg = -1;
|
this.msg = c.Z_NULL;
|
||||||
/* not visible by applications */
|
/* not visible by applications */
|
||||||
this.state = -1;
|
this.state = c.Z_NULL;
|
||||||
/* best guess about the data type: binary or text */
|
/* best guess about the data type: binary or text */
|
||||||
this.data_type = 2;
|
this.data_type = 2;
|
||||||
/* adler32 value of the uncompressed data */
|
/* adler32 value of the uncompressed data */
|
||||||
|
|
Loading…
Add table
Reference in a new issue