Skip to content

Commit

Permalink
Merge pull request #430 from ivmartel/412-cancel-load
Browse files Browse the repository at this point in the history
Fixes #412.
  • Loading branch information
ivmartel authored Nov 28, 2017
2 parents 65895c3 + fcb3fab commit 7fb2962
Show file tree
Hide file tree
Showing 12 changed files with 602 additions and 212 deletions.
32 changes: 31 additions & 1 deletion src/app/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -550,6 +550,16 @@ dwv.App = function ()
*/
function loadImageData(data, loader, options)
{
// allow to cancel
var previousOnKeyDown = window.onkeydown;
window.onkeydown = function (event) {
if (event.ctrlKey && event.keyCode === 88 ) // crtl-x
{
console.log("crtl-x pressed!");
loader.abort();
}
};

// clear variables
self.reset();
// first data name
Expand All @@ -575,7 +585,9 @@ dwv.App = function ()
postLoadInit(data);
};
loader.onerror = function (error) { handleError(error); };
loader.onabort = function (error) { handleAbort(error); };
loader.onloadend = function (/*event*/) {
window.onkeydown = previousOnKeyDown;
if ( drawController ) {
drawController.activateDrawLayer(viewController);
}
Expand Down Expand Up @@ -1234,7 +1246,7 @@ dwv.App = function ()
{
// alert window
if ( error.name && error.message) {
alert(error.name+": "+error.message+".");
alert(error.name+": "+error.message);
}
else {
alert("Error: "+error+".");
Expand All @@ -1247,6 +1259,24 @@ dwv.App = function ()
dwv.gui.displayProgress(100);
}

/**
* Handle an abort: display it to the user.
* @param {Object} error The error to handle.
* @private
*/
function handleAbort(error)
{
// log
if ( error.message ) {
console.warn(error.message);
}
else {
console.warn("Abort called.");
}
// stop progress
dwv.gui.displayProgress(100);
}

/**
* Handle a load progress.
* @private
Expand Down
69 changes: 39 additions & 30 deletions src/image/decoder.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,14 @@ dwv.image.AsynchPixelBufferDecoder = function (script)
// add it the queue and run it
pool.addWorkerTask(workerTask);
};

/**
* Abort decoding.
*/
this.abort = function () {
// abort the thread pool
pool.abort();
};
};

/**
Expand Down Expand Up @@ -72,12 +80,12 @@ dwv.image.SynchPixelBufferDecoder = function (algoName)
* @param {Array} pixelBuffer The pixel buffer.
* @param {Number} bitsAllocated The bits allocated per element in the buffer.
* @param {Boolean} isSigned Is the data signed.
* @return {Array} The decoded pixel buffer.
* @param {Function} callback Callback function to handle decoded data.
* @external jpeg
* @external JpegImage
* @external JpxImage
*/
this.decode = function (pixelBuffer, bitsAllocated, isSigned) {
this.decode = function (pixelBuffer, bitsAllocated, isSigned, callback) {
var decoder = null;
var decodedBuffer = null;
if( algoName === "jpeg-lossless" ) {
Expand Down Expand Up @@ -127,8 +135,15 @@ dwv.image.SynchPixelBufferDecoder = function (algoName)
// send events
this.ondecoded();
this.ondecodeend();
// return result as array
return [decodedBuffer];
// call callback with decoded buffer as array
callback({data: [decodedBuffer]});
};

/**
* Abort decoding.
*/
this.abort = function () {
// nothing to do in the synchronous case.
};
};

Expand All @@ -155,20 +170,22 @@ dwv.image.SynchPixelBufferDecoder.prototype.ondecoded = function ()
* If the 'dwv.image.decoderScripts' variable does not contain the desired algorythm,
* the decoder will switch to the synchronous mode.
*/
dwv.image.PixelBufferDecoder = function (algoName, asynch)
dwv.image.PixelBufferDecoder = function (algoName)
{
/**
* Asynchronous decoder.
* Pixel decoder.
* Defined only once.
* @private
* @type Object
*/
var asynchDecoder = null;
var pixelDecoder = null;

// initialise the asynch decoder (if possible)
if (typeof dwv.image.decoderScripts !== "undefined" &&
typeof dwv.image.decoderScripts[algoName] !== "undefined") {
asynchDecoder = new dwv.image.AsynchPixelBufferDecoder(dwv.image.decoderScripts[algoName]);
pixelDecoder = new dwv.image.AsynchPixelBufferDecoder(dwv.image.decoderScripts[algoName]);
} else {
pixelDecoder = new dwv.image.SynchPixelBufferDecoder(algoName);
}

/**
Expand All @@ -177,31 +194,23 @@ dwv.image.PixelBufferDecoder = function (algoName, asynch)
* @param {Number} bitsAllocated The bits allocated per element in the buffer.
* @param {Boolean} isSigned Is the data signed.
* @param {Object} callback The callback on the conversion.
* @param {Boolean} asynch Should the decoder run asynchronously, default to true.
*/
this.decode = function (pixelBuffer, bitsAllocated, isSigned, callback)
{
// default to asynch
asynch = (typeof asynch === 'undefined') ? true : asynch;

// run asynchronous if asked and we have scripts
if (asynch && asynchDecoder !== null) {
// (re)set event handler
asynchDecoder.ondecodeend = this.ondecodeend;
asynchDecoder.ondecoded = this.ondecoded;
// decode and call the callback
asynchDecoder.decode(pixelBuffer, bitsAllocated, isSigned, callback);
}
else {
// create the decoder
var synchDecoder = new dwv.image.SynchPixelBufferDecoder(algoName);
synchDecoder.ondecodeend = this.ondecodeend;
synchDecoder.ondecoded = this.ondecoded;
// decode
var decodedBuffer = synchDecoder.decode(pixelBuffer, bitsAllocated, isSigned);
// call the callback
callback({data: decodedBuffer});
}
// set event handler
pixelDecoder.ondecodeend = this.ondecodeend;
pixelDecoder.ondecoded = this.ondecoded;
// decode and call the callback
pixelDecoder.decode(pixelBuffer, bitsAllocated, isSigned, callback);
};

/**
* Abort decoding.
*/
this.abort = function ()
{
// decoder classes should define an abort
pixelDecoder.abort();
};
};

Expand Down
9 changes: 9 additions & 0 deletions src/image/dicomBufferToView.js
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,15 @@ dwv.image.DicomBufferToView = function ()
self.onloadend();
}
};

/**
* Abort a conversion.
*/
this.abort = function () {
if ( pixelDecoder ) {
pixelDecoder.abort();
}
};
};

/**
Expand Down
74 changes: 49 additions & 25 deletions src/io/dicomDataLoader.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,13 @@ dwv.io.DicomDataLoader = function ()
*/
var options = {};

/**
* Loading flag.
* @private
* @type Boolean
*/
var isLoading = false;

/**
* Set the loader options.
* @param {Object} opt The input options.
Expand All @@ -25,6 +32,14 @@ dwv.io.DicomDataLoader = function ()
options = opt;
};

/**
* Is the load ongoing?
* @return {Boolean} True if loading.
*/
this.isLoading = function () {
return isLoading;
};

/**
* DICOM buffer to dwv.image.View (asynchronous)
*/
Expand All @@ -37,22 +52,43 @@ dwv.io.DicomDataLoader = function ()
* @param {Number} index The data index.
*/
this.load = function (buffer, origin, index) {
// set loading flag
isLoading = true;
// set character set
if (typeof options.defaultCharacterSet !== "undefined") {
db2v.setDefaultCharacterSet(options.defaultCharacterSet);
}
// connect handlers
db2v.onload = self.onload;
db2v.onloadend = self.onloadend;
db2v.onloadend = function () {
// reset loading flag
isLoading = false;
// call listeners
self.onloadend();
};
db2v.onprogress = self.onprogress;
// convert
try {
db2v.convert( buffer, index );
} catch (error) {
// TODO: error will be for individual file, isLoading is global...
//isLoading = false;
self.onerror(error);
}
};

/**
* Abort load.
*/
this.abort = function () {
// abort conversion
db2v.abort();
// reset loading flag
isLoading = false;
// call listeners
self.onabort({message: "Abort while loading DICOM data."});
};

/**
* Get a file load handler.
* @param {Object} file The file to load.
Expand Down Expand Up @@ -87,25 +123,6 @@ dwv.io.DicomDataLoader = function ()
};
};

/**
* Get an error handler.
* @param {String} origin The file.name/url at the origin of the error.
* @return {Function} An error handler.
*/
this.getErrorHandler = function (origin) {
return function (event) {
var message = "";
if (typeof event.getMessage !== "undefined") {
message = event.getMessage();
} else if (typeof this.status !== "undefined") {
message = "http status: " + this.status;
}
self.onerror( {'name': "RequestError",
'message': "An error occurred while reading '" + origin +
"' (" + message + ") [DicomDataLoader]" } );
};
};

}; // class DicomDataLoader

/**
Expand Down Expand Up @@ -169,19 +186,26 @@ dwv.io.DicomDataLoader.prototype.onload = function (/*event*/) {};
* Default does nothing.
*/
dwv.io.DicomDataLoader.prototype.onloadend = function () {};
/**
* Handle a progress event.
* @param {Object} event The progress event.
* Default does nothing.
*/
dwv.io.DicomDataLoader.prototype.onprogress = function (/*event*/) {};
/**
* Handle an error event.
* @param {Object} event The error event, 'event.message'
* should be the error message.
* @param {Object} event The error event with an
* optional 'event.message'.
* Default does nothing.
*/
dwv.io.DicomDataLoader.prototype.onerror = function (/*event*/) {};
/**
* Handle a progress event.
* @param {Object} event The progress event.
* Handle an abort event.
* @param {Object} event The abort event with an
* optional 'event.message'.
* Default does nothing.
*/
dwv.io.DicomDataLoader.prototype.onprogress = function (/*event*/) {};
dwv.io.DicomDataLoader.prototype.onabort = function (/*event*/) {};

/**
* Add to Loader list.
Expand Down
Loading

0 comments on commit 7fb2962

Please sign in to comment.