[gtk/wip/alexl/broadway7: 16/16] broadway: Optionally support data: uris instead of blobs



commit 12b647661113b13b8a02c35ea7ef7adfce55f3a9
Author: Alexander Larsson <alexl redhat com>
Date:   Fri Mar 29 13:18:17 2019 +0100

    broadway: Optionally support data: uris instead of blobs
    
    This is nice when you want to make a "screenshot" by using save-as.
    Its not going to perform as well though, so you have to enable it
    by adding ?datauri to the url

 gdk/broadway/broadway.js | 72 ++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 69 insertions(+), 3 deletions(-)
---
diff --git a/gdk/broadway/broadway.js b/gdk/broadway/broadway.js
index 0952399673..ba2fdcd727 100644
--- a/gdk/broadway/broadway.js
+++ b/gdk/broadway/broadway.js
@@ -93,6 +93,63 @@ const GDK_HYPER_MASK    = 1 << 27;
 const GDK_META_MASK     = 1 << 28;
 const GDK_RELEASE_MASK  = 1 << 30;
 
+
+var useDataUrls = window.location.search.includes("datauri");
+
+/* This base64code is based on https://github.com/beatgammit/base64-js/blob/master/index.js which is MIT 
licensed */
+
+var b64_lookup = [];
+var base64_code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
+for (var i = 0, len = base64_code.length; i < len; ++i) {
+    b64_lookup[i] = base64_code[i];
+}
+
+function tripletToBase64 (num) {
+    return b64_lookup[num >> 18 & 0x3F] +
+        b64_lookup[num >> 12 & 0x3F] +
+        b64_lookup[num >> 6 & 0x3F] +
+        b64_lookup[num & 0x3F];
+}
+
+function encodeBase64Chunk (uint8, start, end) {
+    var tmp;
+    var output = [];
+    for (var i = start; i < end; i += 3) {
+        tmp =
+            ((uint8[i] << 16) & 0xFF0000) +
+            ((uint8[i + 1] << 8) & 0xFF00) +
+            (uint8[i + 2] & 0xFF);
+        output.push(tripletToBase64(tmp));
+    }
+    return output.join('');
+}
+
+function bytesToDataUri(uint8) {
+    var tmp;
+    var len = uint8.length;
+    var extraBytes = len % 3; // if we have 1 byte left, pad 2 bytes
+    var parts = [];
+    var maxChunkLength = 16383; // must be multiple of 3
+
+    parts.push("data:image/png;base64,");
+
+    // go through the array every three bytes, we'll deal with trailing stuff later
+    for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {
+        parts.push(encodeBase64Chunk(uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength)));
+    }
+
+    // pad the end with zeros, but make sure to not forget the extra bytes
+    if (extraBytes === 1) {
+        tmp = uint8[len - 1];
+        parts.push(b64_lookup[tmp >> 2] + b64_lookup[(tmp << 4) & 0x3F] + '==');
+    } else if (extraBytes === 2) {
+        tmp = (uint8[len - 2] << 8) + uint8[len - 1];
+        parts.push(b64_lookup[tmp >> 10] + b64_lookup[(tmp >> 4) & 0x3F] + b64_lookup[(tmp << 2) & 0x3F] + 
'=');
+    }
+
+    return parts.join('');
+}
+
 /* Helper functions for debugging */
 var logDiv = null;
 function log(str) {
@@ -202,8 +259,15 @@ function getButtonMask (button) {
 }
 
 function Texture(id, data) {
-    var blob = new Blob([data],{type: "image/png"});
-    this.url = window.URL.createObjectURL(blob);
+    var url;
+    if (useDataUrls) {
+        url = bytesToDataUri(data);
+    } else {
+        var blob = new Blob([data],{type: "image/png"});
+        url = window.URL.createObjectURL(blob);
+    }
+
+    this.url = url;
     this.refcount = 1;
     this.id = id;
 
@@ -221,7 +285,9 @@ Texture.prototype.ref = function() {
 Texture.prototype.unref = function() {
     this.refcount -= 1;
     if (this.refcount == 0) {
-        window.URL.revokeObjectURL(this.url);
+        if (this.url.startsWith("blob")) {
+            window.URL.revokeObjectURL(this.url);
+        }
         delete textures[this.id];
     }
 }


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