

#include "write_ppm.h"

int _imagecounter = 0;          // incremental counter to save temporary images


int save_write_ppm_greylevel(const float *image,
                             const int dim1=256, const int dim2=256)
{
  //cout <<"Writing image "<<_imagecounter+1<<endl<<flush;
  int tmp;
  char buffer[10];
  FILE *out_file;
  char tmppath[25];
  float *tmpImage = new float[dim1*dim2];
  memcpy(tmpImage, image, dim1*dim2*sizeof(float));
  
  sprintf(tmppath, "tmpImage_%05d.ppm", _imagecounter);

  _imagecounter++;

  out_file = fopen(tmppath, "w");
  if(out_file == NULL){
    cout << "\nERROR:\tCannot open file "<<tmppath<< " for writing \n\tReturning without writing\n";
    delete[] tmpImage;
    return -1;
  }
  if(dim1>9999 || dim2>9999){
    cout << "WARNING:Image dimension too big,"
      "\n\tedit function write_ppm_greylevel(float* ) in write_ppm.cc\n";
    fclose(out_file);
    delete[] tmpImage;
    return -1;
  }

  scaleArray(tmpImage, dim1*dim2, float(0), float(255)); // scale data into 255 range
  
  fwrite("P2\n", sizeof(char), 3, out_file);             // write format

  sprintf(buffer, "%d %d\n", dim1, dim2);                // compose dimensions
  tmp = 8;
  if (dim1>999) tmp = tmp+1;
  if (dim2>999) tmp = tmp+1;
  fwrite(buffer,  sizeof(char), tmp, out_file);          // write dimensions
  
  fwrite("255\n",  sizeof(char), 4, out_file);            // write greylevel range

  buffer[5] = '\0';
  for(int i=0; i<dim1*dim2; i++){                        // write data
    sprintf(buffer, "%03d ", int(tmpImage[i]));
    fwrite(buffer, sizeof(char), 4, out_file);
    if(i % 15 == 0){
      fwrite("\n", sizeof(char), 1, out_file);
    }
  }
  if(!fclose(out_file)){
    delete out_file;
    delete[] tmpImage;
    return 1;                                            // successfully closed file
  }
  return -1;
  
}


int save_write_ppm_greylevel(const short *image,
                             const int dim1=256, const int dim2=256)
{ 
  int tmp;
  char buffer[10];
  FILE *out_file;
  char tmppath[25];
  short *tmpImage = new short[dim1*dim2];
  memcpy(tmpImage, image, dim1*dim2*sizeof(short));
  
  sprintf(tmppath, "tmpImage_%05d.ppm", _imagecounter);

  _imagecounter++;

  out_file = fopen(tmppath, "w");
  if(out_file == NULL){
    cout << "\nERROR:\tCannot open file "<<tmppath<< " for writing \n\tReturning without writing\n";
    delete[] tmpImage;
    return -1;
  }
  if(dim1>9999 || dim2>9999){
    cout << "WARNING:Image dimension too big,"
      "\n\tedit function write_ppm_greylevel(float* ) in write_ppm.cc\n";
    fclose(out_file);
    delete[] tmpImage;
    return -1;
  }

  scaleArray(tmpImage, dim1*dim2, short(0), short(255)); // scale data into 255 range
  
  fwrite("P2\n", sizeof(char), 3, out_file);             // write format

  sprintf(buffer, "%d %d\n", dim1, dim2);                // compose dimensions
  tmp = 8;
  if (dim1>999) tmp = tmp+1;
  if (dim2>999) tmp = tmp+1;
  fwrite(buffer,  sizeof(char), tmp, out_file);          // write dimensions
  
  fwrite("255\n",  sizeof(char), 4, out_file);           // write greylevel range

  buffer[5] = '\0';
  for(int i=0; i<dim1*dim2; i++){                        // write data
    sprintf(buffer, "%03d ", tmpImage[i]);
    fwrite(buffer, sizeof(char), 4, out_file);
    if(i % 15 == 0){
      fwrite("\n", sizeof(char), 1, out_file);
    }
  }
  if(!fclose(out_file)){
    delete out_file;
    delete[] tmpImage;
    return 1;                                            // successfully closed file
  }
  return -1;
}

int save_write_ppm_color(    const short *image, const int dim1=256, const int dim2=256)
{
  int tmp;
  char buffer[10];
  FILE *out_file;
  char tmppath[25];
  short *tmpImage = new short[dim1*dim2*3];
  memcpy(tmpImage, image, dim1*dim2*3*sizeof(short));
  sprintf(tmppath, "tmpImage_%05d.ppm", _imagecounter);

  _imagecounter++;

  out_file = fopen(tmppath, "w");
  if(out_file == NULL){
    cout << "\n\t Cannot open file "<<tmppath<< " for writing \tReturning without writing\n";
    delete[] tmpImage;
    return -1;
  }
  if(dim1>9999 || dim2>9999){
    cout << "Image dimension too big, edit function write_ppm_color() in write_ppm.cc\n";
    delete[] tmpImage;
    return -1;
  }

  scaleArray(tmpImage, dim1*dim2*3, short(0), short(255));  // scale data into 255 range

  fwrite("P3\n",  sizeof(char), 3, out_file);            // write format

  sprintf(buffer, "%d %d\n", dim1, dim2);                // compose dimensions
  tmp = 8;
  if (dim1>999) tmp = tmp+1;
  if (dim2>999) tmp = tmp+1;
  fwrite(buffer,  sizeof(char), tmp, out_file);          // write dimensions
  
  fwrite("255\n",  sizeof(char), 4, out_file);           // write greylevel range

  buffer[5] = '\0';
  for(int i=0; i<dim1*dim2*3; i++){                      // write data
    sprintf(buffer, "%03d ", tmpImage[i]);
    fwrite(buffer, sizeof(char), 4, out_file);
    if(i % 15 == 0){
      fwrite("\n", sizeof(char), 1, out_file);
    }
  }
  if(!fclose(out_file)){
    delete out_file;
    delete[] tmpImage;
    return 1;                                            // successfully closed file
  }
  return -1;
}

int save_write_ppm_color(    const float *image, const int dim1=256, const int dim2=256)
{
  int tmp;
  char buffer[10];
  FILE *out_file;
  char tmppath[25];
  float *tmpImage = new float[dim1*dim2*3];
  memcpy(tmpImage, image, dim1*dim2*3*sizeof(float));
  sprintf(tmppath, "tmpImage_%05d.ppm", _imagecounter);

  _imagecounter++;

  out_file = fopen(tmppath, "w");
  if(out_file == NULL){
    cout << "\n\t Cannot open file "<<tmppath<< " for writing \tReturning without writing\n";
    delete[] tmpImage;
    return -1;
  }
  if(dim1>9999 || dim2>9999){
    cout << "Image dimension too big, edit function write_ppm_color() in write_ppm.cc\n";
    delete[] tmpImage;
    return -1;
  }

  scaleArray(tmpImage, dim1*dim2*3, float(0), float(255));  // scale data into 255 range

  fwrite("P3\n",  sizeof(char), 3, out_file);            // write format

  sprintf(buffer, "%d %d\n", dim1, dim2);                // compose dimensions
  tmp = 8;
  if (dim1>999) tmp = tmp+1;
  if (dim2>999) tmp = tmp+1;
  fwrite(buffer,  sizeof(char), tmp, out_file);          // write dimensions
  
  fwrite("255\n",  sizeof(char), 4, out_file);           // write greylevel range

  buffer[5] = '\0';
  for(int i=0; i<dim1*dim2*3; i++){                      // write data
    sprintf(buffer, "%03d ", int(tmpImage[i]));
    fwrite(buffer, sizeof(char), 4, out_file);
    if(i % 15 == 0){
      fwrite("\n", sizeof(char), 1, out_file);
    }
  }
  if(!fclose(out_file)){
    delete out_file;
    delete[] tmpImage;
    return 1;                                            // successfully closed file
  }
  return -1;
}



int save_write_and_display_ppm_greylevel(const short *image, const int dim1=256, const int dim2=256)
{
  char command[30];
  int  returnvalue = 0;
  sprintf(command, "xv tmpImage_%05d.ppm &", _imagecounter);
  returnvalue = save_write_ppm_greylevel(image, dim1, dim2);
  if(returnvalue>0) system(command);
  return returnvalue;
}

int save_write_and_display_ppm_greylevel(const float *image, const int dim1=256, const int dim2=256)
{
  char command[30];
  int  returnvalue = 0;
  sprintf(command, "xv tmpImage_%05d.ppm &", _imagecounter);
  //cout << command<<endl;
  returnvalue = save_write_ppm_greylevel(image, dim1, dim2);
  if(returnvalue>0) system(command);
  return returnvalue;
}


int save_write_and_display_ppm_color(    const short *image, const int dim1=256, const int dim2=256)
{
  char command[30];
  int  returnvalue = 0;
  sprintf(command, "xv tmpImage_%05d.ppm &", _imagecounter);
  returnvalue = save_write_ppm_color(image, dim1, dim2);
  if(returnvalue>0) system(command);
  return returnvalue;
}

int save_write_and_display_ppm_color(    const float *image, const int dim1=256, const int dim2=256)
{
  char command[30];
  int  returnvalue = 0;
  sprintf(command, "xv tmpImage_%05d.ppm &", _imagecounter);
  returnvalue = save_write_ppm_color(image, dim1, dim2);
  if(returnvalue>0) system(command);
  return returnvalue;
}

/***** faster, less memory, but not save *****/


int write_ppm_greylevel(float *image,
                             const int dim1=256, const int dim2=256)
{
  int tmp;
  char buffer[10];
  FILE *out_file;
  char tmppath[25];
  
  sprintf(tmppath, "tmpImage_%05d.ppm", _imagecounter);

  _imagecounter++;

  out_file = fopen(tmppath, "w");
  if(out_file == NULL){
    cout << "\nERROR:\tCannot open file "<<tmppath<< " for writing \n\tReturning without writing\n";
    return -1;
  }
  if(dim1>9999 || dim2>9999){
    cout << "WARNING:Image dimension too big,"
      "\n\tedit function write_ppm_greylevel(float* ) in write_ppm.cc\n";
    fclose(out_file);
    return -1;
  }

  scaleArray(image, dim1*dim2, float(0), float(255)); // scale data into 255 range
  
  fwrite("P2\n", sizeof(char), 3, out_file);             // write format

  sprintf(buffer, "%d %d\n", dim1, dim2);                // compose dimensions
  tmp = 8;
  if (dim1>999) tmp = tmp+1;
  if (dim2>999) tmp = tmp+1;
  fwrite(buffer,  sizeof(char), tmp, out_file);          // write dimensions
  
  fwrite("255\n",  sizeof(char), 4, out_file);            // write greylevel range

  buffer[5] = '\0';
  for(int i=0; i<dim1*dim2; i++){                        // write data
    sprintf(buffer, "%03d ", int(image[i]));
    fwrite(buffer, sizeof(char), 4, out_file);
    if(i % 15 == 0){
      fwrite("\n", sizeof(char), 1, out_file);
    }
  }
  if(!fclose(out_file)) return 1;                        // successfully closed file
  return -1;  
}


int write_ppm_greylevel(short *image,
                        const int dim1=256, const int dim2=256)
{
  int tmp;
  char buffer[10];
  FILE *out_file;
  char tmppath[25];
  
  sprintf(tmppath, "tmpImage_%05d.ppm", _imagecounter);

  _imagecounter++;

  out_file = fopen(tmppath, "w");
  if(out_file == NULL){
    cout << "\nERROR:\tCannot open file "<<tmppath<< " for writing \n\tReturning without writing\n";
    return -1;
  }
  if(dim1>9999 || dim2>9999){
    cout << "WARNING:Image dimension too big,"
      "\n\tedit function write_ppm_greylevel(float* ) in write_ppm.cc\n";
    fclose(out_file);
    return -1;
  }

  scaleArray(image, dim1*dim2, short(0), short(255)); // scale data into 255 range
  
  fwrite("P2\n", sizeof(char), 3, out_file);             // write format

  sprintf(buffer, "%d %d\n", dim1, dim2);                // compose dimensions
  tmp = 8;
  if (dim1>999) tmp = tmp+1;
  if (dim2>999) tmp = tmp+1;
  fwrite(buffer,  sizeof(char), tmp, out_file);          // write dimensions
  
  fwrite("255\n",  sizeof(char), 4, out_file);           // write greylevel range

  buffer[5] = '\0';
  for(int i=0; i<dim1*dim2; i++){                        // write data
    sprintf(buffer, "%03d ", image[i]);
    fwrite(buffer, sizeof(char), 4, out_file);
    if(i % 15 == 0){
      fwrite("\n", sizeof(char), 1, out_file);
    }
  }
  if(!fclose(out_file)) return 1;                        // successfully closed file
  return -1;  
}

int write_ppm_color(float *image, const int dim1=256, const int dim2=256)
{
  int tmp;
  char buffer[10];
  FILE *out_file;
  char tmppath[13];
  sprintf(tmppath, "tmpImage_%05d.ppm", _imagecounter);

  _imagecounter++;

  out_file = fopen(tmppath, "w");
  if(out_file == NULL){
    cout << "\n\t Cannot open file "<<tmppath<< " for writing \tReturning without writing\n";
    return -1;
  }
  if(dim1>9999 || dim2>9999){
    cout << "Image dimension too big, edit function write_ppm_color() in write_ppm.cc\n";
    return -1;
  }

  scaleArray(image, dim1*dim2*3, float(0), float(255));  // scale data into 255 range

  fwrite("P3\n",  sizeof(char), 3, out_file);            // write format

  sprintf(buffer, "%d %d\n", dim1, dim2);                // compose dimensions
  tmp = 8;
  if (dim1>999) tmp = tmp+1;
  if (dim2>999) tmp = tmp+1;
  fwrite(buffer,  sizeof(char), tmp, out_file);          // write dimensions
  
  fwrite("255\n",  sizeof(char), 4, out_file);           // write greylevel range

  buffer[5] = '\0';
  for(int i=0; i<dim1*dim2*3; i++){                      // write data
    sprintf(buffer, "%03d ", int(image[i]));
    fwrite(buffer, sizeof(char), 4, out_file);
    if(i % 15 == 0){
      fwrite("\n", sizeof(char), 1, out_file);
    }
  }
  if(!fclose(out_file)) return 1;                        // successfully closed file
  return -1;
}

int write_ppm_color(short *image, const int dim1=256, const int dim2=256)
{
  int tmp;
  char buffer[10];
  FILE *out_file;
  char tmppath[13];
  sprintf(tmppath, "tmpImage_%05d.ppm", _imagecounter);

  _imagecounter++;

  out_file = fopen(tmppath, "w");
  if(out_file == NULL){
    cout << "\n\t Cannot open file "<<tmppath<< " for writing \tReturning without writing\n";
    return -1;
  }
  if(dim1>9999 || dim2>9999){
    cout << "Image dimension too big, edit function write_ppm_color() in write_ppm.cc\n";
    return -1;
  }

  scaleArray(image, dim1*dim2*3, short(0), short(255));  // scale data into 255 range

  fwrite("P3\n",  sizeof(char), 3, out_file);            // write format

  sprintf(buffer, "%d %d\n", dim1, dim2);                // compose dimensions
  tmp = 8;
  if (dim1>999) tmp = tmp+1;
  if (dim2>999) tmp = tmp+1;
  fwrite(buffer,  sizeof(char), tmp, out_file);          // write dimensions
  
  fwrite("255\n",  sizeof(char), 4, out_file);           // write greylevel range

  buffer[5] = '\0';
  for(int i=0; i<dim1*dim2*3; i++){                      // write data
    sprintf(buffer, "%03d ", image[i]);
    fwrite(buffer, sizeof(char), 4, out_file);
    if(i % 15 == 0){
      fwrite("\n", sizeof(char), 1, out_file);
    }
  }
  if(!fclose(out_file)) return 1;                        // successfully closed file
  return -1;
}


int write_and_display_ppm_greylevel(short *image, const int dim1=256, const int dim2=256)
{
  char command[30];
  int  returnvalue = 0;
  sprintf(command, "xv tmpImage_%05d.ppm &", _imagecounter);
  returnvalue = write_ppm_greylevel(image, dim1, dim2);
  
  if(returnvalue>0) system(command);

  return returnvalue;
}

int write_and_display_ppm_greylevel(float *image, const int dim1=256, const int dim2=256)
{
  char command[30];
  int  returnvalue = 0;
  sprintf(command, "xv tmpImage_%05d.ppm &", _imagecounter);
  //cout << command<<endl;
  returnvalue = write_ppm_greylevel(image, dim1, dim2);
  
  if(returnvalue>0) system(command);
  
  return returnvalue;
}



int write_and_display_ppm_color(short *image, const int dim1=256, const int dim2=256)
{
  char command[30];
  int  returnvalue = 0;
  sprintf(command, "xv tmpImage_%05d.ppm &", _imagecounter);
  returnvalue = write_ppm_color(image, dim1, dim2);
  
  if(returnvalue>0) system(command);

  return returnvalue;
}

int write_and_display_ppm_color(float *image, const int dim1=256, const int dim2=256)
{
  char command[30];
  int  returnvalue = 0;
  sprintf(command, "xv tmpImage_%05d.ppm &", _imagecounter);

  returnvalue = write_ppm_color(image, dim1, dim2);
  
  if(returnvalue>0) system(command);
  
  return returnvalue;
}
