nuclear@0: #include nuclear@0: #include nuclear@0: #include nuclear@0: #include nuclear@0: #include "image.h" nuclear@0: nuclear@0: struct image *load_image(const char *fname) nuclear@0: { nuclear@0: FILE *fp; nuclear@0: int i, hdrline = 0; nuclear@0: struct image *img = 0; nuclear@0: nuclear@0: if(!(fp = fopen(fname, "rb"))) { nuclear@0: fprintf(stderr, "failed to open pixmap: %s: %s\n", fname, strerror(errno)); nuclear@0: return 0; nuclear@0: } nuclear@0: nuclear@0: if(!(img = malloc(sizeof *img))) { nuclear@0: perror("failed to allocate image structure"); nuclear@0: goto err; nuclear@0: } nuclear@0: nuclear@0: /* read ppm header */ nuclear@0: while(hdrline < 3) { nuclear@0: char buf[64]; nuclear@0: nuclear@0: if(!fgets(buf, sizeof buf, fp)) { nuclear@0: goto err; nuclear@0: } nuclear@0: nuclear@0: /* skip comments */ nuclear@0: if(buf[0] == '#') nuclear@0: continue; nuclear@0: nuclear@0: switch(hdrline++) { nuclear@0: case 0: nuclear@0: /* first header line should be P6 */ nuclear@0: if(strcmp(buf, "P6\n") != 0) { nuclear@0: goto err; nuclear@0: } nuclear@0: break; nuclear@0: nuclear@0: case 1: nuclear@0: /* second header line contains the pixmap dimensions */ nuclear@0: if(sscanf(buf, "%d %d", &img->width, &img->height) != 2) { nuclear@0: goto err; nuclear@0: } nuclear@0: break; nuclear@0: } nuclear@0: } nuclear@0: nuclear@0: /* allocate the image (each pixel is 3 bytes r, g, and b) */ nuclear@0: if(!(img->pixels = malloc(img->width * img->height * 3))) { nuclear@0: goto err; nuclear@0: } nuclear@0: nuclear@0: /* read all pixels */ nuclear@0: for(i=0; iwidth * img->height * 3; i++) { nuclear@0: int c = fgetc(fp); nuclear@0: if(c < 0) { nuclear@0: goto err; nuclear@0: } nuclear@0: img->pixels[i] = c; nuclear@0: } nuclear@0: fclose(fp); nuclear@0: nuclear@0: return img; nuclear@0: nuclear@0: err: nuclear@0: fprintf(stderr, "failed to load pixmap: %s\n", fname); nuclear@0: if(img) { nuclear@0: free(img->pixels); nuclear@0: free(img); nuclear@0: } nuclear@0: if(fp) { nuclear@0: fclose(fp); nuclear@0: } nuclear@0: return 0; nuclear@0: } nuclear@0: nuclear@0: nuclear@0: void free_image(struct image *img) nuclear@0: { nuclear@0: if(img) { nuclear@0: free(img->pixels); nuclear@0: free(img); nuclear@0: } nuclear@0: }