Socket
Socket
Sign inDemoInstall

nrrd-js

Package Overview
Dependencies
0
Maintainers
1
Versions
5
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.1.1 to 0.2.0

example4.nrrd

0

example.js

@@ -0,0 +0,0 @@ var nrrd = require('./nrrd.js');

364

nrrd.js

@@ -16,3 +16,3 @@ "use strict";

module.exports.serialize = function (nrrdOrg) {
var i, buffer, arr, totalLen = 1, nrrd = {}, prop, nativeType, nativeSize, bufferData, arrData, lines = [], header;
var i, buffer, arr, totalLen = 1, nrrd = {}, prop, nativeType, nativeSize, bufferData, arrData, line, lines = [], header;

@@ -72,4 +72,57 @@ // Copy nrrdOrg to nrrd to allow modifications without altering the original

// Try to infer spatial dimension
var spaceDimension = undefined;
if (nrrd.spaceDimension!==undefined) {
spaceDimension = nrrd.spaceDimension;
} else if (nrrd.space!==undefined) {
switch(nrrd.space) {
case "right-anterior-superior":
case "RAS":
spaceDimension = 3;
break;
case "left-anterior-superior":
case "LAS":
spaceDimension = 3;
break;
case "left-posterior-superior":
case "LPS":
spaceDimension = 3;
break;
case "right-anterior-superior-time":
case "RAST":
spaceDimension = 4;
break;
case "left-anterior-superior-time":
case "LAST":
spaceDimension = 4;
break;
case "left-posterior-superior-time":
case "LPST":
spaceDimension = 4;
break;
case "scanner-xyz":
spaceDimension = 3;
break;
case "scanner-xyz-time":
spaceDimension = 4;
break;
case "3D-right-handed":
spaceDimension = 3;
break;
case "3D-left-handed":
spaceDimension = 3;
break;
case "3D-right-handed-time":
spaceDimension = 4;
break;
case "3D-left-handed-time":
spaceDimension = 4;
break;
default:
console.warn("Unrecognized space: " + nrrd.space);
}
}
// Now check that we have a valid nrrd structure.
checkNRRD(nrrd, true);
checkNRRD(nrrd);

@@ -133,88 +186,17 @@ // Determine number of elements and check that we have enough data (if possible)

// Put in dimension and space dimension (the NRRD spec requires that these are present before any lists whose length depends on them)
var firstProps = ['dimension', 'spaceDimension', 'space'];
for(i=0; i<firstProps.length; i++) {
prop = firstProps[i];
if (nrrd[prop] === undefined) continue; // Skip things we explicitly set to undefined.
line = serializeField(prop, nrrd[prop], nrrd.dimension, spaceDimension);
if (line!==undefined) lines.push(line);
}
// Put in field specifications
for(prop in nrrd) {
if (nrrd[prop] === undefined) continue; // Skip things we explicitly set to undefined.
switch(prop) {
// nrrd-js stuff: skip
case 'data':
case 'buffer':
case 'keys':
case 'version':
break;
// Literal (uninterpreted) fields
case 'content':
case 'number':
case 'sampleunits':
lines.push(prop + ": " + nrrd[prop]);
break;
// Integers (no infinity or whatever, just a plain integer, so the default serialization is good enough)
case 'dimension':
case 'blockSize':
case 'lineSkip':
case 'byteSkip':
assert((typeof nrrd[prop]) == "number" || nrrd[prop] instanceof Number, "Field " + prop + " should at least contain a number!");
lines.push(prop + ": " + nrrd[prop]);
break;
// Floats (default serialization is good enough, as NaN contains nan, ignoring case, and similarly for Infinity inf)
case 'min':
case 'max':
case 'oldMin':
case 'oldMax':
assert((typeof nrrd[prop]) == "number" || nrrd[prop] instanceof Number, "Field " + prop + " should contain a number!");
lines.push(prop + ": " + nrrd[prop]);
break;
// Lists of strings
case 'labels':
case 'units':
assert(nrrd[prop].length !== undefined && nrrd[prop].length == nrrd.dimension, "Field " + prop + " should be a list with length equal to the dimension!");
nrrd[prop].forEach(function (val) { assert((typeof val) == "string" || val instanceof String, "Field " + prop + " should be a list of numbers!"); });
lines.push(prop + ": " + nrrd[prop].map(serializeNRRDQuotedString).join(" "));
break;
// Lists of integers
case 'sizes':
assert(nrrd[prop].length !== undefined && nrrd[prop].length == nrrd.dimension, "Field " + prop + " should be a list with length equal to the dimension!");
nrrd[prop].forEach(function (val) { assert((typeof val) == "number" || val instanceof Number, "Field " + prop + " should be a list of numbers!"); });
lines.push(prop + ": " + nrrd[prop].join(" "));
break;
// Lists of floats
case 'spacings':
case 'thicknesses':
case 'axisMins':
case 'axisMaxs':
assert(nrrd[prop].length !== undefined && nrrd[prop].length == nrrd.dimension, "Field " + prop + " should be a list with length equal to the dimension!");
nrrd[prop].forEach(function (val) { assert((typeof val) == "number" || val instanceof Number, "Field " + prop + " should be a list of numbers!"); });
lines.push(prop + ": " + nrrd[prop].join(" "));
break;
// One-of-a-kind fields
case 'type':
assert((typeof nrrd[prop]) == "string" || nrrd[prop] instanceof String, "Field " + prop + " should contain a string!");
lines.push(prop + ": " + nrrd[prop]);
break;
case 'encoding':
assert((typeof nrrd[prop]) == "string" || nrrd[prop] instanceof String, "Field " + prop + " should contain a string!");
lines.push(prop + ": " + nrrd[prop]);
break;
case 'endian':
assert((typeof nrrd[prop]) == "string" || nrrd[prop] instanceof String, "Field " + prop + " should contain a string!");
lines.push(prop + ": " + nrrd[prop]);
break;
case 'dataFile':
if (nrrd.dataFile.length || (nrrd.dataFile.files && 'subdim' in nrrd.dataFile)) {
// List of data files: skip for now
} else {
lines.push(prop + ": " + serializeNRRDDataFile(nrrd[prop]));
}
break;
case 'centers':
assert(nrrd[prop].length !== undefined && nrrd[prop].length == nrrd.dimension, "Field " + prop + " should be a list with length equal to the dimension!");
lines.push(prop + ": " + nrrd[prop].map(serializeNRRDOptional).join(" "));
break;
case 'kinds':
assert(nrrd[prop].length !== undefined && nrrd[prop].length == nrrd.dimension, "Field " + prop + " should be a list with length equal to the dimension!");
lines.push(prop + ": " + nrrd[prop].map(serializeNRRDOptional).join(" "));
break;
// Something unknown
default:
console.warn("Unrecognized NRRD field: " + prop + ", skipping.");
}
if (firstProps.indexOf(prop)>=0) continue; // Skip the fields we already output.
line = serializeField(prop, nrrd[prop], nrrd.dimension, spaceDimension);
if (line!==undefined) lines.push(line);
}

@@ -224,3 +206,3 @@

if (nrrd.keys) for(prop in nrrd.keys) {
if (prop.contains(":=")) throw new Error("The combination ':=' is not allowed in an NRRD key!");
if (prop.indexOf(":=")>=0) throw new Error("The combination ':=' is not allowed in an NRRD key!");
lines.push(prop + ":=" + escapeValue(nrrd[prop]));

@@ -379,2 +361,119 @@ }

// Serializes NRRD fields
function serializeField(prop, value, dimension, spaceDimension) {
var line;
var propNRRD = mapJavascriptToNRRD(prop);
switch(prop) {
// nrrd-js stuff: skip
case 'data':
case 'buffer':
case 'keys':
case 'version':
break;
// Literal (uninterpreted) fields
case 'content':
case 'number':
case 'sampleUnits':
case 'space':
line = propNRRD + ": " + value;
break;
// Integers (no infinity or whatever, just a plain integer, so the default serialization is good enough)
case 'blockSize':
case 'lineSkip':
case 'byteSkip':
case 'dimension':
case 'spaceDimension':
assert((typeof value) == "number" || value instanceof Number, "Field " + prop + " should at least contain a number!");
line = propNRRD + ": " + value;
break;
// Floats (default serialization is good enough, as NaN contains nan, ignoring case, and similarly for Infinity inf)
case 'min':
case 'max':
case 'oldMin':
case 'oldMax':
assert((typeof value) == "number" || value instanceof Number, "Field " + prop + " should contain a number!");
line = propNRRD + ": " + value;
break;
// Vectors
case 'spaceOrigin':
assert(value.length === spaceDimension, "Field " + prop + " should be a list with length equal to the space dimension!");
value.forEach(function (val) { assert((typeof val) == "number" || val instanceof Number, "Field " + prop + " should be a list of numbers!"); });
line = propNRRD + ": (" + value.join(",") + ")";
break;
// Lists of strings
case 'labels':
case 'units':
case 'spaceUnits':
assert(value.length !== undefined && value.length == dimension, "Field " + prop + " should be a list with length equal to the dimension!");
value.forEach(function (val) { assert((typeof val) == "string" || val instanceof String, "Field " + prop + " should be a list of numbers!"); });
line = propNRRD + ": " + value.map(serializeNRRDQuotedString).join(" ");
break;
// Lists of integers
case 'sizes':
assert(value.length !== undefined && value.length == dimension, "Field " + prop + " should be a list with length equal to the dimension!");
value.forEach(function (val) { assert((typeof val) == "number" || val instanceof Number, "Field " + prop + " should be a list of numbers!"); });
line = propNRRD + ": " + value.join(" ");
break;
// Lists of floats
case 'spacings':
case 'thicknesses':
case 'axisMins':
case 'axisMaxs':
assert(value.length !== undefined && value.length == dimension, "Field " + prop + " should be a list with length equal to the dimension!");
value.forEach(function (val) { assert((typeof val) == "number" || val instanceof Number, "Field " + prop + " should be a list of numbers!"); });
line = propNRRD + ": " + value.join(" ");
break;
// Lists of vectors (dimension sized)
case 'spaceDirections':
assert(value.length !== undefined && value.length === dimension, "Field " + prop + " should be a list with length equal to the dimension!");
value.forEach(function (vec) {
assert(vec.length === spaceDimension, "The elements of field " + prop + " should be lists with length equal to the space dimension!");
vec.forEach(function (val) { assert((typeof val) == "number" || val instanceof Number, "The elements of field " + prop + " should be lists of numbers!"); });
});
line = propNRRD + ": " + value.map(function(vec) { return "(" + vec.join(",") + ")"; }).join(" ");
break;
// Lists of vectors (space dimension sized)
case 'measurementFrame':
assert(value.length !== undefined && value.length === spaceDimension, "Field " + prop + " should be a list with length equal to the space dimension!");
value.forEach(function (vec) {
assert(vec.length === spaceDimension, "The elements of field " + prop + " should be lists with length equal to the space dimension!");
vec.forEach(function (val) { assert((typeof val) == "number" || val instanceof Number, "The elements of field " + prop + " should be lists of numbers!"); });
});
line = propNRRD + ": " + value.map(function(vec) { return "(" + vec.join(",") + ")"; }).join(" ");
break;
// One-of-a-kind fields
case 'type':
assert((typeof value) == "string" || value instanceof String, "Field " + prop + " should contain a string!");
line = propNRRD + ": " + value;
break;
case 'encoding':
assert((typeof value) == "string" || value instanceof String, "Field " + prop + " should contain a string!");
line = propNRRD + ": " + value;
break;
case 'endian':
assert((typeof value) == "string" || value instanceof String, "Field " + prop + " should contain a string!");
line = propNRRD + ": " + value;
break;
case 'dataFile':
if (value.length || (value.files && 'subdim' in value)) {
// List of data files: skip for now
} else {
line = propNRRD + ": " + serializeNRRDDataFile(value);
}
break;
case 'centers':
assert(value.length !== undefined && value.length == dimension, "Field " + prop + " should be a list with length equal to the dimension!");
line = propNRRD + ": " + value.map(serializeNRRDOptional).join(" ");
break;
case 'kinds':
assert(value.length !== undefined && value.length == dimension, "Field " + prop + " should be a list with length equal to the dimension!");
line = propNRRD + ": " + value.map(serializeNRRDOptional).join(" ");
break;
// Something unknown
default:
console.warn("Unrecognized NRRD field: " + prop + ", skipping.");
}
return line;
}
// Parses and normalizes NRRD fields, assumes the field names are already lower case.

@@ -386,3 +485,3 @@ function parseField(identifier, descriptor) {

case 'number':
case 'sampleunits':
case 'sampleUnits':
break;

@@ -394,2 +493,3 @@ // Integers

case 'byteSkip':
case 'spaceDimension':
descriptor = parseNRRDInteger(descriptor);

@@ -402,7 +502,12 @@ break;

case 'oldMax':
descriptor = parseNRRDFloat(descriptor.toLowerCase());
descriptor = parseNRRDFloat(descriptor);
break;
// Vectors
case 'spaceOrigin':
descriptor = parseNRRDVector(descriptor);
break;
// Lists of strings
case 'labels':
case 'units':
case 'spaceUnits':
descriptor = parseNRRDWhitespaceSeparatedList(descriptor, parseNRRDQuotedString);

@@ -421,2 +526,7 @@ break;

break;
// Lists of vectors
case 'spaceDirections':
case 'measurementFrame':
descriptor = parseNRRDWhitespaceSeparatedList(descriptor, parseNRRDVector);
break;
// One-of-a-kind fields

@@ -441,2 +551,5 @@ case 'type':

break;
case 'space':
descriptor = parseNRRDSpace(descriptor);
break;
// Something unknown

@@ -468,4 +581,16 @@ default:

'centers': 'centers', // Not different, just included so it is clear why centerings maps to centers
'centerings': 'centers'
'centerings': 'centers',
'space dimension': 'spaceDimension',
'space units': 'spaceUnits',
'space origin': 'spaceOrigin',
'space directions': 'spaceDirections',
'measurement frame': 'measurementFrame'
};
var mapJavascriptToNRRDStatic = function() {
var id, m = {};
for(id in mapNRRDToJavascriptStatic) {
m[mapNRRDToJavascriptStatic[id]] = id;
}
return m;
}();
function mapNRRDToJavascript(id) {

@@ -479,2 +604,8 @@ // In any case, use the lower case version of the id

}
function mapJavascriptToNRRD(id) {
// Filter out any fields for which we have an explicit NRRD name
if (id in mapJavascriptToNRRDStatic) return mapJavascriptToNRRDStatic[id];
// Otherwise, just return the id
return id;
}

@@ -487,7 +618,7 @@ function parseNRRDInteger(str) {

// Note: this assumes any letters in str are in lower case!
function parseNRRDFloat(str) {
if (str.contains('nan')) return NaN;
if (str.contains('-inf')) return -Infinity;
if (str.contains('inf')) return Infinity;
str = str.toLowerCase();
if (str.indexOf('nan')>=0) return NaN;
if (str.indexOf('-inf')>=0) return -Infinity;
if (str.indexOf('inf')>=0) return Infinity;
var val = parseFloat(str);

@@ -498,2 +629,7 @@ if (Number.isNaN(val)) throw new Error("Malformed NRRD float: " + str);

function parseNRRDVector(str) {
if (str.length<2 || str[0]!=="(" || str[str.length-1]!==")") throw new Error("Malformed NRRD vector: " + str);
return str.slice(1, -1).split(",").map(parseNRRDFloat);
}
function parseNRRDQuotedString(str) {

@@ -503,3 +639,3 @@ if (length<2 || str[0]!='"' || str[str.length-1]!='"') {

}
return str.substring(1, str.length-1).replace('\\"', '"');
return str.slice(1, -1).replace('\\"', '"');
}

@@ -598,2 +734,40 @@

function parseNRRDSpace(space) {
switch(space.toLowerCase()) {
case "right-anterior-superior":
case "ras":
return "right-anterior-superior";
case "left-anterior-superior":
case "las":
return "left-anterior-superior";
case "left-posterior-superior":
case "lps":
return "left-posterior-superior";
case "right-anterior-superior-time":
case "rast":
return "right-anterior-superior-time";
case "left-anterior-superior-time":
case "last":
return "left-anterior-superior-time";
case "left-posterior-superior-time":
case "lpst":
return "left-posterior-superior-time";
case "scanner-xyz":
return "scanner-xyz";
case "scanner-xyz-time":
return "scanner-xyz-time";
case "3d-right-handed":
return "3D-right-handed";
case "3d-left-handed":
return "3D-left-handed";
case "3d-right-handed-time":
return "3D-right-handed-time";
case "3d-left-handed-time":
return "3D-left-handed-time";
default:
console.warn("Unrecognized space: " + space);
return space;
}
}
function parseNRRDEndian(endian) {

@@ -969,2 +1143,4 @@ switch(endian.toLowerCase()) {

// TODO: Check space/orientation fields.
// We should either have inline data or external data

@@ -971,0 +1147,0 @@ if ((ret.data === undefined || ret.data.length === 0) && (ret.buffer === undefined || ret.buffer.byteLength === 0) && ret.dataFile === undefined) {

{
"name": "nrrd-js",
"version": "0.1.1",
"version": "0.2.0",
"description": "Handling NRRD files in Javascript.",

@@ -5,0 +5,0 @@ "main": "nrrd.js",

@@ -0,0 +0,0 @@ NRRD support for Javascript

@@ -54,3 +54,22 @@ var test = require('tape');

}
var file = nrrd.parse(nrrd.serialize(nrrd.parse(fs.readFileSync('example4.nrrd')))),
i, list = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24];
t.equal(file.type, 'uint8');
t.equal(file.dimension, 3);
t.equal(file.sizes.length, 3);
t.equal(file.sizes[0], 4);
t.equal(file.sizes[1], 3);
t.equal(file.sizes[2], 2);
t.equal(file.space, "right-anterior-superior");
t.ok(arrayEqual(file.spaceOrigin, [1.0,2.0,3.0]), "spaceOrigin should be equal to [1.0,2.0,3.0]");
t.ok(arrayEqual(file.spaceDirections, [[1.0,0.0,0.0],[0,0.5,0],[0,0,0.3]]), "spaceDirections should be equal to [[1.0,0,0],...]");
t.equal(file.data.length, 4*3*2);
t.equal(file.data.byteLength, 4*3*2);
for(i=0; i<list.length; i++) {
t.equal(file.data[i], list[i]);
}
t.end();

@@ -80,4 +99,5 @@ });

arr1 = ndarray(new Uint16Array([1,2,3, 65000,64000,63000, 10000,11000,12000, 4,5,6]), [4,3]),
file = nrrd.parse(nrrd.serialize({data: arr1.data, sizes: arr1.shape.slice().reverse()})),
arr2 = ndarray(file.data, file.sizes.slice().reverse());;
serialized = nrrd.serialize({data: arr1.data, sizes: arr1.shape.slice().reverse()}),
file = nrrd.parse(serialized),
arr2 = ndarray(file.data, file.sizes.slice().reverse());

@@ -94,4 +114,18 @@ t.equal(file.dimension, arr1.shape.length);

}
//console.log(String.fromCharCode.apply(null, new Uint8Array(serialized)));
t.end();
});
function arrayEqual(a, b) {
if (a.length === undefined || a.length !== b.length) return false;
for(var i=0; i<a.length; i++) {
if (a[i].length !== undefined) {
if (!arrayEqual(a[i],b[i])) return false;
} else {
if (a[i]!==b[i]) return false;
}
}
return true;
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc