/* Fractal - Mandelbrot set */ #include "frak.h" /* ------------------------- PIXMAP FUNCTIONS ------------------------- */ pixmap * createPixmap(int width, int height) { pixmap *p=NULL; /* try to allocate some space for our pixmap structure */ p = (pixmap *)malloc(sizeof(pixmap)); if (!p) return NULL; /* no free space for pixmap... :( */ p->width = width; p->height = height; /* pixels - 3 unsigned chars for 3 color channels */ p->pixels = (unsigned char *)malloc( sizeof(unsigned char)*3*height*width ); if (!p->pixels) { /* no free space for pixels :( */ free(p); /* giving up, cleaning up... */ return NULL; } return p; /* ok */ } void deletePixmap(pixmap *p) { if (p->pixels) free(p->pixels); if (p) free(p); p = NULL; } /* clears the whole pixmap to black */ void clearPixmap(pixmap *p) { if (!p || !p->pixels) return; /* no pixmap, nothing to draw... */ memset(p->pixels, 0, 3*p->width*p->height); } void putpixel(pixmap *p, const unsigned int x, const unsigned int y, const unsigned char r, const unsigned char g, const unsigned char b) { int position; if (!p || !p->pixels || x >= p->width || y >= p->height) return; position = 3 * (y*p->width + x); p->pixels[position++] = r; p->pixels[position++] = g; p->pixels[position] = b; } void drawPixmap(const pixmap *p, const int xoff, const int yoff) { if (!p || !p->pixels) return; /* no pixmap, nothing to draw... :( */ glRasterPos2i(xoff, yoff); /* set offset for drawing the pixmap */ glDrawPixels(p->width, p->height, GL_RGB, GL_UNSIGNED_BYTE, p->pixels); } int savePixmapTGA(const pixmap *p, const char * fileName) { FILE * fd; int row, col, i; /* TGA header - 24bit true-color image */ unsigned char TGAheader[18] = { 0x00, /* IDLength - no ID field */ 0x00, /* ColorMapType - no color palette */ 0x02, /* ImageType - true-color */ 0x00, 0x00, /* CMapStart - color palette start */ 0x00, 0x00, /* CMapLength - color palette length */ 0x00, /* CMapDepth - color palette depth */ 0x00, 0x00, /* XOffset - image start */ 0x00, 0x00, /* YOffset */ 0x00, 0x00, /* image dimensions */ 0x00, 0x00, 0x18, /* PixelDepth - 24bit */ 0x00 /* ImageDescriptor - 5th bit - (0x00 or 0x20) image begins at the upper-left corner */ }; if(*fileName == '\0') fd = stdout; else fd = fopen(fileName, "wb"); if (!fd) { fprintf(stderr, "Can't save image to: %s\n", fileName); return -1; } memcpy(TGAheader+12, &p->width, 2); memcpy(TGAheader+14, &p->height, 2); fwrite(TGAheader, 18, 1, fd); for (row=0; row < p->height; row++) for (col=0; col < p->width; col++) for (i=2; i>=0; i--) fputc(p->pixels[3 * (row * p->width + col) + i], fd); /* BGR */ fclose(fd); return 0; } int pixmove(const pixmap * p, int xoff, int yoff) { /* move the pixels by x and y offset * movement is done in-place (eg. without any temp pixmap) * * xoff [-PIXMAP_WIDTH-1,PIXMAP_WIDTH-1] < > * yoff [-PIXMAP_HEIGHT-1,PIXMAP_HEIGHT-1] ^ v */ int x, y; if (!p || !p->pixels) return -1; /* no pixmap, or void pixmap */ if ( xoff <= (int)-(p->width) || xoff >= (int)p->width || yoff <= (int)-(p->height) || yoff >= (int)p->height || (xoff == 0 && yoff == 0) ) return -1; /* out of bounds or no movement */ /* trying to unify the loop, but currently, it doesn't work... */ /* x = xoff; if (xoff < 0) x += p->width - 1; y = yoff; if (yoff < 0) y += p->height - 1; while (1) { if ( (xoff < 0 && x < 0) || (xoff > 0 && x >= p->width)) break; while (1) { if ( (yoff < 0 && y < 0) || (yoff > 0 && y >= p->height) ) break; memcpy(p->pixels+3*(x-xoff+(y-yoff)*p->width), p->pixels+3*(x+y*p->width), 3); y += (y > 0 ) ? 1 : -1; } x += (x > 0 ) ? 1 : -1; } */ /* this works OK! */ if (xoff < 0 && yoff > 0) for(x=p->width+xoff-1; x>=0; x--) for(y=yoff; yheight; y++) memcpy(p->pixels+3*(x-xoff+(y-yoff)*p->width), p->pixels+3*(x+y*p->width), 3); else if (xoff >= 0 && yoff >= 0) for(x=xoff; xwidth; x++) for(y=yoff; yheight; y++) memcpy(p->pixels+3*(x-xoff+(y-yoff)*p->width), p->pixels+3*(x+y*p->width), 3); else if (xoff <= 0 && yoff <= 0) for(x=p->width+xoff-1; x>=0; x--) for(y=p->height+yoff-1; y>=0; y--) memcpy(p->pixels+3*(x-xoff+(y-yoff)*p->width), p->pixels+3*(x+y*p->width), 3); else if (xoff > 0 && yoff < 0) for(x=xoff; xwidth; x++) for(y=p->height+yoff-1; y>=0; y--) memcpy(p->pixels+3*(x-xoff+(y-yoff)*p->width), p->pixels+3*(x+y*p->width), 3); return 0; } void pixmapInit(void) { pixMain = createPixmap(width, height); pixPreview = createPixmap( width*PREVIEW_SCALE, height*PREVIEW_SCALE ); if (!pixMain || !pixPreview){ fprintf(stderr, "Could not allocate space for pixmaps."); onExit(); exit(-1); } generatePalette(); }