slimfits
Version:
Package for loading data stored in FITS data format
252 lines • 12.7 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
var interfaces_1 = require("../interfaces");
var KeywordsManager_1 = require("../utils/KeywordsManager");
var ArrayUtils_1 = require("../utils/ArrayUtils");
var Rice_1 = require("../utils/Rice");
var BinaryTableDataReader_1 = require("./BinaryTableDataReader");
var pako_1 = require("pako");
var CompressedImageReader = /** @class */ (function () {
function CompressedImageReader() {
this.binaryTableDataReader = new BinaryTableDataReader_1.BinaryTableDataReader();
}
CompressedImageReader.convertToTiles = function (pointers, compressedData) {
var tiles = [];
var rowsCount = pointers.length / 2;
for (var i = 0; i < rowsCount; i++) {
tiles.push(new Uint8Array(compressedData.buffer, pointers[2 * i + 1], pointers[2 * i]));
}
return tiles;
};
CompressedImageReader.riceExtract = function (compressedTile, blockSize, bytePix) {
return compressedTile;
};
Object.defineProperty(CompressedImageReader.prototype, "name", {
get: function () {
return 'compressed image data';
},
enumerable: true,
configurable: true
});
CompressedImageReader.prototype.canReadData = function (header) {
var ztiles = header.filter(function (k) { return k.key.indexOf('ZTILE') === 0 && (k.key !== 'ZTILE'); });
var compressionType = KeywordsManager_1.KeywordsManager.getValue(header, 'ZCMPTYPE', '');
return KeywordsManager_1.KeywordsManager.hasValueFromList(header, 'XTENSION', ['BINTABLE', 'A3DTABLE']) &&
KeywordsManager_1.KeywordsManager.hasValue(header, 'ZIMAGE', true) && (compressionType === 'RICE_1') &&
(ztiles.length === 2) &&
(ztiles[1].value === 1);
};
CompressedImageReader.prototype.readDataSize = function (header) {
return this.binaryTableDataReader.readDataSize(header);
};
CompressedImageReader.prototype.readDataAsync = function (file, offsetBytes, header) {
return this.binaryTableDataReader.readDataAsync(file, offsetBytes, header)
.then(function (result) {
var riceBlockSize = KeywordsManager_1.KeywordsManager.getValue(header, 'ZVAL1', 32);
var riceByteWidth = KeywordsManager_1.KeywordsManager.getValue(header, 'ZVAL2', 4);
var ztiles = header.filter(function (k) { return k.key.indexOf('ZTILE') === 0 && (k.key !== 'ZTILE'); });
var bitpix = KeywordsManager_1.KeywordsManager.getValue(header, 'ZBITPIX', interfaces_1.BitPix.Unknown);
var tileLinearSize = ztiles.reduce(function (x, y) { return x * y.value; }, 1);
var tileByteSize = interfaces_1.BitPixUtils.getByteSize(bitpix) * tileLinearSize;
var tiles = result
.filter(function (column) { return (column.name === 'COMPRESSED_DATA'); })
.map(function (x) { return x.data; })[0];
var uncompressedBuffer = new ArrayBuffer(tileByteSize * tiles.length);
// floats may be sometimes gzip compressed even though they were explicitly asked to
// be RICE compressed ¯\_(ツ)_/¯
if (((bitpix === interfaces_1.BitPix.Float32) || (bitpix === interfaces_1.BitPix.Float64))
&& result.some(function (column) { return column.name === 'GZIP_COMPRESSED_DATA'; })) {
var gzip_tiles = result.filter(function (column) { return column.name === 'GZIP_COMPRESSED_DATA'; })[0];
var bytesPerElement = interfaces_1.BitPixUtils.getByteSize(bitpix);
gzip_tiles.data.forEach(function (tile, i) {
var inflated_tile = pako_1.inflate(tile);
ArrayUtils_1.ArrayUtils.copy(inflated_tile.buffer, uncompressedBuffer, 0, tileLinearSize, bitpix, true, i * tileByteSize);
});
if (bitpix === interfaces_1.BitPix.Float32) {
var result_1 = new Float32Array(uncompressedBuffer);
return result_1;
}
else {
var result_2 = new Float64Array(uncompressedBuffer);
return result_2;
}
}
if (!tiles) {
throw new Error('COMPRESSED_DATA not found');
}
var uncompressed = [];
// so tiles occupy one place in memory
if (riceByteWidth === interfaces_1.BitPixUtils.getByteSize(interfaces_1.BitPix.Int32)) {
uncompressed = tiles.map(function (tile, index) {
var out = new Int32Array(uncompressedBuffer, index * tileByteSize, tileLinearSize);
Rice_1.Rice.fits_rdecomp(tile, out, riceBlockSize);
return out;
});
}
else if (riceByteWidth === interfaces_1.BitPixUtils.getByteSize(interfaces_1.BitPix.Int16)) {
uncompressed = tiles.map(function (tile, index) {
var out = new Int16Array(uncompressedBuffer, index * tileByteSize, tileLinearSize);
Rice_1.Rice.fits_rdecomp_short(tile, out, riceBlockSize);
return out;
});
}
else if (riceByteWidth === interfaces_1.BitPixUtils.getByteSize(interfaces_1.BitPix.Uint8)) {
uncompressed = tiles.map(function (tile, index) {
var out = new Uint8Array(uncompressedBuffer, index * tileByteSize, tileLinearSize);
Rice_1.Rice.fits_rdecomp_byte(tile, out, riceBlockSize);
return out;
});
}
var bscale = KeywordsManager_1.KeywordsManager.getValue(header, 'BSCALE', 1);
var bzero = KeywordsManager_1.KeywordsManager.getValue(header, 'BZERO', 0);
var zscale = result.filter(function (column) { return column.name === 'ZSCALE'; })[0];
var zzero = result.filter(function (column) { return column.name === 'ZZERO'; })[0];
switch (bitpix) {
case interfaces_1.BitPix.Uint8:
return CompressedImageReader.convertByte(uncompressedBuffer, bzero, bscale);
case interfaces_1.BitPix.Int16:
return CompressedImageReader.convertShort(uncompressedBuffer, bzero, bscale);
case interfaces_1.BitPix.Int32:
return CompressedImageReader.convertInt(uncompressedBuffer, bzero, bscale);
case interfaces_1.BitPix.Float32:
return CompressedImageReader.convertFloat(uncompressed, zscale.data, zzero.data, header);
case interfaces_1.BitPix.Float64:
return CompressedImageReader.convertDouble(uncompressed, zscale.data, zzero.data, header);
default:
throw new Error('Unknow bitpix');
}
});
};
CompressedImageReader.convertByte = function (buffer, bzero, bscale) {
return new Uint8Array(buffer);
};
CompressedImageReader.convertShort = function (buffer, bzero, bscale) {
if ((bscale === 1) && (bzero === 0)) {
return new Int16Array(buffer);
}
else if ((bscale === 1) && (bzero === 32768)) {
var src = new Int16Array(buffer);
var dest = new Uint16Array(buffer);
for (var i = 0; i < src.length; i++) {
dest[i] = bscale * src[i] + bzero;
}
return dest;
}
else {
var data = new Int16Array(buffer);
for (var i = 0; i < data.length; i++) {
data[i] = bscale * data[i] + bzero;
}
return data;
}
};
CompressedImageReader.convertInt = function (buffer, bzero, bscale) {
if ((bscale === 1) && (bzero === 0)) {
return new Int32Array(buffer);
}
else if ((bscale === 1) && (bzero === 2147483648)) {
var src = new Int32Array(buffer);
var dest = new Uint32Array(buffer);
for (var i = 0; i < src.length; i++) {
dest[i] = bscale * src[i] + bzero;
}
return dest;
}
else {
var data = new Int32Array(buffer);
for (var i = 0; i < data.length; i++) {
data[i] = bscale * data[i] + bzero;
}
return data;
}
};
CompressedImageReader.convertFloat = function (tiles, zscale, zzero, header) {
var quantiz = KeywordsManager_1.KeywordsManager.getValue(header, 'ZQUANTIZ', 'NO_DITHER');
var output = new Float32Array(tiles.length * tiles[0].length);
if (quantiz === 'NO_DITHER') {
tiles.forEach(function (tile, tileNum) {
var output_tile = new Float32Array(output.buffer, tileNum * tile.length * 4, tile.length);
var zscale_value = zscale[tileNum][0];
var zzero_value = zzero[tileNum][0];
for (var i = 0; i < tile.length; i++) {
output_tile[i] = tile[i] * zscale_value + zzero_value;
}
});
}
else if (quantiz === 'SUBTRACTIVE_DITHER_1') {
var rn_1 = CompressedImageReader.initRandoms();
var zdither0_1 = KeywordsManager_1.KeywordsManager.getValue(header, 'ZDITHER0', 0);
tiles.forEach(function (tile, tileNum) {
var i0 = (tileNum - 1 + zdither0_1) % 10000;
var i1 = parseInt(rn_1[i0] * 500, 10);
var output_tile = new Float32Array(output.buffer, tileNum * tile.length * 4, tile.length);
var zscale_value = zscale[tileNum][0];
var zzero_value = zzero[tileNum][0];
for (var i = 0; i < tile.length; i++) {
output_tile[i] = (tile[i] - rn_1[i1] + 0.5) * zscale_value + zzero_value;
i1++;
if (i1 === 10000) {
i0 = (i0 + 1) % 10000;
i1 = parseInt(rn_1[i0] * 500, 10);
}
}
});
}
else {
throw new Error('ZQUANTIZ unrecognized type');
}
return output;
};
CompressedImageReader.convertDouble = function (tiles, zscale, zzero, header) {
var quantiz = KeywordsManager_1.KeywordsManager.getValue(header, 'ZQUANTIZ', 'NO_DITHER');
var output = new Float64Array(tiles.length * tiles[0].length);
if (quantiz === 'NO_DITHER') {
tiles.forEach(function (tile, tileNum) {
var output_tile = new Float64Array(output.buffer, tileNum * tile.length * 8, tile.length);
var zscale_value = zscale[tileNum][0];
var zzero_value = zzero[tileNum][0];
for (var i = 0; i < tile.length; i++) {
output_tile[i] = tile[i] * zscale_value + zzero_value;
}
});
}
else if (quantiz === 'SUBTRACTIVE_DITHER_1') {
var rn_2 = CompressedImageReader.initRandoms();
var zdither0_2 = KeywordsManager_1.KeywordsManager.getValue(header, 'ZDITHER0', 0);
tiles.forEach(function (tile, tileNum) {
var i0 = (tileNum - 1 + zdither0_2) % 10000;
var i1 = parseInt(rn_2[i0] * 500, 10);
var output_tile = new Float64Array(output.buffer, tileNum * tile.length * 8, tile.length);
var zscale_value = zscale[tileNum][0];
var zzero_value = zzero[tileNum][0];
for (var i = 0; i < tile.length; i++) {
output_tile[i] = (tile[i] - rn_2[i1] + 0.5) * zscale_value + zzero_value;
i1++;
if (i1 === 10000) {
i0 = (i0 + 1) % 10000;
i1 = parseInt(rn_2[i0] * 500, 10);
}
}
});
}
else {
throw new Error('ZQUANTIZ unrecognized type');
}
return output;
};
CompressedImageReader.initRandoms = function () {
var a = 16807;
var m = 2147483647;
var seed = 1;
var random = new Float32Array(10000);
for (var i = 0; i < random.length; i++) {
var temp = a * seed;
seed = temp - m * parseInt((temp / m), 10);
random[i] = seed / m;
}
return random;
};
return CompressedImageReader;
}());
exports.CompressedImageReader = CompressedImageReader;
//# sourceMappingURL=CompressedImageReader.js.map