gotty/js/spice-web-client/application/WorkerProcess.js

3364 lines
99 KiB
JavaScript
Raw Permalink Normal View History

/*
eyeOS Spice Web Client
Copyright (c) 2015 eyeOS S.L.
Contact Jose Carlos Norte (jose@eyeos.com) for more information about this software.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Affero General Public License version 3 as published by the
Free Software Foundation.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
details.
You should have received a copy of the GNU Affero General Public License
version 3 along with this program in the file "LICENSE". If not, see
<http://www.gnu.org/licenses/agpl-3.0.txt>.
See www.eyeos.org for more details. All requests should be sent to licensing@eyeos.org
The interactive user interfaces in modified source and object code versions
of this program must display Appropriate Legal Notices, as required under
Section 5 of the GNU Affero General Public License version 3.
In accordance with Section 7(b) of the GNU Affero General Public License version 3,
these Appropriate Legal Notices must retain the display of the "Powered by
eyeos" logo and retain the original copyright notice. If the display of the
logo is not reasonably feasible for technical reasons, the Appropriate Legal Notices
must display the words "Powered by eyeos" and retain the original copyright notice.
*/
//Sandboxed script without access to other external functions, objects or anything.
//used for webworkers.
//includes: quic and lz_rgb
window = this;
if (!window['wdi']) {
window['wdi'] = {};
}
window['wdi'].WorkerOperations = {
quic: 0,
lz_rgb: 1,
bytesToUriJpeg: 2,
bytesToUriPng: 3
};
function dispatch(arr, useMessage) {
var u8 = new Uint8Array(arr);
var postMessageW3CCompilant = u8[3];
var result = null;
var operation = u8[0];
if (operation === wdi.WorkerOperations.quic) {
try {
result = wdi.JSQuic.quic_decode(arr);
} catch (e) {
}
} else if (operation === wdi.WorkerOperations.lz_rgb) { //lz?
try {
result = wdi.LZSS.lz_rgb32_decompress_rgb(arr);
} catch (e) {
}
} else if (operation === wdi.WorkerOperations.bytesToUriJpeg) {
try {
result = bytesToURI(u8, 'jpeg');
self.postMessage(result);
return; //string is not transferable!
} catch (e) {
}
} else if (operation === wdi.WorkerOperations.bytesToUriPng) {
try {
result = bytesToURI(u8, 'png');
self.postMessage(result);
return; //string is not transferable!
} catch (e) {
}
}
if (useMessage && result) {
if (postMessageW3CCompilant) {
self.postMessage(result, [result]);
} else {
self.postMessage(result);
}
} else {
return result;
}
}
window['workerDispatch'] = dispatch;
self.addEventListener('message', function(e) {
return dispatch(e.data, true);
}, false);
//bytes to uri
function bytesToURI(data, type) {
var tmpstr = 'data:image/'+type+',';
var len = data.length;
for (var i = 4; i < len; i++) {
if (data[i] < 16) {
tmpstr += '%0';
} else {
tmpstr += '%';
}
tmpstr += data[i].toString(16);
}
return tmpstr;
}
//quic
wdi.QuicImageType = {
QUIC_IMAGE_TYPE_INVALID: 0,
QUIC_IMAGE_TYPE_GRAY: 1,
QUIC_IMAGE_TYPE_RGB16: 2,
QUIC_IMAGE_TYPE_RGB24: 3,
QUIC_IMAGE_TYPE_RGB32: 4,
QUIC_IMAGE_TYPE_RGBA: 5
};
function bytesToInt16(bytes) {
var low = bytes.shift();
var high = bytes.shift();
return high * Math.pow(16, 2) + low;
}
function bytesToInt32(bytes) {
var low = bytesToInt16(bytes);
var high = bytesToInt16(bytes);
return high * Math.pow(16, 4) + low;
}
wdi.quic = {};
function wdi_quic_QuicFamily() {
this.notGRcwlen = [];
this.nGRcodewords = [];
this.notGRprefixmask = [];
this.notGRsuffixlen = [];
this.xlatU2L = [];
this.xlatL2U = [];
}
function wdi_quic_s_bucket() {
this.pcounters = null;
this.bestcode = 0;
}
function wdi_quic_CommonState() {
this.wm_trigger = this;
this.encoder = null;
this.waitcnt = 0;
this.tabrand_seed = wdi.JSQuic.stabrand();
this.wmidx = wdi.JSQuic.DEFwmistart;
this.wmileft = wdi.JSQuic.wminext;
wdi.JSQuic.set_wm_trigger(this);
this.melcstate = 0;
this.melclen = wdi.JSQuic.J[0];
this.melcorder = (1 << this.melclen) >>> 0;
}
function wdi_quic_FamilyStat() {
this.buckets_buf = null;
this.buckets_ptrs = null;
this.counters = 0;
}
function wdi_quic_Channel() {
this.encoder = null;
this.correlate_row_width = 0;
this.correlate_row = null;
this._buckets_ptrs = null;
this.family_stat_8bpc = new wdi_quic_FamilyStat();
this.family_stat_5bpc = new wdi_quic_FamilyStat();
this.state = new wdi_quic_CommonState();
this.oldFirst = 0;
}
wdi.JSQuic = {
QUIC_MAGIC: 1364543811, //"QUIC"
MAXNUMCODES: 8,
DEFevol: 3,
MINevol: 0,
MAXevol: 5,
DEFwmistart: 0,
MINwmistart: 0,
DEFmaxclen: 26,
DEFwmimax: 6,
DEFwminext: 2048,
MINwminext: 1,
MAXwminext: 100000000,
MAX_CHANNELS: 4,
wmimax: 6,
wminext: 2048,
evol: 3,
family_8bpc: new wdi_quic_QuicFamily(),
family_5bpc: new wdi_quic_QuicFamily(),
bppmask: new Int32Array([
0x00000000,
0x00000001, 0x00000003, 0x00000007, 0x0000000f,
0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff,
0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff,
0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff,
0x0001ffff, 0x0003ffff, 0x0007ffff, 0x000fffff,
0x001fffff, 0x003fffff, 0x007fffff, 0x00ffffff,
0x01ffffff, 0x03ffffff, 0x07ffffff, 0x0fffffff,
0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff
]),
bitat: new Int32Array([
0x00000001, 0x00000002, 0x00000004, 0x00000008,
0x00000010, 0x00000020, 0x00000040, 0x00000080,
0x00000100, 0x00000200, 0x00000400, 0x00000800,
0x00001000, 0x00002000, 0x00004000, 0x00008000,
0x00010000, 0x00020000, 0x00040000, 0x00080000,
0x00100000, 0x00200000, 0x00400000, 0x00800000,
0x01000000, 0x02000000, 0x04000000, 0x08000000,
0x10000000, 0x20000000, 0x40000000, 0x80000000
]),
TABRAND_TABSIZE: 256,
TABRAND_SEEDMASK: 0x0ff,
tabrand_chaos: new Int32Array([
0x02c57542, 0x35427717, 0x2f5a2153, 0x9244f155, 0x7bd26d07, 0x354c6052, 0x57329b28, 0x2993868e,
0x6cd8808c, 0x147b46e0, 0x99db66af, 0xe32b4cac, 0x1b671264, 0x9d433486, 0x62a4c192, 0x06089a4b,
0x9e3dce44, 0xdaabee13, 0x222425ea, 0xa46f331d, 0xcd589250, 0x8bb81d7f, 0xc8b736b9, 0x35948d33,
0xd7ac7fd0, 0x5fbe2803, 0x2cfbc105, 0x013dbc4e, 0x7a37820f, 0x39f88e9e, 0xedd58794, 0xc5076689,
0xfcada5a4, 0x64c2f46d, 0xb3ba3243, 0x8974b4f9, 0x5a05aebd, 0x20afcd00, 0x39e2b008, 0x88a18a45,
0x600bde29, 0xf3971ace, 0xf37b0a6b, 0x7041495b, 0x70b707ab, 0x06beffbb, 0x4206051f, 0xe13c4ee3,
0xc1a78327, 0x91aa067c, 0x8295f72a, 0x732917a6, 0x1d871b4d, 0x4048f136, 0xf1840e7e, 0x6a6048c1,
0x696cb71a, 0x7ff501c3, 0x0fc6310b, 0x57e0f83d, 0x8cc26e74, 0x11a525a2, 0x946934c7, 0x7cd888f0,
0x8f9d8604, 0x4f86e73b, 0x04520316, 0xdeeea20c, 0xf1def496, 0x67687288, 0xf540c5b2, 0x22401484,
0x3478658a, 0xc2385746, 0x01979c2c, 0x5dad73c8, 0x0321f58b, 0xf0fedbee, 0x92826ddf, 0x284bec73,
0x5b1a1975, 0x03df1e11, 0x20963e01, 0xa17cf12b, 0x740d776e, 0xa7a6bf3c, 0x01b5cce4, 0x1118aa76,
0xfc6fac0a, 0xce927e9b, 0x00bf2567, 0x806f216c, 0xbca69056, 0x795bd3e9, 0xc9dc4557, 0x8929b6c2,
0x789d52ec, 0x3f3fbf40, 0xb9197368, 0xa38c15b5, 0xc3b44fa8, 0xca8333b0, 0xb7e8d590, 0xbe807feb,
0xbf5f8360, 0xd99e2f5c, 0x372928e1, 0x7c757c4c, 0x0db5b154, 0xc01ede02, 0x1fc86e78, 0x1f3985be,
0xb4805c77, 0x00c880fa, 0x974c1b12, 0x35ab0214, 0xb2dc840d, 0x5b00ae37, 0xd313b026, 0xb260969d,
0x7f4c8879, 0x1734c4d3, 0x49068631, 0xb9f6a021, 0x6b863e6f, 0xcee5debf, 0x29f8c9fb, 0x53dd6880,
0x72b61223, 0x1f67a9fd, 0x0a0f6993, 0x13e59119, 0x11cca12e, 0xfe6b6766, 0x16b6effc, 0x97918fc4,
0xc2b8a563, 0x94f2f741, 0x0bfa8c9a, 0xd1537ae8, 0xc1da349c, 0x873c60ca, 0x95005b85, 0x9b5c080e,
0xbc8abbd9, 0xe1eab1d2, 0x6dac9070, 0x4ea9ebf1, 0xe0cf30d4, 0x1ef5bd7b, 0xd161043e, 0x5d2fa2e2,
0xff5d3cae, 0x86ed9f87, 0x2aa1daa1, 0xbd731a34, 0x9e8f4b22, 0xb1c2c67a, 0xc21758c9, 0xa182215d,
0xccb01948, 0x8d168df7, 0x04238cfe, 0x368c3dbc, 0x0aeadca5, 0xbad21c24, 0x0a71fee5, 0x9fc5d872,
0x54c152c6, 0xfc329483, 0x6783384a, 0xeddb3e1c, 0x65f90e30, 0x884ad098, 0xce81675a, 0x4b372f7d,
0x68bf9a39, 0x43445f1e, 0x40f8d8cb, 0x90d5acb6, 0x4cd07282, 0x349eeb06, 0x0c9d5332, 0x520b24ef,
0x80020447, 0x67976491, 0x2f931ca3, 0xfe9b0535, 0xfcd30220, 0x61a9e6cc, 0xa487d8d7, 0x3f7c5dd1,
0x7d0127c5, 0x48f51d15, 0x60dea871, 0xc9a91cb7, 0x58b53bb3, 0x9d5e0b2d, 0x624a78b4, 0x30dbee1b,
0x9bdf22e7, 0x1df5c299, 0x2d5643a7, 0xf4dd35ff, 0x03ca8fd6, 0x53b47ed8, 0x6f2c19aa, 0xfeb0c1f4,
0x49e54438, 0x2f2577e6, 0xbf876969, 0x72440ea9, 0xfa0bafb8, 0x74f5b3a0, 0x7dd357cd, 0x89ce1358,
0x6ef2cdda, 0x1e7767f3, 0xa6be9fdb, 0x4f5f88f8, 0xba994a3a, 0x08ca6b65, 0xe0893818, 0x9e00a16a,
0xf42bfc8f, 0x9972eedc, 0x749c8b51, 0x32c05f5e, 0xd706805f, 0x6bfbb7cf, 0xd9210a10, 0x31a1db97,
0x923a9559, 0x37a7a1f6, 0x059f8861, 0xca493e62, 0x65157e81, 0x8f6467dd, 0xab85ff9f, 0x9331aff2,
0x8616b9f5, 0xedbd5695, 0xee7e29b1, 0x313ac44f, 0xb903112f, 0x432ef649, 0xdc0a36c0, 0x61cf2bba,
0x81474925, 0xa8b6c7ad, 0xee5931de, 0xb2f8158d, 0x59fb7409, 0x2e3dfaed, 0x9af25a3f, 0xe1fed4d5
]),
besttrigtab: [
[550, 900, 800, 700, 500, 350, 300, 200, 180, 180, 160],
[110, 550, 900, 800, 550, 400, 350, 250, 140, 160, 140],
[100, 120, 550, 900, 700, 500, 400, 300, 220, 250, 160]
],
lzeroes: new Int32Array([
8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
]),
J: new Int32Array([
0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 5, 5, 6, 6, 7,
7, 8, 9, 10, 11, 12, 13, 14, 15
]),
zeroLUT: null,
BPC_MASK: {
4: 0xff,
5: 0xff,
24: 0xff,
16: 0x1f
},
stabrand: function() {
return this.TABRAND_SEEDMASK;
},
tabrand: function(rgb_state) {
rgb_state.tabrand_seed++;
return this.tabrand_chaos[rgb_state.tabrand_seed & this.TABRAND_SEEDMASK];
},
set_wm_trigger: function(state) {
var wm = state.wmidx;
if (wm > 10) {
wm = 10;
}
//>> 1 == / 2
state.wm_trigger = wdi.JSQuic.besttrigtab[Math.floor(wdi.JSQuic.evol >> 1)][wm];
},
ceil_log_2: function(val) {
var result;
if (val === 1) {
return 0;
}
result = 1;
val -= 1;
while ((val >>>= 1)) {
result++;
}
return result;
},
decorelate_init: function(family, bpc) {
var pixelbitmask = this.bppmask[bpc];
var pixelbitmaskshr = pixelbitmask >>> 1;
var s;
for (s = 0; s <= pixelbitmask; s++) {
if (s <= pixelbitmaskshr) {
family.xlatU2L[s] = (s << 1) >>> 0;
} else {
family.xlatU2L[s] = (((pixelbitmask - s) << 1) >>> 0) + 1;
}
}
},
corelate_init: function(family, bpc) {
var pixelbitmask = this.bppmask[bpc];
var s;
for (s = 0; s <= pixelbitmask; s++) {
if (s & 0x01) {
family.xlatL2U[s] = pixelbitmask - (s >>> 1);
} else {
family.xlatL2U[s] = (s >>> 1);
}
}
},
family_init: function(family, bpc, limit) {
var l;
for (l = 0; l < bpc; l++) {
var altprefixlen, altcodewords;
altprefixlen = limit - bpc;
if (altprefixlen > parseInt(this.bppmask[bpc - l])) {
altprefixlen = this.bppmask[bpc - l];
}
altcodewords = this.bppmask[bpc] + 1 - ((altprefixlen << l) >>> 0);
family.nGRcodewords[l] = ((altprefixlen << l) >>> 0);
family.notGRcwlen[l] = altprefixlen + this.ceil_log_2(altcodewords);
family.notGRprefixmask[l] = this.bppmask[32 - altprefixlen];
family.notGRsuffixlen[l] = this.ceil_log_2(altcodewords);
}
//this.decorelate_init(family, bpc);
this.corelate_init(family, bpc);
},
init_zeroLUT: function() {
this.zeroLUT = new Int32Array(256);
var i, j, k, l;
j = k = 1;
l = 8;
for (i = 0; i < 256; ++i) {
this.zeroLUT[i] = l;
--k;
if (k === 0) {
k = j;
--l;
j *= 2;
}
}
},
quic_init: function() {
this.family_init(this.family_8bpc, 8, this.DEFmaxclen);
//this.family_init(this.family_5bpc, 5, this.DEFmaxclen);
this.init_zeroLUT();
//perf improvment
wdi.xlatL2U = new Int32Array(this.family_8bpc.xlatL2U.length);
wdi.xlatL2U.set(this.family_8bpc.xlatL2U);
wdi.notGRprefixmask = new Int32Array(this.family_8bpc.notGRprefixmask.length);
wdi.notGRprefixmask.set(this.family_8bpc.notGRprefixmask);
wdi.nGRcodewords = new Int32Array(this.family_8bpc.nGRcodewords.length);
wdi.nGRcodewords.set(this.family_8bpc.nGRcodewords);
wdi.notGRcwlen = new Int32Array(this.family_8bpc.notGRcwlen.length);
wdi.notGRcwlen.set(this.family_8bpc.notGRcwlen);
wdi.notGRsuffixlen = new Int32Array(this.family_8bpc.notGRsuffixlen.length);
wdi.notGRsuffixlen.set(this.family_8bpc.notGRsuffixlen);
//prepare precomputed lzeroes tables
var lzeroes = wdi.JSQuic.lzeroes;
var lzeroes8 = new Int32Array(lzeroes);
var len = lzeroes.length;
for (var i = 0; i < len; i++) {
lzeroes8[i] = lzeroes[i] + 8;
}
wdi.JSQuic.lzeroes8 = lzeroes8;
//prepare precomputed lzeroes tables
var lzeroes16 = new Int32Array(lzeroes);
for (var i = 0; i < len; i++) {
lzeroes16[i] = lzeroes[i] + 16;
}
wdi.JSQuic.lzeroes16 = lzeroes16;
//prepare precomputed lzeroes tables
var lzeroes24 = new Int32Array(lzeroes);
for (var i = 0; i < len; i++) {
lzeroes24[i] = lzeroes[i] + 24;
}
wdi.JSQuic.lzeroes24 = lzeroes24;
},
quic_image_params: function(encoder, type) {
var channels, bpc;
switch (type) {
case wdi.QuicImageType.QUIC_IMAGE_TYPE_GRAY:
channels = 1;
bpc = 8;
break;
case wdi.QuicImageType.QUIC_IMAGE_TYPE_RGB16:
channels = 3;
bpc = 5;
break;
case wdi.QuicImageType.QUIC_IMAGE_TYPE_RGB24:
channels = 3;
bpc = 8;
break;
case wdi.QuicImageType.QUIC_IMAGE_TYPE_RGB32:
channels = 3;
bpc = 8;
break;
case wdi.QuicImageType.QUIC_IMAGE_TYPE_RGBA:
channels = 4;
bpc = 8;
break;
case wdi.QuicImageType.QUIC_IMAGE_TYPE_INVALID:
default:
channels = 0;
bpc = 0;
}
return [channels, bpc];
},
find_model_params: function(encoder, bpc) {
var bsize = 0;
var bstart = 0;
var bend = 0;
var repcntr = 0;
var result = {};
result.ncounters = 8;
result.levels = 0x1 << bpc;
result.n_buckets_ptrs = 0;
switch (this.evol) {
case 1:
result.repfirst = 3;
result.firstsize = 1;
result.repnext = 2;
result.mulsize = 2;
break;
case 3:
result.repfirst = 1;
result.firstsize = 1;
result.repnext = 1;
result.mulsize = 2;
break;
case 5:
result.repfirst = 1;
result.firstsize = 1;
result.repnext = 1;
result.mulsize = 4;
break;
case 0:
case 2:
case 4:
default:
wdi.Debug.error('fund model params: invalid evol');
return false;
}
result.nbuckets = 0;
repcntr = result.repfirst + 1;
bsize = result.firstsize;
do { /* other buckets */
if (result.nbuckets) {
bstart = bend + 1;
} else {
bstart = 0;
}
if (!--repcntr) {
repcntr = result.repnext;
bsize *= result.mulsize;
}
bend = bstart + bsize - 1;
if (bend + bsize >= result.levels) {
bend = result.levels - 1;
}
if (!result.n_buckets_ptrs) {
result.n_buckets_ptrs = result.levels;
}
result.nbuckets++;
} while (bend < result.levels - 1);
return result;
},
init_model_structures: function(encoder, family, params) {
family.buckets_buf = [];
for (var i = 0; i < params.nbuckets; i++) {
family.buckets_buf[i] = new wdi_quic_s_bucket();
}
family.buckets_ptrs = [];
family.counters = [];
this.fill_model_structures(encoder, family, params);
},
fill_model_structures: function(encoder, family, params) {
var bsize, bstart, bend = 0,
repcntr, bnumber;
bnumber = 0;
repcntr = params.repfirst + 1;
bsize = params.firstsize;
do {
if (bnumber) {
bstart = bend + 1;
} else {
bstart = 0;
}
if (!--repcntr) {
repcntr = params.repnext;
bsize *= params.mulsize;
}
bend = bstart + bsize - 1;
if (bend + bsize >= params.levels) {
bend = params.levels - 1;
}
family.buckets_buf[bnumber].pcounters = new Int32Array(params.ncounters);
for (var x = 0; x < params.ncounters; x++) {
family.buckets_buf[bnumber].pcounters[x] = 0;
}
for (var i = bstart; i <= bend; i++) {
family.buckets_ptrs[i] = family.buckets_buf[bnumber];
}
bnumber++;
} while (bend < params.levels - 1);
},
initChannel: function(encoder, channel) {
channel.encoder = encoder;
channel.state.encoder = encoder;
channel.correlate_row_width = 0;
channel.correlate_row = null;
var params = this.find_model_params(encoder, 8);
encoder.n_buckets_8bpc = params.nbuckets;
this.init_model_structures(encoder, channel.family_stat_8bpc, params);
params = this.find_model_params(encoder, 5);
encoder.n_buckets_5bpc = params.nbuckets;
this.init_model_structures(encoder, channel.family_stat_5bpc, params);
},
encoder_reste_channels: function(encoder, channels, width, bpc) {
encoder.num_channels = channels;
for (var i = 0; i < channels; i++) {
var bucket, end_bucket;
if (encoder.channels[i].correlate_row_width < width) {
encoder.channels[i].correlate_row = new Array(width);
encoder.channels[i].correlate_row_width = width;
}
encoder.channels[i].num_channel = i;
if (bpc === 8) {
bucket = encoder.channels[i].family_stat_8bpc.buckets_buf;
end_bucket = encoder.n_buckets_8bpc;
for (var x = 0; x < end_bucket; x++) {
bucket[x].bestcode = 8 - 1;
}
encoder.channels[i]._buckets_ptrs = encoder.channels[i].family_stat_8bpc.buckets_ptrs;
} else if (bpc === 5) {
bucket = encoder.channels[i].family_stat_5bpc.buckets_buf;
end_bucket = encoder.n_buckets_5bpc;
for (var x = 0; x < end_bucket; x++) {
bucket[x].bestcode = /*BPC*/ 5 - 1;
}
encoder.channels[i]._buckets_ptrs = encoder.channels[i].family_stat_5bpc.buckets_ptrs;
} else {
return FALSE;
}
encoder.channels[i].state.waitcnt = 0;
encoder.channels[i].state.tabrand_seed = wdi.JSQuic.stabrand();
encoder.channels[i].state.wmidx = wdi.JSQuic.DEFwmistart;
encoder.channels[i].state.wmileft = wdi.JSQuic.wminext;
}
return true;
},
decode_channel_run: function(encoder, channel) {
var runlen = 0;
do {
var temp, hits;
//TODO: casting needed?
temp = wdi.JSQuic.zeroLUT[(~(encoder.io_word >>> 24) >>> 0) % 256];
for (hits = 1; hits <= temp; hits++) {
runlen += channel.state.melcorder;
if (channel.state.melcstate < 32) {
channel.state.melclen = wdi.JSQuic.J[++channel.state.melcstate];
channel.state.melcorder = (1 << channel.state.melclen) >>> 0;
}
}
if (temp !== 8) {
encoder.eatbits(temp + 1, encoder);
break;
}
encoder.eatbits(8, encoder);
} while (1);
/* read the length of the remainder */
if (channel.state.melclen) {
runlen += encoder.io_word >>> (32 - channel.state.melclen);
encoder.eatbits(channel.state.melclen, encoder);
}
/* adjust melcoder parameters */
if (channel.state.melcstate) {
channel.state.melclen = wdi.JSQuic.J[--channel.state.melcstate];
channel.state.melcorder = (1 << channel.state.melclen) >>> 0;
}
return runlen;
},
decode_run: function(encoder) {
var runlen = 0;
var temp, hits, tempadd;
var zeroLUT = wdi.JSQuic.zeroLUT;
var rgb_state = encoder.rgb_state;
var J = wdi.JSQuic.J;
var eatbits = encoder.eatbits;
do {
//TODO: casting needed?
temp = zeroLUT[(~(encoder.io_word >>> 24) >>> 0) % 256];
tempadd = temp + 1;
for (hits = 1; hits < tempadd; hits++) {
runlen += encoder.rgb_state.melcorder;
if (rgb_state.melcstate < 32) {
rgb_state.melclen = J[++rgb_state.melcstate];
rgb_state.melcorder = (1 << rgb_state.melclen) >>> 0;
}
}
if (temp !== 8) {
eatbits(tempadd, encoder);
break;
}
encoder.eatbits(8, encoder);
} while (1);
if (rgb_state.melclen) {
runlen += encoder.io_word >>> (32 - rgb_state.melclen);
eatbits(rgb_state.melclen, encoder);
}
if (rgb_state.melcstate) {
rgb_state.melclen = J[--rgb_state.melcstate];
rgb_state.melcorder = (1 << rgb_state.melclen) >>> 0;
}
return runlen;
},
quic_decode: function(data) {
//console.time("test");
var view = new Uint32Array(data);
var encoder = new wdi_quic_Encoder(view);
var opaque = encoder.io_word & 0x0000FF00;
var format = (encoder.io_word >>> 24) & 0xFF;
encoder.eat32bits(); //skip quic size
encoder.eat32bits();
var magic = encoder.io_word;
encoder.eat32bits();
var version = encoder.io_word;
encoder.eat32bits();
var type = encoder.io_word;
encoder.eat32bits();
encoder.type = type; //here?
var width = encoder.io_word;
encoder.width = width; //here?
encoder.eat32bits();
var height = encoder.io_word;
encoder.height = height; //here?
encoder.eat32bits();
var result = wdi.JSQuic.quic_image_params(encoder, type);
var channels = result[0];
var bpc = result[1];
this.encoder_reste_channels(encoder, channels, width, bpc);
var buf = new ArrayBuffer(width * height * 4);
var buf8 = new Uint8Array(buf);
var data = new Uint32Array(buf);
encoder.result = buf8;
encoder.resultData = data;
encoder.setComputedWidth(width);
switch (type) {
case wdi.QuicImageType.QUIC_IMAGE_TYPE_RGB32:
case wdi.QuicImageType.QUIC_IMAGE_TYPE_RGB24:
//ASSERT(encoder->usr, ABS(stride) >= (int)encoder->width * 4);
QUIC_UNCOMPRESS_RGB(encoder, channels, bpc, type);
break;
case wdi.QuicImageType.QUIC_IMAGE_TYPE_RGB16:
// if (type == QUIC_IMAGE_TYPE_RGB16) {
// //ASSERT(encoder->usr, ABS(stride) >= (int)encoder->width * 2);
// QUIC_UNCOMPRESS_RGB(16, rgb16_pixel_t);
// } else if (type == QUIC_IMAGE_TYPE_RGB32) {
// //ASSERT(encoder->usr, ABS(stride) >= (int)encoder->width * 4);
// QUIC_UNCOMPRESS_RGB(16_to_32, rgb32_pixel_t);
// } else {
// //encoder->usr->warn(encoder->usr, "unsupported output format\n");
// return QUIC_ERROR;
// }
break;
case wdi.QuicImageType.QUIC_IMAGE_TYPE_RGBA:
QUIC_UNCOMPRESS_RGBA(encoder, channels, bpc, type);
if (opaque) {
var len = buf8.length - 1;
while (len > 0) {
buf8[len] = 255;
len -= 4;
}
}
break;
//QUIC_UNCOMPRESS_RGBA(encoder, channels, bpc, type);
//
// if (type != QUIC_IMAGE_TYPE_RGBA) {
// //encoder->usr->warn(encoder->usr, "unsupported output format\n");
// return QUIC_ERROR;
// }
// //ASSERT(encoder->usr, ABS(stride) >= (int)encoder->width * 4);
// uncompress_rgba(encoder, buf, stride);
// break;
}
// var len = encoder.result.length;
// while(len--) {
// imgData.data[len] = encoder.result[len];
// }
//console.timeEnd("test");
//imgData.data.set(buf8);
return buf;
}
};
wdi.JSQuic.quic_init();
function wdi_quic_Encoder(data) {
this.computedWidth = 0;
this.result = [];
this.cnt = 0;
this.pxCnt = 0,
this.usr = data;
this.type = null;
this.width = null;
this.height = null;
this.num_channels = null;
this.n_buckets_8bpc = null;
this.n_buckets_5bpc = null;
this.io_available_bits = 32;
this.io_now = 0;
this.io_next_word = null;
this.io_now = null;
this.read_io_word();
this.io_word = this.io_next_word;
this.read_io_word();
this.io_words_count = data.length;
this.rows_completed = 0; //??
this.channels = [];
this.alphaPos = 3; //first alpha
this.rgb_state = new wdi_quic_CommonState();
for (var i = 0; i < 4; i++) {
this.channels[i] = new wdi_quic_Channel();
wdi.JSQuic.initChannel(this, this.channels[i]);
}
}
wdi_quic_Encoder.prototype.append = function(databyte) {
this.result[this.cnt++] = databyte;
}
wdi_quic_Encoder.prototype.appendPixel = function(r, g, b) {
this.resultData[this.pxCnt++] =
(255 << 24) | // alpha
(b << 16) | // blue
(g << 8) | // green
r; // red
this.cnt += 4;
}
wdi_quic_Encoder.prototype.eatbits = function(len, encoder) {
var available_bits = encoder.io_available_bits;
var io_word = encoder.io_word;
var delta = available_bits - len;
io_word = io_word << len;
//enough bits
if (delta >= 0) {
io_word = (io_word | encoder.io_next_word >>> delta) >>> 0;
encoder.io_available_bits = delta;
encoder.io_word = io_word;
return;
}
var io_next_word = encoder.io_next_word;
//not enough bits
delta = -delta; //bits missing
io_word = (io_word | (io_next_word << delta) >>> 0);
///////////////////
//read io word (inlined for perforemance)
io_next_word = encoder.usr[encoder.io_now++];
//end read io_word
/////////////////
available_bits = 32 - delta;
io_word = (io_word | (io_next_word >>> available_bits)) >>> 0;
encoder.io_available_bits = available_bits;
encoder.io_word = io_word;
encoder.io_next_word = io_next_word;
}
wdi_quic_Encoder.prototype.eat32bits = function() {
this.eatbits(16, this);
this.eatbits(16, this);
}
wdi_quic_Encoder.prototype.read_io_word = function() {
this.io_next_word = this.usr[this.io_now++];
}
wdi_quic_Encoder.prototype.row_completed = function() {
this.rows_completed++;
}
wdi_quic_Encoder.prototype.setComputedWidth = function(width) {
this.computedWidth = width * 4;
}
wdi_quic_Encoder.prototype.appendAlpha = function(databyte) {
this.result[this.alphaPos] = databyte;
this.alphaPos += 4;
}
function cnt_l_zeroes(bits) {
if (bits > 0x007FFFFF) {
return wdi.JSQuic.lzeroes[bits >>> 24];
} else if (bits > 0x00007FFF) {
return 8 + wdi.JSQuic.lzeroes[((bits >>> 16) & 0x000000ff)];
} else if (bits > 0x0000007F) {
return 16 + wdi.JSQuic.lzeroes[((bits >>> 8) & 0x000000ff)];
} else {
return 24 + wdi.JSQuic.lzeroes[(bits & 0x000000ff)];
}
}
/*
*
*
* JSQUIC FAMILY
*
*
*/
function golomb_code_len(n, l) {
if (n < wdi.nGRcodewords[l]) {
return (n >>> l) + 1 + l;
} else {
return wdi.notGRcwlen[l];
}
}
function golomb_decoding(l, bits, bppmask, notGRprefixmask, notGRcwlen, nGRcodewords, notGRsuffixlen) {
var cwlen;
var result;
//its better to check first for bigger, tested for performance
if (bits > notGRprefixmask[l]) {
var zeroprefix = cnt_l_zeroes(bits);
cwlen = zeroprefix + 1 + l;
result = ((zeroprefix << l)) | ((bits >>> (32 - cwlen)) & bppmask[l]);
} else {
cwlen = notGRcwlen[l];
result = nGRcodewords[l] + ((bits) >>> (32 - cwlen) & bppmask[notGRsuffixlen[l]]);
}
return [result, cwlen];
}
/* update the bucket using just encoded curval */
function real_update_model(state, bucket, curval, bpp, wm_trigger) {
var i;
var bestcode;
var bestcodelen;
var ithcodelen;
var pcounters = bucket.pcounters;
bestcode = bpp - 1;
bestcodelen = (pcounters[bestcode] += golomb_code_len(curval, bestcode));
for (i = bpp - 2; i >= 0; i--) {
ithcodelen = (pcounters[i] += golomb_code_len(curval, i));
if (ithcodelen < bestcodelen) {
bestcode = i;
bestcodelen = ithcodelen;
}
}
bucket.bestcode = bestcode;
if (bestcodelen > state.wm_trigger) {
while (bpp-- > 0) {
pcounters[bpp] >>>= 1;
}
}
}
function UPDATE_MODEL(index, encoder, bpp, correlate_row_r, correlate_row_g, correlate_row_b) {
real_update_model(encoder.rgb_state, find_bucket(encoder.channels[0],
correlate_row_r[index - 1]), correlate_row_r[index], bpp);
real_update_model(encoder.rgb_state, find_bucket(encoder.channels[1],
correlate_row_g[index - 1]), correlate_row_g[index], bpp);
real_update_model(encoder.rgb_state, find_bucket(encoder.channels[2],
correlate_row_b[index - 1]), correlate_row_b[index], bpp);
}
function find_bucket(channel, val) {
if (val === undefined) {
val = channel.oldFirst;
}
return channel._buckets_ptrs[val];
}
/*
*
*
* JSQUIC RGBA
*
*
*/
function QUIC_UNCOMPRESS_RGBA(encoder, channels, bpc, type) {
quic_uncompress_row0(encoder, channels, bpc, type);
quic_four_uncompress_row0(encoder, encoder.channels[3], bpc, type);
encoder.row_completed();
var height = encoder.height;
var rgb_state = encoder.rgb_state;
for (var row = 1; row < height; row++) {
quic_uncompress_row_a(encoder, channels, bpc, type, rgb_state);
quic_four_uncompress_row(encoder, encoder.channels[3], bpc, type);
encoder.row_completed();
}
}
function quic_four_uncompress_row(encoder, channel, bpc, type) {
var bpc_mask = wdi.JSQuic.BPC_MASK[type];
var pos = 0;
var width = encoder.width;
while ((wdi.JSQuic.wmimax > channel.state.wmidx) && (channel.state.wmileft <= width)) {
if (channel.state.wmileft) {
uncompress_four_row_seg(
encoder,
channel,
pos,
pos + channel.state.wmileft,
bpc,
bpc_mask,
type
);
pos += channel.state.wmileft;
width -= channel.state.wmileft;
}
channel.state.wmidx++;
wdi.JSQuic.set_wm_trigger(channel.state);
channel.state.wmileft = wdi.JSQuic.wminext;
}
if (width) {
uncompress_four_row_seg(
encoder,
channel,
pos,
pos + width,
bpc,
bpc_mask,
type
);
if (wdi.JSQuic.wmimax > channel.state.wmidx) {
channel.state.wmileft -= width;
}
}
}
function uncompress_four_row_seg(encoder, channel, i, end, bpc, bpc_mask, type) {
var correlate_row = channel.correlate_row;
var stopidx = 0;
var waitmask = wdi.JSQuic.bppmask[channel.state.wmidx];
var run_index = 0;
var run_end = 0;
var rle = false;
var computedWidth = encoder.computedWidth;
var rows_completed = encoder.rows_completed;
var offset = ((encoder.rows_completed - 1) * computedWidth);
var data;
var eatbits = encoder.eatbits;
var appendAlpha = encoder.appendAlpha;
var alpha;
var ret, codewordlen;
var bppmask = wdi.JSQuic.bppmask;
var notGRprefixmask = wdi.notGRprefixmask;
var notGRcwlen = wdi.notGRcwlen;
var nGRcodewords = wdi.nGRcodewords;
var notGRsuffixlen = wdi.notGRsuffixlen;
if (!i) {
alpha = UNCOMPRESS_ONE_0_A(channel, encoder, bpc_mask, offset);
if (channel.state.waitcnt) {
--channel.state.waitcnt;
} else {
channel.state.waitcnt = (wdi.JSQuic.tabrand(channel.state) & waitmask);
real_update_model(channel.state, find_bucket(channel,
correlate_row[-1]), correlate_row[0], bpc);
}
stopidx = ++i + channel.state.waitcnt;
} else {
stopidx = i + channel.state.waitcnt;
alpha = encoder.result[encoder.alphaPos - 4];
}
for (;;) {
while (stopidx < end) {
for (; i <= stopidx; i++) {
rle = RLE_PRED_A(i, encoder, run_index, computedWidth, rows_completed);
if (rle) break;
ret = golomb_decoding(find_bucket(channel, correlate_row[i - 1]).bestcode,
encoder.io_word, bppmask, notGRprefixmask, notGRcwlen, nGRcodewords, notGRsuffixlen);
data = ret[0];
codewordlen = ret[1];
correlate_row[i] = data;
alpha = (((wdi.xlatL2U[data] +
((alpha + PIXEL_B(channel, encoder, i, offset)) >>> 1)) & bpc_mask) >>> 0);
appendAlpha.call(encoder, alpha);
eatbits(codewordlen, encoder);
}
if (!rle) {
real_update_model(channel.state, find_bucket(channel,
correlate_row[stopidx - 1]), correlate_row[stopidx], bpc);
stopidx = i + (wdi.JSQuic.tabrand(channel.state) & waitmask);
} else {
break;
}
}
if (!rle) {
for (; i < end; i++) {
rle = RLE_PRED_A(i, encoder, run_index, computedWidth, rows_completed);
if (rle) break;
ret = golomb_decoding(find_bucket(channel, correlate_row[i - 1]).bestcode,
encoder.io_word, bppmask, notGRprefixmask, notGRcwlen, nGRcodewords, notGRsuffixlen);
data = ret[0];
codewordlen = ret[1];
correlate_row[i] = data;
alpha = (((wdi.xlatL2U[data] +
((alpha + PIXEL_B(channel, encoder, i, offset)) >>> 1)) & bpc_mask) >>> 0);
appendAlpha.call(encoder, alpha);
eatbits(codewordlen, encoder);
}
if (!rle) {
channel.state.waitcnt = stopidx - end;
return;
}
}
//RLE
channel.state.waitcnt = stopidx - i;
run_index = i;
run_end = i + wdi.JSQuic.decode_channel_run(encoder, channel);
var cpos = ((encoder.rows_completed) * (encoder.width * 4)) + (i * 4);
var a = encoder.result[cpos - 1];
for (; i < run_end; i++) {
//TODO: how to append?
appendAlpha.call(encoder, a);
}
if (i === end) {
return;
}
stopidx = i + channel.state.waitcnt;
rle = false;
//END RLE
}
}
function quic_four_uncompress_row0(encoder, channel, bpc, type) {
var bpc_mask = wdi.JSQuic.BPC_MASK[type];
var pos = 0;
var width = encoder.width;
while ((wdi.JSQuic.wmimax > channel.state.wmidx) && (channel.state.wmileft <= width)) {
if (channel.state.wmileft) {
uncompress_four_row0_seg(
encoder,
channel,
pos,
pos + channel.wmileft,
wdi.JSQuic.bppmask[channel.state.wmidx],
bpc,
bpc_mask,
type
);
pos += channel.state.wmileft;
width -= channel.state.wmileft;
}
channel.state.wmidx++;
wdi.JSQuic.set_wm_trigger(channel.state);
channel.state.wmileft = wdi.JSQuic.wminext;
}
if (width) {
uncompress_four_row0_seg(
encoder,
channel,
pos,
pos + width,
wdi.JSQuic.bppmask[channel.state.wmidx],
bpc,
bpc_mask,
type
);
if (wdi.JSQuic.wmimax > channel.state.wmidx) {
channel.state.wmileft -= width;
}
}
}
function uncompress_four_row0_seg(encoder, channel, i, end, waitmask, bpc, bpc_mask, type) {
var correlate_row = channel.correlate_row;
var stopidx = 0;
if (!i) {
UNCOMPRESS_ONE_ROW0_0_A(channel);
if (channel.state.waitcnt) {
--channel.state.waitcnt;
} else {
channel.state.waitcnt = (wdi.JSQuic.tabrand(channel.state) & waitmask);
real_update_model(channel.state, find_bucket(channel,
correlate_row[-1]), correlate_row[0], bpc);
}
stopidx = ++i + channel.state.waitcnt;
} else {
stopidx = i + channel.state.waitcnt;
}
while (stopidx < end) {
for (; i <= stopidx; i++) {
UNCOMPRESS_ONE_ROW0_A(channel, i, bpc_mask, encoder, correlate_row);
}
real_update_model(channel.state, find_bucket(channel,
correlate_row[stopidx - 1]), correlate_row[stopidx], bpc);
stopidx = i + (wdi.JSQuic.tabrand(channel.state) & waitmask);
}
for (; i < end; i++) {
UNCOMPRESS_ONE_ROW0_A(channel, i, bpc_mask, encoder, correlate_row);
}
channel.state.waitcnt = stopidx - end;
}
function SAME_PIXEL_A(i, result) {
if (result[i - 1] === result[i + 3]) {
return true;
}
return false;
}
function RLE_PRED_A(i, encoder, run_index, width, rows_completed) {
var pr = ((rows_completed - 1) * width) + (i * 4); //prev r
if (run_index !== i && i > 2) {
if (SAME_PIXEL_A(pr, encoder.result)) {
pr = ((rows_completed) * width) + ((i - 1) * 4); // cur r
if (SAME_PIXEL_A(pr, encoder.result)) {
return true;
}
}
}
return false;
}
function UNCOMPRESS_ONE_0_A(channel, encoder, bpc_mask, offset) {
var ret, codewordlen;
channel.oldFirst = channel.correlate_row[0];
ret = golomb_decoding(find_bucket(channel,
channel.correlate_row[-1]).bestcode, encoder.io_word, wdi.JSQuic.bppmask, wdi.notGRprefixmask, wdi.notGRcwlen, wdi.nGRcodewords, wdi.notGRsuffixlen);
channel.correlate_row[0] = ret[0];
codewordlen = ret[1];
var residuum = wdi.xlatL2U[channel.correlate_row[0]];
var prev = PIXEL_B(channel, encoder, 0, offset);
var resultpixel = ((residuum + prev) & bpc_mask) >>> 0;
encoder.appendAlpha(resultpixel);
encoder.eatbits(codewordlen, encoder);
return resultpixel;
}
function UNCOMPRESS_ONE_A(channel, i, bpc_mask, encoder, correlate_row, offset) {
var ret, codewordlen;
ret = golomb_decoding(find_bucket(channel, correlate_row[i - 1]).bestcode,
encoder.io_word, wdi.JSQuic.bppmask, wdi.notGRprefixmask, wdi.notGRcwlen, wdi.nGRcodewords, wdi.notGRsuffixlen);
var data = ret[0];
codewordlen = ret[1];
correlate_row[i] = data;
encoder.appendAlpha((((wdi.xlatL2U[data] +
((PIXEL_A_A(encoder) + PIXEL_B(channel, encoder, i, offset)) >>> 1)) & bpc_mask) >>> 0));
encoder.eatbits(codewordlen, encoder);
}
function UNCOMPRESS_ONE_ROW0_0_A(channel) {
var ret, codewordlen;
var encoder = channel.encoder;
ret = golomb_decoding(find_bucket(channel, 0).bestcode, encoder.io_word, wdi.JSQuic.bppmask, wdi.notGRprefixmask, wdi.notGRcwlen, wdi.nGRcodewords, wdi.notGRsuffixlen);
channel.correlate_row[0] = ret[0];
codewordlen = ret[1];
encoder.appendAlpha(wdi.xlatL2U[channel.correlate_row[0]]);
encoder.eatbits(codewordlen, encoder);
}
function UNCOMPRESS_ONE_ROW0_A(channel, i, bpc_mask, encoder, correlate_row) {
var ret, codewordlen;
ret = golomb_decoding(find_bucket(channel, correlate_row[i - 1]).bestcode, encoder.io_word, wdi.JSQuic.bppmask, wdi.notGRprefixmask, wdi.notGRcwlen, wdi.nGRcodewords, wdi.notGRsuffixlen);
var data = ret[0];
codewordlen = ret[1];
correlate_row[i] = data;
encoder.appendAlpha(CORELATE_0_A(encoder, channel, i, bpc_mask, correlate_row));
encoder.eatbits(codewordlen, encoder);
}
function CORELATE_0_A(encoder, channel, curr, bpc_mask, correlate_row) {
return ((wdi.xlatL2U[correlate_row[curr]] + PIXEL_A_A(encoder)) & bpc_mask) >>> 0;
}
function PIXEL_A_A(encoder) {
return encoder.result[encoder.alphaPos - 4];
}
/*
*
*
* JSQUIC UNCOMPRESS
*
*
*/
function QUIC_UNCOMPRESS_RGB(encoder, channels, bpc, type) {
quic_uncompress_row0(encoder, channels, bpc, type);
encoder.row_completed();
var rgb_state = encoder.rgb_state;
var height = encoder.height;
var computedAlpha = 255 << 24;
var result = encoder.result;
var resultData = encoder.resultData;
var width = encoder.width;
var bpc_mask = wdi.JSQuic.BPC_MASK[type];
var jsquic = wdi.JSQuic;
var channel_r = encoder.channels[0];
var channel_g = encoder.channels[1];
var channel_b = encoder.channels[2];
var buckets_ptrs_r = channel_r._buckets_ptrs;
var buckets_ptrs_g = channel_g._buckets_ptrs;
var buckets_ptrs_b = channel_b._buckets_ptrs;
var correlate_row_r = channel_r.correlate_row;
var correlate_row_g = channel_g.correlate_row;
var correlate_row_b = channel_b.correlate_row;
var computedWidth = encoder.computedWidth;
var xlatL2U = wdi.xlatL2U;
var lzeroes = wdi.JSQuic.lzeroes;
var lzeroes8 = wdi.JSQuic.lzeroes8;
var lzeroes16 = wdi.JSQuic.lzeroes16;
var lzeroes24 = wdi.JSQuic.lzeroes24;
var notGRprefixmask = wdi.notGRprefixmask;
var notGRcwlen = wdi.notGRcwlen;
var nGRcodewords = wdi.nGRcodewords;
var notGRsuffixlen = wdi.notGRsuffixlen;
var eatbits = encoder.eatbits;
var tabrand = wdi.JSQuic.tabrand;
var decode_run = wdi.JSQuic.decode_run;
var bppmask = wdi.JSQuic.bppmask;
var jsquic = wdi.JSQuic;
var tabrand_chaos = wdi.JSQuic.tabrand_chaos;
var tabrand_seedmask = jsquic.TABRAND_SEEDMASK;
var usr = encoder.usr;
for (var row = 1; row < height; row++) {
quic_uncompress_row(encoder, channels, bpc, type, rgb_state, computedAlpha, result, resultData, width, bpc_mask,
jsquic, channel_r, channel_g, channel_b, buckets_ptrs_r, buckets_ptrs_g, buckets_ptrs_b, correlate_row_r,
correlate_row_g, correlate_row_b, computedWidth, xlatL2U, lzeroes, lzeroes8, lzeroes16, lzeroes24,
notGRprefixmask, notGRcwlen, nGRcodewords, notGRsuffixlen, eatbits, tabrand, decode_run, bppmask, tabrand_chaos,
tabrand_seedmask, usr);
encoder.rows_completed++;
}
}
function quic_uncompress_row(encoder, channels, bpc, type, rgb_state, computedAlpha, result, resultData, width, bpc_mask,
jsquic, channel_r, channel_g, channel_b, buckets_ptrs_r, buckets_ptrs_g, buckets_ptrs_b, correlate_row_r, correlate_row_g,
correlate_row_b, computedWidth, xlatL2U, lzeroes, lzeroes8, lzeroes16, lzeroes24,
notGRprefixmask, notGRcwlen, nGRcodewords, notGRsuffixlen, eatbits, tabrand, decode_run, bppmask, tabrand_chaos,
tabrand_seedmask, usr) {
var pos = 0;
var rows_completed = encoder.rows_completed;
var currentOffset32 = ((rows_completed) * computedWidth / 4);
var offset = ((rows_completed - 1) * computedWidth);
while ((jsquic.wmimax > rgb_state.wmidx) && (rgb_state.wmileft <= width)) {
if (rgb_state.wmileft) {
uncompress_row_seg(
encoder,
pos,
pos + rgb_state.wmileft,
bpc,
bpc_mask,
type,
rgb_state,
computedAlpha,
result,
resultData,
channel_r,
channel_g,
channel_b,
buckets_ptrs_r,
buckets_ptrs_g,
buckets_ptrs_b,
correlate_row_r,
correlate_row_g,
correlate_row_b,
computedWidth,
xlatL2U,
lzeroes,
lzeroes8,
lzeroes16,
lzeroes24,
notGRprefixmask,
notGRcwlen,
nGRcodewords,
notGRsuffixlen,
eatbits,
tabrand,
decode_run,
bppmask,
jsquic,
tabrand_chaos,
rows_completed,
tabrand_seedmask,
offset,
currentOffset32,
usr
);
pos += rgb_state.wmileft;
width -= rgb_state.wmileft;
}
rgb_state.wmidx++;
jsquic.set_wm_trigger(rgb_state);
rgb_state.wmileft = jsquic.wminext;
}
if (width) {
uncompress_row_seg(
encoder,
pos,
pos + width,
bpc,
bpc_mask,
type,
rgb_state,
computedAlpha,
result,
resultData,
channel_r,
channel_g,
channel_b,
buckets_ptrs_r,
buckets_ptrs_g,
buckets_ptrs_b,
correlate_row_r,
correlate_row_g,
correlate_row_b,
computedWidth,
xlatL2U,
lzeroes,
lzeroes8,
lzeroes16,
lzeroes24,
notGRprefixmask,
notGRcwlen,
nGRcodewords,
notGRsuffixlen,
eatbits,
tabrand,
decode_run,
bppmask,
jsquic,
tabrand_chaos,
rows_completed,
tabrand_seedmask,
offset,
currentOffset32,
usr
);
if (jsquic.wmimax > encoder.rgb_state.wmidx) {
rgb_state.wmileft -= width;
}
}
}
function quic_uncompress_row_a(encoder, channels, bpc, type, rgb_state) {
var bpc_mask = wdi.JSQuic.BPC_MASK[type];
var pos = 0;
var width = encoder.width;
while ((wdi.JSQuic.wmimax > rgb_state.wmidx) && (rgb_state.wmileft <= width)) {
if (rgb_state.wmileft) {
uncompress_row_seg_a(
encoder,
pos,
pos + rgb_state.wmileft,
bpc,
bpc_mask,
type,
rgb_state
);
pos += rgb_state.wmileft;
width -= rgb_state.wmileft;
}
rgb_state.wmidx++;
wdi.JSQuic.set_wm_trigger(rgb_state);
rgb_state.wmileft = wdi.JSQuic.wminext;
}
if (width) {
uncompress_row_seg_a(
encoder,
pos,
pos + width,
bpc,
bpc_mask,
type,
rgb_state
);
if (wdi.JSQuic.wmimax > encoder.rgb_state.wmidx) {
rgb_state.wmileft -= width;
}
}
}
function SAME_PIXEL_RGB_A(i, result) {
if (result[i - 4] === result[i] && result[i - 3] === result[i + 1] && result[i - 2] === result[i + 2])
return true;
return false;
}
function SAME_PIXEL(i, result) {
if (result[i - 1] === result[i])
return true;
return false;
}
function RLE_PRED_RGB_A(i, encoder, offset, currentOffset, run_index) {
if (run_index !== i && i > 2) {
if (SAME_PIXEL_RGB_A(offset, encoder.result)) { //fila de arriba
var pr = currentOffset + ((i - 1) * 4);
if (SAME_PIXEL_RGB_A(pr, encoder.result)) { //pixel de la izquierda
return true;
}
}
}
return false;
}
function RLE_PRED(i, encoder, offset, currentOffset, run_index) {
if (run_index !== i && i > 2) {
if (SAME_PIXEL(offset * 4, encoder.result)) { //fila de arriba
var pr = currentOffset + i - 1;
if (SAME_PIXEL(pr * 4, encoder.result)) { //pixel de la izquierda
return true;
}
}
}
return false;
}
function uncompress_row_seg(encoder, i, end, bpc, bpc_mask, type, rgb_state, computedAlpha, result, resultData,
channel_r, channel_g, channel_b, buckets_ptrs_r, buckets_ptrs_g, buckets_ptrs_b, correlate_row_r, correlate_row_g,
correlate_row_b, computedWidth, xlatL2U, lzeroes, lzeroes8, lzeroes16, lzeroes24, notGRprefixmask, notGRcwlen,
nGRcodewords, notGRsuffixlen, eatbits, tabrand, decode_run, bppmask, jsquic, tabrand_chaos, rows_completed,
tabrand_seedmask, offset, currentOffset32, usr) {
var stopidx = 0;
var waitmask = bppmask[rgb_state.wmidx];
var run_index = 0;
var rle = false;
//var offset = ((rows_completed-1) * computedWidth);
//var currentOffset32 = ((rows_completed) * computedWidth/4);
var i_1, i_4; //for performance improvments
var pr, pg, pb;
var prevCorrelatedR, prevCorrelatedG, prevCorrelatedB;
var ret, codewordlen, l, bits, zeroprefix;
var cnt = encoder.cnt;
var pxCnt = encoder.pxCnt;
var prev_row, i4sub, stopidx_sub1;
var available_bits, io_word, delta, io_next_word;
if (!i) {
pr = UNCOMPRESS_ONE_0(channel_r, encoder, bpc_mask, offset);
pg = UNCOMPRESS_ONE_0(channel_g, encoder, bpc_mask, offset);
pb = UNCOMPRESS_ONE_0(channel_b, encoder, bpc_mask, offset);
prevCorrelatedR = correlate_row_r[0];
prevCorrelatedG = correlate_row_g[0];
prevCorrelatedB = correlate_row_b[0];
//inlined appendPixel
resultData[pxCnt++] =
255 << 24 | // alpha
pb << 16 | // blue
pg << 8 | // green
pr; // red
//cnt += 4;
if (rgb_state.waitcnt) {
--rgb_state.waitcnt;
} else {
rgb_state.waitcnt = (tabrand.call(jsquic, rgb_state) & waitmask);
UPDATE_MODEL(0, encoder, bpc, correlate_row_r, correlate_row_g, correlate_row_b);
}
stopidx = ++i + rgb_state.waitcnt;
} else {
stopidx = i + rgb_state.waitcnt;
pr = result[cnt - 4];
pg = result[cnt - 3];
pb = result[cnt - 2];
prevCorrelatedR = correlate_row_r[i - 1];
prevCorrelatedG = correlate_row_g[i - 1];
prevCorrelatedB = correlate_row_b[i - 1];
}
while (true) {
while (stopidx < end) {
i_4 = offset + i * 4;
for (; i <= stopidx; i++) {
/////// critical part
//rle = RLE_PRED(i, encoder, ci, currentOffset32, run_index);
//RLE_PRED INLINE
//inlined same_pixel, see original rle_pred
i4sub = i_4 / 4;
if (resultData[i4sub - 1] === resultData[i4sub]) { //fila de arriba
prev_row = currentOffset32 + i - 1;
if (resultData[prev_row - 1] === resultData[prev_row]) { //pixel de la izquierda
if (run_index !== i && i > 2) {
rle = true;
break;
}
}
}
/////////////////////// INLINING UNCOMPRESS_ONE
//r
/////////////////////// INLINING GOLOMB_DECODING
//ret = golomb_decoding(buckets_ptrs_r[prevCorrelatedR].bestcode,
// encoder.io_word, bppmask, notGRprefixmask, notGRcwlen, nGRcodewords, notGRsuffixlen);
l = buckets_ptrs_r[prevCorrelatedR].bestcode;
bits = encoder.io_word;
if (bits > notGRprefixmask[l]) {
//zeroprefix = cnt_l_zeroes(bits);
if (bits > 0x007FFFFF) {
zeroprefix = lzeroes[bits >>> 24];
} else if (bits > 0x00007FFF) {
zeroprefix = lzeroes8[((bits >>> 16) & 0x000000ff)];
} else if (bits > 0x0000007F) {
zeroprefix = lzeroes16[((bits >>> 8) & 0x000000ff)];
} else {
zeroprefix = lzeroes24[(bits & 0x000000ff)];
}
codewordlen = zeroprefix + 1 + l;
prevCorrelatedR = ((zeroprefix << l)) | ((bits >>> (32 - codewordlen)) & bppmask[l]);
} else {
codewordlen = notGRcwlen[l];
prevCorrelatedR = nGRcodewords[l] + ((bits) >>> (32 - codewordlen) & bppmask[notGRsuffixlen[l]]);
}
correlate_row_r[i] = prevCorrelatedR;
pr = ((((xlatL2U[prevCorrelatedR] +
((pr +
result[i_4++]) >>> 1)) & bpc_mask)));
//eatbits(codewordlen, encoder);
//INLINING EATBITS
available_bits = encoder.io_available_bits;
io_word = encoder.io_word;
delta = available_bits - codewordlen;
io_word = io_word << codewordlen;
//enough bits
if (delta >= 0) {
io_word = (io_word | encoder.io_next_word >>> delta) >>> 0;
encoder.io_available_bits = delta;
encoder.io_word = io_word;
} else {
io_next_word = encoder.io_next_word;
//not enough bits
delta = -delta; //bits missing
io_word = (io_word | (io_next_word << delta) >>> 0);
///////////////////
//read io word (inlined for perforemance)
io_next_word = usr[encoder.io_now++];
//end read io_word
/////////////////
available_bits = 32 - delta;
io_word = (io_word | (io_next_word >>> available_bits)) >>> 0;
encoder.io_available_bits = available_bits;
encoder.io_word = io_word;
encoder.io_next_word = io_next_word;
}
//END INLINING
//g
///////////////////////////////////////INLINING golomb_decoding
//ret = golomb_decoding(buckets_ptrs_g[prevCorrelatedG].bestcode,
// encoder.io_word, bppmask, notGRprefixmask, notGRcwlen, nGRcodewords, notGRsuffixlen);
l = buckets_ptrs_g[prevCorrelatedG].bestcode;
bits = encoder.io_word;
if (bits > notGRprefixmask[l]) {
//zeroprefix = cnt_l_zeroes(bits);
if (bits > 0x007FFFFF) {
zeroprefix = lzeroes[bits >>> 24];
} else if (bits > 0x00007FFF) {
zeroprefix = lzeroes8[((bits >>> 16) & 0x000000ff)];
} else if (bits > 0x0000007F) {
zeroprefix = lzeroes16[((bits >>> 8) & 0x000000ff)];
} else {
zeroprefix = lzeroes24[(bits & 0x000000ff)];
}
codewordlen = zeroprefix + 1 + l;
prevCorrelatedG = ((zeroprefix << l)) | ((bits >>> (32 - codewordlen)) & bppmask[l]);
} else {
codewordlen = notGRcwlen[l];
prevCorrelatedG = nGRcodewords[l] + ((bits) >>> (32 - codewordlen) & bppmask[notGRsuffixlen[l]]);
}
correlate_row_g[i] = prevCorrelatedG;
pg = ((((xlatL2U[prevCorrelatedG] +
((pg +
result[i_4++]) >>> 1)) & bpc_mask)));
//INLINING EATBITS
available_bits = encoder.io_available_bits;
io_word = encoder.io_word;
delta = available_bits - codewordlen;
io_word = io_word << codewordlen;
//enough bits
if (delta >= 0) {
io_word = (io_word | encoder.io_next_word >>> delta) >>> 0;
encoder.io_available_bits = delta;
encoder.io_word = io_word;
} else {
io_next_word = encoder.io_next_word;
//not enough bits
delta = -delta; //bits missing
io_word = (io_word | (io_next_word << delta) >>> 0);
///////////////////
//read io word (inlined for perforemance)
io_next_word = usr[encoder.io_now++];
//end read io_word
/////////////////
available_bits = 32 - delta;
io_word = (io_word | (io_next_word >>> available_bits)) >>> 0;
encoder.io_available_bits = available_bits;
encoder.io_word = io_word;
encoder.io_next_word = io_next_word;
}
//END INLINING
//b
////////////////////////////////// INLINING golomb_decoding
//ret = golomb_decoding(buckets_ptrs_b[prevCorrelatedB].bestcode,
// encoder.io_word, bppmask, notGRprefixmask, notGRcwlen, nGRcodewords, notGRsuffixlen);
l = buckets_ptrs_b[prevCorrelatedB].bestcode;
bits = encoder.io_word;
if (bits > notGRprefixmask[l]) {
//zeroprefix = cnt_l_zeroes(bits);
if (bits > 0x007FFFFF) {
zeroprefix = lzeroes[bits >>> 24];
} else if (bits > 0x00007FFF) {
zeroprefix = lzeroes8[((bits >>> 16) & 0x000000ff)];
} else if (bits > 0x0000007F) {
zeroprefix = lzeroes16[((bits >>> 8) & 0x000000ff)];
} else {
zeroprefix = lzeroes24[(bits & 0x000000ff)];
}
codewordlen = zeroprefix + 1 + l;
prevCorrelatedB = ((zeroprefix << l)) | ((bits >>> (32 - codewordlen)) & bppmask[l]);
} else {
codewordlen = notGRcwlen[l];
prevCorrelatedB = nGRcodewords[l] + ((bits) >>> (32 - codewordlen) & bppmask[notGRsuffixlen[l]]);
}
correlate_row_b[i] = prevCorrelatedB;
pb = ((((xlatL2U[prevCorrelatedB] +
((pb +
result[i_4++]) >>> 1)) & bpc_mask)));
//INLINING EATBITS
available_bits = encoder.io_available_bits;
io_word = encoder.io_word;
delta = available_bits - codewordlen;
io_word = io_word << codewordlen;
//enough bits
if (delta >= 0) {
io_word = (io_word | encoder.io_next_word >>> delta) >>> 0;
encoder.io_available_bits = delta;
encoder.io_word = io_word;
} else {
io_next_word = encoder.io_next_word;
//not enough bits
delta = -delta; //bits missing
io_word = (io_word | (io_next_word << delta) >>> 0);
///////////////////
//read io word (inlined for perforemance)
io_next_word = usr[encoder.io_now++];
//end read io_word
/////////////////
available_bits = 32 - delta;
io_word = (io_word | (io_next_word >>> available_bits)) >>> 0;
encoder.io_available_bits = available_bits;
encoder.io_word = io_word;
encoder.io_next_word = io_next_word;
}
//END INLINING
////////////////////// END INLINING
/**
pr = UNCOMPRESS_ONE(channel_r, i, i_1, i_4, bpc_mask, encoder, correlate_row_r, offset, result, 0, xlatL2U, buckets_ptrs_r, pr);
pg = UNCOMPRESS_ONE(channel_g, i, i_1, i_4, bpc_mask, encoder, correlate_row_g, offset, result, 1, xlatL2U, buckets_ptrs_g, pg);
pb = UNCOMPRESS_ONE(channel_b, i, i_1, i_4, bpc_mask, encoder, correlate_row_b, offset, result, 2, xlatL2U, buckets_ptrs_b, pb);
**/
//this is inlined appendPixel
resultData[pxCnt++] =
computedAlpha | // alpha
pb << 16 | // blue
pg << 8 | // green
pr; // red
//cnt += 4;
i_4++; //skip alpha
}
if (!rle) {
//UPDATE_MODEL(stopidx, encoder, bpc, correlate_row_r, correlate_row_g, correlate_row_b);
//inlining update_model
stopidx_sub1 = stopidx - 1;
real_update_model(rgb_state, buckets_ptrs_r[correlate_row_r[stopidx_sub1]],
correlate_row_r[stopidx], bpc);
real_update_model(rgb_state, buckets_ptrs_g[correlate_row_g[stopidx_sub1]],
correlate_row_g[stopidx], bpc);
real_update_model(rgb_state, buckets_ptrs_b[correlate_row_b[stopidx_sub1]],
correlate_row_b[stopidx], bpc);
//end inlining
rgb_state.tabrand_seed++;
stopidx = i + ((tabrand_chaos[rgb_state.tabrand_seed & tabrand_seedmask]) & waitmask);
} else {
break;
}
}
if (!rle) {
i_4 = offset + i * 4;
for (; i < end; i++) {
//ci = offset32+i;
//rle = RLE_PRED(i, encoder, ci, currentOffset32, run_index);
//RLE_PRED INLINE
//inlined same_pixel, see original rle_pred
i4sub = i_4 / 4;
if (resultData[i4sub - 1] === resultData[i4sub]) { //fila de arriba
prev_row = currentOffset32 + i - 1;
if (resultData[prev_row - 1] === resultData[prev_row]) { //pixel de la izquierda
if (run_index !== i && i > 2) {
rle = true;
break;
}
}
}
//END INLINE*/
////////////////////// INLINING UNCOMPRESS_ONE
//r
//ret = golomb_decoding(buckets_ptrs_r[prevCorrelatedR].bestcode, encoder.io_word, bppmask, notGRprefixmask, notGRcwlen, nGRcodewords, notGRsuffixlen);
//prevCorrelatedR = ret[0];
//codewordlen = ret[1];
l = buckets_ptrs_r[prevCorrelatedR].bestcode;
bits = encoder.io_word;
if (bits > notGRprefixmask[l]) {
//zeroprefix = cnt_l_zeroes(bits);
if (bits > 0x007FFFFF) {
zeroprefix = lzeroes[bits >>> 24];
} else if (bits > 0x00007FFF) {
zeroprefix = lzeroes8[((bits >>> 16) & 0x000000ff)];
} else if (bits > 0x0000007F) {
zeroprefix = lzeroes16[((bits >>> 8) & 0x000000ff)];
} else {
zeroprefix = lzeroes24[(bits & 0x000000ff)];
}
codewordlen = zeroprefix + 1 + l;
prevCorrelatedR = ((zeroprefix << l)) | ((bits >>> (32 - codewordlen)) & bppmask[l]);
} else {
codewordlen = notGRcwlen[l];
prevCorrelatedR = nGRcodewords[l] + ((bits) >>> (32 - codewordlen) & bppmask[notGRsuffixlen[l]]);
}
correlate_row_r[i] = prevCorrelatedR;
pr = ((((xlatL2U[prevCorrelatedR] +
((pr +
result[i_4++]) >>> 1)) & bpc_mask)));
//INLINING EATBITS
available_bits = encoder.io_available_bits;
io_word = encoder.io_word;
delta = available_bits - codewordlen;
io_word = io_word << codewordlen;
//enough bits
if (delta >= 0) {
io_word = (io_word | encoder.io_next_word >>> delta) >>> 0;
encoder.io_available_bits = delta;
encoder.io_word = io_word;
} else {
io_next_word = encoder.io_next_word;
//not enough bits
delta = -delta; //bits missing
io_word = (io_word | (io_next_word << delta) >>> 0);
///////////////////
//read io word (inlined for perforemance)
io_next_word = usr[encoder.io_now++];
//end read io_word
/////////////////
available_bits = 32 - delta;
io_word = (io_word | (io_next_word >>> available_bits)) >>> 0;
encoder.io_available_bits = available_bits;
encoder.io_word = io_word;
encoder.io_next_word = io_next_word;
}
//END INLINING
//g
// ret = golomb_decoding(buckets_ptrs_g[prevCorrelatedG].bestcode, encoder.io_word, bppmask, notGRprefixmask, notGRcwlen, nGRcodewords, notGRsuffixlen);
// prevCorrelatedG = ret[0];
// codewordlen = ret[1];
l = buckets_ptrs_g[prevCorrelatedG].bestcode;
bits = encoder.io_word;
if (bits > notGRprefixmask[l]) {
//zeroprefix = cnt_l_zeroes(bits);
if (bits > 0x007FFFFF) {
zeroprefix = lzeroes[bits >>> 24];
} else if (bits > 0x00007FFF) {
zeroprefix = lzeroes8[((bits >>> 16) & 0x000000ff)];
} else if (bits > 0x0000007F) {
zeroprefix = lzeroes16[((bits >>> 8) & 0x000000ff)];
} else {
zeroprefix = lzeroes24[(bits & 0x000000ff)];
}
codewordlen = zeroprefix + 1 + l;
prevCorrelatedG = ((zeroprefix << l)) | ((bits >>> (32 - codewordlen)) & bppmask[l]);
} else {
codewordlen = notGRcwlen[l];
prevCorrelatedG = nGRcodewords[l] + ((bits) >>> (32 - codewordlen) & bppmask[notGRsuffixlen[l]]);
}
correlate_row_g[i] = prevCorrelatedG;
pg = ((((xlatL2U[prevCorrelatedG] +
((pg +
result[i_4++]) >>> 1)) & bpc_mask)));
//INLINING EATBITS
available_bits = encoder.io_available_bits;
io_word = encoder.io_word;
delta = available_bits - codewordlen;
io_word = io_word << codewordlen;
//enough bits
if (delta >= 0) {
io_word = (io_word | encoder.io_next_word >>> delta) >>> 0;
encoder.io_available_bits = delta;
encoder.io_word = io_word;
} else {
io_next_word = encoder.io_next_word;
//not enough bits
delta = -delta; //bits missing
io_word = (io_word | (io_next_word << delta) >>> 0);
///////////////////
//read io word (inlined for perforemance)
io_next_word = usr[encoder.io_now++];
//end read io_word
/////////////////
available_bits = 32 - delta;
io_word = (io_word | (io_next_word >>> available_bits)) >>> 0;
encoder.io_available_bits = available_bits;
encoder.io_word = io_word;
encoder.io_next_word = io_next_word;
}
//END INLINING
//b
// ret = golomb_decoding(buckets_ptrs_b[prevCorrelatedB].bestcode, encoder.io_word, bppmask, notGRprefixmask, notGRcwlen, nGRcodewords, notGRsuffixlen);
// prevCorrelatedB = ret[0];
// codewordlen = ret[1];
//
l = buckets_ptrs_b[prevCorrelatedB].bestcode;
bits = encoder.io_word;
if (bits > notGRprefixmask[l]) {
//zeroprefix = cnt_l_zeroes(bits);
if (bits > 0x007FFFFF) {
zeroprefix = lzeroes[bits >>> 24];
} else if (bits > 0x00007FFF) {
zeroprefix = lzeroes8[((bits >>> 16) & 0x000000ff)];
} else if (bits > 0x0000007F) {
zeroprefix = lzeroes16[((bits >>> 8) & 0x000000ff)];
} else {
zeroprefix = lzeroes24[(bits & 0x000000ff)];
}
codewordlen = zeroprefix + 1 + l;
prevCorrelatedB = ((zeroprefix << l)) | ((bits >>> (32 - codewordlen)) & bppmask[l]);
} else {
codewordlen = notGRcwlen[l];
prevCorrelatedB = nGRcodewords[l] + ((bits) >>> (32 - codewordlen) & bppmask[notGRsuffixlen[l]]);
}
correlate_row_b[i] = prevCorrelatedB;
pb = ((((xlatL2U[prevCorrelatedB] +
((pb +
result[i_4++]) >>> 1)) & bpc_mask)));
//INLINING EATBITS
available_bits = encoder.io_available_bits;
io_word = encoder.io_word;
delta = available_bits - codewordlen;
io_word = io_word << codewordlen;
//enough bits
if (delta >= 0) {
io_word = (io_word | encoder.io_next_word >>> delta) >>> 0;
encoder.io_available_bits = delta;
encoder.io_word = io_word;
} else {
io_next_word = encoder.io_next_word;
//not enough bits
delta = -delta; //bits missing
io_word = (io_word | (io_next_word << delta) >>> 0);
///////////////////
//read io word (inlined for perforemance)
io_next_word = usr[encoder.io_now++];
//end read io_word
/////////////////
available_bits = 32 - delta;
io_word = (io_word | (io_next_word >>> available_bits)) >>> 0;
encoder.io_available_bits = available_bits;
encoder.io_word = io_word;
encoder.io_next_word = io_next_word;
}
//END INLINING
///////////////////// END INLINING
/**
pr = UNCOMPRESS_ONE(channel_r, i, i_1, i_4, bpc_mask, encoder, correlate_row_r, offset, result, 0, xlatL2U, buckets_ptrs_r, pr);
pg = UNCOMPRESS_ONE(channel_g, i, i_1, i_4, bpc_mask, encoder, correlate_row_g, offset, result, 1, xlatL2U, buckets_ptrs_g, pg);
pb = UNCOMPRESS_ONE(channel_b, i, i_1, i_4, bpc_mask, encoder, correlate_row_b, offset, result, 2, xlatL2U, buckets_ptrs_b, pb);
**/
//this is inlined apendPixel
resultData[pxCnt++] =
(255 << 24) | // alpha
(pb << 16) | // blue
(pg << 8) | // green
pr; // red
//cnt += 4;
i_4++;
}
if (!rle) {
rgb_state.waitcnt = stopidx - end;
encoder.cnt = pxCnt * 4;
encoder.pxCnt = pxCnt;
return;
}
}
///END of critical part
//RLE
rgb_state.waitcnt = stopidx - i;
run_index = i;
run_end = decode_run(encoder);
i = run_end + i;
while (run_end-- > 0) {
//this is inlined appendPixel
resultData[pxCnt++] =
computedAlpha | // alpha
pb << 16 | // blue
pg << 8 | // green
pr; // red
//cnt += 4;
}
if (i === end) {
encoder.cnt = pxCnt * 4;
encoder.pxCnt = pxCnt;
return;
}
i_1 = i - 1;
prevCorrelatedR = correlate_row_r[i_1];
prevCorrelatedG = correlate_row_g[i_1];
prevCorrelatedB = correlate_row_b[i_1];
stopidx = i + rgb_state.waitcnt;
rle = false;
//END RLE
}
}
function uncompress_row_seg_a(encoder, i, end, bpc, bpc_mask, type, rgb_state) {
var channel_r = encoder.channels[0];
var channel_g = encoder.channels[1];
var channel_b = encoder.channels[2];
var buckets_ptrs_r = channel_r._buckets_ptrs;
var buckets_ptrs_g = channel_g._buckets_ptrs;
var buckets_ptrs_b = channel_b._buckets_ptrs;
var correlate_row_r = channel_r.correlate_row;
var correlate_row_g = channel_g.correlate_row;
var correlate_row_b = channel_b.correlate_row;
var stopidx = 0;
var waitmask = wdi.JSQuic.bppmask[rgb_state.wmidx];
var run_index = 0;
var run_end = 0;
var rle = false;
var computedWidth = encoder.computedWidth;
var offset = ((encoder.rows_completed - 1) * computedWidth);
var currentOffset = ((encoder.rows_completed) * computedWidth);
var offset32 = ((encoder.rows_completed - 1) * computedWidth / 4);
var currentOffset32 = ((encoder.rows_completed) * computedWidth / 4);
var result = encoder.result;
var resultData = encoder.resultData;
var i_1, i_4; //for performance improvments
var xlatL2U = wdi.xlatL2U;
var pr, pg, pb;
var prevCorrelatedR, prevCorrelatedG, prevCorrelatedB;
var eatbits = encoder.eatbits;
var tabrand = wdi.JSQuic.tabrand;
var decode_run = wdi.JSQuic.decode_run;
var ret, codewordlen, l, bits, zeroprefix;
var lzeroes = wdi.JSQuic.lzeroes;
var lzeroes8 = wdi.JSQuic.lzeroes8;
var lzeroes16 = wdi.JSQuic.lzeroes16;
var lzeroes24 = wdi.JSQuic.lzeroes24;
var cnt = encoder.cnt;
var pxCnt = encoder.pxCnt;
var bppmask = wdi.JSQuic.bppmask;
var notGRprefixmask = wdi.notGRprefixmask;
var notGRcwlen = wdi.notGRcwlen;
var nGRcodewords = wdi.nGRcodewords;
var notGRsuffixlen = wdi.notGRsuffixlen;
var prev_row, i4sub, ci;
var computedAlpha = 255 << 24;
if (!i) {
pr = UNCOMPRESS_ONE_0(channel_r, encoder, bpc_mask, offset);
pg = UNCOMPRESS_ONE_0(channel_g, encoder, bpc_mask, offset);
pb = UNCOMPRESS_ONE_0(channel_b, encoder, bpc_mask, offset);
prevCorrelatedR = correlate_row_r[0];
prevCorrelatedG = correlate_row_g[0];
prevCorrelatedB = correlate_row_b[0];
//inlined appendPixel
resultData[pxCnt++] =
(255 << 24) | // alpha
(pb << 16) | // blue
(pg << 8) | // green
pr; // red
//cnt += 4;
if (rgb_state.waitcnt) {
--rgb_state.waitcnt;
} else {
rgb_state.waitcnt = (tabrand.call(wdi.JSQuic, rgb_state) & waitmask);
UPDATE_MODEL(0, encoder, bpc, correlate_row_r, correlate_row_g, correlate_row_b);
}
stopidx = ++i + rgb_state.waitcnt;
} else {
stopidx = i + rgb_state.waitcnt;
pr = result[cnt - 4];
pg = result[cnt - 3];
pb = result[cnt - 2];
prevCorrelatedR = correlate_row_r[i - 1];
prevCorrelatedG = correlate_row_g[i - 1];
prevCorrelatedB = correlate_row_b[i - 1];
}
while (true) {
while (stopidx < end) {
i_4 = offset + i * 4;
for (; i <= stopidx; i++) {
/////// critical part
rle = RLE_PRED_RGB_A(i, encoder, i_4, currentOffset, run_index);
//RLE_PRED INLINE
/*if(run_index !== i && i > 2) {
//inlined same_pixel, see original rle_pred
i4sub = i_4/4;
if(encoder.resultData[i4sub-1] === encoder.resultData[i4sub]) { //fila de arriba
var prev_row = currentOffset32 + i-1;
if(encoder.resultData[prev_row-1] === encoder.resultData[prev_row]) { //pixel de la izquierda
rle = true;
}
}
}*/
//END INLINE
if (rle) break;
/////////////////////// INLINING UNCOMPRESS_ONE
//r
/////////////////////// INLINING GOLOMB_DECODING
//ret = golomb_decoding(buckets_ptrs_r[prevCorrelatedR].bestcode,
// encoder.io_word, bppmask, notGRprefixmask, notGRcwlen, nGRcodewords, notGRsuffixlen);
l = buckets_ptrs_r[prevCorrelatedR].bestcode;
bits = encoder.io_word;
if (bits > notGRprefixmask[l]) {
zeroprefix = cnt_l_zeroes(bits);
/*
if (bits > 0x007FFFFF) {
zeroprefix = lzeroes[bits >>> 24];
} else if (bits > 0x00007FFF) {
zeroprefix = lzeroes8[((bits >>> 16) & 0x000000ff)];
} else if (bits > 0x0000007F) {
zeroprefix = lzeroes16[((bits >>> 8) & 0x000000ff) ];
} else {
zeroprefix = lzeroes24[(bits & 0x000000ff) ];
}*/
codewordlen = zeroprefix + 1 + l;
prevCorrelatedR = ((zeroprefix << l)) | ((bits >>> (32 - codewordlen)) & bppmask[l]);
} else {
codewordlen = notGRcwlen[l];
prevCorrelatedR = nGRcodewords[l] + ((bits) >>> (32 - codewordlen) & bppmask[notGRsuffixlen[l]]);
}
correlate_row_r[i] = prevCorrelatedR;
pr = ((((xlatL2U[prevCorrelatedR] +
((pr +
result[i_4++]) >>> 1)) & bpc_mask)));
eatbits(codewordlen, encoder);
//g
///////////////////////////////////////INLINING golomb_decoding
//ret = golomb_decoding(buckets_ptrs_g[prevCorrelatedG].bestcode,
// encoder.io_word, bppmask, notGRprefixmask, notGRcwlen, nGRcodewords, notGRsuffixlen);
l = buckets_ptrs_g[prevCorrelatedG].bestcode;
bits = encoder.io_word;
if (bits > notGRprefixmask[l]) {
zeroprefix = cnt_l_zeroes(bits);
/*
if (bits > 0x007FFFFF) {
zeroprefix = lzeroes[bits >>> 24];
} else if (bits > 0x00007FFF) {
zeroprefix = lzeroes8[((bits >>> 16) & 0x000000ff)];
} else if (bits > 0x0000007F) {
zeroprefix = lzeroes16[((bits >>> 8) & 0x000000ff) ];
} else {
zeroprefix = lzeroes24[(bits & 0x000000ff) ];
}*/
codewordlen = zeroprefix + 1 + l;
prevCorrelatedG = ((zeroprefix << l)) | ((bits >>> (32 - codewordlen)) & bppmask[l]);
} else {
codewordlen = notGRcwlen[l];
prevCorrelatedG = nGRcodewords[l] + ((bits) >>> (32 - codewordlen) & bppmask[notGRsuffixlen[l]]);
}
correlate_row_g[i] = prevCorrelatedG;
pg = ((((xlatL2U[prevCorrelatedG] +
((pg +
result[i_4++]) >>> 1)) & bpc_mask)));
eatbits(codewordlen, encoder);
//b
////////////////////////////////// INLINING golomb_decoding
//ret = golomb_decoding(buckets_ptrs_b[prevCorrelatedB].bestcode,
// encoder.io_word, bppmask, notGRprefixmask, notGRcwlen, nGRcodewords, notGRsuffixlen);
l = buckets_ptrs_b[prevCorrelatedB].bestcode;
bits = encoder.io_word;
if (bits > notGRprefixmask[l]) {
zeroprefix = cnt_l_zeroes(bits);
/*
if (bits > 0x007FFFFF) {
zeroprefix = lzeroes[bits >>> 24];
} else if (bits > 0x00007FFF) {
zeroprefix = lzeroes8[((bits >>> 16) & 0x000000ff)];
} else if (bits > 0x0000007F) {
zeroprefix = lzeroes16[((bits >>> 8) & 0x000000ff) ];
} else {
zeroprefix = lzeroes24[(bits & 0x000000ff) ];
}*/
codewordlen = zeroprefix + 1 + l;
prevCorrelatedB = ((zeroprefix << l)) | ((bits >>> (32 - codewordlen)) & bppmask[l]);
} else {
codewordlen = notGRcwlen[l];
prevCorrelatedB = nGRcodewords[l] + ((bits) >>> (32 - codewordlen) & bppmask[notGRsuffixlen[l]]);
}
correlate_row_b[i] = prevCorrelatedB;
pb = ((((xlatL2U[prevCorrelatedB] +
((pb +
result[i_4++]) >>> 1)) & bpc_mask)));
eatbits(codewordlen, encoder);
////////////////////// END INLINING
/**
pr = UNCOMPRESS_ONE(channel_r, i, i_1, i_4, bpc_mask, encoder, correlate_row_r, offset, result, 0, xlatL2U, buckets_ptrs_r, pr);
pg = UNCOMPRESS_ONE(channel_g, i, i_1, i_4, bpc_mask, encoder, correlate_row_g, offset, result, 1, xlatL2U, buckets_ptrs_g, pg);
pb = UNCOMPRESS_ONE(channel_b, i, i_1, i_4, bpc_mask, encoder, correlate_row_b, offset, result, 2, xlatL2U, buckets_ptrs_b, pb);
**/
//this is inlined appendPixel
resultData[pxCnt++] =
computedAlpha | // alpha
pb << 16 | // blue
pg << 8 | // green
pr; // red
//cnt += 4;
i_4++; //skip alpha
}
if (!rle) {
UPDATE_MODEL(stopidx, encoder, bpc, correlate_row_r, correlate_row_g, correlate_row_b);
stopidx = i + (tabrand.call(wdi.JSQuic, rgb_state) & waitmask);
} else {
break;
}
}
if (!rle) {
i_4 = offset + i * 4;
for (; i < end; i++) {
rle = RLE_PRED_RGB_A(i, encoder, i_4, currentOffset, run_index);
//RLE_PRED INLINE
/*if(run_index !== i && i > 2) {
//inlined same_pixel, see original rle_pred
i4sub = i_4/4;
if(encoder.resultData[i4sub-1] === encoder.resultData[i4sub]) { //fila de arriba
var prev_row = currentOffset32 + i-1;
if(encoder.resultData[prev_row-1] === encoder.resultData[prev_row]) { //pixel de la izquierda
rle = true;
}
}
}
//END INLINE*/
if (rle) break;
////////////////////// INLINING UNCOMPRESS_ONE
//r
//ret = golomb_decoding(buckets_ptrs_r[prevCorrelatedR].bestcode, encoder.io_word, bppmask, notGRprefixmask, notGRcwlen, nGRcodewords, notGRsuffixlen);
//prevCorrelatedR = ret[0];
//codewordlen = ret[1];
l = buckets_ptrs_r[prevCorrelatedR].bestcode;
bits = encoder.io_word;
if (bits > notGRprefixmask[l]) {
zeroprefix = cnt_l_zeroes(bits);
/*
if (bits > 0x007FFFFF) {
zeroprefix = lzeroes[bits >>> 24];
} else if (bits > 0x00007FFF) {
zeroprefix = lzeroes8[((bits >>> 16) & 0x000000ff)];
} else if (bits > 0x0000007F) {
zeroprefix = lzeroes16[((bits >>> 8) & 0x000000ff) ];
} else {
zeroprefix = lzeroes24[(bits & 0x000000ff) ];
}*/
codewordlen = zeroprefix + 1 + l;
prevCorrelatedR = ((zeroprefix << l)) | ((bits >>> (32 - codewordlen)) & bppmask[l]);
} else {
codewordlen = notGRcwlen[l];
prevCorrelatedR = nGRcodewords[l] + ((bits) >>> (32 - codewordlen) & bppmask[notGRsuffixlen[l]]);
}
correlate_row_r[i] = prevCorrelatedR;
pr = ((((xlatL2U[prevCorrelatedR] +
((pr +
result[i_4++]) >>> 1)) & bpc_mask)));
eatbits(codewordlen, encoder);
//g
// ret = golomb_decoding(buckets_ptrs_g[prevCorrelatedG].bestcode, encoder.io_word, bppmask, notGRprefixmask, notGRcwlen, nGRcodewords, notGRsuffixlen);
// prevCorrelatedG = ret[0];
// codewordlen = ret[1];
l = buckets_ptrs_g[prevCorrelatedG].bestcode;
bits = encoder.io_word;
if (bits > notGRprefixmask[l]) {
zeroprefix = cnt_l_zeroes(bits);
/*
if (bits > 0x007FFFFF) {
zeroprefix = lzeroes[bits >>> 24];
} else if (bits > 0x00007FFF) {
zeroprefix = lzeroes8[((bits >>> 16) & 0x000000ff)];
} else if (bits > 0x0000007F) {
zeroprefix = lzeroes16[((bits >>> 8) & 0x000000ff) ];
} else {
zeroprefix = lzeroes24[(bits & 0x000000ff) ];
}*/
codewordlen = zeroprefix + 1 + l;
prevCorrelatedG = ((zeroprefix << l)) | ((bits >>> (32 - codewordlen)) & bppmask[l]);
} else {
codewordlen = notGRcwlen[l];
prevCorrelatedG = nGRcodewords[l] + ((bits) >>> (32 - codewordlen) & bppmask[notGRsuffixlen[l]]);
}
correlate_row_g[i] = prevCorrelatedG;
pg = ((((xlatL2U[prevCorrelatedG] +
((pg +
result[i_4++]) >>> 1)) & bpc_mask)));
eatbits(codewordlen, encoder);
//b
// ret = golomb_decoding(buckets_ptrs_b[prevCorrelatedB].bestcode, encoder.io_word, bppmask, notGRprefixmask, notGRcwlen, nGRcodewords, notGRsuffixlen);
// prevCorrelatedB = ret[0];
// codewordlen = ret[1];
//
l = buckets_ptrs_b[prevCorrelatedB].bestcode;
bits = encoder.io_word;
if (bits > notGRprefixmask[l]) {
zeroprefix = cnt_l_zeroes(bits);
/*
if (bits > 0x007FFFFF) {
zeroprefix = lzeroes[bits >>> 24];
} else if (bits > 0x00007FFF) {
zeroprefix = lzeroes8[((bits >>> 16) & 0x000000ff)];
} else if (bits > 0x0000007F) {
zeroprefix = lzeroes16[((bits >>> 8) & 0x000000ff) ];
} else {
zeroprefix = lzeroes24[(bits & 0x000000ff) ];
}*/
codewordlen = zeroprefix + 1 + l;
prevCorrelatedB = ((zeroprefix << l)) | ((bits >>> (32 - codewordlen)) & bppmask[l]);
} else {
codewordlen = notGRcwlen[l];
prevCorrelatedB = nGRcodewords[l] + ((bits) >>> (32 - codewordlen) & bppmask[notGRsuffixlen[l]]);
}
correlate_row_b[i] = prevCorrelatedB;
pb = ((((xlatL2U[prevCorrelatedB] +
((pb +
result[i_4++]) >>> 1)) & bpc_mask)));
eatbits(codewordlen, encoder);
///////////////////// END INLINING
/**
pr = UNCOMPRESS_ONE(channel_r, i, i_1, i_4, bpc_mask, encoder, correlate_row_r, offset, result, 0, xlatL2U, buckets_ptrs_r, pr);
pg = UNCOMPRESS_ONE(channel_g, i, i_1, i_4, bpc_mask, encoder, correlate_row_g, offset, result, 1, xlatL2U, buckets_ptrs_g, pg);
pb = UNCOMPRESS_ONE(channel_b, i, i_1, i_4, bpc_mask, encoder, correlate_row_b, offset, result, 2, xlatL2U, buckets_ptrs_b, pb);
**/
//this is inlined apendPixel
resultData[pxCnt++] =
(255 << 24) | // alpha
(pb << 16) | // blue
(pg << 8) | // green
pr; // red
//cnt += 4;
i_4++;
}
if (!rle) {
rgb_state.waitcnt = stopidx - end;
encoder.cnt = pxCnt * 4;
encoder.pxCnt = pxCnt;
return;
}
}
///END of critical part
//RLE
rgb_state.waitcnt = stopidx - i;
run_index = i;
run_end = decode_run(encoder);
i = run_end + i;
while (run_end-- > 0) {
//this is inlined appendPixel
resultData[pxCnt++] =
computedAlpha | // alpha
pb << 16 | // blue
pg << 8 | // green
pr; // red
//cnt += 4;
}
if (i === end) {
encoder.cnt = pxCnt * 4;
encoder.pxCnt = pxCnt;
return;
}
i_1 = i - 1;
prevCorrelatedR = correlate_row_r[i_1];
prevCorrelatedG = correlate_row_g[i_1];
prevCorrelatedB = correlate_row_b[i_1];
stopidx = i + rgb_state.waitcnt;
rle = false;
//END RLE
}
}
function quic_uncompress_row0(encoder, channels, bpc, type) {
var bpc_mask = wdi.JSQuic.BPC_MASK[type];
var pos = 0;
var width = encoder.width;
while ((wdi.JSQuic.wmimax > encoder.rgb_state.wmidx) && (encoder.rgb_state.wmileft <= width)) {
if (encoder.rgb_state.wmileft) {
uncompress_row0_seg(
encoder,
pos,
pos + encoder.rgb_state.wmileft,
wdi.JSQuic.bppmask[encoder.rgb_state.wmidx],
bpc,
bpc_mask,
type
);
pos += encoder.rgb_state.wmileft;
width -= encoder.rgb_state.wmileft;
}
encoder.rgb_state.wmidx++;
wdi.JSQuic.set_wm_trigger(encoder.rgb_state);
encoder.rgb_state.wmileft = wdi.JSQuic.wminext;
}
if (width) {
uncompress_row0_seg(
encoder,
pos,
pos + width,
wdi.JSQuic.bppmask[encoder.rgb_state.wmidx],
bpc,
bpc_mask,
type
);
if (wdi.JSQuic.wmimax > encoder.rgb_state.wmidx) {
encoder.rgb_state.wmileft -= width;
}
}
}
function uncompress_row0_seg(encoder, i, end, waitmask, bpc, bpc_mask, type) {
var channel_r = encoder.channels[0];
var channel_g = encoder.channels[1];
var channel_b = encoder.channels[2];
var correlate_row_r = channel_r.correlate_row;
var correlate_row_g = channel_g.correlate_row;
var correlate_row_b = channel_b.correlate_row;
var stopidx = 0;
var pr, pg, pb;
if (!i) {
pr = UNCOMPRESS_ONE_ROW0_0(channel_r);
pg = UNCOMPRESS_ONE_ROW0_0(channel_g);
pb = UNCOMPRESS_ONE_ROW0_0(channel_b);
encoder.appendPixel(pr, pg, pb);
if (encoder.rgb_state.waitcnt) {
--encoder.rgb_state.waitcnt;
} else {
encoder.rgb_state.waitcnt = (wdi.JSQuic.tabrand(encoder.rgb_state) & waitmask);
UPDATE_MODEL(0, encoder, bpc, correlate_row_r, correlate_row_g, correlate_row_b);
}
stopidx = ++i + encoder.rgb_state.waitcnt;
} else {
stopidx = i + encoder.rgb_state.waitcnt;
}
while (stopidx < end) {
for (; i <= stopidx; i++) {
pr = UNCOMPRESS_ONE_ROW0(channel_r, i, bpc_mask, encoder, correlate_row_r, pr);
pg = UNCOMPRESS_ONE_ROW0(channel_g, i, bpc_mask, encoder, correlate_row_g, pg);
pb = UNCOMPRESS_ONE_ROW0(channel_b, i, bpc_mask, encoder, correlate_row_b, pb);
encoder.appendPixel(pr, pg, pb);
}
UPDATE_MODEL(stopidx, encoder, bpc, correlate_row_r, correlate_row_g, correlate_row_b);
stopidx = i + (wdi.JSQuic.tabrand(encoder.rgb_state) & waitmask);
}
for (; i < end; i++) {
pr = UNCOMPRESS_ONE_ROW0(channel_r, i, bpc_mask, encoder, correlate_row_r, pr);
pg = UNCOMPRESS_ONE_ROW0(channel_g, i, bpc_mask, encoder, correlate_row_g, pg);
pb = UNCOMPRESS_ONE_ROW0(channel_b, i, bpc_mask, encoder, correlate_row_b, pb);
encoder.appendPixel(pr, pg, pb);
}
encoder.rgb_state.waitcnt = stopidx - end;
}
function UNCOMPRESS_ONE_0(channel, encoder, bpc_mask, offset) {
var ret, codewordlen;
channel.oldFirst = channel.correlate_row[0];
ret = golomb_decoding(find_bucket(channel,
channel.correlate_row[0]).bestcode, encoder.io_word, wdi.JSQuic.bppmask, wdi.notGRprefixmask, wdi.notGRcwlen, wdi.nGRcodewords, wdi.notGRsuffixlen);
channel.correlate_row[0] = ret[0];
codewordlen = ret[1];
var residuum = wdi.xlatL2U[channel.correlate_row[0]];
var prev = encoder.result[offset + channel.num_channel]; //PIXEL_B
var resultpixel = ((residuum + prev) & bpc_mask);
encoder.eatbits(codewordlen, encoder);
return resultpixel;
}
function UNCOMPRESS_ONE(channel, i, i_1, i_4, bpc_mask, encoder, correlate_row, offset, result, num_channel, xlatL2U, buckets_ptrs, prev_pixel) {
var ret, codewordlen;
ret = golomb_decoding(buckets_ptrs[correlate_row[i_1]].bestcode, encoder.io_word, wdi.JSQuic.bppmask, wdi.notGRprefixmask, wdi.notGRcwlen, wdi.nGRcodewords, wdi.notGRsuffixlen);
var data = ret[0];
codewordlen = ret[1];
correlate_row[i] = data;
var ret = ((((xlatL2U[data] +
((prev_pixel +
result[offset + (i_4) + num_channel]) >>> 1)) & bpc_mask)));
encoder.eatbits(codewordlen, encoder);
return ret;
}
function UNCOMPRESS_ONE_ROW0_0(channel) {
var ret, codewordlen;
var encoder = channel.encoder;
ret = golomb_decoding(find_bucket(channel, 0).bestcode, encoder.io_word, wdi.JSQuic.bppmask, wdi.notGRprefixmask, wdi.notGRcwlen, wdi.nGRcodewords, wdi.notGRsuffixlen);
channel.correlate_row[0] = ret[0]
codewordlen = ret[1];
var ret = wdi.xlatL2U[channel.correlate_row[0]];
encoder.eatbits(codewordlen, encoder);
return ret;
}
function UNCOMPRESS_ONE_ROW0(channel, i, bpc_mask, encoder, correlate_row, prev_pixel) {
var ret, codewordlen;
ret = golomb_decoding(find_bucket(channel, correlate_row[i - 1]).bestcode, encoder.io_word, wdi.JSQuic.bppmask, wdi.notGRprefixmask, wdi.notGRcwlen, wdi.nGRcodewords, wdi.notGRsuffixlen);
correlate_row[i] = ret[0];
codewordlen = ret[1];
var ret = CORELATE_0(encoder, channel, i, bpc_mask, correlate_row, prev_pixel);
encoder.eatbits(codewordlen, encoder);
return ret;
}
function CORELATE_0(encoder, channel, curr, bpc_mask, correlate_row, prev_pixel) {
return ((wdi.xlatL2U[correlate_row[curr]] + prev_pixel) & bpc_mask);
}
function PIXEL_A(encoder) {
return encoder.result[encoder.cnt - 4];
}
function PIXEL_B(channel, encoder, pos, offset) {
return encoder.result[offset + (pos * 4) + channel.num_channel];
}
///////////////////////////////////////////////////////////////////
//LZ
var lzDecompress = {
LZ_IMAGE_TYPE_INVALID: 0,
LZ_IMAGE_TYPE_PLT1_LE: 1,
LZ_IMAGE_TYPE_PLT1_BE: 2,
LZ_IMAGE_TYPE_PLT4_LE: 3,
LZ_IMAGE_TYPE_PLT4_BE: 4,
LZ_IMAGE_TYPE_PLT8: 5,
LZ_IMAGE_TYPE_RGB16: 6,
LZ_IMAGE_TYPE_RGB24: 7,
LZ_IMAGE_TYPE_RGB32: 8,
LZ_IMAGE_TYPE_RGBA: 9,
LZ_IMAGE_TYPE_XXXA: 10,
LZPALETTE_FLAG_PAL_CACHE_ME: 1,
LZPALETTE_FLAG_PAL_FROM_CACHE: 2,
LZPALETTE_FLAG_TOP_DOWN: 4,
PLT_PIXELS_PER_BYTE: [0, 8, 8, 2, 2, 1],
PLT1_MASK: [1, 2, 4, 8, 16, 32, 64, 128],
lz_rgb32_decompress_rgb_opaque_reverse: function(arr) {
//TODO: global alpha and uncouple code
var in_buf = new Uint8Array(arr);
var type = in_buf[2];
var low = in_buf[5] * 256 + in_buf[4]; // 256 = Math.pow(16, 2)
var high = in_buf[7] * 256 + in_buf[6]; // 256 = Math.pow(16, 2)
var len = high * 65536 + low; // 65536 = Math.pow(16,4)
var buf = new ArrayBuffer(len);
var data = new Uint32Array(buf);
var view = new DataView(arr);
var width = view.getUint32(8);
var height = view.getUint32(12);
var out_buf_len = len / 4 -1;
var op = out_buf_len;
var code, ref, ofs, b;
var aux;
var ctrl = in_buf[16];
var encoder = 16; //padding
while (op >= 0) {
ctrl = in_buf[encoder++];
//if ctrl is 0, there is no way for len to be > 0
if (ctrl != 0 && (len = ctrl >> 5)!=0) { //>=32
ref = op; //there is a reference to past bytes, the reference will be
//provided as an offset to our position
ofs = (ctrl & 31) << 8; //get the last 5 bits from ctrl
if (len == 7) {
do {
code = in_buf[encoder++];
len += code;
} while (code == 255);
}
ofs += in_buf[encoder++];
if (ofs == 0) {
aux = data[ref+1]; //if osset is 0...it means just the prior pixel copied over and over....
//in reverse mode, the prior pixel is just the next pixel to the right
while(len > 9) {
data[op] = aux;
data[op-1] = aux;
data[op-2] = aux;
data[op-3] = aux;
data[op-4] = aux;
data[op-5] = aux;
data[op-6] = aux;
data[op-7] = aux;
data[op-8] = aux;
data[op-9] = aux;
op-=10;
len -= 10;
}
while (len-- != 0) {
data[op--] = aux;
}
} else {
if (ofs == 8191) { //check if all the bits in ofs are 1, then get two more bytes
ofs += (in_buf[encoder] << 8) + in_buf[encoder+1];
encoder += 2;
}
ref += ofs + 1;
while(len > 9) {
data[op] = data[ref];
data[op-1] = data[ref-1];
data[op-2] = data[ref-2];
data[op-3] = data[ref-3];
data[op-4] = data[ref-4];
data[op-5] = data[ref-5];
data[op-6] = data[ref-6];
data[op-7] = data[ref-7];
data[op-8] = data[ref-8];
data[op-9] = data[ref-9];
op-=10;
len -= 10;
ref -= 10;
}
while (len-- !== 0) {
data[op--] = data[ref--];
}
}
} else {
while(ctrl > 9) {
data[op] = 4278190080 | in_buf[encoder] << 16 | in_buf[encoder+1] << 8 | in_buf[encoder+2];
data[op-1] = 4278190080 | in_buf[encoder+3] << 16 | in_buf[encoder+4] << 8 | in_buf[encoder+5];
data[op-2] = 4278190080 | in_buf[encoder+6] << 16 | in_buf[encoder+7] << 8 | in_buf[encoder+8];
data[op-3] = 4278190080 | in_buf[encoder+9] << 16 | in_buf[encoder+10] << 8 | in_buf[encoder+11];
data[op-4] = 4278190080 | in_buf[encoder+12] << 16 | in_buf[encoder+13] << 8 | in_buf[encoder+14];
data[op-5] = 4278190080 | in_buf[encoder+15] << 16 | in_buf[encoder+16] << 8 | in_buf[encoder+17];
data[op-6] = 4278190080 | in_buf[encoder+18] << 16 | in_buf[encoder+19] << 8 | in_buf[encoder+20];
data[op-7] = 4278190080 | in_buf[encoder+21] << 16 | in_buf[encoder+22] << 8 | in_buf[encoder+23];
data[op-8] = 4278190080 | in_buf[encoder+24] << 16 | in_buf[encoder+25] << 8 | in_buf[encoder+26];
data[op-9] = 4278190080 | in_buf[encoder+27] << 16 | in_buf[encoder+28] << 8 | in_buf[encoder+29];
encoder += 30;
op -= 10;
ctrl -= 10;
}
if(ctrl != 0) {
if(ctrl == 9) {
data[op] = 4278190080 | in_buf[encoder] << 16 | in_buf[encoder+1] << 8 | in_buf[encoder+2];
data[op-1] = 4278190080 | in_buf[encoder+3] << 16 | in_buf[encoder+4] << 8 | in_buf[encoder+5];
data[op-2] = 4278190080 | in_buf[encoder+6] << 16 | in_buf[encoder+7] << 8 | in_buf[encoder+8];
data[op-3] = 4278190080 | in_buf[encoder+9] << 16 | in_buf[encoder+10] << 8 | in_buf[encoder+11];
data[op-4] = 4278190080 | in_buf[encoder+12] << 16 | in_buf[encoder+13] << 8 | in_buf[encoder+14];
data[op-5] = 4278190080 | in_buf[encoder+15] << 16 | in_buf[encoder+16] << 8 | in_buf[encoder+17];
data[op-6] = 4278190080 | in_buf[encoder+18] << 16 | in_buf[encoder+19] << 8 | in_buf[encoder+20];
data[op-7] = 4278190080 | in_buf[encoder+21] << 16 | in_buf[encoder+22] << 8 | in_buf[encoder+23];
data[op-8] = 4278190080 | in_buf[encoder+24] << 16 | in_buf[encoder+25] << 8 | in_buf[encoder+26];
encoder += 27;
op -= 9;
} else if(ctrl == 8) {
data[op] = 4278190080 | in_buf[encoder] << 16 | in_buf[encoder+1] << 8 | in_buf[encoder+2];
data[op-1] = 4278190080 | in_buf[encoder+3] << 16 | in_buf[encoder+4] << 8 | in_buf[encoder+5];
data[op-2] = 4278190080 | in_buf[encoder+6] << 16 | in_buf[encoder+7] << 8 | in_buf[encoder+8];
data[op-3] = 4278190080 | in_buf[encoder+9] << 16 | in_buf[encoder+10] << 8 | in_buf[encoder+11];
data[op-4] = 4278190080 | in_buf[encoder+12] << 16 | in_buf[encoder+13] << 8 | in_buf[encoder+14];
data[op-5] = 4278190080 | in_buf[encoder+15] << 16 | in_buf[encoder+16] << 8 | in_buf[encoder+17];
data[op-6] = 4278190080 | in_buf[encoder+18] << 16 | in_buf[encoder+19] << 8 | in_buf[encoder+20];
data[op-7] = 4278190080 | in_buf[encoder+21] << 16 | in_buf[encoder+22] << 8 | in_buf[encoder+23];
encoder += 24;
op -= 8;
} else if(ctrl == 7) {
data[op] = 4278190080 | in_buf[encoder] << 16 | in_buf[encoder+1] << 8 | in_buf[encoder+2];
data[op-1] = 4278190080 | in_buf[encoder+3] << 16 | in_buf[encoder+4] << 8 | in_buf[encoder+5];
data[op-2] = 4278190080 | in_buf[encoder+6] << 16 | in_buf[encoder+7] << 8 | in_buf[encoder+8];
data[op-3] = 4278190080 | in_buf[encoder+9] << 16 | in_buf[encoder+10] << 8 | in_buf[encoder+11];
data[op-4] = 4278190080 | in_buf[encoder+12] << 16 | in_buf[encoder+13] << 8 | in_buf[encoder+14];
data[op-5] = 4278190080 | in_buf[encoder+15] << 16 | in_buf[encoder+16] << 8 | in_buf[encoder+17];
data[op-6] = 4278190080 | in_buf[encoder+18] << 16 | in_buf[encoder+19] << 8 | in_buf[encoder+20];
encoder += 21;
op -= 7;
} else if(ctrl == 6) {
data[op] = 4278190080 | in_buf[encoder] << 16 | in_buf[encoder+1] << 8 | in_buf[encoder+2];
data[op-1] = 4278190080 | in_buf[encoder+3] << 16 | in_buf[encoder+4] << 8 | in_buf[encoder+5];
data[op-2] = 4278190080 | in_buf[encoder+6] << 16 | in_buf[encoder+7] << 8 | in_buf[encoder+8];
data[op-3] = 4278190080 | in_buf[encoder+9] << 16 | in_buf[encoder+10] << 8 | in_buf[encoder+11];
data[op-4] = 4278190080 | in_buf[encoder+12] << 16 | in_buf[encoder+13] << 8 | in_buf[encoder+14];
data[op-5] = 4278190080 | in_buf[encoder+15] << 16 | in_buf[encoder+16] << 8 | in_buf[encoder+17];
encoder += 18;
op -= 6;
} else if(ctrl == 5) {
data[op] = 4278190080 | in_buf[encoder] << 16 | in_buf[encoder+1] << 8 | in_buf[encoder+2];
data[op-1] = 4278190080 | in_buf[encoder+3] << 16 | in_buf[encoder+4] << 8 | in_buf[encoder+5];
data[op-2] = 4278190080 | in_buf[encoder+6] << 16 | in_buf[encoder+7] << 8 | in_buf[encoder+8];
data[op-3] = 4278190080 | in_buf[encoder+9] << 16 | in_buf[encoder+10] << 8 | in_buf[encoder+11];
data[op-4] = 4278190080 | in_buf[encoder+12] << 16 | in_buf[encoder+13] << 8 | in_buf[encoder+14];
encoder += 15;
op -= 5;
} else if(ctrl == 4) {
data[op] = 4278190080 | in_buf[encoder] << 16 | in_buf[encoder+1] << 8 | in_buf[encoder+2];
data[op-1] = 4278190080 | in_buf[encoder+3] << 16 | in_buf[encoder+4] << 8 | in_buf[encoder+5];
data[op-2] = 4278190080 | in_buf[encoder+6] << 16 | in_buf[encoder+7] << 8 | in_buf[encoder+8];
data[op-3] = 4278190080 | in_buf[encoder+9] << 16 | in_buf[encoder+10] << 8 | in_buf[encoder+11];
encoder += 12;
op -= 4;
} else if(ctrl == 3) {
data[op] = 4278190080 | in_buf[encoder] << 16 | in_buf[encoder+1] << 8 | in_buf[encoder+2];
data[op-1] = 4278190080 | in_buf[encoder+3] << 16 | in_buf[encoder+4] << 8 | in_buf[encoder+5];
data[op-2] = 4278190080 | in_buf[encoder+6] << 16 | in_buf[encoder+7] << 8 | in_buf[encoder+8];
encoder += 9;
op -= 3;
} else if(ctrl == 2) {
data[op] = 4278190080 | in_buf[encoder] << 16 | in_buf[encoder+1] << 8 | in_buf[encoder+2];
data[op-1] = 4278190080 | in_buf[encoder+3] << 16 | in_buf[encoder+4] << 8 | in_buf[encoder+5];
encoder += 6;
op -= 2;
} else if(ctrl == 1) {
data[op--] = 4278190080 | in_buf[encoder] << 16 | in_buf[encoder+1] << 8 | in_buf[encoder+2];
encoder += 3;
}
}
data[op--] = 4278190080 | in_buf[encoder] << 16 | in_buf[encoder+1] << 8 | in_buf[encoder+2];
encoder+=3;
}
}
//reverse buf
//while, line by line
var left, right, line, temporary;
var length = width-1;
while(height--) {
line = new Uint32Array(buf,height*width*4, width);
left = 0;
right = length;
while (left < right)
{
var temporary = line[left];
line[left++] = line[right];
line[right--] = temporary;
}
}
return buf;
},
lz_rgb32_decompress_rgb: function(arr) {
//TODO: global alpha and uncouple code
var op = 0;
var in_buf = new Uint8Array(arr);
var opaque = in_buf[1];
var type = in_buf[2];
var top_down = in_buf[3];
if(opaque && !top_down) {
return lzDecompress.lz_rgb32_decompress_rgb_opaque_reverse(arr);
}
var low = in_buf[5] * 256 + in_buf[4]; // 256 = Math.pow(16, 2)
var high = in_buf[7] * 256 + in_buf[6]; // 256 = Math.pow(16, 2)
var len = high * 65536 + low; // 65536 = Math.pow(16,4)
var buf = new ArrayBuffer(len);
var data = new Uint32Array(buf);
var out_buf_len = len / 4;
var code, ref, ofs, b;
var op_4, aux;
var ctrl = in_buf[16];
var offsetView;
var encoder = 16; //padding
while (op != out_buf_len) {
ctrl = in_buf[encoder++];
//if ctrl is 0, there is no way for len to be > 0
if (ctrl != 0 && (len = ctrl >> 5)!=0) { //>=32
ref = op;
ofs = (ctrl & 31) << 8; //get the last 5 bits from ctrl
if (len == 7) {
do {
code = in_buf[encoder++];
len += code;
} while (code == 255);
}
ofs += in_buf[encoder++];
if (ofs == 0) {
aux = data[--ref];
while(len > 9) {
data[op] = aux;
data[op+1] = aux;
data[op+2] = aux;
data[op+3] = aux;
data[op+4] = aux;
data[op+5] = aux;
data[op+6] = aux;
data[op+7] = aux;
data[op+8] = aux;
data[op+9] = aux;
op+=10;
len -= 10;
}
while (len-- != 0) {
data[op++] = aux;
}
} else {
if (ofs == 8191) { //check if all the bits in ofs are 1, then get two more bytes
ofs += (in_buf[encoder] << 8) + in_buf[encoder+1];
encoder += 2;
}
ref -= ofs + 1;
//if the copy from array to array is bigger than 100 (tested using benchmark) its cheaper to
//create a view and copy with set. If the copy is less than 100, then its cheaper
//to just iterate it.
if(len > 100 && ref+len < op) {
offsetView = new Uint32Array(buf, ref*4, len);
data.set(offsetView,op);
op += len;
ref += len;
} else {
while(len > 9) {
data[op] = data[ref];
data[op+1] = data[ref+1];
data[op+2] = data[ref+2];
data[op+3] = data[ref+3];
data[op+4] = data[ref+4];
data[op+5] = data[ref+5];
data[op+6] = data[ref+6];
data[op+7] = data[ref+7];
data[op+8] = data[ref+8];
data[op+9] = data[ref+9];
op+=10;
len -= 10;
ref += 10;
}
while (len-- !== 0) {
data[op++] = data[ref++];
}
}
}
} else {
while(ctrl > 9) {
data[op] = 4278190080 | in_buf[encoder] << 16 | in_buf[encoder+1] << 8 | in_buf[encoder+2];
data[op+1] = 4278190080 | in_buf[encoder+3] << 16 | in_buf[encoder+4] << 8 | in_buf[encoder+5];
data[op+2] = 4278190080 | in_buf[encoder+6] << 16 | in_buf[encoder+7] << 8 | in_buf[encoder+8];
data[op+3] = 4278190080 | in_buf[encoder+9] << 16 | in_buf[encoder+10] << 8 | in_buf[encoder+11];
data[op+4] = 4278190080 | in_buf[encoder+12] << 16 | in_buf[encoder+13] << 8 | in_buf[encoder+14];
data[op+5] = 4278190080 | in_buf[encoder+15] << 16 | in_buf[encoder+16] << 8 | in_buf[encoder+17];
data[op+6] = 4278190080 | in_buf[encoder+18] << 16 | in_buf[encoder+19] << 8 | in_buf[encoder+20];
data[op+7] = 4278190080 | in_buf[encoder+21] << 16 | in_buf[encoder+22] << 8 | in_buf[encoder+23];
data[op+8] = 4278190080 | in_buf[encoder+24] << 16 | in_buf[encoder+25] << 8 | in_buf[encoder+26];
data[op+9] = 4278190080 | in_buf[encoder+27] << 16 | in_buf[encoder+28] << 8 | in_buf[encoder+29];
encoder += 30;
op += 10;
ctrl -= 10;
}
//if we are just out of the above loop, ctrl is 9, so do the 9 in a row
if(ctrl != 0) {
if(ctrl == 9) {
data[op] = 4278190080 | in_buf[encoder] << 16 | in_buf[encoder+1] << 8 | in_buf[encoder+2];
data[op+1] = 4278190080 | in_buf[encoder+3] << 16 | in_buf[encoder+4] << 8 | in_buf[encoder+5];
data[op+2] = 4278190080 | in_buf[encoder+6] << 16 | in_buf[encoder+7] << 8 | in_buf[encoder+8];
data[op+3] = 4278190080 | in_buf[encoder+9] << 16 | in_buf[encoder+10] << 8 | in_buf[encoder+11];
data[op+4] = 4278190080 | in_buf[encoder+12] << 16 | in_buf[encoder+13] << 8 | in_buf[encoder+14];
data[op+5] = 4278190080 | in_buf[encoder+15] << 16 | in_buf[encoder+16] << 8 | in_buf[encoder+17];
data[op+6] = 4278190080 | in_buf[encoder+18] << 16 | in_buf[encoder+19] << 8 | in_buf[encoder+20];
data[op+7] = 4278190080 | in_buf[encoder+21] << 16 | in_buf[encoder+22] << 8 | in_buf[encoder+23];
data[op+8] = 4278190080 | in_buf[encoder+24] << 16 | in_buf[encoder+25] << 8 | in_buf[encoder+26];
encoder += 27;
op += 9;
} else if(ctrl == 8) {
data[op] = 4278190080 | in_buf[encoder] << 16 | in_buf[encoder+1] << 8 | in_buf[encoder+2];
data[op+1] = 4278190080 | in_buf[encoder+3] << 16 | in_buf[encoder+4] << 8 | in_buf[encoder+5];
data[op+2] = 4278190080 | in_buf[encoder+6] << 16 | in_buf[encoder+7] << 8 | in_buf[encoder+8];
data[op+3] = 4278190080 | in_buf[encoder+9] << 16 | in_buf[encoder+10] << 8 | in_buf[encoder+11];
data[op+4] = 4278190080 | in_buf[encoder+12] << 16 | in_buf[encoder+13] << 8 | in_buf[encoder+14];
data[op+5] = 4278190080 | in_buf[encoder+15] << 16 | in_buf[encoder+16] << 8 | in_buf[encoder+17];
data[op+6] = 4278190080 | in_buf[encoder+18] << 16 | in_buf[encoder+19] << 8 | in_buf[encoder+20];
data[op+7] = 4278190080 | in_buf[encoder+21] << 16 | in_buf[encoder+22] << 8 | in_buf[encoder+23];
encoder += 24;
op += 8;
} else if(ctrl == 7) {
data[op] = 4278190080 | in_buf[encoder] << 16 | in_buf[encoder+1] << 8 | in_buf[encoder+2];
data[op+1] = 4278190080 | in_buf[encoder+3] << 16 | in_buf[encoder+4] << 8 | in_buf[encoder+5];
data[op+2] = 4278190080 | in_buf[encoder+6] << 16 | in_buf[encoder+7] << 8 | in_buf[encoder+8];
data[op+3] = 4278190080 | in_buf[encoder+9] << 16 | in_buf[encoder+10] << 8 | in_buf[encoder+11];
data[op+4] = 4278190080 | in_buf[encoder+12] << 16 | in_buf[encoder+13] << 8 | in_buf[encoder+14];
data[op+5] = 4278190080 | in_buf[encoder+15] << 16 | in_buf[encoder+16] << 8 | in_buf[encoder+17];
data[op+6] = 4278190080 | in_buf[encoder+18] << 16 | in_buf[encoder+19] << 8 | in_buf[encoder+20];
encoder += 21;
op += 7;
} else if(ctrl == 6) {
data[op] = 4278190080 | in_buf[encoder] << 16 | in_buf[encoder+1] << 8 | in_buf[encoder+2];
data[op+1] = 4278190080 | in_buf[encoder+3] << 16 | in_buf[encoder+4] << 8 | in_buf[encoder+5];
data[op+2] = 4278190080 | in_buf[encoder+6] << 16 | in_buf[encoder+7] << 8 | in_buf[encoder+8];
data[op+3] = 4278190080 | in_buf[encoder+9] << 16 | in_buf[encoder+10] << 8 | in_buf[encoder+11];
data[op+4] = 4278190080 | in_buf[encoder+12] << 16 | in_buf[encoder+13] << 8 | in_buf[encoder+14];
data[op+5] = 4278190080 | in_buf[encoder+15] << 16 | in_buf[encoder+16] << 8 | in_buf[encoder+17];
encoder += 18;
op += 6;
} else if(ctrl == 5) {
data[op] = 4278190080 | in_buf[encoder] << 16 | in_buf[encoder+1] << 8 | in_buf[encoder+2];
data[op+1] = 4278190080 | in_buf[encoder+3] << 16 | in_buf[encoder+4] << 8 | in_buf[encoder+5];
data[op+2] = 4278190080 | in_buf[encoder+6] << 16 | in_buf[encoder+7] << 8 | in_buf[encoder+8];
data[op+3] = 4278190080 | in_buf[encoder+9] << 16 | in_buf[encoder+10] << 8 | in_buf[encoder+11];
data[op+4] = 4278190080 | in_buf[encoder+12] << 16 | in_buf[encoder+13] << 8 | in_buf[encoder+14];
encoder += 15;
op += 5;
} else if(ctrl == 4) {
data[op] = 4278190080 | in_buf[encoder] << 16 | in_buf[encoder+1] << 8 | in_buf[encoder+2];
data[op+1] = 4278190080 | in_buf[encoder+3] << 16 | in_buf[encoder+4] << 8 | in_buf[encoder+5];
data[op+2] = 4278190080 | in_buf[encoder+6] << 16 | in_buf[encoder+7] << 8 | in_buf[encoder+8];
data[op+3] = 4278190080 | in_buf[encoder+9] << 16 | in_buf[encoder+10] << 8 | in_buf[encoder+11];
encoder += 12;
op += 4;
} else if(ctrl == 3) {
data[op] = 4278190080 | in_buf[encoder] << 16 | in_buf[encoder+1] << 8 | in_buf[encoder+2];
data[op+1] = 4278190080 | in_buf[encoder+3] << 16 | in_buf[encoder+4] << 8 | in_buf[encoder+5];
data[op+2] = 4278190080 | in_buf[encoder+6] << 16 | in_buf[encoder+7] << 8 | in_buf[encoder+8];
encoder += 9;
op += 3;
} else if(ctrl == 2) {
data[op] = 4278190080 | in_buf[encoder] << 16 | in_buf[encoder+1] << 8 | in_buf[encoder+2];
data[op+1] = 4278190080 | in_buf[encoder+3] << 16 | in_buf[encoder+4] << 8 | in_buf[encoder+5];
encoder += 6;
op += 2;
} else if(ctrl == 1) {
data[op++] = 4278190080 | in_buf[encoder] << 16 | in_buf[encoder+1] << 8 | in_buf[encoder+2];
encoder += 3;
}
}
data[op++] = 4278190080 | in_buf[encoder] << 16 | in_buf[encoder+1] << 8 | in_buf[encoder+2];
encoder+=3;
}
}
if (type === this.LZ_IMAGE_TYPE_RGBA && !opaque) {
var buf8 = new Uint8Array(buf);
op = 0;
ctrl = null;
//encoder--;
for (ctrl = in_buf[encoder++]; op < out_buf_len; ctrl = in_buf[encoder++]) {
ref = op;
len = ctrl >> 5;
ofs = ((ctrl & 31) << 8);
op_4 = op * 4;
if (ctrl >= 32) {
code;
len--;
if (len === 7 - 1) {
do {
code = in_buf[encoder++];
len += code;
} while (code === 255);
}
code = in_buf[encoder++];
ofs += code;
if (code === 255) {
if ((ofs - code) === (31 << 8)) {
ofs = in_buf[encoder++] << 8;
ofs += in_buf[encoder++];
ofs += 8191;
}
}
len += 3;
ofs += 1;
ref -= ofs;
if (ref === (op - 1)) { //plt4/1 what?
b = ref;
for (; len; --len) {
op_4 = op * 4;
//COPY_PIXEL
buf8[(op_4) + 3] = buf8[(b * 4) + 3];
op++;
}
} else {
for (; len; --len) {
//COPY_REF_PIXEL
op_4 = op * 4;
buf8[(op_4) + 3] = buf8[(ref * 4) + 3];
op++;
ref++;
}
}
} else {
//COPY_COMP_PIXEL
ctrl++;
buf8[(op_4) + 3] = in_buf[encoder++];
op++;
for (--ctrl; ctrl; ctrl--) {
//COPY_COMP_PIXEL
op_4 = op * 4; // faster?
buf8[(op_4) + 3] = in_buf[encoder++];
op++;
}
}
}
}
return buf;
}
};
if (wdi.LZSS) {
wdi.LZSS.lz_rgb32_decompress_rgb = lzDecompress.lz_rgb32_decompress_rgb
} else {
// if (!wdi.LZSS) {
wdi.LZSS = lzDecompress;
}