Store all QImage's pixels with scanLine() method in C++
<p>I am trying to modify an image using <strong>Qt</strong> with the <a href="http://doc.qt.io/qt-4.8/qimage.html#scanLine" rel="nofollow noreferrer"><code>scanLine()</code></a> method. This methods return a pointer to the data of a given row. I founded how to read rows <a href="https://stackoverflow.com/questions/2095039/qt-qimage-pixel-manipulation">here</a>. Right now, I am able to read the value of all pixels like this:</p>

<pre><code>QRgb ** pixels;

pixels = (QRgb **) (malloc(sizeof (QRgb*) * img-&gt;width() * img-&gt;height()));

#pragma omp parallel for
for (int y = 0; y &lt; img-&gt;height(); ++y) {
    pixels[y] = (QRgb*) img-&gt;scanLine(y);
}

for (int x = 0; x &lt; img-&gt;width(); ++x) {
    for (int y = 0; y &lt; img-&gt;height(); ++y) {
        int color =  qRed(pixels[y][x]);
        std::cout &lt;&lt; "Pixel at " &lt;&lt; x &lt;&lt; ", " &lt;&lt; y &lt;&lt; " is " &lt;&lt; color &lt;&lt; std::endl;
    }
}
</code></pre>

<p>Then, I process each pixel and try to add those in a new <code>QRgb **</code> variable, but this is where the program fails while executing.</p>

<pre><code>QRgb ** finalPixels;

finalPixels = (QRgb **) (malloc(sizeof (QRgb*) * img-&gt;width() * img-&gt;height()));

    for (int x = 0; x &lt; img-&gt;width(); ++x) {
        for (int y = 0; y &lt; img-&gt;height(); ++y) {

            // Process pixels[y][x]


            QColor final(/* some new value */);
            QRgb finalrgb = final.rgb();

            finalPixels[y][x] = finalrgb; // What I realy want to do - Make the program fail
            finalPixels[y][x] = &amp;finalrgb; // Don't build : invalid conversion from ‘QRgb* {aka unsigned int*}’ to ‘QRgb {aka unsigned int}’
            finalPixels[y][x] = pixels[y][x]; // Make the program fail


        }
    }
</code></pre>

<p>I don't understand why I can't change the reference of <code>finalPixels[y][x]</code> to a new reference. Is the type of the variable incorrect ? Or this is not how to do ? I readed some stuff about 2 dimensional arrays and pointers but still I can't figure out what is the problem here.</p>

<p><strong>EDIT</strong></p>

<p>@rames answered to this question by proposing to use <code>pixel()</code> and <code>setPixel()</code> methods. These methods are much easier to use, but this is not what I'm looking for. My first implementation was using these methods but as the <a href="http://doc.qt.io/qt-4.8/qimage.html#setPixel" rel="nofollow noreferrer"><code>setPixel()</code> method's documentation</a> says:</p>

<blockquote>
  <p>Warning: This function is expensive due to the call of the internal
  <code>detach()</code> function called within; if performance is a concern, we
  recommend the use of <code>scanLine()</code> to access pixel data directly.</p>
</blockquote>

<p>And since my goal is to apply filters to an image like blur, edge detection, I need performance, so this is why I'm trying to use <code>scanLine()</code>.</p>

<hr>

<p>I tried to change my variable type. And then simply change the pixels' color like this:</p>

<pre><code>QRgb * pixels[img-&gt;height()];


#pragma omp parallel 
for (int y = 0; y &lt; img-&gt;height(); ++y)
   pixels[y] = (QRgb*) img-&gt;scanLine();
}

for (int x = 0; x &lt; img-&gt;width(); ++x) {
  for (int y = 0; y &lt; img-&gt;height(); ++y) {
      QColor c(0,0,0);
      QRgb cr = c.rgb();
      pixels[y][x] = cr;
  }
}
</code></pre>

<p>But even this is failing when the program runs <code>pixels[y][x] = cr;</code> and I don't understand why. The output of QtCreator is <code>he program has unexpectedly finished.</code>.</p>

<hr>

<p>Ok so I know how to modify the pixels of an image with the <code>scanLine()</code> method thanks to @user3528438 and @Rames. But still I can't find a way to get all the pixels in a variable. My goal is to have a temp variable, this way, I can compute a modification on the image with original pixels. Here is the last thing I tried:</p>

<pre><code>QRgb * pixelsCopy[img-&gt;height()][img-&gt;width()];
QRgb * pColor;

for (int y = 0; y &lt; img-&gt;height(); ++y) {
    for (int x = 0; x &lt; img-&gt;width(); ++x) {
        pColor = new QRgb( (QRgb)img-&gt;scanLine(y)[x] );

        pixelsCopy[y][x] = pColor;
    }
}

for (int x = 0; x &lt; img-&gt;width(); ++x) {
    for (int y = 0; y &lt; img-&gt;height(); ++y) {
        int color =  qRed(*pixelsCopy[y][x]); // Return 0
        std::cout &lt;&lt; "Pixel at " &lt;&lt; x &lt;&lt; ", " &lt;&lt; y &lt;&lt; " is " &lt;&lt; color &lt;&lt; std::endl;
    }
} 
</code></pre>

<p>This compile and run well, but all values are 0.. If I compare to the original pixels, this is not the case. Can you explain to me why my values are not the original onces and are all set to 0 in my <code>*pixelsCopy</code> variable ? And also, isn't is too heavy to call <code>scanLine()</code> method for each pixel ? I also tried to change <code>*pixelsCopy</code> to <code>pixelsCopy</code>, but I still get 0 values..</p>

<p><strong>EDIT 2</strong></p>

<p>Thanks to @user3528438 and @Rames, I finally found a way to <strong>copy</strong> pixels into a new variable, but I am getting weird results. I wrote a code that copy the pixels and reapply those to the image and I am not getting the same image.</p>

<pre><code>QRgb pixelsCopy[img-&gt;height()][img-&gt;width()];

for (int y = 0; y &lt; img-&gt;height(); ++y) {
    QRgb * line = reinterpret_cast&lt;QRgb *&gt;(img-&gt;scanLine(y));
    for (int x = 0; x &lt; img-&gt;width(); ++x) {
        pixelsCopy[y][x] = line[x];
    }
}

for (int x = 0; x &lt; img-&gt;width(); ++x) {
    for (int y = 0; y &lt; img-&gt;height(); ++y) {
        int r = qRed(pixelsCopy[y][x]);
        QColor final(r, r, r);
        img-&gt;scanLine(y)[x] = final.rgb();

    }
}
</code></pre>

<p>And this is the before and after:
<a href="https://i.stack.imgur.com/STCmA.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/STCmA.png" alt="enter image description here"></a></p>

<p>It looks like a coordinate mistake but I checked multiple times and saw nothing.. If you have a <strong>faster</strong> and/or <strong>cleaner</strong> way to copy the original pixels, It will be nice to advice me ! </p>