-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpreprocess.c
More file actions
208 lines (171 loc) · 5 KB
/
Copy pathpreprocess.c
File metadata and controls
208 lines (171 loc) · 5 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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <sys/types.h>
#include <unistd.h>
// imagemagick magickcore
#include <ImageMagick-7/MagickCore/MagickCore.h>
struct dir_info
{
int num_files;
char **file_names;
};
struct out_props
{
int h_res;
int v_res;
};
// reads all filenames in file_dir into dir_info->file_names
// stores the number of files in dir_info->num_files
int index_dir(const char *file_dir, struct dir_info *dir_info)
{
DIR *raw_img_dir;
struct dirent *dirent;
char **tmp_p;
int num_files = 0;
int i = 0;
if(!(raw_img_dir = opendir(file_dir))){
fprintf(stderr,"cannot open %s\n", file_dir);
return -1;
}
while((dirent = readdir(raw_img_dir))){
if(dirent->d_type == DT_REG){
++num_files;
tmp_p = malloc(sizeof(char *) * num_files);
if(!tmp_p){
fprintf(stderr, "malloc() failed\n");
return -1;
}
memcpy(tmp_p, dir_info->file_names, sizeof(char *) * (num_files - 1));
if(num_files > 1)
free(dir_info->file_names);
dir_info->file_names = tmp_p;
i = 0;
while(dirent->d_name[i++] != '\0')
;
dir_info->file_names[num_files - 1] = malloc(sizeof(char) * i);
strncpy(dir_info->file_names[num_files - 1], dirent->d_name, i);
}
}
closedir(raw_img_dir);
dir_info->num_files = num_files;
return 0;
}
Image *convert_img(ImageInfo *img_info, ExceptionInfo *exception, struct out_props *out_props)
{
Image *img_in, *img_out;
if(IsMagickCoreInstantiated() == MagickFalse){
fprintf(stderr, "magickcore environment unititalized\n");
return NULL;
}
img_in = ReadImage(img_info, exception);
if(exception->severity != UndefinedException)
CatchException(exception);
if(img_in == (Image *) NULL){
fprintf(stderr, "failed to read image %s\n",
img_info->filename);
return NULL;
}
// resize
img_out = SampleImage(img_in, out_props->h_res, out_props->v_res, exception);
DestroyImage(img_in);
// convert to greyscale
TransformImageColorspace(img_out, GRAYColorspace, exception);
return img_out;
}
int main(int argc, const char **argv)
{
int i, a;
int write_pos;
int n_write_success;
struct out_props out_props;
struct dir_info dir_info;
Image *img;
ImageInfo *image_info;
ExceptionInfo *exception;
char *img_pixels;
FILE *output_data;
if(argc != 5){
printf("%s <input_image_dir> <output_file> <out_h_res> <out_v_res>\n", argv[0]);
return 0;
}
if((output_data = fopen(argv[2], "w+b")) == NULL){
perror("ERROR:");
return -1;
}
sscanf(argv[3], "%d", &out_props.h_res);
sscanf(argv[4], "%d", &out_props.v_res);
// index images
if(index_dir(argv[1], &dir_info)){
fprintf(stderr, "image dir indexing failed, exiting\n");
return -1;
}
n_write_success = dir_info.num_files;
// allocate memory to hold image pixels
img_pixels = NULL;
img_pixels = malloc(sizeof(char) * out_props.h_res * out_props.v_res);
if(!img_pixels){
fprintf(stderr, "failed to allocate memory for image data, exiting\n");
return -1;
}
// write outputfile header data
// *could* implement an actual file format, like idx or something
for(i = 0; i < 2; ++i)
fputc((unsigned char)(dir_info.num_files >> 8 * i), output_data);
for(i = 0; i < 2; ++i)
fputc((unsigned char)(out_props.h_res >> 8 * i), output_data);
for(i = 0; i < 2; ++i)
fputc((unsigned char)(out_props.v_res >> 8 * i), output_data);
// initialize the magickcore environment
MagickCoreGenesis(NULL, MagickTrue);
exception = AcquireExceptionInfo();
image_info = CloneImageInfo((ImageInfo *) NULL);
// this shouldn't fail as this dir was opened and read earlier
// thus not bothering with an error message
if(chdir(argv[1]))
return -1;
for(i = 0; i < dir_info.num_files; ++i){
strcpy(image_info->filename, dir_info.file_names[i]);
// read and convert image to generalized format
img = convert_img(image_info, exception, &out_props);
if(!img){
printf("an error occured, proceeding to next image");
goto process_loop_fail;
}
// extract and store new pixel values
if(ExportImagePixels(img, 0, 0, out_props.h_res, out_props.v_res,
"I", CharPixel, img_pixels, exception) == MagickFalse){
printf("pixel export failed, moving onto next image without writing\n");
goto process_loop_fail;
}
// write pixels to datafile
for(a = 0; a < out_props.h_res * out_props.v_res; ++a)
fputc(img_pixels[a], output_data);
goto process_loop_cleanup;
process_loop_fail:
// decrement num of images written
--n_write_success;
// apply new img_count header
write_pos = ftell(output_data);
fseek(output_data, 0, SEEK_SET);
for(i = 0; i < 2; ++i)
fputc((unsigned char)(n_write_success >> 8 * i), output_data);
// return filepointer
fseek(output_data, write_pos, SEEK_SET);
process_loop_cleanup:
DestroyImage(img);
}
if(chdir(".."))
return -1;
// image conversion and extraction done, dismantle magickcore env
DestroyImageInfo(image_info);
DestroyExceptionInfo(exception);
MagickCoreTerminus();
// cleanup
fclose(output_data);
for(i = 0; i < dir_info.num_files; ++i)
free(dir_info.file_names[i]);
free(img_pixels);
return 0;
}