-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpgm.c
156 lines (126 loc) · 3.73 KB
/
pgm.c
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
147
148
149
150
151
152
153
154
155
156
#include "pgm.h"
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>
/* Create a new empty image with the given characteristics */
pgm_t *new_pgm_image(const int width, const int height, const int maxval)
{
pgm_t *image = malloc(sizeof(pgm_t));
assert(image);
image->width = width;
image->height = height;
image->maxval = maxval;
image->pixels = (unsigned char *) calloc(width * height, sizeof(unsigned char));
assert(image->pixels);
return image;
}
/* Fill an image with random pixels. width, height
and maxval fields should be initialized properly */
void rand_pgm_image(pgm_t *image)
{
for (int i = 0; i < image->width; i++) {
for (int j = 0; j < image->height; j++) {
image->pixels[i*image->width + j] = (unsigned char) rand() % image->maxval;
}
}
}
/* Check if comments exist where the fp is, if so move past them */
void skip_comments(FILE *file)
{
char c;
fscanf(file, " %c", &c);
if (c == '#') {
while (fgetc(file) != '\n');
}
else {
fseek(file, -1, SEEK_CUR);
}
}
/* Load an image from a file */
pgm_t *load_pgm_image(const char *filename)
{
FILE *file = fopen(filename, "rb");
assert(file);
char width_string[6], height_string[6], maxval_string[6];
int width, height, maxval;
char m1, m2;
/* Read image metadata */
skip_comments(file);
fscanf(file, "%c%c", &m1, &m2);
assert(m1 == 'P' && m2 == '5'); // Possible change: if m2 == 2: read ascii format
skip_comments(file);
fscanf(file, " %s", width_string);
width = atoi(width_string);
skip_comments(file);
fscanf(file, " %s", height_string);
height = atoi(height_string);
skip_comments(file);
fscanf(file, " %s", maxval_string);
maxval = atoi(maxval_string);
/* Create empty image */
pgm_t *image = new_pgm_image(width, height, maxval);
/* Read image content, ignore comments */
skip_comments(file);
fread(image->pixels, image->width * image->height, 1, file);
fclose(file);
return image;
}
/* Store an image to a file */
void store_pgm_image(const pgm_t *image, const char *filename)
{
/* Open File */
assert(image && image->pixels);
FILE *file = fopen(filename, "wb");
assert(file);
/* Write metadata */
fprintf(file, "P5\n");
fprintf(file, "%d %d\n%d\n", image->width, image->height, image->maxval);
/* Store the image content */
fwrite(image->pixels, image->width * image->height, 1, file);
fclose(file);
}
/* Create a white square at the center of the image */
void fill_pgm_image(pgm_t *image)
{
for (int i = 0; i < image->height; i++) {
for (int j = 0; j < image->width; j++) {
if (i > image->height/4 && i < image->height*3/4
&& j > image->width/4 && j < image->width*3/4)
{
image->pixels[i*image->width + j] = image->maxval;
}
else {
image->pixels[i*image->width + j] = 0;
}
}
}
}
/* Check to see if the filtered image is
an empty sqare at the center of the image*/
bool check_pgm_image(pgm_t *image)
{
for (int i = 0; i < image->height; i++) {
for (int j = 0; j < image->width; j++) {
bool is_in_square_i = (i == image->height/4 || i == image->height/4 + 1
|| i == image->height*3/4 || i == image->height*3/4 - 1)
&& (j >= image->width/4 && j <= image->width*3/4);
bool is_in_square_j = (j == image->height/4 || j == image->height/4 + 1
|| j == image->height*3/4 || j == image->height*3/4 - 1)
&& (i >= image->height/4 && i <= image->height*3/4);
if (is_in_square_i || is_in_square_j) {
printf("In square: %d %d -> %d\n", i, j, image->pixels[i*image->width + j]);
if (image->pixels[i*image->width + j] == 0) {
return false;
}
}
else {
printf("Out of square: %d %d -> %d\n", i, j, image->pixels[i*image->width + j]);
if (image->pixels[i*image->width + j] != 0) {
return false;
}
}
}
}
return true;
}