LCOV - code coverage report
Current view: top level - frmts/grib/degrib/g2clib - specunpack.c (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 0 47 0.0 %
Date: 2024-05-06 22:33:47 Functions: 0 2 0.0 %

          Line data    Source code
       1             : #include <math.h>
       2             : #include <float.h>
       3             : #include <stdio.h>
       4             : #include <stdlib.h>
       5             : #include "grib2.h"
       6             : 
       7           0 : static float DoubleToFloatClamp(double val) {
       8           0 :    if (val >= FLT_MAX) return FLT_MAX;
       9           0 :    if (val <= -FLT_MAX) return -FLT_MAX;
      10           0 :    return (float)val;
      11             : }
      12             : 
      13           0 : g2int specunpack(unsigned char *cpack,g2int *idrstmpl,g2int ndpts,g2int JJ,
      14             :                g2int KK, g2int MM, g2float *fld)
      15             : //$$$  SUBPROGRAM DOCUMENTATION BLOCK
      16             : //                .      .    .                                       .
      17             : // SUBPROGRAM:    specunpack
      18             : //   PRGMMR: Gilbert          ORG: W/NP11    DATE: 2000-06-21
      19             : //
      20             : // ABSTRACT: This subroutine unpacks a spectral data field that was packed
      21             : //   using the complex packing algorithm for spherical harmonic data as
      22             : //   defined in the GRIB2 documentation,
      23             : //   using info from the GRIB2 Data Representation Template 5.51.
      24             : //
      25             : // PROGRAM HISTORY LOG:
      26             : // 2000-06-21  Gilbert
      27             : //
      28             : // USAGE:    int specunpack(unsigned char *cpack,g2int *idrstmpl,
      29             : //                          g2int ndpts,g2int JJ,g2int KK,g2int MM,g2float *fld)
      30             : //   INPUT ARGUMENT LIST:
      31             : //     cpack    - pointer to the packed data field.
      32             : //     idrstmpl - pointer to the array of values for Data Representation
      33             : //                Template 5.51
      34             : //     ndpts    - The number of data values to unpack (real and imaginary parts)
      35             : //     JJ       - J - pentagonal resolution parameter
      36             : //     KK       - K - pentagonal resolution parameter
      37             : //     MM       - M - pentagonal resolution parameter
      38             : //
      39             : //   OUTPUT ARGUMENT LIST:
      40             : //     fld()    - Contains the unpacked data values.   fld must be allocated
      41             : //                with at least ndpts*sizeof(g2float) bytes before
      42             : //                calling this routine.
      43             : //
      44             : // REMARKS: None
      45             : //
      46             : // ATTRIBUTES:
      47             : //   LANGUAGE: C
      48             : //   MACHINE:
      49             : //
      50             : //$$$
      51             : {
      52             : 
      53             :       g2int  *ifld,j,iofst,nbits;
      54             :       g2float  ref,bscale,dscale,*unpk;
      55             :       g2float  *pscale,tscale;
      56             :       g2int   Js,Ks,Ms,Ts,Ns,Nm,n,m;
      57             :       g2int   inc,incu,incp;
      58             : 
      59           0 :       rdieee(idrstmpl+0,&ref,1);
      60           0 :       bscale = DoubleToFloatClamp(int_power(2.0,idrstmpl[1]));
      61           0 :       dscale = DoubleToFloatClamp(int_power(10.0,-idrstmpl[2]));
      62           0 :       nbits = idrstmpl[3];
      63           0 :       Js=idrstmpl[5];
      64           0 :       Ks=idrstmpl[6];
      65           0 :       Ms=idrstmpl[7];
      66           0 :       Ts=idrstmpl[8];
      67             : 
      68           0 :       if (idrstmpl[9] == 1) {           // unpacked floats are 32-bit IEEE
      69             : 
      70           0 :          unpk=(g2float *)malloc(ndpts*sizeof(g2float));
      71           0 :          ifld=(g2int *)malloc(ndpts*sizeof(g2int));
      72             : 
      73           0 :          gbits(cpack,G2_UNKNOWN_SIZE,ifld,0,32,0,Ts);
      74           0 :          iofst=32*Ts;
      75           0 :          rdieee(ifld,unpk,Ts);          // read IEEE unpacked floats
      76           0 :          gbits(cpack,G2_UNKNOWN_SIZE,ifld,iofst,nbits,0,ndpts-Ts);  // unpack scaled data
      77             : //
      78             : //   Calculate Laplacian scaling factors for each possible wave number.
      79             : //
      80           0 :          pscale=(g2float *)calloc((JJ+MM+1),sizeof(g2float));
      81           0 :          tscale=(g2float)(idrstmpl[4]*1E-6);
      82           0 :          for (n=Js;n<=JJ+MM;n++)
      83           0 :               pscale[n]=(float)pow((g2float)(n*(n+1)),-tscale);
      84             : //
      85             : //   Assemble spectral coeffs back to original order.
      86             : //
      87           0 :          inc=0;
      88           0 :          incu=0;
      89           0 :          incp=0;
      90           0 :          for (m=0;m<=MM;m++) {
      91           0 :             Nm=JJ;      // triangular or trapezoidal
      92           0 :             if ( KK == JJ+MM ) Nm=JJ+m;          // rhombodial
      93           0 :             Ns=Js;      // triangular or trapezoidal
      94           0 :             if ( Ks == Js+Ms ) Ns=Js+m;          // rhombodial
      95           0 :             for (n=m;n<=Nm;n++) {
      96           0 :                if (n<=Ns && m<=Ms) {    // grab unpacked value
      97           0 :                   fld[inc++]=unpk[incu++];         // real part
      98           0 :                   fld[inc++]=unpk[incu++];     // imaginary part
      99             :                }
     100             :                else {                       // Calc coeff from packed value
     101           0 :                   fld[inc++]=(((g2float)ifld[incp++]*bscale)+ref)*
     102           0 :                             dscale*pscale[n];          // real part
     103           0 :                   fld[inc++]=(((g2float)ifld[incp++]*bscale)+ref)*
     104           0 :                             dscale*pscale[n];          // imaginary part
     105             :                }
     106             :             }
     107             :          }
     108             : 
     109           0 :          free(pscale);
     110           0 :          free(unpk);
     111           0 :          free(ifld);
     112             : 
     113             :       }
     114             :       else {
     115           0 :          printf("specunpack: Cannot handle 64 or 128-bit floats.\n");
     116           0 :          for (j=0;j<ndpts;j++) fld[j]=0.0;
     117           0 :          return -3;
     118             :       }
     119             : 
     120           0 :       return 0;
     121             : }

Generated by: LCOV version 1.14