/* * To compile a test program on an SGI: * cc emboss2.c -lm -o emboss2 */ #include #include #include #include #include #include #define FALSE 0 #define TEXTURE 1 static char title[ 57 ]="emboss"; char *data[ 2 ]; char *buff; unsigned int xsize, ysize; void Emboss( double azimuth, double elevation, short width45, char *bump, char *texture, char *dst); void err_arg( char *filename ); void err_open( char *filename ); void err_head( char *filename ); void err_size( char *file1, char *file2 ); void err_read( char *filename ); void err_write( char *filename ); /*------------------------------------------------------------*/ main( int argc, char *argv[] ) /*------------------------------------------------------------*/ { register int i, x, y; int xs1, ys1, xe1, ye1; int x1size, y1size; int ix1, ix2, iy1, iy2; int ifp[ 2 ]; int ofp; int count, j, k, l = 0; char **bump; char *texture; char *txt = 0; char *dst; if( argc != 4 ) err_arg( argv[ 0 ] ); if( *argv[ 3 ] == '0') argv[ 3 ] = "emboss.img"; fprintf(stderr, "\n\tNow calculating %s (int image)\n", argv[ 3 ]); if( *argv[ 2 ] == '0') j = 1; else j = 2; for( i = 0; i < j; i++ ) { infile_open( &ifp[ i ], argv[ i+1 ], &xs1, &xe1, &ye1, &ys1, &x1size, &y1size); size_check( i, argv[ 1 ], argv[ i+1 ], &x1size, &y1size); } ix1 = xs1; ix2 = xe1; iy1 = ye1; iy2 = ys1; data_malloc( &bump, &texture, &dst); outfile_open( argv[ 3 ], &ofp, &ix1, &iy2, &ix2, &iy1); lseek( ofp, xsize*3*sizeof( char ), 0); for( i = 0; i < 2; i++ ) lseek( ifp[ i ], xsize*3*sizeof( char ), 0); /* read input files */ for(y = 0; y < ysize; y++){ for(i = 0; i < j; i++){ count = read( ifp[ i ], data[ i ],xsize*3*sizeof( char )); if( count != xsize*3*sizeof( char )) err_read( argv[i+1]); } for(x = 0 ; x< xsize; x++){ bump[ y ][ x ] = data[ 0 ][ 3 * x + 0 ]; if ( *argv[ 2 ] == '0'){ texture[ l + 0] = 10; texture[ l + 1] = (char)(random()&0x1f) + 200; texture[ l + 2] = (char)(random()&0x1f) + 240; } else{ texture[ l + 0] = 4+data[ 1 ][ 3 * x + 0 ]; texture[ l + 1] = data[ 1 ][ 3 * x + 1 ]; texture[ l + 2] = data[ 1 ][ 3 * x + 2 ]; } l+=3; } txt = texture; } for( i = 0; i < j; i++ ) close( ifp[i] ); /* emboss it */ memset(dst, 0, sizeof(dst)); #define dToR(d) ((d)*(3.14/180)) Emboss( dToR(50), dToR(70), 3, (char *)*bump, txt, (char *)dst); /* create output image (rgb data) */ for(y = 0; y < ysize; y++) { long line[1200]; char *lp = (char *)line; for(x = 0; x < xsize*3; x++) { *lp++ = *dst++; } if((count = write( ofp, line, xsize*3 )) != xsize*3) err_write( argv[ 3 ]); } close ( ofp ); for (i = 0; i < 2; i++) free ( data[ i ]); free ( buff ); for (y = 0; y < ysize; y++) free ( bump[y]); free ( bump); free ( texture); free ( dst); fprintf (stderr,"\tFinish\n"); exit( 0 ); } /*------------------- input file open ------------------------*/ infile_open( int *ifp, char *filename, int *xs1, int *xe1, int *ye1, int *ys1, int *x1size, int *y1size) /*------------------------------------------------------------*/ { register int l; char cbuf[ 96 ]; char intitl[ 96 ]; int count; if(( *ifp = open( filename,O_RDONLY)) == -1 ) err_open( filename ); if(( count = read( *ifp, cbuf, 56 + 24 + 4 * 4)) != 96 ) err_head( filename ); for( l = 0; l < 56; l++) intitl[ l ] = cbuf[ l ]; intitl[ 56 ] = '\0'; fprintf( stderr, "\tInput_title = %s\n", intitl); sscanf( cbuf + 92, "%4d", ye1 ); cbuf[ 92 ] = '\0'; sscanf( cbuf + 88, "%4d", xe1 ); cbuf[ 88 ] = '\0'; sscanf( cbuf + 84, "%4d", ys1 ); cbuf[ 84 ] = '\0'; sscanf( cbuf + 80, "%4d", xs1 ); *x1size = *xe1 - *xs1 + 1; *y1size = *ys1 - *ye1 + 1; } /*----------------- input file size check ---------------------*/ size_check( int i, char *file1, char *file2, int *x1size, int *y1size) /*-------------------------------------------------------------*/ { if( i == 0 ) { xsize = *x1size; ysize = *y1size; } else { if(( xsize != *x1size ) || ( ysize != *y1size )) err_size( file1, file2 ); } } /*----- malloc 1 scan line of input images & output image -----*/ data_malloc( char ***bump, char **texture, char **dst ) /*-------------------------------------------------------------*/ { register int i, y; for( i = 0; i < 2; i++ ){ data[ i ] = ( char *)malloc( sizeof( char )*xsize*3 ); if( data == NULL){ perror( " data " ); exit( 1 ); } } buff = ( char *)malloc( sizeof( char )*xsize*3); if( buff == NULL){ perror( " buff "); exit( 1 ); } *bump = ( char **)malloc( sizeof( char *) * ysize); if( NULL == *bump){ perror( " bump "); exit( 1 ); } (*bump)[ 0 ] = ( char *)malloc( sizeof( char ) * ysize * xsize); if( NULL == (*bump)[0]) { perror( " bump "); exit( 1 ); } for ( y = 1; y < ysize; y++){ (*bump)[ y ] = (*bump)[ y - 1 ]+sizeof( char ) * xsize; } *texture = ( char *)malloc( sizeof( char ) * ysize * xsize * 3); if( NULL == *texture){ perror( " texture "); exit( 1 ); } *dst = ( char *)malloc( sizeof( char ) * ysize * xsize * 3); if (NULL == * dst){ perror( " dst "); exit( 1 ); } } /*--------------- create output image( header ) --------------*/ outfile_open( char *filename, int *ofp, int *ix1, int *iy2, int *ix2, int *iy1) /*------------------------------------------------------------*/ { register int i; char *tm; time_t tim; long tloc; if(( *ofp = creat( filename, 0644)) != -1) { lseek( *ofp, 0L, 0 ); for( i = 0; i < 56; i++ ) buff[ i ] = title[ i ]; tim = time( &tloc ); tm = ctime( &tim ); for( i = 0; i< 24; i++ ) buff[ i + 56 ] = tm[ i ]; sprintf( buff + 80, "%4d%4d%4d%4d", *ix1, *iy2+1, *ix2, *iy1); write( *ofp, buff, 80 + 16 ); } else { fprintf( stderr, "\ncan't creat output file %s\n", filename); close( *ofp ); exit( 1 ); } } /*-------------------------------------------------------------*/ void Emboss( double azimuth, double elevation, short width45, char *bump, char *texture, char *dst) /*-------------------------------------------------------------*/ { long Nx, Ny, Nz, Lx, Ly, Lz, Nz2, NzLz, NdotL; register char *s1, *s2, *s3, shade, background; register int x, y; #define pixelScale 255.9 Lx = cos(azimuth) * cos(elevation) * pixelScale; Ly = sin(azimuth) * cos(elevation) * pixelScale; Lz = sin(elevation) * pixelScale; Nz = (6 * 255) / width45; Nz2 = Nz * Nz; NzLz = Nz * Lz; background = Lz; dst += xsize*3; if (texture) texture += xsize*3; for (y = 1; y < ysize-1; y++, bump += xsize, dst += 3) { s1 = bump + 1; s2 = s1 + xsize; s3 = s2 + xsize; dst += 3; if (texture) texture += 3; for (x = 1; x < xsize-1; x++, s1++, s2++, s3++) { Nx = (int)(s1[-1] + s2[-1] + s3[-1] - s1[1] - s2[1] - s3[1]); Ny = (int)(s3[-1] + s3[0] + s3[1] - s1[-1] - s1[0] - s1[1]); if ( Nx == 0 && Ny == 0 ) shade = background; else if ( (NdotL = Nx*Lx + Ny*Ly + NzLz) < 0 ) shade = 0; else shade = NdotL / sqrt(Nx*Nx + Ny*Ny + Nz2); if ( texture ) { *dst++ = (*texture++ * shade) >> 8; *dst++ = (*texture++ * shade) >> 8; *dst++ = (*texture++ * shade) >> 8; } else { *dst++ = shade; *dst++ = shade; *dst++ = shade; } } if (texture) texture += 3; } } /*------------------------------------------------------------*/ void err_arg( char *filename ) /*------------------------------------------------------------*/ { fprintf(stderr, "\n"); fprintf(stderr, "Usage: %s ", filename); fprintf(stderr, "\n"); fprintf(stderr, ""); fprintf(stderr, ""); fprintf(stderr, ""); fprintf(stderr, "\n"); exit( 1 ); } /*------------------------------------------------------------*/ void err_open( char *filename ) /*------------------------------------------------------------*/ { fprintf( stderr, "\n\tCan't open input file %s\a\n", filename); exit( 1 ); } /*------------------------------------------------------------*/ void err_head( char *filename ) /*------------------------------------------------------------*/ { fprintf( stderr, "\n\tCan't read header %s\a\n", filename); exit( 1 ); } /*------------------------------------------------------------*/ void err_size( char *file1, char *file2 ) /*------------------------------------------------------------*/ { fprintf( stderr, "\n\tWarning : different image size "); fprintf( stderr, "%s & %s\a\n", file1, file2); exit( 1 ); } /*------------------------------------------------------------*/ void err_read( char *filename ) /*------------------------------------------------------------*/ { fprintf( stderr, "\n\tCan't read color data %s\a\n", filename); exit( 1 ); } /*------------------------------------------------------------*/ void err_write( char *filename ) /*------------------------------------------------------------*/ { fprintf( stderr, "\tCan't write output data %s\a\n", filename); exit( 1 ); }