diff --git a/include/display.js b/include/display.js index bfc9776c..f2ecdba3 100644 --- a/include/display.js +++ b/include/display.js @@ -20,7 +20,7 @@ var that = {}, // Public API methods c_forceCanvas = false, // Predefine function variables (jslint) - imageDataGet, bgrxImageData, cmapImageData, + imageDataGet, rgbImageData, bgrxImageData, cmapImageData, setFillColor, rescale, // The full frame buffer (logical canvas) size @@ -497,6 +497,26 @@ that.finishTile = function() { // else: No-op, if not prefer_js then already done by setSubTile }; +rgbImageData = function(x, y, width, height, arr, offset) { + var img, i, j, data, v = viewport; + /* + if ((x - v.x >= v.w) || (y - v.y >= v.h) || + (x - v.x + width < 0) || (y - v.y + height < 0)) { + // Skipping because outside of viewport + return; + } + */ + img = c_ctx.createImageData(width, height); + data = img.data; + for (i=0, j=offset; i < (width * height * 4); i=i+4, j=j+3) { + data[i ] = arr[j ]; + data[i + 1] = arr[j + 1]; + data[i + 2] = arr[j + 2]; + data[i + 3] = 255; // Set Alpha + } + c_ctx.putImageData(img, x - v.x, y - v.y); +}; + bgrxImageData = function(x, y, width, height, arr, offset) { var img, i, j, data, v = viewport; /* @@ -540,6 +560,15 @@ that.blitImage = function(x, y, width, height, arr, offset) { } }; +that.blitRgbImage = function(x, y, width, height, arr, offset) { + if (conf.true_color) { + rgbImageData(x, y, width, height, arr, offset); + } else { + // prolly wrong... + cmapImageData(x, y, width, height, arr, offset); + } +}; + that.blitStringImage = function(str, x, y) { var img = new Image(); img.onload = function () { diff --git a/include/jsunzip.js b/include/jsunzip.js index 2ae9e7fd..db1a9fcb 100755 --- a/include/jsunzip.js +++ b/include/jsunzip.js @@ -197,8 +197,10 @@ function JSUnzip() { * emoller@opera.com */ +"use strict"; + function TINF() { - + this.OK = 0; this.DATA_ERROR = (-3); this.WINDOW_SIZE = 32768; @@ -392,7 +394,7 @@ this.decode_symbol = function(d, t) this.decode_trees = function(d, lt, dt) { var code_tree = new this.TREE(); - lengths = new Array(288+32); + var lengths = new Array(288+32); var hlit, hdist, hclen; var i, num, length; @@ -518,6 +520,13 @@ this.inflate_uncompressed_block = function(d) var length, invlength; var i; + if (d.bitcount > 7) { + var overflow = Math.floor(d.bitcount / 8); + d.sourceIndex -= overflow; + d.bitcount = 0; + d.tag = 0; + } + /* get length */ length = d.source[d.sourceIndex+1]; length = 256*length + d.source[d.sourceIndex]; @@ -605,7 +614,11 @@ this.uncompress = function(source, offset) // Skip zlib header at start of stream if (typeof this.header == 'undefined') { this.header = this.read_bits(d, 16, 0); + /* byte 0: 0x78, 7 = 32k window size, 8 = deflate */ + /* byte 1: check bits for header and other flags */ } + + var blocks = 0; do { @@ -638,21 +651,18 @@ this.uncompress = function(source, offset) } if (res != this.OK) return { 'status' : this.DATA_ERROR }; + blocks++; + + } while (!bfinal && d.sourceIndex < d.source.length); - } while (!bfinal && d.sourceIndex < d.source.length - 3); - + if (blocks != 2) throw ("Unexpected number of blocks"); + if (Object.prototype.toString.call(source) !== '[object Array]') { d.dest = d.dest.join(''); } else { - if (d.dest.length >= this.WINDOW_SIZE) { - d.history = d.dest.slice(d.dest.length - this.WINDOW_SIZE); - } else { - var overflow = d.history.length + d.dest.length - this.WINDOW_SIZE; - if (overflow > 0) - d.history = d.history.slice(overflow); - } d.history.push.apply(d.history, d.dest); + d.history = d.history.slice(-this.WINDOW_SIZE); } return { 'status' : this.OK, 'data' : d.dest }; diff --git a/include/rfb.js b/include/rfb.js index 00784bc5..420c5e66 100644 --- a/include/rfb.js +++ b/include/rfb.js @@ -299,7 +299,7 @@ init_vars = function() { FBU.lines = 0; // RAW FBU.tiles = 0; // HEXTILE FBU.imgQ = []; // TIGHT_PNG image queue - FBU.streams = []; // TIGHT zlib encoders + FBU.zlibs = []; // TIGHT zlib encoders mouse_buttonMask = 0; mouse_arr = []; @@ -1290,11 +1290,22 @@ encHandlers.TIGHT = function display_tight() { return [header, data]; }; + var checksum = function(data) { + var sum=0, i; + for (i=0; i 65536) sum -= 65536; + } + return sum; + } + var decompress = function(data) { // TODO: process resetStreams here var uncompressed = FBU.zlibs[streamId].uncompress(data, 0); if (uncompressed.status != 0) - throw("Invalid data in zlib stream"); + throw("Invalid data in zlib stream"); + Util.Warn("Decompressed " + data.length + " to " + uncompressed.data.length + " checksums " + + checksum(data) + ":" + checksum(uncompressed.data)); return uncompressed.data; } @@ -1319,6 +1330,8 @@ encHandlers.TIGHT = function display_tight() { // Shift ctl, filter id, num colors, palette entries, and clength off ws.rQshiftBytes(3 + paletteSize + clength[0]); + if (streamId == 0) throw ("Wrong stream"); + // Process data if (clength[1] < 12) data = ws.rQshiftBytes(clength[1]); @@ -1337,6 +1350,8 @@ encHandlers.TIGHT = function display_tight() { FBU.bytes = 1 + clength[0] + clength[1]; // ctl + clength size + zlib-data if (ws.rQwait("TIGHT " + cmode, FBU.bytes)) { return false; } + if (streamId != 0) throw ("Wrong stream"); + ws.rQshiftBytes(1 + clength[0]); // ctl + clength if (clength[1] < 12) data = ws.rQshiftBytes(clength[1]); @@ -1357,7 +1372,8 @@ encHandlers.TIGHT = function display_tight() { // Keep tight reset bits resetStreams = ctl & 0xF; - + if (resetStreams) throw ("Tight reset"); + // Figure out filter ctl = ctl >> 4; streamId = ctl & 0x3; @@ -1540,7 +1556,7 @@ scan_tight_imgQ = function() { if (data.type === 'fill') { display.fillRect(data.x, data.y, data.width, data.height, data.color); } else if (data.type === 'rgb') { - // TODO + display.blitRgbImage(data.x, data.y, data.width, data.height, data.img.data, 0); } else { ctx.drawImage(data.img, data.x, data.y); }