title: C++ Image Processing - Reading an Image file into 2D Array
body: <p>I'm an absolute noobie at C++ as I've only been familiar with Java programming. What I'm trying to do is to read an Image file (.bmp) into a matrix where I can perform a convolution with a 3x3 matrix (filter) on the matrix to produce a new image file with the convoluted image.</p>
  
  <p>I've looked around google and managed to come up with the following implementation:</p>
  
  <p>Image.h file:</p>
  
  <pre><code>//  Image.h
  
  #include &lt;fstream&gt; // for file I/O
  
  using namespace std;
  typedef unsigned char unchar; // Easier to understand &amp; code.
  
  class MImage {
  
  public:
      MImage(const char* fileName); //Constructor
      ~MImage(); //Deconstructor
      void write(const char* fileName);
      void smoothFilter(); //smoothing filer.
  private:
      ifstream* pInFile; 
      ofstream* pOutFile;
      unchar imageHeaderData[1078]; //.bmp header data with offset 1078.
      unchar** imageData;
      unchar m_smoothFilter[3][3]; // Smoothing Filter.
      unchar**  filteredData;
  };
  </code></pre>
  
  <p>Image.cpp file:</p>
  
  <pre><code>//  Image.cpp
  //
  
  #ifndef _Image_h
  #define _Image_h
  #define WIDTH 128
  #define HEIGHT 128
  
  #include "Image.h"
  #include &lt;cmath&gt;
  
  #endif
  
  using namespace std;
  typedef unsigned char unchar;
  
  //Constructor
  
  MImage::MImage(const char* fileName){
  
      imageData = new unchar* [HEIGHT]; // create new array size: height of image.
      filteredData = new unchar* [HEIGHT];// create new array size: height of image.
  
      for (int i = 0; i &lt; HEIGHT; i++) {
  
          imageData[i] = new unchar [WIDTH]; //create matrix.
          filteredData[i] = new unchar [WIDTH]; //create matrix.
      }
  
      //image I/O
      pInFile = new ifstream;
      pInFile-&gt;open(fileName, ios::in | ios::binary); // open fileName and read as binary.
      pInFile-&gt;seekg(0, ios::beg); //pos filter at beginning of image file.
      pInFile-&gt;read(reinterpret_cast&lt;char*&gt;(imageHeaderData),1078); //read bmp header data into array.
  
      for(int i=0; i&lt;HEIGHT; i++) {
          pInFile-&gt;read(reinterpret_cast&lt;char*&gt;(imageData[i]),WIDTH);//read row into each array entry.
      }
  
      pInFile-&gt;close(); //close stream.
  
      char m_smoothFilter[3][3] = {
                                   {1,1,1},
                                   {1,2,1},
                                   {1,1,1}
                                  };
  
  }
  
  MImage::~MImage(){
  
      delete pInFile;
      delete pOutFile;
  
      for(int i=0; i&lt;HEIGHT; i++){
          delete[] imageData[i];
          delete[] filteredData[i];
      }
  
      delete[] imageData;
      delete[] filteredData;
  }
  
  void MImage::write(const char* fileName) {
  
      smoothFilter();
      pOutFile = new ofstream;
      pOutFile-&gt;open(fileName, ios::out | ios::trunc | ios::binary);
      pOutFile-&gt;write(reinterpret_cast&lt;char*&gt;(imageHeaderData), 1078); //write header data onto output
  
      for(int i = 0; i &lt; HEIGHT; i++){
  
          pOutFile-&gt;write(reinterpret_cast&lt;char*&gt;(filteredData[i]),WIDTH); // write new image data.
  
      }
  
      pOutFile-&gt;close(); //close stream
  }
  
  void MImage::smoothFilter(){
  
      //copy input image into new image
      for(int i = 0; i &lt; HEIGHT; i++) {
          strcpy(reinterpret_cast&lt;char*&gt;(filteredData[i]), reinterpret_cast&lt;char*&gt;(imageData[i]));
      }
  
      int sumOfPixels = 0;
  
      for(int i = 1; i &lt; HEIGHT -1; i++) {
  
          for(int j = 1; j &lt; WIDTH -1; j++) {
  
              sumOfPixels = m_smoothFilter[0][0] * imageData[i+1][j-1] + // top left corner
                            m_smoothFilter[0][1] * imageData[i+1][j]   + // top center
                            m_smoothFilter[0][2] * imageData[i+1][j+1] + // top right corner
                            m_smoothFilter[1][0] * imageData[i][j-1]   + // center left
                            m_smoothFilter[1][1] * imageData[i][j]     + // center center
                            m_smoothFilter[1][2] * imageData[i][j+1]   + // center right
                            m_smoothFilter[2][0] * imageData[i-1][j-1] + // bottom left corner
                            m_smoothFilter[2][1] * imageData[i-1][j]   + // bottom center
                            m_smoothFilter[2][2] * imageData[i-1][j+1];  // bottom right corner
  
              filteredData[i][j] = (sumOfPixels / ( m_smoothFilter[0][0] + m_smoothFilter[0][1] +
                                                    m_smoothFilter[0][2] + m_smoothFilter[1][0] +
                                                    m_smoothFilter[1][1] + m_smoothFilter[1][2] +
                                                    m_smoothFilter[2][0] + m_smoothFilter[2][1] +
                                                   m_smoothFilter[2][2]));
          }
      }
  
  }
  </code></pre>
  
  <p>Main.cpp file:</p>
  
  <pre><code>//
  //  Main.cpp
  //
  
  #include &lt;iostream&gt;
  #include "Image.cpp"
  #include &lt;fstream&gt;
  
  using namespace std;
  
  int main() {
  
      MImage img("test.bmp");
      img.write("output.bmp");
      return 0;
  
  }
  </code></pre>
  
  <p>When I try to run the following file with:</p>
  
  <pre><code>g++ Main.cpp -o main
  
  ./main
  </code></pre>
  
  <p>I get a segmentation:11 error and not sure what is causing this error!</p>
  
  <p><strong>Note: I have to use a pure C++ implementation so cannot use other libraries.</strong></p>
  
  <p>HELP!</p>
  
  <p>EDIT: 
  I think the code thats giving me the segmentation error is :</p>
  
  <pre><code>for(int i = 0; i &lt; HEIGHT; i++) {
          strcpy(reinterpret_cast&lt;char*&gt;(filteredData[i]), reinterpret_cast&lt;char*&gt;(imageData[i]));
  }
  </code></pre>
  
  <p>But not sure why!</p>
  
  <p>EDIT #3: 
  Works after replacing above code with :</p>
  
  <pre><code>for(int i= 0; i&lt;HEIGHT; i++) {
          strncpy (reinterpret_cast&lt;char*&gt;(filteredData[i]), 
                   reinterpret_cast&lt;char*&gt;(imageData[i]), 
                   sizeof(reinterpret_cast&lt;char*&gt;(filteredData[i])));
      }
  </code></pre>