Skip to content

Commit ad56cb8

Browse files
committed
Complete pa07
1 parent 7791031 commit ad56cb8

File tree

2 files changed

+133
-29
lines changed

2 files changed

+133
-29
lines changed

pa07/Makefile

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
GCCFLAGS=-Wall -Wshadow -g
2+
3+
all: diff-plus
4+
gcc $(GCCFLAGS) answer07.c main.c image-bmp.c -o main
5+
6+
diff-plus:
7+
gcc $(GCCFLAGS) diff-plus.c -o diff-plus

pa07/answer07.c

+126-29
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@
2222
#include "answer07.h"
2323
#include <stdlib.h>
2424
#include <stdio.h>
25+
#include <string.h>
26+
27+
#define TRUE 1
28+
#define FALSE 0
2529

2630
/**
2731
* Loads an ECE264 image file, returning an Image structure.
@@ -30,57 +34,91 @@
3034
* Hint: Please see the README for extensive hints
3135
*/
3236
Image * Image_load(const char * filename) {
33-
FILE * fp;
37+
FILE * fp = NULL;
3438
ImageHeader header;
35-
Image image;
39+
Image * image = NULL;
40+
41+
void _teardown() {
42+
if(image) {
43+
Image_free(image);
44+
image = NULL;
45+
}
46+
fclose(fp);
47+
}
3648

3749
// Open file for reading
38-
fp = fopen(filename, "r");
50+
fp = fopen(filename, "rb");
3951
if(!fp) {
40-
fprintf(stderr, "Cannot open file '%s' for reading.", filename);
41-
return NULL;
52+
fprintf(stderr, "Cannot open file '%s' for reading.\n", filename);
53+
return image;
4254
}
4355

4456
// Read the header
4557
if(fread(&header, sizeof(ImageHeader), 1, fp) != 1) {
46-
fprintf(stderr, "Unable to read header.");
47-
return NULL;
58+
fprintf(stderr, "Unable to read header.\n");
59+
_teardown();
60+
return image;
4861
}
4962

5063
// Check the header's validity
5164
if(header.magic_number != ECE264_IMAGE_MAGIC_NUMBER) {
52-
fprintf(stderr, "Magic number in header does not match.");
53-
return NULL;
65+
fprintf(stderr, "Magic number in header does not match.\n");
66+
_teardown();
67+
return image;
5468
}
5569

5670
// Check width and height
5771
if(header.width <= 0 || header.height <= 0) {
58-
fprintf(stderr, "Image file is not of valid width or height.");
59-
return NULL;
72+
fprintf(stderr, "Image file is not of valid width or height.\n");
73+
_teardown();
74+
return image;
6075
}
6176

6277
// Validate comment
63-
if(header.comment_len < 1) {
64-
fprintf(stderr, "Comment length in header is invalid.");
65-
return NULL;
78+
if(header.comment_len < 1 || header.comment_len > 1024) {
79+
fprintf(stderr, "Comment length in header is invalid.\n");
80+
_teardown();
81+
return image;
82+
}
83+
84+
// Allocate space for image
85+
if(!((image = malloc(sizeof(Image)))
86+
&& (image->comment = malloc(header.comment_len * sizeof(char)))
87+
&& (image->data = malloc(header.width * header.height * sizeof(uint8_t)))
88+
)) {
89+
fprintf(stderr, "Cannot allocate space for image.\n");
90+
_teardown();
91+
return image;
6692
}
6793

94+
// Set width and height
95+
image->width = header.width;
96+
image->height = header.height;
97+
6898
// Read the comment
69-
image.comment = malloc(header.comment_len * sizeof(char));
70-
if(fread(image.comment, header.comment_len, 1, fp) != 1) {
71-
fprintf(stderr, "Cannot read comment.");
72-
free(image.comment);
73-
return NULL;
99+
if((fread(image->comment, header.comment_len, 1, fp) != 1) || image->comment[header.comment_len - 1] != '\0') {
100+
fprintf(stderr, "Cannot read comment.\n");
101+
_teardown();
102+
return image;
74103
}
75104

76105
// Read the image data
77-
image.data = malloc(header.width * header.height * sizeof(uint8_t));
78-
if(fread(image.data, header.width * header.height, 1, fp) != 1) {
79-
fprintf(stderr, "Cannot read pixel data.");
80-
free(image.data);
81-
// NOT DONE
106+
if(fread(image->data, header.width * header.height, 1, fp) != 1) {
107+
fprintf(stderr, "Cannot read pixel data.\n");
108+
_teardown();
109+
return image;
110+
}
82111

83-
return NULL;
112+
// Check if there are trailing bytes
113+
uint8_t byte;
114+
if((fread(&byte, sizeof(uint8_t), 1, fp) != 0) || !feof(fp)) {
115+
fprintf(stderr, "File has trailing bytes. Not continuing.\n");
116+
_teardown();
117+
return image;
118+
}
119+
120+
fclose(fp);
121+
return image;
84122
}
85123

86124
/**
@@ -90,7 +128,44 @@ Image * Image_load(const char * filename) {
90128
* Hint: Please see the README for extensive hints
91129
*/
92130
int Image_save(const char * filename, Image * image) {
93-
return 0;
131+
FILE * fp = NULL;
132+
ImageHeader header;
133+
134+
fp = fopen(filename, "wb");
135+
if(!fp) {
136+
fprintf(stderr, "Cannot open file '%s' for writing.\n", filename);
137+
return FALSE;
138+
}
139+
140+
// Build header
141+
header.magic_number = ECE264_IMAGE_MAGIC_NUMBER;
142+
header.width = image->width;
143+
header.height = image->height;
144+
header.comment_len = strlen(image->comment) + 1;
145+
146+
// Write to file
147+
if(fwrite(&header, sizeof(ImageHeader), 1, fp) != 1) {
148+
fprintf(stderr, "Unable to write header.\n");
149+
fclose(fp);
150+
return FALSE;
151+
}
152+
153+
// Write comment
154+
if(fwrite(image->comment, header.comment_len * sizeof(char), 1, fp) != 1) {
155+
fprintf(stderr, "Unable to write comment.\n");
156+
fclose(fp);
157+
return FALSE;
158+
}
159+
160+
// Image data
161+
if(fwrite(image->data, header.height * header.width * sizeof(uint8_t), 1, fp) != 1) {
162+
fprintf(stderr, "Unable to write image data.\n");
163+
fclose(fp);
164+
return FALSE;
165+
}
166+
167+
fclose(fp);
168+
return TRUE;
94169
}
95170

96171
/**
@@ -103,13 +178,35 @@ int Image_save(const char * filename, Image * image) {
103178
* report an error.
104179
*/
105180
void Image_free(Image * image) {
106-
return;
181+
if(image) {
182+
if(image->data) {
183+
free(image->data);
184+
}
185+
if(image->comment) {
186+
free(image->comment);
187+
}
188+
free(image);
189+
}
107190
}
108191

109192
/**
110193
* Performs linear normalization, see README
111194
*/
112195
void linearNormalization(int width, int height, uint8_t * intensity) {
113-
return;
114-
}
196+
int i;
197+
uint8_t min = 255, max = 0;
198+
199+
// Find max and min
200+
for(i = 0; i < width * height; i++) {
201+
if(intensity[i] > max) {
202+
max = intensity[i];
203+
} else if(intensity[i] < min) {
204+
min = intensity[i];
205+
}
206+
}
115207

208+
// Normalize image
209+
for(i = 0; i < width * height; i++) {
210+
intensity[i] = (intensity[i] - min) * 255.0 / (max - min);
211+
}
212+
}

0 commit comments

Comments
 (0)