hdr-canvas 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5902,6 +5902,283 @@ class Uint16Image extends HDRImage {
5902
5902
  }
5903
5903
  }
5904
5904
 
5905
+ /* eslint-disable no-restricted-globals, no-restricted-syntax */
5906
+ /* global SharedArrayBuffer */
5907
+
5908
+
5909
+ /** @type {<T extends (...args: any) => any>(target: T) => (thisArg: ThisType<T>, ...args: any[]) => any} */
5910
+ function uncurryThis(target) {
5911
+ return (thisArg, ...args) => {
5912
+ return ReflectApply(target, thisArg, args);
5913
+ };
5914
+ }
5915
+
5916
+ /** @type {(target: any, key: string | symbol) => (thisArg: any, ...args: any[]) => any} */
5917
+ function uncurryThisGetter(target, key) {
5918
+ return uncurryThis(
5919
+ ReflectGetOwnPropertyDescriptor(
5920
+ target,
5921
+ key
5922
+ ).get
5923
+ );
5924
+ }
5925
+
5926
+ // Reflect
5927
+ const {
5928
+ apply: ReflectApply,
5929
+ getOwnPropertyDescriptor: ReflectGetOwnPropertyDescriptor,
5930
+ getPrototypeOf: ReflectGetPrototypeOf} = Reflect;
5931
+
5932
+ // Number
5933
+ const {
5934
+ EPSILON,
5935
+ isFinite: NumberIsFinite,
5936
+ isNaN: NumberIsNaN,
5937
+ } = Number;
5938
+
5939
+ // Symbol
5940
+ const {
5941
+ iterator: SymbolIterator,
5942
+ toStringTag: SymbolToStringTag} = Symbol;
5943
+
5944
+ // Math
5945
+ const {
5946
+ abs: MathAbs} = Math;
5947
+
5948
+ // ArrayBuffer
5949
+ const NativeArrayBuffer = ArrayBuffer;
5950
+ const ArrayBufferPrototype = NativeArrayBuffer.prototype;
5951
+ /** @type {(buffer: ArrayBuffer) => ArrayBuffer} */
5952
+ uncurryThisGetter(ArrayBufferPrototype, "byteLength");
5953
+
5954
+ // SharedArrayBuffer
5955
+ const NativeSharedArrayBuffer = typeof SharedArrayBuffer !== "undefined" ? SharedArrayBuffer : null;
5956
+ /** @type {(buffer: SharedArrayBuffer) => SharedArrayBuffer} */
5957
+ NativeSharedArrayBuffer
5958
+ && uncurryThisGetter(NativeSharedArrayBuffer.prototype, "byteLength");
5959
+
5960
+ // TypedArray
5961
+ /** @typedef {Uint8Array|Uint8ClampedArray|Uint16Array|Uint32Array|Int8Array|Int16Array|Int32Array|Float32Array|Float64Array|BigUint64Array|BigInt64Array} TypedArray */
5962
+ /** @type {any} */
5963
+ const TypedArray = ReflectGetPrototypeOf(Uint8Array);
5964
+ TypedArray.from;
5965
+ const TypedArrayPrototype = TypedArray.prototype;
5966
+ TypedArrayPrototype[SymbolIterator];
5967
+ /** @type {(typedArray: TypedArray) => IterableIterator<number>} */
5968
+ uncurryThis(TypedArrayPrototype.keys);
5969
+ /** @type {(typedArray: TypedArray) => IterableIterator<number>} */
5970
+ uncurryThis(
5971
+ TypedArrayPrototype.values
5972
+ );
5973
+ /** @type {(typedArray: TypedArray) => IterableIterator<[number, number]>} */
5974
+ uncurryThis(
5975
+ TypedArrayPrototype.entries
5976
+ );
5977
+ /** @type {(typedArray: TypedArray, array: ArrayLike<number>, offset?: number) => void} */
5978
+ uncurryThis(TypedArrayPrototype.set);
5979
+ /** @type {<T extends TypedArray>(typedArray: T) => T} */
5980
+ uncurryThis(
5981
+ TypedArrayPrototype.reverse
5982
+ );
5983
+ /** @type {<T extends TypedArray>(typedArray: T, value: number, start?: number, end?: number) => T} */
5984
+ uncurryThis(TypedArrayPrototype.fill);
5985
+ /** @type {<T extends TypedArray>(typedArray: T, target: number, start: number, end?: number) => T} */
5986
+ uncurryThis(
5987
+ TypedArrayPrototype.copyWithin
5988
+ );
5989
+ /** @type {<T extends TypedArray>(typedArray: T, compareFn?: (a: number, b: number) => number) => T} */
5990
+ uncurryThis(TypedArrayPrototype.sort);
5991
+ /** @type {<T extends TypedArray>(typedArray: T, start?: number, end?: number) => T} */
5992
+ uncurryThis(TypedArrayPrototype.slice);
5993
+ /** @type {<T extends TypedArray>(typedArray: T, start?: number, end?: number) => T} */
5994
+ uncurryThis(
5995
+ TypedArrayPrototype.subarray
5996
+ );
5997
+ /** @type {((typedArray: TypedArray) => ArrayBuffer)} */
5998
+ uncurryThisGetter(
5999
+ TypedArrayPrototype,
6000
+ "buffer"
6001
+ );
6002
+ /** @type {((typedArray: TypedArray) => number)} */
6003
+ uncurryThisGetter(
6004
+ TypedArrayPrototype,
6005
+ "byteOffset"
6006
+ );
6007
+ /** @type {((typedArray: TypedArray) => number)} */
6008
+ uncurryThisGetter(
6009
+ TypedArrayPrototype,
6010
+ "length"
6011
+ );
6012
+ /** @type {(target: unknown) => string} */
6013
+ uncurryThisGetter(
6014
+ TypedArrayPrototype,
6015
+ SymbolToStringTag
6016
+ );
6017
+
6018
+ // Uint8Array
6019
+ const NativeUint8Array = Uint8Array;
6020
+
6021
+ // Uint16Array
6022
+ const NativeUint16Array = Uint16Array;
6023
+
6024
+ // Uint32Array
6025
+ const NativeUint32Array = Uint32Array;
6026
+
6027
+ // ArrayIterator
6028
+ /** @type {any} */
6029
+ const ArrayIteratorPrototype = ReflectGetPrototypeOf([][SymbolIterator]());
6030
+ /** @type {<T>(arrayIterator: IterableIterator<T>) => IteratorResult<T>} */
6031
+ uncurryThis(ArrayIteratorPrototype.next);
6032
+
6033
+ // Generator
6034
+ /** @type {<T = unknown, TReturn = any, TNext = unknown>(generator: Generator<T, TReturn, TNext>, value?: TNext) => T} */
6035
+ uncurryThis((function* () {})().next);
6036
+
6037
+ // Iterator
6038
+ ReflectGetPrototypeOf(ArrayIteratorPrototype);
6039
+
6040
+ const INVERSE_OF_EPSILON = 1 / EPSILON;
6041
+
6042
+ /**
6043
+ * rounds to the nearest value;
6044
+ * if the number falls midway, it is rounded to the nearest value with an even least significant digit
6045
+ * @param {number} num
6046
+ * @returns {number}
6047
+ */
6048
+ function roundTiesToEven(num) {
6049
+ return (num + INVERSE_OF_EPSILON) - INVERSE_OF_EPSILON;
6050
+ }
6051
+
6052
+ const FLOAT16_MIN_VALUE = 6.103515625e-05;
6053
+ const FLOAT16_MAX_VALUE = 65504;
6054
+ const FLOAT16_EPSILON = 0.0009765625;
6055
+
6056
+ const FLOAT16_EPSILON_MULTIPLIED_BY_FLOAT16_MIN_VALUE = FLOAT16_EPSILON * FLOAT16_MIN_VALUE;
6057
+ const FLOAT16_EPSILON_DEVIDED_BY_EPSILON = FLOAT16_EPSILON * INVERSE_OF_EPSILON;
6058
+
6059
+ /**
6060
+ * round a number to a half float number
6061
+ * @param {unknown} num - double float
6062
+ * @returns {number} half float number
6063
+ */
6064
+ function roundToFloat16(num) {
6065
+ const number = +num;
6066
+
6067
+ // NaN, Infinity, -Infinity, 0, -0
6068
+ if (!NumberIsFinite(number) || number === 0) {
6069
+ return number;
6070
+ }
6071
+
6072
+ // finite except 0, -0
6073
+ const sign = number > 0 ? 1 : -1;
6074
+ const absolute = MathAbs(number);
6075
+
6076
+ // small number
6077
+ if (absolute < FLOAT16_MIN_VALUE) {
6078
+ return sign * roundTiesToEven(absolute / FLOAT16_EPSILON_MULTIPLIED_BY_FLOAT16_MIN_VALUE) * FLOAT16_EPSILON_MULTIPLIED_BY_FLOAT16_MIN_VALUE;
6079
+ }
6080
+
6081
+ const temp = (1 + FLOAT16_EPSILON_DEVIDED_BY_EPSILON) * absolute;
6082
+ const result = temp - (temp - absolute);
6083
+
6084
+ // large number
6085
+ if (result > FLOAT16_MAX_VALUE || NumberIsNaN(result)) {
6086
+ return sign * Infinity;
6087
+ }
6088
+
6089
+ return sign * result;
6090
+ }
6091
+
6092
+ const baseTable = new NativeUint16Array(512);
6093
+ const shiftTable = new NativeUint8Array(512);
6094
+
6095
+ for (let i = 0; i < 256; ++i) {
6096
+ const e = i - 127;
6097
+
6098
+ // very small number (0, -0)
6099
+ if (e < -24) {
6100
+ baseTable[i] = 0x0000;
6101
+ baseTable[i | 0x100] = 0x8000;
6102
+ shiftTable[i] = 24;
6103
+ shiftTable[i | 0x100] = 24;
6104
+
6105
+ // small number (denorm)
6106
+ } else if (e < -14) {
6107
+ baseTable[i] = 0x0400 >> (-e - 14);
6108
+ baseTable[i | 0x100] = (0x0400 >> (-e - 14)) | 0x8000;
6109
+ shiftTable[i] = -e - 1;
6110
+ shiftTable[i | 0x100] = -e - 1;
6111
+
6112
+ // normal number
6113
+ } else if (e <= 15) {
6114
+ baseTable[i] = (e + 15) << 10;
6115
+ baseTable[i | 0x100] = ((e + 15) << 10) | 0x8000;
6116
+ shiftTable[i] = 13;
6117
+ shiftTable[i | 0x100] = 13;
6118
+
6119
+ // large number (Infinity, -Infinity)
6120
+ } else if (e < 128) {
6121
+ baseTable[i] = 0x7c00;
6122
+ baseTable[i | 0x100] = 0xfc00;
6123
+ shiftTable[i] = 24;
6124
+ shiftTable[i | 0x100] = 24;
6125
+
6126
+ // stay (NaN, Infinity, -Infinity)
6127
+ } else {
6128
+ baseTable[i] = 0x7c00;
6129
+ baseTable[i | 0x100] = 0xfc00;
6130
+ shiftTable[i] = 13;
6131
+ shiftTable[i | 0x100] = 13;
6132
+ }
6133
+ }
6134
+
6135
+ const mantissaTable = new NativeUint32Array(2048);
6136
+ for (let i = 1; i < 1024; ++i) {
6137
+ let m = i << 13; // zero pad mantissa bits
6138
+ let e = 0; // zero exponent
6139
+
6140
+ // normalized
6141
+ while ((m & 0x00800000) === 0) {
6142
+ m <<= 1;
6143
+ e -= 0x00800000; // decrement exponent
6144
+ }
6145
+
6146
+ m &= -8388609; // clear leading 1 bit
6147
+ e += 0x38800000; // adjust bias
6148
+
6149
+ mantissaTable[i] = m | e;
6150
+ }
6151
+ for (let i = 1024; i < 2048; ++i) {
6152
+ mantissaTable[i] = 0x38000000 + ((i - 1024) << 13);
6153
+ }
6154
+
6155
+ const exponentTable = new NativeUint32Array(64);
6156
+ for (let i = 1; i < 31; ++i) {
6157
+ exponentTable[i] = i << 23;
6158
+ }
6159
+ exponentTable[31] = 0x47800000;
6160
+ exponentTable[32] = 0x80000000;
6161
+ for (let i = 33; i < 63; ++i) {
6162
+ exponentTable[i] = 0x80000000 + ((i - 32) << 23);
6163
+ }
6164
+ exponentTable[63] = 0xc7800000;
6165
+
6166
+ const offsetTable = new NativeUint16Array(64);
6167
+ for (let i = 1; i < 64; ++i) {
6168
+ if (i !== 32) {
6169
+ offsetTable[i] = 1024;
6170
+ }
6171
+ }
6172
+
6173
+ /**
6174
+ * returns the nearest half-precision float representation of a number
6175
+ * @param {number} x
6176
+ * @returns {number}
6177
+ */
6178
+ function f16round(x) {
6179
+ return roundToFloat16(x);
6180
+ }
6181
+
5905
6182
  class Float16Image extends HDRImage {
5906
6183
  data;
5907
6184
  static DEFAULT_PIXELFORMAT = "rgba-float16";
@@ -5958,17 +6235,17 @@ class Float16Image extends HDRImage {
5958
6235
  return Float16Array.from(hlg);
5959
6236
  }
5960
6237
  static convertArrayToRec2100_hlg(data) {
5961
- const uint16Data = new Float16Array(data.length);
5962
- for (let i = 0; i < data.length; i += 4) {
5963
- const rgbPixel = data.slice(i, i + 4);
5964
- const pixel = Float16Image.convertPixelToRec2100_hlg(rgbPixel);
5965
- uint16Data.set(pixel, i);
6238
+ const float16Array = new Float16Array(data.length);
6239
+ for (let i = 0; i < data.length; i++) {
6240
+ const normalizedFloat = data[i] / 255.0;
6241
+ float16Array[i] = f16round(normalizedFloat);
5966
6242
  }
5967
- return uint16Data;
6243
+ return float16Array;
5968
6244
  }
5969
6245
  pixelCallback(fn) {
5970
6246
  for (let i = 0; i < this.data.length; i += 4) {
5971
- this.data.set(fn(this.data[i], this.data[i + 1], this.data[i + 2], this.data[i + 3]), i);
6247
+ const pixel = fn(this.data[i], this.data[i + 1], this.data[i + 2], this.data[i + 3]);
6248
+ this.data.set(pixel, i);
5972
6249
  }
5973
6250
  }
5974
6251
  static fromImageData(imageData) {
@@ -6034,6 +6311,7 @@ function getHdrOptions() {
6034
6311
  if (browserMajorVersion == null) {
6035
6312
  console.warn(`Unsupported / untested browser (${navigator.userAgent}) detected - using more modern defaults`);
6036
6313
  hdrOptions["colorType"] = "float16";
6314
+ hdrOptions["toneMapping"] = { mode: "extended" };
6037
6315
  }
6038
6316
  else {
6039
6317
  if (browserMajorVersion < 134) {
@@ -6046,7 +6324,10 @@ function getHdrOptions() {
6046
6324
  return hdrOptions;
6047
6325
  }
6048
6326
  function initHDRCanvas(canvas) {
6049
- canvas.configureHighDynamicRange({ mode: "extended" });
6327
+ const browserMajorVersion = getBrowserVersion();
6328
+ if (browserMajorVersion !== null && browserMajorVersion < 134) {
6329
+ canvas.configureHighDynamicRange({ mode: "extended" });
6330
+ }
6050
6331
  const ctx = canvas.getContext("2d", getHdrOptions());
6051
6332
  return ctx;
6052
6333
  }