volray

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 +}