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