Why does my algorithm to convert between index and x,y with bitmap buffers result in the image being flipped vertically? : <p>When working with bitmap buffers like:</p>

<pre><code>[50, 50, 50, 255, 50, 50, 50, 255, ...]
[r,  g,  b,  a,   r,  g,  b,  a, ...]
</code></pre>

<p>I often use math like this:</p>

<pre><code>let bufferWidth = width * 4;
buffer.forEach((channel, index) =&gt; {
    let y = Math.floor(index / bufferWidth);
    let x = Math.floor((index % bufferWidth) / 4);
    let remainder = index % 4;
</code></pre>

<p>in order to calculate x, y, or vice versa to work with flat buffers of bitmap data. Almost always I end up with flipped results and some way or another end up flipping them back, but clearly there's something wrong with my thinking on this.</p>

<p>What's wrong with this math that would cause the bitmap to be flipped?</p>

<p>Full code, a function to crop a bitmap:</p>

<pre><code>function crop(
  buffer,
  width,
  height,
  leftLimit,
  rightLimit,
  lowerLimit,
  upperLimit
) {
  let croppedWidth = rightLimit - leftLimit;
  let croppedHeight = upperLimit - lowerLimit;
  let length = croppedHeight * croppedWidth * 4;
  let bufferWidth = width * 4;
  let croppedBuffer = new Uint8Array(length);
  buffer.forEach((channel, index) =&gt; {
    let y = Math.floor(index / bufferWidth);
    let x = Math.floor((index % bufferWidth) / 4);
    let remainder = index % 4;
    let yCropped = y - lowerLimit;
    let xCropped = x - leftLimit;
    let indexCropped = yCropped * croppedWidth * 4 + xCropped * 4 + remainder;
    if (
      xCropped &gt;= 0 &amp;&amp;
      xCropped &lt;= croppedWidth &amp;&amp;
      yCropped &gt;= 0 &amp;&amp;
      yCropped &lt;= croppedHeight
    ) {
      croppedBuffer[indexCropped] = buffer[index];
    }
  });
  return croppedBuffer;
}
</code></pre>
