<!DOCTYPE html>
<!--
Take frames coming from various sources and read them using copyTo().
-->
<title>copyTo() test</title>
<script src="webcodecs_common.js"></script>
<script type="text/javascript">
  'use strict';

  function yuv_to_rgb601(y, u, v) {
    let b = 1.164 * (y - 16) + 2.018 * (u - 128);
    let g = 1.164 * (y - 16) - 0.813 * (v - 128) - 0.391 * (u - 128);
    let r = 1.164 * (y - 16) + 1.596 * (v - 128);
    return { r: r, g: g, b: b };
  }

  function yuv_to_rgb709(y, u, v) {
    let b = 1.164 * (y - 16) + 2.113 * (u - 128);
    let g = 1.164 * (y - 16) - 0.533 * (v - 128) - 0.213 * (u - 128);
    let r = 1.164 * (y - 16) + 1.793 * (v - 128);
    return { r: r, g: g, b: b };
  }

  function compareArrayBuffers(buffer1, buffer2) {
    const view1 = new DataView(buffer1);
    const view2 = new DataView(buffer2);

    if (view1.byteLength !== view2.byteLength) {
      return false;
    }

    for (let i = 0; i < view1.byteLength; i++) {
      if (view1.getUint8(i) !== view2.getUint8(i)) {
        return false;
      }
    }

    return true;
  }

  async function validateFourColorsBytes(frame) {
    const m = 4;
    const tolerance = 8;
    let expected_xy_color = [
      // Left-top yellow
      { x: m, y: m, r: 255, g: 255, b: 0 },
      // Right-top red
      { x: frame.displayWidth - m, y: m, r: 255, g: 0, b: 0 },
      // Left-bottom blue
      { x: m, y: frame.displayHeight - m, r: 0, g: 0, b: 255 },
      // Right-bottom green
      { x: frame.displayWidth - m, y: frame.displayHeight - m,
        r: 0, g: 255, b: 0 },
    ]

    for (let test of expected_xy_color) {
      const options = {
        rect: { x: test.x, y: test.y, width: 1, height: 1 }
      }
      let size = frame.allocationSize(options);
      let buffer = new ArrayBuffer(size);
      let shared_buffer = new SharedArrayBuffer(size);
      let layout = await frame.copyTo(buffer, options);
      await frame.copyTo(shared_buffer, options);
      TEST.assert(compareArrayBuffers(buffer, shared_buffer),
                  'Readback mismatch between shared and non-shared buffers');
      let view = new DataView(buffer);
      let rgb = null;

      let yuv_to_rgb = yuv_to_rgb601;
      if (frame.colorSpace.matrix == "bt709")
        yuv_to_rgb = yuv_to_rgb709;

      switch (frame.format) {
        case "I420":
        case "I420A":
          rgb = yuv_to_rgb(view.getUint8(layout[0].offset),   // Y
            view.getUint8(layout[1].offset),                  // U
            view.getUint8(layout[2].offset));                 // V
          break;
        case "NV12":
          rgb = yuv_to_rgb(view.getUint8(layout[0].offset),   // Y
            view.getUint8(layout[1].offset),                  // U
            view.getUint8(layout[1].offset + 1));             // V
          break;
        case "RGBX":
        case "RGBA":
          rgb = {
            r: view.getUint8(layout[0].offset),
            g: view.getUint8(layout[0].offset + 1),
            b: view.getUint8(layout[0].offset + 2)
          };
          break;
        case "BGRX":
        case "BGRA":
          rgb = {
            r: view.getUint8(layout[0].offset + 2),
            g: view.getUint8(layout[0].offset + 1),
            b: view.getUint8(layout[0].offset)
          };
          break;
        default:
          TEST.reportFailure("Unexpected frame format: " + frame.format);
          return;
      }

      let message =
          `Test ${frame.format} ${JSON.stringify(test)} ${JSON.stringify(rgb)}`;
      TEST.assert(Math.abs(rgb.r - test.r) < tolerance, message);
      TEST.assert(Math.abs(rgb.g - test.g) < tolerance, message);
      TEST.assert(Math.abs(rgb.b - test.b) < tolerance, message);
    }
  }

  function readWholeBuffer(buffer) {
    let bytes = new Uint8Array(buffer);
    return bytes.reduce((acc, byte) => { return byte ? acc + 1 : acc; }, 0);
  }

  function makeWorker() {
    const worker = new Worker('buffer-read-and-reply-worker.js');
    let resolve_promise = null;
    worker.onmessage = function(e) { resolve_promise(e.data); }
    let worker_promise = new Promise((resolve) => {
      resolve_promise = resolve;
    });
    return { worker , worker_promise };
  }

  async function main(arg) {
    let source_type = arg.source_type;
    TEST.log('Starting test with arguments: ' + JSON.stringify(arg));
    let source = await createFrameSource(source_type, FRAME_WIDTH, FRAME_HEIGHT);
    if (!source) {
      TEST.skip('Unsupported source: ' + source_type);
      return;
    }

    let frame = await source.getNextFrame();
    let size = frame.allocationSize();

    // Readback a whole frame to a regular buffer detach it
    {
      let buf = new ArrayBuffer(size);
      TEST.assert(readWholeBuffer(buf) == 0, "Buffer should be zero");
      let copy_promise = frame.copyTo(buf);
      buf.transfer(1);
      let layout = await copy_promise;
      TEST.assert(layout, "layout is empty / ArrayBuffer");
    }

    // Readback a whole frame to a regular buffer and send it to a worker
    {
      let {worker, worker_promise } = makeWorker();
      let buf = new ArrayBuffer(size);
      TEST.assert(readWholeBuffer(buf) == 0, "Buffer should be zero");
      let copy_promise = frame.copyTo(buf);
      worker.postMessage(buf, [buf]);
      let result_buf = await worker_promise;
      let layout = await copy_promise;
      TEST.assert(readWholeBuffer(result_buf) > 0, "Buffer shouldn't be zero");
      TEST.assert(layout, "layout is empty / ArrayBuffer");
      worker.terminate();
    }

    // Readback a whole frame to a shared buffer and send it to a worker
    {
      let {worker, worker_promise} = makeWorker();
      let buf = new SharedArrayBuffer(size);
      TEST.assert(readWholeBuffer(buf) == 0, "Buffer should be zero");
      let copy_promise = frame.copyTo(buf);
      worker.postMessage(buf);
      await worker_promise;
      let layout = await copy_promise;
      TEST.assert(readWholeBuffer(buf) > 0, "SharedBuffer shouldn't be zero");
      TEST.assert(layout, "layout is empty / SharedArrayBuffer");
      worker.terminate();
    }

    // Validate pixels
    if (!arg.validate_camera_frames && source_type == 'camera') {
      TEST.log("Skip copyTo result validation");
    } else {
      await validateFourColorsBytes(frame);
    }

    frame.close();
    source.close();
    TEST.log('Test completed');
  }
  addManualTestButton([{'source_type': 'offscreen'}]);
  addManualTestButton([{'source_type': 'arraybuffer'}]);
</script>
