dataview64.js 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. import { getFloat16 } from '@petamoriken/float16';
  2. export default class DataView64 {
  3. constructor(arrayBuffer) {
  4. this._dataView = new DataView(arrayBuffer);
  5. }
  6. get buffer() {
  7. return this._dataView.buffer;
  8. }
  9. getUint64(offset, littleEndian) {
  10. const left = this.getUint32(offset, littleEndian);
  11. const right = this.getUint32(offset + 4, littleEndian);
  12. let combined;
  13. if (littleEndian) {
  14. combined = left + ((2 ** 32) * right);
  15. if (!Number.isSafeInteger(combined)) {
  16. throw new Error(
  17. `${combined} exceeds MAX_SAFE_INTEGER. `
  18. + 'Precision may be lost. Please report if you get this message to https://github.com/geotiffjs/geotiff.js/issues',
  19. );
  20. }
  21. return combined;
  22. }
  23. combined = ((2 ** 32) * left) + right;
  24. if (!Number.isSafeInteger(combined)) {
  25. throw new Error(
  26. `${combined} exceeds MAX_SAFE_INTEGER. `
  27. + 'Precision may be lost. Please report if you get this message to https://github.com/geotiffjs/geotiff.js/issues',
  28. );
  29. }
  30. return combined;
  31. }
  32. // adapted from https://stackoverflow.com/a/55338384/8060591
  33. getInt64(offset, littleEndian) {
  34. let value = 0;
  35. const isNegative = (this._dataView.getUint8(offset + (littleEndian ? 7 : 0)) & 0x80) > 0;
  36. let carrying = true;
  37. for (let i = 0; i < 8; i++) {
  38. let byte = this._dataView.getUint8(offset + (littleEndian ? i : 7 - i));
  39. if (isNegative) {
  40. if (carrying) {
  41. if (byte !== 0x00) {
  42. byte = ~(byte - 1) & 0xff;
  43. carrying = false;
  44. }
  45. } else {
  46. byte = ~byte & 0xff;
  47. }
  48. }
  49. value += byte * (256 ** i);
  50. }
  51. if (isNegative) {
  52. value = -value;
  53. }
  54. return value;
  55. }
  56. getUint8(offset, littleEndian) {
  57. return this._dataView.getUint8(offset, littleEndian);
  58. }
  59. getInt8(offset, littleEndian) {
  60. return this._dataView.getInt8(offset, littleEndian);
  61. }
  62. getUint16(offset, littleEndian) {
  63. return this._dataView.getUint16(offset, littleEndian);
  64. }
  65. getInt16(offset, littleEndian) {
  66. return this._dataView.getInt16(offset, littleEndian);
  67. }
  68. getUint32(offset, littleEndian) {
  69. return this._dataView.getUint32(offset, littleEndian);
  70. }
  71. getInt32(offset, littleEndian) {
  72. return this._dataView.getInt32(offset, littleEndian);
  73. }
  74. getFloat16(offset, littleEndian) {
  75. return getFloat16(this._dataView, offset, littleEndian);
  76. }
  77. getFloat32(offset, littleEndian) {
  78. return this._dataView.getFloat32(offset, littleEndian);
  79. }
  80. getFloat64(offset, littleEndian) {
  81. return this._dataView.getFloat64(offset, littleEndian);
  82. }
  83. }