| Index: third_party/WebKit/LayoutTests/fast/images/resources/color-checker-munsell-chart.js | 
| diff --git a/third_party/WebKit/LayoutTests/fast/images/resources/color-checker-munsell-chart.js b/third_party/WebKit/LayoutTests/fast/images/resources/color-checker-munsell-chart.js | 
| new file mode 100644 | 
| index 0000000000000000000000000000000000000000..2f494b316a5d03ca9371c20f55af00922a007951 | 
| --- /dev/null | 
| +++ b/third_party/WebKit/LayoutTests/fast/images/resources/color-checker-munsell-chart.js | 
| @@ -0,0 +1,137 @@ | 
| +function log(message) { | 
| +  document.getElementById('log').textContent += message + '\n'; | 
| +} | 
| + | 
| +function testImageColors(source) { | 
| +  var image = document.querySelector('img'); | 
| + | 
| +  image.onload = function() { | 
| +    runAfterLayoutAndPaint(window.testRunner ? changeColorProfile : profileChanged); | 
| +  }; | 
| + | 
| +  image.src = source; | 
| +} | 
| + | 
| +function changeColorProfile() { | 
| +  /* The test image contains the Munsell colors in a known color space. Convert | 
| +   * the colors to sRGB color space and test the transformed color accuracy. | 
| +   */ | 
| +  window.testRunner.setColorProfile('sRGB', profileChanged); | 
| +} | 
| + | 
| +function profileChanged() { | 
| +  setTimeout(drawImageToCanvas, 0); | 
| +} | 
| + | 
| +function drawImageToCanvas() { | 
| +  var image = document.querySelector('img'); | 
| + | 
| +  var canvas = document.querySelector('canvas'); | 
| +  canvas.width = image.width; | 
| +  canvas.height = image.height; | 
| + | 
| +  canvas.getContext('2d').drawImage(image, 0, 0, canvas.width, canvas.height); | 
| +  chartColorTransform(canvas); | 
| +} | 
| + | 
| +function getCanvasColor(canvas, i) { | 
| +  var x = 40 + (i % 6) * (canvas.width / 6); | 
| +  var y = 40 + Math.floor(i / 6) * (canvas.height / 4); | 
| +  try { | 
| +    var data = canvas.getContext('2d').getImageData(x, y, 1, 1).data; | 
| +    if (data[3] == 255) | 
| +      return { rgb: [data[0], data[1], data[2]] }; | 
| +    return { rgb: [0, 0, 0] }; | 
| +  } catch (error) { | 
| +    console.error(error); | 
| +    return { rgb: [255, 255, 255] }; | 
| +  } | 
| +} | 
| + | 
| +function getMunsellColor(i) { | 
| +  if (!window.munsell_srgb_colors) { | 
| +    window.munsell_srgb_colors = new Array( // Munsell colors in sRGB space. | 
| +      { color: 'Dark Skin',     rgb: [ 115,  80,  64 ] }, | 
| +      { color: 'Light Skin',    rgb: [ 195, 151, 130 ] }, | 
| +      { color: 'Blue Sky',      rgb: [  94, 123, 156 ] }, | 
| +      { color: 'Foliage',       rgb: [  88, 108,  65 ] }, | 
| +      { color: 'Blue Flower',   rgb: [ 130, 129, 177 ] }, | 
| +      { color: 'Bluish Green',  rgb: [ 100, 190, 171 ] }, | 
| +      { color: 'Orange',        rgb: [ 217, 122,  37 ] }, | 
| +      { color: 'Purplish Blue', rgb: [  72,  91, 165 ] }, | 
| +      { color: 'Moderate Red',  rgb: [ 194,  84,  98 ] }, | 
| +      { color: 'Purple',        rgb: [  91,  59, 107 ] }, | 
| +      { color: 'Yellow Green',  rgb: [ 160, 188,  60 ] }, | 
| +      { color: 'Orange Yellow', rgb: [ 230, 163,  42 ] }, | 
| +      { color: 'Blue',          rgb: [  46,  60, 153 ] }, | 
| +      { color: 'Green',         rgb: [  71, 150,  69 ] }, | 
| +      { color: 'Red',           rgb: [ 177,  44,  56 ] }, | 
| +      { color: 'Yellow',        rgb: [ 238, 200,  27 ] }, | 
| +      { color: 'Magenta',       rgb: [ 187,  82, 148 ] }, | 
| +      { color: 'Cyan (*)',      rgb: [ /* -49 */ 0, 135, 166 ] }, | 
| +      { color: 'White',         rgb: [ 243, 242, 237 ] }, | 
| +      { color: 'Neutral 8',     rgb: [ 201, 201, 201 ] }, | 
| +      { color: 'Neutral 6.5',   rgb: [ 161, 161, 161 ] }, | 
| +      { color: 'Neutral 5',     rgb: [ 122, 122, 121 ] }, | 
| +      { color: 'Neutral 3.5',   rgb: [  83,  83,  83 ] }, | 
| +      { color: 'Black',         rgb: [  50,  49,  50 ] } | 
| +    ); | 
| +  } | 
| + | 
| +  if (i < 0 && i >= munsell_srgb_colors.length) | 
| +    return { color: 'invalid-color', rgb: [ 0, 0, 0 ] }; | 
| +  return munsell_srgb_colors[i]; | 
| +} | 
| + | 
| +function getColorError(cx, cy) { | 
| +  var dr = (cx[0] - cy[0]); | 
| +  var dg = (cx[1] - cy[1]); | 
| +  var db = (cx[2] - cy[2]); | 
| +  return Math.round(Math.sqrt((dr * dr) + (dg * dg) + (db * db))); | 
| +} | 
| + | 
| +function pad(string, size) { | 
| +  size = size || 14; | 
| +  if (string.length < size) | 
| +    string += ' '.repeat(size - string.length); | 
| +  return string; | 
| +} | 
| + | 
| +function drawRule(size) { | 
| +  log('-'.repeat(size || 44)); | 
| +} | 
| + | 
| +function chartColorTransform(canvas) { | 
| +  /* | 
| +   * Add header over table of color names, acutal and expected values, and the | 
| +   * per color error (Euclidean distance). | 
| +   */ | 
| +  log(pad('Color') + pad('Actual') + pad('Expected') + 'dE'); | 
| +  drawRule(); | 
| + | 
| +  var totalSquaredError = 0.0; | 
| + | 
| +  /* | 
| +   * Report per color error dE, by comparing with the expected Munsell colors. | 
| +   */ | 
| +  for (var i = 0; i < 24;) { | 
| +    var expected = getMunsellColor(i); | 
| +    var actual = getCanvasColor(canvas, i); | 
| +    var dE = getColorError(actual.rgb, expected.rgb); | 
| + | 
| +    log(pad(expected.color) + pad(actual.rgb.join(',')) + pad(expected.rgb.join(',')) + dE); | 
| +    totalSquaredError += dE * dE; | 
| + | 
| +    if (++i % 6 == 0 && i < 24) | 
| +      drawRule(); | 
| +  } | 
| + | 
| +  /* | 
| +   * Report the total RMS color error neglecting out-of-srgb-gamut color Cyan. | 
| +   */ | 
| +  drawRule(); | 
| +  log('\nResult: total RMS color error: ' + Math.sqrt(totalSquaredError / 24.0).toFixed(2)); | 
| + | 
| +  if (window.testRunner) | 
| +    window.testRunner.notifyDone(); | 
| +} | 
|  |