@cquiroz/aladin-lite
Version:
AladinLite module
1,846 lines (1,528 loc) • 55.7 kB
JavaScript
/* eslint-disable */
// Generated by CoffeeScript 1.6.3
export default (function () {
var Base,
BinaryTable,
CompressedImage,
DataUnit,
Decompress,
FITS,
HDU,
Header,
HeaderVerify,
Image,
ImageUtils,
Parser,
Table,
Tabular,
_ref,
_ref1,
__hasProp = {}.hasOwnProperty,
__extends = function __extends(child, parent) {
for (var key in parent) {
if (__hasProp.call(parent, key)) child[key] = parent[key];
}
function ctor() {
this.constructor = child;
}
ctor.prototype = parent.prototype;
child.prototype = new ctor();
child.__super__ = parent.prototype;
return child;
},
__slice = [].slice;
var astro = {};
Base = function () {
function Base() {}
Base.include = function (obj) {
var key, value;
for (key in obj) {
value = obj[key];
this.prototype[key] = value;
}
return this;
};
Base.extend = function (obj) {
var key, value;
for (key in obj) {
value = obj[key];
this[key] = value;
}
return this;
};
Base.prototype.proxy = function (func) {
var _this = this;
return function () {
return func.apply(_this, arguments);
};
};
Base.prototype.invoke = function (callback, opts, data) {
var context;
context = (opts != null ? opts.context : void 0) != null ? opts.context : this;
if (callback != null) {
return callback.call(context, data, opts);
}
};
return Base;
}();
Parser = function (_super) {
__extends(Parser, _super);
Parser.prototype.LINEWIDTH = 80;
Parser.prototype.BLOCKLENGTH = 2880;
File.prototype.slice = File.prototype.slice || File.prototype.webkitSlice;
Blob.prototype.slice = Blob.prototype.slice || Blob.prototype.webkitSlice;
function Parser(arg, callback, opts) {
var xhr,
_this = this;
this.arg = arg;
this.callback = callback;
this.opts = opts;
this.hdus = [];
this.blockCount = 0;
this.begin = 0;
this.end = this.BLOCKLENGTH;
this.offset = 0;
this.headerStorage = new Uint8Array();
if (typeof this.arg === 'string') {
this.readNextBlock = this._readBlockFromBuffer;
xhr = new XMLHttpRequest();
xhr.open('GET', this.arg);
xhr.responseType = 'arraybuffer'; // the onerror handling has been added wrt the original fitsjs library as retrieved on the astrojs github repo
// if an error occurs, we return an empty object
xhr.onerror = function () {
_this.invoke(_this.callback, _this.opts);
};
xhr.onload = function () {
if (xhr.status !== 200) {
_this.invoke(_this.callback, _this.opts);
return;
}
_this.arg = xhr.response;
_this.length = _this.arg.byteLength;
return _this.readFromBuffer();
};
xhr.send();
} else {
this.length = this.arg.size;
this.readNextBlock = this._readBlockFromFile;
this.readFromFile();
}
}
Parser.prototype.readFromBuffer = function () {
var block;
block = this.arg.slice(this.begin + this.offset, this.end + this.offset);
return this.readBlock(block);
};
Parser.prototype.readFromFile = function () {
var block,
_this = this;
this.reader = new FileReader();
this.reader.onloadend = function (e) {
return _this.readBlock(e.target.result);
};
block = this.arg.slice(this.begin + this.offset, this.end + this.offset);
return this.reader.readAsArrayBuffer(block);
};
Parser.prototype.readBlock = function (block) {
var arr, dataLength, dataunit, header, rowIndex, rows, s, slice, tmp, value, _i, _len, _ref;
arr = new Uint8Array(block);
tmp = new Uint8Array(this.headerStorage);
this.headerStorage = new Uint8Array(this.end);
this.headerStorage.set(tmp, 0);
this.headerStorage.set(arr, this.begin);
rows = this.BLOCKLENGTH / this.LINEWIDTH;
while (rows--) {
rowIndex = rows * this.LINEWIDTH;
if (arr[rowIndex] === 32) {
continue;
}
if (arr[rowIndex] === 69 && arr[rowIndex + 1] === 78 && arr[rowIndex + 2] === 68 && arr[rowIndex + 3] === 32) {
s = '';
_ref = this.headerStorage;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
value = _ref[_i];
s += String.fromCharCode(value);
}
header = new Header(s);
this.start = this.end + this.offset;
dataLength = header.getDataLength();
slice = this.arg.slice(this.start, this.start + dataLength);
if (header.hasDataUnit()) {
dataunit = this.createDataUnit(header, slice);
}
this.hdus.push(new HDU(header, dataunit));
this.offset += this.end + dataLength + this.excessBytes(dataLength);
if (this.offset === this.length) {
this.headerStorage = null;
this.invoke(this.callback, this.opts, this);
return;
}
this.blockCount = 0;
this.begin = this.blockCount * this.BLOCKLENGTH;
this.end = this.begin + this.BLOCKLENGTH;
this.headerStorage = new Uint8Array();
block = this.arg.slice(this.begin + this.offset, this.end + this.offset);
this.readNextBlock(block);
return;
}
break;
}
this.blockCount += 1;
this.begin = this.blockCount * this.BLOCKLENGTH;
this.end = this.begin + this.BLOCKLENGTH;
block = this.arg.slice(this.begin + this.offset, this.end + this.offset);
this.readNextBlock(block);
};
Parser.prototype._readBlockFromBuffer = function (block) {
return this.readBlock(block);
};
Parser.prototype._readBlockFromFile = function (block) {
return this.reader.readAsArrayBuffer(block);
};
Parser.prototype.createDataUnit = function (header, blob) {
var type;
type = header.getDataType();
return new astro.FITS[type](header, blob);
};
Parser.prototype.excessBytes = function (length) {
return (this.BLOCKLENGTH - length % this.BLOCKLENGTH) % this.BLOCKLENGTH;
};
Parser.prototype.isEOF = function () {
if (this.offset === this.length) {
return true;
} else {
return false;
}
};
return Parser;
}(Base);
FITS = function (_super) {
__extends(FITS, _super);
function FITS(arg, callback, opts) {
var parser,
_this = this;
this.arg = arg;
parser = new Parser(this.arg, function (fits) {
_this.hdus = parser.hdus;
return _this.invoke(callback, opts, _this);
});
}
FITS.prototype.getHDU = function (index) {
var hdu, _i, _len, _ref;
if (index != null && this.hdus[index] != null) {
return this.hdus[index];
}
_ref = this.hdus;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
hdu = _ref[_i];
if (hdu.hasData()) {
return hdu;
}
}
};
FITS.prototype.getHeader = function (index) {
return this.getHDU(index).header;
};
FITS.prototype.getDataUnit = function (index) {
return this.getHDU(index).data;
};
return FITS;
}(Base);
FITS.version = '0.6.5';
astro.FITS = FITS;
DataUnit = function (_super) {
__extends(DataUnit, _super);
DataUnit.swapEndian = {
B: function B(value) {
return value;
},
I: function I(value) {
return value << 8 | value >> 8;
},
J: function J(value) {
return (value & 0xFF) << 24 | (value & 0xFF00) << 8 | value >> 8 & 0xFF00 | value >> 24 & 0xFF;
}
};
DataUnit.swapEndian[8] = DataUnit.swapEndian['B'];
DataUnit.swapEndian[16] = DataUnit.swapEndian['I'];
DataUnit.swapEndian[32] = DataUnit.swapEndian['J'];
function DataUnit(header, data) {
if (data instanceof ArrayBuffer) {
this.buffer = data;
} else {
this.blob = data;
}
}
return DataUnit;
}(Base);
astro.FITS.DataUnit = DataUnit;
HeaderVerify = {
verifyOrder: function verifyOrder(keyword, order) {
if (order !== this.cardIndex) {
return console.warn("" + keyword + " should appear at index " + this.cardIndex + " in the FITS header");
}
},
verifyBetween: function verifyBetween(keyword, value, lower, upper) {
if (!(value >= lower && value <= upper)) {
throw "The " + keyword + " value of " + value + " is not between " + lower + " and " + upper;
}
},
verifyBoolean: function verifyBoolean(value) {
if (value === "T") {
return true;
} else {
return false;
}
},
VerifyFns: {
SIMPLE: function SIMPLE() {
var args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
var value = arguments[0];
this.primary = true;
this.verifyOrder("SIMPLE", 0);
return this.verifyBoolean(value);
},
XTENSION: function XTENSION() {
var args;
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
this.extension = true;
this.extensionType = arguments[0];
this.verifyOrder("XTENSION", 0);
return this.extensionType;
},
BITPIX: function BITPIX() {
var args, key, value;
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
key = "BITPIX";
value = parseInt(arguments[0]);
this.verifyOrder(key, 1);
if (value !== 8 && value !== 16 && value !== 32 && value !== -32 && value !== -64) {
throw "" + key + " value " + value + " is not permitted";
}
return value;
},
NAXIS: function NAXIS() {
var args, array, key, required, value, _ref;
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
key = "NAXIS";
value = parseInt(arguments[0]);
array = arguments[1];
if (!array) {
this.verifyOrder(key, 2);
this.verifyBetween(key, value, 0, 999);
if (this.isExtension()) {
if ((_ref = this.extensionType) === "TABLE" || _ref === "BINTABLE") {
required = 2;
if (value !== required) {
throw "" + key + " must be " + required + " for TABLE and BINTABLE extensions";
}
}
}
}
return value;
},
PCOUNT: function PCOUNT() {
var args, key, order, required, value, _ref;
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
key = "PCOUNT";
value = parseInt(arguments[0]);
order = 1 + 1 + 1 + this.get("NAXIS");
this.verifyOrder(key, order);
if (this.isExtension()) {
if ((_ref = this.extensionType) === "IMAGE" || _ref === "TABLE") {
required = 0;
if (value !== required) {
throw "" + key + " must be " + required + " for the " + this.extensionType + " extensions";
}
}
}
return value;
},
GCOUNT: function GCOUNT() {
var args, key, order, required, value, _ref;
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
key = "GCOUNT";
value = parseInt(arguments[0]);
order = 1 + 1 + 1 + this.get("NAXIS") + 1;
this.verifyOrder(key, order);
if (this.isExtension()) {
if ((_ref = this.extensionType) === "IMAGE" || _ref === "TABLE" || _ref === "BINTABLE") {
required = 1;
if (value !== required) {
throw "" + key + " must be " + required + " for the " + this.extensionType + " extensions";
}
}
}
return value;
},
EXTEND: function EXTEND() {
var args, value;
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
value = arguments[0];
if (!this.isPrimary()) {
throw "EXTEND must only appear in the primary header";
}
return this.verifyBoolean(value);
},
BSCALE: function BSCALE() {
var args;
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
return parseFloat(arguments[0]);
},
BZERO: function BZERO() {
var args;
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
return parseFloat(arguments[0]);
},
BLANK: function BLANK() {
var args, value;
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
value = arguments[0];
if (!(this.get("BITPIX") > 0)) {
console.warn("BLANK is not to be used for BITPIX = " + this.get('BITPIX'));
}
return parseInt(value);
},
DATAMIN: function DATAMIN() {
var args;
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
return parseFloat(arguments[0]);
},
DATAMAX: function DATAMAX() {
var args;
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
return parseFloat(arguments[0]);
},
EXTVER: function EXTVER() {
var args;
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
return parseInt(arguments[0]);
},
EXTLEVEL: function EXTLEVEL() {
var args;
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
return parseInt(arguments[0]);
},
TFIELDS: function TFIELDS() {
var args, value;
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
value = parseInt(arguments[0]);
this.verifyBetween("TFIELDS", value, 0, 999);
return value;
},
TBCOL: function TBCOL() {
var args, index, value;
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
value = arguments[0];
index = arguments[2];
this.verifyBetween("TBCOL", index, 0, this.get("TFIELDS"));
return value;
},
ZIMAGE: function ZIMAGE() {
var args;
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
return this.verifyBoolean(arguments[0]);
},
ZCMPTYPE: function ZCMPTYPE() {
var args, value;
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
value = arguments[0];
if (value !== 'GZIP_1' && value !== 'RICE_1' && value !== 'PLIO_1' && value !== 'HCOMPRESS_1') {
throw "ZCMPTYPE value " + value + " is not permitted";
}
if (value !== 'RICE_1') {
throw "Compress type " + value + " is not yet implement";
}
return value;
},
ZBITPIX: function ZBITPIX() {
var args, value;
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
value = parseInt(arguments[0]);
if (value !== 8 && value !== 16 && value !== 32 && value !== 64 && value !== -32 && value !== -64) {
throw "ZBITPIX value " + value + " is not permitted";
}
return value;
},
ZNAXIS: function ZNAXIS() {
var args, array, value;
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
value = parseInt(arguments[0]);
array = arguments[1];
value = value;
if (!array) {
this.verifyBetween("ZNAXIS", value, 0, 999);
}
return value;
},
ZTILE: function ZTILE() {
var args;
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
return parseInt(arguments[0]);
},
ZSIMPLE: function ZSIMPLE() {
var args;
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
if (arguments[0] === "T") {
return true;
} else {
return false;
}
},
ZPCOUNT: function ZPCOUNT() {
var args;
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
return parseInt(arguments[0]);
},
ZGCOUNT: function ZGCOUNT() {
var args;
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
return parseInt(arguments[0]);
},
ZDITHER0: function ZDITHER0() {
var args;
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
return parseInt(arguments[0]);
}
}
};
astro.FITS.HeaderVerify = HeaderVerify;
Header = function (_super) {
__extends(Header, _super);
Header.include(HeaderVerify);
Header.prototype.arrayPattern = /(\D+)(\d+)/;
Header.prototype.maxLines = 600;
function Header(block) {
var method, name, _ref;
this.primary = false;
this.extension = false;
this.verifyCard = {};
_ref = this.VerifyFns;
for (name in _ref) {
method = _ref[name];
this.verifyCard[name] = this.proxy(method);
}
this.cards = {};
this.cards["COMMENT"] = [];
this.cards["HISTORY"] = [];
this.cardIndex = 0;
this.block = block;
this.readBlock(block);
}
Header.prototype.get = function (key) {
if (this.contains(key)) {
return this.cards[key].value;
} else {
return null;
}
};
Header.prototype.set = function (key, value, comment) {
comment = comment || '';
this.cards[key] = {
index: this.cardIndex,
value: value,
comment: comment
};
return this.cardIndex += 1;
};
Header.prototype.contains = function (key) {
return this.cards.hasOwnProperty(key);
};
Header.prototype.readLine = function (l) {
var blank, comment, firstByte, indicator, key, value, _ref;
key = l.slice(0, 8).trim();
blank = key === '';
if (blank) {
return;
}
indicator = l.slice(8, 10);
value = l.slice(10);
if (indicator !== "= ") {
if (key === 'COMMENT' || key === 'HISTORY') {
this.cards[key].push(value.trim());
}
return;
}
_ref = value.split(' /');
value = _ref[0];
comment = _ref[1];
value = value.trim();
firstByte = value[0];
if (firstByte === "'") {
value = value.slice(1, -1).trim();
} else {
if (value !== 'T' && value !== 'F') {
value = parseFloat(value);
}
}
value = this.validate(key, value);
return this.set(key, value, comment);
};
Header.prototype.validate = function (key, value) {
var baseKey, index, isArray, match, _ref;
index = null;
baseKey = key;
isArray = this.arrayPattern.test(key);
if (isArray) {
match = this.arrayPattern.exec(key);
_ref = match.slice(1);
baseKey = _ref[0];
index = _ref[1];
}
if (baseKey in this.verifyCard) {
value = this.verifyCard[baseKey](value, isArray, index);
}
return value;
};
Header.prototype.readBlock = function (block) {
var i, line, lineWidth, nLines, _i, _ref, _results;
lineWidth = 80;
nLines = block.length / lineWidth;
nLines = nLines < this.maxLines ? nLines : this.maxLines;
_results = [];
for (i = _i = 0, _ref = nLines - 1; 0 <= _ref ? _i <= _ref : _i >= _ref; i = 0 <= _ref ? ++_i : --_i) {
line = block.slice(i * lineWidth, (i + 1) * lineWidth);
_results.push(this.readLine(line));
}
return _results;
};
Header.prototype.hasDataUnit = function () {
if (this.get("NAXIS") === 0) {
return false;
} else {
return true;
}
};
Header.prototype.getDataLength = function () {
var i, length, naxis, _i, _ref;
if (!this.hasDataUnit()) {
return 0;
}
naxis = [];
for (i = _i = 1, _ref = this.get("NAXIS"); 1 <= _ref ? _i <= _ref : _i >= _ref; i = 1 <= _ref ? ++_i : --_i) {
naxis.push(this.get("NAXIS" + i));
}
length = naxis.reduce(function (a, b) {
return a * b;
}) * Math.abs(this.get("BITPIX")) / 8;
length += this.get("PCOUNT");
return length;
};
Header.prototype.getDataType = function () {
switch (this.extensionType) {
case 'BINTABLE':
if (this.contains('ZIMAGE')) {
return 'CompressedImage';
}
return 'BinaryTable';
case 'TABLE':
return 'Table';
default:
if (this.hasDataUnit()) {
return 'Image';
} else {
return null;
}
}
};
Header.prototype.isPrimary = function () {
return this.primary;
};
Header.prototype.isExtension = function () {
return this.extension;
};
return Header;
}(Base);
astro.FITS.Header = Header;
ImageUtils = {
getExtent: function getExtent(arr) {
var index, max, min, value;
index = arr.length;
while (index--) {
value = arr[index];
if (isNaN(value)) {
continue;
}
min = max = value;
break;
}
if (index === -1) {
return [NaN, NaN];
}
while (index--) {
value = arr[index];
if (isNaN(value)) {
continue;
}
if (value < min) {
min = value;
}
if (value > max) {
max = value;
}
}
return [min, max];
},
getPixel: function getPixel(arr, x, y) {
return arr[y * this.width + x];
}
};
astro.FITS.ImageUtils = ImageUtils;
Image = function (_super) {
__extends(Image, _super);
Image.include(ImageUtils);
Image.prototype.allocationSize = 16777216;
function Image(header, data) {
var begin, frame, i, naxis, _i, _j, _ref;
Image.__super__.constructor.apply(this, arguments);
naxis = header.get("NAXIS");
this.bitpix = header.get("BITPIX");
this.naxis = [];
for (i = _i = 1; 1 <= naxis ? _i <= naxis : _i >= naxis; i = 1 <= naxis ? ++_i : --_i) {
this.naxis.push(header.get("NAXIS" + i));
}
this.width = header.get("NAXIS1");
this.height = header.get("NAXIS2") || 1;
this.depth = header.get("NAXIS3") || 1;
this.bzero = header.get("BZERO") || 0;
this.bscale = header.get("BSCALE") || 1;
this.bytes = Math.abs(this.bitpix) / 8;
this.length = this.naxis.reduce(function (a, b) {
return a * b;
}) * Math.abs(this.bitpix) / 8;
this.frame = 0;
this.frameOffsets = [];
this.frameLength = this.bytes * this.width * this.height;
this.nBuffers = this.buffer != null ? 1 : 2;
for (i = _j = 0, _ref = this.depth - 1; 0 <= _ref ? _j <= _ref : _j >= _ref; i = 0 <= _ref ? ++_j : --_j) {
begin = i * this.frameLength;
frame = {
begin: begin
};
if (this.buffer != null) {
frame.buffers = [this.buffer.slice(begin, begin + this.frameLength)];
}
this.frameOffsets.push(frame);
}
}
Image.prototype._getFrame = function (buffer, bitpix, bzero, bscale) {
var arr, bytes, dataType, i, nPixels, swapEndian, tmp, value;
bytes = Math.abs(bitpix) / 8;
nPixels = i = buffer.byteLength / bytes;
dataType = Math.abs(bitpix);
if (bitpix > 0) {
switch (bitpix) {
case 8:
tmp = new Uint8Array(buffer);
tmp = new Uint16Array(tmp);
swapEndian = function swapEndian(value) {
return value;
};
break;
case 16:
tmp = new Int16Array(buffer);
swapEndian = function swapEndian(value) {
return (value & 0xFF) << 8 | value >> 8 & 0xFF;
};
break;
case 32:
tmp = new Int32Array(buffer);
swapEndian = function swapEndian(value) {
return (value & 0xFF) << 24 | (value & 0xFF00) << 8 | value >> 8 & 0xFF00 | value >> 24 & 0xFF;
};
}
if (!(parseInt(bzero) === bzero && parseInt(bscale) === bscale)) {
arr = new Float32Array(tmp.length);
} else {
arr = tmp;
}
while (nPixels--) {
tmp[nPixels] = swapEndian(tmp[nPixels]);
arr[nPixels] = bzero + bscale * tmp[nPixels];
}
} else {
arr = new Uint32Array(buffer);
swapEndian = function swapEndian(value) {
return (value & 0xFF) << 24 | (value & 0xFF00) << 8 | value >> 8 & 0xFF00 | value >> 24 & 0xFF;
};
while (i--) {
value = arr[i];
arr[i] = swapEndian(value);
}
arr = new Float32Array(buffer);
while (nPixels--) {
arr[nPixels] = bzero + bscale * arr[nPixels];
}
}
return arr;
};
Image.prototype._getFrameAsync = function (buffers, callback, opts) {
var URL,
blobGetFrame,
blobOnMessage,
fn1,
fn2,
i,
mime,
msg,
onmessage,
pixels,
start,
urlGetFrame,
urlOnMessage,
worker,
_this = this;
onmessage = function onmessage(e) {
var arr, bitpix, bscale, buffer, bzero, data, url;
data = e.data;
buffer = data.buffer;
bitpix = data.bitpix;
bzero = data.bzero;
bscale = data.bscale;
url = data.url; // importScripts(url);
arr = Image.prototype._getFrame(buffer, bitpix, bzero, bscale);
return postMessage(arr);
};
fn1 = onmessage.toString().replace('return postMessage', 'postMessage');
fn1 = "onmessage = " + fn1;
fn2 = this._getFrame.toString();
fn2 = fn2.replace('function', 'function _getFrame');
mime = "application/javascript";
blobOnMessage = new Blob([fn1], {
type: mime
});
blobGetFrame = new Blob([fn2], {
type: mime
});
URL = window.URL || window.webkitURL;
urlOnMessage = URL.createObjectURL(blobOnMessage);
urlGetFrame = URL.createObjectURL(blobGetFrame);
worker = new Worker(urlOnMessage);
msg = {
buffer: buffers[0],
bitpix: this.bitpix,
bzero: this.bzero,
bscale: this.bscale,
url: urlGetFrame
};
i = 0;
pixels = null;
start = 0;
worker.onmessage = function (e) {
var arr;
arr = e.data;
if (pixels == null) {
pixels = new arr.constructor(_this.width * _this.height);
}
pixels.set(arr, start);
start += arr.length;
i += 1;
if (i === _this.nBuffers) {
_this.invoke(callback, opts, pixels);
URL.revokeObjectURL(urlOnMessage);
URL.revokeObjectURL(urlGetFrame);
return worker.terminate();
} else {
msg.buffer = buffers[i];
return worker.postMessage(msg, [buffers[i]]);
}
};
worker.postMessage(msg, [buffers[0]]);
};
Image.prototype.getFrame = function (frame, callback, opts) {
var begin,
blobFrame,
blobs,
buffers,
bytesPerBuffer,
frameInfo,
i,
nRowsPerBuffer,
reader,
start,
_i,
_ref,
_this = this;
this.frame = frame || this.frame;
frameInfo = this.frameOffsets[this.frame];
buffers = frameInfo.buffers;
if ((buffers != null ? buffers.length : void 0) === this.nBuffers) {
return this._getFrameAsync(buffers, callback, opts);
} else {
this.frameOffsets[this.frame].buffers = [];
begin = frameInfo.begin;
blobFrame = this.blob.slice(begin, begin + this.frameLength);
blobs = [];
nRowsPerBuffer = Math.floor(this.height / this.nBuffers);
bytesPerBuffer = nRowsPerBuffer * this.bytes * this.width;
for (i = _i = 0, _ref = this.nBuffers - 1; 0 <= _ref ? _i <= _ref : _i >= _ref; i = 0 <= _ref ? ++_i : --_i) {
start = i * bytesPerBuffer;
if (i === this.nBuffers - 1) {
blobs.push(blobFrame.slice(start));
} else {
blobs.push(blobFrame.slice(start, start + bytesPerBuffer));
}
}
buffers = [];
reader = new FileReader();
reader.frame = this.frame;
i = 0;
reader.onloadend = function (e) {
var buffer;
frame = e.target.frame;
buffer = e.target.result;
_this.frameOffsets[frame].buffers.push(buffer);
i += 1;
if (i === _this.nBuffers) {
return _this.getFrame(frame, callback, opts);
} else {
return reader.readAsArrayBuffer(blobs[i]);
}
};
return reader.readAsArrayBuffer(blobs[0]);
}
};
Image.prototype.getFrames = function (frame, number, callback, opts) {
var _cb,
_this = this;
_cb = function cb(arr, opts) {
_this.invoke(callback, opts, arr);
number -= 1;
frame += 1;
if (!number) {
return;
}
return _this.getFrame(frame, _cb, opts);
};
return this.getFrame(frame, _cb, opts);
};
Image.prototype.isDataCube = function () {
if (this.naxis.length > 2) {
return true;
} else {
return false;
}
};
return Image;
}(DataUnit);
astro.FITS.Image = Image;
Tabular = function (_super) {
__extends(Tabular, _super);
Tabular.prototype.maxMemory = 1048576;
function Tabular(header, data) {
Tabular.__super__.constructor.apply(this, arguments);
this.rowByteSize = header.get("NAXIS1");
this.rows = header.get("NAXIS2");
this.cols = header.get("TFIELDS");
this.length = this.rowByteSize * this.rows;
this.heapLength = header.get("PCOUNT");
this.columns = this.getColumns(header);
if (this.buffer != null) {
this.rowsInMemory = this._rowsInMemoryBuffer;
this.heap = this.buffer.slice(this.length, this.length + this.heapLength);
} else {
this.rowsInMemory = this._rowsInMemoryBlob;
this.firstRowInBuffer = this.lastRowInBuffer = 0;
this.nRowsInBuffer = Math.floor(this.maxMemory / this.rowByteSize);
}
this.accessors = [];
this.descriptors = [];
this.elementByteLengths = [];
this.setAccessors(header);
}
Tabular.prototype._rowsInMemoryBuffer = function () {
return true;
};
Tabular.prototype._rowsInMemoryBlob = function (firstRow, lastRow) {
if (firstRow < this.firstRowInBuffer) {
return false;
}
if (lastRow > this.lastRowInBuffer) {
return false;
}
return true;
};
Tabular.prototype.getColumns = function (header) {
var columns, i, key, _i, _ref;
columns = [];
for (i = _i = 1, _ref = this.cols; 1 <= _ref ? _i <= _ref : _i >= _ref; i = 1 <= _ref ? ++_i : --_i) {
key = "TTYPE" + i;
if (!header.contains(key)) {
return null;
}
columns.push(header.get(key));
}
return columns;
};
Tabular.prototype.getColumn = function (name, callback, opts) {
var accessor,
_cb2,
column,
descriptor,
elementByteLength,
elementByteOffset,
factor,
i,
index,
iterations,
rowsPerIteration,
_this = this;
if (this.blob != null) {
index = this.columns.indexOf(name);
descriptor = this.descriptors[index];
accessor = this.accessors[index];
elementByteLength = this.elementByteLengths[index];
elementByteOffset = this.elementByteLengths.slice(0, index);
if (elementByteOffset.length === 0) {
elementByteOffset = 0;
} else {
elementByteOffset = elementByteOffset.reduce(function (a, b) {
return a + b;
});
}
column = this.typedArray[descriptor] != null ? new this.typedArray[descriptor](this.rows) : [];
rowsPerIteration = ~~(this.maxMemory / this.rowByteSize);
rowsPerIteration = Math.min(rowsPerIteration, this.rows);
factor = this.rows / rowsPerIteration;
iterations = Math.floor(factor) === factor ? factor : Math.floor(factor) + 1;
i = 0;
index = 0;
_cb2 = function cb(buffer, opts) {
var nRows, offset, startRow, view;
nRows = buffer.byteLength / _this.rowByteSize;
view = new DataView(buffer);
offset = elementByteOffset;
while (nRows--) {
column[i] = accessor(view, offset)[0];
i += 1;
offset += _this.rowByteSize;
}
iterations -= 1;
index += 1;
if (iterations) {
startRow = index * rowsPerIteration;
return _this.getTableBuffer(startRow, rowsPerIteration, _cb2, opts);
} else {
_this.invoke(callback, opts, column);
}
};
return this.getTableBuffer(0, rowsPerIteration, _cb2, opts);
} else {
_cb2 = function _cb2(rows, opts) {
column = rows.map(function (d) {
return d[name];
});
return _this.invoke(callback, opts, column);
};
return this.getRows(0, this.rows, _cb2, opts);
}
};
Tabular.prototype.getTableBuffer = function (row, number, callback, opts) {
var begin,
blobRows,
end,
reader,
_this = this;
number = Math.min(this.rows - row, number);
begin = row * this.rowByteSize;
end = begin + number * this.rowByteSize;
blobRows = this.blob.slice(begin, end);
reader = new FileReader();
reader.row = row;
reader.number = number;
reader.onloadend = function (e) {
return _this.invoke(callback, opts, e.target.result);
};
return reader.readAsArrayBuffer(blobRows);
};
Tabular.prototype.getRows = function (row, number, callback, opts) {
var begin,
blobRows,
buffer,
end,
reader,
rows,
_this = this;
if (this.rowsInMemory(row, row + number)) {
if (this.blob != null) {
buffer = this.buffer;
} else {
begin = row * this.rowByteSize;
end = begin + number * this.rowByteSize;
buffer = this.buffer.slice(begin, end);
}
rows = this._getRows(buffer, number);
this.invoke(callback, opts, rows);
return rows;
} else {
begin = row * this.rowByteSize;
end = begin + Math.max(this.nRowsInBuffer * this.rowByteSize, number * this.rowByteSize);
blobRows = this.blob.slice(begin, end);
reader = new FileReader();
reader.row = row;
reader.number = number;
reader.onloadend = function (e) {
var target;
target = e.target;
_this.buffer = target.result;
_this.firstRowInBuffer = _this.lastRowInBuffer = target.row;
_this.lastRowInBuffer += target.number;
return _this.getRows(row, number, callback, opts);
};
return reader.readAsArrayBuffer(blobRows);
}
};
return Tabular;
}(DataUnit);
astro.FITS.Tabular = Tabular;
Table = function (_super) {
__extends(Table, _super);
function Table() {
_ref = Table.__super__.constructor.apply(this, arguments);
return _ref;
}
Table.prototype.dataAccessors = {
A: function A(value) {
return value.trim();
},
I: function I(value) {
return parseInt(value);
},
F: function F(value) {
return parseFloat(value);
},
E: function E(value) {
return parseFloat(value);
},
D: function D(value) {
return parseFloat(value);
}
};
Table.prototype.setAccessors = function (header) {
var descriptor,
form,
i,
match,
pattern,
type,
_i,
_ref1,
_results,
_this = this;
pattern = /([AIFED])(\d+)\.*(\d+)*/;
_results = [];
for (i = _i = 1, _ref1 = this.cols; 1 <= _ref1 ? _i <= _ref1 : _i >= _ref1; i = 1 <= _ref1 ? ++_i : --_i) {
form = header.get("TFORM" + i);
type = header.get("TTYPE" + i);
match = pattern.exec(form);
descriptor = match[1];
_results.push(function (descriptor) {
var accessor;
accessor = function accessor(value) {
return _this.dataAccessors[descriptor](value);
};
return _this.accessors.push(accessor);
}(descriptor));
}
return _results;
};
Table.prototype._getRows = function (buffer) {
var accessor, arr, begin, end, i, index, line, nRows, row, rows, subarray, value, _i, _j, _k, _len, _len1, _ref1, _ref2;
nRows = buffer.byteLength / this.rowByteSize;
arr = new Uint8Array(buffer);
rows = [];
for (i = _i = 0, _ref1 = nRows - 1; 0 <= _ref1 ? _i <= _ref1 : _i >= _ref1; i = 0 <= _ref1 ? ++_i : --_i) {
begin = i * this.rowByteSize;
end = begin + this.rowByteSize;
subarray = arr.subarray(begin, end);
line = '';
for (_j = 0, _len = subarray.length; _j < _len; _j++) {
value = subarray[_j];
line += String.fromCharCode(value);
}
line = line.trim().split(/\s+/);
row = {};
_ref2 = this.accessors;
for (index = _k = 0, _len1 = _ref2.length; _k < _len1; index = ++_k) {
accessor = _ref2[index];
value = line[index];
row[this.columns[index]] = accessor(value);
}
rows.push(row);
}
return rows;
};
return Table;
}(Tabular);
astro.FITS.Table = Table;
BinaryTable = function (_super) {
__extends(BinaryTable, _super);
function BinaryTable() {
_ref1 = BinaryTable.__super__.constructor.apply(this, arguments);
return _ref1;
}
BinaryTable.prototype.typedArray = {
B: Uint8Array,
I: Uint16Array,
J: Uint32Array,
E: Float32Array,
D: Float64Array,
1: Uint8Array,
2: Uint16Array,
4: Uint32Array
};
BinaryTable.offsets = {
L: 1,
B: 1,
I: 2,
J: 4,
K: 8,
A: 1,
E: 4,
D: 8,
C: 8,
M: 16
};
BinaryTable.prototype.dataAccessors = {
L: function L(view, offset) {
var val, x;
x = view.getInt8(offset);
offset += 1;
val = x === 84 ? true : false;
return [val, offset];
},
B: function B(view, offset) {
var val;
val = view.getUint8(offset);
offset += 1;
return [val, offset];
},
I: function I(view, offset) {
var val;
val = view.getInt16(offset);
offset += 2;
return [val, offset];
},
J: function J(view, offset) {
var val;
val = view.getInt32(offset);
offset += 4;
return [val, offset];
},
K: function K(view, offset) {
var factor, highByte, lowByte, mod, val;
highByte = Math.abs(view.getInt32(offset));
offset += 4;
lowByte = Math.abs(view.getInt32(offset));
offset += 4;
mod = highByte % 10;
factor = mod ? -1 : 1;
highByte -= mod;
val = factor * (highByte << 32 | lowByte);
return [val, offset];
},
A: function A(view, offset) {
var val;
val = view.getUint8(offset);
val = String.fromCharCode(val);
offset += 1;
return [val, offset];
},
E: function E(view, offset) {
var val;
val = view.getFloat32(offset);
offset += 4;
return [val, offset];
},
D: function D(view, offset) {
var val;
val = view.getFloat64(offset);
offset += 8;
return [val, offset];
},
C: function C(view, offset) {
var val, val1, val2;
val1 = view.getFloat32(offset);
offset += 4;
val2 = view.getFloat32(offset);
offset += 4;
val = [val1, val2];
return [val, offset];
},
M: function M(view, offset) {
var val, val1, val2;
val1 = view.getFloat64(offset);
offset += 8;
val2 = view.getFloat64(offset);
offset += 8;
val = [val1, val2];
return [val, offset];
}
};
BinaryTable.prototype.toBits = function (byte) {
var arr, i;
arr = [];
i = 128;
while (i >= 1) {
arr.push(byte & i ? 1 : 0);
i /= 2;
}
return arr;
};
BinaryTable.prototype.getFromHeap = function (view, offset, descriptor) {
var arr, heapOffset, heapSlice, i, length;
length = view.getInt32(offset);
offset += 4;
heapOffset = view.getInt32(offset);
offset += 4;
heapSlice = this.heap.slice(heapOffset, heapOffset + length);
arr = new this.typedArray[descriptor](heapSlice);
i = arr.length;
while (i--) {
arr[i] = this.constructor.swapEndian[descriptor](arr[i]);
}
return [arr, offset];
};
BinaryTable.prototype.setAccessors = function (header) {
var count,
descriptor,
form,
i,
isArray,
match,
pattern,
type,
_i,
_ref2,
_results,
_this = this;
pattern = /(\d*)([P|Q]*)([L|X|B|I|J|K|A|E|D|C|M]{1})/;
_results = [];
for (i = _i = 1, _ref2 = this.cols; 1 <= _ref2 ? _i <= _ref2 : _i >= _ref2; i = 1 <= _ref2 ? ++_i : --_i) {
form = header.get("TFORM" + i);
type = header.get("TTYPE" + i);
match = pattern.exec(form);
count = parseInt(match[1]) || 1;
isArray = match[2];
descriptor = match[3];
_results.push(function (descriptor, count) {
var accessor, nBytes;
_this.descriptors.push(descriptor);
_this.elementByteLengths.push(_this.constructor.offsets[descriptor] * count);
if (isArray) {
switch (type) {
case "COMPRESSED_DATA":
accessor = function accessor(view, offset) {
var arr, pixels, _ref3;
_ref3 = _this.getFromHeap(view, offset, descriptor);
arr = _ref3[0];
offset = _ref3[1];
pixels = new _this.typedArray[_this.algorithmParameters["BYTEPIX"]](_this.ztile[0]);
Decompress.Rice(arr, _this.algorithmParameters["BLOCKSIZE"], _this.algorithmParameters["BYTEPIX"], pixels, _this.ztile[0], Decompress.RiceSetup);
return [pixels, offset];
};
break;
case "GZIP_COMPRESSED_DATA":
accessor = function accessor(view, offset) {
var arr;
arr = new Float32Array(_this.width);
i = arr.length;
while (i--) {
arr[i] = NaN;
}
return [arr, offset];
};
break;
default:
accessor = function accessor(view, offset) {
return _this.getFromHeap(view, offset, descriptor);
};
}
} else {
if (count === 1) {
accessor = function accessor(view, offset) {
var value, _ref3;
_ref3 = _this.dataAccessors[descriptor](view, offset);
value = _ref3[0];
offset = _ref3[1];
return [value, offset];
};
} else {
if (descriptor === 'X') {
nBytes = Math.log(count) / Math.log(2);
accessor = function accessor(view, offset) {
var arr, bits, buffer, byte, bytes, _j, _len;
buffer = view.buffer.slice(offset, offset + nBytes);
bytes = new Uint8Array(buffer);
bits = [];
for (_j = 0, _len = bytes.length; _j < _len; _j++) {
byte = bytes[_j];
arr = _this.toBits(byte);
bits = bits.concat(arr);
}
offset += nBytes;
return [bits.slice(0, +(count - 1) + 1 || 9e9), offset];
};
} else if (descriptor === 'A') {
accessor = function accessor(view, offset) {
var arr, buffer, s, value, _j, _len;
buffer = view.buffer.slice(offset, offset + count);
arr = new Uint8Array(buffer);
s = '';
for (_j = 0, _len = arr.length; _j < _len; _j++) {
value = arr[_j];
s += String.fromCharCode(value);
}
s = s.trim();
offset += count;
return [s, offset];
};
} else {
accessor = function accessor(view, offset) {
var data, value, _ref3;
i = count;
data = [];
while (i--) {
_ref3 = _this.dataAccessors[descriptor](view, offset);
value = _ref3[0];
offset = _ref3[1];
data.push(value);
}
return [data, offset];
};
}
}
}
return _this.accessors.push(accessor);
}(descriptor, count));
}
return _results;
};
BinaryTable.prototype._getRows = function (buffer, nRows) {
var accessor, index, offset, row, rows, value, view, _i, _len, _ref2, _ref3;
view = new DataView(buffer);
offset = 0;
rows = [];
while (nRows--) {
row = {};
_ref2 = this.accessors;
for (index = _i = 0, _len = _ref2.length; _i < _len; index = ++_i) {
accessor = _ref2[index];
_ref3 = accessor(view, offset);
value = _ref3[0];
offset = _ref3[1];
row[this.columns[index]] = value;
}
rows.push(row);
}
return rows;
};
return BinaryTable;
}(Tabular);
astro.FITS.BinaryTable = BinaryTable;
Decompress = {
RiceSetup: {
1: function _(array) {
var fsbits, fsmax, lastpix, pointer;
pointer = 1;
fsbits = 3;
fsmax = 6;
lastpix = array[0];
return [fsbits, fsmax, lastpix, pointer];
},
2: function _(array) {
var bytevalue, fsbits, fsmax, lastpix, pointer;
pointer = 2;
fsbits = 4;
fsmax = 14;
lastpix = 0;
bytevalue = array[0];
lastpix = lastpix | bytevalue << 8;
bytevalue = array[1];
lastpix = lastpix | bytevalue;
return [fsbits, fsmax, lastpix, pointer];
},
4: function _(array) {
var bytevalue, fsbits, fsmax, lastpix, pointer;
pointer = 4;
fsbits = 5;
fsmax = 25;
lastpix = 0;
bytevalue = array[0];
lastpix = lastpix | bytevalue << 24;
bytevalue = array[1];
lastpix = lastpix | bytevalue << 16;
bytevalue = array[2];
lastpix = lastpix | bytevalue << 8;
bytevalue = array[3];
lastpix = lastpix | bytevalue;
return [fsbits, fsmax, lastpix, pointer];
}
},
Rice: function Rice(array, blocksize, bytepix, pixels, nx, setup) {
var b, bbits, diff, fs, fsbits, fsmax, i, imax, k, lastpix, nbits, nonzeroCount, nzero, pointer, _ref2, _ref3;
bbits = 1 << fsbits;
_ref2 = setup[bytepix](array);
fsbits = _ref2[0];
fsmax = _ref2[1];
lastpix = _ref2[2];
pointer = _ref2[3];
nonzeroCount = new Uint8Array(256);
nzero = 8;
_ref3 = [128, 255];
k = _ref3[0];
i = _ref3[1];
while (i >= 0) {
while (i >= k) {
nonzeroCount[i] = nzero;
i -= 1;
}
k = k / 2;
nzero -= 1;
}
nonzeroCount[0] = 0;
b = array[pointer++];
nbits = 8;
i = 0;
while (i < nx) {
nbits -= fsbits;
while (nbits < 0) {
b = b << 8 | array[pointer++];
nbits += 8;
}
fs = (b >> nbits) - 1;
b &= (1 << nbits) - 1;
imax = i + blocksize;
if (imax > nx) {
imax = nx;
}
if (fs < 0) {
while (i < imax) {
pixels[i] = lastpix;
i += 1;
}
} else if (fs === fsmax) {
while (i < imax) {
k = bbits - nbits;
diff = b << k;
k -= 8;
while (k >= 0) {
b = array[pointer++];
diff |= b << k;
k -= 8;
}
if (nbits > 0) {
b = array[pointer++];
diff |= b >> -k;
b &= (1 << nbits) - 1;
} else {
b = 0;
}
if ((diff & 1) === 0) {
diff = diff >> 1;
} else {
diff = ~(diff >> 1);
}
pixels[i] = diff + lastpix;
lastpix = pixels[i];
i++;