/
image_io.c
141 lines (113 loc) · 3.17 KB
/
image_io.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
#include "image_io.h"
double **bmp_in(FILE *bmpfile, int32_t *y, int32_t *x)
{
int32_t iy, ix, ic; // various iterators
int32_t offset;
double **image;
uint8_t zerobytes, val;
#ifdef DEBUG
fprintf(stderr, "bmp_in...\n");
#endif
if (fread_le_short(bmpfile) != 19778) // "BM" format tag check
{
fprintf(stderr, "This file is not in BMP format\n");
win_return();
exit(EXIT_FAILURE);
}
fseek(bmpfile, 8, SEEK_CUR); // skipping useless tags
offset = fread_le_word(bmpfile) - 54; // header offset
fseek(bmpfile, 4, SEEK_CUR); // skipping useless tags
*x = fread_le_word(bmpfile);
*y = fread_le_word(bmpfile);
fseek(bmpfile, 2, SEEK_CUR); // skipping useless tags
if (fread_le_short(bmpfile) != 24) // Only format supported
{
fprintf(stderr, "Wrong BMP format, BMP images must be in 24-bit colour\n");
win_return();
exit(EXIT_FAILURE);
}
fseek(bmpfile, 24+offset, SEEK_CUR); // skipping useless tags
image = malloc (*y * sizeof(double)); // image allocation
for (iy=0; iy<*y; iy++)
image[iy]=calloc (*x, sizeof(double));
zerobytes = 4 - ((*x*3) & 3);
if (zerobytes==4)
zerobytes = 0;
for (iy=y-1; iy!=-1; iy--) // BMP pixels are ordered: ...bottom row (left-to-right)... ... ...top row (left-to-right)...
{
for (ix=0; ix<*x; ix++)
{
for (ic=2;ic!=-1;ic--)
{
fread(&val, 1, 1, bmpfile);
image[iy][ix] += (double) val * (1.0/(255.0 * 3.0)); // Conversion to grey by averaging the three channels
}
}
fseek(bmpfile, zerobytes, SEEK_CUR); // skipping padding bytes
}
fclose(bmpfile);
return image;
}
void float32_columns_out(FILE *fout, double **image, int32_t y, int32_t x) {
int32_t i, iy, ix;
float val;
for (ix = 0; ix < x; ix++) {
for (iy = 0; iy < y; iy++) {
val = image[iy][ix];
fwrite(&val, 4, 1, fout);
}
}
}
void bmp_out(FILE *bmpfile, double **image, int32_t y, int32_t x)
{
int32_t i, iy, ix, ic; // various iterators
int32_t filesize, imagesize;
uint8_t zerobytes, val, zero=0;
double vald;
#ifdef DEBUG
fprintf(stderr, "bmp_out...\n");
#endif
zerobytes = 4 - ((x*3) & 3); // computation of zero bytes
if (zerobytes==4)
zerobytes = 0;
//********Tags********
filesize = 56 + ((x*3)+zerobytes) * y;
imagesize = 2 + ((x*3)+zerobytes) * y;
fwrite_le_short(19778, bmpfile);
fwrite_le_word(filesize, bmpfile);
fwrite_le_word(0, bmpfile);
fwrite_le_word(54, bmpfile);
fwrite_le_word(40, bmpfile);
fwrite_le_word(x, bmpfile);
fwrite_le_word(y, bmpfile);
fwrite_le_short(1, bmpfile);
fwrite_le_word(24, bmpfile);
fwrite_le_short(0, bmpfile);
fwrite_le_word(imagesize, bmpfile);
fwrite_le_word(2834, bmpfile);
fwrite_le_word(2834, bmpfile);
fwrite_le_word(0, bmpfile);
fwrite_le_word(0, bmpfile);
//--------Tags--------
for (iy=y-1; iy!=-1; iy--) // backwards writing
{
for (ix=0; ix<x; ix++)
{
vald = image[iy][ix] * 255.0;
if (vald > 255.0)
vald = 255.0;
if (vald < 0.0)
vald = 0.0;
val = vald;
for (ic=2; ic!=-1; ic--)
fwrite(&val, 1, 1, bmpfile);
}
for (i=0; i<zerobytes; i++)
fwrite(&zero, 1, 1, bmpfile); // write padding bytes
}
fwrite_le_short(0, bmpfile);
fclose(bmpfile);
#ifdef DEBUG
fprintf(stderr, "Image size : %dx%d\n", x, y);
#endif
}