title: How to fix my Pthreads code about Mandelbrot set?
body: <p>I have the following Pthreads code about calculating and creating a picture of the Mandelbrot set. My code in C works just fine and it prints the resulting picture nicely. The point is that using the below code, I am able to compile the code and execute it. Afterwards, if I try to view the resulting .ppm file in Gimp, it simply cannot open it. I guess I'm doing something wrong in my code. If someone could help me I would be glad.</p>
  
  <pre><code>// mandpthread.c
  // to compile: gcc mandpthread.c -o mandpthread -lm -lrt -lpthread
  // usage: ./mandpthread &lt;no_of_iterations&gt; &lt;no_of_threads&gt; &gt; output.ppm
  
  #include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;math.h&gt;
  #include &lt;time.h&gt;
  #include &lt;assert.h&gt;
  #include &lt;pthread.h&gt;
  
  typedef struct {
      int r, g, b;
  } rgb;
  
  int NITERATIONS, NTHREADS;
  rgb **m;
  
  void color(rgb **m, int x, int y, int red, int green, int blue)
  {
      m[y][x].r = red;
      m[y][x].g = green;
      m[y][x].b = blue;
  }
  
  void mandelbrot(int tid)
  {
      int w = 600, h = 400, x, y; 
      // each iteration, it calculates: newz = oldz*oldz + p, 
      // where p is the current pixel, and oldz stars at the origin
      double pr, pi;                   // real and imaginary part of the pixel p
      double newRe, newIm, oldRe, oldIm;   // real and imaginary parts of new and old z
      double zoom = 1, moveX = -0.5, moveY = 0; // you can change these to zoom and change position
  
      int start = tid * NITERATIONS/NTHREADS;
      int end = (tid+1) * (NITERATIONS/NTHREADS) - 1;
  
      //loop through every pixel
      for(y = 0; y &lt; h; y++) {
          for(x = 0; x &lt; w; x++) {
              // calculate the initial real and imaginary part of z, 
              // based on the pixel location and zoom and position values
              pr = 1.5 * (x - w / 2) / (0.5 * zoom * w) + moveX;
                  pi = (y - h / 2) / (0.5 * zoom * h) + moveY;
                  newRe = newIm = oldRe = oldIm = 0; //these should start at 0,0
                  // i will represent the number of iterations
                  int i;
                  // start the iteration process
                  for(i = start; i &lt;= end; i++) {
                          // remember value of previous iteration
                          oldRe = newRe;
                          oldIm = newIm;
                          // the actual iteration, the real and imaginary part are calculated
                          newRe = oldRe * oldRe - oldIm * oldIm + pr;
                          newIm = 2 * oldRe * oldIm + pi;
                          // if the point is outside the circle with radius 2: stop
                          if((newRe * newRe + newIm * newIm) &gt; 4) break;
                  }
  
                  if(i == NITERATIONS)
                  color(m, x, y, 0, 0, 0); // black
              else
              {
                  // normalized iteration count method for proper coloring
                  double z = sqrt(newRe * newRe + newIm * newIm);
                  int brightness = 256. * log2(1.75 + i - log2(log2(z))) / log2((double)NITERATIONS);
                  color(m, x, y, brightness, brightness, 255);
              }
  
              }
      }
  
  }
  
  // worker function which will be passed to pthread_create function
  void *worker(void *arg)
  {
      int tid = (int)arg;
      mandelbrot(tid);
  }
  
  
  int main(int argc, char *argv[])
  {
      pthread_t* threads;
      int i, j, rc;
  
      if(argc != 3)
      {
          printf("Usage: %s &lt;no_of_iterations&gt; &lt;no_of_threads&gt; &gt; output.ppm\n", argv[0]);
          exit(1);
      }
  
      NITERATIONS = atoi(argv[1]);
      NTHREADS = atoi(argv[2]);
      threads = (pthread_t*)malloc(NTHREADS * sizeof(pthread_t));
  
      m = malloc(400 * sizeof(rgb *));
      for(i = 0; i &lt; 400; i++)
          m[i] = malloc(600 * sizeof(rgb));
  
      // declaring the needed variables for calculating the running time
      struct timespec begin, end;
      double time_spent;
  
      // starting the run time
      clock_gettime(CLOCK_MONOTONIC, &amp;begin);
  
      printf("P6\n# AUTHOR: ET\n");
      printf("%d %d\n255\n",600,400);
  
      for(i = 0; i &lt; NTHREADS; i++) {
          rc = pthread_create(&amp;threads[i], NULL, worker, (void *)i);
          assert(rc == 0); // checking whether thread creating was successfull
      }
  
      for(i = 0; i &lt; NTHREADS; i++) {
          rc = pthread_join(threads[i], NULL);
          assert(rc == 0); // checking whether thread join was successfull
      }
  
      // printing to file
      for(i = 0; i &lt; 400; i++) {
          for(j = 0; j &lt; 600; j++) {
              fputc((char)m[i][j].r, stdout);
              fputc((char)m[i][j].g, stdout);
              fputc((char)m[i][j].b, stdout);
          }
      }
  
      // ending the run time
      clock_gettime(CLOCK_MONOTONIC, &amp;end);
  
      // calculating time spent during the calculation and printing it
      time_spent = end.tv_sec - begin.tv_sec;
      time_spent += (end.tv_nsec - begin.tv_nsec) / 1000000000.0;
      fprintf(stderr, "Elapsed time: %.2lf seconds.\n", time_spent);
  
      for(i = 0; i &lt; 400; i++)
          free(m[i]);
      free(m);
  
      free(threads);
  
      return 0;
  }
  </code></pre>