Coverage Report

Created: 2026-05-16 08:20

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gdal/frmts/grib/degrib/g2clib/aecunpack.c
Line
Count
Source
1
#include <stdio.h>
2
#include <stdlib.h>
3
#include <limits.h>
4
#include "grib2.h"
5
6
#include "libaec.h"
7
8
// Cf https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp5-42.shtml
9
// and https://github.com/erget/wgrib2/commit/07b0f6fcb9669e0e3285318f50d516731b6956b2
10
11
g2int aecunpack(unsigned char *cpack,g2int len,g2int *idrstmpl,g2int ndpts,
12
                g2float *fld)
13
16
{
14
15
16
      g2int  iret = 0;
16
16
      g2float  refV;
17
18
16
      rdieee(idrstmpl+0,&refV,1);
19
16
      g2float bscale = (g2float)int_power(2.0,idrstmpl[1]);
20
16
      g2float dscale = (g2float)int_power(10.0,-idrstmpl[2]);
21
16
      g2float bdscale = bscale * dscale;
22
16
      g2float refD = refV * dscale;
23
24
16
      g2int nbits = idrstmpl[3];
25
//
26
//  if nbits equals 0, we have a constant field where the reference value
27
//  is the data value at each gridpoint
28
//
29
16
      if (nbits != 0) {
30
16
         int nbytes_per_sample = (nbits + 7) / 8;
31
16
         if( ndpts != 0 && nbytes_per_sample > INT_MAX / ndpts )
32
0
         {
33
0
             return 1;
34
0
         }
35
16
         g2int* ifld=(g2int *)calloc(ndpts,sizeof(g2int));
36
         // Was checked just before
37
         // coverity[integer_overflow,overflow_sink]
38
16
         unsigned char* ctemp=(unsigned char *)calloc((size_t)(ndpts) * nbytes_per_sample,1);
39
16
         if ( ifld == NULL || ctemp == NULL) {
40
0
            fprintf(stderr, "Could not allocate space in aecunpack.\n"
41
0
                    "Data field NOT unpacked.\n");
42
0
            free(ifld);
43
0
            free(ctemp);
44
0
            return(1);
45
0
         }
46
47
16
         struct aec_stream strm = {0};
48
16
         strm.flags = idrstmpl[5]; // CCSDS compression options mask
49
16
         strm.bits_per_sample = nbits;
50
16
         strm.block_size = idrstmpl[6];
51
16
         strm.rsi = idrstmpl[7]; // Restart interval
52
53
16
         strm.next_in = cpack;
54
16
         strm.avail_in = len;
55
16
         strm.next_out = ctemp;
56
16
         strm.avail_out = (size_t)(ndpts) * nbytes_per_sample;
57
58
         // Note: libaec doesn't seem to be very robust to invalid inputs...
59
16
         int status = aec_buffer_decode(&strm);
60
16
         if (status != AEC_OK)
61
12
         {
62
12
             fprintf(stderr, "aec_buffer_decode() failed with return code %d", status);
63
12
             iret = 1;
64
12
         }
65
4
         else
66
4
         {
67
4
             gbits(ctemp,ndpts * nbytes_per_sample,ifld,0,nbytes_per_sample*8,0,ndpts);
68
4
             g2int j;
69
1.62M
             for (j=0;j<ndpts;j++) {
70
1.62M
                fld[j] = refD + bdscale*(g2float)(ifld[j]);
71
1.62M
             }
72
4
         }
73
16
         free(ctemp);
74
16
         free(ifld);
75
16
      }
76
0
      else {
77
0
         g2int j;
78
0
         for (j=0;j<ndpts;j++) fld[j]=refD;
79
0
      }
80
81
16
      return(iret);
82
16
}