Merge branch 'master' of https://github.com/OHIF/Viewers
This commit is contained in:
commit
d1d4e09815
@ -60,7 +60,8 @@ CSocket = function(socket, options) {
|
||||
this.on("released", function() {
|
||||
this.released();
|
||||
});
|
||||
this.on('aborted', function() {
|
||||
this.on('aborted', function(pdu) {
|
||||
console.log('Assocation aborted with reason ' + pdu.reason);
|
||||
this.released();
|
||||
})
|
||||
this.on('message', function(pdvs) {
|
||||
@ -153,11 +154,20 @@ CSocket.prototype.setPresentationContexts = function(uids) {
|
||||
var contexts = [],
|
||||
id = 0;
|
||||
uids.forEach(function(uid) {
|
||||
contexts.push({
|
||||
id: ++id,
|
||||
abstractSyntax: uid,
|
||||
transferSyntaxes: [C.IMPLICIT_LITTLE_ENDIAN, C.EXPLICIT_LITTLE_ENDIAN, C.EXPLICIT_BIG_ENDIAN]
|
||||
});
|
||||
id++;
|
||||
if (typeof uid == 'string') {
|
||||
contexts.push({
|
||||
id: id,
|
||||
abstractSyntax: uid,
|
||||
transferSyntaxes: [C.IMPLICIT_LITTLE_ENDIAN, C.EXPLICIT_LITTLE_ENDIAN, C.EXPLICIT_BIG_ENDIAN]
|
||||
});
|
||||
} else {
|
||||
contexts.push({
|
||||
id: id,
|
||||
abstractSyntax: uid.context,
|
||||
transferSyntaxes: uid.syntaxes
|
||||
});
|
||||
}
|
||||
});
|
||||
this.presentationContexts = contexts;
|
||||
};
|
||||
@ -174,9 +184,7 @@ CSocket.prototype.send = function(pdu, afterCbk) {
|
||||
//console.log('SEND PDU-TYPE: ', pdu.type);
|
||||
var toSend = pdu.buffer();
|
||||
//console.log('send buffer', toSend.toString('hex'));
|
||||
this.socket.write(toSend, afterCbk ? afterCbk : function() {
|
||||
//console.log('Data written');
|
||||
});
|
||||
return this.socket.write(toSend, afterCbk ? afterCbk : null);
|
||||
};
|
||||
|
||||
CSocket.prototype.release = function() {
|
||||
@ -318,7 +326,7 @@ CSocket.prototype.interpret = function(stream) {
|
||||
this.emit('released');
|
||||
} else if (pdu.is(C.ITEM_TYPE_PDU_AABORT)) {
|
||||
//console.log('Aborted');
|
||||
this.emit('aborted');
|
||||
this.emit('aborted', pdu);
|
||||
} else if (pdu.is(C.ITEM_TYPE_PDU_PDATA)) {
|
||||
pdatas.push(pdu);
|
||||
}
|
||||
@ -363,16 +371,19 @@ CSocket.prototype.receivedMessage = function(pdv) {
|
||||
this.lastCommand = msg;
|
||||
|
||||
if (msg.isResponse()) {
|
||||
var replyId = msg.respondedTo(),
|
||||
listener = this.messages[replyId].listener;
|
||||
|
||||
if (msg.is(C.COMMAND_C_GET_RSP) || msg.is(C.COMMAND_C_MOVE_RSP)) {
|
||||
//console.log('remaining', msg.getNumOfRemainingSubOperations(), msg.getNumOfCompletedSubOperations());
|
||||
}
|
||||
if (msg.failure()) {
|
||||
//console.log("message failed with status ", msg.getStatus().toString(16));
|
||||
console.log("message failed with status ", msg.getStatus().toString(16));
|
||||
}
|
||||
listener.emit('response', msg);
|
||||
if (msg.isFinal()) {
|
||||
var replyId = msg.respondedTo();
|
||||
if (this.messages[replyId].listener) {
|
||||
this.messages[replyId].listener.emit('end', msg);
|
||||
if (listener) {
|
||||
listener.emit('end', msg);
|
||||
|
||||
if (!msg.haveData())
|
||||
delete this.messages[replyId];
|
||||
@ -474,9 +485,9 @@ CSocket.prototype.sendMessage = function(context, command, dataset) {
|
||||
|
||||
msgData.command = command;
|
||||
this.messages[messageId] = msgData;
|
||||
|
||||
console.log('Sending command ' + command.typeString());
|
||||
this.send(pdata);
|
||||
if (dataset) {
|
||||
if (dataset && typeof dataset == 'object') {
|
||||
dataset.setSyntax(syntax);
|
||||
var dsData = new PDataTF(),
|
||||
dPdv = new PresentationDataValueItem(cid);
|
||||
@ -488,6 +499,14 @@ CSocket.prototype.sendMessage = function(context, command, dataset) {
|
||||
return msgData.listener;
|
||||
};
|
||||
|
||||
CSocket.prototype.sendPData = function(pdv, after) {
|
||||
var pdata = new PDataTF();
|
||||
pdata.setPresentationDataValueItems([pdv]);
|
||||
//console.log('Sending pdata');
|
||||
//console.log(pdata.totalLength());
|
||||
this.send(pdata, after);
|
||||
};
|
||||
|
||||
CSocket.prototype.verify = function() {
|
||||
this.setPresentationContexts([C.SOP_VERIFICATION]);
|
||||
this.startAssociationRequest(function() {
|
||||
@ -515,6 +534,14 @@ CSocket.prototype.move = function(destination, params, options) {
|
||||
return this.sendMessage(options.context, moveMessage, this.wrapMessage(params));
|
||||
};
|
||||
|
||||
CSocket.prototype.storeInstance = function(sopClassUID, sopInstanceUID, options) {
|
||||
var storeMessage = new CStoreRQ();
|
||||
storeMessage.setAffectedSOPInstanceUID(sopInstanceUID);
|
||||
storeMessage.setAffectedSOPClassUID(sopClassUID);
|
||||
|
||||
return this.sendMessage(sopClassUID, storeMessage, true);
|
||||
}
|
||||
|
||||
CSocket.prototype.moveInstances = function(destination, params, options) {
|
||||
var sendParams = Object.assign({
|
||||
0x00080052: C.QUERY_RETRIEVE_LEVEL_IMAGE,
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
var EventEmitter = Npm.require('events').EventEmitter, net = Npm.require('net'), Socket = net.Socket;
|
||||
var net = Npm.require('net'),
|
||||
Socket = net.Socket;
|
||||
|
||||
var DEFAULT_MAX_PACKAGE_SIZE = 32768;
|
||||
|
||||
@ -21,6 +22,11 @@ Connection = function(options) {
|
||||
|
||||
util.inherits(Connection, EventEmitter);
|
||||
|
||||
var StoreHandle = function() {
|
||||
EventEmitter.call(this);
|
||||
}
|
||||
util.inherits(StoreHandle, EventEmitter);
|
||||
|
||||
Connection.prototype.addPeer = function(options) {
|
||||
if (!options.aeTitle || !options.host || !options.port) {
|
||||
return false;
|
||||
@ -65,6 +71,92 @@ Connection.prototype.selectPeer = function(aeTitle) {
|
||||
return this.peers[aeTitle];
|
||||
}
|
||||
|
||||
Connection.prototype._sendFile = function(socket, sHandle, file, maxSend, metaLength, list) {
|
||||
var fileNameText = typeof file.file == 'string' ? file.file : 'buffer';
|
||||
console.log("Sending file " + fileNameText);
|
||||
var useContext = socket.getContextByUID(file.context), self = this;
|
||||
|
||||
PDU.generatePDatas(useContext.id, file.file, maxSend, null, metaLength, function(err, handle) {
|
||||
if (err) {
|
||||
console.log('Error while sending file');
|
||||
return;
|
||||
}
|
||||
var processNext = function() {
|
||||
var next = list.shift();
|
||||
if (next)
|
||||
self._sendFile(socket, sHandle, next, maxSend, metaLength, list);
|
||||
else
|
||||
socket.release();
|
||||
};
|
||||
|
||||
var store = socket.storeInstance(useContext.abstractSyntax, file.uid);
|
||||
handle.on('pdv', function(pdv) {
|
||||
socket.sendPData(pdv);
|
||||
});
|
||||
handle.on('error', function(err) {
|
||||
sHandle.emit('file', err, fileNameText);
|
||||
processNext();
|
||||
});
|
||||
store.on('response', function(msg) {
|
||||
var statusText = msg.getStatus().toString(16);
|
||||
console.log('STORE reponse with status', statusText);
|
||||
var error = null;
|
||||
if (msg.failure()) {
|
||||
error = new Error(statusText);
|
||||
}
|
||||
sHandle.emit('file', error, fileNameText);
|
||||
processNext();
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
Connection.prototype.storeInstances = function(fileList) {
|
||||
var contexts = {}, read = 0, length = fileList.length, toSend = [], self = this, handle = new StoreHandle();
|
||||
fileList.forEach(function(bufferOrFile){
|
||||
var fileNameText = typeof bufferOrFile == 'string' ? bufferOrFile : 'buffer';
|
||||
DicomMessage.readMetaHeader(bufferOrFile, function(err, metaMessage, metaLength) {
|
||||
read++;
|
||||
if (err) {
|
||||
handle.emit('file', err, fileNameText);
|
||||
return;
|
||||
}
|
||||
console.log('Dicom file ' + (typeof bufferOrFile == 'string' ? bufferOrFile : 'buffer') + ' found');
|
||||
var syntax = metaMessage.getValue(0x00020010),
|
||||
sopClassUID = metaMessage.getValue(0x00020002),
|
||||
instanceUID = metaMessage.getValue(0x00020003);
|
||||
|
||||
if (!contexts[sopClassUID]) {
|
||||
contexts[sopClassUID] = [];
|
||||
}
|
||||
if (syntax && contexts[sopClassUID].indexOf(syntax) == -1) {
|
||||
contexts[sopClassUID].push(syntax);
|
||||
}
|
||||
toSend.push({file : bufferOrFile, context : sopClassUID, uid : instanceUID});
|
||||
|
||||
if (read == length) {
|
||||
var useContexts = [];
|
||||
for (var context in contexts) {
|
||||
var useSyntaxes = contexts[context];
|
||||
if (useSyntaxes.length > 0) {
|
||||
useContexts.push({context : context, syntaxes : contexts[context]});
|
||||
} else {
|
||||
throw "No syntax specified for context " + context;
|
||||
}
|
||||
}
|
||||
|
||||
self.associate({
|
||||
contexts : useContexts
|
||||
}, function(ac) {
|
||||
var maxSend = ac.getMaxSize(), next = toSend.shift();
|
||||
self._sendFile(this, handle, next, maxSend, metaLength, toSend);
|
||||
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
return handle;
|
||||
};
|
||||
|
||||
Connection.prototype.storeResponse = function(messageId, msg) {
|
||||
var rq = this.messages[messageId];
|
||||
|
||||
|
||||
@ -179,6 +179,13 @@ DIMSE.retrieveInstances = function(studyInstanceUID, seriesInstanceUID, params,
|
||||
return future.wait();
|
||||
};
|
||||
|
||||
DIMSE.storeInstances = function(fileList) {
|
||||
var handle = conn.storeInstances(fileList);
|
||||
handle.on('file', function(err, file) {
|
||||
console.log(err, file);
|
||||
})
|
||||
};
|
||||
|
||||
DIMSE.moveInstances = function(studyInstanceUID, seriesInstanceUID, sopInstanceUID, sopClassUID, params) {
|
||||
DIMSE.associate([C.SOP_STUDY_ROOT_MOVE, sopClassUID], function() {
|
||||
var defaultParams = {
|
||||
|
||||
@ -73,7 +73,7 @@ ValueRepresentation.prototype.read = function(stream, length, syntax) {
|
||||
if (!length)
|
||||
return this.defaultValue;
|
||||
if (this.maxLength != length)
|
||||
throw "Invalid length for fixed length tag, vr " + this.type + ", length " + this.maxLength + " != " + length;
|
||||
console.log("Invalid length for fixed length tag, vr " + this.type + ", length " + this.maxLength + " != " + length);
|
||||
}
|
||||
return this.readBytes(stream, length, syntax);
|
||||
}
|
||||
@ -212,11 +212,12 @@ DateValue = function() {
|
||||
util.inherits(DateValue, ValueRepresentation);
|
||||
|
||||
DateValue.prototype.readBytes = function(stream, length) {
|
||||
var datestr = stream.read(C.TYPE_ASCII, 8);
|
||||
var datestr = stream.read(C.TYPE_ASCII, length);
|
||||
|
||||
var year = parseInt(datestr.substring(0,4)),
|
||||
month = parseInt(datestr.substring(4,6)),
|
||||
day = parseInt(datestr.substring(6,8));
|
||||
|
||||
return datestr;//new Date(year, month, day);
|
||||
}
|
||||
|
||||
@ -701,6 +702,20 @@ OtherWordString.prototype.getFields = function(value) {
|
||||
return OtherWordString.super_.prototype.getFields.call(this, [new StringField(value)]);
|
||||
}
|
||||
|
||||
OtherByteString = function() {
|
||||
ValueRepresentation.call(this, "OB");
|
||||
this.maxLength = null;
|
||||
this.padByte = "00";
|
||||
};
|
||||
util.inherits(OtherByteString, ValueRepresentation);
|
||||
|
||||
OtherByteString.prototype.readBytes = function(stream, length) {
|
||||
return stream.read(C.TYPE_HEX, length);
|
||||
}
|
||||
|
||||
OtherByteString.prototype.getFields = function(value) {
|
||||
return OtherByteString.super_.prototype.getFields.call(this, [new HexField(value)]);
|
||||
}
|
||||
|
||||
elementByType = function(type, value, syntax) {
|
||||
var elem = null, nk = DicomElements.dicomNDict[type];
|
||||
@ -789,6 +804,18 @@ readElements = function(stream, syntax) {
|
||||
stream.setEndian(oldEndian);
|
||||
}
|
||||
|
||||
readAElement = function(stream, syntax) {
|
||||
var elem = newElementWithSyntax(syntax);
|
||||
elem.readBytes(stream);
|
||||
return elem;
|
||||
}
|
||||
|
||||
newElementWithSyntax = function(syntax) {
|
||||
var elem = new DataElement();
|
||||
elem.setSyntax(syntax);
|
||||
return elem;
|
||||
}
|
||||
|
||||
var explicitVRList = ["OB", "OW", "OF", "SQ", "UC", "UR", "UT", "UN"],
|
||||
binaryVRs = ["FL", "FD", "SL", "SS", "UL", "US"];
|
||||
|
||||
|
||||
@ -15,6 +15,21 @@ Field.prototype.isNumeric = function() {
|
||||
return false;
|
||||
}
|
||||
|
||||
BufferField = function(buffer, start, length) {
|
||||
Field.call(this, C.TYPE_BUFFER, buffer);
|
||||
this.bufferLength = length;
|
||||
this.bufferStart = start;
|
||||
}
|
||||
util.inherits(BufferField, Field);
|
||||
|
||||
BufferField.prototype.length = function() {
|
||||
return this.bufferLength;
|
||||
}
|
||||
|
||||
BufferField.prototype.write = function(stream) {
|
||||
stream.writeRawBuffer(this.value, this.bufferStart, this.bufferLength);
|
||||
}
|
||||
|
||||
StringField = function(str) {
|
||||
Field.call(this, C.TYPE_ASCII, typeof str == 'string' ? str : "");
|
||||
}
|
||||
|
||||
@ -173,7 +173,7 @@ DicomMessage.prototype.printElements = function(pairs, indent) {
|
||||
return typeName;
|
||||
}
|
||||
|
||||
DicomMessage.prototype.toString = function() {
|
||||
DicomMessage.prototype.typeString = function() {
|
||||
var typeName = "";
|
||||
if (!this.isCommand()) {
|
||||
typeName = "DateSet Message";
|
||||
@ -188,7 +188,12 @@ DicomMessage.prototype.toString = function() {
|
||||
case C.COMMAND_C_FIND_RQ : typeName = "C-FIND-RQ"; break;
|
||||
case C.COMMAND_C_STORE_RSP : typeName = "C-STORE-RSP"; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return typeName;
|
||||
}
|
||||
|
||||
DicomMessage.prototype.toString = function() {
|
||||
var typeName = this.typeString();
|
||||
typeName += " [\n";
|
||||
typeName += this.printElements(this.elementPairs, 0);
|
||||
typeName += "]";
|
||||
@ -217,6 +222,83 @@ DicomMessage.prototype.toObject = function() {
|
||||
return this.walkObject(this.elementPairs);
|
||||
}
|
||||
|
||||
DicomMessage.readToPairs = function(stream, syntax, options) {
|
||||
var pairs = {};
|
||||
while (!stream.end()) {
|
||||
var elem = new DataElement();
|
||||
if (options) {
|
||||
elem.setOptions(options);
|
||||
}
|
||||
elem.setSyntax(syntax);
|
||||
elem.readBytes(stream);
|
||||
pairs[elem.tag.value] = elem;
|
||||
}
|
||||
return pairs;
|
||||
}
|
||||
|
||||
var fileValid = function(stream) {
|
||||
return stream.readString(4, C.TYPE_ASCII) == 'DICM';
|
||||
}
|
||||
|
||||
var readMetaStream = function(stream, useSyntax, length, callback) {
|
||||
var message = new FileMetaMessage();
|
||||
message.setElementPairs(DicomMessage.readToPairs(stream, useSyntax));
|
||||
if (callback) {
|
||||
callback(null, message, length);
|
||||
}
|
||||
return message;
|
||||
}
|
||||
|
||||
DicomMessage.readMetaHeader = function(bufferOrFile, callback) {
|
||||
var useSyntax = C.EXPLICIT_LITTLE_ENDIAN;
|
||||
if (bufferOrFile instanceof Buffer) {
|
||||
var stream = new ReadStream(bufferOrFile);
|
||||
stream.reset();
|
||||
stream.increment(128);
|
||||
if (!fileValid(stream)) {
|
||||
return quitWithError('Invalid a dicom file ', callback);
|
||||
}
|
||||
var el = readAElement(stream, useSyntax),
|
||||
metaLength = el.value,
|
||||
metaStream = stream.more(metaLength);
|
||||
|
||||
return readMetaStream(metaStream, useSyntax, metaLength, callback);
|
||||
} else if (typeof bufferOrFile == 'string') {
|
||||
fs.open(bufferOrFile, 'r', function(err, fd) {
|
||||
if (err) {
|
||||
//fs.closeSync(fd);
|
||||
return quitWithError('Cannot open file', callback);
|
||||
}
|
||||
var buffer = new Buffer(16);
|
||||
fs.read(fd, buffer, 0, 16, 128, function(err, bytesRead) {
|
||||
if (err || bytesRead != 16) {
|
||||
fs.closeSync(fd);
|
||||
return quitWithError('Cannot read file', callback);
|
||||
}
|
||||
var stream = new ReadStream(buffer);
|
||||
if (!fileValid(stream)) {
|
||||
fs.closeSync(fd);
|
||||
return quitWithError('Not a dicom file ' + bufferOrFile, callback);
|
||||
}
|
||||
var el = readAElement(stream, useSyntax),
|
||||
metaLength = el.value,
|
||||
metaBuffer = new Buffer(metaLength);
|
||||
|
||||
fs.read(fd, metaBuffer, 0, metaLength, 144, function(err, bytesRead) {
|
||||
fs.closeSync(fd);
|
||||
if (err || bytesRead != metaLength) {
|
||||
return quitWithError('Invalid a dicom file ' + bufferOrFile, callback);
|
||||
}
|
||||
var metaStream = new ReadStream(metaBuffer);
|
||||
return readMetaStream(metaStream, useSyntax, metaLength, callback);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
DicomMessage.read = function(stream, type, syntax, options) {
|
||||
var elements = [], pairs = {}, useSyntax = type == C.DATA_TYPE_COMMAND ? C.IMPLICIT_LITTLE_ENDIAN : syntax;
|
||||
stream.reset();
|
||||
@ -240,6 +322,7 @@ DicomMessage.read = function(stream, type, syntax, options) {
|
||||
case 0x8010 : message = new CGetRSP(useSyntax); break;
|
||||
case 0x0001 : message = new CStoreRQ(useSyntax); break;
|
||||
case 0x0020 : message = new CFindRQ(useSyntax); break;
|
||||
case 0x8001 : message = new CStoreRSP(useSyntax); break;
|
||||
default : throw "Unrecognized command type " + cmdType.toString(16); break;
|
||||
}
|
||||
|
||||
@ -270,6 +353,12 @@ DataSetMessage.prototype.is = function(type) {
|
||||
return false;
|
||||
}
|
||||
|
||||
FileMetaMessage = function(syntax){
|
||||
DicomMessage.call(this, syntax);
|
||||
this.type = null
|
||||
};
|
||||
util.inherits(FileMetaMessage, DicomMessage);
|
||||
|
||||
CommandMessage = function(syntax) {
|
||||
DicomMessage.call(this, syntax);
|
||||
this.type = C.DATA_TYPE_COMMAND;
|
||||
@ -438,10 +527,18 @@ CStoreRQ.prototype.getMoveMessageId = function() {
|
||||
return this.getValue(0x00001031);
|
||||
}
|
||||
|
||||
CStoreRQ.prototype.getSOPInstanceUID = function() {
|
||||
CStoreRQ.prototype.getAffectedSOPInstanceUID = function() {
|
||||
return this.getValue(0x00001000);
|
||||
}
|
||||
|
||||
CStoreRQ.prototype.setAffectedSOPInstanceUID = function(uid) {
|
||||
this.setElement(0x00001000, uid);
|
||||
}
|
||||
|
||||
CStoreRQ.prototype.setAffectedSOPClassUID = function(uid) {
|
||||
this.setElement(0x00000002, uid);
|
||||
}
|
||||
|
||||
CStoreRSP = function(syntax) {
|
||||
CommandResponse.call(this, syntax);
|
||||
this.commandType = 0x8001;
|
||||
|
||||
@ -1,3 +1,8 @@
|
||||
PDVHandle = function() {
|
||||
|
||||
}
|
||||
util.inherits(PDVHandle, EventEmitter);
|
||||
|
||||
PDU = function() {
|
||||
this.fields = [];
|
||||
this.lengthBytes = 4;
|
||||
@ -103,6 +108,100 @@ mergePDVs = function(pdvs) {
|
||||
return merges;
|
||||
}
|
||||
|
||||
PDU.splitPData = function(pdata, maxSize) {
|
||||
var totalLength = pdata.totalLength();
|
||||
if (totalLength > maxSize) {
|
||||
//split into chunks of pdatas
|
||||
var chunks = Math.floor(totalLength / maxSize), left = totalLength % maxSize;
|
||||
|
||||
for (var i = 0;i < chunks;i++) {
|
||||
if (i == chunks - 1) {
|
||||
if (left < 6) {
|
||||
//need to move some of the last chunk
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return [pdata];
|
||||
}
|
||||
}
|
||||
|
||||
var readChunk = function(fd, bufferSize, slice, callback) {
|
||||
var buffer = new Buffer(bufferSize), length = slice.length, start = slice.start;
|
||||
fs.read(fd, buffer, 0, length, start, function(err, bytesRead) {
|
||||
callback(err, bytesRead, buffer, slice);
|
||||
});
|
||||
}
|
||||
|
||||
PDU.generatePDatas = function(context, bufferOrFile, maxSize, length, metaLength, callback) {
|
||||
var total, isFile = false;
|
||||
if (typeof bufferOrFile == 'string') {
|
||||
var stats = fs.statSync(bufferOrFile);
|
||||
total = stats['size'];
|
||||
isFile = true;
|
||||
} else if (bufferOrFile instanceof Buffer) {
|
||||
total = length ? length : bufferOrFile.length;
|
||||
}
|
||||
var handler = new PDVHandle();
|
||||
|
||||
var slices = [], start = metaLength + 144, index = 0;
|
||||
maxSize -= 6;
|
||||
while (start < total) {
|
||||
var sliceLength = maxSize, isLast = false;
|
||||
if (total - start < maxSize) {
|
||||
sliceLength = total - start;
|
||||
isLast = true;
|
||||
}
|
||||
slices.push({start : start, length : sliceLength, isLast : isLast, index : index});
|
||||
start += sliceLength;
|
||||
index++;
|
||||
}
|
||||
|
||||
if (isFile) {
|
||||
fs.open(bufferOrFile, 'r', function(err, fd) {
|
||||
if (err) {
|
||||
//fs.closeSync(fd);
|
||||
return quitWithError(err, callback);
|
||||
} else callback(null, handler);
|
||||
|
||||
var after = function(err, bytesRead, buffer, slice) {
|
||||
if (err) {
|
||||
fs.closeSync(fd);
|
||||
handler.emit('error', err);
|
||||
return;
|
||||
}
|
||||
var pdv = new RawDataPDV(context, buffer, 0, slice.length, slice.isLast);
|
||||
handler.emit('pdv', pdv);
|
||||
|
||||
if (slices.length < 1) {
|
||||
handler.emit('end');
|
||||
fs.closeSync(fd);
|
||||
} else {
|
||||
var next = slices.shift();
|
||||
readChunk(fd, maxSize, next, after);
|
||||
}
|
||||
};
|
||||
|
||||
var sl = slices.shift();
|
||||
readChunk(fd, maxSize, sl, after);
|
||||
});
|
||||
} else {
|
||||
for (var i = 0;i < slices.length;i++) {
|
||||
var toSlice = slices[i];
|
||||
|
||||
var buffer = bufferOrFile.slice(toSlice.start, toSlice.length);
|
||||
var pdv = new RawDataPDV(context, buffer, 0, toSlice.length, toSlice.isLast);
|
||||
handler.emit('pdv', pdv);
|
||||
|
||||
if (i == slices.length - 1) {
|
||||
handler.emit('end');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
PDU.typeToString = function(type) {
|
||||
var pdu = null, typeNum = parseInt(type, 16);
|
||||
//console.log("RECEIVED PDU-TYPE ", typeNum);
|
||||
@ -269,6 +368,18 @@ AssociateAC.prototype.readBytes = function(stream, length) {
|
||||
this.setUserInformationItem(userItem);
|
||||
}
|
||||
|
||||
AssociateAC.prototype.getMaxSize = function() {
|
||||
var items = this.userInformationItem.userDataItems, length = items.length, size = null;
|
||||
|
||||
for (var i = 0;i < length;i++) {
|
||||
if (items[i].is(C.ITEM_TYPE_MAXIMUM_LENGTH)) {
|
||||
size = items[i].maximumLengthReceived;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
AssociateAbort = function() {
|
||||
this.type = C.ITEM_TYPE_PDU_AABORT;
|
||||
this.source = 1;
|
||||
@ -346,6 +457,12 @@ PDataTF.prototype.getFields = function() {
|
||||
return PDataTF.super_.prototype.getFields.call(this, fields);
|
||||
}
|
||||
|
||||
PDataTF.prototype.totalLength = function() {
|
||||
var fields = this.presentationDataValueItems;
|
||||
|
||||
return this.length(fields);
|
||||
}
|
||||
|
||||
PDataTF.prototype.readBytes = function(stream, length) {
|
||||
var pdvs = this.loadPDV(stream, length);
|
||||
//let merges = mergePDVs(pdvs);
|
||||
@ -422,19 +539,32 @@ PresentationDataValueItem.prototype.getFields = function() {
|
||||
fields.push(new UInt8Field(messageHeader));
|
||||
|
||||
fields.push(this.dataFragment);
|
||||
/*var stream = new WriteStream();this.dataFragment.write(stream);
|
||||
//var f = this.dataFragment.getFields();
|
||||
//var wr = new WriteStream();f[0].setSyntax(this.dataFragment.syntax);f[0].write(wr);
|
||||
var rst = stream.toReadBuffer();
|
||||
rst.setEndian(C.LITTLE_ENDIAN);
|
||||
var group = rst.read(C.TYPE_UINT16),
|
||||
element = rst.read(C.TYPE_UINT16),
|
||||
tag = tagFromNumbers(group, element);
|
||||
|
||||
console.log(tag.toString(), rst.read(C.TYPE_UINT32));*/
|
||||
return PresentationDataValueItem.super_.prototype.getFields.call(this, fields);
|
||||
}
|
||||
|
||||
RawDataPDV = function(context, buffer, start, length, isLast) {
|
||||
this.type = null;
|
||||
this.isLast = isLast;
|
||||
this.dataFragmentBuffer = buffer;
|
||||
this.bufferStart = start;
|
||||
this.bufferLength = length;
|
||||
this.contextId = context;
|
||||
Item.call(this);
|
||||
|
||||
this.lengthBytes = 4;
|
||||
};
|
||||
util.inherits(RawDataPDV, Item);
|
||||
|
||||
RawDataPDV.prototype.getFields = function() {
|
||||
var fields = [new UInt8Field(this.contextId)];
|
||||
var messageHeader = (this.isLast ? 1 : 0) << 1;
|
||||
fields.push(new UInt8Field(messageHeader));
|
||||
fields.push(new BufferField(this.dataFragmentBuffer, this.bufferStart, this.bufferLength));
|
||||
|
||||
return RawDataPDV.super_.prototype.getFields.call(this, fields);
|
||||
}
|
||||
|
||||
ApplicationContextItem = function() {
|
||||
this.type = C.ITEM_TYPE_APPLICATION_CONTEXT;
|
||||
this.applicationContextName = C.APPLICATION_CONTEXT_NAME;
|
||||
|
||||
@ -85,6 +85,13 @@ WriteStream.prototype.writeToBuffer = function(type, value, length) {
|
||||
this.increment(length);
|
||||
}
|
||||
|
||||
WriteStream.prototype.writeRawBuffer = function(source, start, length) {
|
||||
if (!source) return;
|
||||
this.checkSize(length);
|
||||
source.copy(this.rawBuffer, this.offset, start, length);
|
||||
this.increment(length);
|
||||
}
|
||||
|
||||
WriteStream.prototype.write = function(type, value) {
|
||||
if (isString(type)) {
|
||||
this.writeString(value, type);
|
||||
|
||||
@ -42,7 +42,8 @@ C = {
|
||||
TYPE_DOUBLE : 8,
|
||||
TYPE_INT8 : 9,
|
||||
TYPE_INT16 : 10,
|
||||
TYPE_INT32 : 11,
|
||||
TYPE_INT32 : 11,
|
||||
TYPE_BUFFER : 12,
|
||||
RESULT_REASON_ACCEPTANCE : 0,
|
||||
RESULT_REASON_USER_REJECTION : 1,
|
||||
RESULT_REASON_NO_REASON :2,
|
||||
|
||||
@ -1,4 +1,14 @@
|
||||
var dicomNDict = {
|
||||
0x00020000 : { vr : 'UL', vm : C.VM_SINGLE, keyword : "FileMetaInformationGroupLength" },
|
||||
0x00020001 : { vr : 'OB', vm : C.VM_SINGLE, keyword : "FileMetaInformationVersion" },
|
||||
0x00020002 : { vr : 'UI', vm : C.VM_SINGLE, keyword : "MediaStorageSOPClassUID" },
|
||||
0x00020003 : { vr : 'UI', vm : C.VM_SINGLE, keyword : "MediaStorageSOPInstanceUID" },
|
||||
0x00020010 : { vr : 'UI', vm : C.VM_SINGLE, keyword : "TransferSyntaxUID" },
|
||||
0x00020012 : { vr : 'UI', vm : C.VM_SINGLE, keyword : "ImplementationClassUID" },
|
||||
0x00020013 : { vr : 'SH', vm : C.VM_SINGLE, keyword : "ImplementationVersionName" },
|
||||
0x00020016 : { vr : 'AE', vm : C.VM_SINGLE, keyword : "SourceApplicationEntityTitle" },
|
||||
0x00020100 : { vr : 'UI', vm : C.VM_SINGLE, keyword : "PrivateInformationCreatorUID" },
|
||||
0x00020102 : { vr : 'OB', vm : C.VM_SINGLE, keyword : "PrivateInformation" },
|
||||
0x00080001 : { vr : "UL", vm : C.VM_SINGLE, keyword : "LengthToEnd"},
|
||||
0x00080005 : { vr : "CS", vm : C.VM_1N, keyword : "SpecificCharacterSet"},
|
||||
0x00080006 : { vr : "SQ", vm : C.VM_SINGLE, keyword : "LanguageCodeSequence"},
|
||||
|
||||
@ -1 +1,7 @@
|
||||
util = Npm.require("util");
|
||||
util = Npm.require("util");
|
||||
fs = Npm.require('fs');
|
||||
EventEmitter = Npm.require('events').EventEmitter;
|
||||
|
||||
quitWithError = function(message, callback) {
|
||||
return callback(new Error(message), null);
|
||||
};
|
||||
Loading…
Reference in New Issue
Block a user