mandelbrot
diff src/palette.c @ 0:4d85805eb875
mandelbrot initial import
author | John Tsiombikas <nuclear@mutantstargoat.com> |
---|---|
date | Tue, 19 Jun 2012 06:48:38 +0300 |
parents | |
children |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/palette.c Tue Jun 19 06:48:38 2012 +0300 1.3 @@ -0,0 +1,145 @@ 1.4 +/* 1.5 +A simple interactive mandelbrot fractal explorer 1.6 +Copyright (C) John Tsiombikas <nuclear@member.fsf.org> 1.7 + 1.8 +This program is free software: you can redistribute it and/or modify 1.9 +it under the terms of the GNU General Public License as published by 1.10 +the Free Software Foundation, either version 3 of the License, or 1.11 +(at your option) any later version. 1.12 + 1.13 +This program is distributed in the hope that it will be useful, 1.14 +but WITHOUT ANY WARRANTY; without even the implied warranty of 1.15 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1.16 +GNU General Public License for more details. 1.17 + 1.18 +You should have received a copy of the GNU General Public License 1.19 +along with this program. If not, see <http://www.gnu.org/licenses/>. 1.20 +*/ 1.21 +#include <stdio.h> 1.22 +#include <stdlib.h> 1.23 +#include <string.h> 1.24 +#include <errno.h> 1.25 +#include "palette.h" 1.26 + 1.27 +struct palnode { 1.28 + double t; 1.29 + double r, g, b; 1.30 + struct palnode *next; 1.31 +}; 1.32 + 1.33 +static void fill_palette(struct palnode *list); 1.34 +static void free_list(struct palnode *list); 1.35 + 1.36 +int load_palette(const char *fname) 1.37 +{ 1.38 + FILE *fp; 1.39 + int res; 1.40 + 1.41 + if(!(fp = fopen(fname, "r"))) { 1.42 + fprintf(stderr, "failed to open palette file: %s: %s\n", fname, strerror(errno)); 1.43 + return -1; 1.44 + } 1.45 + res = load_palette_file(fp); 1.46 + fclose(fp); 1.47 + return res; 1.48 +} 1.49 + 1.50 +int load_palette_file(FILE *fp) 1.51 +{ 1.52 + char buf[256]; 1.53 + struct palnode *palist = 0, *patail = 0; 1.54 + 1.55 + if(!fgets(buf, sizeof buf, fp) || strstr(buf, "GRAD") != buf) { 1.56 + fprintf(stderr, "invalid palette file, lack of magic!\n"); 1.57 + return -1; 1.58 + } 1.59 + 1.60 + while(fgets(buf, sizeof buf, fp)) { 1.61 + struct palnode *node; 1.62 + float t, r, g, b; 1.63 + 1.64 + if(sscanf(buf, "%f %f %f %f", &t, &r, &g, &b) != 4) { 1.65 + fprintf(stderr, "invalid palette file format\n"); 1.66 + free_list(palist); 1.67 + return -1; 1.68 + } 1.69 + 1.70 + if(!(node = malloc(sizeof *node))) { 1.71 + fprintf(stderr, "failed to allocate memory for list node\n"); 1.72 + free_list(palist); 1.73 + return -1; 1.74 + } 1.75 + node->t = t; 1.76 + node->r = r; 1.77 + node->g = g; 1.78 + node->b = b; 1.79 + node->next = 0; 1.80 + 1.81 + if(palist) { 1.82 + patail->next = node; 1.83 + patail = node; 1.84 + } else { 1.85 + palist = patail = node; 1.86 + } 1.87 + } 1.88 + 1.89 + fill_palette(palist); 1.90 + free_list(palist); 1.91 + return 0; 1.92 +} 1.93 + 1.94 +static void fill_palette(struct palnode *list) 1.95 +{ 1.96 + int i; 1.97 + struct palnode *start, *end; 1.98 + static const struct palnode last = {1.0, 0.0, 0.0, 0.0, 0}; 1.99 + 1.100 + memset(palette, 0, sizeof palette); 1.101 + if(!list) { 1.102 + return; 1.103 + } 1.104 + 1.105 + start = list; 1.106 + end = list->next; 1.107 + 1.108 + while(start && start != &last) { 1.109 + int sidx, eidx, count; 1.110 + double r, g, b, dr, dg, db; 1.111 + 1.112 + if(!end) { 1.113 + end = (struct palnode*)&last; 1.114 + } 1.115 + 1.116 + sidx = (int)(start->t * PAL_SIZE); 1.117 + eidx = (int)(end->t * PAL_SIZE); 1.118 + count = eidx - sidx; 1.119 + 1.120 + r = start->r; 1.121 + g = start->g; 1.122 + b = start->b; 1.123 + dr = (end->r - start->r) / count; 1.124 + dg = (end->g - start->g) / count; 1.125 + db = (end->b - start->b) / count; 1.126 + 1.127 + for(i=0; i<count; i++) { 1.128 + palette[sidx + i].r = (int)(r * 255.0); 1.129 + palette[sidx + i].g = (int)(g * 255.0); 1.130 + palette[sidx + i].b = (int)(b * 255.0); 1.131 + r += dr; 1.132 + g += dg; 1.133 + b += db; 1.134 + } 1.135 + 1.136 + start = end; 1.137 + end = end->next; 1.138 + } 1.139 +} 1.140 + 1.141 +static void free_list(struct palnode *list) 1.142 +{ 1.143 + while(list) { 1.144 + void *tmp = list; 1.145 + list = list->next; 1.146 + free(tmp); 1.147 + } 1.148 +}