mightymandel v16

GPU-based Mandelbrot set explorer

image.c
Go to the documentation of this file.
1 // mightymandel -- GPU-based Mandelbrot Set explorer
2 // Copyright (C) 2012,2013,2014,2015 Claude Heiland-Allen
3 // License GPL3+ http://www.gnu.org/licenses/gpl.html
4 
10 #include <math.h>
11 #include <stdlib.h>
12 
13 #include "mightymandel.h"
14 #include "image.h"
15 #include "texture.h"
16 
28 int cmp_pixel(const void *a, const void *b) {
29  const struct pixel *x = a;
30  const struct pixel *y = b;
31  if (x->n > y->n) { return -1; }
32  if (x->n < y->n) { return 1; }
33  if (x->e > y->e) { return -1; }
34  if (x->e < y->e) { return 1; }
35  return 0;
36 }
37 
49 float *image_get_glitched(int width, int height) {
50  float *raw = (float *) malloc(width * height * sizeof(float));
51  glActiveTexture(GL_TEXTURE0 + TEX_RAW);
52  glGetTexImage(GL_TEXTURE_2D, 0, GL_GREEN, GL_FLOAT, raw);
53  float *data = malloc(width * height * sizeof(float));
54  for (int j = 0; j < height; ++j) {
55  for (int i = 0; i < width; ++i) {
56  int ki = (height - 1 - j) * width + i;
57  int ko = j * width + i;
58  data[ko] = raw[ki];
59  }
60  }
61  free(raw);
62  return data;
63 }
64 
76 float *image_get_iterations(int width, int height) {
77  float *raw = (float *) malloc(width * height * sizeof(float));
78  glActiveTexture(GL_TEXTURE0 + TEX_RAW);
79  glGetTexImage(GL_TEXTURE_2D, 0, GL_RED, GL_FLOAT, raw);
80  float *data = malloc(width * height * sizeof(float));
81  for (int j = 0; j < height; ++j) {
82  for (int i = 0; i < width; ++i) {
83  int ki = (height - 1 - j) * width + i;
84  int ko = j * width + i;
85  data[ko] = raw[ki];
86  }
87  }
88  free(raw);
89  return data;
90 }
91 
103 unsigned char *image_erode(const unsigned char *data, int width, int height) {
104  unsigned char *data2 = (unsigned char *) malloc(width * height);
105  for (int j = 0; j < height; ++j) {
106  for (int i = 0; i < width; ++i) {
107  int k = j * width + i;
108  int setcount = 0;
109  int totalcount = 0;
110  for (int jj = -1; jj <= 1; ++jj) {
111  for (int ii = -1; ii <= 1; ++ ii) {
112  int jjj = j + jj;
113  int iii = i + ii;
114  if (0 <= iii && iii < width && 0 <= jjj && jjj < height) {
115  int kkk = jjj * width + iii;
116  setcount += data[kkk];
117  totalcount++;
118  }
119  }
120  }
121  data2[k] = totalcount == setcount;
122  }
123  }
124  return data2;
125 }
126 
140 struct pixel *image_find_peak_glitches(const float *glitched, const float *iterations, int width, int height, int *count) {
141  struct pixel *pxs = malloc(width * height * sizeof(struct pixel));
142  *count = 0;
143  for (int j = 0; j < height; ++j) {
144  for (int i = 0; i < width; ++i) {
145  int k = j * width + i;
146  if (glitched[k] > 0.0) {
147  pxs[*count].e = glitched[k];
148  pxs[*count].n = iterations[k];
149  pxs[*count].i = i;
150  pxs[*count].j = j;
151  (*count)++;
152  }
153  }
154  }
155  if (*count) {
156  qsort(pxs, *count, sizeof(struct pixel), cmp_pixel);
157  }
158  return pxs;
159 }
160 
161 enum result_t image_result(int width, int height, double *iterations, double *exterior, double *interior, double *glitch) {
162  *iterations = 0;
163  *exterior = 0;
164  *interior = 0;
165  *glitch = 0;
166  double percent = 100.0 / (width * height);
167  float *raw = malloc(width * height * 2 * sizeof(float));
168  glActiveTexture(GL_TEXTURE0 + TEX_RAW);
169  glGetTexImage(GL_TEXTURE_2D, 0, GL_RG, GL_FLOAT, raw);
170  for (int j = 0; j < height; ++j) {
171  for (int i = 0; i < width; ++i) {
172  int k = j * width + i;
173  *iterations = fmaxf(*iterations, fabsf(raw[2*k+0]));
174  *exterior += raw[2*k+0] > 0.0;
175  *interior += raw[2*k+0] <= 0.0;
176  *glitch += raw[2*k+1] != 0.0;
177  }
178  }
179  free(raw);
180  *exterior *= percent;
181  *interior *= percent;
182  *glitch *= percent;
183  if (*glitch < 0.02) { // FIXME hardcoded threshold
184  return result_ok;
185  } else {
186  return result_glitch;
187  }
188 }