@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.
Files changed (113) hide show
  1. package/dist/cram-bundle.js +1 -1
  2. package/dist/cramFile/codecs/byteArrayStop.d.ts +2 -2
  3. package/dist/cramFile/file.js +8 -10
  4. package/dist/cramFile/file.js.map +1 -1
  5. package/dist/cramFile/util.js.map +1 -1
  6. package/dist/htscodecs/arith_gen.d.ts +26 -0
  7. package/dist/htscodecs/arith_gen.js +558 -0
  8. package/dist/htscodecs/arith_gen.js.map +1 -0
  9. package/dist/htscodecs/arith_sh.d.ts +16 -0
  10. package/dist/htscodecs/arith_sh.js +128 -0
  11. package/dist/htscodecs/arith_sh.js.map +1 -0
  12. package/dist/htscodecs/byte_model.d.ts +11 -0
  13. package/dist/htscodecs/byte_model.js +113 -0
  14. package/dist/htscodecs/byte_model.js.map +1 -0
  15. package/dist/htscodecs/fqzcomp.d.ts +2 -0
  16. package/dist/htscodecs/fqzcomp.js +744 -0
  17. package/dist/htscodecs/fqzcomp.js.map +1 -0
  18. package/dist/htscodecs/index.d.ts +5 -0
  19. package/dist/htscodecs/index.js +70 -0
  20. package/dist/htscodecs/index.js.map +1 -0
  21. package/dist/htscodecs/iostream.d.ts +26 -0
  22. package/dist/htscodecs/iostream.js +242 -0
  23. package/dist/htscodecs/iostream.js.map +1 -0
  24. package/dist/htscodecs/main_arith_gen.d.ts +1 -0
  25. package/dist/htscodecs/main_arith_gen.js +86 -0
  26. package/dist/htscodecs/main_arith_gen.js.map +1 -0
  27. package/dist/htscodecs/main_fqzcomp.d.ts +1 -0
  28. package/dist/htscodecs/main_fqzcomp.js +112 -0
  29. package/dist/htscodecs/main_fqzcomp.js.map +1 -0
  30. package/dist/htscodecs/main_rans.d.ts +1 -0
  31. package/dist/htscodecs/main_rans.js +83 -0
  32. package/dist/htscodecs/main_rans.js.map +1 -0
  33. package/dist/htscodecs/main_rans4x16.d.ts +1 -0
  34. package/dist/htscodecs/main_rans4x16.js +82 -0
  35. package/dist/htscodecs/main_rans4x16.js.map +1 -0
  36. package/dist/htscodecs/main_tok3.d.ts +1 -0
  37. package/dist/htscodecs/main_tok3.js +84 -0
  38. package/dist/htscodecs/main_tok3.js.map +1 -0
  39. package/dist/htscodecs/rans.d.ts +2 -0
  40. package/dist/htscodecs/rans.js +480 -0
  41. package/dist/htscodecs/rans.js.map +1 -0
  42. package/dist/htscodecs/rans4x16.d.ts +2 -0
  43. package/dist/htscodecs/rans4x16.js +896 -0
  44. package/dist/htscodecs/rans4x16.js.map +1 -0
  45. package/dist/htscodecs/tok3.d.ts +2 -0
  46. package/dist/htscodecs/tok3.js +347 -0
  47. package/dist/htscodecs/tok3.js.map +1 -0
  48. package/esm/cramFile/codecs/byteArrayStop.d.ts +2 -2
  49. package/esm/cramFile/file.js +8 -10
  50. package/esm/cramFile/file.js.map +1 -1
  51. package/esm/cramFile/util.js.map +1 -1
  52. package/esm/htscodecs/arith_gen.d.ts +26 -0
  53. package/esm/htscodecs/arith_gen.js +558 -0
  54. package/esm/htscodecs/arith_gen.js.map +1 -0
  55. package/esm/htscodecs/arith_sh.d.ts +16 -0
  56. package/esm/htscodecs/arith_sh.js +128 -0
  57. package/esm/htscodecs/arith_sh.js.map +1 -0
  58. package/esm/htscodecs/byte_model.d.ts +11 -0
  59. package/esm/htscodecs/byte_model.js +113 -0
  60. package/esm/htscodecs/byte_model.js.map +1 -0
  61. package/esm/htscodecs/fqzcomp.d.ts +2 -0
  62. package/esm/htscodecs/fqzcomp.js +744 -0
  63. package/esm/htscodecs/fqzcomp.js.map +1 -0
  64. package/esm/htscodecs/index.d.ts +5 -0
  65. package/esm/htscodecs/index.js +70 -0
  66. package/esm/htscodecs/index.js.map +1 -0
  67. package/esm/htscodecs/iostream.d.ts +26 -0
  68. package/esm/htscodecs/iostream.js +242 -0
  69. package/esm/htscodecs/iostream.js.map +1 -0
  70. package/esm/htscodecs/main_arith_gen.d.ts +1 -0
  71. package/esm/htscodecs/main_arith_gen.js +86 -0
  72. package/esm/htscodecs/main_arith_gen.js.map +1 -0
  73. package/esm/htscodecs/main_fqzcomp.d.ts +1 -0
  74. package/esm/htscodecs/main_fqzcomp.js +112 -0
  75. package/esm/htscodecs/main_fqzcomp.js.map +1 -0
  76. package/esm/htscodecs/main_rans.d.ts +1 -0
  77. package/esm/htscodecs/main_rans.js +83 -0
  78. package/esm/htscodecs/main_rans.js.map +1 -0
  79. package/esm/htscodecs/main_rans4x16.d.ts +1 -0
  80. package/esm/htscodecs/main_rans4x16.js +82 -0
  81. package/esm/htscodecs/main_rans4x16.js.map +1 -0
  82. package/esm/htscodecs/main_tok3.d.ts +1 -0
  83. package/esm/htscodecs/main_tok3.js +84 -0
  84. package/esm/htscodecs/main_tok3.js.map +1 -0
  85. package/esm/htscodecs/rans.d.ts +2 -0
  86. package/esm/htscodecs/rans.js +480 -0
  87. package/esm/htscodecs/rans.js.map +1 -0
  88. package/esm/htscodecs/rans4x16.d.ts +2 -0
  89. package/esm/htscodecs/rans4x16.js +896 -0
  90. package/esm/htscodecs/rans4x16.js.map +1 -0
  91. package/esm/htscodecs/tok3.d.ts +2 -0
  92. package/esm/htscodecs/tok3.js +347 -0
  93. package/esm/htscodecs/tok3.js.map +1 -0
  94. package/package.json +1 -2
  95. package/src/cramFile/file.ts +8 -10
  96. package/src/cramFile/util.ts +0 -1
  97. package/src/htscodecs/Makefile +142 -0
  98. package/src/htscodecs/README.md +64 -0
  99. package/src/htscodecs/arith_gen.js +607 -0
  100. package/src/htscodecs/arith_sh.js +138 -0
  101. package/src/htscodecs/byte_model.js +126 -0
  102. package/src/htscodecs/fqzcomp.js +834 -0
  103. package/src/htscodecs/index.js +79 -0
  104. package/src/htscodecs/iostream.js +256 -0
  105. package/src/htscodecs/main_arith_gen.js +96 -0
  106. package/src/htscodecs/main_fqzcomp.js +113 -0
  107. package/src/htscodecs/main_rans.js +88 -0
  108. package/src/htscodecs/main_rans4x16.js +87 -0
  109. package/src/htscodecs/main_tok3.js +86 -0
  110. package/src/htscodecs/rans.js +545 -0
  111. package/src/htscodecs/rans4x16.js +1003 -0
  112. package/src/htscodecs/tok3.js +396 -0
  113. 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