| OLD | NEW | 
|---|
| 1 function log(message) { | 1 window.ignoreCyan = false; | 
| 2   document.getElementById('log').textContent += message + '\n'; |  | 
| 3 } |  | 
| 4 | 2 | 
| 5 function testImageColors(source) { | 3 function testImageColors(source, cyanInTargetGamut) { | 
|  | 4   window.ignoreCyan = !cyanInTargetGamut; | 
|  | 5 | 
| 6   var image = document.querySelector('img'); | 6   var image = document.querySelector('img'); | 
| 7 |  | 
| 8   image.onload = function() { | 7   image.onload = function() { | 
| 9     runAfterLayoutAndPaint(window.testRunner ? changeColorProfile : profileChang
     ed); | 8     runAfterLayoutAndPaint(window.testRunner ? changeColorProfile : profileChang
     ed); | 
| 10   }; | 9   }; | 
| 11 | 10 | 
| 12   image.src = source; | 11   image.src = source; | 
| 13 } | 12 } | 
| 14 | 13 | 
| 15 function changeColorProfile() { | 14 function changeColorProfile() { | 
| 16   /* The test image contains the Munsell colors in a known color space. Convert | 15   /* The test image contains the Munsell colors in a known color space. Convert | 
| 17    * the colors to sRGB color space and test the transformed color accuracy. | 16    * the colors to sRGB color space and test the transformed color accuracy. | 
| 18    */ | 17    */ | 
| 19   window.testRunner.setColorProfile('sRGB', profileChanged); | 18   window.testRunner.setColorProfile('sRGB', profileChanged); | 
| 20 } | 19 } | 
| 21 | 20 | 
| 22 function profileChanged() { | 21 function profileChanged() { | 
| 23   setTimeout(drawImageToCanvas, 0); | 22   setTimeout(drawImageToCanvas, 0); | 
| 24 } | 23 } | 
| 25 | 24 | 
| 26 function drawImageToCanvas() { | 25 function drawImageToCanvas() { | 
| 27   var image = document.querySelector('img'); | 26   var image = document.querySelector('img'); | 
| 28 | 27 | 
| 29   var canvas = document.querySelector('canvas'); | 28   var canvas = document.querySelector('canvas'); | 
| 30   canvas.width = image.width; | 29   canvas.width = image.width; | 
| 31   canvas.height = image.height; | 30   canvas.height = image.height; | 
| 32 | 31 | 
| 33   canvas.getContext('2d').drawImage(image, 0, 0, canvas.width, canvas.height); | 32   canvas.getContext('2d').drawImage(image, 0, 0, canvas.width, canvas.height); | 
| 34   chartColorTransform(canvas); | 33   chartColorTransform(canvas); | 
| 35 } | 34 } | 
| 36 | 35 | 
|  | 36 function log(message) { | 
|  | 37   document.getElementById('log').textContent += message + '\n'; | 
|  | 38 } | 
|  | 39 | 
| 37 function getCanvasColor(canvas, i) { | 40 function getCanvasColor(canvas, i) { | 
| 38   var x = 40 + (i % 6) * (canvas.width / 6); | 41   var x = 40 + (i % 6) * (canvas.width / 6); | 
| 39   var y = 40 + Math.floor(i / 6) * (canvas.height / 4); | 42   var y = 40 + Math.floor(i / 6) * (canvas.height / 4 - 40); | 
| 40   try { | 43   try { | 
| 41     var data = canvas.getContext('2d').getImageData(x, y, 1, 1).data; | 44     var data = canvas.getContext('2d').getImageData(x, y, 1, 1).data; | 
| 42     if (data[3] == 255) | 45     if (data[3] == 255) | 
| 43       return { rgb: [data[0], data[1], data[2]] }; | 46       return { rgb: [data[0], data[1], data[2]] }; | 
| 44     return { rgb: [0, 0, 0] }; | 47     return { rgb: [0, 0, 0] }; | 
| 45   } catch (error) { | 48   } catch (error) { | 
| 46     console.error(error); | 49     console.error(error); | 
| 47     return { rgb: [255, 255, 255] }; | 50     return { rgb: [255, 255, 255] }; | 
| 48   } | 51   } | 
| 49 } | 52 } | 
| (...skipping 26 matching lines...) Expand all  Loading... | 
| 76       { color: 'Neutral 3.5',   rgb: [  83,  83,  83 ] }, | 79       { color: 'Neutral 3.5',   rgb: [  83,  83,  83 ] }, | 
| 77       { color: 'Black',         rgb: [  50,  49,  50 ] } | 80       { color: 'Black',         rgb: [  50,  49,  50 ] } | 
| 78     ); | 81     ); | 
| 79   } | 82   } | 
| 80 | 83 | 
| 81   if (i < 0 && i >= munsell_srgb_colors.length) | 84   if (i < 0 && i >= munsell_srgb_colors.length) | 
| 82     return { color: 'invalid-color', rgb: [ 0, 0, 0 ] }; | 85     return { color: 'invalid-color', rgb: [ 0, 0, 0 ] }; | 
| 83   return munsell_srgb_colors[i]; | 86   return munsell_srgb_colors[i]; | 
| 84 } | 87 } | 
| 85 | 88 | 
|  | 89 function getStudioColor(i) { | 
|  | 90   if (!window.studio_srgb_colors) { | 
|  | 91     // Studio video range white & black and proportions thereof, in sRGB space. | 
|  | 92     window.studio_srgb_colors = new Array( | 
|  | 93       { color: 'SG White',      rgb: [ 237, 237, 237 ] }, | 
|  | 94       { color: 'SG White 1/2',  rgb: [ 130, 130, 130 ] }, | 
|  | 95       { color: 'SG White 1/4',  rgb: [  74,  74,  74 ] }, | 
|  | 96       { color: 'SG Black 4x',   rgb: [  79,  79,  79 ] }, | 
|  | 97       { color: 'SG Black 2x',   rgb: [  48,  48,  48 ] }, | 
|  | 98       { color: 'SG Black',      rgb: [  31,  31,  31 ] } | 
|  | 99     ); | 
|  | 100   } | 
|  | 101 | 
|  | 102   if (i < 0 && i >= studio_srgb_colors.length) | 
|  | 103     return { color: 'invalid-color', rgb: [ 0, 0, 0 ] }; | 
|  | 104   return studio_srgb_colors[i]; | 
|  | 105 } | 
|  | 106 | 
| 86 function getColorError(cx, cy) { | 107 function getColorError(cx, cy) { | 
| 87   var dr = (cx[0] - cy[0]); | 108   var dr = (cx[0] - cy[0]); | 
| 88   var dg = (cx[1] - cy[1]); | 109   var dg = (cx[1] - cy[1]); | 
| 89   var db = (cx[2] - cy[2]); | 110   var db = (cx[2] - cy[2]); | 
| 90   return Math.round(Math.sqrt((dr * dr) + (dg * dg) + (db * db))); | 111   return Math.round(Math.sqrt((dr * dr) + (dg * dg) + (db * db))); | 
| 91 } | 112 } | 
| 92 | 113 | 
| 93 function pad(string, size) { | 114 function pad(string, size) { | 
| 94   size = size || 14; | 115   size = size || 14; | 
| 95   if (string.length < size) | 116   if (string.length < size) | 
| 96     string += ' '.repeat(size - string.length); | 117     string += ' '.repeat(size - string.length); | 
| 97   return string; | 118   return string; | 
| 98 } | 119 } | 
| 99 | 120 | 
| 100 function drawRule(size) { | 121 function drawRule(size) { | 
| 101   log('-'.repeat(size || 44)); | 122   log('-'.repeat(size || 44)); | 
| 102 } | 123 } | 
| 103 | 124 | 
| 104 function chartColorTransform(canvas) { | 125 function chartColorTransform(canvas) { | 
| 105   /* | 126   /* | 
| 106    * Add header over table of color names, acutal and expected values, and the | 127    * Add header over table of color names, actual and expected values, and the | 
| 107    * per color error (Euclidean distance). | 128    * per color error (Euclidean distance). | 
| 108    */ | 129    */ | 
| 109   log(pad('Color') + pad('Actual') + pad('Expected') + 'dE'); | 130   log(pad('Color') + pad('Actual') + pad('Expected') + 'dE'); | 
| 110   drawRule(); | 131   drawRule(); | 
| 111 | 132 | 
| 112   var totalSquaredError = 0.0; | 133   var totalSquaredError = 0.0; | 
| 113 | 134 | 
| 114   /* | 135   /* | 
| 115    * Report per color error dE, by comparing with the expected Munsell colors. | 136    * Report per color error dE, by comparing with the expected Munsell & Studio 
     colors. | 
| 116    */ | 137    */ | 
| 117   for (var i = 0; i < 24;) { | 138   for (var i = 0; i < 30;) { | 
| 118     var expected = getMunsellColor(i); | 139     var expected = (i < 24) ? getMunsellColor(i) : getStudioColor(i - 24); | 
| 119     var actual = getCanvasColor(canvas, i); | 140     var actual = getCanvasColor(canvas, i); | 
| 120     var dE = getColorError(actual.rgb, expected.rgb); | 141     var dE = getColorError(actual.rgb, expected.rgb); | 
| 121 | 142 | 
| 122     log(pad(expected.color) + pad(actual.rgb.join(',')) + pad(expected.rgb.join(
     ',')) + dE); | 143     log(pad(expected.color) + pad(actual.rgb.join(',')) + pad(expected.rgb.join(
     ',')) + dE); | 
| 123     totalSquaredError += dE * dE; |  | 
| 124 | 144 | 
| 125     if (++i % 6 == 0 && i < 24) | 145     if (ignoreCyan && (i + 1) == 18) | 
|  | 146       ; // Do not include the Munsell Cyan (out-of-srgb-gamut) color error. | 
|  | 147     else | 
|  | 148       totalSquaredError += dE * dE; | 
|  | 149 | 
|  | 150     if (++i % 6 == 0 && i <= 24) | 
| 126       drawRule(); | 151       drawRule(); | 
| 127   } | 152   } | 
| 128 | 153 | 
| 129   /* | 154   /* | 
| 130    * Report the total RMS color error neglecting out-of-srgb-gamut color Cyan. | 155    * Report the total RMS color error: lower is better, and should be << 2, whic
     h is the | 
|  | 156    * JND (Just Noticable Difference) perception threshold.  Above a JND, the col
     or error | 
|  | 157    * is noticable to the human eye. | 
| 131    */ | 158    */ | 
| 132   drawRule(); | 159   drawRule(); | 
| 133   log('\nResult: total RMS color error: ' + Math.sqrt(totalSquaredError / 24.0).
     toFixed(2)); | 160   log('\nResult: total RMS color error: ' + Math.sqrt(totalSquaredError / 30.0).
     toFixed(2)); | 
| 134 | 161 | 
| 135   if (window.testRunner) | 162   if (window.testRunner) | 
| 136     window.testRunner.notifyDone(); | 163     window.testRunner.notifyDone(); | 
| 137 } | 164 } | 
| OLD | NEW | 
|---|