#include #include #include #include #include "pnm_image.h" #define NEWA(type,n) (type*)malloc(sizeof(type)*(n)) #define NEW(type) NEWA(type,1) image_t *image_new(int width, int height) { image_t *im=NEW(image_t); im->width=im->stride=width; im->height=height; int wh=width*height; im->data=NEWA(float,wh); return im; } image_t *image_cpy(image_t *src) { image_t *im=image_new(src->width,src->height); memcpy(im->data,src->data,sizeof(*(src->data))*src->width*src->height); return im; } void image_delete(image_t *im) { free(im->data); free(im); } color_image_t *color_image_new(int width, int height) { color_image_t *im=NEW(color_image_t); im->width=width; im->height=height; int wh=width*height; im->c1=NEWA(float,wh); im->c2=NEWA(float,wh); im->c3=NEWA(float,wh); return im; } color_image_t *color_image_cpy(color_image_t *src) { color_image_t *im=color_image_new(src->width,src->height); memcpy(im->c1,src->c1,sizeof(*(src->c1))*src->width*src->height); memcpy(im->c2,src->c2,sizeof(*(src->c1))*src->width*src->height); memcpy(im->c3,src->c3,sizeof(*(src->c1))*src->width*src->height); return im; } void color_image_delete(color_image_t *im) { free(im->c1); free(im->c2); free(im->c3); free(im); } color_image_t *load_ppm(const char *fname) { FILE *f=fopen(fname,"r"); if(!f) { perror("could not open infile"); exit(1); } int px,width,height,maxval; if(fscanf(f,"P%d %d %d %d",&px,&width,&height,&maxval)!=4 || maxval!=255 || (px!=6 && px!=5)) { fprintf(stderr,"Error: input not a raw PGM/PPM with maxval 255\n"); exit(1); } fgetc(f); /* eat the newline */ color_image_t *im=color_image_new(width,height); int i; for(i=0;ic1[i]=fgetc(f); if(px==6) { im->c2[i]=fgetc(f); im->c3[i]=fgetc(f); } else { im->c2[i]=im->c1[i]; im->c3[i]=im->c1[i]; } } fclose(f); return im; } image_t *color_image_channel(const color_image_t *cim, ColorChannel channel) { image_t *ret = image_new(cim->width, cim->height); int i; float *src = channel == CHANNEL_R ? cim->c1 : channel == CHANNEL_G ? cim->c2 : channel == CHANNEL_B ? cim->c3 : NULL; assert(src || !"unknown channel"); memcpy(ret->data, src, sizeof(float) * cim->width * cim->height); return ret; }