Skip to content

Instantly share code, notes, and snippets.

@PatrickSchiffmann
Last active November 10, 2015 05:49
Show Gist options
  • Save PatrickSchiffmann/207fc1ce91bab85193fc to your computer and use it in GitHub Desktop.
Save PatrickSchiffmann/207fc1ce91bab85193fc to your computer and use it in GitHub Desktop.
Version of pgmio.c that works with dynamic arrays from arralloc.c
/* Revised to be readable code and behave as a normal person would expect
* when working with dynamic arrays from arralloc.c
* s1563256, 10.11.2015
*/
/*
* This file contains C routines for the MPI Casestudy.
*
* To access these routines, add the following to your program:
*
* #include "pgmio2.h"
*
* Note: you MUST link with the maths library -lm to access fabs etc.
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "pgmio2.h"
#define MAXLINE 128
/*
* Routine to get the size of a PGM data file
*
* Note that this assumes a single line comment and no other white space.
*/
void pgmsize(char *filename, int *width, int *height) {
FILE *fp;
char dummy[MAXLINE];
int n = MAXLINE;
if (NULL == (fp = fopen(filename,"r"))) {
fprintf(stderr, "pgmsize: cannot open <%s>\n", filename);
exit(-1);
}
// Ignore the first two lines
fgets(dummy, n, fp);
fgets(dummy, n, fp);
// Read dimensions
fscanf(fp,"%d %d", width, height);
fclose(fp);
}
// Reads .pgm to a 2D floating point array.
// E.g. to float** arr = arralloc(sizeof(float), 2, height, width)
// The array must be dynamically allocated (use pointers for indexing).
// Note that this assumes a single line comment and no other white space.
void pgmread(char *filename, float **data, int width, int height) {
FILE *fp;
int width_read, height_read;
int i, j;
char dummy[MAXLINE];
if (NULL == (fp = fopen(filename,"r"))) {
fprintf(stderr, "pgmread: cannot open <%s>\n", filename);
exit(-1);
}
// Ignore first two lines
fgets(dummy, MAXLINE, fp);
fgets(dummy, MAXLINE, fp);
// Read dimensions
fscanf(fp,"%d %d",&width_read, &height_read);
// If dimensions not as expected, exit
if ( width != width_read || height != height_read) {
fprintf(stderr,
"pgmread: size mismatch, (width,ny) = (%d,%d) expected (%d,%d)\n",
width_read, height_read, width, height);
exit(-1);
}
// Read max value and ignore
fscanf(fp,"%d",&i);
// Read pixel values into array
for (i = 0; i < height; i++)
for (j=0; j < width; j++)
fscanf(fp,"%f", &data[i][j]);
fclose(fp);
}
// Writes .pgm from a 2D floating point array.
// E.g. from float** arr = arralloc(sizeof(float), 2, height, width)
// The array must be dynamically allocated (use pointers for indexing).
void pgmwrite(char *filename, float **data, int width, int height) {
FILE *fp;
int i, j, grey;
float xmin, xmax;
float maxval = 255.0;
if (NULL == (fp = fopen(filename,"w"))) {
fprintf(stderr, "pgmwrite: cannot create <%s>\n", filename);
exit(-1);
}
printf("Writing %d x %d picture into file: %s\n", width, height, filename);
// Find the max and min absolute values of the array
find_extrema(data, width, height, &xmin, &xmax);
fprintf(fp, "P2\n");
fprintf(fp, "# Written by pgmio::pgmwrite\n");
fprintf(fp, "%d %d\n", width, height);
fprintf(fp, "%d\n", (int) maxval);
for (i = 0; i < height; i++) {
for (j = 0; j < width; j++) {
grey = maxval * ((fabs(data[i][j])-xmin)/(xmax-xmin))+0.5;
fprintf(fp, "%3d ", grey);
// Ensure line length < 70. 16 * 4 characters= 64. %3d prints padded to 3 chars.
if ( (i * width + j) % 16 == 0)
fprintf(fp, "\n");
}
}
fclose(fp);
}
// Helper functions. Find min and max in 2D array.
void find_extrema(float **data, int width, int height, float *min, float *max) {
float xmin = fabs(data[0][0]);
float xmax = fabs(data[0][0]);
for (int i=0; i<height; i++) {
for (int j=0; j<width; j++) {
if (fabs(data[i][j]) < xmin)
xmin = fabs(data[i][j]);
if (fabs(data[i][j]) > xmax)
xmax = fabs(data[i][j]);
}
}
if (xmin == xmax)
xmin = xmax-1.0;
*min = xmin;
*max = xmax;
}
void pgmsize (char *filename, int *nx, int *ny);
void pgmread (char *filename, float **vx, int nx, int ny);
void pgmwrite(char *filename, float **vx, int nx, int ny);
void find_extrema(float **, int, int, float*, float*);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment