sphmap.c

Go to the documentation of this file.
00001 /*                        S P H M A P . C
00002  * BRL-CAD
00003  *
00004  * Copyright (c) 1986-2012 United States Government as represented by
00005  * the U.S. Army Research Laboratory.
00006  *
00007  * This library is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public License
00009  * version 2.1 as published by the Free Software Foundation.
00010  *
00011  * This library is distributed in the hope that it will be useful, but
00012  * WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with this file; see the file named COPYING for more
00018  * information.
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);           /* lock */
00177         fp = fopen(filename, "rb");
00178         bu_semaphore_release(BU_SEM_SYSCALL);           /* unlock */
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);               /* lock */
00188     y = (int)fread((char *)mapp->_data, mapp->elsize, total, fp);       /* res_syscall */
00189     (void) fclose(fp);
00190     bu_semaphore_release(BU_SEM_SYSCALL);               /* unlock */
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);           /* lock */
00212         fp = fopen(filename, "wb");                     /* res_syscall */
00213         bu_semaphore_release(BU_SEM_SYSCALL);           /* unlock */
00214         if (fp == NULL)
00215             return -1;
00216     }
00217 
00218     for (i = 0; i < mapp->ny; i++) {
00219         bu_semaphore_acquire(BU_SEM_SYSCALL);           /* lock */
00220         got = (int)fwrite((char *)mapp->xbin[i], mapp->elsize,  /* res_syscall */
00221                           mapp->nx[i], fp);
00222         bu_semaphore_release(BU_SEM_SYSCALL);           /* unlock */
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);               /* lock */
00226             (void) fclose(fp);
00227             bu_semaphore_release(BU_SEM_SYSCALL);               /* unlock */
00228             return -1;
00229         }
00230     }
00231 
00232     bu_semaphore_acquire(BU_SEM_SYSCALL);               /* lock */
00233     (void) fclose(fp);
00234     bu_semaphore_release(BU_SEM_SYSCALL);               /* unlock */
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;                   /* index input file */
00244     int x, y;                   /* index texture map */
00245     double j_per_y, i_per_x;    /* ratios */
00246     int nj, ni;                 /* ints of ratios */
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);           /* lock */
00259         fp = fopen(filename, "rb");
00260         bu_semaphore_release(BU_SEM_SYSCALL);           /* unlock */
00261         if (fp == NULL)
00262             return -1;
00263     }
00264 
00265     /* Shamelessly suck it all in */
00266     buffer = (unsigned char *)bu_malloc((unsigned)(nx*nx*3), "bn_spm_pix_load buffer");
00267     bu_semaphore_acquire(BU_SEM_SYSCALL);               /* lock */
00268     i = (int)fread((char *)buffer, 3, nx*ny, fp);       /* res_syscall */
00269     (void)fclose(fp);
00270     bu_semaphore_release(BU_SEM_SYSCALL);               /* unlock */
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     /* for each bin */
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         /* for each cell in bin */
00283         for (x = 0; x < mapp->nx[y]; x++) {
00284             /* Average pixels from the input file */
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             /* Save the color */
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);           /* lock */
00322         fp = fopen(filename, "wb");
00323         bu_semaphore_release(BU_SEM_SYSCALL);           /* unlock */
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);               /* lock */
00332             got = (int)fwrite((char *)pixel, sizeof(pixel), 1, fp);     /* res_syscall */
00333             bu_semaphore_release(BU_SEM_SYSCALL);               /* unlock */
00334             if (got != 1) {
00335                 bu_log("bn_spm_px_save(%s): write error\n", filename);
00336                 bu_semaphore_acquire(BU_SEM_SYSCALL);           /* lock */
00337                 (void) fclose(fp);
00338                 bu_semaphore_release(BU_SEM_SYSCALL);           /* unlock */
00339                 return -1;
00340             }
00341         }
00342     }
00343 
00344     bu_semaphore_acquire(BU_SEM_SYSCALL);               /* lock */
00345     (void) fclose(fp);
00346     bu_semaphore_release(BU_SEM_SYSCALL);               /* unlock */
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  * Local Variables:
00371  * mode: C
00372  * tab-width: 8
00373  * indent-tabs-mode: t
00374  * c-file-style: "stroustrup"
00375  * End:
00376  * ex: shiftwidth=4 tabstop=8
00377  */
Generated on Tue Dec 11 13:14:28 2012 for LIBBN by  doxygen 1.6.3