@gmod/cram 3.0.6 → 3.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cram-bundle.js +1 -1
- package/dist/cramFile/codecs/byteArrayStop.d.ts +2 -2
- package/dist/cramFile/file.js +8 -10
- package/dist/cramFile/file.js.map +1 -1
- package/dist/cramFile/util.js.map +1 -1
- package/dist/htscodecs/arith_gen.d.ts +26 -0
- package/dist/htscodecs/arith_gen.js +558 -0
- package/dist/htscodecs/arith_gen.js.map +1 -0
- package/dist/htscodecs/arith_sh.d.ts +16 -0
- package/dist/htscodecs/arith_sh.js +128 -0
- package/dist/htscodecs/arith_sh.js.map +1 -0
- package/dist/htscodecs/byte_model.d.ts +11 -0
- package/dist/htscodecs/byte_model.js +113 -0
- package/dist/htscodecs/byte_model.js.map +1 -0
- package/dist/htscodecs/fqzcomp.d.ts +2 -0
- package/dist/htscodecs/fqzcomp.js +744 -0
- package/dist/htscodecs/fqzcomp.js.map +1 -0
- package/dist/htscodecs/index.d.ts +5 -0
- package/dist/htscodecs/index.js +70 -0
- package/dist/htscodecs/index.js.map +1 -0
- package/dist/htscodecs/iostream.d.ts +26 -0
- package/dist/htscodecs/iostream.js +242 -0
- package/dist/htscodecs/iostream.js.map +1 -0
- package/dist/htscodecs/main_arith_gen.d.ts +1 -0
- package/dist/htscodecs/main_arith_gen.js +86 -0
- package/dist/htscodecs/main_arith_gen.js.map +1 -0
- package/dist/htscodecs/main_fqzcomp.d.ts +1 -0
- package/dist/htscodecs/main_fqzcomp.js +112 -0
- package/dist/htscodecs/main_fqzcomp.js.map +1 -0
- package/dist/htscodecs/main_rans.d.ts +1 -0
- package/dist/htscodecs/main_rans.js +83 -0
- package/dist/htscodecs/main_rans.js.map +1 -0
- package/dist/htscodecs/main_rans4x16.d.ts +1 -0
- package/dist/htscodecs/main_rans4x16.js +82 -0
- package/dist/htscodecs/main_rans4x16.js.map +1 -0
- package/dist/htscodecs/main_tok3.d.ts +1 -0
- package/dist/htscodecs/main_tok3.js +84 -0
- package/dist/htscodecs/main_tok3.js.map +1 -0
- package/dist/htscodecs/rans.d.ts +2 -0
- package/dist/htscodecs/rans.js +480 -0
- package/dist/htscodecs/rans.js.map +1 -0
- package/dist/htscodecs/rans4x16.d.ts +2 -0
- package/dist/htscodecs/rans4x16.js +896 -0
- package/dist/htscodecs/rans4x16.js.map +1 -0
- package/dist/htscodecs/tok3.d.ts +2 -0
- package/dist/htscodecs/tok3.js +347 -0
- package/dist/htscodecs/tok3.js.map +1 -0
- package/esm/cramFile/codecs/byteArrayStop.d.ts +2 -2
- package/esm/cramFile/file.js +8 -10
- package/esm/cramFile/file.js.map +1 -1
- package/esm/cramFile/util.js.map +1 -1
- package/esm/htscodecs/arith_gen.d.ts +26 -0
- package/esm/htscodecs/arith_gen.js +558 -0
- package/esm/htscodecs/arith_gen.js.map +1 -0
- package/esm/htscodecs/arith_sh.d.ts +16 -0
- package/esm/htscodecs/arith_sh.js +128 -0
- package/esm/htscodecs/arith_sh.js.map +1 -0
- package/esm/htscodecs/byte_model.d.ts +11 -0
- package/esm/htscodecs/byte_model.js +113 -0
- package/esm/htscodecs/byte_model.js.map +1 -0
- package/esm/htscodecs/fqzcomp.d.ts +2 -0
- package/esm/htscodecs/fqzcomp.js +744 -0
- package/esm/htscodecs/fqzcomp.js.map +1 -0
- package/esm/htscodecs/index.d.ts +5 -0
- package/esm/htscodecs/index.js +70 -0
- package/esm/htscodecs/index.js.map +1 -0
- package/esm/htscodecs/iostream.d.ts +26 -0
- package/esm/htscodecs/iostream.js +242 -0
- package/esm/htscodecs/iostream.js.map +1 -0
- package/esm/htscodecs/main_arith_gen.d.ts +1 -0
- package/esm/htscodecs/main_arith_gen.js +86 -0
- package/esm/htscodecs/main_arith_gen.js.map +1 -0
- package/esm/htscodecs/main_fqzcomp.d.ts +1 -0
- package/esm/htscodecs/main_fqzcomp.js +112 -0
- package/esm/htscodecs/main_fqzcomp.js.map +1 -0
- package/esm/htscodecs/main_rans.d.ts +1 -0
- package/esm/htscodecs/main_rans.js +83 -0
- package/esm/htscodecs/main_rans.js.map +1 -0
- package/esm/htscodecs/main_rans4x16.d.ts +1 -0
- package/esm/htscodecs/main_rans4x16.js +82 -0
- package/esm/htscodecs/main_rans4x16.js.map +1 -0
- package/esm/htscodecs/main_tok3.d.ts +1 -0
- package/esm/htscodecs/main_tok3.js +84 -0
- package/esm/htscodecs/main_tok3.js.map +1 -0
- package/esm/htscodecs/rans.d.ts +2 -0
- package/esm/htscodecs/rans.js +480 -0
- package/esm/htscodecs/rans.js.map +1 -0
- package/esm/htscodecs/rans4x16.d.ts +2 -0
- package/esm/htscodecs/rans4x16.js +896 -0
- package/esm/htscodecs/rans4x16.js.map +1 -0
- package/esm/htscodecs/tok3.d.ts +2 -0
- package/esm/htscodecs/tok3.js +347 -0
- package/esm/htscodecs/tok3.js.map +1 -0
- package/package.json +1 -2
- package/src/cramFile/file.ts +8 -10
- package/src/cramFile/util.ts +0 -1
- package/src/htscodecs/Makefile +142 -0
- package/src/htscodecs/README.md +64 -0
- package/src/htscodecs/arith_gen.js +607 -0
- package/src/htscodecs/arith_sh.js +138 -0
- package/src/htscodecs/byte_model.js +126 -0
- package/src/htscodecs/fqzcomp.js +834 -0
- package/src/htscodecs/index.js +79 -0
- package/src/htscodecs/iostream.js +256 -0
- package/src/htscodecs/main_arith_gen.js +96 -0
- package/src/htscodecs/main_fqzcomp.js +113 -0
- package/src/htscodecs/main_rans.js +88 -0
- package/src/htscodecs/main_rans4x16.js +87 -0
- package/src/htscodecs/main_tok3.js +86 -0
- package/src/htscodecs/rans.js +545 -0
- package/src/htscodecs/rans4x16.js +1003 -0
- package/src/htscodecs/tok3.js +396 -0
- package/src/typings/htscodecs.d.ts +0 -6
|
@@ -0,0 +1,744 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* Copyright (c) 2019 Genome Research Ltd.
|
|
4
|
+
* Author(s): James Bonfield
|
|
5
|
+
*
|
|
6
|
+
* Redistribution and use in source and binary forms, with or without
|
|
7
|
+
* modification, are permitted provided that the following conditions are met:
|
|
8
|
+
*
|
|
9
|
+
* 1. Redistributions of source code must retain the above copyright notice,
|
|
10
|
+
* this list of conditions and the following disclaimer.
|
|
11
|
+
*
|
|
12
|
+
* 2. Redistributions in binary form must reproduce the above
|
|
13
|
+
* copyright notice, this list of conditions and the following
|
|
14
|
+
* disclaimer in the documentation and/or other materials provided
|
|
15
|
+
* with the distribution.
|
|
16
|
+
*
|
|
17
|
+
* 3. Neither the names Genome Research Ltd and Wellcome Trust Sanger
|
|
18
|
+
* Institute nor the names of its contributors may be used to endorse
|
|
19
|
+
* or promote products derived from this software without specific
|
|
20
|
+
* prior written permission.
|
|
21
|
+
*
|
|
22
|
+
* THIS SOFTWARE IS PROVIDED BY GENOME RESEARCH LTD AND CONTRIBUTORS "AS
|
|
23
|
+
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
|
24
|
+
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
|
25
|
+
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GENOME RESEARCH
|
|
26
|
+
* LTD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
27
|
+
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
28
|
+
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
29
|
+
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
30
|
+
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
31
|
+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
32
|
+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
33
|
+
*/
|
|
34
|
+
const IOStream = require('./iostream');
|
|
35
|
+
const ByteModel = require('./byte_model');
|
|
36
|
+
const RangeCoder = require('./arith_sh');
|
|
37
|
+
//----------------------------------------------------------------------
|
|
38
|
+
// Main arithmetic entry function: decodes a compressed src and
|
|
39
|
+
// returns the uncompressed buffer.
|
|
40
|
+
function read_array(src, tab, size) {
|
|
41
|
+
var j = 0; // array value
|
|
42
|
+
var z = 0; // array index: tab[j]
|
|
43
|
+
var last = -1;
|
|
44
|
+
// Remove first level of run-length encoding
|
|
45
|
+
var R = new Array(1024); // runs
|
|
46
|
+
while (z < size) {
|
|
47
|
+
var run = src.ReadByte();
|
|
48
|
+
R[j++] = run;
|
|
49
|
+
z += run;
|
|
50
|
+
if (run == last) {
|
|
51
|
+
var copy = src.ReadByte();
|
|
52
|
+
z += run * copy;
|
|
53
|
+
while (copy--)
|
|
54
|
+
R[j++] = run;
|
|
55
|
+
}
|
|
56
|
+
last = run;
|
|
57
|
+
}
|
|
58
|
+
// Now expand runs in R to tab, noting 255 is max run
|
|
59
|
+
var i = 0;
|
|
60
|
+
j = 0;
|
|
61
|
+
z = 0;
|
|
62
|
+
while (z < size) {
|
|
63
|
+
var run_len = 0;
|
|
64
|
+
do {
|
|
65
|
+
var part = R[j++];
|
|
66
|
+
run_len += part;
|
|
67
|
+
} while (part == 255);
|
|
68
|
+
while (run_len--)
|
|
69
|
+
tab[z++] = i;
|
|
70
|
+
i++;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
const QMAX = 256;
|
|
74
|
+
const FLAG_DEDUP = 2;
|
|
75
|
+
const FLAG_FLEN = 4;
|
|
76
|
+
const FLAG_SEL = 8; // whether selector is used in context
|
|
77
|
+
const FLAG_QMAP = 16;
|
|
78
|
+
const FLAG_PTAB = 32;
|
|
79
|
+
const FLAG_DTAB = 64;
|
|
80
|
+
const FLAG_QTAB = 128;
|
|
81
|
+
const GFLAG_MULTI_PARAM = 1;
|
|
82
|
+
const GFLAG_HAVE_STAB = 2;
|
|
83
|
+
const GFLAG_DO_REV = 4;
|
|
84
|
+
// Compute a new context from our current state and qual q
|
|
85
|
+
function fqz_update_ctx(params, state, q) {
|
|
86
|
+
var last = params.context;
|
|
87
|
+
state.qctx = (state.qctx << params.qshift) + params.qtab[q]; // >>> 0
|
|
88
|
+
last += (state.qctx & ((1 << params.qbits) - 1)) << params.qloc; // >>> 0
|
|
89
|
+
if (params.do_pos)
|
|
90
|
+
last += params.ptab[Math.min(state.p, 1023)] << params.ploc;
|
|
91
|
+
if (params.do_delta) {
|
|
92
|
+
last += params.dtab[Math.min(state.delta, 255)] << params.dloc;
|
|
93
|
+
// Is it better to use q here or qtab[q]?
|
|
94
|
+
// If qtab[q] we can map eg [a-z0-9A-Z]->0 ,->1 and have
|
|
95
|
+
// delta being a token number count into comma separated lists?
|
|
96
|
+
state.delta += state.prevq != q ? 1 : 0;
|
|
97
|
+
state.prevq = q;
|
|
98
|
+
}
|
|
99
|
+
if (params.do_sel)
|
|
100
|
+
last += state.s << params.sloc;
|
|
101
|
+
state.p--;
|
|
102
|
+
return last & 0xffff;
|
|
103
|
+
}
|
|
104
|
+
function decode_fqz_single_param(src) {
|
|
105
|
+
var p = {}; // params
|
|
106
|
+
// Load FQZ parameters
|
|
107
|
+
p.context = src.ReadUint16();
|
|
108
|
+
p.pflags = src.ReadByte();
|
|
109
|
+
p.do_dedup = p.pflags & FLAG_DEDUP;
|
|
110
|
+
p.fixed_len = p.pflags & FLAG_FLEN;
|
|
111
|
+
p.do_sel = p.pflags & FLAG_SEL;
|
|
112
|
+
p.do_qmap = p.pflags & FLAG_QMAP;
|
|
113
|
+
p.do_pos = p.pflags & FLAG_PTAB;
|
|
114
|
+
p.do_delta = p.pflags & FLAG_DTAB;
|
|
115
|
+
p.do_qtab = p.pflags & FLAG_QTAB;
|
|
116
|
+
p.max_sym = src.ReadByte();
|
|
117
|
+
var x = src.ReadByte();
|
|
118
|
+
p.qbits = x >> 4;
|
|
119
|
+
p.qshift = x & 15;
|
|
120
|
+
x = src.ReadByte();
|
|
121
|
+
p.qloc = x >> 4;
|
|
122
|
+
p.sloc = x & 15;
|
|
123
|
+
x = src.ReadByte();
|
|
124
|
+
p.ploc = x >> 4;
|
|
125
|
+
p.dloc = x & 15;
|
|
126
|
+
// Qual map, eg to "unbin" Illumina qualities
|
|
127
|
+
p.qmap = new Array(256);
|
|
128
|
+
if (p.pflags & FLAG_QMAP) {
|
|
129
|
+
for (var i = 0; i < p.max_sym; i++)
|
|
130
|
+
p.qmap[i] = src.ReadByte();
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
// Useful optimisation to speed up main loop
|
|
134
|
+
for (var i = 0; i < 256; i++)
|
|
135
|
+
p.qmap[i] = i; // NOP
|
|
136
|
+
}
|
|
137
|
+
// Read tables
|
|
138
|
+
p.qtab = new Array(1024);
|
|
139
|
+
if (p.qbits > 0 && p.pflags & FLAG_QTAB) {
|
|
140
|
+
read_array(src, p.qtab, 256);
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
// Useful optimisation to speed up main loop
|
|
144
|
+
for (var i = 0; i < 256; i++)
|
|
145
|
+
p.qtab[i] = i; // NOP
|
|
146
|
+
}
|
|
147
|
+
p.ptab = new Array(1024);
|
|
148
|
+
if (p.pflags & FLAG_PTAB)
|
|
149
|
+
read_array(src, p.ptab, 1024);
|
|
150
|
+
p.dtab = new Array(256);
|
|
151
|
+
if (p.pflags & FLAG_DTAB)
|
|
152
|
+
read_array(src, p.dtab, 256);
|
|
153
|
+
return p;
|
|
154
|
+
}
|
|
155
|
+
function decode_fqz_params(src) {
|
|
156
|
+
var gparams = {
|
|
157
|
+
max_sym: 0,
|
|
158
|
+
};
|
|
159
|
+
// Check fqz format version
|
|
160
|
+
var vers = src.ReadByte();
|
|
161
|
+
if (vers != 5) {
|
|
162
|
+
console.error('Invalid FQZComp version number');
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
var gflags = src.ReadByte();
|
|
166
|
+
var nparam = gflags & GFLAG_MULTI_PARAM ? src.ReadByte() : 1;
|
|
167
|
+
var max_sel = gflags.nparam > 1 ? gflags.nparam - 1 : 0; // Note max_sel, not num_sel
|
|
168
|
+
var stab = new Array(256);
|
|
169
|
+
if (gflags & GFLAG_HAVE_STAB) {
|
|
170
|
+
max_sel = src.ReadByte();
|
|
171
|
+
read_array(src, stab, 256);
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
for (var i = 0; i < nparam; i++)
|
|
175
|
+
stab[i] = i;
|
|
176
|
+
for (; i < 256; i++)
|
|
177
|
+
stab[i] = nparam - 1;
|
|
178
|
+
}
|
|
179
|
+
gparams.do_rev = gflags & GFLAG_DO_REV;
|
|
180
|
+
gparams.stab = stab;
|
|
181
|
+
gparams.max_sel = max_sel;
|
|
182
|
+
gparams.params = new Array(gparams.nparam);
|
|
183
|
+
for (var p = 0; p < nparam; p++) {
|
|
184
|
+
gparams.params[p] = decode_fqz_single_param(src);
|
|
185
|
+
if (gparams.max_sym < gparams.params[p].max_sym)
|
|
186
|
+
gparams.max_sym = gparams.params[p].max_sym;
|
|
187
|
+
}
|
|
188
|
+
return gparams;
|
|
189
|
+
}
|
|
190
|
+
function fqz_create_models(gparams) {
|
|
191
|
+
var model = {};
|
|
192
|
+
model.qual = new Array(1 << 16);
|
|
193
|
+
for (var i = 0; i < 1 << 16; i++)
|
|
194
|
+
model.qual[i] = new ByteModel(gparams.max_sym + 1); // +1 as max value not num. values
|
|
195
|
+
model.len = new Array(4);
|
|
196
|
+
for (var i = 0; i < 4; i++)
|
|
197
|
+
model.len[i] = new ByteModel(256);
|
|
198
|
+
model.rev = new ByteModel(2);
|
|
199
|
+
model.dup = new ByteModel(2);
|
|
200
|
+
if (gparams.max_sel > 0)
|
|
201
|
+
model.sel = new ByteModel(gparams.max_sel + 1); // +1 as max value not num. values
|
|
202
|
+
return model;
|
|
203
|
+
}
|
|
204
|
+
// Initialise a new record, updating state.
|
|
205
|
+
// Returns 1 if dup, otherwise 0
|
|
206
|
+
function decode_fqz_new_record(src, rc, gparams, model, state, rev) {
|
|
207
|
+
// Parameter selector
|
|
208
|
+
if (gparams.max_sel > 0) {
|
|
209
|
+
state.s = model.sel.ModelDecode(src, rc);
|
|
210
|
+
}
|
|
211
|
+
else {
|
|
212
|
+
state.s = 0;
|
|
213
|
+
}
|
|
214
|
+
state.x = gparams.stab[state.s];
|
|
215
|
+
var params = gparams.params[state.x];
|
|
216
|
+
// Reset contexts at the start of each new record
|
|
217
|
+
if (params.fixed_len >= 0) {
|
|
218
|
+
// Not fixed or fixed but first record
|
|
219
|
+
var len = model.len[0].ModelDecode(src, rc);
|
|
220
|
+
len |= model.len[1].ModelDecode(src, rc) << 8;
|
|
221
|
+
len |= model.len[2].ModelDecode(src, rc) << 16;
|
|
222
|
+
len |= model.len[3].ModelDecode(src, rc) << 24;
|
|
223
|
+
if (params.fixed_len > 0)
|
|
224
|
+
params.fixed_len = -len;
|
|
225
|
+
}
|
|
226
|
+
else {
|
|
227
|
+
len = -params.fixed_len;
|
|
228
|
+
}
|
|
229
|
+
state.len = len;
|
|
230
|
+
if (gparams.do_rev)
|
|
231
|
+
rev[state.rec] = model.rev.ModelDecode(src, rc);
|
|
232
|
+
state.is_dup = 0;
|
|
233
|
+
if (params.pflags & FLAG_DEDUP) {
|
|
234
|
+
if (model.dup.ModelDecode(src, rc))
|
|
235
|
+
state.is_dup = 1;
|
|
236
|
+
}
|
|
237
|
+
state.p = len; // number of remaining bytes in this record
|
|
238
|
+
state.delta = 0;
|
|
239
|
+
state.qctx = 0;
|
|
240
|
+
state.prevq = 0;
|
|
241
|
+
state.rec++;
|
|
242
|
+
}
|
|
243
|
+
function decode_fqz(src, q_lens) {
|
|
244
|
+
// Decode parameter block
|
|
245
|
+
var n_out = src.ReadUint7();
|
|
246
|
+
var gparams = decode_fqz_params(src);
|
|
247
|
+
if (!gparams)
|
|
248
|
+
return;
|
|
249
|
+
var params = gparams.params;
|
|
250
|
+
var rev = new Array(q_lens.length);
|
|
251
|
+
// Create initial models
|
|
252
|
+
var model = fqz_create_models(gparams);
|
|
253
|
+
// Create our entropy encoder and output buffers
|
|
254
|
+
var rc = new RangeCoder(src);
|
|
255
|
+
rc.RangeStartDecode(src);
|
|
256
|
+
var output = new Buffer.allocUnsafe(n_out);
|
|
257
|
+
// Internal FQZ state
|
|
258
|
+
var state = {
|
|
259
|
+
qctx: 0, // Qual-only sub-context
|
|
260
|
+
prevq: 0, // Previous quality value
|
|
261
|
+
delta: 0, // Running delta (q vs prevq)
|
|
262
|
+
p: 0, // Number of bases left in current record
|
|
263
|
+
s: 0, // Current parameter selector value (0 if unused)
|
|
264
|
+
x: 0, // "stab" tabulated copy of s
|
|
265
|
+
len: 0, // Length of current string
|
|
266
|
+
is_dup: 0, // This string is a duplicate of last
|
|
267
|
+
rec: 0, // Record number
|
|
268
|
+
};
|
|
269
|
+
// The main decode loop itself
|
|
270
|
+
var i = 0; // position in output buffer
|
|
271
|
+
while (i < n_out) {
|
|
272
|
+
if (state.p == 0) {
|
|
273
|
+
decode_fqz_new_record(src, rc, gparams, model, state, rev);
|
|
274
|
+
if (state.is_dup > 0) {
|
|
275
|
+
if (model.dup.ModelDecode(src, rc)) {
|
|
276
|
+
// Duplicate of last line
|
|
277
|
+
for (var x = 0; x < len; x++)
|
|
278
|
+
output[i + x] = output[i + x - state.len];
|
|
279
|
+
i += state.len;
|
|
280
|
+
state.p = 0;
|
|
281
|
+
continue;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
q_lens.push(state.len);
|
|
285
|
+
var params = gparams.params[state.x];
|
|
286
|
+
var last = params.context;
|
|
287
|
+
}
|
|
288
|
+
// Decode the current quality (possibly mapped via qmap)
|
|
289
|
+
var Q = model.qual[last].ModelDecode(src, rc);
|
|
290
|
+
//if (params.do_qmap)
|
|
291
|
+
// output[i++] = params.qmap[Q];
|
|
292
|
+
//else
|
|
293
|
+
// output[i++] = Q
|
|
294
|
+
output[i++] = params.qmap[Q]; // optimised version of above
|
|
295
|
+
last = fqz_update_ctx(params, state, Q);
|
|
296
|
+
}
|
|
297
|
+
if (gparams.do_rev)
|
|
298
|
+
reverse_qualities(output, n_out, rev, q_lens);
|
|
299
|
+
return output;
|
|
300
|
+
}
|
|
301
|
+
function reverse_qualities(qual, qual_len, rev, len) {
|
|
302
|
+
var rec = 0;
|
|
303
|
+
var i = 0;
|
|
304
|
+
while (i < qual_len) {
|
|
305
|
+
if (rev[rec]) {
|
|
306
|
+
var j = 0;
|
|
307
|
+
var k = len[rec] - 1;
|
|
308
|
+
while (j < k) {
|
|
309
|
+
var tmp = qual[i + j];
|
|
310
|
+
qual[i + j] = qual[i + k];
|
|
311
|
+
qual[i + k] = tmp;
|
|
312
|
+
j++;
|
|
313
|
+
k--;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
i += len[rec++];
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
function decode(src, q_lens) {
|
|
320
|
+
var stream = new IOStream(src);
|
|
321
|
+
//var n_out = stream.ReadUint32(); stream.ReadUint32(); // move to main
|
|
322
|
+
return decode_fqz(stream, q_lens);
|
|
323
|
+
}
|
|
324
|
+
//----------------------------------------------------------------------
|
|
325
|
+
// FQZComp encoder.
|
|
326
|
+
function pick_fqz_params(src, q_lens, q_dirs, qhist) {
|
|
327
|
+
// Find cardinality of q_dirs
|
|
328
|
+
var qd_last = q_dirs[0];
|
|
329
|
+
for (var i = 0; i < q_dirs.length; i++)
|
|
330
|
+
if (q_dirs[i] != qd_last)
|
|
331
|
+
break;
|
|
332
|
+
var qd_fixed = i == q_dirs.length ? 1 : 0;
|
|
333
|
+
// Scan input to find number of symbols and max symbol
|
|
334
|
+
var nsym = 0;
|
|
335
|
+
var max_sym = 0;
|
|
336
|
+
// selector == 0: Assume one single input dataset
|
|
337
|
+
for (var i = 0; i < 256; i++)
|
|
338
|
+
qhist[0][i] = 0;
|
|
339
|
+
var rec = 0;
|
|
340
|
+
var len = 0;
|
|
341
|
+
for (var i = 0; i < src.length; i++) {
|
|
342
|
+
if (len == 0) {
|
|
343
|
+
len = q_lens[rec < q_lens.length - 1 ? rec++ : rec];
|
|
344
|
+
}
|
|
345
|
+
qhist[0][src[i]]++;
|
|
346
|
+
len--;
|
|
347
|
+
}
|
|
348
|
+
for (var i = 0; i < 256; i++) {
|
|
349
|
+
if (!qhist[0][i])
|
|
350
|
+
continue;
|
|
351
|
+
if (max_sym < i)
|
|
352
|
+
max_sym = i;
|
|
353
|
+
nsym++;
|
|
354
|
+
}
|
|
355
|
+
var qshift = 5;
|
|
356
|
+
var do_qmap = 0;
|
|
357
|
+
// Reduced symbol frequencies implies lower qshift and
|
|
358
|
+
// a lookup table to go from qual to Q
|
|
359
|
+
if (nsym <= 16) {
|
|
360
|
+
do_qmap = 1; // based on qhist
|
|
361
|
+
if (nsym <= 2)
|
|
362
|
+
qshift = 1;
|
|
363
|
+
else if (nsym <= 4)
|
|
364
|
+
qshift = 2;
|
|
365
|
+
else if (nsym <= 8)
|
|
366
|
+
qshift = 3;
|
|
367
|
+
else
|
|
368
|
+
qshift = 4;
|
|
369
|
+
}
|
|
370
|
+
// // Two params and a 1-bit selector.
|
|
371
|
+
// // This is 1% overhead vs two data sets compressed independently.
|
|
372
|
+
// // It's 6.9% smaller than compressing both together with 1 param.
|
|
373
|
+
// if (0) return [{
|
|
374
|
+
// // q4
|
|
375
|
+
// qbits: 8,
|
|
376
|
+
// qshift: 2,
|
|
377
|
+
// qloc: 7,
|
|
378
|
+
//
|
|
379
|
+
// pbits: 7,
|
|
380
|
+
// pshift: 1,
|
|
381
|
+
// ploc: 0,
|
|
382
|
+
//
|
|
383
|
+
// dbits: 0,
|
|
384
|
+
// dshift: 0,
|
|
385
|
+
// dloc: 0,
|
|
386
|
+
//
|
|
387
|
+
// sbits: 0,
|
|
388
|
+
// sloc: 0,
|
|
389
|
+
//
|
|
390
|
+
// //sbits: 2,
|
|
391
|
+
// //do_stab: 1,
|
|
392
|
+
// sbits: 1,
|
|
393
|
+
// do_stab: 0,
|
|
394
|
+
// context: (0<<15),
|
|
395
|
+
//
|
|
396
|
+
// max_sym: 36,
|
|
397
|
+
// nsym: 4,
|
|
398
|
+
//
|
|
399
|
+
// do_qmap: 1,
|
|
400
|
+
// do_dedup: 0,
|
|
401
|
+
// fixed_len: 1,
|
|
402
|
+
// do_sel: 0,
|
|
403
|
+
// do_rev: 0,
|
|
404
|
+
// do_pos: 1,
|
|
405
|
+
// do_delta: 0,
|
|
406
|
+
// do_qtab: 0
|
|
407
|
+
// }, {
|
|
408
|
+
// //q40
|
|
409
|
+
// qbits: 9,
|
|
410
|
+
// qshift: 5,
|
|
411
|
+
// qloc: 7,
|
|
412
|
+
//
|
|
413
|
+
// pbits: 7,
|
|
414
|
+
// pshift: 0,
|
|
415
|
+
// ploc: 0,
|
|
416
|
+
//
|
|
417
|
+
// dbits: 0,
|
|
418
|
+
// dshift: 0,
|
|
419
|
+
// dloc: 0,
|
|
420
|
+
//
|
|
421
|
+
// sbits: 0,
|
|
422
|
+
// sloc: 0,
|
|
423
|
+
//
|
|
424
|
+
// //sbits: 2,
|
|
425
|
+
// //do_stab: 1,
|
|
426
|
+
// sbits: 1,
|
|
427
|
+
// do_stab: 0,
|
|
428
|
+
// context: (1<<15),
|
|
429
|
+
//
|
|
430
|
+
// max_sym: 44,
|
|
431
|
+
// nsym: 45,
|
|
432
|
+
//
|
|
433
|
+
// do_qmap: 0,
|
|
434
|
+
// do_dedup: 0,
|
|
435
|
+
// fixed_len: 1,
|
|
436
|
+
// do_sel: 0,
|
|
437
|
+
// do_rev: 0,
|
|
438
|
+
// do_pos: 1,
|
|
439
|
+
// do_delta: 0,
|
|
440
|
+
// do_qtab: 0
|
|
441
|
+
// }]
|
|
442
|
+
return [
|
|
443
|
+
{
|
|
444
|
+
qbits: 8 + (qshift > 4),
|
|
445
|
+
qshift: qshift,
|
|
446
|
+
qloc: 7,
|
|
447
|
+
pbits: 7,
|
|
448
|
+
pshift: q_lens[0] > 128 ? 1 : 0,
|
|
449
|
+
ploc: 0,
|
|
450
|
+
dbits: qshift > 4 ? 0 : 1,
|
|
451
|
+
dshift: 3,
|
|
452
|
+
dloc: 15,
|
|
453
|
+
// NB: Also useful as a way of embedding sel and doing sel
|
|
454
|
+
// specific contexts. Identical bar context. Eg 0<<15 or 1<<15.
|
|
455
|
+
sbits: 0,
|
|
456
|
+
sloc: 15,
|
|
457
|
+
do_stab: 0,
|
|
458
|
+
context: 0 << 15,
|
|
459
|
+
max_sym: max_sym,
|
|
460
|
+
nsym: nsym,
|
|
461
|
+
do_qmap: do_qmap,
|
|
462
|
+
do_dedup: 0,
|
|
463
|
+
fixed_len: q_lens.length == 1 ? 1 : 0,
|
|
464
|
+
do_sel: 0,
|
|
465
|
+
do_rev: 0,
|
|
466
|
+
do_pos: 1,
|
|
467
|
+
do_delta: qshift <= 4 ? 1 : 0,
|
|
468
|
+
do_qtab: 0,
|
|
469
|
+
// Override above with some attempt at using selectors
|
|
470
|
+
// when the q_dirs are specific and non-fixed.
|
|
471
|
+
qbits: 8 + (qshift > 4) - (qd_fixed == 0),
|
|
472
|
+
sbits: 1,
|
|
473
|
+
sloc: 15 - (qshift <= 4), // read1 vs read2
|
|
474
|
+
do_stab: 1,
|
|
475
|
+
do_sel: 1,
|
|
476
|
+
// // q4+dir: 7245769 with, 7353962 without. 1.5% saving
|
|
477
|
+
// qbits: 6,
|
|
478
|
+
// dbits: 2,
|
|
479
|
+
// dshift: 2,
|
|
480
|
+
// dloc: 13,
|
|
481
|
+
// sbits: 1,
|
|
482
|
+
// sloc: 15,
|
|
483
|
+
// do_stab: 1,
|
|
484
|
+
// do_sel: 1,
|
|
485
|
+
// with 20 bits of context, q40 = 31741545
|
|
486
|
+
// qbits 10, dbits 2, pbits 7, sbits 1
|
|
487
|
+
},
|
|
488
|
+
];
|
|
489
|
+
}
|
|
490
|
+
function store_array(out, tab, size) {
|
|
491
|
+
var i = 0; // index into tab
|
|
492
|
+
var j = 0; // current value in tab[i]
|
|
493
|
+
var tmp1 = new Array(size * 2);
|
|
494
|
+
var sz1 = 0;
|
|
495
|
+
// First level of RLE. Replace all runs of 'j' values
|
|
496
|
+
// with run-lengths, including zeros for missing values.
|
|
497
|
+
// Eg 0 1 2 2 2 3 3 3 4 4 4 5 5 5 5 7 7
|
|
498
|
+
// to 1 1 3 3 3 4 0 2
|
|
499
|
+
while (i < size) {
|
|
500
|
+
// Length of j^{th} element
|
|
501
|
+
var i_start = i;
|
|
502
|
+
while (i < size && tab[i] == j)
|
|
503
|
+
i++;
|
|
504
|
+
var run_len = i - i_start;
|
|
505
|
+
// Encode run length to tmp array
|
|
506
|
+
do {
|
|
507
|
+
var r = Math.min(255, run_len);
|
|
508
|
+
tmp1[sz1++] = r;
|
|
509
|
+
run_len -= r;
|
|
510
|
+
} while (r == 255);
|
|
511
|
+
j++;
|
|
512
|
+
}
|
|
513
|
+
// Second round of RLE on our tmp array, using a different
|
|
514
|
+
// RLE algorithm.
|
|
515
|
+
// Eg 1 1 3 3 3 4 0 2
|
|
516
|
+
// to 1 1 +0 3 3 +1 4 0 2
|
|
517
|
+
var last = -1;
|
|
518
|
+
var tmp2 = new Array(size * 2);
|
|
519
|
+
var sz2 = 0;
|
|
520
|
+
i = 0; // index into tmp1]
|
|
521
|
+
// k is used size of tmp1[]
|
|
522
|
+
while (i < sz1) {
|
|
523
|
+
var curr = tmp1[i++];
|
|
524
|
+
tmp2[sz2++] = curr;
|
|
525
|
+
if (curr == last) {
|
|
526
|
+
var i_start = i;
|
|
527
|
+
while (i < sz1 && tmp1[i] == last && i - i_start < 255)
|
|
528
|
+
i++;
|
|
529
|
+
tmp2[sz2++] = i - i_start;
|
|
530
|
+
}
|
|
531
|
+
else {
|
|
532
|
+
last = curr;
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
// Append 2nd RLE, tmp2, to out.
|
|
536
|
+
out.WriteData(tmp2, sz2);
|
|
537
|
+
}
|
|
538
|
+
// q_lens is an array of quality lengths per record.
|
|
539
|
+
// (If they're all the same, just set one value.)
|
|
540
|
+
function encode_fqz_params(out, params, qhist, qtab, ptab, dtab, stab) {
|
|
541
|
+
var dsqr = [
|
|
542
|
+
0, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
|
543
|
+
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7,
|
|
544
|
+
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
|
545
|
+
];
|
|
546
|
+
for (var i = 0; i < params.length; i++)
|
|
547
|
+
stab[i] = i; // 1 parameter set per selector value
|
|
548
|
+
for (; i < 256; i++)
|
|
549
|
+
stab[i] = params.length - 1;
|
|
550
|
+
// Store global meta-data
|
|
551
|
+
out.WriteByte(5); // FQZ format number
|
|
552
|
+
var gflags = (params.length > 1 ? GFLAG_MULTI_PARAM : 0) |
|
|
553
|
+
(params[0].do_stab ? GFLAG_HAVE_STAB : 0);
|
|
554
|
+
out.WriteByte(gflags);
|
|
555
|
+
if (gflags & GFLAG_MULTI_PARAM)
|
|
556
|
+
out.WriteByte(params.length); // Number of parameter blocks.
|
|
557
|
+
if (gflags & GFLAG_HAVE_STAB) {
|
|
558
|
+
var max_sel = 1 << params[0].sbits;
|
|
559
|
+
if (max_sel > 0)
|
|
560
|
+
max_sel--;
|
|
561
|
+
out.WriteByte(max_sel);
|
|
562
|
+
store_array(out, stab, 256);
|
|
563
|
+
}
|
|
564
|
+
// Store per-param meta-data
|
|
565
|
+
for (var p = 0; p < params.length; p++) {
|
|
566
|
+
out.WriteUint16(params[p].context);
|
|
567
|
+
out.WriteByte((params[p].do_qtab ? FLAG_QTAB : 0) | // FLAG
|
|
568
|
+
(params[p].do_delta ? FLAG_DTAB : 0) |
|
|
569
|
+
(params[p].do_pos ? FLAG_PTAB : 0) |
|
|
570
|
+
(params[p].do_qmap ? FLAG_QMAP : 0) |
|
|
571
|
+
(params[p].do_sel ? FLAG_SEL : 0) |
|
|
572
|
+
(params[p].fixed_len ? FLAG_FLEN : 0) |
|
|
573
|
+
(params[p].do_dedup ? FLAG_DEDUP : 0));
|
|
574
|
+
if (params[p].do_qmap)
|
|
575
|
+
out.WriteByte(params[p].nsym);
|
|
576
|
+
else
|
|
577
|
+
out.WriteByte(params[p].max_sym);
|
|
578
|
+
out.WriteByte((params[p].qbits << 4) | params[p].qshift);
|
|
579
|
+
out.WriteByte((params[p].qloc << 4) | params[p].sloc);
|
|
580
|
+
out.WriteByte((params[p].ploc << 4) | params[p].dloc);
|
|
581
|
+
if (params[p].do_qmap) {
|
|
582
|
+
params[p].max_sym = params[p].nsym;
|
|
583
|
+
var n = 0;
|
|
584
|
+
for (var i = 0; i < 256; i++) {
|
|
585
|
+
if (qhist[p][i]) {
|
|
586
|
+
out.WriteByte(i);
|
|
587
|
+
qhist[p][i] = n++;
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
// Ensure we have all matched input params
|
|
591
|
+
for (; n < params[p].nsym; n++)
|
|
592
|
+
out.WriteByte(0);
|
|
593
|
+
}
|
|
594
|
+
else {
|
|
595
|
+
//params[p].nsym = 255;
|
|
596
|
+
for (var i = 0; i < 256; i++)
|
|
597
|
+
qhist[p][i] = i; // NOP
|
|
598
|
+
}
|
|
599
|
+
if (params[p].qbits > 0) {
|
|
600
|
+
// // Eg map 0-44 to a smaller range, to improve context usage.
|
|
601
|
+
// // Makes q40 test set go from 33596471 to 33450075 (-0.4%)
|
|
602
|
+
// params[p].do_qtab = 1;
|
|
603
|
+
// for (var j = i = 0; i < params[p].max_sym; i++) {
|
|
604
|
+
// qtab[i]=j;
|
|
605
|
+
// if ((i%3)!=0 | i >= 28) j++
|
|
606
|
+
// console.log("qtab[",i,"]=",qtab[i]);
|
|
607
|
+
// }
|
|
608
|
+
// for (; i < 256; i++)
|
|
609
|
+
// qtab[i] = qtab[params[p].max_sym-1]
|
|
610
|
+
for (var i = 0; i < 256; i++)
|
|
611
|
+
qtab[p][i] = i; // NOP for now
|
|
612
|
+
if (params[p].do_qtab)
|
|
613
|
+
store_array(out, qtab[p], 256);
|
|
614
|
+
}
|
|
615
|
+
if (params[p].pbits > 0) {
|
|
616
|
+
for (var i = 0; i < 1024; i++)
|
|
617
|
+
ptab[p][i] = Math.min((1 << params[p].pbits) - 1, i >> params[p].pshift);
|
|
618
|
+
store_array(out, ptab[p], 1024);
|
|
619
|
+
}
|
|
620
|
+
if (params[p].dbits > 0) {
|
|
621
|
+
for (var i = 0; i < 256; i++)
|
|
622
|
+
if (dsqr[i] > (1 << params[p].dbits) - 1)
|
|
623
|
+
dsqr[i] = (1 << params[p].dbits) - 1;
|
|
624
|
+
for (var i = 0; i < 256; i++)
|
|
625
|
+
dtab[p][i] = dsqr[Math.min(dsqr.length - 1, i >> params[p].dshift)];
|
|
626
|
+
store_array(out, dtab[p], 256);
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
return out;
|
|
630
|
+
}
|
|
631
|
+
function encode_fqz(out, src, q_lens, q_dirs, params, qhist, qtab, ptab, dtab, stab) {
|
|
632
|
+
//console.error("0:",params[0])
|
|
633
|
+
//console.error("1:",params[1])
|
|
634
|
+
var max_sel = 1 << params[0].sbits;
|
|
635
|
+
if (max_sel > 0)
|
|
636
|
+
max_sel--;
|
|
637
|
+
var n_in = src.length;
|
|
638
|
+
// Create the models
|
|
639
|
+
var max_sym = 0;
|
|
640
|
+
for (var p = 0; p < params.length; p++)
|
|
641
|
+
if (max_sym < params[p].max_sym)
|
|
642
|
+
max_sym = params[p].max_sym;
|
|
643
|
+
var model_qual = new Array(1 << 16);
|
|
644
|
+
for (var i = 0; i < 1 << 16; i++)
|
|
645
|
+
model_qual[i] = new ByteModel(max_sym + 1);
|
|
646
|
+
var model_len = new Array(4);
|
|
647
|
+
for (var i = 0; i < 4; i++)
|
|
648
|
+
model_len[i] = new ByteModel(256);
|
|
649
|
+
var model_rev = new ByteModel(2);
|
|
650
|
+
var model_dup = new ByteModel(2);
|
|
651
|
+
var model_sel = new ByteModel(max_sel + 1);
|
|
652
|
+
// Note: our JavaScript encoder doesn't have a way for reversing
|
|
653
|
+
// some quality strings, so we ignore do_rev for now.
|
|
654
|
+
var rc = new RangeCoder(src);
|
|
655
|
+
// The main encoding loop
|
|
656
|
+
var p = 0; // remaining position along current record
|
|
657
|
+
var i = 0; // index in src data
|
|
658
|
+
var rec = 0;
|
|
659
|
+
while (i < n_in) {
|
|
660
|
+
if (p == 0) {
|
|
661
|
+
//var s = 0 // single non-mixed sample
|
|
662
|
+
var s = q_dirs[rec];
|
|
663
|
+
if (params[0].sbits > 0) {
|
|
664
|
+
// FIXME: check All params[].do_stab / sbits must be identical
|
|
665
|
+
//console.log("Ssel", s)
|
|
666
|
+
model_sel.ModelEncode(out, rc, s);
|
|
667
|
+
}
|
|
668
|
+
var x = stab[s];
|
|
669
|
+
// Reset contexts at the statr of each new record
|
|
670
|
+
var len = q_lens[Math.min(q_lens.length - 1, rec++)];
|
|
671
|
+
if (params[x].fixed_len) {
|
|
672
|
+
if (params[x].fixed_len > 0) {
|
|
673
|
+
// First length
|
|
674
|
+
//console.log("Len", len)
|
|
675
|
+
model_len[0].ModelEncode(out, rc, len & 0xff);
|
|
676
|
+
model_len[1].ModelEncode(out, rc, (len >> 8) & 0xff);
|
|
677
|
+
model_len[2].ModelEncode(out, rc, (len >> 16) & 0xff);
|
|
678
|
+
model_len[3].ModelEncode(out, rc, (len >> 24) & 0xff);
|
|
679
|
+
params[x].fixed_len = -1; // indicate we've stored it once
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
else {
|
|
683
|
+
//console.log("len", len)
|
|
684
|
+
model_len[0].ModelEncode(out, rc, len & 0xff);
|
|
685
|
+
model_len[1].ModelEncode(out, rc, (len >> 8) & 0xff);
|
|
686
|
+
model_len[2].ModelEncode(out, rc, (len >> 16) & 0xff);
|
|
687
|
+
model_len[3].ModelEncode(out, rc, (len >> 24) & 0xff);
|
|
688
|
+
}
|
|
689
|
+
if (params[x].do_dedup)
|
|
690
|
+
process.exit(1); // FIXME
|
|
691
|
+
p = len;
|
|
692
|
+
var delta = 0;
|
|
693
|
+
//var last = 0
|
|
694
|
+
var last = params[x].context;
|
|
695
|
+
var qlast = 0;
|
|
696
|
+
var q1 = 0;
|
|
697
|
+
}
|
|
698
|
+
// Encode current quality
|
|
699
|
+
var q = src[i++];
|
|
700
|
+
var Q = qhist[x][q];
|
|
701
|
+
model_qual[last].ModelEncode(out, rc, Q);
|
|
702
|
+
//console.log("Ctx",last,qhist[x][q])
|
|
703
|
+
// Update contexts for next quality
|
|
704
|
+
qlast = (qlast << params[x].qshift) + qtab[x][Q];
|
|
705
|
+
last = params[x].context;
|
|
706
|
+
last += (qlast & ((1 << params[x].qbits) - 1)) << params[x].qloc;
|
|
707
|
+
// 46.6-48.6 billion cycles with ifs + "<< params[x].?loc" shifts
|
|
708
|
+
// 47.3-47.3 billion cycles with ifs
|
|
709
|
+
// 47.1-47.9 billion cycles without ifs
|
|
710
|
+
if (params[x].pbits > 0)
|
|
711
|
+
last += ptab[x][Math.min(p, 1023)] << params[x].ploc;
|
|
712
|
+
if (params[x].dbits > 0) {
|
|
713
|
+
last += dtab[x][Math.min(delta, 255)] << params[x].dloc;
|
|
714
|
+
delta += q1 != Q ? 1 : 0;
|
|
715
|
+
q1 = Q;
|
|
716
|
+
}
|
|
717
|
+
if (params[x].do_sel)
|
|
718
|
+
last += s << params[x].sloc;
|
|
719
|
+
last = last & 0xffff;
|
|
720
|
+
p--;
|
|
721
|
+
}
|
|
722
|
+
rc.RangeFinishEncode(out);
|
|
723
|
+
return out.buf.slice(0, out.pos);
|
|
724
|
+
}
|
|
725
|
+
function encode(src, q_lens, q_dirs) {
|
|
726
|
+
var qhist = new Array(2);
|
|
727
|
+
var qtab = new Array(2);
|
|
728
|
+
var ptab = new Array(2);
|
|
729
|
+
var dtab = new Array(2);
|
|
730
|
+
var stab = new Array(256);
|
|
731
|
+
for (var s = 0; s < 2; s++) {
|
|
732
|
+
qhist[s] = new Array(256);
|
|
733
|
+
qtab[s] = new Array(256);
|
|
734
|
+
ptab[s] = new Array(1024);
|
|
735
|
+
dtab[s] = new Array(256);
|
|
736
|
+
}
|
|
737
|
+
var out = new IOStream('', 0, src.length * 1.1 + 100); // FIXME: guestimate worst case
|
|
738
|
+
out.WriteUint7(src.length);
|
|
739
|
+
var params = pick_fqz_params(src, q_lens, q_dirs, qhist);
|
|
740
|
+
var out = encode_fqz_params(out, params, qhist, qtab, ptab, dtab, stab);
|
|
741
|
+
return encode_fqz(out, src, q_lens, q_dirs, params, qhist, qtab, ptab, dtab, stab);
|
|
742
|
+
}
|
|
743
|
+
module.exports = { decode, encode };
|
|
744
|
+
//# sourceMappingURL=fqzcomp.js.map
|