[gtk+] broadway: Use zlib compression for broadway buffers



commit 149b3af105bd493cf267a1b69a3661cdfa88a46c
Author: Alexander Larsson <alexl redhat com>
Date:   Thu Nov 7 13:54:54 2013 +0100

    broadway: Use zlib compression for broadway buffers
    
    This imports the MIT licensed js unzip from:
    https://github.com/imaya/zlib.js
    
    and uses it to decompress in js on the client side.

 gdk/broadway/Makefile.am       |    6 ++--
 gdk/broadway/broadway-output.c |   43 ++++++++++++++++++++++-----------------
 gdk/broadway/broadway.js       |    5 ++-
 gdk/broadway/rawinflate.min.js |   15 ++++++++++++++
 gdk/broadway/toarray.pl        |   24 ++++++++++++----------
 5 files changed, 58 insertions(+), 35 deletions(-)
---
diff --git a/gdk/broadway/Makefile.am b/gdk/broadway/Makefile.am
index e48e09e..d0bcabd 100644
--- a/gdk/broadway/Makefile.am
+++ b/gdk/broadway/Makefile.am
@@ -30,12 +30,12 @@ libgdkbroadwayinclude_HEADERS =     \
        gdkbroadwayvisual.h
 
 clienthtml.h: client.html
-       $(PERL) $(srcdir)/toarray.pl $(srcdir)/client.html client_html > $@
+       $(PERL) $(srcdir)/toarray.pl client_html $(srcdir)/client.html > $@
 
 EXTRA_DIST += client.html
 
-broadwayjs.h: broadway.js
-       $(PERL) $(srcdir)/toarray.pl $(srcdir)/broadway.js broadway_js > $@
+broadwayjs.h: broadway.js rawinflate.min.js
+       $(PERL) $(srcdir)/toarray.pl broadway_js $(srcdir)/broadway.js $(srcdir)/rawinflate.min.js  > $@
 
 EXTRA_DIST += broadway.js
 
diff --git a/gdk/broadway/broadway-output.c b/gdk/broadway/broadway-output.c
index 517a65b..e77be33 100644
--- a/gdk/broadway/broadway-output.c
+++ b/gdk/broadway/broadway-output.c
@@ -155,18 +155,6 @@ append_uint32 (BroadwayOutput *output, guint32 v)
 }
 
 static void
-overwrite_uint32 (BroadwayOutput *output, gsize pos, guint32 v)
-{
-  guint8 *buf = (guint8 *)output->buf->str + pos;
-
-  buf[0] = (v >> 0) & 0xff;
-  buf[1] = (v >> 8) & 0xff;
-  buf[2] = (v >> 16) & 0xff;
-  buf[3] = (v >> 24) & 0xff;
-}
-
-
-static void
 write_header(BroadwayOutput *output, char op)
 {
   append_char (output, op);
@@ -283,8 +271,11 @@ broadway_output_put_buffer (BroadwayOutput *output,
                             BroadwayBuffer *prev_buffer,
                             BroadwayBuffer *buffer)
 {
-  gsize size_start, image_start, len;
+  gsize len;
   int w, h;
+  GZlibCompressor *compressor;
+  GOutputStream *out, *out_mem;
+  GString *encoded;
 
   write_header (output, BROADWAY_OP_PUT_BUFFER);
 
@@ -295,12 +286,26 @@ broadway_output_put_buffer (BroadwayOutput *output,
   append_uint16 (output, w);
   append_uint16 (output, h);
 
-  size_start = output->buf->len;
-  append_uint32 (output, 0);
+  encoded = g_string_new ("");
+  broadway_buffer_encode (buffer, prev_buffer, encoded);
+
+  compressor = g_zlib_compressor_new (G_ZLIB_COMPRESSOR_FORMAT_RAW, -1);
+  out_mem = g_memory_output_stream_new_resizable ();
+  out = g_converter_output_stream_new (out_mem, G_CONVERTER (compressor));
+  g_object_unref (compressor);
+
+  if (!g_output_stream_write_all (out, encoded->str, encoded->len,
+                                  NULL, NULL, NULL) ||
+      !g_output_stream_close (out, NULL, NULL))
+    g_warning ("compression failed\n");
+
+
+  len = g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (out_mem));
+  append_uint32 (output, len);
 
-  image_start = output->buf->len;
-  broadway_buffer_encode (buffer, prev_buffer, output->buf);
-  len = output->buf->len - image_start;
+  g_string_append_len (output->buf, g_memory_output_stream_get_data (G_MEMORY_OUTPUT_STREAM (out_mem)), len);
 
-  overwrite_uint32 (output, size_start, len);
+  g_string_free (encoded, TRUE);
+  g_object_unref (out);
+  g_object_unref (out_mem);
 }
diff --git a/gdk/broadway/broadway.js b/gdk/broadway/broadway.js
index 084cce7..90e7eb0 100644
--- a/gdk/broadway/broadway.js
+++ b/gdk/broadway/broadway.js
@@ -329,7 +329,7 @@ function copyRect(src, srcX, srcY, dest, destX, destY, width, height)
     }
 }
 
-function cmdPutBuffer(id, w, h, data)
+function cmdPutBuffer(id, w, h, compressed)
 {
     var surface = surfaces[id];
     var context = surface.canvas.getContext("2d");
@@ -345,7 +345,8 @@ function cmdPutBuffer(id, w, h, data)
     var src = 0;
     var dest = 0;
 
-    //log("put buffer " + w + "x" + h + " size: " + data.length);
+    var inflate = new Zlib.RawInflate(compressed);
+    var data = inflate.decompress();
 
     while (src < data.length)  {
         var b = data[src++];
diff --git a/gdk/broadway/rawinflate.min.js b/gdk/broadway/rawinflate.min.js
new file mode 100644
index 0000000..f9c7f87
--- /dev/null
+++ b/gdk/broadway/rawinflate.min.js
@@ -0,0 +1,15 @@
+/** @license zlib.js 2012 - imaya [ https://github.com/imaya/zlib.js ] The MIT License */(function() {'use 
strict';var l=void 0,p=this;function q(c,d){var a=c.split("."),b=p;!(a[0]in 
b)&&b.execScript&&b.execScript("var "+a[0]);for(var 
e;a.length&&(e=a.shift());)!a.length&&d!==l?b[e]=d:b=b[e]?b[e]:b[e]={}};var r="undefined"!==typeof 
Uint8Array&&"undefined"!==typeof Uint16Array&&"undefined"!==typeof Uint32Array;function u(c){var 
d=c.length,a=0,b=Number.POSITIVE_INFINITY,e,f,g,h,k,m,s,n,t;for(n=0;n<d;++n)c[n]>a&&(a=c[n]),c[n]<b&&(b=c[n]);e=1<<a;f=new
 
(r?Uint32Array:Array)(e);g=1;h=0;for(k=2;g<=a;){for(n=0;n<d;++n)if(c[n]===g){m=0;s=h;for(t=0;t<g;++t)m=m<<1|s&1,s>>=1;for(t=m;t<e;t+=k)f[t]=g<<16|n;++h}++g;h<<=1;k<<=1}return[f,a,b]};function
 v(c,d){this.g=[];this.h=32768;this.c=this.f=this.d=this.k=0;this.input=r?new 
Uint8Array(c):c;this.l=!1;this.i=w;this.p=!1;if(d||!(d={}))d.index&&(this.d=d.index),d.bufferSize&&(this.h=d.bufferSize),d.bufferType&&(this.i=d.bufferType),d.resize&
 &(this.p=d.resize);switch(this.i){case x:this.a=32768;this.b=new 
(r?Uint8Array:Array)(32768+this.h+258);break;case w:this.a=0;this.b=new 
(r?Uint8Array:Array)(this.h);this.e=this.u;this.m=this.r;this.j=this.s;break;default:throw Error("invalid 
inflate mode");
+}}var x=0,w=1;
+v.prototype.t=function(){for(;!this.l;){var c=y(this,3);c&1&&(this.l=!0);c>>>=1;switch(c){case 0:var 
d=this.input,a=this.d,b=this.b,e=this.a,f=l,g=l,h=l,k=b.length,m=l;this.c=this.f=0;f=d[a++];if(f===l)throw 
Error("invalid uncompressed block header: LEN (first byte)");g=f;f=d[a++];if(f===l)throw Error("invalid 
uncompressed block header: LEN (second byte)");g|=f<<8;f=d[a++];if(f===l)throw Error("invalid uncompressed 
block header: NLEN (first byte)");h=f;f=d[a++];if(f===l)throw Error("invalid uncompressed block header: NLEN 
(second byte)");h|=
+f<<8;if(g===~h)throw Error("invalid uncompressed block header: length verify");if(a+g>d.length)throw 
Error("input buffer is broken");switch(this.i){case 
x:for(;e+g>b.length;){m=k-e;g-=m;if(r)b.set(d.subarray(a,a+m),e),e+=m,a+=m;else 
for(;m--;)b[e++]=d[a++];this.a=e;b=this.e();e=this.a}break;case 
w:for(;e+g>b.length;)b=this.e({o:2});break;default:throw Error("invalid inflate 
mode");}if(r)b.set(d.subarray(a,a+g),e),e+=g,a+=g;else 
for(;g--;)b[e++]=d[a++];this.d=a;this.a=e;this.b=b;break;case 1:this.j(z,
+A);break;case 2:B(this);break;default:throw Error("unknown BTYPE: "+c);}}return this.m()};
+var C=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],D=r?new 
Uint16Array(C):C,E=[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,258,258],F=r?new
 Uint16Array(E):E,G=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0],H=r?new 
Uint8Array(G):G,I=[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577],J=r?new
 Uint16Array(I):I,K=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,
+13],L=r?new Uint8Array(K):K,M=new 
(r?Uint8Array:Array)(288),N,O;N=0;for(O=M.length;N<O;++N)M[N]=143>=N?8:255>=N?9:279>=N?7:8;var z=u(M),P=new 
(r?Uint8Array:Array)(30),Q,R;Q=0;for(R=P.length;Q<R;++Q)P[Q]=5;var A=u(P);function y(c,d){for(var 
a=c.f,b=c.c,e=c.input,f=c.d,g;b<d;){g=e[f++];if(g===l)throw Error("input buffer is 
broken");a|=g<<b;b+=8}g=a&(1<<d)-1;c.f=a>>>d;c.c=b-d;c.d=f;return g}
+function S(c,d){for(var 
a=c.f,b=c.c,e=c.input,f=c.d,g=d[0],h=d[1],k,m,s;b<h;){k=e[f++];if(k===l)break;a|=k<<b;b+=8}m=g[a&(1<<h)-1];s=m>>>16;c.f=a>>s;c.c=b-s;c.d=f;return
 m&65535}
+function B(c){function d(a,c,b){var d,f,e,g;for(g=0;g<a;)switch(d=S(this,c),d){case 
16:for(e=3+y(this,2);e--;)b[g++]=f;break;case 17:for(e=3+y(this,3);e--;)b[g++]=0;f=0;break;case 
18:for(e=11+y(this,7);e--;)b[g++]=0;f=0;break;default:f=b[g++]=d}return b}var 
a=y(c,5)+257,b=y(c,5)+1,e=y(c,4)+4,f=new 
(r?Uint8Array:Array)(D.length),g,h,k,m;for(m=0;m<e;++m)f[D[m]]=y(c,3);g=u(f);h=new 
(r?Uint8Array:Array)(a);k=new (r?Uint8Array:Array)(b);c.j(u(d.call(c,a,g,h)),u(d.call(c,b,g,k)))}
+v.prototype.j=function(c,d){var a=this.b,b=this.a;this.n=c;for(var 
e=a.length-258,f,g,h,k;256!==(f=S(this,c));)if(256>f)b>=e&&(this.a=b,a=this.e(),b=this.a),a[b++]=f;else{g=f-257;k=F[g];0<H[g]&&(k+=y(this,H[g]));f=S(this,d);h=J[f];0<L[f]&&(h+=y(this,L[f]));b>=e&&(this.a=b,a=this.e(),b=this.a);for(;k--;)a[b]=a[b++-h]}for(;8<=this.c;)this.c-=8,this.d--;this.a=b};
+v.prototype.s=function(c,d){var a=this.b,b=this.a;this.n=c;for(var 
e=a.length,f,g,h,k;256!==(f=S(this,c));)if(256>f)b>=e&&(a=this.e(),e=a.length),a[b++]=f;else{g=f-257;k=F[g];0<H[g]&&(k+=y(this,H[g]));f=S(this,d);h=J[f];0<L[f]&&(h+=y(this,L[f]));b+k>e&&(a=this.e(),e=a.length);for(;k--;)a[b]=a[b++-h]}for(;8<=this.c;)this.c-=8,this.d--;this.a=b};
+v.prototype.e=function(){var c=new 
(r?Uint8Array:Array)(this.a-32768),d=this.a-32768,a,b,e=this.b;if(r)c.set(e.subarray(32768,c.length));else{a=0;for(b=c.length;a<b;++a)c[a]=e[a+32768]}this.g.push(c);this.k+=c.length;if(r)e.set(e.subarray(d,d+32768));else
 for(a=0;32768>a;++a)e[a]=e[d+a];this.a=32768;return e};
+v.prototype.u=function(c){var 
d,a=this.input.length/this.d+1|0,b,e,f,g=this.input,h=this.b;c&&("number"===typeof 
c.o&&(a=c.o),"number"===typeof 
c.q&&(a+=c.q));2>a?(b=(g.length-this.d)/this.n[2],f=258*(b/2)|0,e=f<h.length?h.length+f:h.length<<1):e=h.length*a;r?(d=new
 Uint8Array(e),d.set(h)):d=h;return this.b=d};
+v.prototype.m=function(){var c=0,d=this.b,a=this.g,b,e=new 
(r?Uint8Array:Array)(this.k+(this.a-32768)),f,g,h,k;if(0===a.length)return 
r?this.b.subarray(32768,this.a):this.b.slice(32768,this.a);f=0;for(g=a.length;f<g;++f){b=a[f];h=0;for(k=b.length;h<k;++h)e[c++]=b[h]}f=32768;for(g=this.a;f<g;++f)e[c++]=d[f];this.g=[];return
 this.buffer=e};
+v.prototype.r=function(){var c,d=this.a;r?this.p?(c=new 
Uint8Array(d),c.set(this.b.subarray(0,d))):c=this.b.subarray(0,d):(this.b.length>d&&(this.b.length=d),c=this.b);return
 this.buffer=c};q("Zlib.RawInflate",v);q("Zlib.RawInflate.prototype.decompress",v.prototype.t);var 
T={ADAPTIVE:w,BLOCK:x},U,V,W,X;if(Object.keys)U=Object.keys(T);else for(V in 
U=[],W=0,T)U[W++]=V;W=0;for(X=U.length;W<X;++W)V=U[W],q("Zlib.RawInflate.BufferType."+V,T[V]);}).call(this); 
//@ sourceMappingURL=rawinflate.min.js.map
diff --git a/gdk/broadway/toarray.pl b/gdk/broadway/toarray.pl
index e430885..b8cdb6f 100755
--- a/gdk/broadway/toarray.pl
+++ b/gdk/broadway/toarray.pl
@@ -1,15 +1,17 @@
 #!/usr/bin/perl -w
 
-my $FILENAME = $ARGV[0];
+my $ARRAYNAME = $ARGV[0];
+print "static const char $ARRAYNAME\[\] = \"";
 
-open FILE, $FILENAME or die "Cannot open $FILENAME";
-
-my $ARRAYNAME = $ARGV[1];
-print "static const char $ARRAYNAME\[\] =";
-while (<FILE>) {
-    s \\@\\\\ g;
-    s@"@\\"@g;
-    chomp ($_);
-    print "\n  \"$_\\n\"";
+for ($i = 1; $i <= $#ARGV; $i = $i + 1) {
+    my $FILENAME = $ARGV[$i];
+    open FILE, $FILENAME or die "Cannot open $FILENAME";
+    while (my $line = <FILE>) {
+        foreach my $c (split //, $line) {
+            printf ("\\x%02x", ord ($c));
+        }
+    }
 }
-print ";\n";
+
+print "\";\n";
+


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]