From 08076f085418750559eedba2e6ede046b66b836d Mon Sep 17 00:00:00 2001 From: Christopher Cameron Date: Mon, 17 Mar 2025 13:59:00 +0000 Subject: [PATCH 1/2] Add ImageData Float16Array support Add the ImageDataPixelFormat enum type, which can take on values of "rgba-unorm8" (the current default of 8-bit unsigned normalized RGBA) and "rgba-float16" (the new option for 16-bit floating point RGBA). Add ImageDataPixelFormat to the ImageDataSettings dictionary used by ImageData constructors, to allow creation of ImageData objects that are backed by Float16Array. Add ImageDataPixelFormat as an attribute to ImageData. Add a new ImageDataArray type which is the union of Uint8ClampedArray and Float16Array. Change the ImageData data attribute to be this union type instead of Uint8ClampedArray. Fix the Canvas Pixel ArrayBuffer section to correctly describe the pixel layout of an ImageBuffer (there was a bug in the spec specifying that an ImageData's pixel data starts at the beginning of its data attributes's backing ArrayBuffer, when what was intended was for it to start at the beginning of its data attribute). Fixes #10856 --- source | 136 ++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 101 insertions(+), 35 deletions(-) diff --git a/source b/source index 904af003371..204d43a33b2 100644 --- a/source +++ b/source @@ -2907,6 +2907,7 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute
  • DOMString
  • double
  • enumeration
  • +
  • Float16Array
  • Function
  • long
  • object
  • @@ -66035,19 +66036,25 @@ interface TextMetrics { readonly attribute double ideographicBaseline; }; +typedef (Uint8ClampedArray or Float16Array) ImageDataArray; + +enum ImageDataPixelFormat { "rgba-unorm8", "rgba-float16" }; + dictionary ImageDataSettings { PredefinedColorSpace colorSpace; + ImageDataPixelFormat pixelFormat = "rgba-unorm8"; }; [Exposed=(Window,Worker), Serializable] interface ImageData { constructor(unsigned long sw, unsigned long sh, optional ImageDataSettings settings = {}); - constructor(Uint8ClampedArray data, unsigned long sw, optional unsigned long sh, optional ImageDataSettings settings = {}); + constructor(ImageDataArray data, unsigned long sw, optional unsigned long sh, optional ImageDataSettings settings = {}); readonly attribute unsigned long width; readonly attribute unsigned long height; - readonly attribute Uint8ClampedArray data; + readonly attribute ImageDataArray data; + readonly attribute ImageDataPixelFormat pixelFormat; readonly attribute PredefinedColorSpace colorSpace; }; @@ -70400,9 +70407,8 @@ try {
    imageData = new ImageData(data, sw [, sh [, settings ] ])
    -

    Returns an ImageData object using the data provided in the Uint8ClampedArray argument, interpreted using the given - dimensions and the color space indicated by settings.

    +

    Returns an ImageData object using the data provided in the ImageDataArray + argument, interpreted using the given dimensions and the color space indicated by settings.

    As each pixel in the data is represented by four numbers, the length of the data needs to be a multiple of four times the given width. If the height is provided as well, then the length @@ -70491,7 +70497,7 @@ try { constructor steps are:

      -
    1. Let length be the number of bytes in data.

    2. +
    3. Let length be the length of data.

    4. If length is not a nonzero integral multiple of four, then throw an "InvalidStateError" DOMException.

    5. @@ -70519,8 +70525,7 @@ try { source set to data.

      This step does not set this's data to a copy of data. - It sets it to the actual Uint8ClampedArray object - passed as data.

      + It sets it to the actual ImageData object passed as data.

    @@ -70609,30 +70614,61 @@ try {

    To initialize an ImageData object imageData, given a positive integer number of rows rows, a positive integer number of pixels per row pixelsPerRow, an optional ImageDataSettings settings, an optional Uint8ClampedArray source, and an optional - PredefinedColorSpace settings, an optional + ImageDataArray source, + and an optional PredefinedColorSpace defaultColorSpace:

      -
    1. If source was given, then initialize the data attribute of imageData to - source.

    2. +
    3. If source was given then:

      +
        +
      1. If settings was given and + settings["pixelFormat"] + equals "rgba-unorm8" and + source is not of type Uint8ClampedArray + then throw an "InvalidStateError" DOMException.

      2. -
      3. -

        Otherwise (source was not given), initialize the data attribute of imageData to a new Uint8ClampedArray object. The Uint8ClampedArray object must use a new Canvas - Pixel ArrayBuffer for its storage, and must have a - zero start offset and a length equal to the length of its storage, in bytes. The Canvas - Pixel ArrayBuffer must have the correct size to - store rows × pixelsPerRow pixels.

        +
      4. If settings was given and + settings["pixelFormat"] + equals "rgba-float16" and + source is not of type Float16Array + then throw an "InvalidStateError" DOMException.

      5. -

        If the Canvas Pixel ArrayBuffer cannot be - allocated, then rethrow the RangeError thrown by JavaScript, - and return.

        +
      6. Initialize the data attribute of imageData to + source.

      7. +
      +
    4. + +
    5. Otherwise (source was not given):

      +
        +
      1. If settings was given and + settings["pixelFormat"] + equals "rgba-unorm8", or if + settings was not given, then + initialize the data attribute of imageData to a new + Uint8ClampedArray object. + The Uint8ClampedArray object + must have a length of 4 × rows × pixelsPerRow elements, + must use a new ArrayBuffer for its storage, + must have a byte offset of zero bytes, + and must have a byte length of 4 × rows × pixelsPerRow bytes. + If the ArrayBuffer could not be allocated, then rethrow the + RangeError thrown by JavaScript, and return.

      2. + +
      3. If settings was given and + settings["pixelFormat"] + equals "rgba-float16", then + initialize the data attribute of imageData to a new + Float16Array object. + The Float16Array object + must have a length of 4 × rows × pixelsPerRow elements, + must use a new ArrayBuffer for its storage, + must have a byte offset of zero bytes, + and must have a byte length of 8 × rows × pixelsPerRow bytes. + If the ArrayBuffer could not be allocated, then rethrow the + RangeError thrown by JavaScript, and return.

      4. +
    6. Initialize the height attribute of imageData to rows.

    7. +
    8. If settings was given, then initialize the + pixelFormat + attribute of imageData to + settings["pixelFormat"].

    9. + +
    10. Otherwise, initialize the pixelFormat + attribute of imageData to + "rgba-unorm8".

    11. +
    12. If settings was given and settings["colorSpace"] exists, then initialize the serialized.[[ColorSpace]].

    -

    A Canvas Pixel ArrayBuffer is an ArrayBuffer whose data is represented in left-to-right order, row - by row top to bottom, starting with the top left, with each pixel's red, green, blue, and alpha - components being given in that order for each pixel. Each component of each pixel represented in - this array must be in the range 0..255, representing the 8 bit value for that component. The - components must be assigned consecutive indices starting with 0 for the top left pixel's red - component.

    +

    The ImageDataPixelFormat enumeration is used to specify type of the + data attribute of an ImageData + and the arrangement and numerical representation of the color channel values for each pixel.

    + +

    The "rgba-unorm8" value indicates that the + data attribute of an ImageData must be of type + Uint8ClampedArray. + The color components of each pixel must be stored in four sequential elements in the order of red, green, blue, and then alpha. + Each element represents the 8-bit unsigned normalized value for that component.

    + +

    The "rgba-float16" value indicates that the + data attribute of an ImageData must be of type + Float16Array. + The color components of each pixel must be stored in four sequential elements in the order of red, green, blue, and then alpha. + Each element represents the value for that component.

    + +

    An ImageData object represents a rectanglar bitmap + with width equal to the width attribute + and height equal to the height attribute. + The pixel values of this bitmap are stored in the data attribute + in left-to-right order, row by row from top to bottom, starting with 0 for the top left pixel, + with the order and numerical representation of the color components of each + pixel determined by the pixelFormat attribute. + The color space of the pixel values of the bitmap is determined by the + colorSpace attribute.

    The putImageData(imageData, @@ -70777,7 +70843,7 @@ try { set the pixel with coordinate (dx+x, dy+y) in bitmap to the color of the pixel at coordinate (x, y) in the imageData data structure's - Canvas Pixel ArrayBuffer, + bitmap, converted from imageData's colorSpace to the color space of bitmap using 'relative-colorimetric' rendering intent.

    From cb43615809e505c9dc2140ae7151aca2b26df0a1 Mon Sep 17 00:00:00 2001 From: Christopher Cameron Date: Fri, 21 Mar 2025 08:22:41 +0000 Subject: [PATCH 2/2] Incorporate feedback from kaiido review --- source | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source b/source index 204d43a33b2..c0df94fa436 100644 --- a/source +++ b/source @@ -70525,7 +70525,7 @@ try { source set to data.

    This step does not set this's data to a copy of data. - It sets it to the actual ImageData object passed as data.

    + It sets it to the actual ImageDataArray object passed as data.

    @@ -70612,8 +70612,8 @@ try {

    To initialize an ImageData object imageData, given a - positive integer number of rows rows, a positive integer number of pixels per row - pixelsPerRow, an optional ImageDataSettings pixelsPerRow, a positive integer number + of rows rows, an optional ImageDataSettings settings, an optional ImageDataArray source, and an optional PredefinedColorSpace The ImageDataPixelFormat enumeration is used to specify type of the data attribute of an ImageData - and the arrangement and numerical representation of the color channel values for each pixel.

    + and the arrangement and numerical representation of the color components for each pixel.

    The "rgba-unorm8" value indicates that the