else {
for (i=0; i < (count*2); i+=2) {
values[i] = readMethod.call(
this.dataView, offset + (i*fieldTypeLength), this.littleEndian
);
values[i+1] = readMethod.call(
this.dataView, offset + ((i+1)*fieldTypeLength), this.littleEndian
);
}
}
if (fieldType === fieldTypes.ASCII) {
return String.fromCharCode.apply(null, values);
}
return values;
},
getFieldValues: function(fieldTag, fieldType, typeCount, valueOffset) {
var fieldValues;
var fieldTypeLength = this.getFieldTypeLength(fieldType);
if (fieldTypeLength * typeCount <= 4) {
fieldValues = this.getValues(fieldType, typeCount, valueOffset);
}
else {
var actualOffset = this.dataView.getUint32(valueOffset, this.littleEndian);
fieldValues = this.getValues(fieldType, typeCount, actualOffset);
}
if (typeCount === 1 && arrayFields.indexOf(fieldTag) === -1 && !(fieldType === fieldTypes.RATIONAL || fieldType === fieldTypes.SRATIONAL)) {
return fieldValues[0];
}
return fieldValues;
},
parseGeoKeyDirectory: function(fileDirectory) {
var rawGeoKeyDirectory = fileDirectory.GeoKeyDirectory;
if (!rawGeoKeyDirectory) {
return null;
}
var geoKeyDirectory = {};
for (var i = 4; i < rawGeoKeyDirectory[3] * 4; i += 4) {
var key = geoKeyNames[rawGeoKeyDirectory[i]],
location = (rawGeoKeyDirectory[i+1]) ? (fieldTagNames[rawGeoKeyDirectory[i+1]]) : null,
count = rawGeoKeyDirectory[i+2],
offset = rawGeoKeyDirectory[i+3];
var value = null;
if (!location) {
value = offset;
}
else {
value = fileDirectory[location];
if (typeof value === "undefined" || value === null) {
throw new Error("Could not get value of geoKey '" + key + "'.");
}
else if (typeof value === "string") {
value = value.substring(offset, offset + count - 1);
}
else if (value.subarray) {
value = value.subarray(offset, offset + count - 1);
}
}
geoKeyDirectory[key] = value;
}
return geoKeyDirectory;
},
parseFileDirectories: function(byteOffset) {
var nextIFDByteOffset = byteOffset;
var fileDirectories = [];
while (nextIFDByteOffset !== 0x00000000) {
var numDirEntries = this.dataView.getUint16(nextIFDByteOffset, this.littleEndian);
var fileDirectory = {};
for (var i = byteOffset + 2, entryCount = 0; entryCount < numDirEntries; i += 12, ++entryCount) {
var fieldTag = this.dataView.getUint16(i, this.littleEndian);
var fieldType = this.dataView.getUint16(i + 2, this.littleEndian);
var typeCount = this.dataView.getUint32(i + 4, this.littleEndian);
fileDirectory[fieldTagNames[fieldTag]] = this.getFieldValues(
fieldTag, fieldType, typeCount, i + 8
);
}
fileDirectories.push([
fileDirectory, this.parseGeoKeyDirectory(fileDirectory)
]);
nextIFDByteOffset = this.dataView.getUint32(i, this.littleEndian);
}
return fileDirectories;
},
getImage: function(index) {
index = index || 0;
var fileDirectoryAndGeoKey = this.fileDirectories[index];
if (!fileDirectoryAndGeoKey) {
throw new RangeError("Invalid image index");
}
return new GeoTIFFImage(fileDirectoryAndGeoKey[0], fileDirectoryAndGeoKey[1], this.dataView, this.littleEndian);
},
getImageCount: function() {
return this.fileDirectories.length;
}
};
module.exports = GeoTIFF;