ROOT  6.06/09
Reference Guide
main.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2010-2011 Matthias Kretz <kretz@kde.org>
3 
4  Permission to use, copy, modify, and distribute this software
5  and its documentation for any purpose and without fee is hereby
6  granted, provided that the above copyright notice appear in all
7  copies and that both that the copyright notice and this
8  permission notice and warranty disclaimer appear in supporting
9  documentation, and that the name of the author not be used in
10  advertising or publicity pertaining to distribution of the
11  software without specific, written prior permission.
12 
13  The author disclaim all warranties with regard to this
14  software, including all implied warranties of merchantability
15  and fitness. In no event shall the author be liable for any
16  special, indirect or consequential damages or any damages
17  whatsoever resulting from loss of use, data or profits, whether
18  in an action of contract, negligence or other tortious action,
19  arising out of or in connection with the use or performance of
20  this software.
21 
22 */
23 
24 #include "main.h"
25 #include "../tsc.h"
26 #include <complex>
27 #include <cmath>
28 
29 #include <QApplication>
30 #include <QTextStream>
31 #include <QTimer>
32 #include <QtCore/QtDebug>
33 #include <QPainter>
34 #include <QProgressBar>
35 
36 #ifdef Scalar
37 typedef float float_v;
38 typedef int int_v;
39 typedef bool int_m;
40 #else
41 #include <Vc/Vc>
42 
43 using Vc::float_v;
44 using Vc::float_m;
45 using Vc::int_v;
46 using Vc::int_m;
47 #endif
48 
50  : m_out(stdout)
51 {
52 }
53 
55 {
56  static int lastPercent = -1;
57  static int lastHash = 0;
58  int p = static_cast<int>(vf + 0.5f);
59  int h = static_cast<int>(vf * 0.78f + 0.5f);
60  bool flush = false;
61  if (p != lastPercent) {
62  flush = true;
63  if (lastPercent == -1) {
64  m_out << "\033[80D\033[K"
65  << "[ ";
66  m_out.setFieldWidth(3);
67  m_out << p;
68  m_out.setFieldWidth(0);
69  m_out << "% ]"
70  << "\033[79D";
71  } else {
72  m_out << "\033[s\033[80D\033[37C";
73  m_out.setFieldWidth(3);
74  m_out << p;
75  m_out.setFieldWidth(0);
76  m_out << "\033[u";
77  }
78  lastPercent = p;
79  }
80  for (; lastHash < h; ++lastHash) {
81  flush = true;
82  if (lastHash < 36 || lastHash > 39) {
83  m_out << '#';
84  } else {
85  m_out << "\033[1C";
86  }
87  }
88  if (flush) {
89  m_out.flush();
90  }
91 }
92 
94 {
95  setValue(100.f);
96  m_out << "\033[2C";
97  m_out.flush();
98 }
99 
101 {
102 }
103 
104 void Baker::setSize(int w, int h)
105 {
106  m_y = -1.f;
107  m_height = 2.f;
108 
109  m_width = w * m_height / h;
110  m_x = m_width * -0.667f;
111 
112  m_image = QImage(w, h, QImage::Format_RGB32);
113 }
114 
115 void Baker::setFilename(const QString &filename)
116 {
118 }
119 
120 typedef std::complex<float_v> Z;
121 
122 static inline Z P(Z z, Z c)
123 {
124  return z * z + c;
125 }
126 
127 static inline Z::value_type fastNorm(const Z &z)
128 {
129  return z.real() * z.real() + z.imag() * z.imag();
130 }
131 
132 template<typename T> static inline T square(T a) { return a * a; }
133 template<typename T> static inline T minOf(T a, T b) { return a < b ? a : b; }
134 template<typename T> static inline T maxOf(T a, T b) { return a < b ? b : a; }
135 template<typename T> static inline T clamp(T min, T value, T max)
136 {
137  if (value > max) {
138  return max;
139  }
140  return value < min ? min : value;
141 }
142 
143 struct Pixel
144 {
145  float blue;
146  float green;
147  float red;
148 };
149 
150 static const Pixel NULL_PIXEL = { 0, 0, 0 };
151 
152 class Canvas
153 {
154  public:
155  Canvas(int h, int w);
156  void addDot(float x, float y, int red, int green, int blue);
157  void toQImage(QImage *);
158 
159  private:
160  void addDot(int x, int y, float red, float green, float blue) {
161  Pixel &p = m_pixels[x + y * m_width];
162  p.blue += blue;
163  p.green += green;
164  p.red += red;
165  }
166  const int m_width;
167  std::vector<Pixel> m_pixels;
168 };
169 
170 Canvas::Canvas(int h, int w)
171  : m_width(w), m_pixels(h * w, NULL_PIXEL)
172 {
173 }
174 
175 void Canvas::addDot(float x, float y, int red, int green, int blue)
176 {
177  const int x1 = static_cast<int>(std::floor(x));
178  const int x2 = static_cast<int>(std::ceil (x));
179  const int y1 = static_cast<int>(std::floor(y));
180  const int y2 = static_cast<int>(std::ceil (y));
181  const float xfrac = x - std::floor(x);
182  const float yfrac = y - std::floor(y);
183  const float r = red;
184  const float g = green;
185  const float b = blue;
186  const float frac11 = (1.f - xfrac) * (1.f - yfrac);
187  const float frac12 = (1.f - xfrac) * yfrac;
188  const float frac21 = xfrac * (1.f - yfrac);
189  const float frac22 = xfrac * yfrac;
190  addDot(x1, y1, r * frac11, g * frac11, b * frac11);
191  addDot(x2, y1, r * frac21, g * frac21, b * frac21);
192  addDot(x1, y2, r * frac12, g * frac12, b * frac12);
193  addDot(x2, y2, r * frac22, g * frac22, b * frac22);
194 }
195 
196 #define BUDDHABROT_USE_FUNCTION1
197 
198 #ifdef BUDDHABROT_USE_FUNCTION2
199 static inline uchar reduceRange(float x, float m, float h)
200 {
201  /* m: max, h: median
202  * +- -+
203  * | 3 3 2 |
204  * | 510 h + 127 m - 765 h m |
205  * | -------------------------- |
206  * | 3 3 2 2 |
207  * | h m + h m - 2 h m |
208  * | |
209  * | 3 3 2 |
210  * | - 255 h - 254 m + 765 h m |
211  * | ---------------------------- |
212  * | 4 2 3 3 2 |
213  * | h m - 2 h m + h m |
214  * | |
215  * | 2 2 |
216  * | - 510 h m + 255 h + 127 m |
217  * | --------------------------- |
218  * | 4 2 3 3 2 |
219  * | h m - 2 h m + h m |
220  * +- -+
221  */
222  const float h2 = h * h;
223  const float h3 = h2 * h;
224  const float m2 = m * m;
225  const float m3 = m2 * m;
226  const float denom = h * m * square(m - h);
227  return minOf(255.f, 0.5f //rounding
228  + x / denom * (
229  510.f * h3 + 127.f * m3 - 765.f * h2 * m
230  + x / m * (
231  765.f * h * m2 - 255.f * h3 - 254.f * m3
232  + x * (
233  255.f * h2 + 127.f * m2 - 510.f * h * m)
234  )));
235 }
236 #elif defined(BUDDHABROT_USE_FUNCTION1)
237 static inline unsigned int reduceRange(float x, float m, float h)
238 {
239  if (x <= m) {
240  return 0.5f // rounding
241  + 4.f / 255.f * h * h / m * x
242  + square(x) * (h / square(m)) * (4.f - 8.f / 255.f * h);
243  } else {
244  return 0.5f // rounding
245  + 255.f - 4.f * h + 4.f / 255.f * square(h)
246  + x / m * (16.f * h - 1020.f - 12.f / 255.f * square(h))
247  + square(x / m) * (1020.f - 12.f * h + 8.f / 255.f * square(h));
248  }
249 }
250 #endif
251 
252 void Canvas::toQImage(QImage *img)
253 {
254  uchar *line = img->scanLine(0);
255  const Pixel *p = &m_pixels[0];
256 #ifdef BUDDHABROT_USE_FUNCTION2
257  float max [3] = { 0.f, 0.f, 0.f };
258  std::vector<float> sorted[3];
259  for (int i = 0; i < 3; ++i) {
260  sorted[i].reserve(m_pixels.size());
261  }
262  for (unsigned int i = 0; i < m_pixels.size(); ++i) {
263  max[0] = maxOf(max[0], m_pixels[i].red);
264  max[1] = maxOf(max[1], m_pixels[i].green);
265  max[2] = maxOf(max[2], m_pixels[i].blue);
266  if (m_pixels[i].red > 1.f) {
267  sorted[0].push_back(m_pixels[i].red);
268  }
269  if (m_pixels[i].green > 1.f) {
270  sorted[1].push_back(m_pixels[i].green);
271  }
272  if (m_pixels[i].blue > 1.f) {
273  sorted[2].push_back(m_pixels[i].blue);
274  }
275  }
276  for (int i = 0; i < 3; ++i) {
277  std::sort(sorted[i].begin(), sorted[i].end());
278  }
279  const float median[3] = {
280  sorted[0][sorted[0].size() / 2],
281  sorted[1][sorted[1].size() / 2],
282  sorted[2][sorted[2].size() / 2]
283  };
284 
285  /*
286  int hist[3][2];
287  for (int i = 0; i < 3; ++i) {
288  hist[i][0] = hist[i][1] = 0;
289  }
290  for (unsigned int i = 0; i < m_pixels.size(); ++i) {
291  ++hist[0][reduceRange(m_pixels[i].red , max[0], median[0]) / 128];
292  ++hist[1][reduceRange(m_pixels[i].green, max[1], median[1]) / 128];
293  ++hist[2][reduceRange(m_pixels[i].blue , max[2], median[2]) / 128];
294  }
295  qDebug() << "Histogram:\n red:"
296  << median[0] << hist[0][0] << hist[0][1] << "\ngreen:"
297  << median[1] << hist[1][0] << hist[1][1] << "\n blue:"
298  << median[2] << hist[2][0] << hist[2][1];
299  */
300 
301  for (int yy = 0; yy < img->height(); ++yy) {
302  for (int xx = 0; xx < img->width(); ++xx) {
303  line[0] = reduceRange(p->blue , max[2], median[2]);
304  line[1] = reduceRange(p->green, max[1], median[1]);
305  line[2] = reduceRange(p->red , max[0], median[0]);
306  line += 4;
307  ++p;
308  }
309  }
310 #elif defined(BUDDHABROT_USE_FUNCTION1)
311  float max[3] = { 0.f, 0.f, 0.f };
312  for (unsigned int i = 0; i < m_pixels.size(); ++i) {
313  max[0] = maxOf(max[0], m_pixels[i].red);
314  max[1] = maxOf(max[1], m_pixels[i].green);
315  max[2] = maxOf(max[2], m_pixels[i].blue);
316  }
317  float h[3] = { 220.f, 220.f, 220.f };
318 
319  /*
320  int hist[3][2];
321  for (int i = 0; i < 3; ++i) {
322  hist[i][0] = hist[i][1] = 0;
323  }
324  for (unsigned int i = 0; i < m_pixels.size(); ++i) {
325  ++hist[0][reduceRange(m_pixels[i].red , max[0], h[0]) / 128];
326  ++hist[1][reduceRange(m_pixels[i].green, max[1], h[1]) / 128];
327  ++hist[2][reduceRange(m_pixels[i].blue , max[2], h[2]) / 128];
328  }
329  qDebug() << "Histogram:\n red:"
330  << hist[0][0] << hist[0][1] << "\ngreen:"
331  << hist[1][0] << hist[1][1] << "\n blue:"
332  << hist[2][0] << hist[2][1];
333  */
334 
335  for (int yy = 0; yy < img->height(); ++yy) {
336  for (int xx = 0; xx < img->width(); ++xx) {
337  line[0] = reduceRange(p->blue , max[2], h[2]);
338  line[1] = reduceRange(p->green, max[1], h[1]);
339  line[2] = reduceRange(p->red , max[0], h[0]);
340  line += 4;
341  ++p;
342  }
343  }
344 #else
345  float max [3] = { 0.f, 0.f, 0.f };
346  float mean [3] = { 0.f, 0.f, 0.f };
347  float stddev[3] = { 0.f, 0.f, 0.f };
348  for (unsigned int i = 0; i < m_pixels.size(); ++i) {
349  max[0] = maxOf(max[0], m_pixels[i].red);
350  max[1] = maxOf(max[1], m_pixels[i].green);
351  max[2] = maxOf(max[2], m_pixels[i].blue);
352  mean[0] += m_pixels[i].red;
353  mean[1] += m_pixels[i].green;
354  mean[2] += m_pixels[i].blue;
355  stddev[0] += square(m_pixels[i].red);
356  stddev[1] += square(m_pixels[i].green);
357  stddev[2] += square(m_pixels[i].blue);
358  }
359  const float normalization = 1.f / m_pixels.size();
360  mean[0] *= normalization;
361  mean[1] *= normalization;
362  mean[2] *= normalization;
363  stddev[0] = std::sqrt(stddev[0] * normalization - square(mean[0]));
364  stddev[1] = std::sqrt(stddev[1] * normalization - square(mean[1]));
365  stddev[2] = std::sqrt(stddev[2] * normalization - square(mean[2]));
366  qDebug() << " max:" << max[0] << max[1] << max[2];
367  qDebug() << " mean:" << mean[0] << mean[1] << mean[2];
368  qDebug() << "stddev:" << stddev[0] << stddev[1] << stddev[2];
369 
370  // colors have the range 0..max at this point
371  // they should be transformed such that for the resulting mean and stddev:
372  // mean - stddev = 0
373  // mean + stddev = min(min(2 * mean, max), 255)
374  //
375  // newColor = (c - mean) * min(min(2 * mean, max), 255) * 0.5 / stddev + 127.5
376 
377  const float center[3] = {
378  minOf(minOf(2.f * mean[0], max[0]), 255.f) * 0.5f,
379  minOf(minOf(2.f * mean[1], max[1]), 255.f) * 0.5f,
380  minOf(minOf(2.f * mean[2], max[2]), 255.f) * 0.5f
381  };
382 
383  const float sdFactor[3] = { 2.f, 2.f, 2.f };
384  const float redFactor = center[0] / (sdFactor[0] * stddev[0]);
385  const float greenFactor = center[1] / (sdFactor[1] * stddev[1]);
386  const float blueFactor = center[2] / (sdFactor[2] * stddev[2]);
387 
388  for (int yy = 0; yy < img->height(); ++yy) {
389  for (int xx = 0; xx < img->width(); ++xx) {
390  line[0] = clamp(0, static_cast<int>(center[2] + (p->blue - mean[2]) * blueFactor ), 255);
391  line[1] = clamp(0, static_cast<int>(center[1] + (p->green - mean[1]) * greenFactor), 255);
392  line[2] = clamp(0, static_cast<int>(center[0] + (p->red - mean[0]) * redFactor ), 255);
393  line += 4;
394  ++p;
395  }
396  }
397 #endif
398 }
399 
401 {
402  red[0] = 2;
403  red[1] = 10;
404  green[0] = 0;
405  green[1] = 1;
406  blue[0] = 11;
407  blue[1] = 20;
408  it[0] = 10000;
409  it[1] = 50000;
410  steps[0] = steps[1] = -1;
411 }
412 
414 {
415  const int iHeight = m_image.height();
416  const int iWidth = m_image.width();
417 
418  // Parameters Begin
419  const float S = 4.f;
420  const float nSteps[2] = {
421  static_cast<float>(m_opt.steps[0] == -1 ? std::sqrt(iWidth) * iWidth : m_opt.steps[0]),
422  static_cast<float>(m_opt.steps[1] == -1 ? std::sqrt(iHeight) * iHeight : m_opt.steps[1])
423  };
424  const int upperBound[3] = { m_opt.red[1], m_opt.green[1], m_opt.blue[1] };
425  const int lowerBound[3] = { m_opt.red[0], m_opt.green[0], m_opt.blue[0] };
426  int overallLowerBound = m_opt.it[0];
427  int maxIterations = m_opt.it[1];// maxOf(maxOf(overallLowerBound, upperBound[0]), maxOf(upperBound[1], upperBound[2]));
428  float realMin = -2.102613f;
429  float realMax = 1.200613f;
430  float imagMin = 0.f;
431  float imagMax = 1.23971f;
432  // Parameters End
433 
435  timer.Start();
436 
437  // helper constants
438  const int overallUpperBound = maxOf(upperBound[0], maxOf(upperBound[1], upperBound[2]));
439  const float maxX = static_cast<float>(iWidth ) - 1.f;
440  const float maxY = static_cast<float>(iHeight) - 1.f;
441  const float xFact = iWidth / m_width;
442  const float yFact = iHeight / m_height;
443  const float realStep = (realMax - realMin) / nSteps[0];
444  const float imagStep = (imagMax - imagMin) / nSteps[1];
445 
446  Canvas canvas(iHeight, iWidth);
447 #ifdef Scalar
448  for (float real = realMin; real <= realMax; real += realStep) {
449  m_progress.setValue(99.f * (real - realMin) / (realMax - realMin));
450  for (float imag = imagMin; imag <= imagMax; imag += imagStep) {
451  Z c(real, imag);
452  Z c2 = Z(1.08f * real + 0.15f, imag);
453  if (fastNorm(Z(real + 1.f, imag)) < 0.06f || (std::real(c2) < 0.42f && fastNorm(c2) < 0.417f)) {
454  continue;
455  }
456  Z z = c;
457  int n;
458  for (n = 0; n <= maxIterations && fastNorm(z) < S; ++n) {
459  z = P(z, c);
460  }
461  if (n <= maxIterations && n >= overallLowerBound) {
462  // point is outside of the Mandelbrot set and required enough (overallLowerBound)
463  // iterations to reach the cut-off value S
464  Z cn(real, -imag);
465  Z zn = cn;
466  z = c;
467  for (int i = 0; i <= overallUpperBound; ++i) {
468  const float y2 = (std::imag(z) - m_y) * yFact;
469  const float yn2 = (std::imag(zn) - m_y) * yFact;
470  if (y2 >= 0.f && y2 < maxY && yn2 >= 0.f && yn2 < maxY) {
471  const float x2 = (std::real(z) - m_x) * xFact;
472  if (x2 >= 0.f && x2 < maxX) {
473  const int red = (i >= lowerBound[0] && i <= upperBound[0]) ? 1 : 0;
474  const int green = (i >= lowerBound[1] && i <= upperBound[1]) ? 1 : 0;
475  const int blue = (i >= lowerBound[2] && i <= upperBound[2]) ? 1 : 0;
476  canvas.addDot(x2, y2 , red, green, blue);
477  canvas.addDot(x2, yn2, red, green, blue);
478  }
479  }
480  z = P(z, c);
481  zn = P(zn, cn);
482  if (fastNorm(z) >= S) { // optimization: skip some useless looping
483  break;
484  }
485  }
486  }
487  }
488  }
489 #else
490  const float imagStep2 = imagStep * float_v::Size;
491  const float_v imagMin2 = imagMin + imagStep * static_cast<float_v>(int_v::IndexesFromZero());
492  for (float real = realMin; real <= realMax; real += realStep) {
493  m_progress.setValue(99.f * (real - realMin) / (realMax - realMin));
494  for (float_v imag = imagMin2; imag <= imagMax; imag += imagStep2) {
495  // FIXME: extra "tracks" if nSteps[1] is not a multiple of float_v::Size
496  Z c(float_v(real), imag);
497  Z c2 = Z(float_v(1.08f * real + 0.15f), imag);
498  if (fastNorm(Z(float_v(real + 1.f), imag)) < 0.06f || (std::real(c2) < 0.42f && fastNorm(c2) < 0.417f)) {
499  continue;
500  }
501  Z z = c;
502  int_v n(Vc::Zero);
503  int_m inside = fastNorm(z) < S;
504  while (!(inside && n <= maxIterations).isEmpty()) {
505  z = P(z, c);
506  ++n(inside);
507  inside &= fastNorm(z) < S;
508  }
509  inside |= n < overallLowerBound;
510  if (inside.isFull()) {
511  continue;
512  }
513  Z cn(float_v(real), -imag);
514  Z zn = cn;
515  z = c;
516  for (int i = 0; i <= overallUpperBound; ++i) {
517  const float_v y2 = (std::imag(z) - m_y) * yFact;
518  const float_v yn2 = (std::imag(zn) - m_y) * yFact;
519  const float_v x2 = (std::real(z) - m_x) * xFact;
520  z = P(z, c);
521  zn = P(zn, cn);
522  const float_m drawMask = !inside && y2 >= 0.f && x2 >= 0.f && y2 < maxY && x2 < maxX && yn2 >= 0.f && yn2 < maxY;
523 
524  const int red = (i >= lowerBound[0] && i <= upperBound[0]) ? 1 : 0;
525  const int green = (i >= lowerBound[1] && i <= upperBound[1]) ? 1 : 0;
526  const int blue = (i >= lowerBound[2] && i <= upperBound[2]) ? 1 : 0;
527 
528  foreach_bit(int j, drawMask) {
529  canvas.addDot(x2[j], y2 [j], red, green, blue);
530  canvas.addDot(x2[j], yn2[j], red, green, blue);
531  }
532  if (fastNorm(z) >= S) { // optimization: skip some useless looping
533  break;
534  }
535  }
536  }
537  }
538 #endif
539  canvas.toQImage(&m_image);
540 
541  timer.Stop();
542  m_progress.done();
543  qDebug() << timer.Cycles() << "cycles";
544 
545  if (m_filename.isEmpty()) {
546  m_filename = QString("r%1-%2_g%3-%4_b%5-%6_s%7-%8_i%9-%10_%11x%12.png")
547  .arg(lowerBound[0]).arg(upperBound[0])
548  .arg(lowerBound[1]).arg(upperBound[1])
549  .arg(lowerBound[2]).arg(upperBound[2])
550  .arg(nSteps[0]).arg(nSteps[1])
551  .arg(overallLowerBound).arg(maxIterations)
552  .arg(m_image.width()).arg(m_image.height());
553  }
554 
555  m_image.save(m_filename);
556 }
557 
558 static void usage(const char *argv0)
559 {
560  Baker::Options o;
561 
562  QTextStream out(stdout);
563  out << "Usage: " << argv0 << " [options] [<filename>]\n\n"
564  << "Options:\n"
565  << " -h|--help This message.\n"
566  << " -s|--size <w> <h> Specify the width and height of the resulting image file. [1024 768]\n"
567  << " -r|--red <int> <int> Specify lower and upper iteration bounds for a red trace. ["
568  << o.red[0] << ' ' << o.red[1] << "]\n"
569  << " -g|--green <int> <int> Specify lower and upper iteration bounds for a green trace. ["
570  << o.green[0] << ' ' << o.green[1] << "]\n"
571  << " -b|--blue <int> <int> Specify lower and upper iteration bounds for a blue trace. ["
572  << o.blue[0] << ' ' << o.blue[1] << "]\n"
573  << " --steps <int> <int> Specify the steps in real and imaginary direction. [width^1.5 height^1.5]\n"
574  << " --minIt <int> Overall lower iteration bound. [" << o.it[0] << "]\n"
575  << " --maxIt <int> Overall upper iteration bound. [" << o.it[1] << "]\n"
576  ;
577 }
578 
579 int main(int argc, char **argv)
580 {
581  QCoreApplication app(argc, argv);
582  const QStringList &args = QCoreApplication::arguments();
583  if (args.contains("--help") || args.contains("-h")) {
584  usage(argv[0]);
585  return 0;
586  }
587 
588  Baker b;
589 
590  Baker::Options opt;
591  int width = 1024;
592  int height = 768;
593 
594  // parse args
595  for (int i = 1; i < args.size(); ++i) {
596  const QString &arg = args[i];
597  bool ok = true;
598  if (arg == QLatin1String("--red") || arg == QLatin1String("-r")) {
599  opt.red[0] = args[++i].toInt(&ok);
600  if (ok) {
601  opt.red[1] = args[++i].toInt(&ok);
602  }
603  } else if (arg == QLatin1String("--green") || arg == QLatin1String("-g")) {
604  opt.green[0] = args[++i].toInt(&ok);
605  if (ok) {
606  opt.green[1] = args[++i].toInt(&ok);
607  }
608  } else if (arg == QLatin1String("--blue") || arg == QLatin1String("-b")) {
609  opt.blue[0] = args[++i].toInt(&ok);
610  if (ok) {
611  opt.blue[1] = args[++i].toInt(&ok);
612  }
613  } else if (arg == QLatin1String("--steps")) {
614  opt.steps[0] = args[++i].toInt(&ok);
615  if (ok) {
616  opt.steps[1] = args[++i].toInt(&ok);
617  }
618  } else if (arg == QLatin1String("--minIt")) {
619  opt.it[0] = args[++i].toInt(&ok);
620  } else if (arg == QLatin1String("--maxIt")) {
621  opt.it[1] = args[++i].toInt(&ok);
622  } else if (arg == QLatin1String("--size") || arg == QLatin1String("-s")) {
623  width = args[++i].toInt(&ok);
624  if (ok) {
625  height = args[++i].toInt(&ok);
626  }
627  } else {
628  static bool filenameSet = false;
629  ok = !filenameSet;
630  filenameSet = true;
631  b.setFilename(arg);
632  }
633  if (!ok) {
634  usage(argv[0]);
635  return 1;
636  }
637  }
638 
639  b.setOptions(opt);
640  b.setSize(width, height);
641  b.createImage();
642  return 0;
643 }
void setValue(float v)
Definition: main.cpp:54
static Vc_ALWAYS_INLINE int_v min(const int_v &x, const int_v &y)
Definition: vector.h:433
Baker()
Definition: main.cpp:100
void setSize(int w, int h)
Definition: main.cpp:104
int steps[2]
Definition: main.h:51
const char * Size
Definition: TXMLSetup.cxx:56
double T(double x)
Definition: ChebyshevPol.h:34
static const char * filename()
TArc * a
Definition: textangle.C:12
void Stop()
Definition: tsc.h:53
static T square(T a)
Definition: main.cpp:132
QImage m_image
Definition: main.h:68
float m_height
Definition: main.h:67
double sqrt(double)
TStopwatch timer
Definition: pirndm.C:37
float_v::Mask float_m
Definition: vector.h:424
#define foreach_bit(_it_, _mask_)
Definition: vector.h:146
unsigned long long Cycles() const
Definition: tsc.h:63
void createImage()
Definition: main.cpp:413
static T clamp(T min, T value, T max)
Definition: main.cpp:135
int it[2]
Definition: main.h:52
int green[2]
Definition: main.h:49
ProgressWriter()
Definition: main.cpp:49
ProgressWriter m_progress
Definition: main.h:70
char * out
Definition: TBase64.cxx:29
int blue[2]
Definition: main.h:50
static T maxOf(T a, T b)
Definition: main.cpp:134
Options m_opt
Definition: main.h:63
static T minOf(T a, T b)
Definition: main.cpp:133
int red[2]
Definition: main.h:48
TMarker * m
Definition: textangle.C:8
double floor(double)
float m_y
Definition: main.h:65
static void usage(const char *argv0)
Definition: main.cpp:558
static unsigned int reduceRange(float x, float m, float h)
Definition: main.cpp:237
return c2
Definition: legend2.C:14
double f(double x)
static const float S
Definition: mandel.cpp:113
int main(int argc, char **argv)
Main program.
Definition: main.cpp:22
static Z::value_type fastNorm(const Z &z)
Definition: main.cpp:127
static Vc_ALWAYS_INLINE int_v max(const int_v &x, const int_v &y)
Definition: vector.h:440
Definition: main.h:43
static Z P(Z z, Z c)
Definition: main.cpp:122
int_v::Mask int_m
Definition: vector.h:426
double ceil(double)
Vector< int > int_v
Definition: vector.h:419
QTextStream m_out
Definition: main.h:40
float m_x
Definition: main.h:64
std::complex< float_v > Z
Definition: main.cpp:120
void Start()
Definition: tsc.h:43
void done()
Definition: main.cpp:93
void setOptions(Options o)
Definition: main.h:57
float value
Definition: math.cpp:443
void setFilename(const QString &)
Definition: main.cpp:115
const Int_t n
Definition: legend1.C:16
float m_width
Definition: main.h:66
QString m_filename
Definition: main.h:69
static const float h
Definition: main.cpp:50
Vector< float > float_v
Definition: vector.h:417