mandelbrot

view 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 source
1 /*
2 A simple interactive mandelbrot fractal explorer
3 Copyright (C) John Tsiombikas <nuclear@member.fsf.org>
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <errno.h>
22 #include "palette.h"
24 struct palnode {
25 double t;
26 double r, g, b;
27 struct palnode *next;
28 };
30 static void fill_palette(struct palnode *list);
31 static void free_list(struct palnode *list);
33 int load_palette(const char *fname)
34 {
35 FILE *fp;
36 int res;
38 if(!(fp = fopen(fname, "r"))) {
39 fprintf(stderr, "failed to open palette file: %s: %s\n", fname, strerror(errno));
40 return -1;
41 }
42 res = load_palette_file(fp);
43 fclose(fp);
44 return res;
45 }
47 int load_palette_file(FILE *fp)
48 {
49 char buf[256];
50 struct palnode *palist = 0, *patail = 0;
52 if(!fgets(buf, sizeof buf, fp) || strstr(buf, "GRAD") != buf) {
53 fprintf(stderr, "invalid palette file, lack of magic!\n");
54 return -1;
55 }
57 while(fgets(buf, sizeof buf, fp)) {
58 struct palnode *node;
59 float t, r, g, b;
61 if(sscanf(buf, "%f %f %f %f", &t, &r, &g, &b) != 4) {
62 fprintf(stderr, "invalid palette file format\n");
63 free_list(palist);
64 return -1;
65 }
67 if(!(node = malloc(sizeof *node))) {
68 fprintf(stderr, "failed to allocate memory for list node\n");
69 free_list(palist);
70 return -1;
71 }
72 node->t = t;
73 node->r = r;
74 node->g = g;
75 node->b = b;
76 node->next = 0;
78 if(palist) {
79 patail->next = node;
80 patail = node;
81 } else {
82 palist = patail = node;
83 }
84 }
86 fill_palette(palist);
87 free_list(palist);
88 return 0;
89 }
91 static void fill_palette(struct palnode *list)
92 {
93 int i;
94 struct palnode *start, *end;
95 static const struct palnode last = {1.0, 0.0, 0.0, 0.0, 0};
97 memset(palette, 0, sizeof palette);
98 if(!list) {
99 return;
100 }
102 start = list;
103 end = list->next;
105 while(start && start != &last) {
106 int sidx, eidx, count;
107 double r, g, b, dr, dg, db;
109 if(!end) {
110 end = (struct palnode*)&last;
111 }
113 sidx = (int)(start->t * PAL_SIZE);
114 eidx = (int)(end->t * PAL_SIZE);
115 count = eidx - sidx;
117 r = start->r;
118 g = start->g;
119 b = start->b;
120 dr = (end->r - start->r) / count;
121 dg = (end->g - start->g) / count;
122 db = (end->b - start->b) / count;
124 for(i=0; i<count; i++) {
125 palette[sidx + i].r = (int)(r * 255.0);
126 palette[sidx + i].g = (int)(g * 255.0);
127 palette[sidx + i].b = (int)(b * 255.0);
128 r += dr;
129 g += dg;
130 b += db;
131 }
133 start = end;
134 end = end->next;
135 }
136 }
138 static void free_list(struct palnode *list)
139 {
140 while(list) {
141 void *tmp = list;
142 list = list->next;
143 free(tmp);
144 }
145 }