title: Firefox throwing a exception with HTML Canvas putImageData
body: <p>So I was working on this little javascript experiment and I needed a widget to track the FPS of it. I ported a widget I've been using with Actionscript 3 to Javascript and it seems to be working fine with Chrome/Safari but on Firefox is throwing an exception.</p>
  
  <p>This is the experiment:</p>
  
  <p><a href="http://mrdoob.com/projects/chromeexperiments/depth_of_field__debug/" rel="noreferrer">Depth of Field</a></p>
  
  <p>This is the error:</p>
  
  <pre><code>[Exception... "An invalid or illegal string was specified"  code: "12" nsresult: "0x8053000c (NS_ERROR_DOM_SYNTAX_ERR)"  location: "http://mrdoob.com/projects/chromeexperiments/depth_of_field__debug/js/net/hires/debug/Stats.js Line: 105"]
  </code></pre>
  
  <p>The line that is complaning about is this one:</p>
  
  <pre><code>graph.putImageData(graphData, 1, 0, 0, 0, 69, 50);
  </code></pre>
  
  <p>Which is a crappy code to "scroll" the bitmap pixels. The idea is that I only draw a few pixels on the left of the bitmap and then on the next frame I copy the whole bitmap and paste it on pixel to the right. This error usually is thrown because you're pasting a bitmap bigger than the source and it's going off the limits, but in theory that shouldn't be the case as I'm defining 69 as the width of the rectangle to paste (being the bitmap 70px wide).</p>
  
  <p>And this is full code:</p>
  
  <pre><code>var Stats = {
  baseFps: null,
  
  timer: null,
  timerStart: null,
  timerLast: null,
  fps: null,
  ms: null,
  
  container: null,
  fpsText: null,
  msText: null,
  memText: null,
  memMaxText: null,
  
  graph: null,
  graphData: null, 
  
  init: function(userfps)
  {
      baseFps = userfps;
  
      timer = 0;
      timerStart = new Date() - 0;
      timerLast = 0; 
      fps = 0;
      ms = 0;
  
      container = document.createElement("div");
      container.style.fontFamily = 'Arial';
      container.style.fontSize = '10px';
      container.style.backgroundColor = '#000033';
      container.style.width = '70px';
      container.style.paddingTop = '2px';
  
      fpsText = document.createElement("div");
      fpsText.style.color = '#ffff00';
      fpsText.style.marginLeft = '3px';
      fpsText.style.marginBottom = '-3px';
      fpsText.innerHTML = "FPS:";
      container.appendChild(fpsText);
  
      msText = document.createElement("div");
      msText.style.color = '#00ff00';
      msText.style.marginLeft = '3px';
      msText.style.marginBottom = '-3px';
      msText.innerHTML = "MS:";
      container.appendChild(msText);
  
      memText = document.createElement("div");
      memText.style.color = '#00ffff';
      memText.style.marginLeft = '3px';
      memText.style.marginBottom = '-3px';
      memText.innerHTML = "MEM:";
      container.appendChild(memText);
  
      memMaxText = document.createElement("div");
      memMaxText.style.color = '#ff0070';
      memMaxText.style.marginLeft = '3px';
      memMaxText.style.marginBottom = '3px';
      memMaxText.innerHTML = "MAX:";
      container.appendChild(memMaxText);
  
      var canvas = document.createElement("canvas");
      canvas.width = 70;
      canvas.height = 50;
      container.appendChild(canvas);
  
      graph = canvas.getContext("2d");
      graph.fillStyle = '#000033';
      graph.fillRect(0, 0, canvas.width, canvas.height );
  
      graphData = graph.getImageData(0, 0, canvas.width, canvas.height);
  
      setInterval(this.update, 1000/baseFps);
  
      return container;
  },
  
  update: function()
  {
      timer = new Date() - timerStart;
  
      if ((timer - 1000) &gt; timerLast)
      {
          fpsText.innerHTML = "FPS: " + fps + " / " + baseFps;
          timerLast = timer;
  
          graph.putImageData(graphData, 1, 0, 0, 0, 69, 50);
          graph.fillRect(0,0,1,50);
          graphData = graph.getImageData(0, 0, 70, 50);
  
          var index = ( Math.floor(Math.min(50, (fps / baseFps) * 50)) * 280 /* 70 * 4 */ );
          graphData.data[index] = graphData.data[index + 1] = 256;
  
          index = ( Math.floor(Math.min(50, 50 - (timer - ms) * .5)) * 280 /* 70 * 4 */ );
          graphData.data[index + 1] = 256;            
  
          graph.putImageData (graphData, 0, 0);
  
          fps = 0;            
      }
  
      ++fps;
  
      msText.innerHTML = "MS: " + (timer - ms);
      ms = timer;
  }
  </code></pre>
  
  <p>}</p>
  
  <p>Any ideas? Thanks in advance.</p>