Welcome to Fractal Forums

Fractal Software => Programming => Topic started by: madmuppet on April 27, 2011, 01:54:15 PM




Title: large size mandelbrot
Post by: madmuppet on April 27, 2011, 01:54:15 PM
I am trying to draw large images with a program I wrote in c along with sdl as the graphic component.

I can generate images up to ~6000 * 4000 but when I tried a much larger image ~ 60,000 * 40,000 my program segment faults ..

the ultimate aim is to print off an image and hang it on the wall .. Im looking at using the golden ratio so the image will be in the region of 1.618 * 1m

I have been looking online for ideas .. there are a lot about drawing the mandelbrot set .. I am still looking for anything related to drawing large images.

Im pretty sure I have reached the limit going in the direction I have been so I need to look elsewhere .. so any ideas on how to go about this is appreciated ..

currently I am looking at using an array to store the colors and write to a file then try and convert to an image ..

hope I am not too vague thanks for any help al.

any questions or if you want to see what I am doing so far np ..:p



Title: Re: large size mandelbrot
Post by: bib on April 27, 2011, 02:11:31 PM
Iwhen I tried a much larger image ~ 60,000 * 40,000 my program segment faults ..

the ultimate aim is to print off an image and hang it on the wall .. Im looking at using the golden ratio so the image will be in the region of 1.618 * 1m

Why such a large size? To print in 300 dpi and 1,6x1m you need about 19000x12000 pixels.


Title: Re: large size mandelbrot
Post by: panzerboy on April 27, 2011, 03:51:13 PM
It depends on your printing technology. Colour Lasers can't vary the droplet size so to achieve grays or different levels of colour they have to dither the dots. If thats the case theres no need to supply an image at the maximum resolution calculated by image size X DPI. Some Inkjets can vary the droplet size the following page says of how Epson can achieve 5 different droplet sizes,
http://www.epson.com.sg/epson_singapore/explore_epson/innovation/micro_piezo.page
5 levels of droplet size plus no droplet is 6 shades, 256/6 is 42.66.. squareroot is about 6.5 so you'd still need a 6.5x6.5 array of dots to give 256 shades 1440/6.5 is 221.5 DPI. At 1mX1.618m thats 8722 X 14,112.


Title: Re: large size mandelbrot
Post by: Fractal Ken on April 27, 2011, 05:25:46 PM
I can generate images up to ~6000 * 4000 but when I tried a much larger image ~ 60,000 * 40,000 my program segment faults ..

If your program is 32 bit (as opposed to 64 bit), you're probably attempting to address more memory than is possible.


Title: Re: large size mandelbrot
Post by: madmuppet on April 28, 2011, 05:50:15 AM
I have a dual boot machine running 32 bit xp and 64 bit lenny debian.

on xp I have a virtualbox debian wheezy 32 bit machine where I have been writing the program. the program works fine on both the virtual machine and the full lenny debian ..

my machine is an amd quad core phenom 2 940 running 4 gig ram and a 1gb 4870 ..

my guess is the graphics card is having problems so anyways ideas on finding a way of representing an image this size appreciated


Title: Re: large size mandelbrot
Post by: Softology on May 01, 2011, 05:35:50 AM
Don't store the entire image data in memory.  Calculate the pixels as normal and write/stream the bytes directly to an image file.  I use BMP as the format as it is fairly simple to write the raw bytes header and image data.  http://en.wikipedia.org/wiki/BMP_file_format

Once you have your huge BMP file, you can convert it to JPG/PNG/etc in Photoshop if needed.

That method allows huge images and the only limitation is disk space.

Jason.


Title: Re: large size mandelbrot
Post by: madmuppet on May 01, 2011, 10:06:52 AM
thanks for the info .. I am having a look at it now.

cheers al.


Title: Re: large size mandelbrot
Post by: madmuppet on May 12, 2011, 01:25:25 AM
I have been busy learining how to open and write to a bmp file .. I have one question though .. what is the practical limit for a file?

how big can I draw a pic before its too big to open?

thanks for the help al.


Title: Re: large size mandelbrot
Post by: zenzero-2001 on May 15, 2011, 03:29:42 AM
Hi

I'm not sure if there is a file size limit on bmp, but I have created files over a Gb in size with no problem. So long as you have enough memory in your computer it will be easy to open the resultant file. If you run out of memory, the computer will use the hard disk as virtual memory and this will be slow - but it should get there eventually.

It has been awhile since I coded it, but if I remember correctly, I had a bitmap of one pixel height and the required width in memory and I would append this to the file after calculating each row of the fractal. Here is some old code I wrote:

Code:
struct BMPHeader
{
short bfType;   // "BM"
int bfSize;           // Size of file in bytes
int bfReserved;       // set to 0
int bfOffBits;        // Byte offset to actual bitmap data (= 54)
int biSize;           // Size of BITMAPINFOHEADER, in bytes (= 40)
int biWidth;          // Width of image, in pixels
int biHeight;         // Height of images, in pixels
short biPlanes;       // Number of planes in target device (set to 1)
short biBitCount;     // Bits per pixel
int biCompression;    // Type of compression (0 if no compression)
int biSizeImage;      // Image size, in bytes (0 if no compression)
int biXPelsPerMeter;  // Resolution in pixels/ meter of display device
int biYPelsPerMeter;  // Resolution in pixels/ meter of display device
int biClrUsed;        // Number of colors in the color table (if 0, use maximum allowed by biBitCount)
int biClrImportant;   // Number of important colors. If 0, all colors are important
};


class RenderObject
{
private:
FILE* file;
struct BMPHeader bmph;
int bytesPerLine;

public:
RenderObject(void)
{
file = NULL;
}

bool OpenFile(char* filename, int width, int height)
{
bytesPerLine = 4 * width;

bmph.bfType = 0x4D42;
bmph.bfOffBits = 54;
bmph.bfSize = bmph.bfOffBits + bytesPerLine * height;
bmph.bfReserved = 0;
bmph.biSize = 40;
bmph.biWidth = width;
bmph.biHeight = -height;
bmph.biPlanes = 1;
bmph.biBitCount = 32;
bmph.biCompression = 0;
bmph.biSizeImage = bytesPerLine * height;
bmph.biXPelsPerMeter = 0;
bmph.biYPelsPerMeter = 0;
bmph.biClrUsed = 0;       
bmph.biClrImportant = 0;

errno_t err = fopen_s(&file, filename, "wb");

if(err != 0)
{ return false; }
 
fwrite(&bmph.bfType, 2, 1, file);
fwrite(&bmph.bfSize, 4, 1, file);
fwrite(&bmph.bfReserved, 4, 1, file);
fwrite(&bmph.bfOffBits, 4, 1, file);
fwrite(&bmph.biSize, 4, 1, file);
fwrite(&bmph.biWidth, 4, 1, file);
fwrite(&bmph.biHeight, 4, 1, file);
fwrite(&bmph.biPlanes, 2, 1, file);
fwrite(&bmph.biBitCount, 2, 1, file);
fwrite(&bmph.biCompression, 4, 1, file);
fwrite(&bmph.biSizeImage, 4, 1, file);
fwrite(&bmph.biXPelsPerMeter, 4, 1, file);
fwrite(&bmph.biYPelsPerMeter, 4, 1, file);
fwrite(&bmph.biClrUsed, 4, 1, file);
fwrite(&bmph.biClrImportant, 4, 1, file);

return true;
}

void Render(int* ptr)
{
fwrite(ptr, bytesPerLine, 1, file);
}

void CloseFile(void)
{
fclose(file);
}
};

I pass a pointer of the bitmap row in memory to the method Render at the end of each row. That way I only have to store a one row bitmap in memory at a time.

It is possible to make super high-res images this way and then resize them down in Photoshop or GIMP to obtain "anti-aliasing".

Hope this helps!

zenzero-2001


Title: Re: large size mandelbrot
Post by: zenzero-2001 on May 15, 2011, 01:26:43 PM
Hi

I just did some testing and I have been able to create a 20,000 x 20,000 pixel image and successfully load into GIMP (haven't tried Photoshop). It took a short while though. The file size was 1.5Gb and GIMP used over 1.2Gb memory to load it - I'm lucky, I have 8Gb in my machine :) I will have a try with some larger images.

zenzero-2001


Title: Re: large size mandelbrot
Post by: zenzero-2001 on May 15, 2011, 02:10:27 PM
My program is written in .NET and I have been running it under WINE in Linux, it crashes when trying to create images a bit larger than 20,000 x 20,000 with bad memory allocation. Running natively with Windows, I successfully created a 32,768 x 32,768 image - I was not able to create anything larger because of the 4Gb file size limit with FAT32. The 32,768 x 32,768 image comes to 4Gb exactly. I tried for 64,000 x 48,000, it seemed to be rendering fine until it hit the limit and stopped.

I'm just copying the 32,768 x 32,768 file to my usb stick so I can try and open it in my 8Gb Linux machine. My Windows machine only has 1.5Gb, so I don't think I will even try opening it on that :)

zenzero-2001


Title: Re: large size mandelbrot
Post by: zenzero-2001 on May 15, 2011, 02:13:04 PM
By the way a 64,000 x 48,000 32bit bmp image will take up 11.4 Gb disk space!


Title: Re: large size mandelbrot
Post by: zenzero-2001 on May 15, 2011, 02:45:41 PM
I'm using 32 bit bmps in my program, if I used 24bit then the file size would be smaller.

Correction to my earlier statement about 32,768 x 32,768 coming to 4Gb exactly, it is actually a bit larger because of the header - so that would take it over the 4Gb FAT32 limit. I wasn't therefore able to open it due to it being an invalid bmp file.



Title: Re: large size mandelbrot
Post by: madmuppet on May 26, 2011, 12:35:07 AM
thanks for all the info zenzero ..

I can now write a mandelbrot set to bitmap and view it in my browser .. however when I try and open it in the gimp I get an error reading bmp file header for the image.

if anyone wants to look at the code and give some pointers feel free ..

Code:
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<inttypes.h>
#define SMOOTH log( 0.5 * log( window->ESCAPE ))

//prototyping the structures ..

struct window{
  int xscreen,yscreen,Nxscreen,Nyscreen;
  unsigned long long int MAX,ESCAPE;
  long double ximage,yimage,xoff,yoff;
}wdw,*window;

struct bmpfile{
  unsigned char    magic[2];
}bf,*bfp;

struct fileheader{
  uint32_t         filesize;
  uint16_t         creator1;
  uint16_t         creator2;
  uint32_t         bmpoffset;
}fh,*fhp;

struct bmpinfoheader{
  uint32_t        headersize;
  int32_t         width;
  int32_t         height;
  uint16_t        nplanes;
  uint16_t        bitsperpixel;
  uint32_t        compressiontype;
  uint32_t        bitmapbytesize;
  int32_t         hres;
  int32_t         vres;
  uint32_t        ncolors;
  uint32_t        nimpcolors;
}bh,*bhp;

struct rgb{
  unsigned char r;
  unsigned char g;
  unsigned char b;
 };

//prototype the functions ..

struct rgb *color(  long long int count,struct window* window, struct rgb* thc, int c );
int multiply(long double real, long double imaginary,struct window* window );
void control( struct window* window, int bpl,struct bmpfile* bfp,
      struct fileheader* fhp,struct bmpinfoheader* bhp );
void start();
//color gives four values for color red green blue ..
struct rgb *color( long long int count, struct window* window, struct rgb* thc,int x ){
  int d, r, c = 1,cn, red = 0, green = 0, blue = 0;
 
  cn = count % 512;

  //if the count is over the max then the color should be black ..

  if(count == window->MAX){
    thc[x].b = 0;
    thc[x].g = 0;
    thc[x].r = 0;
    return( thc );
  }
  //otherwise find a color ..
  while(( cn % 256 ) != 0 ){
    d = cn / 256;
    r = cn % 256;
   
    switch( c ){
    case 1: red = r;
      break;
    case 2: green = r;
      break;
    case 3: blue = r;
      break;
    default:printf("shit happens\n");
    }
    cn = d;
    ++c;
   }
  //put color into struct array .. single dimension array of screen width size ..
  //will write a single line ( row ) at a time.

   thc[x].b = blue * 4;
   thc[x].g = green * 8;
   thc[x].r = red * 16;
   return(thc);
}
// multiply is an iterative process which returns a count which is
// converted into a color.
int multiply(long double real, long double imaginary, struct window* window ){

  unsigned long long int count = 1;
  long double x,y,z = 0,xx,yy,tempr = real,tempi = imaginary;
  //made some significant speed gains in control function by trying to use less division
  //so tried it here z is computed once used 3 times ..

  while( count < window->MAX &&
  abs( z ) < window->ESCAPE ){
    x = tempr * tempr;
    y = tempi * tempi;
    z = tempr * tempi;

    xx = x - y;
    yy = 2 * z;
    z = x + y;

    tempr = real + xx;
    tempi = imaginary + yy;
    count++;
  }
  if(count >= window->MAX ){
    return count;
  }
  return ( count - ( log( 0.5 * log( z )) - SMOOTH ) / log( 2 ));
}
void control( struct window* window, int bpl,struct bmpfile* bfp,
      struct fileheader* fhp,struct bmpinfoheader* bhp ){

  //create the array to hold each line colors ..
  int x,y,count;
  long double real,imaginary, convx,convy;

  struct rgb array[ bpl ];
  struct rgb *thc;
  thc = array;
 
  FILE *fp;

  printf("control\n");

  //zero array ..
  for(count = 0; count < window->Nxscreen -1; count++ ){
    array[x].b = 0;
    array[x].g = 0;
    array[x].r = 0;
    //    array[x].reserve = 50;
   }
  //write the headers for the bitmap ..

  fp = fopen("image-01.bmp","wb");
  fwrite(bfp,sizeof(bf),1,fp);
  fwrite(fhp,sizeof(fh),1,fp);
  fwrite(bhp,sizeof(bh),1,fp);
 
  //save time divide once use many times ..
  // numbers give an imaginary number for each pixel ..

  convx =  window->ximage / window->Nxscreen;
  convy =  window->yimage / window->Nyscreen;

  for( y = window->Nyscreen; y < 0; y++ ){
    for( x = 1; x < window->Nxscreen;  x++ ){
      real = convx * x - window->xoff;
      imaginary = window->yoff - ( convy * y );
      count = multiply( real, imaginary, window ); 
      color( count, window, thc, x );
    } 
    //should have a full array here .. write it out .. I know the bitmap starts from
    //bottom left to top right but all I want at this stage is something close to mandelbrot set.
    //I have tried to accomadate this by starting y at max and reducing to zero.
    fwrite(&array,sizeof(array),1,fp);
   }
  fclose( fp );
}
void start( ){
  //setting the conditions for the bitmap .. also screen size and image size.
 
  int bpl;
  bfp = &bf;
  fhp = &fh;
  bhp = &bh;
  window = &wdw;
 
  window->MAX = 128;//can and will change these later
  window->ESCAPE = 4;

  window->xscreen = 809;
  window->yscreen = -500;

  window->Nxscreen = window->xscreen;
  window->Nyscreen = window->yscreen;
 
 //make sure the screen is divisible by 4 ..
  bpl = window->Nxscreen;
  while(bpl % 4 != 0){
    bpl++;
  }
  window->ximage = 3.2; //I am going to draw small set with sdl .. when I see something I like
  window->yimage = 2.0; //I will draw it with this program .. so these conditions will change ..
  window->xoff = 2.2;      //a data struct in my sdl program holds the info and writes it out for me.
  window->yoff = 1.0;

  bfp->magic[0] = 'B';
  bfp->magic[1] = 'M';
 
  fhp->filesize = fhp->bmpoffset + abs(window->Nyscreen * bpl);//being lazy I do not want to compute these each
  //time.
  fhp->bmpoffset = 54;
  fhp->creator1 = 0;
  fhp->creator2 = 0; 
 
  bhp->width = bpl;
  bhp->height = - window->Nyscreen;
  bhp->nplanes = 1;
  bhp->bitsperpixel = 24;
  bhp->compressiontype = 0;
  bhp->bitmapbytesize = bpl * bhp->height;
  bhp->hres = 2835;
  bhp->vres = 2835;
  bhp->ncolors = 0;
  bhp->nimpcolors = 0;
  bhp->headersize = bhp->bitsperpixel + bhp->bitmapbytesize;
 
  control( window,bpl,bfp,fhp,bhp );
}
int main( int argc, char * argv[] ){
  printf("main\n");

  start(); //GO!!
  return(0);
}



Title: Re: large size mandelbrot
Post by: madmuppet on May 28, 2011, 12:50:20 PM
finally got it working .. currently in process of testing a 27,000 x 15,000 pixel mandelbrot set ..

adjusted the headersize in my last program and brought together two of the strutures .. it works in my webrowser and gimp as well .. yay!

no to come up with a good color scheme .. any ideas?


Title: Re: large size mandelbrot
Post by: Tux89 on May 29, 2011, 07:58:50 PM
Hi, I've tried to implement that approach in my .net software and works great! I can render 32768*32768 either with opencl (one row at time).
After I've created the image I can't open it. Photoshop says that the bitmap header is corrupted, but I've check and it's ok. I thinks it's because I've only 4GB of ram...
Anyway, what do you mean with "color scheme"? it's corrupted or just you don't like it? I get corrupted image at the first because I have not managed the image padding.


Title: Re: large size mandelbrot
Post by: madmuppet on May 30, 2011, 03:04:43 AM
I was using another coloring scheme that produced very blue pictures .. just this morning I have implemented smooth coloring properly and its made a huge difference ..

I want to use my first program to find nice shots and then crunch it with my second .. lets me use the computer without having to worry about clicking on the mandelbrot set picture and wrecking hours of work ..

Im going to try and merge them together but just happy that today it works ..

heres my code the first uses c and sdl the second straight c .. Im using debian squeeze amd64 and gcc 4.4.5

regards the padding the only problem I have is that the image has to be a multiple of 4 pixels wide .. so my image which should be 809 x 500 is 812 x 500 which leaves a 3 pixel wide black side edge .. something Im prepared to put up with ..

pressing keyboard 2 doubles image size
pressing 3 increases both max iterations and escape value
pressing 4 doubles both max iterations and escape value
pressing b takes you back .. first time you have to press twice .. because it draws the same screen again before going back
press s to save
press esc to quit.

program two pump the values in and wait .. default to the whole set and a very low number of iterations ..

next step is using bignums ..
Code:
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<SDL/SDL.h>
 
#define smooth log( 0.5 * log( window->ESCAPE ))

SDL_Surface *screen;
SDL_Event event;

struct window{
  int xscreen,yscreen,Nxscreen,Nyscreen;
  int a,b,c,d;
  unsigned long long int MAX,ESCAPE;
  long double ximage,yimage,xoff,yoff;
};

struct data{
  int Nxscreen[50],Nyscreen[50];
  long double ximage[50],yimage[50],xoff[50],yoff[50];
};

struct pxcolor{
  int r;
  int g;
  int b;
}arraycolor[512],*prgb;

void write_data(struct data* data);
struct window *image_size( struct window* window );
struct window *window_size( struct window* window );
struct window *mouse( int z, struct window* window );
void putpixel( int x, int y, Uint32 colors );
Uint32 getcolor( int count,struct window* window, struct pxcolor* prgb );
int multiply(long double real, long double imaginary,struct window* window );
void numbers( struct window* window, struct pxcolor* prgb );
void repeat( struct window* window, struct pxcolor* prgb );
void control( struct window* window, struct data* data, struct pxcolor* prgb );
void start( );
void numbers( struct window* window, struct pxcolor* prgb );
void unlock();
void lock();
void sdl( struct window* window );

void write_data(struct data* data){
  FILE *fp;
  int c;
 
  fp = fopen("image_info","w");
  for(c = 0;c < 50; c++){
    fprintf(fp,"c = %i\n",c);
    fprintf(fp,"Nxscreen = %i\n",data->Nxscreen[c]);
    fprintf(fp,"Nyscreen = %i\n",data->Nyscreen[c]);
   
    fprintf(fp,"ximage = %.40Lf\n",data->ximage[c]);
    fprintf(fp,"yimage = %.40Lf\n",data->yimage[c]);
   
    fprintf(fp,"xoff = %.40Lf\n",data->xoff[c]);
    fprintf(fp,"yoff = %.40Lf\n",data->yoff[c]);
  }
  fclose(fp);
}
struct window *image_size( struct window* window ){
  long double s,t,u,v,z;

  z = window->ximage / window->Nxscreen;
  s = z * window->c - window->xoff;
  u = z * window->a - window->xoff;
 
  z = window->yimage / window->Nyscreen; 
  t = window->yoff - ( z * window->d );
  v = window->yoff - ( z * window->b );
 
  window->ximage = u - s;
  window->yimage = t - v;
  window->xoff = -s;
  window->yoff = t;
  return window;
}
struct window *window_size( struct window* window ){

  int t;
   
  window->Nxscreen = window->a - window->c;
  window->Nyscreen = window->b - window->d;
 
  if( window->Nxscreen > window->Nyscreen ){
    t = window->xscreen / window->Nxscreen;
  }
  else{
    t = window->yscreen / window->Nyscreen;
  }

  window->Nxscreen = window->Nxscreen * t;
  window->Nyscreen = window->Nyscreen * t;
  return window;
}
struct window *mouse( int z, struct window* window ){
 
  if( z == 1 ){
    window->c = event.button.x;
    window->d = event.button.y;
  }
  if( z != 1 ){
    window->a = event.button.x;
    window->b = event.button.y;
  }
  return window; 
}
void putpixel( int x, int y, Uint32 colors ){

  Uint32 *bufp;
  bufp = ( Uint32 *)screen->pixels + y*screen->pitch / 4 + x;
  *bufp = colors;
}
Uint32 getcolor( int count, struct window* window, struct pxcolor* prgb ){
  int  red = prgb[( count % 512 )].r;
  int  green = prgb[( count % 512 )].g;
  int blue = prgb[( count % 512 )].b;
  Uint32 colors;
   if(count == window->MAX){
     return( colors = SDL_MapRGB(screen->format,0,0,0));
   }
   else{
     return colors = SDL_MapRGB(screen->format,
( blue ),( green ),( red ));
   }
}
int multiply(long double real, long double imaginary, struct window* window ){

  int count = 1;
  long double x,y,z = 0,xx,yy,tempr = real,tempi = imaginary;
 
  while( count < window->MAX &&
  abs( z ) < window->ESCAPE ){
    x = tempr * tempr;
    y = tempi * tempi;
    z = tempr * tempi;

    xx = x - y;
    yy = 2 * z;
    z = x + y;
 
    tempr = real + xx;
    tempi = imaginary + yy;
    count++;
  }
  if(count >= window->MAX ){
    return count;
  }
  else{
    return ( count - ( log( 0.5 * log( z )) - smooth ) / log( 2 ));
  }
}
void numbers( struct window* window, struct pxcolor* prgb ){
 
  int x,y,count;
  Uint32 colors;
  long double real,imaginary, convx,convy;
 
  convx =  window->ximage / window->Nxscreen;
  convy =  window->yimage / window->Nyscreen;

  for( x = 1; x < window->Nxscreen; x++ ){
    for( y = 1; y < window->Nyscreen; y++ ){
      real = convx * x - window->xoff;
      imaginary = window->yoff - ( convy * y );
      count = multiply( real, imaginary, window );
      colors = getcolor( count, window, prgb);
      putpixel( x, y, colors );
    }
  }SDL_UpdateRect( screen,0,0,window->Nxscreen,window->Nyscreen );
  printf("draw finish\n");
}
void repeat( struct window* window, struct pxcolor* prgb){

  sdl( window );
  lock();
  numbers( window,prgb );
  unlock();
}
void control(struct window* window, struct data* data, struct pxcolor* prgb ){

  int c = 1;
  int z = 1;

  while( SDL_WaitEvent( &event )){
    switch( event.type ){
    case SDL_MOUSEBUTTONDOWN:{
      if (event.button.button == SDL_BUTTON_LEFT){
      mouse( z, window );
      if( z != 1 ){

image_size( window );
window_size( window );

data->Nxscreen[c] = window->Nxscreen;
data->Nyscreen[c] = window->Nyscreen;
data->ximage[c] = window->ximage;
data->yimage[c] = window->yimage;
data->xoff[c] = window->xoff;
data->yoff[c] = window->yoff;

c++;
repeat( window, prgb  );
      }
         z = -z;
      }

break;
      }
    case SDL_KEYDOWN:{

      /***DOUBLE WINDOW SIZE***/
      if( event.key.keysym.sym == SDLK_2 ){
window->Nxscreen = window->Nxscreen * 2;
window->Nyscreen = window->Nyscreen * 2;
repeat( window, prgb  );
      }

      if( event.key.keysym.sym == SDLK_3 ){
window->MAX = 4096;
window->ESCAPE = 100;
repeat( window, prgb  );
      }
      if( event.key.keysym.sym == SDLK_4 ){
window->MAX = window->MAX * 2;
window->ESCAPE = window->ESCAPE * 2;
repeat( window, prgb  );
      }
      if( event.key.keysym.sym == SDLK_b ){
c = c - 1;
window->Nxscreen = data->Nxscreen[c];
window->Nyscreen = data->Nyscreen[c];

window->ximage = data->ximage[c];
window->yimage = data->yimage[c];

window->xoff = data->xoff[c];
window->yoff = data->yoff[c];
repeat( window, prgb  );
      }
       if( event.key.keysym.sym == SDLK_s ){
SDL_SaveBMP( screen, "shot.bmp" );
      }
       if( event.key.keysym.sym == SDLK_ESCAPE ){
write_data(data);
return( SDL_Quit());
      }
      break;
    }
    }}

}
void unlock(){

   if( SDL_MUSTLOCK( screen )){   
    SDL_UnlockSurface( screen );
  }
}
void lock(){
           
  if( SDL_MUSTLOCK( screen )){
    if( SDL_LockSurface( screen ) < 0 ){
      return;
    }
  }
}
void sdl( struct window* window ){

  SDL_Init( SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE );
  SDL_WM_SetCaption("smooth.c",NULL);
 
              screen = SDL_SetVideoMode
( window->Nxscreen,window->Nyscreen,
  32,SDL_SWSURFACE ); 
}

void start( ){
 
  int c;
  struct window wdw;
  struct window *window;
  window = &wdw;

  struct data dta;
  struct data *data;
  data = &dta;
  prgb = arraycolor;

  window->MAX = 128;
  window->ESCAPE = 4;
  window->xscreen = 809;
  window->yscreen = 500;
  window->Nxscreen = window->xscreen;
  window->Nyscreen = window->yscreen;
  window->ximage = 3.2;
  window->yimage = 2.0;
  window->xoff = 2.2;
  window->yoff = 1.0;


  for(c = 0; c < 50; c++){
    data->Nxscreen[c] = 0;
    data->Nyscreen[c] = 0;
    data->ximage[c] = 0;
    data->yimage[c] = 0;
    data->xoff[c] = 0;
    data->yoff[c] = 0;
  }
  //make sure initial image is avaliable so no further attempt to go back is made.
  data->Nxscreen[0] = 809;
  data->Nyscreen[0] = 500;
  data->ximage[0] = 3.2;
  data->yimage[0] = 2.0;
  data->xoff[0] = 2.2;
  data->yoff[0] = 1.0;

  for( c = 0; c < 512; c++ ){
    prgb[c].r = 0;
    prgb[c].g = 0;
    prgb[c].b = 0;
  }

  for( c = 0; c < 512; c++ ){
    prgb[c].r = c % 256;
    prgb[c].g = ( c + 32 ) % 256;
    prgb[c].b = ( c + 64 ) % 256;
  }
  repeat( window, prgb );
  control( window, data, prgb ); 
}
int main( int argc, char * argv[] ){
 
  start();
  return(0);
}


and the 2nd

Code:
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<inttypes.h>
#define smooth log( 0.5 * log( window->ESCAPE ))

//prototyping the structures ..

struct window{
  int Nxscreen,Nyscreen;
  unsigned long long int MAX,ESCAPE;
  long double ximage,yimage,xoff,yoff;
}wdw,*window;

struct pxcolor{
  int r[512];
  int g[512];
  int b[512];
}rgb,*prgb;

struct bmp{
  unsigned char magic[2];    // "BM"
}bfp,*bf
;
struct header{
  uint32_t filesize;                   // Size of file in bytes
  uint16_t creator1;                   //Set to 0
  uint16_t creator2;                   // Set to 0
  uint32_t offset;                     // Byte offset to actual bitmap data (= 54)
  uint32_t headersize;                 // Size of BITMAPINFOHEADER, in bytes (= 40)
  int32_t width;                       // Width of image, in pixels
  int32_t height;                      // Height of images, in pixels
  uint16_t nplanes;                    // Number of planes in target device (set to 1)
  uint16_t bitsperpixel;               // Bits per pixel
  uint32_t compressiontype;            // Type of compression (0 if no compression)
  uint32_t bitmapbytesize;             // Image size, in bytes (0 if no compression)<----remember 0
  int32_t hres;                        // Resolution in pixels/ meter of display device
  int32_t vres;                        // Resolution in pixels/ meter of display device
  uint32_t ncolors;                    // Number of colors in the color table (if 0, use maximum allowed by biBitCount)
  uint32_t nimpcolors;                 // Number of important colors. If 0, all colors are important
}bmp,*hp;

struct rgb{
  unsigned char r;
  unsigned char g;
  unsigned char b;
 };

//prototype the functions ..

struct rgb *color(  long long int count,struct window* window,
    struct rgb* thc, int x,
    struct pxcolor* prgb );
int multiply(long double real, long double imaginary,struct window* window );
void control( struct window* window, int bpl, struct header* hp,
      struct bmp* bf, struct pxcolor* prgb );
void start();

struct rgb *color( long long int count, struct window* window,
   struct rgb* thc,int x,
   struct pxcolor* prgb ){
  int  red = prgb->r[count];
  int  green = prgb->g[count];
  int blue = prgb->b[count];

  if(count == window->MAX){
    thc[x].b = 0;
    thc[x].g = 0;
    thc[x].r = 0;
    return( thc );
  }
  else{
   thc[x].b = blue;
   thc[x].g = green;
   thc[x].r = red;
   return(thc);
  }
}
// multiply is an iterative process which returns a count which is
// converted into a color.
int multiply(long double real, long double imaginary, struct window* window ){

  unsigned long long int count = 1;
  long double x,y,z = 0,xx,yy,tempr = real,tempi = imaginary;

  while( count < window->MAX &&
  abs( z ) < window->ESCAPE ){
    x = tempr * tempr;
    y = tempi * tempi;
    z = tempr * tempi;

    xx = x - y;
    yy = 2 * z;
    z = x + y;

    tempr = real + xx;
    tempi = imaginary + yy;
    count++;
  }
  if(count >= window->MAX ){
    return count;
  }
  return ( count - ( log( 0.5 * log( z )) - smooth ) / log( 2 ));
}
void control( struct window* window, int bpl, struct header* hp,
      struct bmp* bf, struct pxcolor* prgb ){

  //create the array to hold each line colors ..
  int x,y,count;
  long double real,imaginary, convx,convy;
  struct rgb array[ bpl ];
  struct rgb *thc;
  thc = array;
 
  FILE *fp;

  //zero array ..
  for(count = 0; count < window->Nxscreen -1; count++ ){
    thc[x].b = 0;
    thc[x].g = 0;
    thc[x].r = 0;
    //    array[x].reserve = 50;
   }
  //write the headers for the bitmap ..

  fp = fopen("image-01.bmp","wb");
  fwrite(bf,sizeof(bfp),1,fp); 
  fwrite(&bmp,sizeof(bmp),1,fp);
 
  //imaginary number for each pixel

  convx =  window->ximage / window->Nxscreen;
  convy =  window->yimage / window->Nyscreen;

  for( y = window->Nyscreen; y < 0; y++ ){
    for( x = 1; x < window->Nxscreen;  x++ ){
      real = convx * x - window->xoff;
      imaginary = window->yoff - ( convy * y );
      count = multiply( real, imaginary, window ); 
      color( count, window, thc, x, prgb );
    } 
    //should have a full array here .. write it out .. draw line by line
    fwrite(&array,sizeof(array),1,fp);
   }
  fclose( fp );
}
void start( ){
  //setting the conditions for the bitmap .. also screen size and image size.
 
  int bpl;
  int c;
  window = &wdw;
  hp = &bmp;
  bf = &bfp;
  struct pxcolor arraycolor;
  prgb = &arraycolor;

  window->MAX = 1028;
  window->ESCAPE = 400;
  window->Nxscreen = 809;
  window->Nyscreen = -500;
  window->ximage = 3.2; 
  window->yimage = 2.0;
  window->xoff = 2.2;   
  window->yoff = 1.0;
 
 //make sure the Nxscreen is divisible by 4 ..
  bpl = window->Nxscreen;
  while(bpl % 4 != 0){
    bpl++;
  }
  bf->magic[0] = 'B';
  bf->magic[1] = 'M';
  hp->creator1 = 0;
  hp->creator2 = 0;
  hp->offset = 54;
  hp->filesize = hp->offset + (window->Nyscreen * bpl);
  hp->width = bpl;
  hp->height = -window->Nyscreen;
  hp->nplanes = 1;
  hp->bitsperpixel = 24;
  hp->compressiontype = 0;
  hp->bitmapbytesize = bpl * hp->height;
  hp->hres = 2835;
  hp->vres = 2835;
  hp->ncolors = 0;
  hp->nimpcolors = 0;
  hp->headersize = hp->bitsperpixel + hp->bitmapbytesize;

  //initialise all pxcolor elements to zero
  for( c = 0; c < 512; c++ ){
    prgb->r[c] = 0;
    prgb->g[c] = 0;
    prgb->b[c] = 0;
  }
  for( c = 0; c < 512; c++ ){
    prgb->r[c] = c % 256;
    prgb->g[c] = ( c + 32 ) % 256;
    prgb->b[c] = ( c + 64 ) % 256;
  }
  control( window,bpl,hp,bf,prgb );
}
int main( int argc, char * argv[] ){
  start(); //GO!!
  return(0);
}


Title: Re: large size mandelbrot
Post by: Tux89 on May 30, 2011, 12:35:16 PM
I'm at the university by now, when i come back home I can post my "padding solution"!.
Can I try your color scheme in my program? I prefer blue pictures but I don't know how to render them.


Title: Re: large size mandelbrot
Post by: Tux89 on May 30, 2011, 06:26:51 PM
Code:
byte[] LinePadding(byte[] line, int width)
{
    //byte to add
    int padding = 0;

    //while width * 3 (rgb) + padding isn't a multiple of 4, add pad byte
    while (((width * 3 + padding) % 4) != 0)
        padding++;

    //if pad isn't needed
    if(padding <= 0)
        return line;

    //Create new array with all elements = 0
    byte[] newLine = new byte[width * 3 + padding];

    //Copy old line in new padded line (left the extra byte = 0)
    Array.Copy(line, newLine, line.Length);

    //return padded line
    return newLine;
}



Title: Re: large size mandelbrot
Post by: madmuppet on May 30, 2011, 11:35:32 PM
thanks Tux89 I use something like that ..

the smooth coloring was explained to me here by Dave Mankin a few months back .. I just got around to adding an array of colors .. I was recently still using an idea I had a while ago which is not so good.

help yourself to the code if its of any use ..:p

(http://img268.imageshack.us/img268/1954/shothl.th.jpg) (http://img268.imageshack.us/i/shothl.jpg/)

Uploaded with ImageShack.us (http://imageshack.us)


Title: Re: large size mandelbrot
Post by: Tux89 on May 31, 2011, 10:22:48 AM
Thanks! Anyway confirm that Photoshop and Gimp says "Bitmap Header corrupted" if you haven't enough ram. Before change you're code check if it's the problem, because I can open my "corrupted" 32768 x 32768 image on computers with 16GB of ram.


Title: Re: large size mandelbrot
Post by: zenzero-2001 on June 02, 2011, 12:50:00 AM
Glad you got the large bitmap code working.

A nice colour scheme is the one used in the wikipedia page: http://en.wikipedia.org/wiki/File:Mandel_zoom_00_mandelbrot_set.jpg

It is an Ultra Fractal gradient which you may or may not be able to take advantage of depending on how you have implemented palettes / gradients in your code.

I am using it in my new program that I am developing. I plan to release the first version as open source software later this year.


Title: Re: large size mandelbrot
Post by: madmuppet on June 04, 2011, 06:23:00 AM
thanks zenzero .. Im not sure how the wiki mandelbrot set color is set up so Im not sure how to clone it with my program .. it would be very nice though.