BRL-CAD
convert.c
Go to the documentation of this file.
1 /* C O N V E R T . C
2  * BRL-CAD
3  *
4  * Copyright (c) 2004-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 <ctype.h>
25 #include <string.h>
26 
27 #include "bu/cv.h"
28 #include "bu/endian.h"
29 #include "bu/malloc.h"
30 #include "bu/str.h"
31 
32 int
33 bu_cv_cookie(const char *in) /* input format */
34 {
35  const char *p;
36  int collector;
37  int result = 0x0000; /* zero/one channel, Net, unsigned, char, clip */
38  int val;
39 
40  if (UNLIKELY(!in)) return 0;
41  if (UNLIKELY(!*in)) return 0;
42  if (UNLIKELY(strlen(in) > 4 || strlen(in) < 1)) return 0;
43 
44  collector = 0;
45  for (p=in, val = *p; val>0 && val<CHAR_MAX && isdigit(val); ++p, val = *p)
46  collector = collector*10 + (val - '0');
47 
48  if (collector > 255) {
49  collector = 255;
50  } else if (collector == 0) {
51  collector = 1;
52  }
53  result = collector; /* number of channels set '|=' */
54 
55  if (!*p) return 0;
56 
57  if (*p == 'h') {
58  result |= CV_HOST_MASK;
59  ++p;
60  } else if (*p == 'n') {
61  ++p;
62  }
63 
64  if (!*p) return 0;
65  if (*p == 'u') {
66  ++p;
67  } else if (*p == 's') {
68  /* could be 'signed' or 'short' */
69  const char *p2;
70  p2 = p+1;
71  val = *p2;
72  if (*p2 && val>0 && val<CHAR_MAX && (islower(val) || isdigit(val))) {
73  result |= CV_SIGNED_MASK;
74  ++p;
75  }
76  }
77 
78  if (!*p)
79  return 0;
80 
81  switch (*p) {
82  case 'c':
83  case '8':
84  result |= CV_8;
85  break;
86  case '1':
87  p++;
88  if (*p != '6') return 0;
89  /* fall through */
90  case 's':
91  result |= CV_16;
92  break;
93  case '3':
94  p++;
95  if (*p != '2') return 0;
96  /* fall through */
97  case 'i':
98  result |= CV_32;
99  break;
100  case '6':
101  p++;
102  if (*p != '4') return 0;
103  /* fall through */
104  case 'l':
105  result |= CV_64;
106  break;
107  case 'd':
108  result |= CV_D;
109  break;
110  default:
111  return 0;
112  }
113  p++;
114 
115  if (!*p) return result;
116  if (*p == 'N') {
117  result |= CV_NORMAL;
118  } else if (*p == 'C') {
119  result |= CV_CLIP;
120  } else if (*p == 'L') {
121  result |= CV_LIT;
122  } else {
123  return 0;
124  }
125  return result;
126 }
127 
128 
129 HIDDEN void
130 bu_cv_fmt_cookie(char *buf, size_t buflen, int cookie)
131 {
132  register char *cp = buf;
133  size_t len;
134 
135  if (UNLIKELY(buflen == 0)) {
136  fprintf(stderr, "bu_cv_pr_cookie: call me with a bigger buffer\n");
137  return;
138  }
139  buflen--;
140  if (UNLIKELY(cookie == 0)) {
141  bu_strlcpy(cp, "bogus!", buflen);
142  return;
143  }
144 
145  snprintf(cp, buflen, "%d", cookie & CV_CHANNEL_MASK);
146  len = strlen(cp);
147  cp += len;
148  if (UNLIKELY(buflen < len))
149  {
150  fprintf(stderr, "bu_cv_pr_cookie: call me with a bigger buffer\n");
151  return;
152  }
153  buflen -= len;
154 
155  if (UNLIKELY(buflen == 0)) {
156  fprintf(stderr, "bu_cv_pr_cookie: call me with a bigger buffer\n");
157  return;
158  }
159  if (cookie & CV_HOST_MASK) {
160  *cp++ = 'h';
161  buflen--;
162  } else {
163  *cp++ = 'n';
164  buflen--;
165  }
166 
167  if (UNLIKELY(buflen == 0)) {
168  fprintf(stderr, "bu_cv_pr_cookie: call me with a bigger buffer\n");
169  return;
170  }
171  if (cookie & CV_SIGNED_MASK) {
172  *cp++ = 's';
173  buflen--;
174  } else {
175  *cp++ = 'u';
176  buflen--;
177  }
178 
179  if (UNLIKELY(buflen == 0)) {
180  fprintf(stderr, "bu_cv_pr_cookie: call me with a bigger buffer\n");
181  return;
182  }
183  switch (cookie & CV_TYPE_MASK) {
184  case CV_8:
185  *cp++ = '8';
186  buflen--;
187  break;
188  case CV_16:
189  bu_strlcpy(cp, "16", buflen);
190  cp += 2;
191  buflen -= 2;
192  break;
193  case CV_32:
194  bu_strlcpy(cp, "32", buflen);
195  cp += 2;
196  buflen -= 2;
197  break;
198  case CV_64:
199  bu_strlcpy(cp, "64", buflen);
200  cp += 2;
201  buflen -= 2;
202  break;
203  case CV_D:
204  *cp++ = 'd';
205  buflen -= 1;
206  break;
207  default:
208  *cp++ = '?';
209  buflen -= 1;
210  break;
211  }
212 
213  if (UNLIKELY(buflen == 0)) {
214  fprintf(stderr, "bu_cv_pr_cookie: call me with a bigger buffer\n");
215  return;
216  }
217  switch (cookie & CV_CONVERT_MASK) {
218  case CV_CLIP:
219  *cp++ = 'C';
220  buflen -= 1;
221  break;
222  case CV_NORMAL:
223  *cp++ = 'N';
224  buflen -= 1;
225  break;
226  case CV_LIT:
227  *cp++ = 'L';
228  buflen -= 1;
229  break;
230  default:
231  *cp++ = 'X';
232  buflen -= 1;
233  break;
234  }
235  *cp = '\0';
236 }
237 
238 
239 void
240 bu_cv_pr_cookie(char *title, int cookie)
241 {
242  char buf[128];
243 
244  bu_cv_fmt_cookie(buf, sizeof(buf), cookie);
245  fprintf(stderr, "%s cookie '%s' (x%x)\n", title, buf, cookie);
246 }
247 
248 
249 size_t
250 bu_cv(void *out, char *outfmt, size_t size, void *in, char *infmt, size_t count)
251 {
252  int incookie, outcookie;
253  incookie = bu_cv_cookie(infmt);
254  outcookie = bu_cv_cookie(outfmt);
255  return bu_cv_w_cookie(out, outcookie, size, in, incookie, count);
256 }
257 
258 
259 int
260 bu_cv_optimize(register int cookie)
261 {
262  int fmt;
263 
264  if (cookie & CV_HOST_MASK)
265  return cookie; /* already in most efficient form */
266 
267  /* This is a network format request */
268  fmt = cookie & CV_TYPE_MASK;
269 
270  switch (fmt) {
271  case CV_D:
272  cookie |= CV_HOST_MASK; /* host uses network fmt */
273  return cookie;
274  case CV_8:
275  return cookie | CV_HOST_MASK; /* bytes already host format */
276  case CV_16:
277  case CV_32:
278  case CV_64:
279  /* host is big-endian, so is network */
280  if (bu_byteorder() == BU_BIG_ENDIAN)
281  cookie |= CV_HOST_MASK;
282  return cookie;
283  }
284  return 0; /* ERROR */
285 }
286 
287 
288 size_t
289 bu_cv_itemlen(register int cookie)
290 {
291  register int fmt = (cookie & CV_TYPE_MASK) >> CV_TYPE_SHIFT;
292  static size_t host_size_table[8] = {0, sizeof(char),
293  sizeof(short), sizeof(int),
294  sizeof(long int), sizeof(double)};
295  static size_t net_size_table[8] = {0, 1, 2, 4, 8, 8};
296 
297  if (cookie & CV_HOST_MASK)
298  return host_size_table[fmt];
299  return net_size_table[fmt];
300 }
301 
302 
303 size_t
304 bu_cv_ntohss(register short int *out, size_t size, register void *in, size_t count)
305 {
306  size_t limit;
307  register size_t i;
308 
309  limit = size / sizeof(signed short);
310  if (limit < count)
311  count = limit;
312 
313  for (i=0; i<count; i++) {
314  *out++ = ((signed char *)in)[0] << 8 | ((unsigned char *)in)[1];
315  /* XXX This needs sign extension here for the case of
316  * XXX a negative 2-byte input on a 4 or 8 byte machine.
317  * XXX The "signed char" trick isn't enough.
318  * XXX Use your Cyber trick w/magic numbers or something.
319  */
320  in = ((char *)in) + 2;
321  }
322  return count;
323 }
324 
325 
326 size_t
327 bu_cv_ntohus(register short unsigned int *out, size_t size, register void *in, size_t count)
328 {
329  size_t limit;
330  register size_t i;
331 
332  limit = size / sizeof(unsigned short);
333  if (limit < count)
334  count = limit;
335 
336  for (i=0; i<count; i++) {
337  *out++ = ((unsigned char *)in)[0]<<8 |
338  ((unsigned char *)in)[1];
339  in = ((char *)in) + 2;
340  }
341  return count;
342 }
343 
344 
345 size_t
346 bu_cv_ntohsl(register long int *out, size_t size, register void *in, size_t count)
347 {
348  size_t limit;
349  register size_t i;
350 
351  limit = size / sizeof(signed long int);
352  if (limit < count)
353  count = limit;
354 
355  for (i=0; i<count; i++) {
356  *out++ = ((signed char *)in)[0] << 24 |
357  ((unsigned char *)in)[1] << 16 |
358  ((unsigned char *)in)[2] << 8 |
359  ((unsigned char *)in)[3];
360  /* XXX Sign extension here */
361  in = ((char *)in) + 4;
362  }
363 
364  return count;
365 }
366 
367 
368 size_t
369 bu_cv_ntohul(register long unsigned int *out, size_t size, register void *in, size_t count)
370 {
371  size_t limit;
372  register size_t i;
373 
374  limit = size / sizeof(unsigned long int);
375  if (limit < count)
376  count = limit;
377 
378  for (i=0; i<count; i++) {
379  *out++ =
380  (unsigned long)((unsigned char *)in)[0] << 24 |
381  (unsigned long)((unsigned char *)in)[1] << 16 |
382  (unsigned long)((unsigned char *)in)[2] << 8 |
383  (unsigned long)((unsigned char *)in)[3];
384  in = ((char *)in) + 4;
385  }
386  return count;
387 }
388 
389 
390 size_t
391 bu_cv_htonss(void *out, size_t size, register short int *in, size_t count)
392 {
393  size_t limit;
394  register size_t i;
395  register unsigned char *cp = (unsigned char *)out;
396  register int val;
397 
398  limit = size / 2;
399  if (count > limit) count = limit;
400 
401  for (i=0; i<count; i++) {
402  *cp++ = (val = *in++)>>8;
403  *cp++ = val;
404  }
405  return count;
406 }
407 
408 
409 size_t
410 bu_cv_htonus(void *out, size_t size, register short unsigned int *in, size_t count)
411 {
412  size_t limit;
413  register size_t i;
414  register unsigned char *cp = (unsigned char *)out;
415  register int val;
416 
417  limit = size / 2;
418  if (count > limit)
419  count = limit;
420 
421  for (i=0; i<count; i++) {
422  *cp++ = (val = *in++)>>8;
423  *cp++ = val;
424  }
425  return count;
426 }
427 
428 
429 size_t
430 bu_cv_htonsl(void *out, size_t size, register long int *in, size_t count)
431 {
432  size_t limit;
433  register size_t i;
434  register unsigned char *cp = (unsigned char *)out;
435  register long val;
436 
437  limit = size / 4;
438  if (count > limit)
439  count = limit;
440 
441  for (i=0; i<count; i++) {
442  *cp++ = (val = *in++)>>24;
443  *cp++ = val>>16;
444  *cp++ = val>> 8;
445  *cp++ = val;
446  }
447  return count;
448 }
449 
450 
451 size_t
452 bu_cv_htonul(void *out, size_t size, register long unsigned int *in, size_t count)
453 {
454  size_t limit;
455  register size_t i;
456  register unsigned char *cp = (unsigned char *)out;
457  register long val;
458 
459  limit = size / 4;
460  if (count > limit)
461  count = limit;
462 
463  for (i=0; i<count; i++) {
464  *cp++ = (val = *in++)>>24;
465  *cp++ = val>>16;
466  *cp++ = val>> 8;
467  *cp++ = val;
468  }
469  return count;
470 }
471 
472 
473 size_t
474 bu_cv_w_cookie(void *out, int outcookie, size_t size, void *in, int incookie, size_t count)
475 {
476  size_t work_count = 4096;
477  size_t number_done = 0;
478  int inIsHost, outIsHost, infmt, outfmt;
479  size_t insize, outsize;
480  size_t bufsize;
481  void *t1;
482  void *t2;
483  void *t3;
484  void *from;
485  void *to;
486  void *hold;
487  register size_t i;
488 
489  /*
490  * Work_count is the size of the working buffer. If count is
491  * smaller than the default work_count (4096) use the smaller
492  * number.
493  */
494 
495  if (work_count > count)
496  work_count = count;
497 
498  incookie = bu_cv_optimize(incookie);
499  outcookie = bu_cv_optimize(outcookie);
500 
501  /*
502  * break out the conversion code and the format code. Conversion
503  * is net<-->host. Format is 8/16/32/64/D casting.
504  */
505  inIsHost = incookie & CV_HOST_MASK; /* not zero if host */
506  outIsHost= outcookie& CV_HOST_MASK;
507  infmt = incookie & CV_TYPE_MASK;
508  outfmt = outcookie & CV_TYPE_MASK;
509  /*
510  * Find the number of bytes required for one item of each kind.
511  */
512  outsize = bu_cv_itemlen(outcookie);
513  insize = bu_cv_itemlen(incookie);
514 
515  /*
516  * If the input format is the same as the output format then the
517  * most that has to be done is a host to net or net to host
518  * conversion.
519  */
520  if (infmt == outfmt) {
521 
522  /*
523  * Input format is the same as output format, do we need to do
524  * a host/net conversion?
525  */
526  if (inIsHost == outIsHost) {
527 
528  /*
529  * No conversion required. Check the amount of space
530  * remaining before doing the memmove.
531  */
532  if ((unsigned int)count * outsize > size) {
533  number_done = (int)(size / outsize);
534  } else {
535  number_done = count;
536  }
537 
538  /*
539  * This is the simplest case, binary copy and out.
540  */
541  memmove((void *)out, (void *)in, (size_t)number_done * outsize);
542  return number_done;
543 
544  /*
545  * Well it's still the same format but the conversions are
546  * different. Only one of the *vert variables can be HOST
547  * therefore if inIsHost != HOST then outIsHost must be
548  * host format.
549  */
550 
551  } else if (inIsHost != CV_HOST_MASK) {
552  /* net format */
553  switch (incookie & (CV_SIGNED_MASK | CV_TYPE_MASK)) {
554  case CV_SIGNED_MASK | CV_16:
555  return bu_cv_ntohss((signed short *)out, size, in, count);
556  case CV_16:
557  return bu_cv_ntohus((unsigned short *)out, size, in, count);
558  case CV_SIGNED_MASK | CV_32:
559  return bu_cv_ntohsl((signed long *)out, size, in, count);
560  case CV_32:
561  return bu_cv_ntohul((unsigned long *)out, size, in, count);
562  case CV_D:
563  (void) bu_cv_ntohd((unsigned char *)out, (unsigned char *)in, count);
564  return count;
565  }
566 
567  /*
568  * Since inIsHost != outIsHost and inIsHost == HOST then
569  * outIsHost must be in net format. call the correct
570  * subroutine to do the conversion.
571  */
572  } else {
573  switch (incookie & (CV_SIGNED_MASK | CV_TYPE_MASK)) {
574  case CV_SIGNED_MASK | CV_16:
575  return bu_cv_htonss(out, size, (short *)in, count);
576  case CV_16:
577  return bu_cv_htonus(out, size, (unsigned short *)in, count);
578  case CV_SIGNED_MASK | CV_32:
579  return bu_cv_htonsl(out, size, (long *)in, count);
580  case CV_32:
581  return bu_cv_htonul(out, size, (unsigned long *)in, count);
582  case CV_D:
583  (void) bu_cv_htond((unsigned char *)out, (unsigned char *)in, count);
584  return count;
585  }
586  }
587  }
588  /*
589  * If we get to this point then the input format is known to be of
590  * a different type than the output format. This will require a
591  * cast to, from or to and from double.
592  *
593  * Because the number of steps is not known initially, we get
594  * three working buffers. The size of a double is the largest of
595  * any of the sizes we may be dealing with.
596  */
597 
598  bufsize = work_count * sizeof(double);
599  t1 = (void *) bu_malloc(bufsize, "convert.c: t1");
600  t2 = (void *) bu_malloc(bufsize, "convert.c: t2");
601  t3 = (void *) bu_malloc(bufsize, "convert.c: t3");
602 
603  /*
604  * From here on we will be working on a chunk of process at a time.
605  */
606  while (size >= (unsigned int)outsize && number_done < count) {
607  size_t remaining;
608 
609  /*
610  * Size is the number of bytes that the caller said was
611  * available. We need the check to make sure that we will not
612  * convert too many entries, overflowing the output buffer.
613  */
614 
615  /*
616  * Get number of full entries that can be converted
617  */
618  remaining = (int)(size / outsize);
619 
620  /*
621  * If number of entries that would fit in the output buffer is
622  * larger than the number of entries left to convert(based on
623  * count and number done), set remaining to request count
624  * minus the number of conversions already completed.
625  */
626  if (remaining > count - number_done) {
627  remaining = count - number_done;
628  }
629  /*
630  * If we are in the last chunk, set the work count to take up
631  * the slack.
632  */
633  if (remaining < work_count) work_count = remaining;
634 
635  /*
636  * All input at any stage will come from the "from" pointer.
637  * We start with the from pointer pointing to the input
638  * buffer.
639  */
640  from = in;
641 
642  /*
643  * We will be processing work_count entries of insize bytes
644  * each, so we set the in pointer to be ready for the next
645  * time through the loop.
646  */
647  in = ((char *) in) + work_count * insize;
648 
649  /*
650  * If the input is in net format convert it to host format.
651  * Because we know that the input format is not equal to the
652  * output this means that there will be at least two
653  * conversions taking place if the input is in net format.
654  * (from net to host then at least one cast)
655  */
656  if (inIsHost != CV_HOST_MASK) {
657  /* net format */
658  switch (incookie & (CV_SIGNED_MASK | CV_TYPE_MASK)) {
659  case CV_SIGNED_MASK | CV_16:
660  (void) bu_cv_ntohss((short *)t1, bufsize, from, work_count);
661  break;
662  case CV_16:
663  (void) bu_cv_ntohus((unsigned short *)t1, bufsize, from, work_count);
664  break;
665  case CV_SIGNED_MASK | CV_32:
666  (void) bu_cv_ntohsl((long *)t1, bufsize, from, work_count);
667  break;
668  case CV_32:
669  (void) bu_cv_ntohul((unsigned long *)t1, bufsize, from, work_count);
670  break;
671  case CV_D:
672  (void) bu_cv_ntohd((unsigned char *)t1, (unsigned char *)from, work_count);
673  break;
674  }
675  /*
676  * Point the "from" pointer to the host format.
677  */
678  from = t1;
679  }
680 
681 
682  /*
683  * "From" is a pointer to a HOST format buffer.
684  */
685 
686  /*
687  * If the input format is not double then there must be a cast
688  * to double.
689  */
690  if (infmt != CV_D) {
691 
692  /*
693  * if the output conversion is HOST and output format is
694  * DOUBLE then this will be the last step.
695  */
696  if (outIsHost == CV_HOST_MASK && outfmt == CV_D) {
697  to = out;
698  } else {
699  to = t2;
700  }
701 
702  hold = to;
703  /*
704  * Cast the input format to double.
705  */
706  switch (incookie & (CV_SIGNED_MASK | CV_TYPE_MASK)) {
707  case CV_SIGNED_MASK | CV_8:
708  for (i=0; i< work_count; i++) {
709  *((double *)to) = *((signed char *)from);
710  to = (void *)(((double *)to) + 1);
711  from = ((char *)from) + 1;
712  }
713  break;
714  case CV_8:
715  for (i=0; i < work_count; i++) {
716  *((double *)to) = *((unsigned char *)from);
717  to = (void *)(((double *)to) + 1);
718  from = (void *)(((unsigned char *)from) + 1);
719  }
720  break;
721  case CV_SIGNED_MASK | CV_16:
722  for (i=0; i < work_count; i++) {
723  *((double *)to) = *((signed short *)from);
724  to = (void *)(((double *)to) + 1);
725  from = (void *)(((signed short *)from) + 1);
726  }
727  break;
728  case CV_16:
729  for (i=0; i < work_count; i++) {
730  *((double *)to) = *((unsigned short *)from);
731  to = (void *)(((double *)to) + 1);
732  from = (void *)(((unsigned short *)from) + 1);
733  }
734  break;
735  case CV_SIGNED_MASK | CV_32:
736  for (i=0; i < work_count; i++) {
737  *((double *)to) = *((signed long int *)from);
738  to = (void *)(((double *)to) + 1);
739  from = (void *)(((signed long int *)from) + 1);
740  }
741  break;
742  case CV_32:
743  for (i=0; i < work_count; i++) {
744  *((double *)to) = *((unsigned long int *) from);
745  to = (void *)(((double *)to) + 1);
746  from = (void *)(((unsigned long int *)from) + 1);
747  }
748  break;
749  default:
750  fprintf(stderr, "Unimplemented input format\n");
751  break;
752  }
753  from = hold;
754  }
755 
756  if (outfmt != CV_D) {
757  /*
758  * The input point is now pointing to a double in host
759  * format. If the output is also in host format then the
760  * next conversion will be the last conversion, set the
761  * destination to reflect this.
762  */
763 
764  if (outIsHost == CV_HOST_MASK) {
765  to = out;
766  } else {
767  to = t3;
768  }
769 
770  /*
771  * The output format is something other than DOUBLE (tested
772  * for earlier), do a cast from double to requested
773  * format.
774  */
775  hold = to;
776 
777  switch (outcookie & (CV_SIGNED_MASK | CV_TYPE_MASK)) {
778  case CV_SIGNED_MASK | CV_8:
779  for (i=0; i<work_count; i++) {
780  *((signed char *)to) = *((double *)from);
781  to = (void *)(((signed char *)to) + 1);
782  from = (void *)(((double *)from) + 1);
783  }
784  break;
785  case CV_8:
786  for (i=0; i<work_count; i++) {
787  *((unsigned char *)to) =
788  (unsigned char)(*((double *)from));
789  to = (void *)(((unsigned char *)to) + 1);
790  from = (void *)(((double *)from) + 1);
791  }
792  break;
793  case CV_SIGNED_MASK | CV_16:
794  for (i=0; i<work_count; i++) {
795  *((signed short int *)to) =
796  *((double *)from);
797  to = (void *)(((signed short int *)to) + 1);
798  from = (void *)(((double *)from) + 1);
799  }
800  break;
801  case CV_16:
802  for (i=0; i<work_count; i++) {
803  *((unsigned short int *)to) =
804  *((double *)from);
805  to = (void *)(((unsigned short int *)to) + 1);
806  from = (void *)(((double *)from) + 1);
807  }
808  break;
809  case CV_SIGNED_MASK | CV_32:
810  for (i=0; i<work_count; i++) {
811  *((signed long int *)to) =
812  *((double *)from);
813  to = (void *)(((signed long int *)to) + 1);
814  from = (void *)(((double *)from) + 1);
815  }
816  break;
817  case CV_32:
818  for (i=0; i<work_count; i++) {
819  *((unsigned long int *)to) =
820  *((double *)from);
821  to = (void *)(((unsigned long int *)to) + 1);
822  from = (void *)(((double *)from) + 1);
823  }
824  break;
825  default:
826  fprintf(stderr, "Unimplemented output format\n");
827  break;
828 
829  }
830  from = hold;
831  /*
832  * The input is now pointing to a host formatted buffer of
833  * the requested output format.
834  */
835 
836  /*
837  * If the output conversion is network then do a host to
838  * net call for either 16 or 32 bit values using Host TO
839  * Network All Short | Long
840  */
841  if (outIsHost != CV_HOST_MASK) {
842  switch (outfmt) {
843  case CV_16 | CV_SIGNED_MASK:
844  (void) bu_cv_htonss(out, bufsize, (short int *)from, work_count);
845  break;
846  case CV_16:
847  (void) bu_cv_htonus(out, bufsize, (unsigned short int *)from, work_count);
848  break;
849  case CV_32 | CV_SIGNED_MASK:
850  (void) bu_cv_htonsl(out, bufsize, (long int *)from, work_count);
851  break;
852  case CV_32:
853  (void) bu_cv_htonul(out, bufsize, (unsigned long int *)from, work_count);
854  break;
855  case CV_D:
856  default:
857  /* do nothing */
858  break;
859  }
860  }
861 
862  }
863  /*
864  * move the output pointer. reduce the amount of space
865  * remaining in the output buffer. Increment the count of
866  * values converted.
867  */
868  out = ((char *)out) + work_count * outsize;
869  size -= work_count * outsize;
870  number_done += work_count;
871  }
872  /*
873  * All Done! Clean up and leave.
874  */
875  bu_free(t1, "convert.c: t1");
876  bu_free(t2, "convert.c: t2");
877  bu_free(t3, "convert.c: t3");
878  return number_done;
879 }
880 
881 
882 /*
883  * Local Variables:
884  * mode: C
885  * tab-width: 8
886  * indent-tabs-mode: t
887  * c-file-style: "stroustrup"
888  * End:
889  * ex: shiftwidth=4 tabstop=8
890  */
Definition: db_flip.c:35
void bu_cv_pr_cookie(char *title, int cookie)
Definition: convert.c:240
#define CV_LIT
Definition: cv.h:80
size_t bu_cv_ntohul(register long unsigned int *out, size_t size, register void *in, size_t count)
Definition: convert.c:369
#define CV_CLIP
Definition: cv.h:78
bu_endian_t bu_byteorder(void)
Definition: endian.c:27
Header file for the BRL-CAD common definitions.
void bu_cv_htond(unsigned char *out, const unsigned char *in, size_t count)
HIDDEN void bu_cv_fmt_cookie(char *buf, size_t buflen, int cookie)
Definition: convert.c:130
#define HIDDEN
Definition: common.h:86
void * bu_malloc(size_t siz, const char *str)
Definition: malloc.c:314
size_t bu_cv_htonss(void *out, size_t size, register short int *in, size_t count)
Definition: convert.c:391
#define CV_SIGNED_MASK
Definition: cv.h:65
#define CV_TYPE_MASK
Definition: cv.h:66
#define CV_64
Definition: cv.h:75
size_t bu_cv_w_cookie(void *out, int outcookie, size_t size, void *in, int incookie, size_t count)
Definition: convert.c:474
size_t bu_cv(void *out, char *outfmt, size_t size, void *in, char *infmt, size_t count)
Definition: convert.c:250
size_t bu_cv_htonus(void *out, size_t size, register short unsigned int *in, size_t count)
Definition: convert.c:410
#define CV_TYPE_SHIFT
Definition: cv.h:69
#define bu_strlcpy(dst, src, size)
Definition: str.h:60
int bu_cv_optimize(register int cookie)
Definition: convert.c:260
int bu_cv_cookie(const char *in)
Definition: convert.c:33
#define CV_16
Definition: cv.h:73
goto out
Definition: nmg_mod.c:3846
size_t bu_cv_htonul(void *out, size_t size, register long unsigned int *in, size_t count)
Definition: convert.c:452
#define CV_32
Definition: cv.h:74
size_t bu_cv_ntohus(register short unsigned int *out, size_t size, register void *in, size_t count)
Definition: convert.c:327
size_t bu_cv_htonsl(void *out, size_t size, register long int *in, size_t count)
Definition: convert.c:430
void bu_cv_ntohd(unsigned char *out, const unsigned char *in, size_t count)
#define CV_NORMAL
Definition: cv.h:79
#define CV_CONVERT_MASK
Definition: cv.h:67
#define CV_D
Definition: cv.h:76
#define CV_8
Definition: cv.h:72
void bu_free(void *ptr, const char *str)
Definition: malloc.c:328
size_t bu_cv_ntohss(register short int *out, size_t size, register void *in, size_t count)
Definition: convert.c:304
#define CV_CHANNEL_MASK
Definition: cv.h:63
size_t bu_cv_itemlen(register int cookie)
Definition: convert.c:289
Definition: joint.h:163
size_t bu_cv_ntohsl(register long int *out, size_t size, register void *in, size_t count)
Definition: convert.c:346
#define CV_HOST_MASK
Definition: cv.h:64
#define UNLIKELY(expression)
Definition: common.h:282