c_forceCanvas = false,
// Predefine function variables (jslint)
- imageDataGet, bgrxImageData, cmapImageData,
+ imageDataGet, rgbImageData, bgrxImageData, cmapImageData,
setFillColor, rescale,
// The full frame buffer (logical canvas) size
// 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;
/*
}
};
+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 () {
* emoller@opera.com
*/
+"use strict";
+
function TINF() {
-
+
this.OK = 0;
this.DATA_ERROR = (-3);
this.WINDOW_SIZE = 32768;
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;
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];
// 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 {
}
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 };
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 = [];
return [header, data];
};
+ var checksum = function(data) {
+ var sum=0, i;
+ for (i=0; i<data.length;i++) {
+ sum += data[i];
+ if (sum > 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;
}
// 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]);
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]);
// Keep tight reset bits
resetStreams = ctl & 0xF;
-
+ if (resetStreams) throw ("Tight reset");
+
// Figure out filter
ctl = ctl >> 4;
streamId = ctl & 0x3;
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);
}