00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 #ifndef lint
00041 static const char RCSid[] = "@(#)$Header: /cvsroot/brlcad/brlcad/src/libbn/sphmap.c,v 14.11 2006/09/07 01:19:17 lbutler Exp $ (BRL)";
00042 #endif
00043
00044 #include "common.h"
00045
00046
00047
00048 #include <stdio.h>
00049 #include <math.h>
00050 #ifdef HAVE_STRING_H
00051 #include <string.h>
00052 #else
00053 #include <strings.h>
00054 #endif
00055 #include "machine.h"
00056 #include "bu.h"
00057 #include "vmath.h"
00058 #include "bn.h"
00059 #include "spm.h"
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074 spm_map_t *
00075 spm_init(int N, int elsize)
00076 {
00077 int i, nx, total, index;
00078 register spm_map_t *mapp;
00079
00080 mapp = (spm_map_t *)bu_malloc( sizeof(spm_map_t), "spm_map_t");
00081 if( mapp == SPM_NULL )
00082 return( SPM_NULL );
00083 bzero( (char *)mapp, sizeof(spm_map_t) );
00084
00085 mapp->elsize = elsize;
00086 mapp->ny = N/2;
00087 mapp->nx = (int *) bu_malloc( (unsigned)(N/2 * sizeof(*(mapp->nx))), "sph nx" );
00088 if( mapp->nx == NULL ) {
00089 spm_free( mapp );
00090 return( SPM_NULL );
00091 }
00092 mapp->xbin = (unsigned char **) bu_malloc( (unsigned)(N/2 * sizeof(char *)), "sph xbin" );
00093 if( mapp->xbin == NULL ) {
00094 spm_free( mapp );
00095 return( SPM_NULL );
00096 }
00097
00098 total = 0;
00099 for( i = 0; i < N/4; i++ ) {
00100 nx = ceil( N*cos( i*bn_twopi/N ) );
00101 if( nx > N ) nx = N;
00102 mapp->nx[ N/4 + i ] = nx;
00103 mapp->nx[ N/4 - i -1 ] = nx;
00104
00105 total += 2*nx;
00106 }
00107
00108 mapp->_data = (unsigned char *) bu_calloc( (unsigned)total, elsize, "spm_init data" );
00109 if( mapp->_data == NULL ) {
00110 spm_free( mapp );
00111 return( SPM_NULL );
00112 }
00113
00114 index = 0;
00115 for( i = 0; i < N/2; i++ ) {
00116 mapp->xbin[i] = &((mapp->_data)[index]);
00117 index += elsize * mapp->nx[i];
00118 }
00119 mapp->magic = SPM_MAGIC;
00120 return( mapp );
00121 }
00122
00123
00124
00125
00126
00127
00128 void
00129 spm_free(spm_map_t *mp)
00130 {
00131 RT_CK_SPM(mp);
00132 if( mp == SPM_NULL )
00133 return;
00134
00135 if( mp->_data != NULL ) {
00136 (void) bu_free( (char *)mp->_data, "sph _data" );
00137 mp->_data = NULL;
00138 }
00139
00140 if( mp->nx != NULL ) {
00141 (void) bu_free( (char *)mp->nx, "sph nx" );
00142 mp->nx = NULL;
00143 }
00144
00145 if( mp->xbin != NULL ) {
00146 (void) bu_free( (char *)mp->xbin, "sph xbin" );
00147 mp->xbin = NULL;
00148 }
00149
00150 (void) bu_free( (char *)mp, "spm_map_t" );
00151 }
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162 void
00163 spm_read(register spm_map_t *mapp, register unsigned char *valp, double u, double v)
00164 {
00165 int x, y;
00166 register unsigned char *cp;
00167 register int i;
00168
00169 RT_CK_SPM(mapp);
00170
00171 y = v * mapp->ny;
00172 x = u * mapp->nx[y];
00173 cp = &(mapp->xbin[y][x*mapp->elsize]);
00174
00175 i = mapp->elsize;
00176 while( i-- > 0 ) {
00177 *valp++ = *cp++;
00178 }
00179 }
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190 void
00191 spm_write(register spm_map_t *mapp, register unsigned char *valp, double u, double v)
00192 {
00193 int x, y;
00194 register unsigned char *cp;
00195 register int i;
00196
00197 RT_CK_SPM(mapp);
00198
00199 y = v * mapp->ny;
00200 x = u * mapp->nx[y];
00201 cp = &(mapp->xbin[y][x*mapp->elsize]);
00202
00203 i = mapp->elsize;
00204 while( i-- > 0 ) {
00205 *cp++ = *valp++;
00206 }
00207 }
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218 char *
00219 spm_get(register spm_map_t *mapp, double u, double v)
00220 {
00221 int x, y;
00222 register unsigned char *cp;
00223
00224 RT_CK_SPM(mapp);
00225
00226 y = v * mapp->ny;
00227 x = u * mapp->nx[y];
00228 cp = &(mapp->xbin[y][x*mapp->elsize]);
00229
00230 return( (char *)cp );
00231 }
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242 int
00243 spm_load(spm_map_t *mapp, char *filename)
00244 {
00245 int y, total;
00246 FILE *fp;
00247
00248 RT_CK_SPM(mapp);
00249
00250 if( strcmp( filename, "-" ) == 0 )
00251 fp = stdin;
00252 else {
00253 bu_semaphore_acquire( BU_SEM_SYSCALL );
00254 fp = fopen( filename, "r" );
00255 bu_semaphore_release( BU_SEM_SYSCALL );
00256 if( fp == NULL )
00257 return( -1 );
00258 }
00259
00260 total = 0;
00261 for( y = 0; y < mapp->ny; y++ )
00262 total += mapp->nx[y];
00263
00264 bu_semaphore_acquire( BU_SEM_SYSCALL );
00265 y = fread( (char *)mapp->_data, mapp->elsize, total, fp );
00266 (void) fclose( fp );
00267 bu_semaphore_release( BU_SEM_SYSCALL );
00268
00269 if( y != total )
00270 return( -1 );
00271
00272 return( 0 );
00273 }
00274
00275
00276
00277
00278
00279
00280
00281 int
00282 spm_save(spm_map_t *mapp, char *filename)
00283 {
00284 int i;
00285 int got;
00286 FILE *fp;
00287
00288 RT_CK_SPM(mapp);
00289
00290 if( strcmp( filename, "-" ) == 0 )
00291 fp = stdout;
00292 else {
00293 bu_semaphore_acquire( BU_SEM_SYSCALL );
00294 fp = fopen( filename, "w" );
00295 bu_semaphore_release( BU_SEM_SYSCALL );
00296 if( fp == NULL )
00297 return( -1 );
00298 }
00299
00300 for( i = 0; i < mapp->ny; i++ ) {
00301 bu_semaphore_acquire( BU_SEM_SYSCALL );
00302 got = fwrite( (char *)mapp->xbin[i], mapp->elsize,
00303 mapp->nx[i], fp );
00304 bu_semaphore_release( BU_SEM_SYSCALL );
00305 if( got != mapp->nx[i] ) {
00306 bu_log("spm_save(%s): write error\n", filename);
00307 bu_semaphore_acquire( BU_SEM_SYSCALL );
00308 (void) fclose( fp );
00309 bu_semaphore_release( BU_SEM_SYSCALL );
00310 return( -1 );
00311 }
00312 }
00313
00314 bu_semaphore_acquire( BU_SEM_SYSCALL );
00315 (void) fclose( fp );
00316 bu_semaphore_release( BU_SEM_SYSCALL );
00317
00318 return( 0 );
00319 }
00320
00321
00322
00323
00324
00325
00326
00327
00328 int
00329 spm_px_load(spm_map_t *mapp, char *filename, int nx, int ny)
00330 {
00331 int i, j;
00332 int x, y;
00333 double j_per_y, i_per_x;
00334 int nj, ni;
00335 unsigned char *cp;
00336 unsigned char *buffer;
00337 unsigned long red, green, blue;
00338 long count;
00339 FILE *fp;
00340
00341 RT_CK_SPM(mapp);
00342
00343 if( strcmp( filename, "-" ) == 0 )
00344 fp = stdin;
00345 else {
00346 bu_semaphore_acquire( BU_SEM_SYSCALL );
00347 fp = fopen( filename, "r" );
00348 bu_semaphore_release( BU_SEM_SYSCALL );
00349 if( fp == NULL )
00350 return( -1 );
00351 }
00352
00353
00354 buffer = (unsigned char *)bu_malloc( (unsigned)(nx*nx*3), "spm_px_load buffer" );
00355 bu_semaphore_acquire( BU_SEM_SYSCALL );
00356 i = fread( (char *)buffer, 3, nx*ny, fp );
00357 (void) fclose( fp );
00358 bu_semaphore_release( BU_SEM_SYSCALL );
00359 if( i != nx*ny ) {
00360 bu_log("spm_px_load(%s) read error\n", filename);
00361 return( -1 );
00362 }
00363
00364 j_per_y = (double)ny / (double)mapp->ny;
00365 nj = (int)j_per_y;
00366
00367 for( y = 0; y < mapp->ny; y++ ) {
00368 i_per_x = (double)nx / (double)mapp->nx[y];
00369 ni = (int)i_per_x;
00370
00371 for( x = 0; x < mapp->nx[y]; x++ ) {
00372
00373 red = green = blue = 0;
00374 count = 0;
00375 for( j = y*j_per_y; j < y*j_per_y+nj; j++ ) {
00376 for( i = x*i_per_x; i < x*i_per_x+ni; i++ ) {
00377 red = red + (unsigned long)buffer[ 3*(j*nx+i) ];
00378 green = green + (unsigned long)buffer[ 3*(j*nx+i)+1 ];
00379 blue = blue + (unsigned long)buffer[ 3*(j*nx+i)+2 ];
00380 count++;
00381 }
00382 }
00383
00384 cp = &(mapp->xbin[y][x*3]);
00385 *cp++ = (unsigned char)(red/count);
00386 *cp++ = (unsigned char)(green/count);
00387 *cp++ = (unsigned char)(blue/count);
00388 }
00389 }
00390 (void) bu_free( (char *)buffer, "spm buffer" );
00391
00392 return( 0 );
00393 }
00394
00395
00396
00397
00398
00399
00400
00401 int
00402 spm_px_save(spm_map_t *mapp, char *filename, int nx, int ny)
00403 {
00404 int x, y;
00405 FILE *fp;
00406 unsigned char pixel[3];
00407 int got;
00408
00409 RT_CK_SPM(mapp);
00410
00411 if( strcmp( filename, "-" ) == 0 )
00412 fp = stdout;
00413 else {
00414 bu_semaphore_acquire( BU_SEM_SYSCALL );
00415 fp = fopen( filename, "w" );
00416 bu_semaphore_release( BU_SEM_SYSCALL );
00417 if( fp == NULL )
00418 return( -1 );
00419 }
00420
00421 for( y = 0; y < ny; y++ ) {
00422 for( x = 0; x < nx; x++ ) {
00423 spm_read( mapp, pixel, (double)x/(double)nx, (double)y/(double)ny );
00424 bu_semaphore_acquire( BU_SEM_SYSCALL );
00425 got = fwrite( (char *)pixel, sizeof(pixel), 1, fp );
00426 bu_semaphore_release( BU_SEM_SYSCALL );
00427 if( got != 1 ) {
00428 bu_log("spm_px_save(%s): write error\n", filename);
00429 bu_semaphore_acquire( BU_SEM_SYSCALL );
00430 (void) fclose( fp );
00431 bu_semaphore_release( BU_SEM_SYSCALL );
00432 return( -1 );
00433 }
00434 }
00435 }
00436
00437 bu_semaphore_acquire( BU_SEM_SYSCALL );
00438 (void) fclose( fp );
00439 bu_semaphore_release( BU_SEM_SYSCALL );
00440
00441 return( 0 );
00442 }
00443
00444
00445
00446
00447
00448
00449
00450 void
00451 spm_dump(spm_map_t *mp, int verbose)
00452 {
00453 int i;
00454
00455 RT_CK_SPM(mp);
00456
00457 bu_log("elsize = %d\n", mp->elsize );
00458 bu_log("ny = %d\n", mp->ny );
00459 bu_log("_data = 0x%x\n", mp->_data );
00460 if( !verbose ) return;
00461 for( i = 0; i < mp->ny; i++ ) {
00462 bu_log(" nx[%d] = %3d, xbin[%d] = 0x%x\n",
00463 i, mp->nx[i], i, mp->xbin[i] );
00464 }
00465 }
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475