LCOV - code coverage report
Current view: directory - frmts/northwood - northwood.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 292 127 43.5 %
Date: 2012-04-28 Functions: 12 5 41.7 %

       1                 : /******************************************************************************
       2                 :  * $Id: northwood.cpp 24120 2012-03-15 19:41:49Z warmerdam $
       3                 :  *
       4                 :  * Project:  GRC/GRD Reader
       5                 :  * Purpose:  Northwood Format basic implementation
       6                 :  * Author:   Perry Casson
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 2007, Waypoint Information Technology
      10                 :  *
      11                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      12                 :  * copy of this software and associated documentation files (the "Software"),
      13                 :  * to deal in the Software without restriction, including without limitation
      14                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      15                 :  * and/or sell copies of the Software, and to permit persons to whom the
      16                 :  * Software is furnished to do so, subject to the following conditions:
      17                 :  *
      18                 :  * The above copyright notice and this permission notice shall be included
      19                 :  * in all copies or substantial portions of the Software.
      20                 :  *
      21                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      22                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      23                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      24                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      25                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      26                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      27                 :  * DEALINGS IN THE SOFTWARE.
      28                 :  ****************************************************************************/
      29                 : 
      30                 : 
      31                 : //#ifndef MSVC
      32                 : #include "gdal_pam.h"
      33                 : //#endif
      34                 : 
      35                 : #include "northwood.h"
      36                 : 
      37                 : 
      38               8 : int nwt_ParseHeader( NWT_GRID * pGrd, char *nwtHeader )
      39                 : {
      40                 :     int i;
      41                 :     unsigned short usTmp;
      42                 :     double dfTmp;
      43                 :     unsigned char cTmp[256];
      44                 : 
      45               8 :     if( nwtHeader[4] == '1' )
      46               6 :         pGrd->cFormat = 0x00;        // grd - surface type
      47               2 :     else if( nwtHeader[4] == '8' )
      48               2 :         pGrd->cFormat = 0x80;        //  grc classified type
      49                 : 
      50               8 :     pGrd->stClassDict = NULL;
      51                 : 
      52                 :     memcpy( (void *) &pGrd->fVersion, (void *) &nwtHeader[5],
      53               8 :               sizeof(pGrd->fVersion) );
      54                 :     CPL_LSBPTR32(&pGrd->fVersion);
      55                 : 
      56               8 :     memcpy( (void *) &usTmp, (void *) &nwtHeader[9], 2 );
      57                 :     CPL_LSBPTR16(&usTmp);
      58               8 :     pGrd->nXSide = (unsigned int) usTmp;
      59               8 :     if( pGrd->nXSide == 0 )
      60                 :     {
      61                 :         memcpy( (void *) &pGrd->nXSide, (void *) &nwtHeader[128],
      62               0 :                 sizeof(pGrd->nXSide) );
      63                 :         CPL_LSBPTR32(&pGrd->nXSide);
      64                 :     }
      65                 : 
      66               8 :     memcpy( (void *) &usTmp, (void *) &nwtHeader[11], 2 );
      67                 :     CPL_LSBPTR16(&usTmp);
      68               8 :     pGrd->nYSide = (unsigned int) usTmp;
      69               8 :     if( pGrd->nYSide == 0 )
      70                 :     {
      71                 :         memcpy( (void *) &pGrd->nYSide, (void *) &nwtHeader[132],
      72               0 :                 sizeof(pGrd->nYSide) );
      73                 :         CPL_LSBPTR32(&pGrd->nYSide);
      74                 :     }
      75                 : 
      76                 :     memcpy( (void *) &pGrd->dfMinX, (void *) &nwtHeader[13],
      77               8 :             sizeof(pGrd->dfMinX) );
      78                 :     CPL_LSBPTR64(&pGrd->dfMinX);
      79                 :     memcpy( (void *) &pGrd->dfMaxX, (void *) &nwtHeader[21],
      80               8 :             sizeof(pGrd->dfMaxX) );
      81                 :     CPL_LSBPTR64(&pGrd->dfMaxX);
      82                 :     memcpy( (void *) &pGrd->dfMinY, (void *) &nwtHeader[29],
      83               8 :             sizeof(pGrd->dfMinY) );
      84                 :     CPL_LSBPTR64(&pGrd->dfMinY);
      85                 :     memcpy( (void *) &pGrd->dfMaxY, (void *) &nwtHeader[37],
      86               8 :             sizeof(pGrd->dfMaxY) );
      87                 :     CPL_LSBPTR64(&pGrd->dfMaxY);
      88                 : 
      89               8 :     pGrd->dfStepSize = (pGrd->dfMaxX - pGrd->dfMinX) / (pGrd->nXSide - 1);
      90               8 :     dfTmp = (pGrd->dfMaxY - pGrd->dfMinY) / (pGrd->nYSide - 1);
      91                 : 
      92                 :     memcpy( (void *) &pGrd->fZMin, (void *) &nwtHeader[45],
      93               8 :             sizeof(pGrd->fZMin) );
      94                 :     CPL_LSBPTR32(&pGrd->fZMin);
      95                 :     memcpy( (void *) &pGrd->fZMax, (void *) &nwtHeader[49],
      96               8 :             sizeof(pGrd->fZMax) );
      97                 :     CPL_LSBPTR32(&pGrd->fZMax);
      98                 :     memcpy( (void *) &pGrd->fZMinScale, (void *) &nwtHeader[53],
      99               8 :             sizeof(pGrd->fZMinScale) );
     100                 :     CPL_LSBPTR32(&pGrd->fZMinScale);
     101                 :     memcpy( (void *) &pGrd->fZMaxScale, (void *) &nwtHeader[57],
     102               8 :             sizeof(pGrd->fZMaxScale) );
     103                 :     CPL_LSBPTR32(&pGrd->fZMaxScale);
     104                 : 
     105                 :     memcpy( (void *) &pGrd->cDescription, (void *) &nwtHeader[61],
     106               8 :             sizeof(pGrd->cDescription) );
     107                 :     memcpy( (void *) &pGrd->cZUnits, (void *) &nwtHeader[93],
     108               8 :             sizeof(pGrd->cZUnits) );
     109                 : 
     110               8 :     memcpy( (void *) &i, (void *) &nwtHeader[136], 4 );
     111                 :     CPL_LSBPTR32(&i);
     112                 : 
     113               8 :     if( i == 1129336130 )
     114                 :     {                            //BMPC
     115               0 :         if( nwtHeader[140] & 0x01 )
     116                 :         {
     117               0 :             pGrd->cHillShadeBrightness = nwtHeader[144];
     118               0 :             pGrd->cHillShadeContrast = nwtHeader[145];
     119                 :         }
     120                 :     }
     121                 : 
     122                 :     memcpy( (void *) &pGrd->cMICoordSys, (void *) &nwtHeader[256],
     123               8 :             sizeof(pGrd->cMICoordSys) );
     124               8 :     pGrd->cMICoordSys[sizeof(pGrd->cMICoordSys)-1] = '\0';
     125                 : 
     126               8 :     pGrd->iZUnits = nwtHeader[512];
     127                 : 
     128               8 :     if( nwtHeader[513] & 0x80 )
     129               0 :         pGrd->bShowGradient = true;
     130                 : 
     131               8 :     if( nwtHeader[513] & 0x40 )
     132               0 :         pGrd->bShowHillShade = true;
     133                 : 
     134               8 :     if( nwtHeader[513] & 0x20 )
     135               0 :         pGrd->bHillShadeExists = true;
     136                 : 
     137                 :     memcpy( (void *) &pGrd->iNumColorInflections, (void *) &nwtHeader[516],
     138               8 :             2 );
     139                 :     CPL_LSBPTR16(&pGrd->iNumColorInflections);
     140                 : 
     141               8 :     if (pGrd->iNumColorInflections > 32)
     142                 :     {
     143               0 :         CPLError(CE_Failure, CPLE_AppDefined, "Corrupt header");
     144               0 :         pGrd->iNumColorInflections = (unsigned short)i;
     145               0 :         return FALSE;
     146                 :     }
     147                 :     
     148              38 :     for( i = 0; i < pGrd->iNumColorInflections; i++ )
     149                 :     {
     150                 :         
     151                 :         memcpy( (void *) &pGrd->stInflection[i].zVal,
     152              30 :                 (void *) &nwtHeader[518 + (7 * i)], 4 );
     153                 :         CPL_LSBPTR32(&pGrd->stInflection[i].zVal);
     154                 :         memcpy( (void *) &pGrd->stInflection[i].r,
     155              30 :                 (void *) &nwtHeader[522 + (7 * i)], 1 );
     156                 :         memcpy( (void *) &pGrd->stInflection[i].g,
     157              30 :                 (void *) &nwtHeader[523 + (7 * i)], 1 );
     158                 :         memcpy( (void *) &pGrd->stInflection[i].b,
     159              30 :                 (void *) &nwtHeader[524 + (7 * i)], 1 );
     160                 :     }
     161                 : 
     162                 :     memcpy( (void *) &pGrd->fHillShadeAzimuth, (void *) &nwtHeader[966],
     163               8 :             sizeof(pGrd->fHillShadeAzimuth) );
     164                 :     CPL_LSBPTR32(&pGrd->fHillShadeAzimuth);
     165                 :     memcpy( (void *) &pGrd->fHillShadeAngle, (void *) &nwtHeader[970],
     166               8 :             sizeof(pGrd->fHillShadeAngle) );
     167                 :     CPL_LSBPTR32(&pGrd->fHillShadeAngle);
     168                 : 
     169               8 :     pGrd->cFormat += nwtHeader[1023];    // the msb for grd/grc was already set
     170                 : 
     171                 : 
     172                 :     // there are more types than this - need to build other types for testing
     173               8 :     if( pGrd->cFormat & 0x80 )
     174                 :     {
     175               2 :         if( nwtHeader[1023] == 0 )
     176               0 :             pGrd->nBitsPerPixel = 16;
     177                 :         else
     178               2 :             pGrd->nBitsPerPixel = nwtHeader[1023] * 4;
     179                 :     }
     180                 :     else
     181               6 :         pGrd->nBitsPerPixel = nwtHeader[1023] * 8;
     182                 : 
     183                 : 
     184               8 :     if( pGrd->cFormat & 0x80 )        // if is GRC load the Dictionary
     185                 :     {
     186                 :         VSIFSeekL( pGrd->fp,
     187                 :                    1024 + (pGrd->nXSide * pGrd->nYSide) * (pGrd->nBitsPerPixel/8),
     188               2 :                    SEEK_SET );
     189                 : 
     190               2 :         if( !VSIFReadL( &usTmp, 2, 1, pGrd->fp) )
     191                 :         {
     192                 :             CPLError( CE_Failure, CPLE_FileIO, 
     193               0 :                       "Read failure, file short?" );
     194               0 :             return FALSE;
     195                 :         }
     196                 :         CPL_LSBPTR16(&usTmp);
     197                 :         pGrd->stClassDict =
     198               2 :             (NWT_CLASSIFIED_DICT *) calloc( sizeof(NWT_CLASSIFIED_DICT), 1 );
     199                 : 
     200               2 :         pGrd->stClassDict->nNumClassifiedItems = usTmp;
     201                 : 
     202                 :         pGrd->stClassDict->stClassifedItem =
     203                 :             (NWT_CLASSIFIED_ITEM **) calloc( sizeof(NWT_CLASSIFIED_ITEM *),
     204                 :                                              pGrd->
     205                 :                                              stClassDict->nNumClassifiedItems +
     206               2 :                                              1 );
     207                 : 
     208                 :         //load the dictionary
     209               8 :         for( usTmp=0; usTmp < pGrd->stClassDict->nNumClassifiedItems; usTmp++ )
     210                 :         {
     211                 :             NWT_CLASSIFIED_ITEM *psItem = 
     212               6 :                 pGrd->stClassDict->stClassifedItem[usTmp] =
     213               6 :                 (NWT_CLASSIFIED_ITEM *) calloc(sizeof(NWT_CLASSIFIED_ITEM), 1);
     214                 : 
     215               6 :             if( !VSIFReadL( &cTmp, 9, 1, pGrd->fp ) )
     216                 :             {
     217                 :                 CPLError( CE_Failure, CPLE_FileIO, 
     218               0 :                           "Read failure, file short?" );
     219               0 :                 return FALSE;
     220                 :             }
     221               6 :             memcpy( (void *) &psItem->usPixVal, (void *) &cTmp[0], 2 );
     222                 :             CPL_LSBPTR16(&psItem->usPixVal);
     223                 :             memcpy( (void *) &psItem->res1,
     224               6 :                     (void *) &cTmp[2], 1 );
     225                 :             memcpy( (void *) &psItem->r,
     226               6 :                     (void *) &cTmp[3], 1 );
     227                 :             memcpy( (void *) &psItem->g,
     228               6 :                     (void *) &cTmp[4], 1 );
     229                 :             memcpy( (void *) &psItem->b,
     230               6 :                     (void *) &cTmp[5], 1 );
     231                 :             memcpy( (void *) &psItem->res2,
     232               6 :                     (void *) &cTmp[6], 1 );
     233                 :             memcpy( (void *) &psItem->usLen,
     234               6 :                     (void *) &cTmp[7], 2 );
     235                 :             CPL_LSBPTR16(&psItem->usLen);
     236                 :                     
     237               6 :             if ( psItem->usLen > sizeof(psItem->szClassName)-1 )
     238                 :             {
     239                 :                 CPLError( CE_Failure, CPLE_AppDefined, 
     240                 :                           "Unexpected long class name, %d characters long - unable to read file.",
     241               0 :                           psItem->usLen );
     242               0 :                 return FALSE;
     243                 :             }
     244                 : 
     245               6 :             if( !VSIFReadL( &psItem->szClassName, psItem->usLen, 1, pGrd->fp ) )
     246               0 :                 return FALSE;
     247                 :         }
     248                 :     }
     249                 :     
     250               8 :     return TRUE;
     251                 : }
     252                 : 
     253                 : 
     254                 : // Create a color gradient ranging from ZMin to Zmax using the color
     255                 : // inflections defined in grid
     256               6 : int nwt_LoadColors( NWT_RGB * pMap, int mapSize, NWT_GRID * pGrd )
     257                 : {
     258                 :     int i;
     259                 :     NWT_RGB sColor;
     260               6 :     int nWarkerMark = 0;
     261                 : 
     262               6 :     createIP( 0, 255, 255, 255, pMap, &nWarkerMark );
     263                 :     // If Zmin is less than the 1st inflection use the 1st inflections color to
     264                 :     // the start of the ramp
     265               6 :     if( pGrd->fZMin <= pGrd->stInflection[0].zVal )
     266                 :     {
     267                 :         createIP( 1, pGrd->stInflection[0].r,
     268                 :                      pGrd->stInflection[0].g,
     269               6 :                      pGrd->stInflection[0].b, pMap, &nWarkerMark );
     270                 :     }
     271                 :     // find what inflections zmin is between
     272              12 :     for( i = 0; i < pGrd->iNumColorInflections; i++ )
     273                 :     {
     274              12 :         if( pGrd->fZMin < pGrd->stInflection[i].zVal )
     275                 :         {
     276                 :             // then we must be between i and i-1
     277               6 :             linearColor( &sColor, &pGrd->stInflection[i - 1],
     278               6 :                                   &pGrd->stInflection[i],
     279              18 :                                   pGrd->fZMin );
     280               6 :             createIP( 1, sColor.r, sColor.g, sColor.b, pMap, &nWarkerMark );
     281               6 :             break;
     282                 :         }
     283                 :     }
     284                 :     // the interesting case of zmin beig higher than the max inflection value
     285               6 :     if( i >= pGrd->iNumColorInflections )
     286                 :     {
     287                 :         createIP( 1,
     288                 :                   pGrd->stInflection[pGrd->iNumColorInflections - 1].r,
     289                 :                   pGrd->stInflection[pGrd->iNumColorInflections - 1].g,
     290                 :                   pGrd->stInflection[pGrd->iNumColorInflections - 1].b,
     291               0 :                   pMap, &nWarkerMark );
     292                 :         createIP( mapSize - 1,
     293                 :                   pGrd->stInflection[pGrd->iNumColorInflections - 1].r,
     294                 :                   pGrd->stInflection[pGrd->iNumColorInflections - 1].g,
     295                 :                   pGrd->stInflection[pGrd->iNumColorInflections - 1].b,
     296               0 :                   pMap, &nWarkerMark );
     297                 :     }
     298                 :     else
     299                 :     {
     300               6 :         int index = 0;
     301              30 :         for( ; i < pGrd->iNumColorInflections; i++ )
     302                 :         {
     303              24 :             if( pGrd->fZMax < pGrd->stInflection[i].zVal )
     304                 :             {
     305                 :                 // then we must be between i and i-1
     306               0 :                 linearColor( &sColor, &pGrd->stInflection[i - 1],
     307               0 :                                       &pGrd->stInflection[i], pGrd->fZMax );
     308               0 :                 index = mapSize - 1;
     309                 :                 createIP( index, sColor.r, sColor.g, sColor.b, pMap,
     310               0 :                            &nWarkerMark );
     311               0 :                 break;
     312                 :             }
     313                 :             // save the inflections between zmin and zmax
     314                 :             index = (int)( ( (pGrd->stInflection[i].zVal - pGrd->fZMin) /
     315                 :                                               (pGrd->fZMax - pGrd->fZMin) )
     316              24 :                            * mapSize);
     317                 :                            
     318              24 :             if ( index >= mapSize )
     319               6 :                 index = mapSize - 1;
     320                 :             createIP( index,
     321                 :                       pGrd->stInflection[i].r,
     322                 :                       pGrd->stInflection[i].g,
     323                 :                       pGrd->stInflection[i].b,
     324              24 :                       pMap, &nWarkerMark );
     325                 :         }
     326               6 :         if( index < mapSize - 1 )
     327                 :             createIP( mapSize - 1,
     328                 :                       pGrd->stInflection[pGrd->iNumColorInflections - 1].r,
     329                 :                       pGrd->stInflection[pGrd->iNumColorInflections - 1].g,
     330                 :                       pGrd->stInflection[pGrd->iNumColorInflections - 1].b,
     331               0 :                       pMap, &nWarkerMark );
     332                 :     }
     333               6 :     return 0;
     334                 : }
     335                 : 
     336                 : //solve for a color between pIPLow and pIPHigh
     337               6 : void linearColor( NWT_RGB * pRGB, NWT_INFLECTION * pIPLow, NWT_INFLECTION * pIPHigh,
     338                 :                       float fMid )
     339                 : {
     340               6 :     if( fMid < pIPLow->zVal )
     341                 :     {
     342               0 :         pRGB->r = pIPLow->r;
     343               0 :         pRGB->g = pIPLow->g;
     344               0 :         pRGB->b = pIPLow->b;
     345                 :     }
     346               6 :     else if( fMid > pIPHigh->zVal )
     347                 :     {
     348               0 :         pRGB->r = pIPHigh->r;
     349               0 :         pRGB->g = pIPHigh->g;
     350               0 :         pRGB->b = pIPHigh->b;
     351                 :     }
     352                 :     else
     353                 :     {
     354               6 :         float scale = (fMid - pIPLow->zVal) / (pIPHigh->zVal - pIPLow->zVal);
     355                 :         pRGB->r = (unsigned char)
     356               6 :                 (scale * (pIPHigh->r - pIPLow->r) + pIPLow->r + 0.5);
     357                 :         pRGB->g = (unsigned char)
     358               6 :                 (scale * (pIPHigh->g - pIPLow->g) + pIPLow->g + 0.5);
     359                 :         pRGB->b = (unsigned char)
     360               6 :                 (scale * (pIPHigh->b - pIPLow->b) + pIPLow->b + 0.5);
     361                 :     }
     362               6 : }
     363                 : 
     364                 : // insert IP's into the map filling as we go
     365              42 : void createIP( int index, unsigned char r, unsigned char g, unsigned char b,
     366                 :                NWT_RGB * map, int *pnWarkerMark )
     367                 : {
     368                 :     int i;
     369                 : 
     370              42 :     if( index == 0 )
     371                 :     {
     372               6 :         map[0].r = r;
     373               6 :         map[0].g = g;
     374               6 :         map[0].b = b;
     375               6 :         *pnWarkerMark = 0;
     376               6 :         return;
     377                 :     }
     378                 : 
     379              36 :     if( index <= *pnWarkerMark )
     380               6 :         return;
     381                 : 
     382              30 :     int wm = *pnWarkerMark;
     383                 : 
     384              30 :     float rslope = (float)(r - map[wm].r) / (float)(index - wm);
     385              30 :     float gslope = (float)(g - map[wm].g) / (float)(index - wm);
     386              30 :     float bslope = (float)(b - map[wm].b) / (float)(index - wm);
     387           24570 :     for( i = wm + 1; i < index; i++)
     388                 :     {
     389           24540 :         map[i].r = map[wm].r + (unsigned char)(((i - wm) * rslope) + 0.5);
     390           24540 :         map[i].g = map[wm].g + (unsigned char)(((i - wm) * gslope) + 0.5);
     391           24540 :         map[i].b = map[wm].b + (unsigned char)(((i - wm) * bslope) + 0.5);
     392                 :     }
     393              30 :     map[index].r = r;
     394              30 :     map[index].g = g;
     395              30 :     map[index].b = b;
     396              30 :     *pnWarkerMark = index;
     397              30 :     return;
     398                 : }
     399                 : 
     400               0 : void nwt_HillShade( unsigned char *r, unsigned char *g, unsigned char *b,
     401                 :                     char *h )
     402                 : {
     403                 :     HLS hls;
     404                 :     NWT_RGB rgb;
     405               0 :     rgb.r = *r;
     406               0 :     rgb.g = *g;
     407               0 :     rgb.b = *b;
     408               0 :     hls = RGBtoHLS( rgb );
     409               0 :     hls.l += ((short) *h) * HLSMAX / 256;
     410               0 :     rgb = HLStoRGB( hls );
     411                 : 
     412               0 :     *r = rgb.r;
     413               0 :     *g = rgb.g;
     414               0 :     *b = rgb.b;
     415                 :     return;
     416                 : }
     417                 : 
     418                 : 
     419               0 : NWT_GRID *nwtOpenGrid( char *filename )
     420                 : {
     421                 :     NWT_GRID *pGrd;
     422                 :     char nwtHeader[1024];
     423                 :     VSILFILE *fp;
     424                 : 
     425               0 :     if( (fp = VSIFOpenL( filename, "rb" )) == NULL )
     426                 :     {
     427               0 :         fprintf( stderr, "\nCan't open %s\n", filename );
     428               0 :         return NULL;
     429                 :     }
     430                 : 
     431               0 :     if( !VSIFReadL( nwtHeader, 1024, 1, fp ) )
     432               0 :         return NULL;
     433                 : 
     434               0 :     if( nwtHeader[0] != 'H' ||
     435               0 :         nwtHeader[1] != 'G' ||
     436               0 :         nwtHeader[2] != 'P' ||
     437               0 :         nwtHeader[3] != 'C' )
     438               0 :           return NULL;
     439                 : 
     440               0 :     pGrd = (NWT_GRID *) calloc( sizeof(NWT_GRID), 1 );
     441                 : 
     442               0 :     if( nwtHeader[4] == '1' )
     443               0 :         pGrd->cFormat = 0x00;        // grd - surface type
     444               0 :     else if( nwtHeader[4] == '8' )
     445               0 :         pGrd->cFormat = 0x80;        //  grc classified type
     446                 :     else
     447                 :     {
     448                 :         fprintf( stderr, "\nUnhandled Northwood format type = %0xd\n",
     449               0 :                  nwtHeader[4] );
     450               0 :         if( pGrd )
     451               0 :             free( pGrd );
     452               0 :         return NULL;
     453                 :     }
     454                 : 
     455               0 :     strcpy( pGrd->szFileName, filename );
     456               0 :     pGrd->fp = fp;
     457               0 :     nwt_ParseHeader( pGrd, nwtHeader );
     458                 : 
     459               0 :     return pGrd;
     460                 : }
     461                 : 
     462                 : //close the file and free the mem
     463               8 : void nwtCloseGrid( NWT_GRID * pGrd )
     464                 : {
     465                 :     unsigned short usTmp;
     466                 : 
     467               8 :     if( (pGrd->cFormat & 0x80) && pGrd->stClassDict )        // if is GRC - free the Dictionary
     468                 :     {
     469               8 :         for( usTmp = 0; usTmp < pGrd->stClassDict->nNumClassifiedItems; usTmp++ )
     470                 :         {
     471               6 :             free( pGrd->stClassDict->stClassifedItem[usTmp] );
     472                 :         }
     473               2 :         free( pGrd->stClassDict->stClassifedItem );
     474               2 :         free( pGrd->stClassDict );
     475                 :     }
     476               8 :     if( pGrd->fp )
     477               0 :         VSIFCloseL( pGrd->fp );
     478               8 :     free( pGrd );
     479                 :         return;
     480                 : }
     481                 : 
     482               0 : void nwtGetRow( NWT_GRID * pGrd )
     483                 : {
     484                 : 
     485               0 : }
     486                 : 
     487               0 : void nwtPrintGridHeader( NWT_GRID * pGrd )
     488                 : {
     489                 :     int i;
     490                 : 
     491               0 :     if( pGrd->cFormat & 0x80 )
     492                 :     {
     493               0 :         printf( "\n%s\n\nGrid type is Classified ", pGrd->szFileName );
     494               0 :         if( pGrd->cFormat == 0x81 )
     495               0 :             printf( "4 bit (Less than 16 Classes)" );
     496               0 :         else if( pGrd->cFormat == 0x82 )
     497               0 :             printf( "8 bit (Less than 256 Classes)" );
     498               0 :         else if( pGrd->cFormat == 0x84 )
     499               0 :             printf( "16 bit (Less than 65536 Classes)" );
     500                 :         else
     501                 :         {
     502               0 :             printf( "GRC - Unhandled Format or Type %d", pGrd->cFormat );
     503               0 :             return;
     504                 :         }
     505                 :     }
     506                 :     else
     507                 :     {
     508               0 :         printf( "\n%s\n\nGrid type is Numeric ", pGrd->szFileName );
     509               0 :         if( pGrd->cFormat == 0x00 )
     510               0 :             printf( "16 bit (Standard Percision)" );
     511               0 :         else if( pGrd->cFormat == 0x01 )
     512               0 :             printf( "32 bit (High Percision)" );
     513                 :         else
     514                 :         {
     515               0 :             printf( "GRD - Unhandled Format or Type %d", pGrd->cFormat );
     516               0 :             return;
     517                 :         }
     518                 :     }
     519               0 :     printf( "\nDim (x,y) = (%d,%d)", pGrd->nXSide, pGrd->nYSide );
     520               0 :     printf( "\nStep Size = %f", pGrd->dfStepSize );
     521                 :     printf( "\nBounds = (%f,%f) (%f,%f)", pGrd->dfMinX, pGrd->dfMinY,
     522               0 :             pGrd->dfMaxX, pGrd->dfMaxY );
     523               0 :     printf( "\nCoordinate System = %s", pGrd->cMICoordSys );
     524                 : 
     525               0 :     if( !(pGrd->cFormat & 0x80) )    // print the numeric specific stuff
     526                 :     {
     527                 :         printf( "\nMin Z = %f Max Z = %f Z Units = %d \"%s\"", pGrd->fZMin,
     528               0 :                 pGrd->fZMax, pGrd->iZUnits, pGrd->cZUnits );
     529                 : 
     530               0 :         printf( "\n\nDisplay Mode =" );
     531               0 :         if( pGrd->bShowGradient )
     532               0 :             printf( " Color Gradient" );
     533                 : 
     534               0 :         if( pGrd->bShowGradient && pGrd->bShowHillShade )
     535               0 :             printf( " and" );
     536                 : 
     537               0 :         if( pGrd->bShowHillShade )
     538               0 :             printf( " Hill Shading" );
     539                 : 
     540               0 :         for( i = 0; i < pGrd->iNumColorInflections; i++ )
     541                 :         {
     542                 :             printf( "\nColor Inflection %d - %f (%d,%d,%d)", i + 1,
     543                 :                     pGrd->stInflection[i].zVal, pGrd->stInflection[i].r,
     544               0 :                     pGrd->stInflection[i].g, pGrd->stInflection[i].b );
     545                 :         }
     546                 : 
     547               0 :         if( pGrd->bHillShadeExists )
     548                 :         {
     549                 :             printf("\n\nHill Shade Azumith = %.1f Inclination = %.1f "
     550                 :                    "Brightness = %d Contrast = %d",
     551                 :                    pGrd->fHillShadeAzimuth, pGrd->fHillShadeAngle,
     552               0 :                    pGrd->cHillShadeBrightness, pGrd->cHillShadeContrast );
     553                 :         }
     554                 :         else
     555               0 :             printf( "\n\nNo Hill Shade Data" );
     556                 :     }
     557                 :     else                            // print the classified specific stuff
     558                 :     {
     559                 :         printf( "\nNumber of Classes defined = %d",
     560               0 :                 pGrd->stClassDict->nNumClassifiedItems );
     561               0 :         for( i = 0; i < (int) pGrd->stClassDict->nNumClassifiedItems; i++ )
     562                 :         {
     563                 :             printf( "\n%s - (%d,%d,%d)  Raw = %d  %d %d",
     564               0 :                     pGrd->stClassDict->stClassifedItem[i]->szClassName,
     565               0 :                     pGrd->stClassDict->stClassifedItem[i]->r,
     566               0 :                     pGrd->stClassDict->stClassifedItem[i]->g,
     567               0 :                     pGrd->stClassDict->stClassifedItem[i]->b,
     568               0 :                     pGrd->stClassDict->stClassifedItem[i]->usPixVal,
     569               0 :                     pGrd->stClassDict->stClassifedItem[i]->res1,
     570               0 :                     pGrd->stClassDict->stClassifedItem[i]->res2 );
     571                 :         }
     572                 :     }
     573                 : }
     574                 : 
     575               0 : HLS RGBtoHLS( NWT_RGB rgb )
     576                 : {
     577                 :     short R, G, B;                /* input RGB values */
     578                 :     HLS hls;
     579                 :     unsigned char cMax, cMin;        /* max and min RGB values */
     580                 :     short Rdelta, Gdelta, Bdelta;    /* intermediate value: % of spread from max */
     581                 :     /* get R, G, and B out of DWORD */
     582               0 :     R = rgb.r;
     583               0 :     G = rgb.g;
     584               0 :     B = rgb.b;
     585                 : 
     586                 :     /* calculate lightness */
     587               0 :     cMax = (unsigned char) MAX( MAX(R,G), B );
     588               0 :     cMin = (unsigned char) MIN( MIN(R,G), B );
     589               0 :     hls.l = (((cMax + cMin) * HLSMAX) + RGBMAX) / (2 * RGBMAX);
     590                 : 
     591               0 :     if( cMax == cMin )
     592                 :     {                            /* r=g=b --> achromatic case */
     593               0 :         hls.s = 0;                /* saturation */
     594               0 :         hls.h = UNDEFINED;        /* hue */
     595                 :     }
     596                 :     else
     597                 :     {                            /* chromatic case */
     598                 :         /* saturation */
     599               0 :         if( hls.l <= (HLSMAX / 2) )
     600                 :             hls.s =
     601               0 :               (((cMax - cMin) * HLSMAX) + ((cMax + cMin) / 2)) / (cMax + cMin);
     602                 :         else
     603                 :             hls.s= (((cMax - cMin) * HLSMAX) + ((2 * RGBMAX - cMax - cMin) / 2))
     604               0 :               / (2 * RGBMAX - cMax - cMin);
     605                 : 
     606                 :         /* hue */
     607                 :         Rdelta =
     608               0 :             (((cMax - R) * (HLSMAX / 6)) + ((cMax - cMin) / 2)) / (cMax - cMin);
     609                 :         Gdelta =
     610               0 :             (((cMax - G) * (HLSMAX / 6)) + ((cMax - cMin) / 2)) / (cMax - cMin);
     611                 :         Bdelta =
     612               0 :             (((cMax - B) * (HLSMAX / 6)) + ((cMax - cMin) / 2)) / (cMax - cMin);
     613                 : 
     614               0 :         if( R == cMax )
     615               0 :             hls.h = Bdelta - Gdelta;
     616               0 :         else if( G == cMax )
     617               0 :             hls.h = (HLSMAX / 3) + Rdelta - Bdelta;
     618                 :         else                        /* B == cMax */
     619               0 :             hls.h = ((2 * HLSMAX) / 3) + Gdelta - Rdelta;
     620                 : 
     621               0 :         if( hls.h < 0 )
     622               0 :             hls.h += HLSMAX;
     623               0 :         if( hls.h > HLSMAX )
     624               0 :             hls.h -= HLSMAX;
     625                 :     }
     626               0 :     return hls;
     627                 : }
     628                 : 
     629                 : 
     630                 : /* utility routine for HLStoRGB */
     631               0 : short HueToRGB( short n1, short n2, short hue )
     632                 : {
     633                 :     /* range check: note values passed add/subtract thirds of range */
     634               0 :     if( hue < 0 )
     635               0 :         hue += HLSMAX;
     636                 : 
     637               0 :     if( hue > HLSMAX )
     638               0 :         hue -= HLSMAX;
     639                 : 
     640                 :     /* return r,g, or b value from this tridrant */
     641               0 :     if( hue < (HLSMAX / 6) )
     642               0 :         return (n1 + (((n2 - n1) * hue + (HLSMAX / 12)) / (HLSMAX / 6)));
     643               0 :     if( hue < (HLSMAX / 2) )
     644               0 :         return (n2);
     645               0 :     if( hue < ((HLSMAX * 2) / 3) )
     646                 :         return (n1 +
     647                 :                 (((n2 - n1) * (((HLSMAX * 2) / 3) - hue) +
     648               0 :                 (HLSMAX / 12)) / (HLSMAX / 6)));
     649                 :     else
     650               0 :         return (n1);
     651                 : }
     652                 : 
     653               0 : NWT_RGB HLStoRGB( HLS hls )
     654                 : {
     655                 :     NWT_RGB rgb;
     656                 :     short Magic1, Magic2;            /* calculated magic numbers (really!) */
     657                 : 
     658               0 :     if( hls.s == 0 )
     659                 :     {                            /* achromatic case */
     660               0 :         rgb.r = rgb.g = rgb.b = (unsigned char) ((hls.l * RGBMAX) / HLSMAX);
     661               0 :         if( hls.h != UNDEFINED )
     662                 :         {
     663                 :             /* ERROR */
     664                 :         }
     665                 :     }
     666                 :     else
     667                 :     {                            /* chromatic case */
     668                 :         /* set up magic numbers */
     669               0 :         if( hls.l <= (HLSMAX / 2) )
     670               0 :             Magic2 = (hls.l * (HLSMAX + hls.s) + (HLSMAX / 2)) / HLSMAX;
     671                 :         else
     672               0 :             Magic2 = hls.l + hls.s - ((hls.l * hls.s) + (HLSMAX / 2)) / HLSMAX;
     673               0 :         Magic1 = 2 * hls.l - Magic2;
     674                 : 
     675                 :         /* get RGB, change units from HLSMAX to RGBMAX */
     676               0 :         rgb.r = (unsigned char) ((HueToRGB (Magic1, Magic2, hls.h + (HLSMAX / 3)) * RGBMAX + (HLSMAX / 2)) / HLSMAX);
     677               0 :         rgb.g = (unsigned char) ((HueToRGB (Magic1, Magic2, hls.h) * RGBMAX + (HLSMAX / 2)) / HLSMAX);
     678               0 :         rgb.b = (unsigned char) ((HueToRGB (Magic1, Magic2, hls.h - (HLSMAX / 3)) * RGBMAX + (HLSMAX / 2)) / HLSMAX);
     679                 :     }
     680                 : 
     681               0 :     return rgb;
     682                 : }

Generated by: LCOV version 1.7