From 63b31cf0b1f43738f780aeb834619a55ac949f8f Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Tue, 11 Aug 2015 19:17:06 -0700 Subject: [PATCH] GUAC-240: Read images received through "img" streams using a Guacamole.DataURIReader - appending to standard Blob objects is too slow. --- .../src/main/webapp/modules/Client.js | 6 +- .../src/main/webapp/modules/DataURIReader.js | 86 +++++++++++++++++++ 2 files changed, 89 insertions(+), 3 deletions(-) create mode 100644 guacamole-common-js/src/main/webapp/modules/DataURIReader.js diff --git a/guacamole-common-js/src/main/webapp/modules/Client.js b/guacamole-common-js/src/main/webapp/modules/Client.js index 799f9650f..31b3b398b 100644 --- a/guacamole-common-js/src/main/webapp/modules/Client.js +++ b/guacamole-common-js/src/main/webapp/modules/Client.js @@ -897,12 +897,12 @@ Guacamole.Client = function(tunnel) { // Create stream var stream = streams[stream_index] = new Guacamole.InputStream(guac_client, stream_index); - var reader = new Guacamole.BlobReader(stream, mimetype); + var reader = new Guacamole.DataURIReader(stream, mimetype); - // Draw blob when stream is complete + // Draw image when stream is complete reader.onend = function drawImageBlob() { display.setChannelMask(layer, channelMask); - display.drawBlob(layer, x, y, reader.getBlob()); + display.draw(layer, x, y, reader.getURI()); }; }, diff --git a/guacamole-common-js/src/main/webapp/modules/DataURIReader.js b/guacamole-common-js/src/main/webapp/modules/DataURIReader.js new file mode 100644 index 000000000..65e9c4d07 --- /dev/null +++ b/guacamole-common-js/src/main/webapp/modules/DataURIReader.js @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2015 Glyptodon LLC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +var Guacamole = Guacamole || {}; + +/** + * A reader which automatically handles the given input stream, returning + * received blobs as a single data URI built over the course of the stream. + * Note that this object will overwrite any installed event handlers on the + * given Guacamole.InputStream. + * + * @constructor + * @param {Guacamole.InputStream} stream + * The stream that data will be read from. + */ +Guacamole.DataURIReader = function(stream, mimetype) { + + /** + * Reference to this Guacamole.DataURIReader. + * @private + */ + var guac_reader = this; + + /** + * Current data URI. + * + * @type String + */ + var uri = 'data:' + mimetype + ';base64,'; + + // Receive blobs as array buffers + stream.onblob = function dataURIReaderBlob(data) { + + // Currently assuming data will ALWAYS be safe to simply append. This + // will not be true if the received base64 data encodes a number of + // bytes that isn't a multiple of three (as base64 expands in a ratio + // of exactly 3:4). + uri += data; + + }; + + // Simply call onend when end received + stream.onend = function dataURIReaderEnd() { + if (guac_reader.onend) + guac_reader.onend(); + }; + + /** + * Returns the data URI of all data received through the underlying stream + * thus far. + * + * @returns {String} + * The data URI of all data received through the underlying stream thus + * far. + */ + this.getURI = function getURI() { + return uri; + }; + + /** + * Fired once this stream is finished and no further data will be written. + * + * @event + */ + this.onend = null; + +}; \ No newline at end of file