piclaw 0.0.19 → 0.0.21
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/.output/nitro.json +1 -1
- package/.output/public/assets/defult-D5RLDUrI.js +1 -0
- package/.output/public/assets/{dist-CMBqBOCp.js → dist-BH_oa-kv.js} +1 -1
- package/.output/public/assets/index-7JvURuHy.js +204 -0
- package/.output/public/assets/index-K43slwjJ.css +1 -0
- package/.output/public/index.html +11 -2
- package/.output/server/_...path_.get.mjs +16 -0
- package/.output/server/_chunks/app.mjs +261 -181
- package/.output/server/_chunks/browser.mjs +4 -1
- package/.output/server/_chunks/config.mjs +4 -0
- package/.output/server/_chunks/db.mjs +32 -28
- package/.output/server/_chunks/device-bus.mjs +123 -0
- package/.output/server/_chunks/dummy.mjs +1 -1
- package/.output/server/_chunks/logger.mjs +23 -0
- package/.output/server/_chunks/login.mjs +1 -1
- package/.output/server/_chunks/notes.mjs +1 -3
- package/.output/server/_chunks/renderer-template.mjs +1 -1
- package/.output/server/_chunks/sandbox.mjs +217 -0
- package/.output/server/_chunks/server.mjs +2302 -122
- package/.output/server/_chunks/terminal.mjs +63 -8
- package/.output/server/_chunks/uploads.mjs +60 -0
- package/.output/server/_chunks/virtual.mjs +192 -54
- package/.output/server/_id_.delete.mjs +5 -2
- package/.output/server/_id_.patch.mjs +2 -0
- package/.output/server/_id_2.delete.mjs +8 -0
- package/.output/server/_jid_.delete.mjs +5 -2
- package/.output/server/_jid_.patch.mjs +37 -4
- package/.output/server/_jid_2.delete.mjs +5 -2
- package/.output/server/_libs/@acemir/cssom+[...].mjs +2269 -1137
- package/.output/server/_libs/@google/genai.mjs +337 -273
- package/.output/server/_libs/@mariozechner/pi-agent-core+[...].mjs +381 -2073
- package/.output/server/_libs/@mariozechner/pi-coding-agent+[...].mjs +231 -131
- package/.output/server/_libs/_.mjs +3 -2
- package/.output/server/_libs/_10.mjs +2 -4
- package/.output/server/_libs/_11.mjs +2 -4
- package/.output/server/_libs/_12.mjs +2 -3
- package/.output/server/_libs/_13.mjs +2 -3
- package/.output/server/_libs/_14.mjs +2 -4
- package/.output/server/_libs/_15.mjs +2 -4
- package/.output/server/_libs/_16.mjs +2 -3
- package/.output/server/_libs/_17.mjs +2 -4
- package/.output/server/_libs/_18.mjs +2 -2
- package/.output/server/_libs/_19.mjs +2 -2
- package/.output/server/_libs/_2.mjs +3 -3
- package/.output/server/_libs/_20.mjs +2 -2
- package/.output/server/_libs/_21.mjs +2 -2
- package/.output/server/_libs/_22.mjs +2 -2
- package/.output/server/_libs/_23.mjs +2 -2
- package/.output/server/_libs/_24.mjs +2 -2
- package/.output/server/_libs/_25.mjs +2 -2
- package/.output/server/_libs/_26.mjs +2 -2
- package/.output/server/_libs/_27.mjs +2 -2
- package/.output/server/_libs/_28.mjs +2 -2
- package/.output/server/_libs/_29.mjs +2 -2
- package/.output/server/_libs/_3.mjs +3 -3
- package/.output/server/_libs/_30.mjs +2 -2
- package/.output/server/_libs/_31.mjs +2 -2
- package/.output/server/_libs/_32.mjs +2 -2
- package/.output/server/_libs/_33.mjs +2 -2
- package/.output/server/_libs/_34.mjs +2 -2
- package/.output/server/_libs/_35.mjs +2 -2
- package/.output/server/_libs/_36.mjs +2 -2
- package/.output/server/_libs/_37.mjs +2 -2
- package/.output/server/_libs/_38.mjs +2 -2
- package/.output/server/_libs/_39.mjs +2 -2
- package/.output/server/_libs/_4.mjs +4 -3
- package/.output/server/_libs/_40.mjs +2 -2
- package/.output/server/_libs/_41.mjs +2 -2
- package/.output/server/_libs/_42.mjs +2 -2
- package/.output/server/_libs/_43.mjs +2 -2
- package/.output/server/_libs/_44.mjs +2 -2
- package/.output/server/_libs/_45.mjs +2 -2
- package/.output/server/_libs/_46.mjs +2 -2
- package/.output/server/_libs/_47.mjs +2 -2
- package/.output/server/_libs/_48.mjs +2 -2
- package/.output/server/_libs/_49.mjs +2 -2
- package/.output/server/_libs/_5.mjs +2 -3
- package/.output/server/_libs/_50.mjs +2 -2
- package/.output/server/_libs/_51.mjs +2 -2
- package/.output/server/_libs/_52.mjs +2 -2
- package/.output/server/_libs/_53.mjs +2 -2
- package/.output/server/_libs/_54.mjs +2 -2
- package/.output/server/_libs/_55.mjs +2 -2
- package/.output/server/_libs/_56.mjs +2 -2
- package/.output/server/_libs/_57.mjs +2 -2
- package/.output/server/_libs/_58.mjs +2 -2
- package/.output/server/_libs/_59.mjs +2 -2
- package/.output/server/_libs/_6.mjs +2 -3
- package/.output/server/_libs/_60.mjs +2 -2
- package/.output/server/_libs/_61.mjs +2 -2
- package/.output/server/_libs/_62.mjs +2 -2
- package/.output/server/_libs/_63.mjs +2 -2
- package/.output/server/_libs/_64.mjs +2 -2
- package/.output/server/_libs/_65.mjs +2 -2
- package/.output/server/_libs/_66.mjs +2 -2
- package/.output/server/_libs/_67.mjs +2 -2
- package/.output/server/_libs/_68.mjs +2 -2
- package/.output/server/_libs/_69.mjs +2 -2
- package/.output/server/_libs/_7.mjs +2 -5
- package/.output/server/_libs/_70.mjs +2 -2
- package/.output/server/_libs/_71.mjs +2 -2
- package/.output/server/_libs/_72.mjs +2 -2
- package/.output/server/_libs/_73.mjs +2 -2
- package/.output/server/_libs/_74.mjs +2 -2
- package/.output/server/_libs/_75.mjs +2 -2
- package/.output/server/_libs/_76.mjs +2 -2
- package/.output/server/_libs/_77.mjs +2 -2
- package/.output/server/_libs/_78.mjs +2 -2
- package/.output/server/_libs/_79.mjs +2 -2
- package/.output/server/_libs/_8.mjs +2 -3
- package/.output/server/_libs/_80.mjs +2 -2
- package/.output/server/_libs/_81.mjs +2 -2
- package/.output/server/_libs/_82.mjs +2 -2
- package/.output/server/_libs/_83.mjs +2 -2
- package/.output/server/_libs/_84.mjs +2 -2
- package/.output/server/_libs/_85.mjs +2 -2
- package/.output/server/_libs/_86.mjs +2 -2
- package/.output/server/_libs/_87.mjs +2 -2
- package/.output/server/_libs/_88.mjs +2 -2
- package/.output/server/_libs/_89.mjs +2 -2
- package/.output/server/_libs/_9.mjs +2 -4
- package/.output/server/_libs/_90.mjs +5 -2
- package/.output/server/_libs/_91.mjs +3 -2
- package/.output/server/_libs/_92.mjs +2 -2
- package/.output/server/_libs/_93.mjs +2 -2
- package/.output/server/_libs/_94.mjs +2 -2
- package/.output/server/_libs/agent-base.mjs +1 -1
- package/.output/server/_libs/cheerio+[...].mjs +1 -1
- package/.output/server/_libs/data-uri-to-buffer.mjs +2 -67
- package/.output/server/_libs/data-urls+[...].mjs +1 -1
- package/.output/server/_libs/diff.mjs +1 -1
- package/.output/server/_libs/exodus__bytes.mjs +99 -81
- package/.output/server/_libs/fetch-blob+node-domexception.mjs +1 -1
- package/.output/server/_libs/h3+rou3+srvx.mjs +34 -4
- package/.output/server/_libs/html-encoding-sniffer.mjs +1 -1
- package/.output/server/_libs/https-proxy-agent.mjs +2 -2
- package/.output/server/_libs/jsdom.mjs +1 -1
- package/.output/server/_libs/just-bash+[...].mjs +4676 -3916
- package/.output/server/_libs/mariozechner__jiti.mjs +1 -1
- package/.output/server/_libs/mariozechner__pi-ai.mjs +1472 -0
- package/.output/server/_libs/md4x.mjs +1 -1
- package/.output/server/_libs/mime.mjs +838 -1
- package/.output/server/_libs/node-fetch.mjs +4 -4
- package/.output/server/_libs/node-liblzma.mjs +1 -1
- package/.output/server/_libs/silvia-odwyer__photon-node.mjs +1 -1
- package/.output/server/_routes/api/auth/approve.mjs +2 -0
- package/.output/server/_routes/api/auth/revoke.mjs +2 -0
- package/.output/server/_routes/api/auth/status.mjs +25 -6
- package/.output/server/_routes/api/browser2.mjs +1 -1
- package/.output/server/_routes/api/config2.mjs +2 -0
- package/.output/server/_routes/api/device_events.mjs +36 -0
- package/.output/server/_routes/api/files/groups.mjs +1 -2
- package/.output/server/_routes/api/files/raw.mjs +1 -1
- package/.output/server/_routes/api/groups.mjs +5 -3
- package/.output/server/_routes/api/groups2.mjs +18 -6
- package/.output/server/_routes/api/health.mjs +1 -2
- package/.output/server/_routes/api/messages.mjs +7 -1
- package/.output/server/_routes/api/notes/delete.mjs +4 -1
- package/.output/server/_routes/api/notes/write.mjs +2 -0
- package/.output/server/_routes/api/ntfy/setup.mjs +8 -0
- package/.output/server/_routes/api/pi/apikey.mjs +3 -2
- package/.output/server/_routes/api/pi/apikey_providers.mjs +1 -2
- package/.output/server/_routes/api/pi/commands.mjs +13 -3
- package/.output/server/_routes/api/pi/login/events.mjs +0 -1
- package/.output/server/_routes/api/pi/login/respond.mjs +2 -1
- package/.output/server/_routes/api/pi/login.mjs +1 -2
- package/.output/server/_routes/api/pi/logout.mjs +2 -1
- package/.output/server/_routes/api/pi/models.mjs +1 -2
- package/.output/server/_routes/api/pi/models_config2.mjs +2 -0
- package/.output/server/_routes/api/pi/settings2.mjs +2 -0
- package/.output/server/_routes/api/pi/status.mjs +1 -2
- package/.output/server/_routes/api/proxy.mjs +19 -1
- package/.output/server/_routes/api/sandbox.mjs +26 -0
- package/.output/server/_routes/api/sandbox2.mjs +17 -0
- package/.output/server/_routes/api/send.mjs +26 -18
- package/.output/server/_routes/api/status.mjs +1 -3
- package/.output/server/_routes/api/stop.mjs +11 -0
- package/.output/server/_routes/api/store/plugins.mjs +75 -0
- package/.output/server/_routes/api/store/skills.mjs +11 -0
- package/.output/server/_routes/api/tasks2.mjs +3 -2
- package/.output/server/_routes/api/telegram/setup.mjs +5 -2
- package/.output/server/_routes/api/telegram/status.mjs +1 -2
- package/.output/server/_routes/api/terminal2.mjs +2 -1
- package/.output/server/_routes/api/tunnel/setup.mjs +4 -2
- package/.output/server/_runtime.mjs +1 -2
- package/.output/server/_utils.mjs +10 -2
- package/.output/server/index.mjs +1 -1
- package/.output/server/node_modules/amdefine/amdefine.js +301 -0
- package/.output/server/node_modules/amdefine/package.json +16 -0
- package/.output/server/node_modules/compressjs/lib/BWT.js +420 -0
- package/.output/server/node_modules/compressjs/lib/BWTC.js +234 -0
- package/.output/server/node_modules/compressjs/lib/BitStream.js +108 -0
- package/.output/server/node_modules/compressjs/lib/Bzip2.js +936 -0
- package/.output/server/node_modules/compressjs/lib/CRC32.js +105 -0
- package/.output/server/node_modules/compressjs/lib/Context1Model.js +56 -0
- package/.output/server/node_modules/compressjs/lib/DefSumModel.js +152 -0
- package/.output/server/node_modules/compressjs/lib/DeflateDistanceModel.js +55 -0
- package/.output/server/node_modules/compressjs/lib/Dmc.js +197 -0
- package/.output/server/node_modules/compressjs/lib/DummyRangeCoder.js +81 -0
- package/.output/server/node_modules/compressjs/lib/FenwickModel.js +194 -0
- package/.output/server/node_modules/compressjs/lib/Huffman.js +514 -0
- package/.output/server/node_modules/compressjs/lib/HuffmanAllocator.js +227 -0
- package/.output/server/node_modules/compressjs/lib/LogDistanceModel.js +46 -0
- package/.output/server/node_modules/compressjs/lib/Lzjb.js +300 -0
- package/.output/server/node_modules/compressjs/lib/LzjbR.js +241 -0
- package/.output/server/node_modules/compressjs/lib/Lzp3.js +273 -0
- package/.output/server/node_modules/compressjs/lib/MTFModel.js +208 -0
- package/.output/server/node_modules/compressjs/lib/NoModel.js +46 -0
- package/.output/server/node_modules/compressjs/lib/PPM.js +343 -0
- package/.output/server/node_modules/compressjs/lib/RangeCoder.js +238 -0
- package/.output/server/node_modules/compressjs/lib/Simple.js +111 -0
- package/.output/server/node_modules/compressjs/lib/Stream.js +53 -0
- package/.output/server/node_modules/compressjs/lib/Util.js +324 -0
- package/.output/server/node_modules/compressjs/lib/freeze.js +14 -0
- package/.output/server/node_modules/compressjs/main.js +29 -0
- package/.output/server/node_modules/compressjs/package.json +35 -0
- package/.output/server/package.json +2 -1
- package/README.md +10 -1
- package/lib/index.d.mts +1 -0
- package/lib/index.mjs +1 -0
- package/lib/piclaw.mjs +100 -0
- package/lib/utils.mjs +96 -0
- package/package.json +16 -11
- package/.output/public/assets/defult-CMO6TZ5a.js +0 -1
- package/.output/public/assets/index-jdnbJw-M.js +0 -204
- package/.output/public/assets/index-ooXrRwgl.css +0 -1
- package/.output/server/_chunks/commands.mjs +0 -282
- package/.output/server/_chunks/pi.mjs +0 -202
- package/.output/server/_chunks/session.mjs +0 -1114
- package/.output/server/_libs/@aws-crypto/crc32+[...].mjs +0 -299
- package/.output/server/_libs/@aws-sdk/client-bedrock-runtime+[...].mjs +0 -17828
- package/.output/server/_libs/@aws-sdk/credential-provider-http+[...].mjs +0 -122
- package/.output/server/_libs/@aws-sdk/credential-provider-ini+[...].mjs +0 -417
- package/.output/server/_libs/@aws-sdk/credential-provider-process+[...].mjs +0 -54
- package/.output/server/_libs/@aws-sdk/credential-provider-sso+[...].mjs +0 -1151
- package/.output/server/_libs/@aws-sdk/credential-provider-web-identity+[...].mjs +0 -50
- package/.output/server/_libs/@smithy/credential-provider-imds+[...].mjs +0 -369
- package/.output/server/_libs/@tootallnate/quickjs-emscripten+[...].mjs +0 -3011
- package/.output/server/_libs/_100.mjs +0 -2
- package/.output/server/_libs/_101.mjs +0 -2
- package/.output/server/_libs/_102.mjs +0 -5
- package/.output/server/_libs/_103.mjs +0 -3
- package/.output/server/_libs/_104.mjs +0 -2
- package/.output/server/_libs/_105.mjs +0 -3
- package/.output/server/_libs/_106.mjs +0 -2
- package/.output/server/_libs/_107.mjs +0 -2
- package/.output/server/_libs/_95.mjs +0 -2
- package/.output/server/_libs/_96.mjs +0 -2
- package/.output/server/_libs/_97.mjs +0 -2
- package/.output/server/_libs/_98.mjs +0 -2
- package/.output/server/_libs/_99.mjs +0 -2
- package/.output/server/_libs/amdefine.mjs +0 -188
- package/.output/server/_libs/ast-types.mjs +0 -2270
- package/.output/server/_libs/aws-sdk__nested-clients.mjs +0 -3141
- package/.output/server/_libs/basic-ftp.mjs +0 -1906
- package/.output/server/_libs/compressjs.mjs +0 -50
- package/.output/server/_libs/degenerator+[...].mjs +0 -9964
- package/.output/server/_libs/get-uri.mjs +0 -413
- package/.output/server/_libs/http-proxy-agent.mjs +0 -123
- package/.output/server/_libs/ip-address.mjs +0 -1423
- package/.output/server/_libs/lru-cache.mjs +0 -732
- package/.output/server/_libs/netmask.mjs +0 -139
- package/.output/server/_libs/pac-proxy-agent+[...].mjs +0 -3104
- package/.output/server/_libs/proxy-agent+proxy-from-env.mjs +0 -204
- package/.output/server/_libs/smithy__core.mjs +0 -192
- package/.output/server/node_modules/tslib/modules/index.js +0 -70
- package/.output/server/node_modules/tslib/modules/package.json +0 -3
- package/.output/server/node_modules/tslib/package.json +0 -47
- package/.output/server/node_modules/tslib/tslib.js +0 -484
- package/bin/piclaw.mjs +0 -195
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
/** Simple range coding model w/ escape, suitable for sparse symbol sets.
|
|
2
|
+
* Uses a move-to-front list, which is simple and relatively performant,
|
|
3
|
+
* but slows down a lot if you want to try to model escapes more precisely
|
|
4
|
+
* (which is why this feature is disabled by default).
|
|
5
|
+
*/
|
|
6
|
+
if (typeof define !== 'function') { var define = require('amdefine')(module); }
|
|
7
|
+
define(['./RangeCoder','./Stream','./Util'],function(RangeCoder,Stream,Util){
|
|
8
|
+
|
|
9
|
+
var DEFAULT_MAX_PROB = 0xFF00;
|
|
10
|
+
var DEFAULT_INCREMENT= 0x0100;
|
|
11
|
+
|
|
12
|
+
var NUMERIC_SORT = function(a, b) { return a - b; };
|
|
13
|
+
|
|
14
|
+
var MTFModel = function(coder, size, max_prob, increment, betterEscape) {
|
|
15
|
+
this.coder = coder;
|
|
16
|
+
this.increment = (+increment) || DEFAULT_INCREMENT;
|
|
17
|
+
this.max_prob = (+max_prob) || DEFAULT_MAX_PROB;
|
|
18
|
+
console.assert((this.max_prob + (this.increment-1)) <= 0xFFFF);
|
|
19
|
+
this.sym = Util.makeU16Buffer(size+1);
|
|
20
|
+
this.prob= Util.makeU16Buffer(size+2);
|
|
21
|
+
this.sym[0] = size; // escape code
|
|
22
|
+
this.prob[0]= 0;
|
|
23
|
+
this.seenSyms = 1;
|
|
24
|
+
// total probability always found in this.prob[this.seenSyms]
|
|
25
|
+
this.prob[this.seenSyms] = this.increment;
|
|
26
|
+
this.numSyms = size;
|
|
27
|
+
if (betterEscape) {
|
|
28
|
+
this.sortedSeen = [size];
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
MTFModel.factory = function(coder, max_prob, increment, betterEscape) {
|
|
32
|
+
return function(size) {
|
|
33
|
+
return new MTFModel(coder, size, max_prob, increment, betterEscape);
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
MTFModel.prototype.clone = function() {
|
|
37
|
+
var newModel = new MTFModel(this.coder, this.numSyms, this.max_prob,
|
|
38
|
+
this.increment, !!this.sortedSeen);
|
|
39
|
+
var i;
|
|
40
|
+
for (i=0; i<this.seenSyms; i++) {
|
|
41
|
+
newModel.sym[i] = this.sym[i];
|
|
42
|
+
newModel.prob[i] = this.prob[i];
|
|
43
|
+
}
|
|
44
|
+
newModel.prob[i] = this.prob[i]; // total probability
|
|
45
|
+
newModel.seenSyms = this.seenSyms;
|
|
46
|
+
if (this.sortedSeen) {
|
|
47
|
+
newModel.sortedSeen = this.sortedSeen.slice(0);
|
|
48
|
+
}
|
|
49
|
+
return newModel;
|
|
50
|
+
};
|
|
51
|
+
MTFModel.prototype._update = function(symbol, index, sy_f) {
|
|
52
|
+
var j, tot_f;
|
|
53
|
+
// move this symbol to the end
|
|
54
|
+
for (j=index; j<this.seenSyms-1; j++) {
|
|
55
|
+
this.sym[j] = this.sym[j+1];
|
|
56
|
+
this.prob[j] = this.prob[j+1] - sy_f;
|
|
57
|
+
}
|
|
58
|
+
if (index < this.seenSyms) {
|
|
59
|
+
this.sym[j] = symbol;
|
|
60
|
+
this.prob[j] = this.prob[j+1] - sy_f;
|
|
61
|
+
// increase frequency for this symbol, and total freq at same time
|
|
62
|
+
this.prob[this.seenSyms] = tot_f =
|
|
63
|
+
this.prob[this.seenSyms] + this.increment;
|
|
64
|
+
if (symbol === this.numSyms && this.seenSyms >= this.numSyms) {
|
|
65
|
+
// this is the last time we'll see an escape! remove it.
|
|
66
|
+
tot_f = this.prob[--this.seenSyms];
|
|
67
|
+
if (this.sortedSeen) { this.sortedSeen.length--; }
|
|
68
|
+
}
|
|
69
|
+
} else { // add to the end
|
|
70
|
+
tot_f = this.prob[this.seenSyms];
|
|
71
|
+
this.sym[index] = symbol;
|
|
72
|
+
this.prob[index] = tot_f;
|
|
73
|
+
tot_f += this.increment;
|
|
74
|
+
this.prob[++this.seenSyms] = tot_f;
|
|
75
|
+
if (this.sortedSeen) {
|
|
76
|
+
this.sortedSeen.push(symbol);
|
|
77
|
+
// hopefully sort is very fast on a mostly-sorted array
|
|
78
|
+
this.sortedSeen.sort(NUMERIC_SORT);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
if (tot_f >= this.max_prob) { this._rescale(); }
|
|
82
|
+
return;
|
|
83
|
+
};
|
|
84
|
+
MTFModel.prototype._rescale = function() {
|
|
85
|
+
var i, j, total=0;
|
|
86
|
+
var noEscape = true;
|
|
87
|
+
if (this.sortedSeen) { this.sortedSeen.length = 0; }
|
|
88
|
+
for(i=0, j=0; i<this.seenSyms; i++) {
|
|
89
|
+
var sym = this.sym[i];
|
|
90
|
+
var sy_f = this.prob[i+1] - this.prob[i];
|
|
91
|
+
sy_f >>>= 1;
|
|
92
|
+
if (sy_f > 0) {
|
|
93
|
+
if (sym === this.numSyms) {
|
|
94
|
+
noEscape = false;
|
|
95
|
+
}
|
|
96
|
+
this.sym[j] = sym;
|
|
97
|
+
this.prob[j++] = total;
|
|
98
|
+
total += sy_f;
|
|
99
|
+
if (this.sortedSeen) { this.sortedSeen.push(sym); }
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
this.prob[j] = total;
|
|
103
|
+
this.seenSyms = j;
|
|
104
|
+
if (this.sortedSeen) {
|
|
105
|
+
this.sortedSeen.sort(NUMERIC_SORT);
|
|
106
|
+
}
|
|
107
|
+
// don't allow escape to go to zero prob if we still need it
|
|
108
|
+
if (noEscape && this.seenSyms < this.numSyms) {
|
|
109
|
+
// NOTE this adds this.increment to escape freq; the FenwickModel
|
|
110
|
+
// just adds one.
|
|
111
|
+
this._update(this.numSyms/*escape*/, this.seenSyms/*at end*/);
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
MTFModel.prototype.decode = function() {
|
|
115
|
+
var tot_f = this.prob[this.seenSyms];
|
|
116
|
+
var prob = this.coder.decodeCulFreq(tot_f);
|
|
117
|
+
// we're expecting to find the probability near the "most recent" side
|
|
118
|
+
// of our array
|
|
119
|
+
var i;
|
|
120
|
+
for (i=this.seenSyms-1; i>=0; i--) {
|
|
121
|
+
if (this.prob[i] <= prob /*&& prob < this.prob[i+1]*/)
|
|
122
|
+
break;
|
|
123
|
+
}
|
|
124
|
+
console.assert(i>=0);
|
|
125
|
+
var symbol = this.sym[i];
|
|
126
|
+
var lt_f = this.prob[i];
|
|
127
|
+
var sy_f = this.prob[i + 1] - lt_f;
|
|
128
|
+
this.coder.decodeUpdate(sy_f, lt_f, tot_f);
|
|
129
|
+
this._update(symbol, i, sy_f);
|
|
130
|
+
if (symbol === this.numSyms) {
|
|
131
|
+
/* this is an escape */
|
|
132
|
+
/* decode the literal */
|
|
133
|
+
sy_f = 1;
|
|
134
|
+
tot_f = this.numSyms;
|
|
135
|
+
if (this.sortedSeen) {
|
|
136
|
+
// do a slower, but more precise decoding of the literal
|
|
137
|
+
// by excluding the already-seen symbols.
|
|
138
|
+
var seen = this.sortedSeen;
|
|
139
|
+
tot_f = this.numSyms - this.seenSyms;
|
|
140
|
+
if (seen[seen.length-1] === this.numSyms) { tot_f++; }
|
|
141
|
+
symbol = lt_f = this.coder.decodeCulFreq(tot_f);
|
|
142
|
+
for (i=0; i < seen.length && seen[i] <= symbol ; i++) {
|
|
143
|
+
symbol++;
|
|
144
|
+
}
|
|
145
|
+
} else {
|
|
146
|
+
symbol = lt_f = this.coder.decodeCulFreq(tot_f);
|
|
147
|
+
}
|
|
148
|
+
this.coder.decodeUpdate(sy_f, lt_f, tot_f);
|
|
149
|
+
this._update(symbol, this.seenSyms);
|
|
150
|
+
}
|
|
151
|
+
return symbol;
|
|
152
|
+
};
|
|
153
|
+
MTFModel.prototype.encode = function(symbol) {
|
|
154
|
+
// look for symbol, from most-recent to oldest
|
|
155
|
+
var i, sy_f, lt_f, tot_f;
|
|
156
|
+
for (i=this.seenSyms-1; i>=0; i--) {
|
|
157
|
+
if (symbol === this.sym[i]) {
|
|
158
|
+
// ok, found it.
|
|
159
|
+
lt_f = this.prob[i];
|
|
160
|
+
sy_f = this.prob[i + 1] - lt_f;
|
|
161
|
+
tot_f = this.prob[this.seenSyms];
|
|
162
|
+
this.coder.encodeFreq(sy_f, lt_f, tot_f);
|
|
163
|
+
return this._update(symbol, i, sy_f);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
// couldn't find this symbol. encode as escape.
|
|
167
|
+
console.assert(symbol !== this.numSyms); // catch infinite recursion
|
|
168
|
+
this.encode(this.numSyms); // guaranteed to be found in the table.
|
|
169
|
+
// code symbol as literal
|
|
170
|
+
sy_f = 1;
|
|
171
|
+
lt_f = symbol;
|
|
172
|
+
tot_f = this.numSyms;
|
|
173
|
+
if (this.sortedSeen) {
|
|
174
|
+
// do a slower, but more precise encoding of the literal
|
|
175
|
+
// by excluding the already-seen symbols.
|
|
176
|
+
var seen = this.sortedSeen;
|
|
177
|
+
tot_f -= this.seenSyms;
|
|
178
|
+
if (seen[seen.length-1] === this.numSyms) { tot_f++; }
|
|
179
|
+
for (i=0; i < seen.length && seen[i] < symbol; i++) {
|
|
180
|
+
lt_f--;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
this.coder.encodeFreq(sy_f, lt_f, tot_f);
|
|
184
|
+
// now add symbol to the end.
|
|
185
|
+
return this._update(symbol, this.seenSyms);
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
MTFModel.MAGIC = 'mtfm';
|
|
189
|
+
/** Simple order-0 compressor, as self-test. */
|
|
190
|
+
MTFModel.compressFile = Util.compressFileHelper(MTFModel.MAGIC, function(inStream, outStream, fileSize, props, finalByte) {
|
|
191
|
+
var range = new RangeCoder(outStream);
|
|
192
|
+
range.encodeStart(finalByte, 1);
|
|
193
|
+
var model = new MTFModel(range, (fileSize<0) ? 257 : 256);
|
|
194
|
+
Util.compressWithModel(inStream, fileSize, model);
|
|
195
|
+
range.encodeFinish();
|
|
196
|
+
}, true);
|
|
197
|
+
|
|
198
|
+
/** Simple order-0 decompresser, as self-test. */
|
|
199
|
+
MTFModel.decompressFile = Util.decompressFileHelper(MTFModel.MAGIC, function(inStream, outStream, fileSize) {
|
|
200
|
+
var range = new RangeCoder(inStream);
|
|
201
|
+
range.decodeStart(true/*we already read the 'free' byte*/);
|
|
202
|
+
var model = new MTFModel(range, (fileSize<0) ? 257 : 256);
|
|
203
|
+
Util.decompressWithModel(outStream, fileSize, model);
|
|
204
|
+
range.decodeFinish();
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
return MTFModel;
|
|
208
|
+
});
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/** Simple "lack of model" -- just encode the bits directly.
|
|
2
|
+
* Useful especially with sparse spaces or Huffman coders where there's
|
|
3
|
+
* no obvious prediction to be made that will pay for itself.
|
|
4
|
+
*/
|
|
5
|
+
if (typeof define !== 'function') { var define = require('amdefine')(module); }
|
|
6
|
+
define(['./BitStream','./Util'],function(BitStream,Util) {
|
|
7
|
+
|
|
8
|
+
var NoModel = function(bitstream, size) {
|
|
9
|
+
this.bitstream = bitstream;
|
|
10
|
+
this.bits = Util.fls(size-1);
|
|
11
|
+
};
|
|
12
|
+
NoModel.factory = function(bitstream) {
|
|
13
|
+
return function(size) { return new NoModel(bitstream, size); };
|
|
14
|
+
};
|
|
15
|
+
NoModel.prototype.encode = function(symbol) {
|
|
16
|
+
var i;
|
|
17
|
+
for (i=this.bits-1; i>=0; i--) {
|
|
18
|
+
var b = (symbol >>> i) & 1;
|
|
19
|
+
this.bitstream.writeBit(b);
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
NoModel.prototype.decode = function() {
|
|
23
|
+
var i, r = 0;
|
|
24
|
+
for (i=this.bits-1; i>=0; i--) {
|
|
25
|
+
r <<= 1;
|
|
26
|
+
if (this.bitstream.readBit()) r++;
|
|
27
|
+
}
|
|
28
|
+
return r;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
/** Brain-dead self-test. */
|
|
32
|
+
NoModel.MAGIC = 'nomo';
|
|
33
|
+
NoModel.compressFile = Util.compressFileHelper(NoModel.MAGIC, function(inStream, outStream, fileSize, props) {
|
|
34
|
+
var bitstream = new BitStream(outStream);
|
|
35
|
+
var model = new NoModel(bitstream, (fileSize<0) ? 257 : 256);
|
|
36
|
+
Util.compressWithModel(inStream, fileSize, model);
|
|
37
|
+
bitstream.flush();
|
|
38
|
+
});
|
|
39
|
+
NoModel.decompressFile = Util.decompressFileHelper(NoModel.MAGIC, function(inStream, outStream, fileSize) {
|
|
40
|
+
var bitstream = new BitStream(inStream);
|
|
41
|
+
var model = new NoModel(bitstream, (fileSize<0) ? 257 : 256);
|
|
42
|
+
Util.decompressWithModel(outStream, fileSize, model);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
return NoModel;
|
|
46
|
+
});
|
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
/** Particularly simple-minded implementation of PPM compression. */
|
|
2
|
+
if (typeof define !== 'function') { var define = require('amdefine')(module); }
|
|
3
|
+
define(['./RangeCoder','./Util'], function(RangeCoder,Util) {
|
|
4
|
+
|
|
5
|
+
var MAX_CONTEXT = 5;
|
|
6
|
+
var LOG_WINDOW_SIZE = 18;
|
|
7
|
+
var WINDOW_SIZE = 1 << LOG_WINDOW_SIZE;
|
|
8
|
+
|
|
9
|
+
var Window = function() {
|
|
10
|
+
this.buffer = Util.makeU8Buffer(WINDOW_SIZE);
|
|
11
|
+
this.pos = 0;
|
|
12
|
+
this.firstPass = true;
|
|
13
|
+
for (var i=0; i<MAX_CONTEXT; i++) {
|
|
14
|
+
this.put('cSaCsA'.charCodeAt(i%6));
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
Window.prototype.put = function(_byte) {
|
|
18
|
+
this.buffer[this.pos++] = _byte;
|
|
19
|
+
if (this.pos >= WINDOW_SIZE) { this.pos = 0; this.firstPass = false; }
|
|
20
|
+
return _byte;
|
|
21
|
+
};
|
|
22
|
+
Window.prototype.get = function(pos) {
|
|
23
|
+
return this.buffer[pos & (WINDOW_SIZE-1)];
|
|
24
|
+
};
|
|
25
|
+
// the context ending just before 'pos'
|
|
26
|
+
Window.prototype.context = function(pos, n) {
|
|
27
|
+
var c = [], i;
|
|
28
|
+
pos = (pos - n) & (WINDOW_SIZE-1);
|
|
29
|
+
for (i=0; i<n; i++) {
|
|
30
|
+
c.push(this.buffer[pos++]);
|
|
31
|
+
if (pos >= WINDOW_SIZE) { pos = 0; }
|
|
32
|
+
}
|
|
33
|
+
return String.fromCharCode.apply(String, c);
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
var DMM_INCREMENT = 0x100, DMM_MAX_PROB = 0xFF00;
|
|
37
|
+
|
|
38
|
+
var PPM = function(coder, size) {
|
|
39
|
+
this.window = new Window();
|
|
40
|
+
this.contexts = Object.create(null);
|
|
41
|
+
// brain-dead '-1' context, using full exclusion
|
|
42
|
+
var Cm1Context = function() { };
|
|
43
|
+
Cm1Context.prototype.encode = function(symbol, exclude) {
|
|
44
|
+
var i, lt_f = 0;
|
|
45
|
+
for (i=0; i<symbol; i++) {
|
|
46
|
+
if (!exclude[i]) {
|
|
47
|
+
lt_f++;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
var tot_f = size - exclude.total;
|
|
51
|
+
coder.encodeFreq(1, lt_f, tot_f);
|
|
52
|
+
};
|
|
53
|
+
Cm1Context.prototype.decode = function(exclude) {
|
|
54
|
+
var i, symbol, lt_f;
|
|
55
|
+
var tot_f = size - exclude.total;
|
|
56
|
+
symbol = lt_f = coder.decodeCulFreq(tot_f);
|
|
57
|
+
for (i=0; i<=symbol; i++) {
|
|
58
|
+
if (exclude[i]) {
|
|
59
|
+
symbol++;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
coder.decodeUpdate(1, lt_f, tot_f);
|
|
63
|
+
return symbol;
|
|
64
|
+
};
|
|
65
|
+
this.cm1coder = new Cm1Context();
|
|
66
|
+
|
|
67
|
+
var DenseMTFModel = function() {
|
|
68
|
+
this.sym = [size];
|
|
69
|
+
this.prob= [0, DMM_INCREMENT];
|
|
70
|
+
this.refcount = 0;
|
|
71
|
+
};
|
|
72
|
+
DenseMTFModel.prototype._rescale = function() {
|
|
73
|
+
var seenSyms = this.sym.length;
|
|
74
|
+
var i, j, total=0;
|
|
75
|
+
var noEscape = true;
|
|
76
|
+
for(i=0, j=0; i<seenSyms; i++) {
|
|
77
|
+
var sym = this.sym[i];
|
|
78
|
+
var sy_f = this.prob[i+1] - this.prob[i];
|
|
79
|
+
sy_f >>>= 1;
|
|
80
|
+
if (sy_f > 0) {
|
|
81
|
+
if (sym === size) {
|
|
82
|
+
noEscape = false;
|
|
83
|
+
}
|
|
84
|
+
this.sym[j] = sym;
|
|
85
|
+
this.prob[j++] = total;
|
|
86
|
+
total += sy_f;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
this.prob[j] = total;
|
|
90
|
+
seenSyms = this.sym.length = j;
|
|
91
|
+
this.prob.length = seenSyms + 1;
|
|
92
|
+
// don't allow escape to go to zero prob if we still need it
|
|
93
|
+
if (noEscape && seenSyms < size) {
|
|
94
|
+
total = this._update(size/*escape*/, seenSyms/*at end*/, 0, 1);
|
|
95
|
+
}
|
|
96
|
+
return total;
|
|
97
|
+
};
|
|
98
|
+
DenseMTFModel.prototype.update = function(symbol, incr) {
|
|
99
|
+
// find symbol
|
|
100
|
+
var i=0;
|
|
101
|
+
for (i=0; i<this.sym.length; i++) {
|
|
102
|
+
if (this.sym[i] === symbol) {
|
|
103
|
+
return this._update(symbol, i, this.prob[i+1] - this.prob[i], incr);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
// symbol escaped
|
|
107
|
+
return this._update(symbol, i, 0, incr);
|
|
108
|
+
};
|
|
109
|
+
DenseMTFModel.prototype._update = function(symbol, index, sy_f, incr) {
|
|
110
|
+
var seenSyms = this.sym.length;
|
|
111
|
+
var i, j, tot_f;
|
|
112
|
+
// move this symbol to the end
|
|
113
|
+
for (j=index; j<seenSyms-1; j++) {
|
|
114
|
+
this.sym[j] = this.sym[j+1];
|
|
115
|
+
this.prob[j] = this.prob[j+1] - sy_f;
|
|
116
|
+
}
|
|
117
|
+
// "method D" -- if we add a new escaped symbol, escape & the symbol
|
|
118
|
+
// both increase by 1/2.
|
|
119
|
+
if (index < seenSyms) {
|
|
120
|
+
this.sym[j] = symbol;
|
|
121
|
+
this.prob[j] = this.prob[j+1] - sy_f;
|
|
122
|
+
// increase frequency for this symbol, and total freq at same time
|
|
123
|
+
this.prob[seenSyms] = tot_f =
|
|
124
|
+
this.prob[seenSyms] + incr;
|
|
125
|
+
} else { // add to the end
|
|
126
|
+
tot_f = this.prob[seenSyms];
|
|
127
|
+
this.sym[index] = symbol;
|
|
128
|
+
this.prob[index] = tot_f;
|
|
129
|
+
tot_f += incr;
|
|
130
|
+
this.prob[++seenSyms] = tot_f;
|
|
131
|
+
// remove probability of escape if table just filled up
|
|
132
|
+
if (this.sym.length > size) {
|
|
133
|
+
for (i=0; i<seenSyms; i++) {
|
|
134
|
+
if (size === this.sym[i]) {
|
|
135
|
+
// found it.
|
|
136
|
+
this._update(size, i, this.prob[i+1] - this.prob[i], -1);
|
|
137
|
+
this.sym.length--;
|
|
138
|
+
this.prob.length--;
|
|
139
|
+
tot_f = this.prob[this.prob.length-1];
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
if (tot_f >= DMM_MAX_PROB) { tot_f = this._rescale(); }
|
|
145
|
+
return tot_f;
|
|
146
|
+
};
|
|
147
|
+
DenseMTFModel.prototype.encode = function(symbol, exclude) {
|
|
148
|
+
// look for symbol, from most-recent to oldest
|
|
149
|
+
var i, j, sy_f, lt_f, tot_f, seenSyms = this.sym.length;
|
|
150
|
+
var ex_seen = 0, ex_lt_f = 0, ex_tot_f = 0, ex_sy_f;
|
|
151
|
+
for (i=seenSyms-1; i>=0; i--) {
|
|
152
|
+
lt_f = this.prob[i];
|
|
153
|
+
sy_f = this.prob[i + 1] - lt_f;
|
|
154
|
+
if (symbol === this.sym[i]) {
|
|
155
|
+
// ok, found it.
|
|
156
|
+
// count up the rest of the probabilities
|
|
157
|
+
for (j=i-1; j>=0 && ex_seen < exclude.total; j--) {
|
|
158
|
+
if (exclude[this.sym[j]]) {
|
|
159
|
+
ex_seen += 1;
|
|
160
|
+
ex_sy_f = this.prob[j+1] - this.prob[j];
|
|
161
|
+
ex_lt_f += ex_sy_f;
|
|
162
|
+
ex_tot_f += ex_sy_f;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
tot_f = this.prob[seenSyms];
|
|
166
|
+
// adjust by excluded symbols
|
|
167
|
+
lt_f -= ex_lt_f;
|
|
168
|
+
tot_f -= ex_tot_f;
|
|
169
|
+
coder.encodeFreq(sy_f, lt_f, tot_f);
|
|
170
|
+
if (symbol === size) { // only update table for escapes
|
|
171
|
+
this._update(symbol, i, sy_f, DMM_INCREMENT/2);
|
|
172
|
+
return false; // escape.
|
|
173
|
+
} // otherwise we'll do update later
|
|
174
|
+
return true; // encoded character!
|
|
175
|
+
} else if (exclude[this.sym[i]]) {
|
|
176
|
+
ex_seen += 1;
|
|
177
|
+
ex_tot_f += sy_f;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
// couldn't find this symbol. encode as escape.
|
|
181
|
+
this.encode(size, exclude);
|
|
182
|
+
// add symbols to exclusion table
|
|
183
|
+
console.assert(this.sym[this.sym.length-1] === size);//escape
|
|
184
|
+
for (i=0; i<this.sym.length-1; i++) {
|
|
185
|
+
if (!exclude[this.sym[i]]) {
|
|
186
|
+
exclude[this.sym[i]] = true;
|
|
187
|
+
exclude.total++;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
};
|
|
191
|
+
DenseMTFModel.prototype.decode = function(exclude) {
|
|
192
|
+
var seenSyms = this.sym.length;
|
|
193
|
+
var tot_f = this.prob[seenSyms];
|
|
194
|
+
var ex_seen = 0, ex_lt_f = 0, ex_tot_f = 0, ex_sy_f;
|
|
195
|
+
var i;
|
|
196
|
+
for (i=seenSyms-1; i>=0 && ex_seen < exclude.total; i--) {
|
|
197
|
+
if (exclude[this.sym[i]]) {
|
|
198
|
+
ex_seen += 1;
|
|
199
|
+
ex_tot_f += this.prob[i+1] - this.prob[i];
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
var prob = coder.decodeCulFreq(tot_f - ex_tot_f) + ex_tot_f;
|
|
203
|
+
// we're expecting to find the probability near the "most recent" side
|
|
204
|
+
// of our array
|
|
205
|
+
ex_lt_f = ex_tot_f;
|
|
206
|
+
for (i=seenSyms-1; i>=0; i--) {
|
|
207
|
+
if (exclude[this.sym[i]]) {
|
|
208
|
+
ex_sy_f = this.prob[i+1] - this.prob[i];
|
|
209
|
+
ex_lt_f -= ex_sy_f;
|
|
210
|
+
prob -= ex_sy_f;
|
|
211
|
+
} else if (this.prob[i] <= prob /*&& prob < this.prob[i+1]*/)
|
|
212
|
+
break;
|
|
213
|
+
}
|
|
214
|
+
console.assert(i>=0);
|
|
215
|
+
var symbol = this.sym[i];
|
|
216
|
+
var lt_f = this.prob[i];
|
|
217
|
+
var sy_f = this.prob[i + 1] - lt_f;
|
|
218
|
+
coder.decodeUpdate(sy_f, lt_f - ex_lt_f, tot_f - ex_tot_f);
|
|
219
|
+
// defer update
|
|
220
|
+
if (symbol < size) { return symbol; }
|
|
221
|
+
// an escape
|
|
222
|
+
this._update(symbol, i, sy_f, DMM_INCREMENT/2);
|
|
223
|
+
// add symbols to exclusion table
|
|
224
|
+
console.assert(this.sym[this.sym.length-1] === size);//escape
|
|
225
|
+
for (i=0; i<this.sym.length-1; i++) {
|
|
226
|
+
if (!exclude[this.sym[i]]) {
|
|
227
|
+
exclude[this.sym[i]] = true;
|
|
228
|
+
exclude.total++;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
return -1;
|
|
232
|
+
};
|
|
233
|
+
this.newContext = function(initialSymbol) {
|
|
234
|
+
return new DenseMTFModel();
|
|
235
|
+
};
|
|
236
|
+
this.newExclude = function() {
|
|
237
|
+
var result = Object.create(null);
|
|
238
|
+
result.total = 0; // no excluded symbols (yet)
|
|
239
|
+
return result;
|
|
240
|
+
};
|
|
241
|
+
// set up some initial contexts
|
|
242
|
+
(function() {
|
|
243
|
+
var i, j;
|
|
244
|
+
for (i=0; i<MAX_CONTEXT; i++) {
|
|
245
|
+
for (j=0; j<=i; j++) {
|
|
246
|
+
var cc = this.window.context(j+((MAX_CONTEXT-1)-i), j);
|
|
247
|
+
if (!this.contexts[cc]) { this.contexts[cc] = this.newContext(); }
|
|
248
|
+
this.contexts[cc].refcount++;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}).call(this);
|
|
252
|
+
};
|
|
253
|
+
PPM.prototype.update = function(symbol, contextString, matchLevel) {
|
|
254
|
+
// slide up the contexts, updating them
|
|
255
|
+
var model, c, cc;
|
|
256
|
+
for (c=0; c <= MAX_CONTEXT; c++) {
|
|
257
|
+
cc = contextString.slice(MAX_CONTEXT - c);
|
|
258
|
+
model = this.contexts[cc];
|
|
259
|
+
if (!model) {
|
|
260
|
+
model = this.contexts[cc] = this.newContext();
|
|
261
|
+
}
|
|
262
|
+
if (c >= matchLevel) {
|
|
263
|
+
// only update useful contexts
|
|
264
|
+
model.update(symbol, DMM_INCREMENT / 2);
|
|
265
|
+
}
|
|
266
|
+
// refcount all contexts, whether used/updated or not
|
|
267
|
+
model.refcount++;
|
|
268
|
+
}
|
|
269
|
+
// now garbage-collect old contexts
|
|
270
|
+
contextString = this.window.context(this.window.pos + MAX_CONTEXT,
|
|
271
|
+
MAX_CONTEXT);
|
|
272
|
+
var firstPass = this.window.firstPass;
|
|
273
|
+
for (c=MAX_CONTEXT; c>=0 && !firstPass; c--) {
|
|
274
|
+
cc = contextString.slice(0, c);
|
|
275
|
+
model = this.contexts[cc];
|
|
276
|
+
console.assert(model);
|
|
277
|
+
if ((--model.refcount) <= 0) {
|
|
278
|
+
console.assert(cc !== ''); // don't allow context-0 to be gc'ed!
|
|
279
|
+
delete this.contexts[cc];
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
// ok, advance window.
|
|
283
|
+
this.window.put(symbol);
|
|
284
|
+
};
|
|
285
|
+
PPM.prototype.decode = function() {
|
|
286
|
+
var contextString = this.window.context(this.window.pos, MAX_CONTEXT);
|
|
287
|
+
var exclude = this.newExclude();
|
|
288
|
+
var model, c, cc, symbol;
|
|
289
|
+
for (c=MAX_CONTEXT; c>=0; c--) {
|
|
290
|
+
cc = contextString.slice(MAX_CONTEXT - c);
|
|
291
|
+
model = this.contexts[cc];
|
|
292
|
+
if (model) {
|
|
293
|
+
symbol = model.decode(exclude);
|
|
294
|
+
if (symbol >= 0) {
|
|
295
|
+
this.update(symbol, contextString, c);
|
|
296
|
+
return symbol;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
// still no match, fall back to context -1
|
|
301
|
+
symbol = this.cm1coder.decode(exclude);
|
|
302
|
+
this.update(symbol, contextString, c);
|
|
303
|
+
return symbol;
|
|
304
|
+
};
|
|
305
|
+
PPM.prototype.encode = function(symbol) {
|
|
306
|
+
var contextString = this.window.context(this.window.pos, MAX_CONTEXT);
|
|
307
|
+
var exclude = this.newExclude();
|
|
308
|
+
var c;
|
|
309
|
+
for (c=MAX_CONTEXT; c>=0; c--) {
|
|
310
|
+
var cc = contextString.slice(MAX_CONTEXT - c);
|
|
311
|
+
var model = this.contexts[cc];
|
|
312
|
+
if (model) {
|
|
313
|
+
var success = model.encode(symbol, exclude);
|
|
314
|
+
if (success) {
|
|
315
|
+
this.update(symbol, contextString, c);
|
|
316
|
+
return;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
// fall back to context -1 (but still use exclusion table)
|
|
321
|
+
this.cm1coder.encode(symbol, exclude);
|
|
322
|
+
this.update(symbol, contextString, c);
|
|
323
|
+
return;
|
|
324
|
+
};
|
|
325
|
+
|
|
326
|
+
PPM.MAGIC = 'ppm2';
|
|
327
|
+
PPM.compressFile = Util.compressFileHelper(PPM.MAGIC, function(inStream, outStream, fileSize, props, finalByte) {
|
|
328
|
+
var range = new RangeCoder(outStream);
|
|
329
|
+
range.encodeStart(finalByte, 1);
|
|
330
|
+
var model = new PPM(range, (fileSize<0) ? 257 : 256);
|
|
331
|
+
Util.compressWithModel(inStream, fileSize, model);
|
|
332
|
+
range.encodeFinish();
|
|
333
|
+
}, true);
|
|
334
|
+
PPM.decompressFile = Util.decompressFileHelper(PPM.MAGIC, function(inStream, outStream, fileSize) {
|
|
335
|
+
var range = new RangeCoder(inStream);
|
|
336
|
+
range.decodeStart(true/*we already read the 'free' byte*/);
|
|
337
|
+
var model = new PPM(range, (fileSize<0) ? 257 : 256);
|
|
338
|
+
Util.decompressWithModel(outStream, fileSize, model);
|
|
339
|
+
range.decodeFinish();
|
|
340
|
+
});
|
|
341
|
+
|
|
342
|
+
return PPM;
|
|
343
|
+
});
|