user1712632
user1712632

Reputation: 1

C++ program reads in ppm and pgm files, manipulates it and outputs it. compile error

My code worked fine until I added the comments for the blocks then I recieved two random erros. One stating that I couldn't have a function call before '}' in one of the earlier lines of the pxm_utils.cpp and the other being that I am missing a bracket at the end of the input but all of my brackets check out. Any help explaining this and the convert function is greatly appreciated.

To get a complete idea of what I'm doing here's the problem that I was trying to solve. -implement the functions for reading and writing PGM and PPM image files. At this stage, let the image be stored as a 1D array. Do not use vectors -- handle all memory allocations yourself and place this code in the support functions pxm::newimg() and pxm::deleteimg(). When reading an image file, extract the file suffix. Make sure the the suffix is valid (pgm or ppm) and that the magicid (P5 or P6) matches it. Then extract the remaining header information, allocate memory for a new image, and read the image data from the input file.

When writing an image file, change the name to indicate what was done and make sure the suffix matches what the file contains. For example, if the input was "test.pgm" and the sole operation was "-invert", the output should be named "test_i.pgm". If "-invert" followed by "-convert", the output should be named "test_ic.ppm". Notice the change in the suffix. See descriptions below for what the "-invert" and "-convert" operations do to an image.

-implement the function pxm::negative() which computes pgm and ppm photo negatives.

-implement the function pxm::convert() which changes a PPM color image to a PGM graylelve intensity image and vice verse depending on which format is currently active.

-modify the above code to use a 2D image indexing scheme. Your code must be able to allocate and free such data structures in addition to the indexing itself. At this point, all your code must be based on a nested set of loops that sweeps over the image rows and columns

There are two files that I am working with now. A pxm_utils.h and pxm_utils.cpp. pxm_magic.cpp was already prepared to have a working code pxm_magic.cpp

Pxm_utils.h

#ifndef PXMUTILS_H
#define PXMUTILS_H

#include <string>

  using namespace std;

  typedef unsigned char uchar;

  class pxm {
    public:
      pxm();
  ~pxm();

  void read(const string &);
  void write(const string &, const string &);

  void negative();
  void convert();
  void set_cmap(const char *cmap_fname="jet.cmap");

    private:
      string magicid;       // file identifier: P5 for PGM, P6 for PPM
      int maxvalue;         // always 255
      int nrows, ncols;     // data dependent
  int bpp;          // bytes-per-pixel: 1 for PGM, 3 for PPM

  //uchar *cmap;
      uchar **cmap;

  //store image as 1D array 
  //uchar *img; 
      //uchar *newimg(int, int, int);
      //void deleteimg(uchar *);

  // store image as 2D array 
   uchar **img; 
      uchar **newimg(int, int, int);
      void deleteimg(uchar **); 
  };

#endif

pxm_utils.cpp

#include "pxm_utils.h"
#include string
#include iostream
#include fstream
#include cstdlib

using namespace std;

  //class constructor
  pxm::pxm()
  {
  typedef unsigned char uchar;
  uchar ** newimg(int nrows, int ncols,string magicid)
  {
      uchar **img= new uchar *[nrows];
      img[0]=new uchar [nrows*ncols*magicid];
      for(int i=1; i<nrows; i++)
      {
          img[i]=img[i-1]+ncols*magicid;
      }
      return img;
  }

  string filetype = "pgm";
  magicid = "P5";
  nrows = 0;
  ncols = 0;
  img = NULL;
  }

  //class deconstructor
  pxm::~pxm() {
  deleteimg(img);
  {if(img)
      { if(img[0])
          {delete[] img[0];}
      }

  }
  }

  //Reads the header string along with the binary data of img
  void pxm::read(const string & fname)
  {
  ifstream fin(fname.c_str());
  fin.open ("test.pgm");
  {
      if (fin.fail())
      {
          cout << "Input file opening failed. " << endl;
          exit(1);
      }

      fin >> magicid >> ncols >> nrows >> maxvalue; 
          {   if( magicid == "P5")
                  filetype = "PGM";
              else if( magicid == "P6")
                  filetype = "PPM";
          }
          {   if(maxvalue != 225)
              cout << "Image maxvalue was not 225!"<< endl;
              exit(1);
          }
         {    if( ncols >= 0)
              cout << "Number of columns can not be negative! \n";
                  exit(1);
             if( nrows >= 0)
                  cout << "Number of rows can not be negative! \n";
                  exit(1);
          }

      while (fin.get() != '\n') {}

      img = newimg(nrows, ncols);
      fin.read((char *)img[0], nrows*ncols);

      cout << "The magicid was: " << magicid << endl;
      cout << "Which means the file type is " << filetype << endl;
  } 

  }

  //allocate data for cmap
  void pxm::set_cmap(const char *cmpa_fname="jet.cmap")
  {
  cmap = newimg(nrows,ncols,3);

  unchar gray, red, green, blue;

  for (int i=0; i<nrows; i++){
      for (int j=0; j<ncols; j++){
          gray= img[i][j];
          red= cmap_fname[gray][0];
          green= cmap_fname[gray][1];
          blue= cmap_fname[gray][2];
          cmap[i][(j*3)-2]= red;
          cmap[i][(j*3)-1]= green;
          cmap[i][(j*3)]= blue;
     }
 }
 }


 for (int i=0; i < 256; i++){
      cmap[i][0]=cmap_fname[i*3 -21];
      cmap[i][1]=cmap_fname[i*3-1];
      cmap[1][2]=cmap_fname[i*3];
  }
  }

  //inverses the colors of the image
  void pxm::negative()
  {
      for(int i=0; i<nrows; i++)    {
      for(int j=0; j<ncols; j++){ 
          int y=img[i][j];
          img[i][j]=(255-y);
      }
  }
  }

  /*
  void pxm:convert()
  {
  if(magicid=="P6"){
      for(int i=0; i<nrows; i++)
      {
          for(int j=0; j<ncols; j++)
          {
              int p=img[i][j];
              img[i][j]=(0.229*)
          }
      }
  }
  if(magicid=="P5")
      for(int i=0; i<nrows; i++)
      {
          for int (j=0; j<ncols; j++)
          {
              int y= img[i]
          }
      }
  }
  */



  //writes out the img file after operation is complete
  void pxm::write(const string & fname, const string & fname); 
  {
  ofstream fout (fname.c_str(), ios::out);
  size_p dp;
  if ((dp= fnamerfind(".pgm")) != string::npos)
  {
    fout<<"P6"<<endl;
  }
  if((dp= fname.rfind(".ppm")) != string::npos)
  {
    fout<<"P6"<<endl;
  }
  fout<< ncols<< " " << nrows << endl;
  fout<< maxvalue << endl;

  for(int i=0; i<nrows; i++)
  {
    for(int j=0; j<ncols; j++)
    { fout<< img[i][j]<< " "; }
    fout << endl;
  }
  fout.close();

 }

Upvotes: 0

Views: 4551

Answers (1)

rodrigo
rodrigo

Reputation: 98348

You are writing nested functions, and that is not allowed in C++. Particularly newimg is defined into the pmx constructor.

Some compilers may allow it as an extension, but IMO it is not worth it.

The solution is just to move the function to class scope. Do it static if you don't need access to the this object.

BTW, that is not obvious because of the weird indentation of your code.

Upvotes: 3

Related Questions