GUACAMOLE-884: Merge Leverage createImageBitmap() for reading image data where supported

This commit is contained in:
Virtually Nick
2019-10-09 15:52:09 -04:00
committed by GitHub
3 changed files with 108 additions and 30 deletions

View File

@@ -1190,13 +1190,10 @@ Guacamole.Client = function(tunnel) {
// Create stream // Create stream
var stream = streams[stream_index] = new Guacamole.InputStream(guac_client, stream_index); var stream = streams[stream_index] = new Guacamole.InputStream(guac_client, stream_index);
var reader = new Guacamole.DataURIReader(stream, mimetype);
// Draw image when stream is complete // Draw received contents once decoded
reader.onend = function drawImageBlob() { display.setChannelMask(layer, channelMask);
display.setChannelMask(layer, channelMask); display.drawStream(layer, x, y, stream, mimetype);
display.draw(layer, x, y, reader.getURI());
};
}, },

View File

@@ -512,11 +512,17 @@ Guacamole.Display = function() {
* Draws the specified image at the given coordinates. The image specified * Draws the specified image at the given coordinates. The image specified
* must already be loaded. * must already be loaded.
* *
* @param {Guacamole.Layer} layer The layer to draw upon. * @param {Guacamole.Layer} layer
* @param {Number} x The destination X coordinate. * The layer to draw upon.
* @param {Number} y The destination Y coordinate. *
* @param {Image} image The image to draw. Note that this is an Image * @param {Number} x
* object - not a URL. * The destination X coordinate.
*
* @param {Number} y
* The destination Y coordinate.
*
* @param {CanvasImageSource} image
* The image to draw. Note that this not a URL.
*/ */
this.drawImage = function(layer, x, y, image) { this.drawImage = function(layer, x, y, image) {
scheduleTask(function __display_drawImage() { scheduleTask(function __display_drawImage() {
@@ -543,26 +549,97 @@ Guacamole.Display = function() {
*/ */
this.drawBlob = function(layer, x, y, blob) { this.drawBlob = function(layer, x, y, blob) {
// Create URL for blob var task;
var url = URL.createObjectURL(blob);
// Draw and free blob URL when ready // Prefer createImageBitmap() over blob URLs if available
var task = scheduleTask(function __display_drawBlob() { if (window.createImageBitmap) {
// Draw the image only if it loaded without errors var bitmap;
if (image.width && image.height)
layer.drawImage(x, y, image);
// Blob URL no longer needed // Draw image once loaded
URL.revokeObjectURL(url); task = scheduleTask(function drawImageBitmap() {
layer.drawImage(x, y, bitmap);
}, true);
}, true); // Load image from provided blob
window.createImageBitmap(blob).then(function bitmapLoaded(decoded) {
bitmap = decoded;
task.unblock();
});
// Load image from URL }
var image = new Image();
image.onload = task.unblock; // Use blob URLs and the Image object if createImageBitmap() is
image.onerror = task.unblock; // unavailable
image.src = url; else {
// Create URL for blob
var url = URL.createObjectURL(blob);
// Draw and free blob URL when ready
task = scheduleTask(function __display_drawBlob() {
// Draw the image only if it loaded without errors
if (image.width && image.height)
layer.drawImage(x, y, image);
// Blob URL no longer needed
URL.revokeObjectURL(url);
}, true);
// Load image from URL
var image = new Image();
image.onload = task.unblock;
image.onerror = task.unblock;
image.src = url;
}
};
/**
* Draws the image within the given stream at the given coordinates. The
* image will be loaded automatically, and this and any future operations
* will wait for the image to finish loading. This function will
* automatically choose an approriate method for reading and decoding the
* given image stream, and should be preferred for received streams except
* where manual decoding of the stream is unavoidable.
*
* @param {Guacamole.Layer} layer
* The layer to draw upon.
*
* @param {Number} x
* The destination X coordinate.
*
* @param {Number} y
* The destination Y coordinate.
*
* @param {Guacamole.InputStream} stream
* The stream along which image data will be received.
*
* @param {String} mimetype
* The mimetype of the image within the stream.
*/
this.drawStream = function drawStream(layer, x, y, stream, mimetype) {
// If createImageBitmap() is available, load the image as a blob so
// that function can be used
if (window.createImageBitmap) {
var reader = new Guacamole.BlobReader(stream, mimetype);
reader.onend = function drawImageBlob() {
guac_display.drawBlob(layer, x, y, reader.getBlob());
};
}
// Lacking createImageBitmap(), fall back to data URIs and the Image
// object
else {
var reader = new Guacamole.DataURIReader(stream, mimetype);
reader.onend = function drawImageDataURI() {
guac_display.draw(layer, x, y, reader.getURI());
};
}
}; };

View File

@@ -319,10 +319,14 @@ Guacamole.Layer = function(width, height) {
* Draws the specified image at the given coordinates. The image specified * Draws the specified image at the given coordinates. The image specified
* must already be loaded. * must already be loaded.
* *
* @param {Number} x The destination X coordinate. * @param {Number} x
* @param {Number} y The destination Y coordinate. * The destination X coordinate.
* @param {Image} image The image to draw. Note that this is an Image *
* object - not a URL. * @param {Number} y
* The destination Y coordinate.
*
* @param {CanvasImageSource} image
* The image to draw. Note that this is not a URL.
*/ */
this.drawImage = function(x, y, image) { this.drawImage = function(x, y, image) {
if (layer.autosize) fitRect(x, y, image.width, image.height); if (layer.autosize) fitRect(x, y, image.width, image.height);