/* Simple PPM functions. See sample main function for usage. * * int get_ppm_from_file( image * x, FILE * fp ) -- allocates and * reads a binary PPM ("P6") from a file. * int copy_ppm( image x, image * y ) -- allocates a copy of x, puts in *y. * * Allocation functions return a nonzero value if successful. * * void put_ppm_to_file( image x, FILE * gp ) -- writes x to a file. * void dealloc_ppm( image x ) -- frees an allocated image. * * pixel get_pixel( image z, int x, int y ) --- get RGB pixel at (x,y) * void put_pixel( image z, int x, int y, pixel p ) -- places pixel at (x,y) */ typedef unsigned char BYTE; typedef struct pixel_struct { int rgb[3]; } pixel; typedef struct image_struct { int width, height, max, bpp, raster; BYTE * raw; BYTE ** pixel; } image; pixel get_pixel( image z, int x, int y ) { BYTE * foo, i; pixel p; for( i=0; i<3; i++) { p.rgb[i] = z.pixel[y][(x+i)*3*z.bpp]; if( z.bpp!=1 ) p.rgb[i] = (p.rgb[i]<<8) + z.pixel[y][(x+i)*3*z.bpp+1]; } return p; } void put_pixel( image z, int x, int y, pixel p ) { BYTE * foo, i; for( i=0; i<3; i++) { z.pixel[y][(x+i)*3*z.bpp] = p.rgb[i] & 0xff; if( z.bpp!=1 ) 0xff & (z.pixel[y][(x+i)*3*z.bpp+1] >> 8); } } int alloc_ppm( image * y ) { int i=0; y->raw = (BYTE *) malloc( y->height * y->raster ); y->pixel = (BYTE **) malloc( y->height * sizeof(BYTE*) ); if( y->raw!=NULL && y->pixel!=NULL ) for( i=0; iheight; i++ ) y->pixel[i] = y->raw + i*y->raster; else fprintf( stderr, "Failed to allocate memory!\n" ); return i; } void dealloc_ppm( image x ) { free( x.pixel ); free( x.raw ); } int copy_ppm( image x, image * y ) { int i=0; *y = x; if( alloc_ppm(y) ) for( i=0; iheight*y->raster; i++ ) y->raw[i] = x.raw[i]; return i; } int get_int( FILE * fp ) { /* scan int from ppm, passing over comments */ int k; unsigned char ch; do { while( isspace(ch=getc(fp)) ) ; if( ch=='#' ) while( (ch=getc(fp))!='\n' ) ; } while( !isdigit(ch) ); for( k=(ch-'0'); isdigit(ch=getc(fp)); k = 10*k+(ch-'0') ); return k; } int get_ppm_from_file( image * x, FILE * fp ) { int flag=0; char magic[3]="ZZ"; fread(magic,2,1,fp); if( strcmp(magic,"P6")==0 ) { x->width=get_int(fp); x->height=get_int(fp); x->max=get_int(fp); x->bpp = (x->max<256) ? 1 : 2; x->raster = x->width * x->bpp * 3; if( flag=alloc_ppm(x) ) fread( x->raw, x->height, x->raster, fp ); } else fprintf( stderr, "This is not a valid binary PPM (magic # is not P6)\n" ); return flag; } void put_ppm_to_file( image x, FILE * gp ) { fprintf( gp, "P6\n%d %d %d\n", x.width, x.height, x.max ) ; fwrite( x.raw, x.height, x.raster, gp ); }