LCOV - code coverage report
Current view: top level - frmts/grib/degrib/degrib - scan.c (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 12 17 70.6 %
Date: 2024-04-27 14:28:19 Functions: 1 1 100.0 %

          Line data    Source code
       1             : /*****************************************************************************
       2             :  * scan.c
       3             :  *
       4             :  * DESCRIPTION
       5             :  *    This file contains the code that is used to assist with handling the
       6             :  * possible scan values of the grid.
       7             :  *
       8             :  * HISTORY
       9             :  *   10/2002 Arthur Taylor (MDL / RSIS): Created.
      10             :  *
      11             :  * NOTES
      12             :  *****************************************************************************
      13             :  */
      14             : #include "scan.h"
      15             : 
      16             : /*****************************************************************************
      17             :  * ScanIndex2XY() --
      18             :  *
      19             :  * Arthur Taylor / MDL
      20             :  *
      21             :  * PURPOSE
      22             :  *   To convert from the index of the GRIB2 message which is defined by the
      23             :  * scan parameter, to one that seemed reasonable.  The choice for internal
      24             :  * array orientation boiled down to either (scan = 0000) (start from upper
      25             :  * left and across similar to a CRT screen) or (scan = 0100) (start at lower
      26             :  * left and go up ).
      27             :  *   It was decided that (scan 0100) was what people expected.  The only catch
      28             :  * is that Spatial Analyst requires (scan = 0000), so when writing to that
      29             :  * format we have to switch.
      30             :  *   For more info on scan flags: see Grib2 "Flag" Table 3.4
      31             :  *
      32             :  * ARGUMENTS
      33             :  *    row = The index in the scanned in data. (Input)
      34             :  *   X, Y = The x,y position in a scan == 0100 world. (Output)
      35             :  *   scan = The orientation of the GRIB2 grid. (Input)
      36             :  * Nx, Ny = The Dimensions of the grid (Input).
      37             :  *
      38             :  * FILES/DATABASES: None
      39             :  *
      40             :  * RETURNS: void
      41             :  *   Returns x, y, in bounds of [1..Nx], [1..Ny]
      42             :  *      Assuming row is in [0..Nx*Ny)
      43             :  *
      44             :  * HISTORY
      45             :  *   10/2002 Arthur Taylor (MDL/RSIS): Created.
      46             :  *    7/2003 AAT: Switched to x, y [1..Nx] because that is what the map
      47             :  *           routines give.
      48             :  *
      49             :  * NOTES
      50             :  * scan based on Grib2 "Flag" Table 3.4
      51             :  *  scan & GRIB2BIT_1 => decrease x
      52             :  *  scan & GRIB2BIT_2 => increase y
      53             :  *  scan & GRIB2BIT_3 => adjacent points in y direction consecutive.
      54             :  *  scan & GRIB2BIT_4 => adjacent rows scan in opposite directions.
      55             :  *****************************************************************************
      56             :  */
      57     5431920 : void ScanIndex2XY (sInt4 row, sInt4 *X, sInt4 *Y, uChar scan, sInt4 Nx,
      58             :                    sInt4 Ny)
      59             : {
      60             :    sInt4 x;             /* local copy of x */
      61             :    sInt4 y;             /* local copy of y */
      62             : 
      63     5431920 :    if (scan & GRIB2BIT_3) {
      64           0 :       x = row / Ny;
      65           0 :       if ((scan & GRIB2BIT_4) && ((x % 2) == 1)) {
      66           0 :          y = (Ny - 1) - (row % Ny);
      67             :       } else {
      68           0 :          y = row % Ny;
      69             :       }
      70             :    } else {
      71     5431920 :       y = row / Nx;
      72     5431920 :       if ((scan & GRIB2BIT_4) && ((y % 2) == 1)) {
      73      124608 :          x = (Nx - 1) - (row % Nx);
      74             :       } else {
      75     5307310 :          x = row % Nx;
      76             :       }
      77             :    }
      78     5431920 :    if (scan & GRIB2BIT_1) {
      79           0 :       x = (Nx - 1 - x);
      80             :    }
      81     5431920 :    if (!(scan & GRIB2BIT_2)) {
      82     5179960 :       y = (Ny - 1 - y);
      83             :    }
      84             :    /* Changed following two lines (with the + 1) on 7/22/2003 */
      85     5431920 :    *X = x + 1;
      86     5431920 :    *Y = y + 1;
      87     5431920 : }
      88             : 
      89             : /*****************************************************************************
      90             :  * XY2ScanIndex() --
      91             :  *
      92             :  * Arthur Taylor / MDL
      93             :  *
      94             :  * PURPOSE
      95             :  *   To convert from an x,y coordinate system that matches scan = 0100 to the
      96             :  * scan index of the GRIB2 message as defined by the scan parameter.
      97             :  *   This tends to be less important than ScanIndex2XY, but is provided for
      98             :  * testing purposes, and in case it is useful.
      99             :  *
     100             :  * ARGUMENTS
     101             :  *    Row = The index in the scanned in data. (Output)
     102             :  *   x, y = The x,y position in a (scan = 0100) world. (Input)
     103             :  *   scan = The orientation of the GRIB2 grid. (Input)
     104             :  * Nx, Ny = The Dimensions of the grid (Input).
     105             :  *
     106             :  * FILES/DATABASES: None
     107             :  *
     108             :  * RETURNS: void
     109             :  *   Returns row in [0..Nx*Ny)
     110             :  *      Assuming x, y, is in bounds of [1..Nx], [1..Ny]
     111             :  *
     112             :  * HISTORY
     113             :  *   10/2002 Arthur Taylor (MDL/RSIS): Created.
     114             :  *    7/2003 AAT: Switched to x, y [1..Nx] because that is what the map
     115             :  *           routines give.
     116             :  *
     117             :  * NOTES
     118             :  * scan based on Grib2 "Flag" Table 3.4
     119             :  *  scan & GRIB2BIT_1 => decrease x
     120             :  *  scan & GRIB2BIT_2 => increase y
     121             :  *  scan & GRIB2BIT_3 => adjacent points in y direction consecutive.
     122             :  *  scan & GRIB2BIT_4 => adjacent rows scan in opposite directions.
     123             :  *****************************************************************************
     124             :  */
     125             : #ifdef unused_by_GDAL
     126             : void XY2ScanIndex (sInt4 *Row, sInt4 x, sInt4 y, uChar scan, sInt4 Nx,
     127             :                    sInt4 Ny)
     128             : {
     129             :    sInt4 row;           /* local copy of row */
     130             : 
     131             :    /* Added following two lines on 7/22/2003 */
     132             :    x = x - 1;
     133             :    y = y - 1;
     134             :    if (scan & GRIB2BIT_1) {
     135             :       x = (Nx - 1 - x);
     136             :    }
     137             :    if (!(scan & GRIB2BIT_2)) {
     138             :       y = (Ny - 1 - y);
     139             :    }
     140             :    if (scan & GRIB2BIT_3) {
     141             :       if ((scan & GRIB2BIT_4) && ((x % 2) == 1)) {
     142             :          row = Ny - 1 - y + x * Ny;
     143             :       } else {
     144             :          row = y + x * Ny;
     145             :       }
     146             :    } else {
     147             :       if ((scan & GRIB2BIT_4) && ((y % 2) == 1)) {
     148             :          row = Nx - 1 - x + y * Nx;
     149             :       } else {
     150             :          row = x + y * Nx;
     151             :       }
     152             :    }
     153             :    *Row = row;
     154             : }
     155             : #endif // unused_by_GDAL
     156             : 
     157             : /*****************************************************************************
     158             :  * main() --
     159             :  *
     160             :  * Arthur Taylor / MDL
     161             :  *
     162             :  * PURPOSE
     163             :  *   To test the ScanIndex2XY, and XY2ScanIndex routines, to make sure that
     164             :  * they are inverses of each other, for all possible scan values.  Also to
     165             :  * see what a sample array looks like in the various scans, and to make sure
     166             :  * that we are generating (scan = 0100) data.
     167             :  *
     168             :  * ARGUMENTS
     169             :  * argc = The number of arguments on the command line. (Input)
     170             :  * argv = The arguments on the command line. (Input)
     171             :  *
     172             :  * FILES/DATABASES: None
     173             :  *
     174             :  * RETURNS: void
     175             :  *
     176             :  * HISTORY
     177             :  *   10/2002 Arthur Taylor (MDL/RSIS): Created.
     178             :  *
     179             :  * NOTES
     180             :  *****************************************************************************
     181             :  */
     182             : #ifdef TEST_SCAN
     183             : #include <stdio.h>
     184             : int main (int argc, char **argv)
     185             : {
     186             :    int data[3][4];
     187             :    int ray1[6];
     188             :    int ray2[6];
     189             :    sInt4 Nx = 2, Ny = 3;
     190             :    sInt4 NxNy = 6;
     191             :    sInt4 row, x, y;
     192             :    sInt4 x1, y1;
     193             :    int i;
     194             :    int scan;
     195             : 
     196             :    /* Set up sample data. */
     197             :    for (x = 1; x <= Nx; x++) {
     198             :       for (y = 1; y <= Ny; y++) {
     199             :          data[x][y] = 1 + x + (y * 2);
     200             :       }
     201             :    }
     202             :    for (i = 0; i < 16; i++) {
     203             :       scan = i << 4;
     204             :       /* Print scan info. */
     205             :       printf ("Checking xy2row -> row2xy for scan %d ", i);
     206             :       if (scan & GRIB2BIT_1)
     207             :          printf ("-1");
     208             :       else
     209             :          printf ("-0");
     210             :       if (scan & GRIB2BIT_2)
     211             :          printf ("-1");
     212             :       else
     213             :          printf ("-0");
     214             :       if (scan & GRIB2BIT_3)
     215             :          printf ("-1");
     216             :       else
     217             :          printf ("-0");
     218             :       if (scan & GRIB2BIT_4)
     219             :          printf ("-1");
     220             :       else
     221             :          printf ("-0");
     222             :       printf ("\n");
     223             : 
     224             :       /* Test invertiblity of functions. */
     225             :       for (x = 1; x <= Nx; x++) {
     226             :          for (y = 1; y <= Ny; y++) {
     227             :             XY2ScanIndex (&row, x, y, scan, Nx, Ny);
     228             :             ScanIndex2XY (row, &x1, &y1, scan, Nx, Ny);
     229             :             if ((x1 != x) || (y1 != y)) {
     230             :                printf ("   %ld %ld .. %ld .. %ld %ld \n", x, y, row, x1, y1);
     231             :             }
     232             :          }
     233             :       }
     234             : 
     235             :       /* Set up sample scan data. */
     236             :       for (x = 1; x <= Nx; x++) {
     237             :          for (y = 1; y <= Ny; y++) {
     238             :             XY2ScanIndex (&row, x, y, scan, Nx, Ny);
     239             :             ray1[row] = data[x][y];
     240             :          }
     241             :       }
     242             : 
     243             :       /* Convert from ray1[] to ray2[] where ray2[] is scan value 0100. */
     244             :       for (x = 0; x < NxNy; x++) {
     245             :          printf ("%d ", ray1[x]);
     246             :          ScanIndex2XY (x, &x1, &y1, scan, Nx, Ny);
     247             :          /*
     248             :           * To get scan 0000 do the following:
     249             :           * row = x1 + ((Ny-1) - y1) * Nx;
     250             :           */
     251             :          row = (x1 - 1) + (y1 - 1) * Nx;
     252             :          ray2[row] = ray1[x];
     253             :       }
     254             :       printf ("\n");
     255             :       for (x = 0; x < NxNy; x++) {
     256             :          printf ("%d ", ray2[x]);
     257             :       }
     258             :       printf ("\n");
     259             :    }
     260             :    return 0;
     261             : }
     262             : #endif

Generated by: LCOV version 1.14