LCOV - code coverage report
Current view: directory - frmts/raw - pauxdataset.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 350 232 66.3 %
Date: 2010-01-09 Functions: 23 15 65.2 %

       1                 : /******************************************************************************
       2                 :  * $Id: pauxdataset.cpp 16706 2009-04-02 03:44:07Z warmerdam $
       3                 :  *
       4                 :  * Project:  PCI .aux Driver
       5                 :  * Purpose:  Implementation of PAuxDataset
       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 "rawdataset.h"
      31                 : #include "cpl_string.h"
      32                 : #include "ogr_spatialref.h"
      33                 : 
      34                 : CPL_CVSID("$Id: pauxdataset.cpp 16706 2009-04-02 03:44:07Z warmerdam $");
      35                 : 
      36                 : CPL_C_START
      37                 : void  GDALRegister_PAux(void);
      38                 : CPL_C_END
      39                 : 
      40                 : /************************************************************************/
      41                 : /* ==================================================================== */
      42                 : /*        PAuxDataset       */
      43                 : /* ==================================================================== */
      44                 : /************************************************************************/
      45                 : 
      46                 : class PAuxRasterBand;
      47                 : 
      48                 : class PAuxDataset : public RawDataset
      49                 : {
      50                 :     friend class PAuxRasterBand;
      51                 : 
      52                 :     FILE  *fpImage; // image data file.
      53                 : 
      54                 :     int         nGCPCount;
      55                 :     GDAL_GCP    *pasGCPList;
      56                 :     char        *pszGCPProjection;
      57                 : 
      58                 :     void        ScanForGCPs();
      59                 :     char       *PCI2WKT( const char *pszGeosys, const char *pszProjParms );
      60                 : 
      61                 :     char       *pszProjection;
      62                 : 
      63                 :   public:
      64                 :         PAuxDataset();
      65                 :               ~PAuxDataset();
      66                 :     
      67                 :     char  *pszAuxFilename;
      68                 :     char  **papszAuxLines;
      69                 :     int   bAuxUpdated;
      70                 :     
      71                 :     virtual const char *GetProjectionRef();
      72                 :     virtual CPLErr GetGeoTransform( double * );
      73                 :     virtual CPLErr SetGeoTransform( double * );
      74                 : 
      75                 :     virtual int    GetGCPCount();
      76                 :     virtual const char *GetGCPProjection();
      77                 :     virtual const GDAL_GCP *GetGCPs();
      78                 : 
      79                 :     static GDALDataset *Open( GDALOpenInfo * );
      80                 :     static GDALDataset *Create( const char * pszFilename,
      81                 :                                 int nXSize, int nYSize, int nBands,
      82                 :                                 GDALDataType eType, char ** papszParmList );
      83                 : };
      84                 : 
      85                 : /************************************************************************/
      86                 : /* ==================================================================== */
      87                 : /*                           PAuxRasterBand                             */
      88                 : /* ==================================================================== */
      89                 : /************************************************************************/
      90                 : 
      91                 : class PAuxRasterBand : public RawRasterBand
      92                 : {
      93                 :     GDALColorTable  *poCT;
      94                 : 
      95                 :   public:
      96                 : 
      97                 :                  PAuxRasterBand( GDALDataset *poDS, int nBand, FILE * fpRaw, 
      98                 :                                  vsi_l_offset nImgOffset, int nPixelOffset,
      99                 :                                  int nLineOffset,
     100                 :                                  GDALDataType eDataType, int bNativeOrder );
     101                 : 
     102                 :                  ~PAuxRasterBand();
     103                 : 
     104                 :     virtual double GetNoDataValue( int *pbSuccess = NULL );
     105                 :     virtual CPLErr SetNoDataValue( double );
     106                 : 
     107                 :     virtual GDALColorTable *GetColorTable();
     108                 :     virtual GDALColorInterp GetColorInterpretation();
     109                 : 
     110                 :     virtual void SetDescription( const char *pszNewDescription );
     111                 : };
     112                 : 
     113                 : /************************************************************************/
     114                 : /*                           PAuxRasterBand()                           */
     115                 : /************************************************************************/
     116                 : 
     117              46 : PAuxRasterBand::PAuxRasterBand( GDALDataset *poDS, int nBand,
     118                 :                                 FILE * fpRaw, vsi_l_offset nImgOffset,
     119                 :                                 int nPixelOffset, int nLineOffset,
     120                 :                                 GDALDataType eDataType, int bNativeOrder )
     121                 :         : RawRasterBand( poDS, nBand, fpRaw, 
     122                 :                          nImgOffset, nPixelOffset, nLineOffset, 
     123              46 :                          eDataType, bNativeOrder, TRUE )
     124                 : 
     125                 : {
     126              46 :     PAuxDataset *poPDS = (PAuxDataset *) poDS;
     127                 : 
     128              46 :     poCT = NULL;
     129                 : 
     130                 : /* -------------------------------------------------------------------- */
     131                 : /*      Does this channel have a description?                           */
     132                 : /* -------------------------------------------------------------------- */
     133                 :     char  szTarget[128];
     134                 : 
     135              46 :     sprintf( szTarget, "ChanDesc-%d", nBand );
     136              46 :     if( CSLFetchNameValue( poPDS->papszAuxLines, szTarget ) != NULL )
     137                 :         GDALRasterBand::SetDescription( 
     138               0 :             CSLFetchNameValue( poPDS->papszAuxLines, szTarget ) );
     139                 : 
     140                 : /* -------------------------------------------------------------------- */
     141                 : /*      See if we have colors.  Currently we must have color zero,      */
     142                 : /*      but this shouldn't really be a limitation.                      */
     143                 : /* -------------------------------------------------------------------- */
     144              46 :     sprintf( szTarget, "METADATA_IMG_%d_Class_%d_Color", nBand, 0 );
     145              46 :     if( CSLFetchNameValue( poPDS->papszAuxLines, szTarget ) != NULL )
     146                 :     {
     147                 :         const char *pszLine;
     148                 :         int         i;
     149                 : 
     150               0 :         poCT = new GDALColorTable();
     151                 : 
     152               0 :         for( i = 0; i < 256; i++ )
     153                 :         {
     154                 :             int nRed, nGreen, nBlue;
     155                 : 
     156               0 :             sprintf( szTarget, "METADATA_IMG_%d_Class_%d_Color", nBand, i );
     157               0 :             pszLine = CSLFetchNameValue( poPDS->papszAuxLines, szTarget );
     158               0 :             while( pszLine && *pszLine == ' ' )
     159               0 :                 pszLine++;
     160                 : 
     161               0 :             if( pszLine != NULL
     162                 :                 && EQUALN(pszLine, "(RGB:",5)
     163                 :                 && sscanf( pszLine+5, "%d %d %d", 
     164                 :                            &nRed, &nGreen, &nBlue ) == 3 )
     165                 :             {
     166                 :                 GDALColorEntry    oColor;
     167                 :                 
     168               0 :                 oColor.c1 = (short) nRed;
     169               0 :                 oColor.c2 = (short) nGreen;
     170               0 :                 oColor.c3 = (short) nBlue;
     171               0 :                 oColor.c4 = 255;
     172                 : 
     173               0 :                 poCT->SetColorEntry( i, &oColor );
     174                 :             }
     175                 :         }
     176                 :     }
     177              46 : }
     178                 : 
     179                 : /************************************************************************/
     180                 : /*                          ~PAuxRasterBand()                           */
     181                 : /************************************************************************/
     182                 : 
     183              92 : PAuxRasterBand::~PAuxRasterBand()
     184                 : 
     185                 : {
     186              46 :     if( poCT != NULL )
     187               0 :         delete poCT;
     188              92 : }
     189                 : 
     190                 : /************************************************************************/
     191                 : /*                           GetNoDataValue()                           */
     192                 : /************************************************************************/
     193                 : 
     194               4 : double PAuxRasterBand::GetNoDataValue( int *pbSuccess )
     195                 : 
     196                 : {
     197               4 :     PAuxDataset *poPDS = (PAuxDataset *) poDS;
     198                 :     char  szTarget[128];
     199                 :     const char  *pszLine;
     200                 : 
     201               4 :     sprintf( szTarget, "METADATA_IMG_%d_NO_DATA_VALUE", nBand );
     202                 : 
     203               4 :     pszLine = CSLFetchNameValue( poPDS->papszAuxLines, szTarget );
     204                 : 
     205               4 :     if( pbSuccess != NULL )
     206               4 :         *pbSuccess = (pszLine != NULL);
     207                 : 
     208               4 :     if( pszLine == NULL )
     209               4 :         return -1e8;
     210                 :     else
     211               0 :         return atof(pszLine);
     212                 : }
     213                 : 
     214                 : /************************************************************************/
     215                 : /*                           SetNoDataValue()                           */
     216                 : /************************************************************************/
     217                 : 
     218               0 : CPLErr PAuxRasterBand::SetNoDataValue( double dfNewValue )
     219                 : 
     220                 : {
     221               0 :     PAuxDataset *poPDS = (PAuxDataset *) poDS;
     222                 :     char  szTarget[128];
     223                 :     char  szValue[128];
     224                 : 
     225               0 :     if( GetAccess() == GA_ReadOnly )
     226                 :     {
     227                 :         CPLError( CE_Failure, CPLE_NoWriteAccess, 
     228               0 :                   "Can't update readonly dataset." );
     229               0 :         return CE_Failure;
     230                 :     }
     231                 : 
     232               0 :     sprintf( szTarget, "METADATA_IMG_%d_NO_DATA_VALUE", nBand );
     233               0 :     sprintf( szValue, "%24.12f", dfNewValue );
     234                 :     poPDS->papszAuxLines = 
     235               0 :         CSLSetNameValue( poPDS->papszAuxLines, szTarget, szValue );
     236                 :     
     237               0 :     poPDS->bAuxUpdated = TRUE;
     238                 : 
     239               0 :     return CE_None;
     240                 : }
     241                 : 
     242                 : /************************************************************************/
     243                 : /*                           SetDescription()                           */
     244                 : /*                                                                      */
     245                 : /*      We override the set description so we can mark the auxfile      */
     246                 : /*      info as changed.                                                */
     247                 : /************************************************************************/
     248                 : 
     249               0 : void PAuxRasterBand::SetDescription( const char *pszNewDescription )
     250                 : 
     251                 : {
     252               0 :     PAuxDataset *poPDS = (PAuxDataset *) poDS;
     253                 : 
     254               0 :     if( GetAccess() == GA_Update )
     255                 :     {
     256                 :         char  szTarget[128];
     257                 : 
     258               0 :         sprintf( szTarget, "ChanDesc-%d", nBand );
     259                 :         poPDS->papszAuxLines = 
     260                 :             CSLSetNameValue( poPDS->papszAuxLines, 
     261               0 :                              szTarget, pszNewDescription  );
     262                 :     
     263               0 :         poPDS->bAuxUpdated = TRUE;
     264                 :     }
     265                 : 
     266               0 :     GDALRasterBand::SetDescription( pszNewDescription );
     267               0 : }
     268                 : 
     269                 : 
     270                 : /************************************************************************/
     271                 : /*                           GetColorTable()                            */
     272                 : /************************************************************************/
     273                 : 
     274               0 : GDALColorTable *PAuxRasterBand::GetColorTable()
     275                 : 
     276                 : {
     277               0 :     return poCT;
     278                 : }
     279                 : 
     280                 : /************************************************************************/
     281                 : /*                       GetColorInterpretation()                       */
     282                 : /************************************************************************/
     283                 : 
     284              15 : GDALColorInterp PAuxRasterBand::GetColorInterpretation()
     285                 : 
     286                 : {
     287              15 :     if( poCT == NULL )
     288              15 :         return GCI_Undefined;
     289                 :     else
     290               0 :         return GCI_PaletteIndex;
     291                 : }
     292                 : 
     293                 : /************************************************************************/
     294                 : /* ==================================================================== */
     295                 : /*        PAuxDataset       */
     296                 : /* ==================================================================== */
     297                 : /************************************************************************/
     298                 : 
     299                 : /************************************************************************/
     300                 : /*                            PAuxDataset()                             */
     301                 : /************************************************************************/
     302                 : 
     303              24 : PAuxDataset::PAuxDataset()
     304                 : {
     305              24 :     papszAuxLines = NULL;
     306              24 :     fpImage = NULL;
     307              24 :     bAuxUpdated = FALSE;
     308              24 :     pszAuxFilename = NULL;
     309              24 :     nGCPCount = 0;
     310              24 :     pasGCPList = NULL;
     311                 : 
     312              24 :     pszProjection = NULL;
     313              24 :     pszGCPProjection = NULL;
     314              24 : }
     315                 : 
     316                 : /************************************************************************/
     317                 : /*                            ~PAuxDataset()                            */
     318                 : /************************************************************************/
     319                 : 
     320              48 : PAuxDataset::~PAuxDataset()
     321                 : 
     322                 : {
     323              24 :     FlushCache();
     324              24 :     if( fpImage != NULL )
     325              23 :         VSIFCloseL( fpImage );
     326                 : 
     327              24 :     if( bAuxUpdated )
     328                 :     {
     329              10 :         CSLSetNameValueSeparator( papszAuxLines, ": " );
     330              10 :         CSLSave( papszAuxLines, pszAuxFilename );
     331                 :     }
     332                 : 
     333              24 :     CPLFree( pszProjection );
     334                 : 
     335              24 :     CPLFree( pszGCPProjection );
     336              24 :     GDALDeinitGCPs( nGCPCount, pasGCPList );
     337              24 :     CPLFree( pasGCPList );
     338                 : 
     339              24 :     CPLFree( pszAuxFilename );
     340              24 :     CSLDestroy( papszAuxLines );
     341              48 : }
     342                 : 
     343                 : /************************************************************************/
     344                 : /*                              PCI2WKT()                               */
     345                 : /*                                                                      */
     346                 : /*      Convert PCI coordinate system to WKT.  For now this is very     */
     347                 : /*      incomplete, but can be filled out in the future.                */
     348                 : /************************************************************************/
     349                 : 
     350               0 : char *PAuxDataset::PCI2WKT( const char *pszGeosys, 
     351                 :                             const char *pszProjParms )
     352                 : 
     353                 : {
     354               0 :     OGRSpatialReference oSRS;
     355                 : 
     356               0 :     while( *pszGeosys == ' ' )
     357               0 :         pszGeosys++;
     358                 : 
     359                 : /* -------------------------------------------------------------------- */
     360                 : /*      Parse projection parameters array.                              */
     361                 : /* -------------------------------------------------------------------- */
     362                 :     double adfProjParms[16];
     363                 :     
     364               0 :     memset( adfProjParms, 0, sizeof(adfProjParms) );
     365                 : 
     366               0 :     if( pszProjParms != NULL )
     367                 :     {
     368                 :         char **papszTokens;
     369                 :         int i;
     370                 : 
     371               0 :         papszTokens = CSLTokenizeString( pszProjParms );
     372                 :         
     373               0 :         for( i=0; papszTokens != NULL && papszTokens[i] != NULL && i < 16; i++)
     374               0 :             adfProjParms[i] = atof(papszTokens[i]);
     375                 : 
     376               0 :         CSLDestroy( papszTokens );
     377                 :     }
     378                 :     
     379                 : /* -------------------------------------------------------------------- */
     380                 : /*      Convert to SRS.                                                 */
     381                 : /* -------------------------------------------------------------------- */
     382               0 :     if( oSRS.importFromPCI( pszGeosys, NULL, adfProjParms ) == OGRERR_NONE )
     383                 :     {
     384               0 :         char *pszResult = NULL;
     385                 : 
     386               0 :         oSRS.exportToWkt( &pszResult );
     387                 : 
     388               0 :         return pszResult;
     389                 :     }
     390                 :     else
     391               0 :         return NULL;
     392                 : }
     393                 : 
     394                 : /************************************************************************/
     395                 : /*                            ScanForGCPs()                             */
     396                 : /************************************************************************/
     397                 : 
     398              23 : void PAuxDataset::ScanForGCPs()
     399                 : 
     400                 : {
     401                 : #define MAX_GCP   256
     402                 : 
     403              23 :     nGCPCount = 0;
     404              23 :     pasGCPList = (GDAL_GCP *) CPLCalloc(sizeof(GDAL_GCP),MAX_GCP);
     405                 : 
     406                 : /* -------------------------------------------------------------------- */
     407                 : /*      Get the GCP coordinate system.                                  */
     408                 : /* -------------------------------------------------------------------- */
     409                 :     const char  *pszMapUnits, *pszProjParms;
     410                 : 
     411              23 :     pszMapUnits = CSLFetchNameValue( papszAuxLines, "GCP_1_MapUnits" );
     412              23 :     pszProjParms = CSLFetchNameValue( papszAuxLines, "GCP_1_ProjParms" );
     413                 :     
     414              23 :     if( pszMapUnits != NULL )
     415               0 :         pszGCPProjection = PCI2WKT( pszMapUnits, pszProjParms );
     416                 :     
     417                 : /* -------------------------------------------------------------------- */
     418                 : /*      Collect standalone GCPs.  They look like:                       */
     419                 : /*                                                                      */
     420                 : /*      GCP_1_n = row, col, x, y [,z [,"id"[, "desc"]]]     */
     421                 : /* -------------------------------------------------------------------- */
     422                 :     int i;
     423                 : 
     424              23 :     for( i = 0; nGCPCount < MAX_GCP; i++ )
     425                 :     {
     426                 :         char  szName[50];
     427                 :         char    **papszTokens;
     428                 : 
     429              23 :         sprintf( szName, "GCP_1_%d", i+1 );
     430              23 :         if( CSLFetchNameValue( papszAuxLines, szName ) == NULL )
     431              23 :             break;
     432                 : 
     433                 :         papszTokens = CSLTokenizeStringComplex( 
     434                 :             CSLFetchNameValue( papszAuxLines, szName ), 
     435               0 :             " ", TRUE, FALSE );
     436                 : 
     437               0 :         if( CSLCount(papszTokens) >= 4 )
     438                 :         {
     439               0 :             GDALInitGCPs( 1, pasGCPList + nGCPCount );
     440                 : 
     441               0 :             pasGCPList[nGCPCount].dfGCPX = atof(papszTokens[2]);
     442               0 :             pasGCPList[nGCPCount].dfGCPY = atof(papszTokens[3]);
     443               0 :             pasGCPList[nGCPCount].dfGCPPixel = atof(papszTokens[0]);
     444               0 :             pasGCPList[nGCPCount].dfGCPLine = atof(papszTokens[1]);
     445                 : 
     446               0 :             if( CSLCount(papszTokens) > 4 )
     447               0 :                 pasGCPList[nGCPCount].dfGCPZ = atof(papszTokens[4]);
     448                 : 
     449               0 :             CPLFree( pasGCPList[nGCPCount].pszId );
     450               0 :             if( CSLCount(papszTokens) > 5 )
     451                 :             {
     452               0 :                 pasGCPList[nGCPCount].pszId = CPLStrdup(papszTokens[5]);
     453                 :             }
     454                 :             else
     455                 :             {
     456               0 :                 sprintf( szName, "GCP_%d", i+1 );
     457               0 :                 pasGCPList[nGCPCount].pszId = CPLStrdup( szName );
     458                 :             }
     459                 : 
     460               0 :             if( CSLCount(papszTokens) > 6 )
     461                 :             {
     462               0 :                 CPLFree( pasGCPList[nGCPCount].pszInfo );
     463               0 :                 pasGCPList[nGCPCount].pszInfo = CPLStrdup(papszTokens[6]);
     464                 :             }
     465                 : 
     466               0 :             nGCPCount++;
     467                 :         }
     468                 : 
     469               0 :         CSLDestroy(papszTokens);
     470                 :     }
     471              23 : }
     472                 : 
     473                 : /************************************************************************/
     474                 : /*                            GetGCPCount()                             */
     475                 : /************************************************************************/
     476                 : 
     477               0 : int PAuxDataset::GetGCPCount()
     478                 : 
     479                 : {
     480               0 :     return nGCPCount;
     481                 : }
     482                 : 
     483                 : /************************************************************************/
     484                 : /*                          GetGCPProjection()                          */
     485                 : /************************************************************************/
     486                 : 
     487               0 : const char *PAuxDataset::GetGCPProjection()
     488                 : 
     489                 : {
     490               0 :     if( nGCPCount > 0 && pszGCPProjection != NULL )
     491               0 :         return pszGCPProjection;
     492                 :     else
     493               0 :         return "";
     494                 : }
     495                 : 
     496                 : /************************************************************************/
     497                 : /*                               GetGCP()                               */
     498                 : /************************************************************************/
     499                 : 
     500               0 : const GDAL_GCP *PAuxDataset::GetGCPs()
     501                 : 
     502                 : {
     503               0 :     return pasGCPList;
     504                 : }
     505                 : 
     506                 : /************************************************************************/
     507                 : /*                          GetProjectionRef()                          */
     508                 : /************************************************************************/
     509                 : 
     510               0 : const char *PAuxDataset::GetProjectionRef()
     511                 : 
     512                 : {
     513               0 :     if( pszProjection )
     514               0 :         return pszProjection;
     515                 :     else
     516               0 :         return GDALPamDataset::GetProjectionRef();
     517                 : }
     518                 : 
     519                 : /************************************************************************/
     520                 : /*                          GetGeoTransform()                           */
     521                 : /************************************************************************/
     522                 : 
     523               1 : CPLErr PAuxDataset::GetGeoTransform( double * padfGeoTransform )
     524                 : 
     525                 : {
     526               1 :     if( CSLFetchNameValue(papszAuxLines, "UpLeftX") != NULL 
     527                 :         && CSLFetchNameValue(papszAuxLines, "UpLeftY") != NULL 
     528                 :         && CSLFetchNameValue(papszAuxLines, "LoRightX") != NULL 
     529                 :         && CSLFetchNameValue(papszAuxLines, "LoRightY") != NULL )
     530                 :     {
     531                 :         double  dfUpLeftX, dfUpLeftY, dfLoRightX, dfLoRightY;
     532                 : 
     533               1 :         dfUpLeftX = atof(CSLFetchNameValue(papszAuxLines, "UpLeftX" ));
     534               1 :         dfUpLeftY = atof(CSLFetchNameValue(papszAuxLines, "UpLeftY" ));
     535               1 :         dfLoRightX = atof(CSLFetchNameValue(papszAuxLines, "LoRightX" ));
     536               1 :         dfLoRightY = atof(CSLFetchNameValue(papszAuxLines, "LoRightY" ));
     537                 : 
     538               1 :         padfGeoTransform[0] = dfUpLeftX;
     539               1 :         padfGeoTransform[1] = (dfLoRightX - dfUpLeftX) / GetRasterXSize();
     540               1 :         padfGeoTransform[2] = 0.0;
     541               1 :         padfGeoTransform[3] = dfUpLeftY;
     542               1 :         padfGeoTransform[4] = 0.0;
     543               1 :         padfGeoTransform[5] = (dfLoRightY - dfUpLeftY) / GetRasterYSize();
     544                 : 
     545               1 :         return CE_None;
     546                 :     }
     547                 :     else
     548                 :     {
     549               0 :         padfGeoTransform[0] = 0.0;
     550               0 :         padfGeoTransform[1] = 1.0;
     551               0 :         padfGeoTransform[2] = 0.0;
     552               0 :         padfGeoTransform[3] = 0.0;
     553               0 :         padfGeoTransform[4] = 0.0;
     554               0 :         padfGeoTransform[5] = 1.0;
     555                 : 
     556               0 :         return CE_Failure;
     557                 :     }
     558                 : }
     559                 : 
     560                 : /************************************************************************/
     561                 : /*                          SetGeoTransform()                           */
     562                 : /************************************************************************/
     563                 : 
     564              10 : CPLErr PAuxDataset::SetGeoTransform( double * padfGeoTransform )
     565                 : 
     566                 : {
     567                 :     char  szUpLeftX[128];
     568                 :     char  szUpLeftY[128];
     569                 :     char  szLoRightX[128];
     570                 :     char  szLoRightY[128];
     571                 : 
     572              34 :     if( ABS(padfGeoTransform[0]) < 181 
     573              16 :         && ABS(padfGeoTransform[1]) < 1 )
     574                 :     {
     575               8 :         sprintf( szUpLeftX, "%.12f", padfGeoTransform[0] );
     576               8 :         sprintf( szUpLeftY, "%.12f", padfGeoTransform[3] );
     577                 :         sprintf( szLoRightX, "%.12f", 
     578               8 :                padfGeoTransform[0] + padfGeoTransform[1] * GetRasterXSize() );
     579                 :         sprintf( szLoRightY, "%.12f", 
     580               8 :                padfGeoTransform[3] + padfGeoTransform[5] * GetRasterYSize() );
     581                 :     }
     582                 :     else
     583                 :     {
     584               2 :         sprintf( szUpLeftX, "%.3f", padfGeoTransform[0] );
     585               2 :         sprintf( szUpLeftY, "%.3f", padfGeoTransform[3] );
     586                 :         sprintf( szLoRightX, "%.3f", 
     587               2 :                padfGeoTransform[0] + padfGeoTransform[1] * GetRasterXSize() );
     588                 :         sprintf( szLoRightY, "%.3f", 
     589               2 :                padfGeoTransform[3] + padfGeoTransform[5] * GetRasterYSize() );
     590                 :     }
     591                 :         
     592                 :     papszAuxLines = CSLSetNameValue( papszAuxLines, 
     593              10 :                                      "UpLeftX", szUpLeftX );
     594                 :     papszAuxLines = CSLSetNameValue( papszAuxLines, 
     595              10 :                                      "UpLeftY", szUpLeftY );
     596                 :     papszAuxLines = CSLSetNameValue( papszAuxLines, 
     597              10 :                                      "LoRightX", szLoRightX );
     598                 :     papszAuxLines = CSLSetNameValue( papszAuxLines, 
     599              10 :                                      "LoRightY", szLoRightY );
     600                 : 
     601              10 :     bAuxUpdated = TRUE;
     602                 : 
     603              10 :     return CE_None;
     604                 : }
     605                 : 
     606                 : /************************************************************************/
     607                 : /*                                Open()                                */
     608                 : /************************************************************************/
     609                 : 
     610            8626 : GDALDataset *PAuxDataset::Open( GDALOpenInfo * poOpenInfo )
     611                 : 
     612                 : {
     613                 :     int   i;
     614            8626 :     CPLString   osAuxFilename;
     615                 :     char  **papszTokens;
     616            8626 :     CPLString   osTarget;
     617                 :     
     618            8626 :     if( poOpenInfo->nHeaderBytes < 1 )
     619            8292 :         return NULL;
     620                 : 
     621                 : /* -------------------------------------------------------------------- */
     622                 : /*      If this is an .aux file, fetch out and form the name of the     */
     623                 : /*      file it references.                                             */
     624                 : /* -------------------------------------------------------------------- */
     625                 : 
     626             334 :     osTarget = poOpenInfo->pszFilename;
     627                 : 
     628             334 :     if( EQUAL(CPLGetExtension( poOpenInfo->pszFilename ),"aux")
     629                 :         && EQUALN((const char *) poOpenInfo->pabyHeader,"AuxilaryTarget: ",16))
     630                 :     {
     631                 :         char  szAuxTarget[1024];
     632                 :         char    *pszPath;
     633               2 :         const char *pszSrc = (const char *) poOpenInfo->pabyHeader+16;
     634                 : 
     635              92 :         for( i = 0; 
     636              68 :              pszSrc[i] != 10 && pszSrc[i] != 13 && pszSrc[i] != '\0'
     637                 :                  && i < (int) sizeof(szAuxTarget)-1;
     638                 :              i++ )
     639                 :         {
     640              22 :             szAuxTarget[i] = pszSrc[i];
     641                 :         }
     642               2 :         szAuxTarget[i] = '\0';
     643                 : 
     644               2 :         pszPath = CPLStrdup(CPLGetPath(poOpenInfo->pszFilename));
     645               2 :         osTarget = CPLFormFilename(pszPath, szAuxTarget, NULL);
     646               2 :         CPLFree(pszPath);
     647                 :     }
     648                 : 
     649                 : /* -------------------------------------------------------------------- */
     650                 : /*      Now we need to tear apart the filename to form a .aux           */
     651                 : /*      filename.                                                       */
     652                 : /* -------------------------------------------------------------------- */
     653             334 :     osAuxFilename = CPLResetExtension(osTarget,"aux");
     654                 : 
     655                 : /* -------------------------------------------------------------------- */
     656                 : /*      Do we have a .aux file?                                         */
     657                 : /* -------------------------------------------------------------------- */
     658             334 :     if( poOpenInfo->papszSiblingFiles != NULL
     659                 :         && CSLFindString( poOpenInfo->papszSiblingFiles, 
     660                 :                           CPLGetFilename(osAuxFilename) ) == -1 )
     661                 :     {
     662             283 :         return NULL;
     663                 :     }
     664                 :     
     665                 :     FILE  *fp;
     666                 : 
     667              51 :     fp = VSIFOpenL( osAuxFilename, "r" );
     668              51 :     if( fp == NULL )
     669                 :     {
     670              27 :         osAuxFilename = CPLResetExtension(osTarget,"AUX");
     671              27 :         fp = VSIFOpenL( osAuxFilename, "r" );
     672                 :     }
     673                 : 
     674              51 :     if( fp == NULL )
     675              27 :         return NULL;
     676                 : 
     677                 : /* -------------------------------------------------------------------- */
     678                 : /*      Is this file a PCI .aux file?  Check the first line for the */
     679                 : /*  telltale AuxilaryTarget keyword.        */
     680                 : /*                  */
     681                 : /*  At this point we should be verifying that it refers to our  */
     682                 : /*  binary file, but that is a pretty involved test.    */
     683                 : /* -------------------------------------------------------------------- */
     684                 :     const char *  pszLine;
     685                 : 
     686              24 :     pszLine = CPLReadLineL( fp );
     687                 : 
     688              24 :     VSIFCloseL( fp );
     689                 : 
     690              24 :     if( pszLine == NULL 
     691                 :         || (!EQUALN(pszLine,"AuxilaryTarget",14) 
     692                 :             && !EQUALN(pszLine,"AuxiliaryTarget",15)) ) 
     693                 :     {
     694               0 :         return NULL;
     695                 :     }
     696                 :     
     697                 : /* -------------------------------------------------------------------- */
     698                 : /*      Create a corresponding GDALDataset.                             */
     699                 : /* -------------------------------------------------------------------- */
     700                 :     PAuxDataset   *poDS;
     701                 : 
     702              24 :     poDS = new PAuxDataset();
     703                 : 
     704                 : /* -------------------------------------------------------------------- */
     705                 : /*      Load the .aux file into a string list suitable to be            */
     706                 : /*      searched with CSLFetchNameValue().                              */
     707                 : /* -------------------------------------------------------------------- */
     708              48 :     poDS->papszAuxLines = CSLLoad( osAuxFilename );
     709              24 :     poDS->pszAuxFilename = CPLStrdup(osAuxFilename);
     710                 :     
     711                 : /* -------------------------------------------------------------------- */
     712                 : /*      Find the RawDefinition line to establish overall parameters.    */
     713                 : /* -------------------------------------------------------------------- */
     714              24 :     pszLine = CSLFetchNameValue(poDS->papszAuxLines, "RawDefinition");
     715                 : 
     716                 :     // It seems PCI now writes out .aux files without RawDefinition in 
     717                 :     // some cases.  See bug 947.
     718              24 :     if( pszLine == NULL )
     719                 :     {
     720               0 :         delete poDS;
     721               0 :         return NULL;
     722                 :     }
     723                 : 
     724              24 :     papszTokens = CSLTokenizeString(pszLine);
     725                 : 
     726              24 :     if( CSLCount(papszTokens) < 3 )
     727                 :     {
     728                 :         CPLError( CE_Failure, CPLE_AppDefined,
     729                 :                   "RawDefinition missing or corrupt in %s.",
     730               0 :                   poOpenInfo->pszFilename );
     731               0 :         CSLDestroy( papszTokens );
     732               0 :         return NULL;
     733                 :     }
     734                 : 
     735              24 :     poDS->nRasterXSize = atoi(papszTokens[0]);
     736              24 :     poDS->nRasterYSize = atoi(papszTokens[1]);
     737              24 :     poDS->nBands = atoi(papszTokens[2]);
     738              24 :     poDS->eAccess = poOpenInfo->eAccess;
     739                 : 
     740              24 :     CSLDestroy( papszTokens );
     741                 : 
     742              24 :     if (!GDALCheckDatasetDimensions(poDS->nRasterXSize, poDS->nRasterYSize) ||
     743                 :         !GDALCheckBandCount(poDS->nBands, FALSE))
     744                 :     {
     745               1 :         delete poDS;
     746               1 :         return NULL;
     747                 :     }
     748                 : 
     749                 : /* -------------------------------------------------------------------- */
     750                 : /*      Open the file.                                                  */
     751                 : /* -------------------------------------------------------------------- */
     752              23 :     if( poOpenInfo->eAccess == GA_Update )
     753                 :     {
     754              18 :         poDS->fpImage = VSIFOpenL( osTarget, "rb+" );
     755                 : 
     756              18 :         if( poDS->fpImage == NULL )
     757                 :         {
     758                 :             CPLError( CE_Failure, CPLE_OpenFailed,
     759                 :                       "File %s is missing or read-only, check permissions.",
     760               0 :                       osTarget.c_str() );
     761                 :             
     762               0 :             delete poDS;
     763               0 :             return NULL;
     764                 :         }
     765                 :     }
     766                 :     else
     767                 :     {
     768               5 :         poDS->fpImage = VSIFOpenL( osTarget, "rb" );
     769                 : 
     770               5 :         if( poDS->fpImage == NULL )
     771                 :         {
     772                 :             CPLError( CE_Failure, CPLE_OpenFailed,
     773                 :                       "File %s is missing or unreadable.",
     774               0 :                       osTarget.c_str() );
     775                 :             
     776               0 :             delete poDS;
     777               0 :             return NULL;
     778                 :         }
     779                 :     }
     780                 : 
     781                 : /* -------------------------------------------------------------------- */
     782                 : /*      Collect raw definitions of each channel and create              */
     783                 : /*      corresponding bands.                                            */
     784                 : /* -------------------------------------------------------------------- */
     785              23 :     int iBand = 0;
     786              69 :     for( i = 0; i < poDS->nBands; i++ )
     787                 :     {
     788                 :         char  szDefnName[32];
     789                 :         GDALDataType eType;
     790              46 :         int bNative = TRUE;
     791                 : 
     792              46 :         sprintf( szDefnName, "ChanDefinition-%d", i+1 );
     793                 : 
     794              46 :         pszLine = CSLFetchNameValue(poDS->papszAuxLines, szDefnName);
     795              46 :         if (pszLine == NULL)
     796                 :         {
     797               0 :             continue;
     798                 :         }
     799                 : 
     800              46 :         papszTokens = CSLTokenizeString(pszLine);
     801              46 :         if( CSLCount(papszTokens) < 4 )
     802                 :         {
     803                 :             // Skip the band with broken description
     804               0 :             CSLDestroy( papszTokens );
     805               0 :             continue;
     806                 :         }
     807                 : 
     808              46 :         if( EQUAL(papszTokens[0],"16U") )
     809               8 :             eType = GDT_UInt16;
     810              38 :         else if( EQUAL(papszTokens[0],"16S") )
     811               2 :             eType = GDT_Int16;
     812              36 :         else if( EQUAL(papszTokens[0],"32R") )
     813               2 :             eType = GDT_Float32;
     814                 :         else
     815              34 :             eType = GDT_Byte;
     816                 : 
     817              46 :         if( CSLCount(papszTokens) > 4 )
     818                 :         {
     819                 : #ifdef CPL_LSB
     820              46 :             bNative = EQUAL(papszTokens[4],"Swapped");
     821                 : #else
     822                 :             bNative = EQUAL(papszTokens[4],"Unswapped");
     823                 : #endif
     824                 :         }
     825                 : 
     826              46 :         vsi_l_offset nBandOffset = CPLScanUIntBig(papszTokens[1],
     827              92 :                                                strlen(papszTokens[1]));
     828              46 :         int nPixelOffset = atoi(papszTokens[2]);
     829              46 :         int nLineOffset = atoi(papszTokens[3]);
     830                 : 
     831              46 :         if (nPixelOffset <= 0 || nLineOffset <= 0)
     832                 :         {
     833                 :             // Skip the band with broken offsets
     834               0 :             CSLDestroy( papszTokens );
     835               0 :             continue;
     836                 :         }
     837                 : 
     838                 :         poDS->SetBand( iBand+1, 
     839                 :             new PAuxRasterBand( poDS, iBand+1, poDS->fpImage,
     840                 :                                 nBandOffset,
     841                 :                                 nPixelOffset,
     842              46 :                                 nLineOffset, eType, bNative ) );
     843              46 :         iBand ++;
     844                 : 
     845              46 :         CSLDestroy( papszTokens );
     846                 :     }
     847                 : 
     848              23 :     poDS->nBands = iBand;
     849                 : 
     850                 : /* -------------------------------------------------------------------- */
     851                 : /*      Get the projection.                                             */
     852                 : /* -------------------------------------------------------------------- */
     853                 :     const char  *pszMapUnits, *pszProjParms;
     854                 : 
     855              23 :     pszMapUnits = CSLFetchNameValue( poDS->papszAuxLines, "MapUnits" );
     856              23 :     pszProjParms = CSLFetchNameValue( poDS->papszAuxLines, "ProjParms" );
     857                 :     
     858              23 :     if( pszMapUnits != NULL )
     859               0 :         poDS->pszProjection = poDS->PCI2WKT( pszMapUnits, pszProjParms );
     860                 :     
     861                 : /* -------------------------------------------------------------------- */
     862                 : /*      Initialize any PAM information.                                 */
     863                 : /* -------------------------------------------------------------------- */
     864              23 :     poDS->SetDescription( osTarget );
     865              23 :     poDS->TryLoadXML();
     866                 : 
     867                 : /* -------------------------------------------------------------------- */
     868                 : /*      Check for overviews.                                            */
     869                 : /* -------------------------------------------------------------------- */
     870              23 :     poDS->oOvManager.Initialize( poDS, osTarget );
     871                 : 
     872              23 :     poDS->ScanForGCPs();
     873              23 :     poDS->bAuxUpdated = FALSE;
     874                 : 
     875              23 :     return( poDS );
     876                 : }
     877                 : 
     878                 : /************************************************************************/
     879                 : /*                               Create()                               */
     880                 : /************************************************************************/
     881                 : 
     882              33 : GDALDataset *PAuxDataset::Create( const char * pszFilename,
     883                 :                                   int nXSize, int nYSize, int nBands,
     884                 :                                   GDALDataType eType,
     885                 :                                   char ** /* papszParmList */ )
     886                 : 
     887                 : {
     888                 :     char  *pszAuxFilename;
     889                 : 
     890                 : /* -------------------------------------------------------------------- */
     891                 : /*      Verify input options.                                           */
     892                 : /* -------------------------------------------------------------------- */
     893              33 :     if( eType != GDT_Byte && eType != GDT_Float32 && eType != GDT_UInt16
     894                 :         && eType != GDT_Int16 )
     895                 :     {
     896                 :         CPLError( CE_Failure, CPLE_AppDefined,
     897                 :               "Attempt to create PCI .Aux labelled dataset with an illegal\n"
     898                 :               "data type (%s).\n",
     899              14 :               GDALGetDataTypeName(eType) );
     900                 : 
     901              14 :         return NULL;
     902                 :     }
     903                 : 
     904                 : /* -------------------------------------------------------------------- */
     905                 : /*      Try to create the file.                                         */
     906                 : /* -------------------------------------------------------------------- */
     907                 :     FILE  *fp;
     908                 : 
     909              19 :     fp = VSIFOpenL( pszFilename, "w" );
     910                 : 
     911              19 :     if( fp == NULL )
     912                 :     {
     913                 :         CPLError( CE_Failure, CPLE_OpenFailed,
     914                 :                   "Attempt to create file `%s' failed.\n",
     915               0 :                   pszFilename );
     916               0 :         return NULL;
     917                 :     }
     918                 : 
     919                 : /* -------------------------------------------------------------------- */
     920                 : /*      Just write out a couple of bytes to establish the binary        */
     921                 : /*      file, and then close it.                                        */
     922                 : /* -------------------------------------------------------------------- */
     923              19 :     VSIFWriteL( (void *) "\0\0", 2, 1, fp );
     924              19 :     VSIFCloseL( fp );
     925                 : 
     926                 : /* -------------------------------------------------------------------- */
     927                 : /*      Create the aux filename.                                        */
     928                 : /* -------------------------------------------------------------------- */
     929              19 :     pszAuxFilename = (char *) CPLMalloc(strlen(pszFilename)+5);
     930              19 :     strcpy( pszAuxFilename, pszFilename );;
     931                 : 
     932             479 :     for( int i = strlen(pszAuxFilename)-1; i > 0; i-- )
     933                 :     {
     934             462 :         if( pszAuxFilename[i] == '.' )
     935                 :         {
     936               2 :             pszAuxFilename[i] = '\0';
     937               2 :             break;
     938                 :         }
     939                 :     }
     940                 : 
     941              19 :     strcat( pszAuxFilename, ".aux" );
     942                 : 
     943                 : /* -------------------------------------------------------------------- */
     944                 : /*      Open the file.                                                  */
     945                 : /* -------------------------------------------------------------------- */
     946              19 :     fp = VSIFOpenL( pszAuxFilename, "wt" );
     947              19 :     if( fp == NULL )
     948                 :     {
     949                 :         CPLError( CE_Failure, CPLE_OpenFailed,
     950                 :                   "Attempt to create file `%s' failed.\n",
     951               0 :                   pszAuxFilename );
     952               0 :         return NULL;
     953                 :     }
     954              19 :     CPLFree( pszAuxFilename );
     955                 :     
     956                 : /* -------------------------------------------------------------------- */
     957                 : /*      We need to write out the original filename but without any      */
     958                 : /*      path components in the AuxilaryTarget line.  Do so now.         */
     959                 : /* -------------------------------------------------------------------- */
     960                 :     int   iStart;
     961                 : 
     962              19 :     iStart = strlen(pszFilename)-1;
     963             150 :     while( iStart > 0 && pszFilename[iStart-1] != '/'
     964              56 :            && pszFilename[iStart-1] != '\\' )
     965              56 :         iStart--;
     966                 : 
     967              19 :     VSIFPrintfL( fp, "AuxilaryTarget: %s\n", pszFilename + iStart );
     968                 : 
     969                 : /* -------------------------------------------------------------------- */
     970                 : /*      Write out the raw definition for the dataset as a whole.        */
     971                 : /* -------------------------------------------------------------------- */
     972                 :     VSIFPrintfL( fp, "RawDefinition: %d %d %d\n",
     973              19 :                 nXSize, nYSize, nBands );
     974                 : 
     975                 : /* -------------------------------------------------------------------- */
     976                 : /*      Write out a definition for each band.  We always write band     */
     977                 : /*      sequential files for now as these are pretty efficiently        */
     978                 : /*      handled by GDAL.                                                */
     979                 : /* -------------------------------------------------------------------- */
     980              19 :     vsi_l_offset    nImgOffset = 0;
     981                 :     
     982              57 :     for( int iBand = 0; iBand < nBands; iBand++ )
     983                 :     {
     984                 :         const char  *pszTypeName;
     985                 :         char        szImgOffset[64];
     986                 :         int         nPixelOffset, nLineOffset, nChars;
     987                 : 
     988              38 :         nPixelOffset = GDALGetDataTypeSize(eType)/8;
     989              38 :         nLineOffset = nXSize * nPixelOffset;
     990                 : 
     991              38 :         if( eType == GDT_Float32 )
     992               2 :             pszTypeName = "32R";
     993              36 :         else if( eType == GDT_Int16 )
     994               2 :             pszTypeName = "16S";
     995              34 :         else if( eType == GDT_UInt16 )
     996               2 :             pszTypeName = "16U";
     997                 :         else
     998              32 :             pszTypeName = "8U";
     999                 : 
    1000              38 :         nChars = CPLPrintUIntBig( szImgOffset, nImgOffset, 63 );
    1001              38 :         szImgOffset[nChars] = '\0';
    1002                 : 
    1003                 :         VSIFPrintfL( fp, "ChanDefinition-%d: %s %s %d %d %s\n", iBand+1,
    1004                 :                     pszTypeName, strpbrk(szImgOffset, "-.0123456789"),
    1005                 :                     nPixelOffset, nLineOffset,
    1006                 : #ifdef CPL_LSB
    1007                 :                     "Swapped"
    1008                 : #else
    1009                 :                     "Unswapped"
    1010                 : #endif
    1011              38 :                     );
    1012                 : 
    1013              38 :         nImgOffset += (vsi_l_offset)nYSize * nLineOffset;
    1014                 :     }
    1015                 : 
    1016                 : /* -------------------------------------------------------------------- */
    1017                 : /*      Cleanup                                                         */
    1018                 : /* -------------------------------------------------------------------- */
    1019              19 :     VSIFCloseL( fp );
    1020                 : 
    1021              19 :     return (GDALDataset *) GDALOpen( pszFilename, GA_Update );
    1022                 : }
    1023                 : 
    1024                 : /************************************************************************/
    1025                 : /*                             PAuxDelete()                             */
    1026                 : /************************************************************************/
    1027                 : 
    1028               2 : CPLErr PAuxDelete( const char * pszBasename )
    1029                 : 
    1030                 : {
    1031                 :     FILE  *fp;
    1032                 :     const char *pszLine;
    1033                 : 
    1034               2 :     fp = VSIFOpenL( CPLResetExtension( pszBasename, "aux" ), "r" );
    1035               2 :     if( fp == NULL )
    1036                 :     {
    1037                 :         CPLError( CE_Failure, CPLE_AppDefined, 
    1038                 :                   "%s does not appear to be a PAux dataset, there is no .aux file.",
    1039               0 :                   pszBasename );
    1040               0 :         return CE_Failure;
    1041                 :     }
    1042                 : 
    1043               2 :     pszLine = CPLReadLineL( fp );
    1044               2 :     VSIFCloseL( fp );
    1045                 :     
    1046               2 :     if( pszLine == NULL || !EQUALN(pszLine,"AuxilaryTarget",14) )
    1047                 :     {
    1048                 :         CPLError( CE_Failure, CPLE_AppDefined, 
    1049                 :                   "%s does not appear to be a PAux dataset,\n"
    1050                 :                   "the .aux file does not start with AuxilaryTarget",
    1051               0 :                   pszBasename );
    1052               0 :         return CE_Failure;
    1053                 :     }
    1054                 : 
    1055               2 :     if( VSIUnlink( pszBasename ) != 0 )
    1056                 :     {
    1057                 :         CPLError( CE_Failure, CPLE_AppDefined, 
    1058               0 :                   "OS unlinking file %s.", pszBasename );
    1059               0 :         return CE_Failure;
    1060                 :     }
    1061                 : 
    1062               2 :     VSIUnlink( CPLResetExtension( pszBasename, "aux" ) );
    1063                 : 
    1064               2 :     return CE_None;
    1065                 : }
    1066                 : 
    1067                 : /************************************************************************/
    1068                 : /*                         GDALRegister_PAux()                          */
    1069                 : /************************************************************************/
    1070                 : 
    1071             338 : void GDALRegister_PAux()
    1072                 : 
    1073                 : {
    1074                 :     GDALDriver  *poDriver;
    1075                 : 
    1076             338 :     if( GDALGetDriverByName( "PAux" ) == NULL )
    1077                 :     {
    1078             336 :         poDriver = new GDALDriver();
    1079                 :         
    1080             336 :         poDriver->SetDescription( "PAux" );
    1081                 :         poDriver->SetMetadataItem( GDAL_DMD_LONGNAME, 
    1082             336 :                                    "PCI .aux Labelled" );
    1083                 :         poDriver->SetMetadataItem( GDAL_DMD_HELPTOPIC, 
    1084             336 :                                    "frmt_various.html#PAux" );
    1085                 :         poDriver->SetMetadataItem( GDAL_DMD_CREATIONDATATYPES, 
    1086             336 :                                    "Byte Int16 UInt16 Float32" );
    1087                 : 
    1088             336 :         poDriver->pfnOpen = PAuxDataset::Open;
    1089             336 :         poDriver->pfnCreate = PAuxDataset::Create;
    1090             336 :         poDriver->pfnDelete = PAuxDelete;
    1091                 : 
    1092             336 :         GetGDALDriverManager()->RegisterDriver( poDriver );
    1093                 :     }
    1094             338 : }
    1095                 : 

Generated by: LCOV version 1.7