title: Convolution for image filtering
body: <p>I'm trying to make a program in C that apply a gaussian filter to an image. I have successfully created functions that read/write the image with libpng and a function that create a kernel associated to a gaussian function.</p>
  
  <p>My code is inspired by this one : <a href="http://zarb.org/~gc/html/libpng.html" rel="nofollow noreferrer">http://zarb.org/~gc/html/libpng.html</a> and it was working for basic tasks. For example, I could increase the red value and save the image. The problem is that when I try to apply the convolution matrice I get a segmentation fault when I try to access the value of the <code>ptr</code> pointer. I don't understand why before I could read this value and not now. Also Just before <code>printf</code> with gdb I can read the values linked to ptr. Here the segfault with gdb :</p>
  
  <pre><code>0x0000555555555991 in convolute (image=0x7fffffffda80, matrice=0x7fffffffda78) at imageTools.c:157
  157               printf("%d",ptr[0]);
  </code></pre>
  
  <p>I'm also wondering if making loops that calculate the value for each pixel is the very efficient because it makes a lot of computation and I think it takes a lot of time while in software like Photoshop it is almost instantaneous.</p>
  
  <p>Here is my code :
  <code>imageTools.c</code></p>
  
  <pre><code>void convolute(image_t* image, double** matrice){
    image_t imageTemp = *image;
    int x,y,i,j;
    png_byte r,v,b;
    for(x=2;x&lt;image-&gt;height-2;x++){
      for(y=2;y&lt;image-&gt;width-2;y++){
        png_byte* new_row = imageTemp.row_pointers[x];
        png_byte* new_ptr = &amp;(new_row[y*4]);
        /*png_byte* new_pixel = malloc(4*sizeof(png_byte));*/
        r=0;v=0;b=0;
        for(i=-2;i&lt;3;i++){
          png_byte* row = image-&gt;row_pointers[i];
          for(j=-2;j&lt;3;j++){
            png_byte* ptr = &amp;(row[j*4]);
            printf("%d",ptr[0]); /* Here is the segfault*/
            r += (png_byte) ptr[0];
            v += (png_byte) ptr[1];
            b += (png_byte) ptr[2];
          }
        }
        printf("R: %d, V: %d, B: %d",r,v,b);
        new_ptr[0] = r;
        new_ptr[1] = v;
        new_ptr[2] = b;
      }
    }
    image = &amp;imageTemp;
  }
  </code></pre>
  
  <p><code>main.c</code></p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;stdint.h&gt;
  
  #define PNG_DEBUG 3
  #include &lt;png.h&gt;
  
  #include "imageTools.h"
  #include "filtreGaussien.h"
  
  int main()
  {
      image_t image;
      double** noyau;
      int i,j;
  
      if(read_png_file("test.png", &amp;image)){
        printf("OK!\n");
        printf("Height: %d, Width: %d\n", image.height, image.width);
  
        noyau  = noyauGaussien(1.0);
        for(i=0;i&lt;5;i++){
          printf("| ");
          for(j=0;j&lt;5;j++){
            printf("%f | ",noyau[i][j]);
          }
          printf("\n");
        }
  
        convolute(&amp;image, &amp;noyau);
  
        write_png_file("test2.png", &amp;image);
      } else {
        printf("An error as occured. Exiting...");
      }
      return 0;
  }
  </code></pre>
  
  <p><code>image_t</code> structure :</p>
  
  <pre><code>typedef struct{
    png_bytep* row_pointers;
    int width;
    int height;
    png_byte color_type;
    png_byte bit_depth;
  }
  image_t;
  </code></pre>