PageRenderTime 48ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/wrfv2_fire/external/io_grib1/WGRIB/BDSunpk.c

http://github.com/jbeezley/wrf-fire
C | 133 lines | 98 code | 11 blank | 24 comment | 26 complexity | a75fa67da2bcdf1e33fc2c30ffc47e6f MD5 | raw file
Possible License(s): AGPL-1.0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <stddef.h>
  4. #include <limits.h>
  5. #include "grib.h"
  6. #include "pds4.h"
  7. #include "bms.h"
  8. #include "bds.h"
  9. /* 1996 wesley ebisuzaki
  10. *
  11. * Unpack BDS section
  12. *
  13. * input: *bits, pointer to packed integer data
  14. * *bitmap, pointer to bitmap (undefined data), NULL if none
  15. * n_bits, number of bits per packed integer
  16. * n, number of data points (includes undefined data)
  17. * ref, scale: flt[] = ref + scale*packed_int
  18. * output: *flt, pointer to output array
  19. * undefined values filled with UNDEFINED
  20. *
  21. * note: code assumes an integer > 32 bits
  22. *
  23. * 7/98 v1.2.1 fix bug for bitmaps and nbit >= 25 found by Larry Brasfield
  24. * 2/01 v1.2.2 changed jj from long int to double
  25. * 3/02 v1.2.3 added unpacking extensions for spectral data
  26. * Luis Kornblueh, MPIfM
  27. */
  28. static unsigned int mask[] = {0,1,3,7,15,31,63,127,255};
  29. static unsigned int map_masks[8] = {128, 64, 32, 16, 8, 4, 2, 1};
  30. static double shift[9] = {1.0, 2.0, 4.0, 8.0, 16.0, 32.0, 64.0, 128.0, 256.0};
  31. void BDS_unpack(float *flt, unsigned char *bds, unsigned char *bitmap,
  32. int n_bits, int n, double ref, double scale) {
  33. unsigned char *bits;
  34. int i, mask_idx, t_bits, c_bits, j_bits;
  35. unsigned int j, map_mask, tbits, jmask, bbits;
  36. double jj;
  37. if (BDS_Harmonic(bds)) {
  38. bits = bds + 15;
  39. /* fill in global mean */
  40. *flt++ = BDS_Harmonic_RefValue(bds);
  41. n -= 1;
  42. }
  43. else {
  44. bits = bds + 11;
  45. }
  46. tbits = bbits = 0;
  47. /* assume integer has 32+ bits */
  48. if (n_bits <= 25) {
  49. jmask = (1 << n_bits) - 1;
  50. t_bits = 0;
  51. if (bitmap) {
  52. for (i = 0; i < n; i++) {
  53. /* check bitmap */
  54. mask_idx = i & 7;
  55. if (mask_idx == 0) bbits = *bitmap++;
  56. if ((bbits & map_masks[mask_idx]) == 0) {
  57. *flt++ = UNDEFINED;
  58. continue;
  59. }
  60. while (t_bits < n_bits) {
  61. tbits = (tbits * 256) + *bits++;
  62. t_bits += 8;
  63. }
  64. t_bits -= n_bits;
  65. j = (tbits >> t_bits) & jmask;
  66. *flt++ = ref + scale*j;
  67. }
  68. }
  69. else {
  70. for (i = 0; i < n; i++) {
  71. while (t_bits < n_bits) {
  72. tbits = (tbits * 256) + *bits++;
  73. t_bits += 8;
  74. }
  75. t_bits -= n_bits;
  76. flt[i] = (tbits >> t_bits) & jmask;
  77. }
  78. /* at least this vectorizes :) */
  79. for (i = 0; i < n; i++) {
  80. flt[i] = ref + scale*flt[i];
  81. }
  82. }
  83. }
  84. else {
  85. /* older unoptimized code, not often used */
  86. c_bits = 8;
  87. map_mask = 128;
  88. while (n-- > 0) {
  89. if (bitmap) {
  90. j = (*bitmap & map_mask);
  91. if ((map_mask >>= 1) == 0) {
  92. map_mask = 128;
  93. bitmap++;
  94. }
  95. if (j == 0) {
  96. *flt++ = UNDEFINED;
  97. continue;
  98. }
  99. }
  100. jj = 0.0;
  101. j_bits = n_bits;
  102. while (c_bits <= j_bits) {
  103. if (c_bits == 8) {
  104. jj = jj * 256.0 + (double) (*bits++);
  105. j_bits -= 8;
  106. }
  107. else {
  108. jj = (jj * shift[c_bits]) + (double) (*bits & mask[c_bits]);
  109. bits++;
  110. j_bits -= c_bits;
  111. c_bits = 8;
  112. }
  113. }
  114. if (j_bits) {
  115. c_bits -= j_bits;
  116. jj = (jj * shift[j_bits]) + (double) ((*bits >> c_bits) & mask[j_bits]);
  117. }
  118. *flt++ = ref + scale*jj;
  119. }
  120. }
  121. return;
  122. }