-
Notifications
You must be signed in to change notification settings - Fork 1
/
image.c
139 lines (119 loc) · 4.13 KB
/
image.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
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include "image.h"
Image *image_init(int width, int height) {
Image *image;
/* U slucaju greske prekida se program. */
assert(width >= 0 && height >= 0);
/* Alocira se prostor za smestanje clanova strukture. */
image = (Image *) malloc(sizeof(Image));
assert(image != NULL);
/* Inicijlizuju se clanovi strukture. */
image->width = width;
image->height = height;
if (width == 0 || height == 0)
image->pixels = NULL;
else {
image->pixels = (char *)malloc(3 * width * height * sizeof(char));
assert(image->pixels != NULL);
}
/* Vraca se pokazivac na inicijlizovanu strukturu. */
return image;
}
void image_done(Image *image) {
/*
* Oslobadja se prostor za cuvanje podataka o pikselima
* a potom se oslobadja i prostor u kojem su cuvani
* podaci same strukture.
*/
free(image->pixels);
free(image);
}
void image_read(Image *image, char *filename) {
FILE *file;
BITMAPFILEHEADER bfh;
BITMAPINFOHEADER bih;
unsigned int i;
unsigned char r, g, b, a;
/* Brise se prethodni sadrzaj strukture Image. */
free(image->pixels);
image->pixels = NULL;
/* Otvara se fajl koji sadrzi sliku u binarnom rezimu. */
assert((file = fopen(filename, "rb")) != NULL);
/* Ocitavaju se podaci prvog zaglavlja. */
fread(&bfh.type, 2, 1, file);
fread(&bfh.size, 4, 1, file);
fread(&bfh.reserved1, 2, 1, file);
fread(&bfh.reserved2, 2, 1, file);
fread(&bfh.offsetbits, 4, 1, file);
/* Ocitavaju se podaci drugog zaglavlja. */
fread(&bih.size, 4, 1, file);
fread(&bih.width, 4, 1, file);
fread(&bih.height, 4, 1, file);
fread(&bih.planes, 2, 1, file);
fread(&bih.bitcount, 2, 1, file);
fread(&bih.compression, 4, 1, file);
fread(&bih.sizeimage, 4, 1, file);
fread(&bih.xpelspermeter, 4, 1, file);
fread(&bih.ypelspermeter, 4, 1, file);
fread(&bih.colorsused, 4, 1, file);
fread(&bih.colorsimportant, 4, 1, file);
/*
* Od podataka iz drugog zaglavlja koristimo samo informacije
* o dimenzijama slike.
*/
image->width = bih.width;
image->height = bih.height;
/*
* U zavisnosti od toga koliko bitova informacija se cita po pikselu
* (da li samo R, G i B komponenta ili R, G, B i A), alociramo niz
* odgovarajuce duzine.
*/
if (bih.bitcount == 24)
image->pixels = (char *)malloc(3 * bih.width * bih.height * sizeof(char));
else if (bih.bitcount == 32)
image->pixels = (char *)malloc(4 * bih.width * bih.height * sizeof(char));
else {
fprintf(stderr, "image_read(): Podrzane su samo slike koje po pikselu cuvaju 24 ili 32 bita podataka.\n");
exit(1);
}
assert(image->pixels != NULL);
/* Ucitavaju se podaci o pikselima i smestaju u alocirani niz. */
if (bih.bitcount == 24)
/*
* Ako se po pikselu cita 24 bita = 3 bajta informacija, pretpostavljamo
* da oni (ta 3 bajta) predstavljaju R, G i B komponentu boje (1 bajt po
* komponenti).
*/
for (i = 0; i < bih.width * bih.height; i++) {
/*
* Ovo mozda izgleda cudno, to sto se komponente boje citaju u suprotnom redosledu,
* tj. prvo plava, pa zelena, pa crvena, ali tako pise u specifikaciji bmp formata.
*/
fread(&b, sizeof(char), 1, file);
fread(&g, sizeof(char), 1, file);
fread(&r, sizeof(char), 1, file);
image->pixels[3 * i] = r;
image->pixels[3 * i + 1] = g;
image->pixels[3 * i + 2] = b;
}
else if (bih.bitcount == 32)
/*
* Ako se po pikselu cita 32 bita = 4 bajta informacija, pretpostavljamo
* da oni (ta 4 bajta) predstavljaju R, G, B i A komponentu boje (1 bajt po
* komponenti).
*/
for (i = 0; i < bih.width * bih.height; i++) {
fread(&b, sizeof(char), 1, file);
fread(&g, sizeof(char), 1, file);
fread(&r, sizeof(char), 1, file);
fread(&a, sizeof(char), 1, file);
image->pixels[4 * i] = r;
image->pixels[4 * i + 1] = g;
image->pixels[4 * i + 2] = b;
image->pixels[4 * i + 3] = a;
}
/* Zatvara se fajl. */
fclose(file);
}