// A solution to asn 2 image generation with malloc and 1D pointer arithmetic // compile as "gcc -O circle_demo.c -lm" since this uses trig functions // run as "a.out 1024 768 20 > circles.ppm" or any other image size #include #include #include void circle(unsigned char *, int, int, int, int, int); main(int argc, char *argv[]) { unsigned char *image, *tempptr; int x, y, width, height, csize; float a; if(argc < 4) { fprintf(stderr, "Usage: %s width height radius\n", argv[0]); exit(1); } width = atoi(argv[1]); height = atoi(argv[2]); csize = atoi(argv[3]); // allocate a pre-zeroed space, all black, for the RGB color image image = calloc(1, height*width*3*sizeof(unsigned char)); // clock scan to generate circle centers around a larger circle pattern for(a = 2*M_PI; a >= 0.0; a -= M_PI/9) { x = width/2 + sin(a) * width/3; y = height/2 + cos(a) * height/3; circle(image, x, y, csize, width, height); } printf("P6\n%d %d\n255\n", width, height); // PPM format header fflush(stdout); // force the header to be written to file descriptor 1 // this write appends the actual image data to stdout which is FD 1 write(1, image, width*height*3*sizeof(unsigned char)); return(0); } // arguments are the address of the center, the radius and overall image width void circle(unsigned char *image, int cx, int cy, int csize, int wid, int ht) { int x, y; unsigned char *p; for(y = -csize; y <= csize; y++) { for(x = -csize; x <= csize; x++) { if(x*x + y*y > csize*csize) continue; // reject points outside of circle if(x+cx < 0 || x+cx >= wid || y+cy < 0 || y+cy >= ht) continue; // reject if outside the image bounds // compute the 1D address of this pixel p = image + 3*((y+cy)*wid + (x+cx)); // put yellow into the 3 consecutive RGB bytes *p++ = 255; *p++ = 255; *p++ = 0; } } }