-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpgmformat.c
More file actions
146 lines (124 loc) · 5.38 KB
/
pgmformat.c
File metadata and controls
146 lines (124 loc) · 5.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
/* This code was written by Richard Zanibbi in May 1998
* based on code by Donald Quon and Hai Pham,
* and Dr. R. T. Whitaker of the University of Tennesee
* for use in Queen's University's CISC 859 course.
*
* These routines read PGM bitmaps (types P2 and P5)
* and write out PGM files in binary (P5) format.
* Note that lines in PGM files should be no longer than 70
* characters long.
*
* PGM files have a maximum value of 255 for each pixel (8 bit greyscale)
*
* NOTE:
* Width and height paramaters must appear on the same line separated by
* a space in column size - number of rows order.
*/
#include <stdio.h>
#include <stdlib.h>
#include "pgmformat.h"
/* INPUT: a filename (char*),row and column dimension variables (long), and
* a pointer to a 2D array of unsigned char's of size MAXROWS x MAXCOLS
* (row major).
* OUTPUT: an integer is returned indicating whether or not the
* file was read into memory (in row major order). 1 is returned if the
* file is read correctly, 0 if it is not. If there are
* too few pixels, the function still returns 1, but returns an error
* message. Error messages are also returned if a file cannot be open,
* or if the specifications of the file are invalid.
* NOTE: The case where too many pixels are in a file is not detected.
*/
int pgmRead (char *fileName, struct PgmType* pgm) {
FILE *filePointer; /* for file buffer */
char line[MAXLENGTH]; /* for character input from file */
int maximumValue = 0; /* max value from header */
int binary; /* flag to indicate if file is binary (P5)*/
long numberRead = 0; /* counter for number of pixels read */
/* Open the file, return an error if necessary. */
if ((filePointer = fopen(fileName,"r")) == NULL) {
printf ("ERROR: cannot open file\n\n");
fclose (filePointer);
return (0);
}
/* Initialize columnsidth, and height */
pgm->height = 0;
pgm->width = 0;
/* Check the file signature ("Magic Numbers" P2 and P5); skip comments
* and blank lines (CR with no spaces before it).*/
fgets (line,MAXLENGTH,filePointer);
while (line[0]=='#' || line[0]=='\n') fgets (line,MAXLENGTH,filePointer);
if (line[0]=='P' && (line[1]=='5')) {
binary = 1;
sscanf (line+2,"%d %d %d",&(pgm->width),&(pgm->height), &maximumValue);
/* printf ("\nFORMAT: P5\n"); */
}
else {
printf ("ERROR: incorrect file format\n\n");
fclose (filePointer);
return (0);
}
if ((pgm->width)<1 ||(pgm->height)<1 || maximumValue<0 || maximumValue>MAXVALUE){
printf ("ERROR: invalid file specifications (cols/rows/max value)\n\n");
printf ("%d %d %d\n", pgm->width, pgm->height, maximumValue);
fclose (filePointer);
return (0);
}
else if ((pgm->width) > MAXCOLS || (pgm->height) > MAXROWS) {
printf ("ERROR: increase MAXROWS/MAXCOLS in PGM.h");
fclose (filePointer);
return (0);
}
int bufferSize = pgm->width * pgm->height;
pgm->bytes = malloc(bufferSize);
numberRead = fread(pgm->bytes, 1, bufferSize, filePointer);
if (numberRead < bufferSize) {
printf ("ERROR: fewer pixels than rows*cols indicates\n\n");
printf ("Leu %d\n", numberRead);
return 0;
}
/* close the file and return 1 indicating success */
fclose (filePointer);
return (1);
}
/* INPUT: a filename (char*), the dimensions of the pixmap (rows,cols of
* type long), and a pointer to a 2D array (MAXROWS x MAXCOLS) in row
* major order.
* OUTPUT: an integer is returned indicating if the desired file was written
* (in P5 PGM format (binary)). A 1 is returned if the write was completed
* and 0 if it was not. An error message is returned if the file is not
* properly opened.
*/
int pgmWrite(char* filename, long rows,long cols,
unsigned char image[MAXROWS][MAXCOLS],char* comment_string) {
FILE* file; /* pointer to the file buffer */
int maxval; /* maximum value in the image array */
long nwritten = 0; /* counter for the number of pixels written */
long i,j; /* for loop counters */
/* return 0 if the dimensions are larger than the image array. */
if (rows > MAXROWS || cols > MAXCOLS) {
printf ("ERROR: row/col specifications larger than image array:\n");
return (0);
}
/* open the file; write header and comments specified by the user. */
if ((file = fopen(filename, "w")) == NULL) {
printf("ERROR: file open failed\n");
return(0);
}
fprintf(file,"P5\n");
if (comment_string != NULL) fprintf(file,"# %s \n", comment_string);
/* write the dimensions of the image */
fprintf(file,"%ld %ld \n", cols, rows);
/* NOTE: MAXIMUM VALUE IS WHITE; COLOURS ARE SCALED FROM 0 - */
/* MAXVALUE IN A .PGM FILE. */
/* WRITE MAXIMUM VALUE TO FILE */
fprintf(file, "%d\n", (int)255);
/* Write data */
for (i=0; i < rows; i++) {
nwritten += fwrite((void*)&(image[i][0]),sizeof(unsigned char),
cols, file);
}
/* printf ("\nNumber of pixels total(from rows*cols): %ld\n",rows*cols); */
/* printf ("Number of pixels written: %ld\n\n",nwritten); */
fclose(file);
return(1);
}