summaryrefslogtreecommitdiff
path: root/lz.js
diff options
context:
space:
mode:
authorJeremy White <jwhite@codeweavers.com>2012-06-04 17:22:01 +0300
committerAlon Levy <alevy@redhat.com>2012-06-04 17:22:01 +0300
commitf8f622157c174ba3facc088646484ccba99acc69 (patch)
tree88d99c83e53fa8509a8ca33a6e9f6bdc015e5791 /lz.js
initial
Diffstat (limited to 'lz.js')
-rw-r--r--lz.js158
1 files changed, 158 insertions, 0 deletions
diff --git a/lz.js b/lz.js
new file mode 100644
index 0000000..2914c37
--- /dev/null
+++ b/lz.js
@@ -0,0 +1,158 @@
+"use strict";
+/*
+ Copyright (C) 2012 by Jeremy P. White <jwhite@codeweavers.com>
+
+ This file is part of spice-html5.
+
+ spice-html5 is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ spice-html5 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 Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with spice-html5. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+/*----------------------------------------------------------------------------
+** lz.js
+** Functions for handling SPICE_IMAGE_TYPE_LZ_RGB
+** Adapted from lz.c .
+**--------------------------------------------------------------------------*/
+function lz_rgb32_decompress(in_buf, at, out_buf, type, default_alpha)
+{
+ var encoder = at;
+ var op = 0;
+ var ctrl;
+ var ctr = 0;
+
+ for (ctrl = in_buf[encoder++]; (op * 4) < out_buf.length; ctrl = in_buf[encoder++])
+ {
+ var ref = op;
+ var len = ctrl >> 5;
+ var ofs = (ctrl & 31) << 8;
+
+//if (type == LZ_IMAGE_TYPE_RGBA)
+//console.log(ctr++ + ": from " + (encoder + 28) + ", ctrl " + ctrl + ", len " + len + ", ofs " + ofs + ", op " + op);
+ if (ctrl >= 32) {
+
+ var 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 += 1;
+ if (type == LZ_IMAGE_TYPE_RGBA)
+ len += 2;
+
+ ofs += 1;
+
+ ref -= ofs;
+ if (ref == (op - 1)) {
+ var b = ref;
+//if (type == LZ_IMAGE_TYPE_RGBA) console.log("alpha " + out_buf[(b*4)+3] + " dupped into pixel " + op + " through pixel " + (op + len));
+ for (; len; --len) {
+ if (type == LZ_IMAGE_TYPE_RGBA)
+ {
+ out_buf[(op*4) + 3] = out_buf[(b*4)+3];
+ }
+ else
+ {
+ for (i = 0; i < 4; i++)
+ out_buf[(op*4) + i] = out_buf[(b*4)+i];
+ }
+ op++;
+ }
+ } else {
+//if (type == LZ_IMAGE_TYPE_RGBA) console.log("alpha copied to pixel " + op + " through " + (op + len) + " from " + ref);
+ for (; len; --len) {
+ if (type == LZ_IMAGE_TYPE_RGBA)
+ {
+ out_buf[(op*4) + 3] = out_buf[(ref*4)+3];
+ }
+ else
+ {
+ for (i = 0; i < 4; i++)
+ out_buf[(op*4) + i] = out_buf[(ref*4)+i];
+ }
+ op++; ref++;
+ }
+ }
+ } else {
+ ctrl++;
+
+ if (type == LZ_IMAGE_TYPE_RGBA)
+ {
+//console.log("alpha " + in_buf[encoder] + " set into pixel " + op);
+ out_buf[(op*4) + 3] = in_buf[encoder++];
+ }
+ else
+ {
+ out_buf[(op*4) + 0] = in_buf[encoder + 2];
+ out_buf[(op*4) + 1] = in_buf[encoder + 1];
+ out_buf[(op*4) + 2] = in_buf[encoder + 0];
+ if (default_alpha)
+ out_buf[(op*4) + 3] = 255;
+ encoder += 3;
+ }
+ op++;
+
+
+ for (--ctrl; ctrl; ctrl--) {
+ if (type == LZ_IMAGE_TYPE_RGBA)
+ {
+//console.log("alpha " + in_buf[encoder] + " set into pixel " + op);
+ out_buf[(op*4) + 3] = in_buf[encoder++];
+ }
+ else
+ {
+ out_buf[(op*4) + 0] = in_buf[encoder + 2];
+ out_buf[(op*4) + 1] = in_buf[encoder + 1];
+ out_buf[(op*4) + 2] = in_buf[encoder + 0];
+ if (default_alpha)
+ out_buf[(op*4) + 3] = 255;
+ encoder += 3;
+ }
+ op++;
+ }
+ }
+
+ }
+ return encoder - 1;
+}
+
+function convert_spice_lz_rgb_to_web(context, lz_rgb)
+{
+ var u8 = new Uint8Array(lz_rgb.data);
+ var at;
+ if (lz_rgb.type != LZ_IMAGE_TYPE_RGB32 && lz_rgb.type != LZ_IMAGE_TYPE_RGBA)
+ return undefined;
+
+ var ret = context.createImageData(lz_rgb.width, lz_rgb.height);
+
+ at = lz_rgb32_decompress(u8, 0, ret.data, LZ_IMAGE_TYPE_RGB32, lz_rgb.type != LZ_IMAGE_TYPE_RGBA);
+ if (lz_rgb.type == LZ_IMAGE_TYPE_RGBA)
+ lz_rgb32_decompress(u8, at, ret.data, LZ_IMAGE_TYPE_RGBA, false);
+
+ return ret;
+}