Exemplo n.º 1
0
static void
getOrFakeAndMap(const char *      const andPgmFname,
                int               const xorCols,
                int               const xorRows,
                gray ***          const andPGMarrayP,
                pixval *          const andMaxvalP,
                colorhash_table * const andChtP,
                const char **     const errorP) {

    int andRows, andCols;
    
    if (!andPgmFname) {
        /* He's not supplying a bitmap for 'and'.  Fake the bitmap. */
        *andPGMarrayP = NULL;
        *andMaxvalP   = 1;
        *andChtP      = NULL;
        *errorP       = NULL;
    } else {
        FILE * andfile;
        andfile = pm_openr(andPgmFname);
        *andPGMarrayP = pgm_readpgm(andfile, &andCols, &andRows, andMaxvalP);
        pm_close(andfile);

        if ((andCols != xorCols) || (andRows != xorRows)) {
            asprintfN(errorP,
                      "And mask and image have different dimensions "
                     "(%d x %d vs %d x %d).  Aborting.",
                     andCols, xorCols, andRows, xorRows);
        } else
            *errorP = NULL;
    }
}
Exemplo n.º 2
0
/** return data */
const void *GeoImage::data()
{
  if (data_)
    return (void *) data_;
  qDebug("GeoImage::data() - load data");
  QString fname = filename();
  qDebug("GeoImage::data() %s", fname.toLatin1().constData());

  FILE *fp;
  fp = fopen(fname.toLatin1().constData(), "r");
  if (!fp) {
    qDebug("#  (ERROR)GeoImage::load(%s) Can't open file for reading!",
           fname.toLatin1().constData());
    return 0;
  }
  int cols, rows;
  //float minval, maxval;
  switch (type_) {
  case PFM_FLOAT:
  case PFM_UINT:
  case PFM_SINT:
  case PFM_SINT16:
  case PFM_UINT16:
  case PFM_BYTE:
  case PFM_3BYTE:
    data_ = pfm_readpfm_type(fp, &cols, &rows, &minval_, &maxval_, type_, 0);
    testSize(cols, rows, type_);
    break;
  case PBM:
    data_ = (void *) pbm_readpbm(fp, &cols, &rows);
    minval_ = 0.0, maxval_ = 1.0;
    testSize(cols, rows, type_);
    break;
  case PGM:{
      gray maxval, **data_g;
      data_g = pgm_readpgm(fp, &cols, &rows, &maxval);
      data_ = (void *) data_g;
      minval_ = 0.0, maxval_ = (float) maxval;
      testSize(cols, rows, type_);
    }
    break;
  case PPM:
    pixval maxval;
    pixel **dat_p;
    dat_p = ppm_readppm(fp, &cols, &rows, &maxval);
    data_ = (void *) dat_p;
    minval_ = 0.0, maxval_ = (float) maxval;
    testSize(cols, rows, type_);
    break;
  default:
    qDebug("Unknown type %d",type_);
    fclose(fp);
    return 0;
  }
  fclose(fp);
  if (data_) dataSize_=rows_*cols_*sizeOfData(type_);
  cache_.useImage(this);
  return data_;
}
Exemplo n.º 3
0
static void
readAlpha(const char filespec[], gray *** const alphaP,
          int const cols, int const rows, pixval * const alphamaxvalP) {

    FILE * alpha_file;
    int alphacols, alpharows;
        
    alpha_file = pm_openr(filespec);
    *alphaP = pgm_readpgm(alpha_file, &alphacols, &alpharows, alphamaxvalP);
    pm_close(alpha_file);
    
    if (cols != alphacols || rows != alpharows)
        pm_error("Alpha mask is not the same dimensions as the "
                 "image.  Image is %d by %d, while mask is %d x %d.",
                 cols, rows, alphacols, alpharows);
}
Exemplo n.º 4
0
pnm_image_t *pnm_image_pgmRead(pnm_image_t *image, FILE *fp)
{
  gray **pixels;
  int  cols, rows;
  gray maxval;
  int i,j;

  pixels = pgm_readpgm(fp, &cols, &rows, &maxval);

  image = pnm_image_alloc(image, 1, cols, rows);
  image->maxval = maxval;
  for (i=0; i < rows; i++) 
    for (j=0; j < cols; j++) 
      image->pixels[0][i][j] = (pnm_pixval) pixels[i][j];
  
  return (image);
}
Exemplo n.º 5
0
    std::unique_ptr<Image> loadPGMImage(const char* filepath)
    {
        FILE* fp = fopen(filepath, "rb");
        if (!fp)
        {
            printf("error loading file %s at loadPGMImage()\n", filepath);
            return std::unique_ptr<Image>();
        }

        int img_w, img_h;
        gray max_pval;
        gray** pixels = pgm_readpgm(fp, &img_w, &img_h, &max_pval);
        if (!pixels)
        {
            printf("error reading image from file %s at loadPGMImage()\n", filepath);
            fclose(fp);
            return std::unique_ptr<Image>();
        }

        auto img_ptr = std::make_unique<Image>(img_w, img_h, 3);

        for (int y = 0; y < img_h; y++)
        {
            for (int x = 0; x < img_w; x++)
            {
                (img_ptr->getValues(0))[y * img_w + x] = static_cast<float>(pixels[y][x])
                        / max_pval;
                (img_ptr->getValues(1))[y * img_w + x] = static_cast<float>(pixels[y][x])
                        / max_pval;
                (img_ptr->getValues(2))[y * img_w + x] = static_cast<float>(pixels[y][x])
                        / max_pval;
            }
        }

        ppm_freearray(pixels, img_h);
        fclose(fp);
        return img_ptr;
    }
Exemplo n.º 6
0
int main(int argc, char *argv[])
{

  int saca_pgm();
  FILE *fd;
  FILE *fd1;
 

  int cols, rows, i, j, bucle, carpeta, nresultados;
  
  float carac[11];
  gray   maxval;
  gray **imagen;
  gray **imagen1;

  struct dirent **resultados=NULL;

  // inicializamos todas las variables
  pgm_init(&argc, argv);
  nresultados=0;

  printf("Haciendo magia...\n");

  fd = fopen(filepatron, "r");

  if (fd == NULL ) {
    pm_error("error: no puedo abrir los ficheros");
    exit(-1);
  }
  imagen = pgm_readpgm(fd, &cols, &rows, &maxval);

  if (imgpatron == NULL ) {
    pm_error("error: no puedo leer las imagenes");
    exit(-1);
  }

 // abrimos el fichero de imagen en modo lectura
    fd1 = fopen(argv[1], "r");

    if (fd1 == NULL ) {
      pm_error("error: no puedo abrir los ficheros");
      exit(-1);
    }

    // leemos la imagen
    imagen1 = pgm_readpgm(fd1, &cols, &rows, &maxval);

    if (imagen == NULL ) {
      pm_error("error: no puedo leer las imagenes");
      exit(-1);
    }

    //*******************************************************************//
    //en 'imagen' tenemos la foto a analizar para el fichero clasificador//
    //*******************************************************************//

    for(i=0; i<rows;i++){
      for(j=0; j<cols; j++){
        //Retiramos fondo por division
        imagen[i][j] = MIN(255, 255*((float)imagen[i][j]/(float)imgpatron[i][j]) );
	//Aplicamos umbral
	if(imagen[i][j] <= 210)
		imagen[i][j] = 0;
	else
		imagen[i][j] = 255;
       }
	
    }
    // <----- falta erosionar y dilatar!!!
	
	/* dilate */
	pgm_dilate(imagen, cols, rows, 2);
	/* erode */
	pgm_erode(imagen, cols, rows, 2);
 
	pgm_writepgm(stdout, imagen, cols, rows, 255, 0);
 	
fclose(fd);
    //Liberamos la memoria de la imagen, para cargar otra
    pgm_freearray(imagen, rows);
	
 printf("Fin de la magia...\n");
  fclose(patron);
  exit(0);

}
Exemplo n.º 7
0
int main (int argc, char * argv[])
{
  int c = 0;
  gboolean verbose = FALSE;
  GtsSurface * s;
  CostFunc cost_func = (CostFunc) height_cost;
  gpointer cost_data = NULL;
  GtsStopFunc stop_func = NULL;
  gpointer stop_data = NULL;
  StopOptions stop = NUMBER;
  guint number = 0;
  gdouble cmin = 0.0;
  gboolean logcost = FALSE;
  gboolean flat = FALSE;
  gdouble relative = 0.;
  gboolean keep_enclosing = FALSE;
  gboolean closed = FALSE;

  if (!setlocale (LC_ALL, "POSIX"))
    g_warning ("cannot set locale to POSIX");

  while (c != EOF) {
#ifdef HAVE_GETOPT_LONG
    static struct option long_options[] = {
      {"closed", no_argument, NULL, 'C'},
      {"keep", no_argument, NULL, 'k'},
      {"relative", required_argument, NULL, 'r'},
      {"flat", no_argument, NULL, 'f'},
      {"log", no_argument, NULL, 'l'},
      {"number", required_argument, NULL, 'n'},
      {"cost", required_argument, NULL, 'c'},
      {"help", no_argument, NULL, 'h'},
      {"verbose", no_argument, NULL, 'v'},
      { NULL }
    };
    int option_index = 0;
    switch ((c = getopt_long (argc, argv, "hvn:c:lfr:kC",
			      long_options, &option_index))) {
#else /* not HAVE_GETOPT_LONG */
    switch ((c = getopt (argc, argv, "hvn:c:lfr:kC"))) {
#endif /* not HAVE_GETOPT_LONG */
    case 'C': /* closed */
      closed = TRUE;
      keep_enclosing = TRUE;
      break;
    case 'k': /* keep */
      keep_enclosing = TRUE;
      break;
    case 'r': /* relative */
      cost_func = (CostFunc) relative_height_cost;
      relative = strtod (optarg, NULL);
      cost_data = &relative;
      if (relative <= 0.) {
	fprintf (stderr, "happrox: argument for -r option must be strictly positive\n");
	return 1;
      }
      break;
    case 'f': /* flat file */
      flat = TRUE;
      break;
    case 'l': /* log cost */
      logcost = TRUE;
      break;
    case 'n': /* stop by number */
      stop = NUMBER;
      number = strtol (optarg, NULL, 0);
      break;
    case 'c': /* stop by cost */
      stop = COST;
      cmin = strtod (optarg, NULL);
      break;
    case 'h': /* help */
      fprintf (stderr,
	       "Usage: happrox [OPTION]... < [input.pgm|input] > output.gts\n"
	       "Returns a simplified triangulation of a set of points using\n"
	       "algorithm III of Garland and Heckbert (1995).\n"
	       "\n"
	       "  -n N, --number=N    stop the refinement process if the number of\n"
	       "                      vertices is larger than N\n"
	       "  -c C, --cost=C      stop the refinement process if the cost of insertion\n"
	       "                      of a vertex is smaller than C\n"
	       "  -f    --flat        input is a flat file with three x,y,z columns\n"
	       "                        (default is PGM file)\n"
               "  -r Z  --relative=Z  use relative height cost for all heights larger than Z\n"
	       "  -k    --keep        keep enclosing triangle\n"
	       "  -C    --closed      close the surface\n"
	       "  -l    --log         log evolution of cost\n" 
	       "  -v,   --verbose     display surface statistics\n"
	       "  -h,   --help        display this help and exit\n"
	       "\n"
	       "Report bugs to %s\n",
	       GTS_MAINTAINER);
      return 0;
      break;
    case 'v':
      verbose = TRUE;
      break;
    case '?': /* wrong options */
      fprintf (stderr, "Try `happrox --help' for more information.\n");
      return 1;
    }
  }

  switch (stop) {
  case NUMBER:
    if (verbose)
      stop_func = (GtsStopFunc) stop_number_verbose;
    else
      stop_func = (GtsStopFunc) stop_number;
    if (logcost)
      stop_func = (GtsStopFunc) stop_number_log_cost;
    stop_data = &number;
    break;
  case COST:
    if (verbose)
      stop_func = (GtsStopFunc) stop_cost_verbose;
    else
      stop_func = (GtsStopFunc) stop_cost; 
    stop_data = &cmin;
    break;
  default:
    g_assert_not_reached ();
  }

  if (flat) {
    GSList * points = NULL;
    guint n = 0;
    gdouble x, y, z;

    while (scanf ("%lf %lf %lf", &x, &y, &z) == 3) {
      points = g_slist_prepend (points, gts_vertex_new (gts_vertex_class (), x, y, z));
      n++;
    }
    if (verbose)
      fprintf (stderr, "happrox: %d vertices\n", n);

    s = happrox_list (points, keep_enclosing, closed, cost_func, cost_data, stop_func, stop_data);
  }
  else {
    gint width, height;
    gray ** g, maxgray;

    g = pgm_readpgm (stdin, &width, &height, &maxgray);
    if (verbose)
      fprintf (stderr, "happrox: width: %d height: %d maxgray: %d\n",
	       width, height, maxgray);
    
    s = happrox (g, width, height, cost_func, cost_data, stop_func, stop_data);
  }

  if (verbose) {
    fputc ('\n', stderr);
    gts_surface_print_stats (s, stderr);
  }
  gts_surface_write (s, stdout);

  return 0;
}
Exemplo n.º 8
0
int
main (int argc, const char ** argv) {

    FILE * ifP;
    gray ** grays;
    unsigned int tone[PGM_MAXMAXVAL+1];
    unsigned int r0, r45, r90;
    unsigned int d;
    unsigned int x, y;
    unsigned int row;
    int rows, cols;
    int argn;
    unsigned int itone;
    unsigned int toneCt;
    float ** p_matrix0, ** p_matrix45, ** p_matrix90, ** p_matrix135;
    float a2m[4], contrast[4], corr[4], var[4], idm[4], savg[4];
    float sentropy[4], svar[4], entropy[4], dvar[4], dentropy[4];
    float icorr[4], maxcorr[4];
    gray maxval;
    unsigned int i;
    const char * const usage = "[-d <d>] [pgmfile]";

    pm_proginit(&argc, argv);

    argn = 1;

    /* Check for flags. */
    if ( argn < argc && argv[argn][0] == '-' )
    {
        if ( argv[argn][1] == 'd' )
        {
            ++argn;
            if ( argn == argc || sscanf( argv[argn], "%u", &d ) != 1 )
                pm_usage( usage );
        }
        else
            pm_usage( usage );
        ++argn;
    }

    if ( argn < argc )
    {
        ifP = pm_openr( argv[argn] );
        ++argn;
    }
    else
        ifP = stdin;

    if ( argn != argc )
        pm_usage( usage );

    d = 1;

    grays = pgm_readpgm(ifP, &cols, &rows, &maxval);
    pm_close (ifP);

    /* Determine the number of different gray scales (not maxval) */
    for (i = 0; i <= PGM_MAXMAXVAL; ++i)
        tone[i] = -1;
    for (row = 0; row < rows; ++row) {
        unsigned int col;
        for (col = 0; col < cols; ++col)
            tone[grays[row][col]] = grays[row][col];
    }
    for (i = 0, toneCt = 0; i <= PGM_MAXMAXVAL; ++i) {
        if (tone[i] != -1)
            ++toneCt;
    }
    pm_message("(Image has %u gray levels.)", toneCt);

    /* Collapse array, taking out all zero values */
    for (row = 0, itone = 0; row <= PGM_MAXMAXVAL; ++row)
        if (tone[row] != -1)
            tone[itone++] = tone[row];
    /* Now array contains only the gray levels present (in ascending order) */

    /* Allocate memory for gray-tone spatial dependence matrix */
    p_matrix0   = matrix (0, toneCt, 0, toneCt);
    p_matrix45  = matrix (0, toneCt, 0, toneCt);
    p_matrix90  = matrix (0, toneCt, 0, toneCt);
    p_matrix135 = matrix (0, toneCt, 0, toneCt);

    for (row = 0; row < toneCt; ++row) {
        unsigned int col;
        for (col = 0; col < toneCt; ++col) {
            p_matrix0 [row][col] = p_matrix45 [row][col] = 0;
            p_matrix90[row][col] = p_matrix135[row][col] = 0;
        }
    }
    if (d > cols)
        pm_error("Image is narrower (%u columns) "
                 "than specified distance (%u)", cols, d);

    /* Find gray-tone spatial dependence matrix */
    pm_message("Computing spatial dependence matrix...");
    for (row = 0; row < rows; ++row) {
        unsigned int col;
        for (col = 0; col < cols; ++col) {
            unsigned int angle;
            for (angle = 0, x = 0; angle <= 135; angle += 45) {
                while (tone[x] != grays[row][col])
                    ++x;
                if (angle == 0 && col + d < cols) {
                    y = 0;
                    while (tone[y] != grays[row][col + d])
                        ++y;
                    ++p_matrix0[x][y];
                    ++p_matrix0[y][x];
                }
                if (angle == 90 && row + d < rows) {
                    y = 0;
                    while (tone[y] != grays[row + d][col])
                        ++y;
                    ++p_matrix90[x][y];
                    ++p_matrix90[y][x];
                }
                if (angle == 45 && row + d < rows && col >= d) {
                    y = 0;
                    while (tone[y] != grays[row + d][col - d])
                        ++y;
                    ++p_matrix45[x][y];
                    ++p_matrix45[y][x];
                }
                if (angle == 135 && row + d < rows && col + d < cols) {
                    y = 0;
                    while (tone[y] != grays[row + d][col + d])
                        ++y;
                    ++p_matrix135[x][y];
                    ++p_matrix135[y][x];
                }
            }
        }
    }
    /* Gray-tone spatial dependence matrices are complete */

    /* Find normalizing constants */
    r0  = 2 * rows * (cols - d);
    r45 = 2 * (rows - d) * (cols - d);
    r90 = 2 * (rows - d) * cols;

    /* Normalize gray-tone spatial dependence matrix */
    for (itone = 0; itone < toneCt; ++itone) {
        unsigned int jtone;
        for (jtone = 0; jtone < toneCt; ++jtone) {
            p_matrix0[itone][jtone]   /= r0;
            p_matrix45[itone][jtone]  /= r45;
            p_matrix90[itone][jtone]  /= r90;
            p_matrix135[itone][jtone] /= r45;
        }
    }
    pm_message(" ...done.");

    pm_message("Computing textural features ...");

    fprintf(stdout, "\n");
    fprintf(stdout,
            "%s         0         45         90        135        Avg\n",
            BL);

    a2m[0] = f1_a2m(p_matrix0,   toneCt);
    a2m[1] = f1_a2m(p_matrix45,  toneCt);
    a2m[2] = f1_a2m(p_matrix90,  toneCt);
    a2m[3] = f1_a2m(p_matrix135, toneCt);
    results(F1, a2m);

    contrast[0] = f2_contrast(p_matrix0,   toneCt);
    contrast[1] = f2_contrast(p_matrix45,  toneCt);
    contrast[2] = f2_contrast(p_matrix90,  toneCt);
    contrast[3] = f2_contrast(p_matrix135, toneCt);
    results(F2, contrast);


    corr[0] = f3_corr(p_matrix0,   toneCt);
    corr[1] = f3_corr(p_matrix45,  toneCt);
    corr[2] = f3_corr(p_matrix90,  toneCt);
    corr[3] = f3_corr(p_matrix135, toneCt);
    results(F3, corr);

    var[0] = f4_var(p_matrix0,   toneCt);
    var[1] = f4_var(p_matrix45,  toneCt);
    var[2] = f4_var(p_matrix90,  toneCt);
    var[3] = f4_var(p_matrix135, toneCt);
    results(F4, var);


    idm[0] = f5_idm(p_matrix0,   toneCt);
    idm[1] = f5_idm(p_matrix45,  toneCt);
    idm[2] = f5_idm(p_matrix90,  toneCt);
    idm[3] = f5_idm(p_matrix135, toneCt);
    results(F5, idm);

    savg[0] = f6_savg(p_matrix0,  toneCt);
    savg[1] = f6_savg(p_matrix45,  toneCt);
    savg[2] = f6_savg(p_matrix90,  toneCt);
    savg[3] = f6_savg(p_matrix135, toneCt);
    results(F6, savg);

    svar[0] = f7_svar(p_matrix0,   toneCt, savg[0]);
    svar[1] = f7_svar(p_matrix45,  toneCt, savg[1]);
    svar[2] = f7_svar(p_matrix90,  toneCt, savg[2]);
    svar[3] = f7_svar(p_matrix135, toneCt, savg[3]);
    results(F7, svar);

    sentropy[0] = f8_sentropy(p_matrix0,   toneCt);
    sentropy[1] = f8_sentropy(p_matrix45,  toneCt);
    sentropy[2] = f8_sentropy(p_matrix90,  toneCt);
    sentropy[3] = f8_sentropy(p_matrix135, toneCt);
    results(F8, sentropy);

    entropy[0] = f9_entropy(p_matrix0,   toneCt);
    entropy[1] = f9_entropy(p_matrix45,  toneCt);
    entropy[2] = f9_entropy(p_matrix90,  toneCt);
    entropy[3] = f9_entropy(p_matrix135, toneCt);
    results(F9, entropy);

    dvar[0] = f10_dvar(p_matrix0,   toneCt);
    dvar[1] = f10_dvar(p_matrix45,  toneCt);
    dvar[2] = f10_dvar(p_matrix90,  toneCt);
    dvar[3] = f10_dvar(p_matrix135, toneCt);
    results(F10, dvar);

    dentropy[0] = f11_dentropy(p_matrix0,   toneCt);
    dentropy[1] = f11_dentropy(p_matrix45,  toneCt);
    dentropy[2] = f11_dentropy(p_matrix90,  toneCt);
    dentropy[3] = f11_dentropy(p_matrix135, toneCt);
    results (F11, dentropy);

    icorr[0] = f12_icorr(p_matrix0,   toneCt);
    icorr[1] = f12_icorr(p_matrix45,  toneCt);
    icorr[2] = f12_icorr(p_matrix90,  toneCt);
    icorr[3] = f12_icorr(p_matrix135, toneCt);
    results(F12, icorr);

    icorr[0] = f13_icorr(p_matrix0,   toneCt);
    icorr[1] = f13_icorr(p_matrix45,  toneCt);
    icorr[2] = f13_icorr(p_matrix90,  toneCt);
    icorr[3] = f13_icorr(p_matrix135, toneCt);
    results(F13, icorr);

    maxcorr[0] = f14_maxcorr(p_matrix0,   toneCt);
    maxcorr[1] = f14_maxcorr(p_matrix45,  toneCt);
    maxcorr[2] = f14_maxcorr(p_matrix90,  toneCt);
    maxcorr[3] = f14_maxcorr(p_matrix135, toneCt);
    results(F14, maxcorr);

    pm_message(" ...done.");

    return 0;
}
Exemplo n.º 9
0
int main(int argc, char *argv[]) {
    FILE *fp, *fp_out;
    gray maxval;
    int format;
    int width = 0;
    int height = 0;
    int i, j;
    gray **pgm_data;
    int threshold = 127;
    
    int c;
    extern char *optarg;
    extern int optind;

    while((c = getopt(argc, argv, "t:")) != EOF) {
        switch( c ) {
            case 't':
                sscanf(optarg, "%d", &threshold);
                break;
		}
	}

//    printf("argc: %d\n", argc);
//    printf("optind: %d\n", optind);
//    printf("threshold: %d\n", threshold);

    // optind -- index in argv of the first argv-element that is not an option
    if((argc - optind) != 2) {
        fprintf(stderr, "Usage error\n");
        fprintf(stderr, "Usage: %s <input image> <output image>\n", argv[0]);
        fprintf(stderr, "Option:\n");
        fprintf(stderr, "-t <threshold>\n");

        exit(1);
    }

    // all PGM programs must call pgm_init() just after invocation, 
    // before they process their arguments.
    pgm_init(&argc, argv);

    // PBM function for reading, which is almost equivalent 
    // to f = fopen(filename, "rb");
    fp = pm_openr(argv[optind]);

    // read the PGM image header
    pgm_readpgminit(fp, &width, &height, &maxval, &format);

    printf("Succesfully read the header!\n\n");
    printf("= PGM image information =\n");
    printf("Width: %d\n", width);
    printf("Height: %d\n", height);
    printf("Max color: %d\n", maxval);
//    printf("Format: %c\n\n", PGM_FORMAT_TYPE(format));

    // close then open file again for reading data
    fclose(fp);
    fp = pm_openr(argv[optind]);
    
    pgm_data = pgm_readpgm(fp, &width, &height, &maxval);
    
    printf("Succesfully get the PGM image data!\n\n");

    tImage img;
    img.width = width;
    img.height = height;
    img.pixelType = GRAY8;
    img.pPixel = (UCHAR *)malloc(width * height * sizeof(UCHAR));

    // copy data to our format
    for(i = 0; i < height; i++) {
        for(j = 0; j < width; j++) {
            img.pPixel[i * width + j] = pgm_data[i][j];
        }
    }

    img = binarize(img, threshold);

    // convert back to the pgm format
    for(i = 0; i < height; i++) {
        for(j = 0; j < width; j++) {
            pgm_data[i][j] = img.pPixel[i * width + j];
        }
    }

    fp_out = pm_openw(argv[optind + 1]);

    // forceplain is a logical value that tells pgm_writepgminit() to 
    // write a header for a plain PGM format file, as opposed to a raw 
    // PGM format file.
    // 1 -> not a binary format
    int forceplain = 0;
    pgm_writepgm(fp_out, pgm_data, width, height, maxval, forceplain);
    
    printf("Succesfully write the binarized PGM image to disk!\n\n");

    free(img.pPixel);
    fclose(fp);
    fclose(fp_out);

    return 1;
}