iso21496-1-jpg.html (4408B)
1 <!DOCTYPE HTML> 2 <script src="/resources/testharness.js"></script> 3 <script src="/resources/testharnessreport.js"></script> 4 <script> 5 // Render serveral equivalent ISO 21496-1 gainmap images with various values for 6 // globalHdrHeadroom. 7 // The test images used by this test have an SDR representation (at headroom 0) 8 // with pixel values in sRGB of: 9 // #C08040, #8040C0, #40C080, #FFFFFF 10 // They have an HDR representation (at headroom 1) with pixel values in sRGB of 11 // #40C080, #C08040, #8040C0 color(srgb 0x17F/0xFF, 0x17F/0xFF, 0x17F/0xFF) 12 // The test images vary in: 13 // * Some have SDR as the base image (encoded as sRGB) and some have HDR as the 14 // base image (encoded as Rec2100 PQ or Rec2100 HLG). 15 // * Some use sRGB as the gain application primaries, others use Rec2020 16 // The tests that use a Rec2100 PQ or HLG base are allowed a higher amount of 17 // error because of the brutal quantization error in those spaces. 18 const tests = [ 19 { 20 filename:'iso21496-1-base_srgb-altr_none-use_base.jpg', 21 desc:'base sRGB, use base primaries', 22 workingSpace:'srgb', 23 epsilon:0x4/255 24 }, 25 { 26 filename:'iso21496-1-base_srgb-altr_rec2020-use_altr.jpg', 27 desc:'base sRGB, alternate Rec2020, use alternate primaries', 28 workingSpace:'rec2020', 29 epsilon:0x4/255 30 }, 31 { 32 filename:'iso21496-1-base_rec2100pq-altr_none-use_base.jpg', 33 desc:'base Rec2100 PQ, use base primaries', 34 workingSpace:'rec2020', 35 epsilon:0xC/255 36 }, 37 { 38 filename:'iso21496-1-base_rec2100pq-altr_none-use_altr.jpg', 39 desc:'base Rec2100 PQ, alternate has no profile, use alternate primaries', 40 workingSpace:'rec2020', 41 epsilon:0xC/255 42 }, 43 { 44 filename:'iso21496-1-base_rec2100hlg-altr_none-use_base.jpg', 45 desc:'base Rec2100 HLG, use base primaries', 46 workingSpace:'rec2020', 47 epsilon:0x8/255 48 }, 49 ]; 50 for (const test of tests) { 51 promise_test(async () => { 52 filename = test.filename; 53 const canvas = new OffscreenCanvas(64, 64); 54 const ctx = canvas.getContext('2d', {colorType:'float16'}); 55 if (ctx.globalHDRHeadroom === undefined) { 56 return; 57 } 58 59 // All test images evaluate to these sRGB values at headroom 0 60 const sdrExpected = [ 61 [ 0xC0/0xFF, 0x80/0xFF, 0x40/0xFF], 62 [ 0x80/0xFF, 0x40/0xFF, 0xC0/0xFF], 63 [ 0x40/0xFF, 0xC0/0xFF, 0x80/0xFF], 64 [ 0xFF/0xFF, 0xFF/0xFF, 0xFF/0xFF]]; 65 66 // All test images evaluate to these sRGB values at headroom 1 67 const hdrExpected = [ 68 [ 0x40/0xFF, 0xC0/0xFF, 0x80/0xFF], 69 [ 0xC0/0xFF, 0x80/0xFF, 0x40/0xFF], 70 [ 0x80/0xFF, 0x40/0xFF, 0xC0/0xFF], 71 [0x17F/0xFF, 0x17F/0xFF, 0x17F/0xFF]]; 72 73 const globalHDRHeadroomValues = [ 74 0, 1, Infinity, 0.75, 75 ] 76 const expectedPixelValues = [ 77 sdrExpected, hdrExpected, hdrExpected, null, 78 ]; 79 80 // The interpolated values at HDR headroom 0.75 depend on the gain 81 // application color space primaries. 82 if (test.workingSpace === 'srgb') { 83 expectedPixelValues[3] = [ 84 [ 0.335045, 0.681192, 0.424504, ], 85 [ 0.681192, 0.424504, 0.335045, ], 86 [ 0.424504, 0.335045, 0.681192, ], 87 [ 1.357607, 1.357607, 1.357607, ],]; 88 } 89 if (test.workingSpace === 'rec2020') { 90 expectedPixelValues[3] = [ 91 [ 0.443076, 0.687104, 0.429474, ], 92 [ 0.690319, 0.428588, 0.362702, ], 93 [ 0.496921, 0.349176, 0.692474, ], 94 [ 1.357607, 1.357607, 1.357607, ],]; 95 } 96 97 // Draw the image at the specified headrooms. 98 const image = new Image; 99 image.src = 'resources/' + filename; 100 await new Promise(resolve => image.onload = resolve); 101 for (let x = 0; x < 4; ++x) { 102 ctx.globalHDRHeadroom = globalHDRHeadroomValues[x]; 103 ctx.drawImage(image, 16*x, 0); 104 } 105 106 // Read back a pixel in each solid color region. 107 for (let x = 0; x < 4; ++x) { 108 for (let y = 0; y < 4; ++y) { 109 const name = 'globalHDRHeadroom: ' + globalHDRHeadroomValues[x] + ', ' + 110 'y:' + y; 111 const data = ctx.getImageData( 112 8 + 16*x, 8 + 16*y, 1, 1, 113 {colorSpace:'srgb', pixelFormat:'rgba-float16'}); 114 const actual = data.data; 115 const expected = expectedPixelValues[x][y]; 116 for (let c = 0; c < 3; ++c) { 117 assert_approx_equals( 118 actual[c], expected[c], test.epsilon, name); 119 } 120 } 121 } 122 }, test.desc); 123 } 124 </script>