qvolray
diff src/volume.c @ 8:ae10631bb11b
cleaning up a bit to expand
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sat, 07 Apr 2012 16:07:12 +0300 |
parents | |
children | a6765984e057 |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/volume.c Sat Apr 07 16:07:12 2012 +0300 1.3 @@ -0,0 +1,162 @@ 1.4 +#include <stdio.h> 1.5 +#include <stdlib.h> 1.6 +#include <string.h> 1.7 +#include <ctype.h> 1.8 + 1.9 +#ifndef __APPLE__ 1.10 +#include <GL/gl.h> 1.11 +#else 1.12 +#include <OpenGL/gl.h> 1.13 +#endif 1.14 + 1.15 +#include <imago2.h> 1.16 + 1.17 +struct slice { 1.18 + char *name; 1.19 + struct slice *next; 1.20 +}; 1.21 + 1.22 +static struct slice *read_voldesc(const char *fname, struct volume *vol); 1.23 +static char *trim(char *str); 1.24 + 1.25 +struct volume *load_volume(const char *fname) 1.26 +{ 1.27 + struct slice *slist; 1.28 + struct volume *vol = 0; 1.29 + 1.30 + if(!(vol = malloc(sizeof *vol))) { 1.31 + perror("failed to allocate volume"); 1.32 + return 0; 1.33 + } 1.34 + memset(vol, 0, sizeof *vol); 1.35 + vol->zaspect = 1; 1.36 + 1.37 + if(!(slist = read_voldesc(fname, vol))) { 1.38 + goto err; 1.39 + } 1.40 + 1.41 + glGenTextures(1, &vol->tex_vol); 1.42 + glBindTexture(GL_TEXTURE_3D, vol->tex_vol); 1.43 + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 1.44 + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 1.45 + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 1.46 + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 1.47 + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); 1.48 + 1.49 + for(i=0; i<vol->sz[2]; i++) { 1.50 + struct img_pixmap img; 1.51 + struct slice *slice = head; 1.52 + head = head->next; 1.53 + 1.54 + img_init(&img); 1.55 + if(img_load(&img, slice->name) == -1) { 1.56 + fprintf(stderr, "failed to load volume slice: %s\n", slice->name); 1.57 + goto err; 1.58 + } 1.59 + } 1.60 + 1.61 + glGenTextures(1, &vol->tex_grad); 1.62 + glBindTexture(GL_TEXTURE_3D, vol->tex_grad); 1.63 + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 1.64 + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 1.65 + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 1.66 + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 1.67 + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); 1.68 + 1.69 +err: 1.70 + while(slist) { 1.71 + struct slice *tmp = slist; 1.72 + slist = slist->next; 1.73 + free(tmp->name); 1.74 + free(tmp); 1.75 + } 1.76 + if(vol) { 1.77 + if(vol->tex_vol) 1.78 + glDeleteTextures(1, &vol->tex_vol); 1.79 + if(vol->tex_grad) 1.80 + glDeleteTextures(1, &vol->tex_grad); 1.81 + free(vol); 1.82 + } 1.83 + return 0; 1.84 +} 1.85 + 1.86 +static struct slice *read_voldesc(const char *fname, struct volume *vol) 1.87 +{ 1.88 + FILE *fp = 0; 1.89 + char buf[512]; 1.90 + int mode_slices = 0; 1.91 + struct slice *head = 0, *tail; 1.92 + 1.93 + if(!(fp = fopen(fname, "r"))) { 1.94 + fprintf(stderr, "failed to open volume descriptor: %s\n", fname); 1.95 + return 0; 1.96 + } 1.97 + fgets(buf, sizeof buf, fp); 1.98 + if(strstr(buf, "VOLDESC") != buf) { 1.99 + fprintf(stderr, "invalid file format while trying to read volume descriptor: %s\n", fname); 1.100 + goto err; 1.101 + } 1.102 + 1.103 + while(fgets(buf, sizeof buf, fp)) { 1.104 + char *line = trim(buf); 1.105 + 1.106 + if(!*line || *line == '#') 1.107 + continue; 1.108 + 1.109 + if(mode_slices) { 1.110 + /* we're in the part that contains filenames... append to the list */ 1.111 + struct slice *node = malloc(sizeof *node); 1.112 + if(!node || !(node->name = malloc(strlen(line) + 1))) { 1.113 + perror("failed to allocate list node"); 1.114 + free(node); 1.115 + goto err; 1.116 + } 1.117 + strcpy(node->name, line); 1.118 + node->next = 0; 1.119 + 1.120 + if(head) { 1.121 + tail->next = node; 1.122 + tail = node; 1.123 + } else { 1.124 + head = tail = node; 1.125 + } 1.126 + vol->sz[2]++; 1.127 + } else { 1.128 + /* TODO we're in the options part... parse */ 1.129 + } 1.130 + } 1.131 + fclose(fp); 1.132 + 1.133 + if(!vol->sz[2]) { 1.134 + fprintf(stderr, "file: %s contains no slices\n", fname); 1.135 + goto err; 1.136 + } 1.137 + 1.138 + return head; 1.139 + 1.140 +err: 1.141 + while(head) { 1.142 + struct slice *tmp = head; 1.143 + head = head->next; 1.144 + free(tmp->name); 1.145 + free(tmp); 1.146 + } 1.147 + if(fp) { 1.148 + fclose(fp); 1.149 + } 1.150 + return 0; 1.151 +} 1.152 + 1.153 +static char *trim(char *str) 1.154 +{ 1.155 + char *tmp = str + strlen(str) - 1; 1.156 + 1.157 + while(isspace(*tmp)) 1.158 + tmp--; 1.159 + tmp[1] = 0; 1.160 + 1.161 + tmp = str; 1.162 + while(isspace(*tmp)) 1.163 + tmp++; 1.164 + return tmp; 1.165 +}