// Generated by CoffeeScript 1.6.3 (function() { var Base, BinaryTable, CompressedImage, DataUnit, Decompress, FITS, HDU, Header, HeaderVerify, Image, ImageUtils, Parser, Table, Tabular, _ref, _ref1, __hasProp = {}.hasOwnProperty, __extends = function(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; if (this.astro == null) { this.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'; 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'; this.astro.FITS = FITS; DataUnit = (function(_super) { __extends(DataUnit, _super); DataUnit.swapEndian = { B: function(value) { return value; }, I: function(value) { return (value << 8) | (value >> 8); }, J: function(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); this.astro.FITS.DataUnit = DataUnit; HeaderVerify = { verifyOrder: function(keyword, order) { if (order !== this.cardIndex) { return console.warn("" + keyword + " should appear at index " + this.cardIndex + " in the FITS header"); } }, verifyBetween: function(keyword, value, lower, upper) { if (!(value >= lower && value <= upper)) { throw "The " + keyword + " value of " + value + " is not between " + lower + " and " + upper; } }, verifyBoolean: function(value) { if (value === "T") { return true; } else { return false; } }, VerifyFns: { SIMPLE: function() { var args, value; args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; value = arguments[0]; this.primary = true; this.verifyOrder("SIMPLE", 0); return this.verifyBoolean(value); }, XTENSION: function() { 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() { 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() { 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() { 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() { 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() { 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() { var args; args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; return parseFloat(arguments[0]); }, BZERO: function() { var args; args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; return parseFloat(arguments[0]); }, BLANK: function() { 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() { var args; args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; return parseFloat(arguments[0]); }, DATAMAX: function() { var args; args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; return parseFloat(arguments[0]); }, EXTVER: function() { var args; args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; return parseInt(arguments[0]); }, EXTLEVEL: function() { var args; args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; return parseInt(arguments[0]); }, TFIELDS: function() { 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() { 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() { var args; args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; return this.verifyBoolean(arguments[0]); }, ZCMPTYPE: function() { 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() { 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() { 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() { var args; args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; return parseInt(arguments[0]); }, ZSIMPLE: function() { var args; args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; if (arguments[0] === "T") { return true; } else { return false; } }, ZPCOUNT: function() { var args; args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; return parseInt(arguments[0]); }, ZGCOUNT: function() { var args; args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; return parseInt(arguments[0]); }, ZDITHER0: function() { var args; args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; return parseInt(arguments[0]); } } }; this.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); this.astro.FITS.Header = Header; ImageUtils = { getExtent: function(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(arr, x, y) { return arr[y * this.width + x]; } }; this.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(value) { return value; }; break; case 16: tmp = new Int16Array(buffer); swapEndian = function(value) { return ((value & 0xFF) << 8) | ((value >> 8) & 0xFF); }; break; case 32: tmp = new Int32Array(buffer); swapEndian = function(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(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(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 = _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(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); this.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, cb, 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; cb = function(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, cb, opts); } else { _this.invoke(callback, opts, column); } }; return this.getTableBuffer(0, rowsPerIteration, cb, opts); } else { cb = function(rows, opts) { column = rows.map(function(d) { return d[name]; }); return _this.invoke(callback, opts, column); }; return this.getRows(0, this.rows, cb, 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); this.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(value) { return value.trim(); }, I: function(value) { return parseInt(value); }, F: function(value) { return parseFloat(value); }, E: function(value) { return parseFloat(value); }, D: function(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(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); this.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(view, offset) { var val, x; x = view.getInt8(offset); offset += 1; val = x === 84 ? true : false; return [val, offset]; }, B: function(view, offset) { var val; val = view.getUint8(offset); offset += 1; return [val, offset]; }, I: function(view, offset) { var val; val = view.getInt16(offset); offset += 2; return [val, offset]; }, J: function(view, offset) { var val; val = view.getInt32(offset); offset += 4; return [val, offset]; }, K: function(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(view, offset) { var val; val = view.getUint8(offset); val = String.fromCharCode(val); offset += 1; return [val, offset]; }, E: function(view, offset) { var val; val = view.getFloat32(offset); offset += 4; return [val, offset]; }, D: function(view, offset) { var val; val = view.getFloat64(offset); offset += 8; return [val, offset]; }, C: function(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(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(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(view, offset) { var arr; arr = new Float32Array(_this.width); i = arr.length; while (i--) { arr[i] = NaN; } return [arr, offset]; }; break; default: accessor = function(view, offset) { return _this.getFromHeap(view, offset, descriptor); }; } } else { if (count === 1) { accessor = function(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(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(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(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); this.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(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++; } } else { while (i < imax) { while (b === 0) { nbits += 8; b = array[pointer++]; } nzero = nbits - nonzeroCount[b]; nbits -= nzero + 1; b ^= 1 << nbits; nbits -= fs; while (nbits < 0) { b = (b << 8) | array[pointer++]; nbits += 8; } diff = (nzero << fs) | (b >> nbits); b &= (1 << nbits) - 1; if ((diff & 1) === 0) { diff = diff >> 1; } else { diff = ~(diff >> 1); } pixels[i] = diff + lastpix; lastpix = pixels[i]; i++; } } } return pixels; } }; this.astro.FITS.Decompress = Decompress; CompressedImage = (function(_super) { __extends(CompressedImage, _super); CompressedImage.include(ImageUtils); CompressedImage.extend(Decompress); CompressedImage.randomGenerator = function() { var a, i, m, random, seed, temp, _i; a = 16807; m = 2147483647; seed = 1; random = new Float32Array(10000); for (i = _i = 0; _i <= 9999; i = ++_i) { temp = a * seed; seed = temp - m * parseInt(temp / m); random[i] = seed / m; } return random; }; CompressedImage.randomSequence = CompressedImage.randomGenerator(); function CompressedImage(header, data) { var i, key, value, ztile, _i, _ref2; CompressedImage.__super__.constructor.apply(this, arguments); this.zcmptype = header.get("ZCMPTYPE"); this.zbitpix = header.get("ZBITPIX"); this.znaxis = header.get("ZNAXIS"); this.zblank = header.get("ZBLANK"); this.blank = header.get("BLANK"); this.zdither = header.get('ZDITHER0') || 0; this.ztile = []; for (i = _i = 1, _ref2 = this.znaxis; 1 <= _ref2 ? _i <= _ref2 : _i >= _ref2; i = 1 <= _ref2 ? ++_i : --_i) { ztile = header.contains("ZTILE" + i) ? header.get("ZTILE" + i) : i === 1 ? header.get("ZNAXIS1") : 1; this.ztile.push(ztile); } this.width = header.get("ZNAXIS1"); this.height = header.get("ZNAXIS2") || 1; this.algorithmParameters = {}; if (this.zcmptype === 'RICE_1') { this.algorithmParameters["BLOCKSIZE"] = 32; this.algorithmParameters["BYTEPIX"] = 4; } i = 1; while (true) { key = "ZNAME" + i; if (!header.contains(key)) { break; } value = "ZVAL" + i; this.algorithmParameters[header.get(key)] = header.get(value); i += 1; } this.zmaskcmp = header.get("ZMASKCMP"); this.zquantiz = header.get("ZQUANTIZ") || "LINEAR_SCALING"; this.bzero = header.get("BZERO") || 0; this.bscale = header.get("BSCALE") || 1; } CompressedImage.prototype._getRows = function(buffer, nRows) { var accessor, arr, blank, data, i, index, nTile, offset, r, rIndex, row, scale, seed0, seed1, value, view, zero, _i, _j, _len, _len1, _ref2, _ref3; view = new DataView(buffer); offset = 0; arr = new Float32Array(this.width * this.height); 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; } data = row['COMPRESSED_DATA'] || row['UNCOMPRESSED_DATA'] || row['GZIP_COMPRESSED_DATA']; blank = row['ZBLANK'] || this.zblank; scale = row['ZSCALE'] || this.bscale; zero = row['ZZERO'] || this.bzero; nTile = this.height - nRows; seed0 = nTile + this.zdither - 1; seed1 = (seed0 - 1) % 10000; rIndex = parseInt(this.constructor.randomSequence[seed1] * 500); for (index = _j = 0, _len1 = data.length; _j < _len1; index = ++_j) { value = data[index]; i = (nTile - 1) * this.width + index; if (value === -2147483647) { arr[i] = NaN; } else if (value === -2147483646) { arr[i] = 0; } else { r = this.constructor.randomSequence[rIndex]; arr[i] = (value - r + 0.5) * scale + zero; } rIndex += 1; if (rIndex === 10000) { seed1 = (seed1 + 1) % 10000; rIndex = parseInt(this.randomSequence[seed1] * 500); } } } return arr; }; CompressedImage.prototype.getFrame = function(nFrame, callback, opts) { var heapBlob, reader, _this = this; if (this.heap) { this.frame = nFrame || this.frame; return this.getRows(0, this.rows, callback, opts); } else { heapBlob = this.blob.slice(this.length, this.length + this.heapLength); reader = new FileReader(); reader.onloadend = function(e) { _this.heap = e.target.result; return _this.getFrame(nFrame, callback, opts); }; return reader.readAsArrayBuffer(heapBlob); } }; return CompressedImage; })(BinaryTable); this.astro.FITS.CompressedImage = CompressedImage; HDU = (function() { function HDU(header, data) { this.header = header; this.data = data; } HDU.prototype.hasData = function() { if (this.data != null) { return true; } else { return false; } }; return HDU; })(); this.astro.FITS.HDU = HDU; }).call(this);