LCOV - code coverage report
Current view: directory - frmts/sdts - sdtsrasterreader.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 156 93 59.6 %
Date: 2010-01-09 Functions: 8 6 75.0 %

       1                 : /******************************************************************************
       2                 :  * $Id: sdtsrasterreader.cpp 17213 2009-06-07 11:55:50Z rouault $
       3                 :  *
       4                 :  * Project:  SDTS Translator
       5                 :  * Purpose:  Implementation of SDTSRasterReader class.
       6                 :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 1999, Frank Warmerdam
      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                 : #include "sdts_al.h"
      31                 : 
      32                 : CPL_CVSID("$Id: sdtsrasterreader.cpp 17213 2009-06-07 11:55:50Z rouault $");
      33                 : 
      34                 : /************************************************************************/
      35                 : /*                          SDTSRasterReader()                          */
      36                 : /************************************************************************/
      37                 : 
      38               2 : SDTSRasterReader::SDTSRasterReader()
      39                 : 
      40                 : {
      41               2 :     nXSize = 0;
      42               2 :     nYSize = 0;
      43               2 :     nXBlockSize = 0;
      44               2 :     nYBlockSize = 0;
      45               2 :     nXStart = 0;
      46               2 :     nYStart = 0;
      47                 :     
      48               2 :     strcpy( szINTR, "CE" );
      49               2 : }
      50                 : 
      51                 : /************************************************************************/
      52                 : /*                             ~SDTSRasterReader()                     */
      53                 : /************************************************************************/
      54                 : 
      55               2 : SDTSRasterReader::~SDTSRasterReader()
      56                 : {
      57               2 : }
      58                 : 
      59                 : /************************************************************************/
      60                 : /*                               Close()                                */
      61                 : /************************************************************************/
      62                 : 
      63               0 : void SDTSRasterReader::Close()
      64                 : 
      65                 : {
      66               0 :     oDDFModule.Close();
      67               0 : }
      68                 : 
      69                 : /************************************************************************/
      70                 : /*                                Open()                                */
      71                 : /*                                                                      */
      72                 : /*      Open the requested cell file, and collect required              */
      73                 : /*      information.                                                    */
      74                 : /************************************************************************/
      75                 : 
      76               2 : int SDTSRasterReader::Open( SDTS_CATD * poCATD, SDTS_IREF * poIREF,
      77                 :                             const char * pszModule )
      78                 : 
      79                 : {
      80               2 :     strncpy( szModule, pszModule, sizeof(szModule) );
      81               2 :     szModule[sizeof(szModule) - 1] = '\0';
      82                 :     
      83                 : /* ==================================================================== */
      84                 : /*      Search the LDEF module for the requested cell module.           */
      85                 : /* ==================================================================== */
      86               2 :     DDFModule   oLDEF;
      87                 :     DDFRecord   *poRecord;
      88                 : 
      89                 : /* -------------------------------------------------------------------- */
      90                 : /*      Open the LDEF module, and report failure if it is missing.      */
      91                 : /* -------------------------------------------------------------------- */
      92               2 :     if( poCATD->GetModuleFilePath("LDEF") == NULL )
      93                 :     {
      94                 :         CPLError( CE_Failure, CPLE_AppDefined,
      95                 :                   "Can't find LDEF entry in CATD module ... "
      96               0 :                   "can't treat as raster.\n" );
      97               0 :         return FALSE;
      98                 :     }
      99                 :     
     100               2 :     if( !oLDEF.Open( poCATD->GetModuleFilePath("LDEF") ) )
     101               0 :         return FALSE;
     102                 : 
     103                 : /* -------------------------------------------------------------------- */
     104                 : /*      Read each record, till we find what we want.                    */
     105                 : /* -------------------------------------------------------------------- */
     106               4 :     while( (poRecord = oLDEF.ReadRecord() ) != NULL )
     107                 :     {
     108               2 :         if( EQUAL(poRecord->GetStringSubfield("LDEF",0,"CMNM",0), pszModule) )
     109               2 :             break;
     110                 :     }
     111                 : 
     112               2 :     if( poRecord == NULL )
     113                 :     {
     114                 :         CPLError( CE_Failure, CPLE_AppDefined,
     115                 :                   "Can't find module `%s' in LDEF file.\n",
     116               0 :                   pszModule );
     117               0 :         return FALSE;
     118                 :     }
     119                 :     
     120                 : /* -------------------------------------------------------------------- */
     121                 : /*      Extract raster dimensions, and origin offset (0/1).             */
     122                 : /* -------------------------------------------------------------------- */
     123               2 :     nXSize = poRecord->GetIntSubfield( "LDEF", 0, "NCOL", 0 );
     124               2 :     nYSize = poRecord->GetIntSubfield( "LDEF", 0, "NROW", 0 );
     125                 : 
     126               2 :     nXStart = poRecord->GetIntSubfield( "LDEF", 0, "SOCI", 0 );
     127               2 :     nYStart = poRecord->GetIntSubfield( "LDEF", 0, "SORI", 0 );
     128                 : 
     129                 : /* -------------------------------------------------------------------- */
     130                 : /*      Get the point in the pixel that the origin defines.  We only    */
     131                 : /*      support top left and center.                                    */
     132                 : /* -------------------------------------------------------------------- */
     133               2 :     strcpy( szINTR, poRecord->GetStringSubfield(  "LDEF", 0, "INTR", 0 ) );
     134               2 :     if( EQUAL(szINTR,"") )
     135               0 :         strcpy( szINTR, "CE" );
     136                 :     
     137               2 :     if( !EQUAL(szINTR,"CE") && !EQUAL(szINTR,"TL") )
     138                 :     {
     139                 :         CPLError( CE_Warning, CPLE_AppDefined,
     140                 :                   "Unsupported INTR value of `%s', assume CE.\n"
     141                 :                   "Positions may be off by one pixel.\n",
     142               0 :                   szINTR );
     143               0 :         strcpy( szINTR, "CE" );
     144                 :     }
     145                 : 
     146                 : /* -------------------------------------------------------------------- */
     147                 : /*      Record the LDEF record number we used so we can find the        */
     148                 : /*      corresponding RSDF record.                                      */
     149                 : /* -------------------------------------------------------------------- */
     150                 :     int         nLDEF_RCID;
     151                 : 
     152               2 :     nLDEF_RCID = poRecord->GetIntSubfield( "LDEF", 0, "RCID", 0 );
     153                 :     
     154               2 :     oLDEF.Close();
     155                 : 
     156                 : /* ==================================================================== */
     157                 : /*      Search the RSDF module for the requested cell module.           */
     158                 : /* ==================================================================== */
     159               2 :     DDFModule   oRSDF;
     160                 : 
     161                 : /* -------------------------------------------------------------------- */
     162                 : /*      Open the RSDF module, and report failure if it is missing.      */
     163                 : /* -------------------------------------------------------------------- */
     164               2 :     if( poCATD->GetModuleFilePath("RSDF") == NULL )
     165                 :     {
     166                 :         CPLError( CE_Failure, CPLE_AppDefined,
     167                 :                   "Can't find RSDF entry in CATD module ... "
     168               0 :                   "can't treat as raster.\n" );
     169               0 :         return FALSE;
     170                 :     }
     171                 :     
     172               2 :     if( !oRSDF.Open( poCATD->GetModuleFilePath("RSDF") ) )
     173               0 :         return FALSE;
     174                 : 
     175                 : /* -------------------------------------------------------------------- */
     176                 : /*      Read each record, till we find what we want.                    */
     177                 : /* -------------------------------------------------------------------- */
     178               4 :     while( (poRecord = oRSDF.ReadRecord() ) != NULL )
     179                 :     {
     180               2 :         if( poRecord->GetIntSubfield("LYID",0,"RCID",0) == nLDEF_RCID )
     181               2 :             break;
     182                 :     }
     183                 : 
     184               2 :     if( poRecord == NULL )
     185                 :     {
     186                 :         CPLError( CE_Failure, CPLE_AppDefined,
     187                 :                   "Can't find LDEF:%d record in RSDF file.\n",
     188               0 :                   nLDEF_RCID );
     189               0 :         return FALSE;
     190                 :     }
     191                 :     
     192                 : /* -------------------------------------------------------------------- */
     193                 : /*      Establish the raster pixel/line to georef transformation.       */
     194                 : /* -------------------------------------------------------------------- */
     195                 :     double      dfZ;
     196                 :         
     197               2 :     if( poRecord->FindField( "SADR" ) == NULL )
     198                 :     {
     199                 :         CPLError( CE_Failure, CPLE_AppDefined,
     200               0 :                   "Can't find SADR field in RSDF record.\n" );
     201               0 :         return FALSE;
     202                 :     }
     203                 :     
     204                 :     poIREF->GetSADR( poRecord->FindField( "SADR" ), 1,
     205               2 :                      adfTransform + 0, adfTransform + 3, &dfZ );
     206                 : 
     207               2 :     adfTransform[1] = poIREF->dfXRes;
     208               2 :     adfTransform[2] = 0.0;
     209               2 :     adfTransform[4] = 0.0;
     210               2 :     adfTransform[5] = -1 * poIREF->dfYRes;
     211                 : 
     212                 : /* -------------------------------------------------------------------- */
     213                 : /*      If the origin is the center of the pixel, then shift it back    */
     214                 : /*      half a pixel to the top left of the top left.                   */
     215                 : /* -------------------------------------------------------------------- */
     216               2 :     if( EQUAL(szINTR,"CE") )
     217                 :     {
     218               2 :         adfTransform[0] -= adfTransform[1] * 0.5;
     219               2 :         adfTransform[3] -= adfTransform[5] * 0.5;
     220                 :     }
     221                 : 
     222                 : /* -------------------------------------------------------------------- */
     223                 : /*      Verify some other assumptions.                                  */
     224                 : /* -------------------------------------------------------------------- */
     225                 :     const char  *pszString;
     226                 :     
     227               2 :     pszString = poRecord->GetStringSubfield( "RSDF", 0, "OBRP", 0); 
     228               2 :     if( !EQUAL(pszString,"G2") )
     229                 :     {
     230                 :         CPLError( CE_Failure, CPLE_AppDefined,
     231                 :                   "OBRP value of `%s' not expected 2D raster code (G2).\n",
     232               0 :                   pszString );
     233               0 :         return FALSE;
     234                 :     }
     235                 :     
     236               2 :     pszString = poRecord->GetStringSubfield( "RSDF", 0, "SCOR", 0); 
     237               2 :     if( !EQUAL(pszString,"TL") )
     238                 :     {
     239                 :         CPLError( CE_Warning, CPLE_AppDefined,
     240                 :                   "SCOR (origin) is `%s' instead of expected top left.\n"
     241                 :                   "Georef coordinates will likely be incorrect.\n",
     242               0 :                   pszString );
     243                 :     }
     244                 : 
     245               2 :     oRSDF.Close();
     246                 :     
     247                 : /* -------------------------------------------------------------------- */
     248                 : /*      For now we will assume that the block size is one scanline.     */
     249                 : /*      We will blow a gasket later while reading the cell file if      */
     250                 : /*      this isn't the case.                                            */
     251                 : /*                                                                      */
     252                 : /*      This isn't a very flexible raster implementation!               */
     253                 : /* -------------------------------------------------------------------- */
     254               2 :     nXBlockSize = nXSize;
     255               2 :     nYBlockSize = 1;
     256                 : 
     257                 : /* ==================================================================== */
     258                 : /*      Fetch the data type used for the raster, and the units from     */
     259                 : /*      the data dictionary/schema record (DDSH).                       */
     260                 : /* ==================================================================== */
     261               2 :     DDFModule   oDDSH;
     262                 : 
     263                 : /* -------------------------------------------------------------------- */
     264                 : /*      Open the DDSH module, and report failure if it is missing.      */
     265                 : /* -------------------------------------------------------------------- */
     266               2 :     if( poCATD->GetModuleFilePath("DDSH") == NULL )
     267                 :     {
     268                 :         CPLError( CE_Failure, CPLE_AppDefined,
     269                 :                   "Can't find DDSH entry in CATD module ... "
     270               0 :                   "can't treat as raster.\n" );
     271               0 :         return FALSE;
     272                 :     }
     273                 :     
     274               2 :     if( !oDDSH.Open( poCATD->GetModuleFilePath("DDSH") ) )
     275               0 :         return FALSE;
     276                 : 
     277                 : /* -------------------------------------------------------------------- */
     278                 : /*      Read each record, till we find what we want.                    */
     279                 : /* -------------------------------------------------------------------- */
     280               4 :     while( (poRecord = oDDSH.ReadRecord() ) != NULL )
     281                 :     {
     282               2 :         if( EQUAL(poRecord->GetStringSubfield("DDSH",0,"NAME",0),pszModule) )
     283               2 :             break;
     284                 :     }
     285                 : 
     286               2 :     if( poRecord == NULL )
     287                 :     {
     288                 :         CPLError( CE_Failure, CPLE_AppDefined,
     289                 :                   "Can't find DDSH record for %s.\n",
     290               0 :                   pszModule );
     291               0 :         return FALSE;
     292                 :     }
     293                 : 
     294                 : /* -------------------------------------------------------------------- */
     295                 : /*      Get some values we are interested in.                           */
     296                 : /* -------------------------------------------------------------------- */
     297               2 :     if( poRecord->GetStringSubfield("DDSH",0,"FMT",0) != NULL )
     298               2 :         strcpy( szFMT, poRecord->GetStringSubfield("DDSH",0,"FMT",0) );
     299                 :     else
     300               0 :         strcpy( szFMT, "BUI16" );
     301                 : 
     302               2 :     if( poRecord->GetStringSubfield("DDSH",0,"UNIT",0) != NULL )
     303               2 :         strcpy( szUNITS, poRecord->GetStringSubfield("DDSH",0,"UNIT",0) );
     304                 :     else
     305               0 :         strcpy( szUNITS, "METERS" );
     306                 : 
     307               2 :     if( poRecord->GetStringSubfield("DDSH",0,"ATLB",0) != NULL )
     308               2 :         strcpy( szLabel, poRecord->GetStringSubfield("DDSH",0,"ATLB",0) );
     309                 :     else
     310               0 :         strcpy( szLabel, "" );
     311                 :     
     312                 : /* -------------------------------------------------------------------- */
     313                 : /*      Open the cell file.                                             */
     314                 : /* -------------------------------------------------------------------- */
     315               2 :     return( oDDFModule.Open( poCATD->GetModuleFilePath(pszModule) ) );
     316                 : }
     317                 : 
     318                 : /************************************************************************/
     319                 : /*                              GetBlock()                              */
     320                 : /*                                                                      */
     321                 : /*      Read a requested block of raster data from the file.            */
     322                 : /*                                                                      */
     323                 : /*      Currently we will always use sequential access.  In the         */
     324                 : /*      future we should modify the iso8211 library to support          */
     325                 : /*      seeking, and modify this to seek directly to the right          */
     326                 : /*      record once it's location is known.                             */
     327                 : /************************************************************************/
     328                 : 
     329                 : /**
     330                 :   Read a block of raster data from the file.
     331                 : 
     332                 :   @param nXOffset X block offset into the file.  Normally zero for scanline
     333                 :   organized raster files.
     334                 : 
     335                 :   @param nYOffset Y block offset into the file.  Normally the scanline offset
     336                 :   from top of raster for scanline organized raster files.
     337                 : 
     338                 :   @param pData pointer to GInt16 (signed short) buffer of data into which to
     339                 :   read the raster.
     340                 : 
     341                 :   @return TRUE on success and FALSE on error.
     342                 : 
     343                 :   */
     344                 : 
     345              25 : int SDTSRasterReader::GetBlock( int nXOffset, int nYOffset, void * pData )
     346                 : 
     347                 : {
     348                 :     DDFRecord   *poRecord;
     349                 :     int         nBytesPerValue;
     350                 :     int         iTry;
     351                 :     
     352                 :     CPLAssert( nXOffset == 0 );
     353                 : 
     354                 : /* -------------------------------------------------------------------- */
     355                 : /*      Analyse the datatype.                                           */
     356                 : /* -------------------------------------------------------------------- */
     357                 :     CPLAssert( EQUAL(szFMT,"BI16") || EQUAL(szFMT,"BFP32") );
     358                 : 
     359              25 :     if( EQUAL(szFMT,"BI16") )
     360              25 :         nBytesPerValue = 2;
     361                 :     else
     362               0 :         nBytesPerValue = 4;
     363                 : 
     364              50 :     for(iTry=0;iTry<2;iTry++)
     365                 :     {
     366                 :     /* -------------------------------------------------------------------- */
     367                 :     /*      Read through till we find the desired record.                   */
     368                 :     /* -------------------------------------------------------------------- */
     369              25 :         CPLErrorReset();
     370              25 :         while( (poRecord = oDDFModule.ReadRecord()) != NULL )
     371                 :         {
     372              25 :             if( poRecord->GetIntSubfield( "CELL", 0, "ROWI", 0 )
     373                 :                 == nYOffset + nYStart )
     374                 :             {
     375              25 :                 break;
     376                 :             }
     377                 :         }
     378                 : 
     379              25 :         if( CPLGetLastErrorType() == CE_Failure )
     380               0 :             return FALSE;
     381                 : 
     382                 :     /* -------------------------------------------------------------------- */
     383                 :     /*      If we didn't get what we needed just start over.                */
     384                 :     /* -------------------------------------------------------------------- */
     385              25 :         if( poRecord == NULL )
     386                 :         {
     387               0 :             if (iTry == 0)
     388               0 :                 oDDFModule.Rewind();
     389                 :             else
     390                 :             {
     391                 :                 CPLError( CE_Failure, CPLE_AppDefined,
     392                 :                           "Cannot read scanline %d.  Raster access failed.\n",
     393               0 :                           nYOffset );
     394               0 :                 return FALSE;
     395                 :             }
     396                 :         }
     397                 :         else
     398                 :         {
     399              25 :             break;
     400                 :         }
     401                 :     }
     402                 : 
     403                 : /* -------------------------------------------------------------------- */
     404                 : /*      Validate the records size.  Does it represent exactly one       */
     405                 : /*      scanline?                                                       */
     406                 : /* -------------------------------------------------------------------- */
     407                 :     DDFField    *poCVLS;
     408                 : 
     409              25 :     poCVLS = poRecord->FindField( "CVLS" );
     410              25 :     if( poCVLS == NULL )
     411               0 :         return FALSE;
     412                 : 
     413              25 :     if( poCVLS->GetRepeatCount() != nXSize )
     414                 :     {
     415                 :         CPLError( CE_Failure, CPLE_AppDefined,
     416                 :                   "Cell record is %d long, but we expected %d, the number\n"
     417                 :                   "of pixels in a scanline.  Raster access failed.\n",
     418               0 :                   poCVLS->GetRepeatCount(), nXSize );
     419               0 :         return FALSE;
     420                 :     }
     421                 : 
     422                 : /* -------------------------------------------------------------------- */
     423                 : /*      Does the CVLS field consist of exactly 1 B(16) field?           */
     424                 : /* -------------------------------------------------------------------- */
     425              25 :     if( poCVLS->GetDataSize() < nBytesPerValue * nXSize
     426                 :         || poCVLS->GetDataSize() > nBytesPerValue * nXSize + 1 )
     427                 :     {
     428                 :         CPLError( CE_Failure, CPLE_AppDefined,
     429                 :                   "Cell record is not of expected format.  Raster access "
     430               0 :                   "failed.\n" );
     431                 : 
     432               0 :         return FALSE;
     433                 :     }
     434                 : 
     435                 : /* -------------------------------------------------------------------- */
     436                 : /*      Copy the data to the application buffer, and byte swap if       */
     437                 : /*      required.                                                       */
     438                 : /* -------------------------------------------------------------------- */
     439              25 :     memcpy( pData, poCVLS->GetData(), nXSize * nBytesPerValue );
     440                 : 
     441                 : #ifdef CPL_LSB
     442              25 :     if( nBytesPerValue == 2 )
     443                 :     {
     444            8500 :         for( int i = 0; i < nXSize; i++ )
     445                 :         {
     446            8475 :             ((GInt16 *) pData)[i] = CPL_MSBWORD16(((GInt16 *) pData)[i]);
     447                 :         }
     448                 :     }
     449                 :     else
     450                 :     {
     451               0 :         for( int i = 0; i < nXSize; i++ )
     452                 :         {
     453               0 :             CPL_MSBPTR32( ((GByte *)pData) + i*4 );
     454                 :         }
     455                 :     }
     456                 : #endif
     457                 :     
     458              25 :     return TRUE;
     459                 : }
     460                 : 
     461                 : /************************************************************************/
     462                 : /*                            GetTransform()                            */
     463                 : /************************************************************************/
     464                 : 
     465                 : /**
     466                 :   Fetch the transformation between pixel/line coordinates and georeferenced
     467                 :   coordinates.
     468                 : 
     469                 :   @param padfTransformOut pointer to an array of six doubles which will be
     470                 :   filled with the georeferencing transform.
     471                 : 
     472                 :   @return TRUE is returned, indicating success.
     473                 : 
     474                 :   The padfTransformOut array consists of six values.  The pixel/line coordinate
     475                 :   (Xp,Yp) can be related to a georeferenced coordinate (Xg,Yg) or (Easting,
     476                 :   Northing).
     477                 : 
     478                 :   <pre>
     479                 :   Xg = padfTransformOut[0] + Xp * padfTransform[1] + Yp * padfTransform[2]
     480                 :   Yg = padfTransformOut[3] + Xp * padfTransform[4] + Yp * padfTransform[5]
     481                 :   </pre>
     482                 : 
     483                 :   In other words, for a north up image the top left corner of the top left
     484                 :   pixel is at georeferenced coordinate (padfTransform[0],padfTransform[3])
     485                 :   the pixel width is padfTransform[1], the pixel height is padfTransform[5]
     486                 :   and padfTransform[2] and padfTransform[4] will be zero.
     487                 : 
     488                 :   */
     489                 : 
     490               1 : int SDTSRasterReader::GetTransform( double * padfTransformOut )
     491                 : 
     492                 : {
     493               1 :     memcpy( padfTransformOut, adfTransform, sizeof(double)*6 );
     494                 : 
     495               1 :     return TRUE;
     496                 : }
     497                 : 
     498                 : /************************************************************************/
     499                 : /*                           GetRasterType()                            */
     500                 : /************************************************************************/
     501                 : 
     502                 : /**
     503                 :  * Fetch the pixel data type.
     504                 :  *
     505                 :  * Returns one of SDTS_RT_INT16 (1) or SDTS_RT_FLOAT32 (6) indicating the
     506                 :  * type of buffer that should be passed to GetBlock().
     507                 :  */
     508                 : 
     509               2 : int SDTSRasterReader::GetRasterType()
     510                 : 
     511                 : {
     512               2 :     if( EQUAL(szFMT,"BFP32") )
     513               0 :         return 6;
     514                 :     else
     515               2 :         return 1;
     516                 : }
     517                 : 
     518                 : /************************************************************************/
     519                 : /*                             GetMinMax()                              */
     520                 : /************************************************************************/
     521                 : 
     522                 : /**
     523                 :  * Fetch the minimum and maximum raster values that occur in the file.
     524                 :  *
     525                 :  * Note this operation current results in a scan of the entire file.
     526                 :  *
     527                 :  * @param pdfMin variable in which the minimum value encountered is returned.
     528                 :  * @param pdfMax variable in which the maximum value encountered is returned.
     529                 :  * @param dfNoData a value to ignore when computing min/max, defaults to
     530                 :  * -32766.
     531                 :  *
     532                 :  * @return TRUE on success, or FALSE if an error occurs.
     533                 :  */
     534                 : 
     535               0 : int SDTSRasterReader::GetMinMax( double * pdfMin, double * pdfMax,
     536                 :                                  double dfNoData )
     537                 : 
     538                 : {
     539                 :     void  *pBuffer;
     540               0 :     int   bFirst = TRUE;
     541               0 :     int   b32Bit = GetRasterType() == SDTS_RT_FLOAT32;
     542                 : 
     543                 :     CPLAssert( GetBlockXSize() == GetXSize() && GetBlockYSize() == 1 );
     544                 :     
     545               0 :     pBuffer = CPLMalloc(sizeof(float) * GetXSize());
     546                 : 
     547               0 :     for( int iLine = 0; iLine < GetYSize(); iLine++ )
     548                 :     {
     549               0 :         if( !GetBlock( 0, iLine, pBuffer ) )
     550                 :         {
     551               0 :             CPLFree( pBuffer );
     552               0 :             return FALSE;
     553                 :         }
     554                 : 
     555               0 :         for( int iPixel = 0; iPixel < GetXSize(); iPixel++ )
     556                 :         {
     557                 :             double  dfValue;
     558                 :             
     559               0 :             if( b32Bit )
     560               0 :                 dfValue = ((float *) pBuffer)[iPixel];
     561                 :             else
     562               0 :                 dfValue = ((short *) pBuffer)[iPixel];
     563                 : 
     564               0 :             if( dfValue != dfNoData )
     565                 :             {
     566               0 :                 if( bFirst )
     567                 :                 {
     568               0 :                     *pdfMin = *pdfMax = dfValue;
     569               0 :                     bFirst = FALSE;
     570                 :                 }
     571                 :                 else
     572                 :                 {
     573               0 :                     *pdfMin = MIN(*pdfMin,dfValue);
     574               0 :                     *pdfMax = MAX(*pdfMax,dfValue);
     575                 :                 }
     576                 :             }
     577                 :         }
     578                 :     }
     579                 : 
     580               0 :     CPLFree( pBuffer );
     581                 :     
     582               0 :     return !bFirst;
     583                 : }
     584                 : 
     585                 : 

Generated by: LCOV version 1.7