typed-array.ts 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. /**
  2. * Copyright (c) 2018-2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
  3. *
  4. * Taken/adapted from DensityServer (https://github.com/dsehnal/DensityServer)
  5. *
  6. * @author David Sehnal <david.sehnal@gmail.com>
  7. * @author Alexander Rose <alexander.rose@weirdbyte.de>
  8. */
  9. import { FileHandle } from 'mol-io/common/file-handle';
  10. import { SimpleBuffer } from 'mol-io/common/simple-buffer';
  11. export type TypedArrayValueType = 'float32' | 'int8' | 'int16'
  12. export namespace TypedArrayValueType {
  13. export const Float32: TypedArrayValueType = 'float32';
  14. export const Int8: TypedArrayValueType = 'int8';
  15. export const Int16: TypedArrayValueType = 'int16';
  16. }
  17. export type TypedArrayValueArray = Float32Array | Int8Array | Int16Array
  18. export interface TypedArrayBufferContext {
  19. type: TypedArrayValueType,
  20. elementByteSize: number,
  21. readBuffer: SimpleBuffer,
  22. valuesBuffer: Uint8Array,
  23. values: TypedArrayValueArray
  24. }
  25. export function getElementByteSize(type: TypedArrayValueType) {
  26. if (type === TypedArrayValueType.Float32) return 4;
  27. if (type === TypedArrayValueType.Int16) return 2;
  28. return 1;
  29. }
  30. export function makeTypedArray(type: TypedArrayValueType, buffer: ArrayBuffer, byteOffset = 0, length?: number): TypedArrayValueArray {
  31. if (type === TypedArrayValueType.Float32) return new Float32Array(buffer, byteOffset, length);
  32. if (type === TypedArrayValueType.Int16) return new Int16Array(buffer, byteOffset, length);
  33. return new Int8Array(buffer, byteOffset, length);
  34. }
  35. export function createTypedArray(type: TypedArrayValueType, size: number) {
  36. switch (type) {
  37. case TypedArrayValueType.Float32: return new Float32Array(new ArrayBuffer(4 * size));
  38. case TypedArrayValueType.Int8: return new Int8Array(new ArrayBuffer(1 * size));
  39. case TypedArrayValueType.Int16: return new Int16Array(new ArrayBuffer(2 * size));
  40. }
  41. throw Error(`${type} is not a supported value format.`);
  42. }
  43. export function createTypedArrayBufferContext(size: number, type: TypedArrayValueType): TypedArrayBufferContext {
  44. let elementByteSize = getElementByteSize(type);
  45. let arrayBuffer = new ArrayBuffer(elementByteSize * size);
  46. let readBuffer = SimpleBuffer.fromArrayBuffer(arrayBuffer);
  47. let valuesBuffer = SimpleBuffer.IsNativeEndianLittle ? arrayBuffer : new ArrayBuffer(elementByteSize * size);
  48. return {
  49. type,
  50. elementByteSize,
  51. readBuffer,
  52. valuesBuffer: new Uint8Array(valuesBuffer),
  53. values: makeTypedArray(type, valuesBuffer)
  54. };
  55. }
  56. export async function readTypedArray(ctx: TypedArrayBufferContext, file: FileHandle, position: number, byteCount: number, valueByteOffset: number, littleEndian?: boolean) {
  57. await file.readBuffer(position, ctx.readBuffer, byteCount, valueByteOffset);
  58. if (ctx.elementByteSize > 1 && ((littleEndian !== void 0 && littleEndian !== SimpleBuffer.IsNativeEndianLittle) || !SimpleBuffer.IsNativeEndianLittle)) {
  59. // fix the endian
  60. SimpleBuffer.flipByteOrder(ctx.readBuffer, ctx.valuesBuffer, byteCount, ctx.elementByteSize, valueByteOffset);
  61. }
  62. return ctx.values;
  63. }