rev |
line source |
nuclear@8
|
1 #include <stdio.h>
|
nuclear@8
|
2 #include <stdlib.h>
|
nuclear@8
|
3 #include <string.h>
|
nuclear@8
|
4 #include <ctype.h>
|
nuclear@8
|
5
|
nuclear@8
|
6 #ifndef __APPLE__
|
nuclear@8
|
7 #include <GL/gl.h>
|
nuclear@8
|
8 #else
|
nuclear@8
|
9 #include <OpenGL/gl.h>
|
nuclear@8
|
10 #endif
|
nuclear@8
|
11
|
nuclear@8
|
12 #include <imago2.h>
|
nuclear@8
|
13
|
nuclear@8
|
14 struct slice {
|
nuclear@8
|
15 char *name;
|
nuclear@8
|
16 struct slice *next;
|
nuclear@8
|
17 };
|
nuclear@8
|
18
|
nuclear@8
|
19 static struct slice *read_voldesc(const char *fname, struct volume *vol);
|
nuclear@8
|
20 static char *trim(char *str);
|
nuclear@8
|
21
|
nuclear@8
|
22 struct volume *load_volume(const char *fname)
|
nuclear@8
|
23 {
|
nuclear@8
|
24 struct slice *slist;
|
nuclear@8
|
25 struct volume *vol = 0;
|
nuclear@8
|
26
|
nuclear@8
|
27 if(!(vol = malloc(sizeof *vol))) {
|
nuclear@8
|
28 perror("failed to allocate volume");
|
nuclear@8
|
29 return 0;
|
nuclear@8
|
30 }
|
nuclear@8
|
31 memset(vol, 0, sizeof *vol);
|
nuclear@8
|
32 vol->zaspect = 1;
|
nuclear@8
|
33
|
nuclear@8
|
34 if(!(slist = read_voldesc(fname, vol))) {
|
nuclear@8
|
35 goto err;
|
nuclear@8
|
36 }
|
nuclear@8
|
37
|
nuclear@8
|
38 glGenTextures(1, &vol->tex_vol);
|
nuclear@8
|
39 glBindTexture(GL_TEXTURE_3D, vol->tex_vol);
|
nuclear@8
|
40 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
nuclear@8
|
41 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
nuclear@8
|
42 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
nuclear@8
|
43 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
nuclear@8
|
44 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
|
nuclear@8
|
45
|
nuclear@8
|
46 for(i=0; i<vol->sz[2]; i++) {
|
nuclear@8
|
47 struct img_pixmap img;
|
nuclear@8
|
48 struct slice *slice = head;
|
nuclear@8
|
49 head = head->next;
|
nuclear@8
|
50
|
nuclear@8
|
51 img_init(&img);
|
nuclear@8
|
52 if(img_load(&img, slice->name) == -1) {
|
nuclear@8
|
53 fprintf(stderr, "failed to load volume slice: %s\n", slice->name);
|
nuclear@8
|
54 goto err;
|
nuclear@8
|
55 }
|
nuclear@8
|
56 }
|
nuclear@8
|
57
|
nuclear@8
|
58 glGenTextures(1, &vol->tex_grad);
|
nuclear@8
|
59 glBindTexture(GL_TEXTURE_3D, vol->tex_grad);
|
nuclear@8
|
60 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
nuclear@8
|
61 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
nuclear@8
|
62 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
nuclear@8
|
63 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
nuclear@8
|
64 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
|
nuclear@8
|
65
|
nuclear@8
|
66 err:
|
nuclear@8
|
67 while(slist) {
|
nuclear@8
|
68 struct slice *tmp = slist;
|
nuclear@8
|
69 slist = slist->next;
|
nuclear@8
|
70 free(tmp->name);
|
nuclear@8
|
71 free(tmp);
|
nuclear@8
|
72 }
|
nuclear@8
|
73 if(vol) {
|
nuclear@8
|
74 if(vol->tex_vol)
|
nuclear@8
|
75 glDeleteTextures(1, &vol->tex_vol);
|
nuclear@8
|
76 if(vol->tex_grad)
|
nuclear@8
|
77 glDeleteTextures(1, &vol->tex_grad);
|
nuclear@8
|
78 free(vol);
|
nuclear@8
|
79 }
|
nuclear@8
|
80 return 0;
|
nuclear@8
|
81 }
|
nuclear@8
|
82
|
nuclear@8
|
83 static struct slice *read_voldesc(const char *fname, struct volume *vol)
|
nuclear@8
|
84 {
|
nuclear@8
|
85 FILE *fp = 0;
|
nuclear@8
|
86 char buf[512];
|
nuclear@8
|
87 int mode_slices = 0;
|
nuclear@8
|
88 struct slice *head = 0, *tail;
|
nuclear@8
|
89
|
nuclear@8
|
90 if(!(fp = fopen(fname, "r"))) {
|
nuclear@8
|
91 fprintf(stderr, "failed to open volume descriptor: %s\n", fname);
|
nuclear@8
|
92 return 0;
|
nuclear@8
|
93 }
|
nuclear@8
|
94 fgets(buf, sizeof buf, fp);
|
nuclear@8
|
95 if(strstr(buf, "VOLDESC") != buf) {
|
nuclear@8
|
96 fprintf(stderr, "invalid file format while trying to read volume descriptor: %s\n", fname);
|
nuclear@8
|
97 goto err;
|
nuclear@8
|
98 }
|
nuclear@8
|
99
|
nuclear@8
|
100 while(fgets(buf, sizeof buf, fp)) {
|
nuclear@8
|
101 char *line = trim(buf);
|
nuclear@8
|
102
|
nuclear@8
|
103 if(!*line || *line == '#')
|
nuclear@8
|
104 continue;
|
nuclear@8
|
105
|
nuclear@8
|
106 if(mode_slices) {
|
nuclear@8
|
107 /* we're in the part that contains filenames... append to the list */
|
nuclear@8
|
108 struct slice *node = malloc(sizeof *node);
|
nuclear@8
|
109 if(!node || !(node->name = malloc(strlen(line) + 1))) {
|
nuclear@8
|
110 perror("failed to allocate list node");
|
nuclear@8
|
111 free(node);
|
nuclear@8
|
112 goto err;
|
nuclear@8
|
113 }
|
nuclear@8
|
114 strcpy(node->name, line);
|
nuclear@8
|
115 node->next = 0;
|
nuclear@8
|
116
|
nuclear@8
|
117 if(head) {
|
nuclear@8
|
118 tail->next = node;
|
nuclear@8
|
119 tail = node;
|
nuclear@8
|
120 } else {
|
nuclear@8
|
121 head = tail = node;
|
nuclear@8
|
122 }
|
nuclear@8
|
123 vol->sz[2]++;
|
nuclear@8
|
124 } else {
|
nuclear@8
|
125 /* TODO we're in the options part... parse */
|
nuclear@8
|
126 }
|
nuclear@8
|
127 }
|
nuclear@8
|
128 fclose(fp);
|
nuclear@8
|
129
|
nuclear@8
|
130 if(!vol->sz[2]) {
|
nuclear@8
|
131 fprintf(stderr, "file: %s contains no slices\n", fname);
|
nuclear@8
|
132 goto err;
|
nuclear@8
|
133 }
|
nuclear@8
|
134
|
nuclear@8
|
135 return head;
|
nuclear@8
|
136
|
nuclear@8
|
137 err:
|
nuclear@8
|
138 while(head) {
|
nuclear@8
|
139 struct slice *tmp = head;
|
nuclear@8
|
140 head = head->next;
|
nuclear@8
|
141 free(tmp->name);
|
nuclear@8
|
142 free(tmp);
|
nuclear@8
|
143 }
|
nuclear@8
|
144 if(fp) {
|
nuclear@8
|
145 fclose(fp);
|
nuclear@8
|
146 }
|
nuclear@8
|
147 return 0;
|
nuclear@8
|
148 }
|
nuclear@8
|
149
|
nuclear@8
|
150 static char *trim(char *str)
|
nuclear@8
|
151 {
|
nuclear@8
|
152 char *tmp = str + strlen(str) - 1;
|
nuclear@8
|
153
|
nuclear@8
|
154 while(isspace(*tmp))
|
nuclear@8
|
155 tmp--;
|
nuclear@8
|
156 tmp[1] = 0;
|
nuclear@8
|
157
|
nuclear@8
|
158 tmp = str;
|
nuclear@8
|
159 while(isspace(*tmp))
|
nuclear@8
|
160 tmp++;
|
nuclear@8
|
161 return tmp;
|
nuclear@8
|
162 }
|