LTP GCOV extension - code coverage report
Current view: directory - frmts/northwood - northwood.cpp
Test: gdal_filtered.info
Date: 2010-07-12 Instrumented lines: 276
Code covered: 44.9 % Executed lines: 124

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

Generated by: LTP GCOV extension version 1.5