BRL-CAD
sphmap.c
Go to the documentation of this file.
1 /* S P H M A P . C
2  * BRL-CAD
3  *
4  * Copyright (c) 1986-2014 United States Government as represented by
5  * the U.S. Army Research Laboratory.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public License
9  * version 2.1 as published by the Free Software Foundation.
10  *
11  * This library is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this file; see the file named COPYING for more
18  * information.
19  */
20 
21 #include "common.h"
22 
23 #include <stdio.h>
24 #include <math.h>
25 #include <string.h>
26 
27 #include "bu/parallel.h"
28 #include "bu/log.h"
29 #include "bu/malloc.h"
30 #include "bu/str.h"
31 #include "vmath.h"
32 #include "spm.h"
33 
34 
35 void
36 bn_spm_free(bn_spm_map_t *mp)
37 {
38  BN_CK_SPM_MAP(mp);
39  if (mp == BN_SPM_MAP_NULL)
40  return;
41 
42  if (mp->_data != NULL) {
43  (void) bu_free((char *)mp->_data, "sph _data");
44  mp->_data = NULL;
45  }
46 
47  if (mp->nx != NULL) {
48  (void) bu_free((char *)mp->nx, "sph nx");
49  mp->nx = NULL;
50  }
51 
52  if (mp->xbin != NULL) {
53  (void) bu_free((char *)mp->xbin, "sph xbin");
54  mp->xbin = NULL;
55  }
56 
57  (void) bu_free((char *)mp, "bn_spm_map_t");
58 }
59 
60 
61 bn_spm_map_t *
62 bn_spm_init(int N, int elsize)
63 {
64  int i, nx, total, idx;
65  register bn_spm_map_t *mapp;
66 
67  BU_ALLOC(mapp, bn_spm_map_t);
68  if (mapp == BN_SPM_MAP_NULL)
69  return BN_SPM_MAP_NULL;
70  memset((char *)mapp, 0, sizeof(bn_spm_map_t));
71 
72  mapp->elsize = elsize;
73  mapp->ny = N/2;
74  mapp->nx = (int *) bu_malloc((unsigned)(N/2 * sizeof(*(mapp->nx))), "sph nx");
75  if (mapp->nx == NULL) {
76  bn_spm_free(mapp);
77  return BN_SPM_MAP_NULL;
78  }
79  mapp->xbin = (unsigned char **) bu_malloc((unsigned)(N/2 * sizeof(char *)), "sph xbin");
80  if (mapp->xbin == NULL) {
81  bn_spm_free(mapp);
82  return BN_SPM_MAP_NULL;
83  }
84 
85  total = 0;
86  for (i = 0; i < N/4; i++) {
87  nx = ceil(N*cos(i*M_2PI/N));
88  V_MIN(nx, N);
89 
90  mapp->nx[ N/4 + i ] = nx;
91  mapp->nx[ N/4 - i -1 ] = nx;
92 
93  total += 2*nx;
94  }
95 
96  mapp->_data = (unsigned char *) bu_calloc((unsigned)total, elsize, "bn_spm_init data");
97  if (mapp->_data == NULL) {
98  bn_spm_free(mapp);
99  return BN_SPM_MAP_NULL;
100  }
101 
102  idx = 0;
103  for (i = 0; i < N/2; i++) {
104  mapp->xbin[i] = &((mapp->_data)[idx]);
105  idx += elsize * mapp->nx[i];
106  }
107  mapp->magic = BN_SPM_MAGIC;
108  return mapp;
109 }
110 
111 
112 void
113 bn_spm_read(register bn_spm_map_t *mapp, register unsigned char *valp, double u, double v)
114 {
115  int x, y;
116  register unsigned char *cp;
117  register int i;
118 
119  BN_CK_SPM_MAP(mapp);
120 
121  y = v * mapp->ny;
122  x = u * mapp->nx[y];
123  cp = &(mapp->xbin[y][x*mapp->elsize]);
124 
125  i = mapp->elsize;
126  while (i-- > 0) {
127  *valp++ = *cp++;
128  }
129 }
130 
131 
132 void
133 bn_spm_write(register bn_spm_map_t *mapp, register unsigned char *valp, double u, double v)
134 {
135  int x, y;
136  register unsigned char *cp;
137  register int i;
138 
139  BN_CK_SPM_MAP(mapp);
140 
141  y = v * mapp->ny;
142  x = u * mapp->nx[y];
143  cp = &(mapp->xbin[y][x*mapp->elsize]);
144 
145  i = mapp->elsize;
146  while (i-- > 0) {
147  *cp++ = *valp++;
148  }
149 }
150 
151 
152 char *
153 bn_spm_get(register bn_spm_map_t *mapp, double u, double v)
154 {
155  int x, y;
156  register unsigned char *cp;
157 
158  BN_CK_SPM_MAP(mapp);
159 
160  y = v * mapp->ny;
161  x = u * mapp->nx[y];
162  cp = &(mapp->xbin[y][x*mapp->elsize]);
163 
164  return (char *)cp;
165 }
166 
167 
168 int
169 bn_spm_load(bn_spm_map_t *mapp, char *filename)
170 {
171  int y, total;
172  FILE *fp;
173 
174  BN_CK_SPM_MAP(mapp);
175 
176  if (BU_STR_EQUAL(filename, "-"))
177  fp = stdin;
178  else {
180  fp = fopen(filename, "rb");
181  bu_semaphore_release(BU_SEM_SYSCALL); /* unlock */
182  if (fp == NULL)
183  return -1;
184  }
185 
186  total = 0;
187  for (y = 0; y < mapp->ny; y++)
188  total += mapp->nx[y];
189 
191  y = (int)fread((char *)mapp->_data, mapp->elsize, total, fp); /* res_syscall */
192  (void) fclose(fp);
193  bu_semaphore_release(BU_SEM_SYSCALL); /* unlock */
194 
195  if (y != total)
196  return -1;
197 
198  return 0;
199 }
200 
201 
202 int
203 bn_spm_save(bn_spm_map_t *mapp, char *filename)
204 {
205  int i;
206  int got;
207  FILE *fp;
208 
209  BN_CK_SPM_MAP(mapp);
210 
211  if (BU_STR_EQUAL(filename, "-"))
212  fp = stdout;
213  else {
215  fp = fopen(filename, "wb"); /* res_syscall */
216  bu_semaphore_release(BU_SEM_SYSCALL); /* unlock */
217  if (fp == NULL)
218  return -1;
219  }
220 
221  for (i = 0; i < mapp->ny; i++) {
223  got = (int)fwrite((char *)mapp->xbin[i], mapp->elsize, /* res_syscall */
224  mapp->nx[i], fp);
225  bu_semaphore_release(BU_SEM_SYSCALL); /* unlock */
226  if (got != mapp->nx[i]) {
227  bu_log("WARNING: Unable to write SPM to [%s]\n", filename);
229  (void) fclose(fp);
230  bu_semaphore_release(BU_SEM_SYSCALL); /* unlock */
231  return -1;
232  }
233  }
234 
236  (void) fclose(fp);
237  bu_semaphore_release(BU_SEM_SYSCALL); /* unlock */
238 
239  return 0;
240 }
241 
242 
243 int
244 bn_spm_pix_load(bn_spm_map_t *mapp, char *filename, int nx, int ny)
245 {
246  int i, j; /* index input file */
247  int x, y; /* index texture map */
248  double j_per_y, i_per_x; /* ratios */
249  int nj, ni; /* ints of ratios */
250  unsigned char *cp;
251  unsigned char *buffer;
252  unsigned long red, green, blue;
253  long count;
254  FILE *fp;
255 
256  BN_CK_SPM_MAP(mapp);
257 
258  if (BU_STR_EQUAL(filename, "-"))
259  fp = stdin;
260  else {
262  fp = fopen(filename, "rb");
263  bu_semaphore_release(BU_SEM_SYSCALL); /* unlock */
264  if (fp == NULL)
265  return -1;
266  }
267 
268  /* Shamelessly suck it all in */
269  buffer = (unsigned char *)bu_malloc((unsigned)(nx*nx*3), "bn_spm_pix_load buffer");
271  i = (int)fread((char *)buffer, 3, nx*ny, fp); /* res_syscall */
272  (void)fclose(fp);
273  bu_semaphore_release(BU_SEM_SYSCALL); /* unlock */
274  if (i != nx*ny) {
275  bu_log("bn_spm_pix_load(%s) read error\n", filename);
276  return -1;
277  }
278 
279  j_per_y = (double)ny / (double)mapp->ny;
280  nj = (int)j_per_y;
281  /* for each bin */
282  for (y = 0; y < mapp->ny; y++) {
283  i_per_x = (double)nx / (double)mapp->nx[y];
284  ni = (int)i_per_x;
285  /* for each cell in bin */
286  for (x = 0; x < mapp->nx[y]; x++) {
287  /* Average pixels from the input file */
288  red = green = blue = 0;
289  count = 0;
290  for (j = y*j_per_y; j < y*j_per_y+nj; j++) {
291  for (i = x*i_per_x; i < x*i_per_x+ni; i++) {
292  red = red + (unsigned long)buffer[ 3*(j*nx+i) ];
293  green = green + (unsigned long)buffer[ 3*(j*nx+i)+1 ];
294  blue = blue + (unsigned long)buffer[ 3*(j*nx+i)+2 ];
295  count++;
296  }
297  }
298  /* Save the color */
299  cp = &(mapp->xbin[y][x*3]);
300  *cp++ = (unsigned char)(red/count);
301  *cp++ = (unsigned char)(green/count);
302  *cp++ = (unsigned char)(blue/count);
303  }
304  }
305  (void) bu_free((char *)buffer, "bn_spm buffer");
306 
307  return 0;
308 }
309 
310 
311 int
312 bn_spm_pix_save(bn_spm_map_t *mapp, char *filename, int nx, int ny)
313 {
314  int x, y;
315  FILE *fp;
316  unsigned char pixel[3];
317  int got;
318 
319  BN_CK_SPM_MAP(mapp);
320 
321  if (BU_STR_EQUAL(filename, "-"))
322  fp = stdout;
323  else {
325  fp = fopen(filename, "wb");
326  bu_semaphore_release(BU_SEM_SYSCALL); /* unlock */
327  if (fp == NULL)
328  return -1;
329  }
330 
331  for (y = 0; y < ny; y++) {
332  for (x = 0; x < nx; x++) {
333  bn_spm_read(mapp, pixel, (double)x/(double)nx, (double)y/(double)ny);
335  got = (int)fwrite((char *)pixel, sizeof(pixel), 1, fp); /* res_syscall */
336  bu_semaphore_release(BU_SEM_SYSCALL); /* unlock */
337  if (got != 1) {
338  bu_log("bn_spm_px_save(%s): write error\n", filename);
340  (void) fclose(fp);
341  bu_semaphore_release(BU_SEM_SYSCALL); /* unlock */
342  return -1;
343  }
344  }
345  }
346 
348  (void) fclose(fp);
349  bu_semaphore_release(BU_SEM_SYSCALL); /* unlock */
350 
351  return 0;
352 }
353 
354 
355 void
356 bn_spm_dump(bn_spm_map_t *mp, int verbose)
357 {
358  int i;
359 
360  BN_CK_SPM_MAP(mp);
361 
362  bu_log("elsize = %d\n", mp->elsize);
363  bu_log("ny = %d\n", mp->ny);
364  bu_log("_data = %p\n", (void *)mp->_data);
365  if (!verbose) return;
366  for (i = 0; i < mp->ny; i++) {
367  bu_log(" nx[%d] = %3d, xbin[%d] = %p\n",
368  i, mp->nx[i], i, (void *)mp->xbin[i]);
369  }
370 }
371 
372 /*
373  * Local Variables:
374  * mode: C
375  * tab-width: 8
376  * indent-tabs-mode: t
377  * c-file-style: "stroustrup"
378  * End:
379  * ex: shiftwidth=4 tabstop=8
380  */
char filename[MAXLENGTH]
Definition: human.c:105
void bn_spm_dump(bn_spm_map_t *mp, int verbose)
Definition: sphmap.c:356
void bu_log(const char *,...) _BU_ATTR_PRINTF12
Definition: log.c:176
int bn_spm_pix_save(bn_spm_map_t *mapp, char *filename, int nx, int ny)
Definition: sphmap.c:312
char * bn_spm_get(register bn_spm_map_t *mapp, double u, double v)
Definition: sphmap.c:153
#define N
Definition: randmt.c:39
void bu_semaphore_acquire(unsigned int i)
Definition: semaphore.c:180
Header file for the BRL-CAD common definitions.
int bn_spm_pix_load(bn_spm_map_t *mapp, char *filename, int nx, int ny)
Definition: sphmap.c:244
int bn_spm_save(bn_spm_map_t *mapp, char *filename)
Definition: sphmap.c:203
void * bu_malloc(size_t siz, const char *str)
Definition: malloc.c:314
void * memset(void *s, int c, size_t n)
void bn_spm_write(register bn_spm_map_t *mapp, register unsigned char *valp, double u, double v)
Definition: sphmap.c:133
#define BU_ALLOC(_ptr, _type)
Definition: malloc.h:223
void * bu_calloc(size_t nelem, size_t elsize, const char *str)
Definition: malloc.c:321
int bn_spm_load(bn_spm_map_t *mapp, char *filename)
Definition: sphmap.c:169
#define BN_SPM_MAGIC
Definition: magic.h:71
void bu_semaphore_release(unsigned int i)
Definition: semaphore.c:218
#define BU_SEM_SYSCALL
Definition: parallel.h:178
bn_spm_map_t * bn_spm_init(int N, int elsize)
Definition: sphmap.c:62
void bu_free(void *ptr, const char *str)
Definition: malloc.c:328
void bn_spm_read(register bn_spm_map_t *mapp, register unsigned char *valp, double u, double v)
Definition: sphmap.c:113
void bn_spm_free(bn_spm_map_t *mp)
Definition: sphmap.c:36
HIDDEN void verbose(struct human_data_t *dude)
Definition: human.c:2008
#define BU_STR_EQUAL(s1, s2)
Definition: str.h:126