00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "common.h"
00022
00023 #include <stdio.h>
00024 #include <math.h>
00025 #include <string.h>
00026
00027 #include "bu.h"
00028 #include "vmath.h"
00029 #include "bn.h"
00030 #include "spm.h"
00031
00032
00033 void
00034 bn_spm_free(bn_spm_map_t *mp)
00035 {
00036 BN_CK_SPM_MAP(mp);
00037 if (mp == BN_SPM_MAP_NULL)
00038 return;
00039
00040 if (mp->_data != NULL) {
00041 (void) bu_free((char *)mp->_data, "sph _data");
00042 mp->_data = NULL;
00043 }
00044
00045 if (mp->nx != NULL) {
00046 (void) bu_free((char *)mp->nx, "sph nx");
00047 mp->nx = NULL;
00048 }
00049
00050 if (mp->xbin != NULL) {
00051 (void) bu_free((char *)mp->xbin, "sph xbin");
00052 mp->xbin = NULL;
00053 }
00054
00055 (void) bu_free((char *)mp, "bn_spm_map_t");
00056 }
00057
00058
00059 bn_spm_map_t *
00060 bn_spm_init(int N, int elsize)
00061 {
00062 int i, nx, total, idx;
00063 register bn_spm_map_t *mapp;
00064
00065 mapp = (bn_spm_map_t *)bu_malloc(sizeof(bn_spm_map_t), "bn_spm_map_t");
00066 if (mapp == BN_SPM_MAP_NULL)
00067 return BN_SPM_MAP_NULL;
00068 memset((char *)mapp, 0, sizeof(bn_spm_map_t));
00069
00070 mapp->elsize = elsize;
00071 mapp->ny = N/2;
00072 mapp->nx = (int *) bu_malloc((unsigned)(N/2 * sizeof(*(mapp->nx))), "sph nx");
00073 if (mapp->nx == NULL) {
00074 bn_spm_free(mapp);
00075 return BN_SPM_MAP_NULL;
00076 }
00077 mapp->xbin = (unsigned char **) bu_malloc((unsigned)(N/2 * sizeof(char *)), "sph xbin");
00078 if (mapp->xbin == NULL) {
00079 bn_spm_free(mapp);
00080 return BN_SPM_MAP_NULL;
00081 }
00082
00083 total = 0;
00084 for (i = 0; i < N/4; i++) {
00085 nx = ceil(N*cos(i*bn_twopi/N));
00086 if (nx > N) nx = N;
00087 mapp->nx[ N/4 + i ] = nx;
00088 mapp->nx[ N/4 - i -1 ] = nx;
00089
00090 total += 2*nx;
00091 }
00092
00093 mapp->_data = (unsigned char *) bu_calloc((unsigned)total, elsize, "bn_spm_init data");
00094 if (mapp->_data == NULL) {
00095 bn_spm_free(mapp);
00096 return BN_SPM_MAP_NULL;
00097 }
00098
00099 idx = 0;
00100 for (i = 0; i < N/2; i++) {
00101 mapp->xbin[i] = &((mapp->_data)[idx]);
00102 idx += elsize * mapp->nx[i];
00103 }
00104 mapp->magic = BN_SPM_MAGIC;
00105 return mapp;
00106 }
00107
00108
00109 void
00110 bn_spm_read(register bn_spm_map_t *mapp, register unsigned char *valp, double u, double v)
00111 {
00112 int x, y;
00113 register unsigned char *cp;
00114 register int i;
00115
00116 BN_CK_SPM_MAP(mapp);
00117
00118 y = v * mapp->ny;
00119 x = u * mapp->nx[y];
00120 cp = &(mapp->xbin[y][x*mapp->elsize]);
00121
00122 i = mapp->elsize;
00123 while (i-- > 0) {
00124 *valp++ = *cp++;
00125 }
00126 }
00127
00128
00129 void
00130 bn_spm_write(register bn_spm_map_t *mapp, register unsigned char *valp, double u, double v)
00131 {
00132 int x, y;
00133 register unsigned char *cp;
00134 register int i;
00135
00136 BN_CK_SPM_MAP(mapp);
00137
00138 y = v * mapp->ny;
00139 x = u * mapp->nx[y];
00140 cp = &(mapp->xbin[y][x*mapp->elsize]);
00141
00142 i = mapp->elsize;
00143 while (i-- > 0) {
00144 *cp++ = *valp++;
00145 }
00146 }
00147
00148
00149 char *
00150 bn_spm_get(register bn_spm_map_t *mapp, double u, double v)
00151 {
00152 int x, y;
00153 register unsigned char *cp;
00154
00155 BN_CK_SPM_MAP(mapp);
00156
00157 y = v * mapp->ny;
00158 x = u * mapp->nx[y];
00159 cp = &(mapp->xbin[y][x*mapp->elsize]);
00160
00161 return (char *)cp;
00162 }
00163
00164
00165 int
00166 bn_spm_load(bn_spm_map_t *mapp, char *filename)
00167 {
00168 int y, total;
00169 FILE *fp;
00170
00171 BN_CK_SPM_MAP(mapp);
00172
00173 if (BU_STR_EQUAL(filename, "-"))
00174 fp = stdin;
00175 else {
00176 bu_semaphore_acquire(BU_SEM_SYSCALL);
00177 fp = fopen(filename, "rb");
00178 bu_semaphore_release(BU_SEM_SYSCALL);
00179 if (fp == NULL)
00180 return -1;
00181 }
00182
00183 total = 0;
00184 for (y = 0; y < mapp->ny; y++)
00185 total += mapp->nx[y];
00186
00187 bu_semaphore_acquire(BU_SEM_SYSCALL);
00188 y = (int)fread((char *)mapp->_data, mapp->elsize, total, fp);
00189 (void) fclose(fp);
00190 bu_semaphore_release(BU_SEM_SYSCALL);
00191
00192 if (y != total)
00193 return -1;
00194
00195 return 0;
00196 }
00197
00198
00199 int
00200 bn_spm_save(bn_spm_map_t *mapp, char *filename)
00201 {
00202 int i;
00203 int got;
00204 FILE *fp;
00205
00206 BN_CK_SPM_MAP(mapp);
00207
00208 if (BU_STR_EQUAL(filename, "-"))
00209 fp = stdout;
00210 else {
00211 bu_semaphore_acquire(BU_SEM_SYSCALL);
00212 fp = fopen(filename, "wb");
00213 bu_semaphore_release(BU_SEM_SYSCALL);
00214 if (fp == NULL)
00215 return -1;
00216 }
00217
00218 for (i = 0; i < mapp->ny; i++) {
00219 bu_semaphore_acquire(BU_SEM_SYSCALL);
00220 got = (int)fwrite((char *)mapp->xbin[i], mapp->elsize,
00221 mapp->nx[i], fp);
00222 bu_semaphore_release(BU_SEM_SYSCALL);
00223 if (got != mapp->nx[i]) {
00224 bu_log("WARNING: Unable to write SPM to [%s]\n", filename);
00225 bu_semaphore_acquire(BU_SEM_SYSCALL);
00226 (void) fclose(fp);
00227 bu_semaphore_release(BU_SEM_SYSCALL);
00228 return -1;
00229 }
00230 }
00231
00232 bu_semaphore_acquire(BU_SEM_SYSCALL);
00233 (void) fclose(fp);
00234 bu_semaphore_release(BU_SEM_SYSCALL);
00235
00236 return 0;
00237 }
00238
00239
00240 int
00241 bn_spm_pix_load(bn_spm_map_t *mapp, char *filename, int nx, int ny)
00242 {
00243 int i, j;
00244 int x, y;
00245 double j_per_y, i_per_x;
00246 int nj, ni;
00247 unsigned char *cp;
00248 unsigned char *buffer;
00249 unsigned long red, green, blue;
00250 long count;
00251 FILE *fp;
00252
00253 BN_CK_SPM_MAP(mapp);
00254
00255 if (BU_STR_EQUAL(filename, "-"))
00256 fp = stdin;
00257 else {
00258 bu_semaphore_acquire(BU_SEM_SYSCALL);
00259 fp = fopen(filename, "rb");
00260 bu_semaphore_release(BU_SEM_SYSCALL);
00261 if (fp == NULL)
00262 return -1;
00263 }
00264
00265
00266 buffer = (unsigned char *)bu_malloc((unsigned)(nx*nx*3), "bn_spm_pix_load buffer");
00267 bu_semaphore_acquire(BU_SEM_SYSCALL);
00268 i = (int)fread((char *)buffer, 3, nx*ny, fp);
00269 (void)fclose(fp);
00270 bu_semaphore_release(BU_SEM_SYSCALL);
00271 if (i != nx*ny) {
00272 bu_log("bn_spm_pix_load(%s) read error\n", filename);
00273 return -1;
00274 }
00275
00276 j_per_y = (double)ny / (double)mapp->ny;
00277 nj = (int)j_per_y;
00278
00279 for (y = 0; y < mapp->ny; y++) {
00280 i_per_x = (double)nx / (double)mapp->nx[y];
00281 ni = (int)i_per_x;
00282
00283 for (x = 0; x < mapp->nx[y]; x++) {
00284
00285 red = green = blue = 0;
00286 count = 0;
00287 for (j = y*j_per_y; j < y*j_per_y+nj; j++) {
00288 for (i = x*i_per_x; i < x*i_per_x+ni; i++) {
00289 red = red + (unsigned long)buffer[ 3*(j*nx+i) ];
00290 green = green + (unsigned long)buffer[ 3*(j*nx+i)+1 ];
00291 blue = blue + (unsigned long)buffer[ 3*(j*nx+i)+2 ];
00292 count++;
00293 }
00294 }
00295
00296 cp = &(mapp->xbin[y][x*3]);
00297 *cp++ = (unsigned char)(red/count);
00298 *cp++ = (unsigned char)(green/count);
00299 *cp++ = (unsigned char)(blue/count);
00300 }
00301 }
00302 (void) bu_free((char *)buffer, "bn_spm buffer");
00303
00304 return 0;
00305 }
00306
00307
00308 int
00309 bn_spm_pix_save(bn_spm_map_t *mapp, char *filename, int nx, int ny)
00310 {
00311 int x, y;
00312 FILE *fp;
00313 unsigned char pixel[3];
00314 int got;
00315
00316 BN_CK_SPM_MAP(mapp);
00317
00318 if (BU_STR_EQUAL(filename, "-"))
00319 fp = stdout;
00320 else {
00321 bu_semaphore_acquire(BU_SEM_SYSCALL);
00322 fp = fopen(filename, "wb");
00323 bu_semaphore_release(BU_SEM_SYSCALL);
00324 if (fp == NULL)
00325 return -1;
00326 }
00327
00328 for (y = 0; y < ny; y++) {
00329 for (x = 0; x < nx; x++) {
00330 bn_spm_read(mapp, pixel, (double)x/(double)nx, (double)y/(double)ny);
00331 bu_semaphore_acquire(BU_SEM_SYSCALL);
00332 got = (int)fwrite((char *)pixel, sizeof(pixel), 1, fp);
00333 bu_semaphore_release(BU_SEM_SYSCALL);
00334 if (got != 1) {
00335 bu_log("bn_spm_px_save(%s): write error\n", filename);
00336 bu_semaphore_acquire(BU_SEM_SYSCALL);
00337 (void) fclose(fp);
00338 bu_semaphore_release(BU_SEM_SYSCALL);
00339 return -1;
00340 }
00341 }
00342 }
00343
00344 bu_semaphore_acquire(BU_SEM_SYSCALL);
00345 (void) fclose(fp);
00346 bu_semaphore_release(BU_SEM_SYSCALL);
00347
00348 return 0;
00349 }
00350
00351
00352 void
00353 bn_spm_dump(bn_spm_map_t *mp, int verbose)
00354 {
00355 int i;
00356
00357 BN_CK_SPM_MAP(mp);
00358
00359 bu_log("elsize = %d\n", mp->elsize);
00360 bu_log("ny = %d\n", mp->ny);
00361 bu_log("_data = %p\n", (void *)mp->_data);
00362 if (!verbose) return;
00363 for (i = 0; i < mp->ny; i++) {
00364 bu_log(" nx[%d] = %3d, xbin[%d] = %p\n",
00365 i, mp->nx[i], i, (void *)mp->xbin[i]);
00366 }
00367 }
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377