LCOV - code coverage report
Current view: directory - frmts/nitf - rpftocfile.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 280 201 71.8 %
Date: 2010-01-09 Functions: 4 3 75.0 %

       1                 : /******************************************************************************
       2                 :  * $Id: rpftocfile.cpp 17617 2009-09-07 19:14:46Z rouault $
       3                 :  *
       4                 :  * Project:  RPF A.TOC read Library
       5                 :  * Purpose:  Module responsible for opening a RPF TOC file, populating RPFToc
       6                 :  *           structure
       7                 :  * Author:   Even Rouault, even.rouault at mines-paris.org
       8                 :  *
       9                 :  **********************************************************************
      10                 :  * Copyright (c) 2007, Even Rouault
      11                 :  *
      12                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      13                 :  * copy of this software and associated documentation files (the "Software"),
      14                 :  * to deal in the Software without restriction, including without limitation
      15                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      16                 :  * and/or sell copies of the Software, and to permit persons to whom the
      17                 :  * Software is furnished to do so, subject to the following conditions:
      18                 :  *
      19                 :  * The above copyright notice and this permission notice shall be included
      20                 :  * in all copies or substantial portions of the Software.
      21                 :  *
      22                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      23                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      24                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      25                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      26                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      27                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      28                 :  * DEALINGS IN THE SOFTWARE.
      29                 :  ****************************************************************************/
      30                 : 
      31                 : /* Portions of code are placed under the following copyright : */
      32                 : /*
      33                 :  ******************************************************************************
      34                 :  * Copyright (C) 1995 Logiciels et Applications Scientifiques (L.A.S.) Inc
      35                 :  * Permission to use, copy, modify and distribute this software and
      36                 :  * its documentation for any purpose and without fee is hereby granted,
      37                 :  * provided that the above copyright notice appear in all copies, that
      38                 :  * both the copyright notice and this permission notice appear in
      39                 :  * supporting documentation, and that the name of L.A.S. Inc not be used 
      40                 :  * in advertising or publicity pertaining to distribution of the software 
      41                 :  * without specific, written prior permission. L.A.S. Inc. makes no
      42                 :  * representations about the suitability of this software for any purpose.
      43                 :  * It is provided "as is" without express or implied warranty.
      44                 :  ******************************************************************************
      45                 :  */
      46                 : 
      47                 : #include "rpftoclib.h"
      48                 : #include "cpl_vsi.h"
      49                 : #include "cpl_conv.h"
      50                 : #include "cpl_string.h"
      51                 : 
      52                 : CPL_CVSID("$Id: rpftocfile.cpp 17617 2009-09-07 19:14:46Z rouault $");
      53                 : 
      54                 : /************************************************************************/
      55                 : /*                        RPFTOCTrim()                                    */
      56                 : /************************************************************************/
      57                 : 
      58              40 : static void RPFTOCTrim(char* str)
      59                 : {
      60              40 :     char* c = str;
      61                 :     int i;
      62              40 :     if (str == NULL || *str == 0)
      63               0 :         return;
      64                 : 
      65              80 :     while(*c == ' ')
      66                 :     {
      67               0 :         c++;
      68                 :     }
      69              40 :     if (c != str)
      70                 :     {
      71               0 :         memmove(str, c, strlen(c)+1);
      72                 :     }
      73                 :     
      74              40 :     i = strlen(str) - 1;
      75              96 :     while (i >= 0 && str[i] == ' ')
      76                 :     {
      77              16 :         str[i] = 0;
      78              16 :         i--;
      79                 :     }
      80                 : }
      81                 : 
      82                 : /************************************************************************/
      83                 : /*                        RPFTOCRead()                                 */
      84                 : /************************************************************************/
      85                 : 
      86                 :  
      87               0 : RPFToc* RPFTOCRead(const char* pszFilename, NITFFile* psFile)
      88                 : {
      89                 :     int TRESize;
      90                 :     const char* pachTRE = NITFFindTRE( psFile->pachTRE, psFile->nTREBytes, 
      91               0 :                            "RPFHDR", &TRESize );
      92               0 :     if (pachTRE == NULL)
      93                 :     {
      94                 :         CPLError( CE_Failure, CPLE_NotSupported, 
      95               0 :                   "Invalid TOC file. Can't find RPFHDR." );
      96               0 :         return NULL;
      97                 :     }
      98                 : 
      99               0 :     if (TRESize < 48)
     100                 :     {
     101                 :         CPLError( CE_Failure, CPLE_NotSupported, 
     102               0 :                   "Not enough bytes in RPFHDR." );
     103               0 :         return NULL;
     104                 :     }
     105                 : 
     106               0 :     int nRemainingBytes = psFile->nTREBytes - (pachTRE - psFile->pachTRE);
     107               0 :     if (nRemainingBytes < 48)
     108                 :     {
     109                 :         CPLError(CE_Failure, CPLE_AppDefined,
     110               0 :                 "Cannot read RPFHDR TRE. Not enough bytes");
     111               0 :         return NULL;
     112                 :     }
     113                 : 
     114               0 :     return  RPFTOCReadFromBuffer(pszFilename, psFile->fp, pachTRE);
     115                 : }
     116                 : 
     117                 : 
     118                 : /* This function is directly inspired by function parse_toc coming from ogdi/driver/rpf/utils.c */
     119                 : 
     120               8 : RPFToc* RPFTOCReadFromBuffer(const char* pszFilename, FILE* fp, const char* tocHeader)
     121                 : {
     122                 :     int i, j;
     123                 :     unsigned int locationSectionPhysicalLocation;
     124                 :     
     125                 :     unsigned short nSections;
     126               8 :     unsigned int boundaryRectangleSectionSubHeaderPhysIndex = 0, boundaryRectangleSectionSubHeaderLength = 0;
     127               8 :     unsigned int boundaryRectangleTablePhysIndex = 0, boundaryRectangleTableLength = 0;
     128               8 :     unsigned int frameFileIndexSectionSubHeaderPhysIndex = 0, frameFileIndexSectionSubHeaderLength = 0;
     129               8 :     unsigned int frameFileIndexSubsectionPhysIndex = 0, frameFileIndexSubsectionLength = 0;
     130                 :     
     131                 :     unsigned int boundaryRectangleTableOffset;
     132                 :     unsigned short boundaryRectangleCount;
     133                 :     
     134                 :     unsigned int frameIndexTableOffset;
     135                 :     unsigned int nFrameFileIndexRecords;
     136                 :     unsigned short nFrameFilePathnameRecords;
     137                 :     unsigned short frameFileIndexRecordLength;
     138                 : 
     139               8 :     int newBoundaryId = 0;
     140                 : 
     141                 :     RPFToc* toc;
     142                 :     
     143               8 :     tocHeader += 1; /* skip endian */
     144               8 :     tocHeader += 2; /* skip header length */
     145               8 :     tocHeader += 12; /* skip file name : this should be A.TOC (padded) */
     146               8 :     tocHeader += 1; /* skip new  */
     147               8 :     tocHeader += 15; /* skip standard_num  */
     148               8 :     tocHeader += 8; /* skip standard_date  */
     149               8 :     tocHeader += 1; /* skip classification  */
     150               8 :     tocHeader += 2; /* skip country  */
     151               8 :     tocHeader += 2; /* skip release  */
     152                 :     
     153               8 :     memcpy(&locationSectionPhysicalLocation, tocHeader, sizeof(unsigned int));
     154               8 :     CPL_MSBPTR32(&locationSectionPhysicalLocation);
     155                 :     
     156               8 :     if( VSIFSeekL( fp, locationSectionPhysicalLocation, SEEK_SET ) != 0)
     157                 :     {
     158                 :         CPLError( CE_Failure, CPLE_NotSupported, 
     159                 :                   "Invalid TOC file. Unable to seek to locationSectionPhysicalLocation at offset %d.",
     160               0 :                    locationSectionPhysicalLocation );
     161               0 :         return NULL;
     162                 :     }
     163                 :     
     164                 :     /* Skip location section length (4) and component location table offset (2)*/
     165               8 :     VSIFSeekL( fp, 4 + 2, SEEK_CUR);
     166                 :     
     167                 :     /* How many sections: # of section location records */
     168               8 :     VSIFReadL( &nSections, 1, sizeof(nSections), fp);
     169               8 :     CPL_MSBPTR16( &nSections );
     170                 :     
     171                 :     /* Skip location record length(2) + component aggregate length(4) */
     172               8 :     VSIFSeekL( fp, 2 + 4, SEEK_CUR);
     173                 :     
     174              40 :     for (i = 0; i < nSections; i++)
     175                 :     {
     176                 :         unsigned short id;
     177                 :         unsigned int sectionLength, physIndex;
     178              32 :         VSIFReadL( &id, 1, sizeof(id), fp);
     179              32 :         CPL_MSBPTR16( &id );
     180                 :         
     181              32 :         VSIFReadL( &sectionLength, 1, sizeof(sectionLength), fp);
     182              32 :         CPL_MSBPTR32( &sectionLength );
     183                 :         
     184              32 :         VSIFReadL( &physIndex, 1, sizeof(physIndex), fp);
     185              32 :         CPL_MSBPTR32( &physIndex );
     186                 :         
     187              32 :         if (id == LID_BoundaryRectangleSectionSubheader)
     188                 :         {
     189               8 :             boundaryRectangleSectionSubHeaderPhysIndex = physIndex;
     190               8 :             boundaryRectangleSectionSubHeaderLength = sectionLength;
     191                 :         }
     192              24 :         else if (id == LID_BoundaryRectangleTable)
     193                 :         {
     194               8 :             boundaryRectangleTablePhysIndex = physIndex;
     195               8 :             boundaryRectangleTableLength = sectionLength;
     196                 :         }
     197              16 :         else if (id == LID_FrameFileIndexSectionSubHeader)
     198                 :         {
     199               8 :             frameFileIndexSectionSubHeaderPhysIndex = physIndex;
     200               8 :             frameFileIndexSectionSubHeaderLength = sectionLength;
     201                 :         }
     202               8 :         else if (id == LID_FrameFileIndexSubsection)
     203                 :         {
     204               8 :             frameFileIndexSubsectionPhysIndex = physIndex;
     205               8 :             frameFileIndexSubsectionLength = sectionLength;
     206                 :         }
     207                 :     }
     208                 :     
     209               8 :     if (boundaryRectangleSectionSubHeaderPhysIndex == 0)
     210                 :     {
     211                 :         CPLError( CE_Failure, CPLE_NotSupported, 
     212               0 :                   "Invalid TOC file. Can't find LID_BoundaryRectangleSectionSubheader." );
     213               0 :         return NULL;
     214                 :     }
     215               8 :     if (boundaryRectangleTablePhysIndex == 0)
     216                 :     {
     217                 :         CPLError( CE_Failure, CPLE_NotSupported, 
     218               0 :                   "Invalid TOC file. Can't find LID_BoundaryRectangleTable." );
     219               0 :         return NULL;
     220                 :     }
     221               8 :     if (frameFileIndexSectionSubHeaderPhysIndex == 0)
     222                 :     {
     223                 :         CPLError( CE_Failure, CPLE_NotSupported, 
     224               0 :                   "Invalid TOC file. Can't find LID_FrameFileIndexSectionSubHeader." );
     225               0 :         return NULL;
     226                 :     }
     227               8 :     if (frameFileIndexSubsectionPhysIndex == 0)
     228                 :     {
     229                 :         CPLError( CE_Failure, CPLE_NotSupported, 
     230               0 :                   "Invalid TOC file. Can't find LID_FrameFileIndexSubsection." );
     231               0 :         return NULL;
     232                 :     }
     233                 :     
     234               8 :     if( VSIFSeekL( fp, boundaryRectangleSectionSubHeaderPhysIndex, SEEK_SET ) != 0)
     235                 :     {
     236                 :         CPLError( CE_Failure, CPLE_NotSupported, 
     237                 :                   "Invalid TOC file. Unable to seek to boundaryRectangleSectionSubHeaderPhysIndex at offset %d.",
     238               0 :                    boundaryRectangleSectionSubHeaderPhysIndex );
     239               0 :         return NULL;
     240                 :     }
     241                 :     
     242               8 :     VSIFReadL( &boundaryRectangleTableOffset, 1, sizeof(boundaryRectangleTableOffset), fp);
     243               8 :     CPL_MSBPTR32( &boundaryRectangleTableOffset );
     244                 :     
     245               8 :     VSIFReadL( &boundaryRectangleCount, 1, sizeof(boundaryRectangleCount), fp);
     246               8 :     CPL_MSBPTR16( &boundaryRectangleCount );
     247                 :     
     248               8 :     if( VSIFSeekL( fp, boundaryRectangleTablePhysIndex, SEEK_SET ) != 0)
     249                 :     {
     250                 :         CPLError( CE_Failure, CPLE_NotSupported, 
     251                 :                   "Invalid TOC file. Unable to seek to boundaryRectangleTablePhysIndex at offset %d.",
     252               0 :                    boundaryRectangleTablePhysIndex );
     253               0 :         return NULL;
     254                 :     }
     255                 :     
     256               8 :     toc = (RPFToc*)CPLMalloc(sizeof(RPFToc));
     257               8 :     toc->nEntries = boundaryRectangleCount;
     258               8 :     toc->entries = (RPFTocEntry*)CPLMalloc(boundaryRectangleCount * sizeof(RPFTocEntry));
     259               8 :     memset(toc->entries, 0, boundaryRectangleCount * sizeof(RPFTocEntry));
     260                 :     
     261              16 :     for(i=0;i<toc->nEntries;i++)
     262                 :     {
     263               8 :         toc->entries[i].isOverviewOrLegend = 0;
     264                 :         
     265               8 :         VSIFReadL( toc->entries[i].type, 1, 5, fp);
     266               8 :         toc->entries[i].type[5] = 0;
     267               8 :         RPFTOCTrim(toc->entries[i].type);
     268                 :         
     269               8 :         VSIFReadL( toc->entries[i].compression, 1, 5, fp);
     270               8 :         toc->entries[i].compression[5] = 0;
     271               8 :         RPFTOCTrim(toc->entries[i].compression);
     272                 :         
     273               8 :         VSIFReadL( toc->entries[i].scale, 1, 12, fp);
     274               8 :         toc->entries[i].scale[12] = 0;
     275               8 :         RPFTOCTrim(toc->entries[i].scale);
     276              16 :         if (toc->entries[i].scale[0] == '1' &&
     277               8 :             toc->entries[i].scale[1] == ':')
     278                 :         {
     279               8 :             memmove(toc->entries[i].scale,
     280               8 :                     toc->entries[i].scale+2,
     281              24 :                     strlen(toc->entries[i].scale+2)+1);
     282                 :         }
     283                 :         
     284               8 :         VSIFReadL( toc->entries[i].zone, 1, 1, fp);
     285               8 :         toc->entries[i].zone[1] = 0;
     286               8 :         RPFTOCTrim(toc->entries[i].zone);
     287                 :         
     288               8 :         VSIFReadL( toc->entries[i].producer, 1, 5, fp);
     289               8 :         toc->entries[i].producer[5] = 0;
     290               8 :         RPFTOCTrim(toc->entries[i].producer);
     291                 : 
     292               8 :         VSIFReadL( &toc->entries[i].nwLat, 1, sizeof(double), fp);
     293               8 :         CPL_MSBPTR64( &toc->entries[i].nwLat);
     294                 : 
     295               8 :         VSIFReadL( &toc->entries[i].nwLong, 1, sizeof(double), fp);
     296               8 :         CPL_MSBPTR64( &toc->entries[i].nwLong);
     297                 : 
     298               8 :         VSIFReadL( &toc->entries[i].swLat, 1, sizeof(double), fp);
     299               8 :         CPL_MSBPTR64( &toc->entries[i].swLat);
     300                 : 
     301               8 :         VSIFReadL( &toc->entries[i].swLong, 1, sizeof(double), fp);
     302               8 :         CPL_MSBPTR64( &toc->entries[i].swLong);
     303                 : 
     304               8 :         VSIFReadL( &toc->entries[i].neLat, 1, sizeof(double), fp);
     305               8 :         CPL_MSBPTR64( &toc->entries[i].neLat);
     306                 : 
     307               8 :         VSIFReadL( &toc->entries[i].neLong, 1, sizeof(double), fp);
     308               8 :         CPL_MSBPTR64( &toc->entries[i].neLong);
     309                 : 
     310               8 :         VSIFReadL( &toc->entries[i].seLat, 1, sizeof(double), fp);
     311               8 :         CPL_MSBPTR64( &toc->entries[i].seLat);
     312                 :         
     313               8 :         VSIFReadL( &toc->entries[i].seLong, 1, sizeof(double), fp);
     314               8 :         CPL_MSBPTR64( &toc->entries[i].seLong);
     315                 :         
     316               8 :         VSIFReadL( &toc->entries[i].vertResolution, 1, sizeof(double), fp);
     317               8 :         CPL_MSBPTR64( &toc->entries[i].vertResolution);
     318                 :         
     319               8 :         VSIFReadL( &toc->entries[i].horizResolution, 1, sizeof(double), fp);
     320               8 :         CPL_MSBPTR64( &toc->entries[i].horizResolution);
     321                 :         
     322               8 :         VSIFReadL( &toc->entries[i].vertInterval, 1, sizeof(double), fp);
     323               8 :         CPL_MSBPTR64( &toc->entries[i].vertInterval);
     324                 : 
     325               8 :         VSIFReadL( &toc->entries[i].horizInterval, 1, sizeof(double), fp);
     326               8 :         CPL_MSBPTR64( &toc->entries[i].horizInterval);
     327                 :         
     328               8 :         VSIFReadL( &toc->entries[i].nVertFrames, 1, sizeof(int), fp);
     329               8 :         CPL_MSBPTR32( &toc->entries[i].nVertFrames );
     330                 :         
     331               8 :         VSIFReadL( &toc->entries[i].nHorizFrames, 1, sizeof(int), fp);
     332               8 :         CPL_MSBPTR32( &toc->entries[i].nHorizFrames );
     333                 :         
     334               8 :         toc->entries[i].frameEntries = (RPFTocFrameEntry*)
     335               8 :                 VSIMalloc3(toc->entries[i].nVertFrames, toc->entries[i].nHorizFrames, sizeof(RPFTocFrameEntry));
     336               8 :         if (toc->entries[i].frameEntries == NULL)
     337                 :         {
     338                 :             CPLError( CE_Failure, CPLE_OutOfMemory,
     339               0 :                       "RPFTOCReadFromBuffer : Out of memory. Probably due to corrupted TOC file.");
     340               0 :             RPFTOCFree(toc);
     341               0 :             return NULL;
     342                 :         }
     343               8 :         memset(toc->entries[i].frameEntries, 0,
     344              16 :                toc->entries[i].nVertFrames * toc->entries[i].nHorizFrames * sizeof(RPFTocFrameEntry));
     345                 :         
     346                 :         CPLDebug("RPFTOC", "[%d] type=%s, compression=%s, scale=%s, zone=%s, producer=%s, nVertFrames=%d, nHorizFrames=%d",
     347              24 :                  i, toc->entries[i].type, toc->entries[i].compression, toc->entries[i].scale,
     348              32 :                  toc->entries[i].zone, toc->entries[i].producer, toc->entries[i].nVertFrames, toc->entries[i].nHorizFrames);
     349                 :     }
     350                 :     
     351               8 :     if( VSIFSeekL( fp, frameFileIndexSectionSubHeaderPhysIndex, SEEK_SET ) != 0)
     352                 :     {
     353                 :         CPLError( CE_Failure, CPLE_NotSupported, 
     354                 :                   "Invalid TOC file. Unable to seek to frameFileIndexSectionSubHeaderPhysIndex at offset %d.",
     355               0 :                    frameFileIndexSectionSubHeaderPhysIndex );
     356               0 :         RPFTOCFree(toc);
     357               0 :         return NULL;
     358                 :     }
     359                 :     
     360                 :     /* Skip 1 byte security classification */
     361               8 :     VSIFSeekL( fp, 1, SEEK_CUR );
     362                 :     
     363               8 :     VSIFReadL( &frameIndexTableOffset, 1, sizeof(frameIndexTableOffset), fp);
     364               8 :     CPL_MSBPTR32( &frameIndexTableOffset );
     365                 :     
     366               8 :     VSIFReadL( &nFrameFileIndexRecords, 1, sizeof(nFrameFileIndexRecords), fp);
     367               8 :     CPL_MSBPTR32( &nFrameFileIndexRecords );
     368                 :     
     369               8 :     VSIFReadL( &nFrameFilePathnameRecords, 1, sizeof(nFrameFilePathnameRecords), fp);
     370               8 :     CPL_MSBPTR16( &nFrameFilePathnameRecords );
     371                 :     
     372               8 :     VSIFReadL( &frameFileIndexRecordLength, 1, sizeof(frameFileIndexRecordLength), fp);
     373               8 :     CPL_MSBPTR16( &frameFileIndexRecordLength );
     374                 :     
     375              16 :     for (i=0;i<(int)nFrameFileIndexRecords;i++)
     376                 :     {
     377                 :         RPFTocEntry* entry;
     378                 :         RPFTocFrameEntry* frameEntry;
     379                 :         unsigned short boundaryId, frameRow, frameCol;
     380                 :         unsigned int offsetFrameFilePathName;
     381                 :         unsigned short pathLength;
     382                 :         
     383               8 :         if( VSIFSeekL( fp, frameFileIndexSubsectionPhysIndex + frameFileIndexRecordLength * i, SEEK_SET ) != 0)
     384                 :         {
     385                 :             CPLError( CE_Failure, CPLE_NotSupported, 
     386                 :                     "Invalid TOC file. Unable to seek to frameFileIndexSubsectionPhysIndex(%d) at offset %d.",
     387               0 :                      i, frameFileIndexSubsectionPhysIndex + frameFileIndexRecordLength * i);
     388               0 :             RPFTOCFree(toc);
     389               0 :             return NULL;
     390                 :         }
     391                 : 
     392               8 :         VSIFReadL( &boundaryId, 1, sizeof(boundaryId), fp);
     393               8 :         CPL_MSBPTR16( &boundaryId );
     394                 :         
     395               8 :         if (i == 0 && boundaryId == 0)
     396               8 :             newBoundaryId = 1;
     397               8 :         if (newBoundaryId == 0)
     398               0 :             boundaryId--;
     399                 :         
     400               8 :         if (boundaryId >= toc->nEntries)
     401                 :         {
     402                 :             CPLError( CE_Failure, CPLE_NotSupported, 
     403                 :                     "Invalid TOC file. Bad boundary id (%d) for frame file index %d.",
     404               0 :                      boundaryId, i);
     405               0 :             RPFTOCFree(toc);
     406               0 :             return NULL;
     407                 :         }
     408                 :         
     409               8 :         entry = &toc->entries[boundaryId];
     410               8 :         entry->boundaryId = boundaryId;
     411                 :         
     412               8 :         VSIFReadL( &frameRow, 1, sizeof(frameRow), fp);
     413               8 :         CPL_MSBPTR16( &frameRow );
     414                 :         
     415               8 :         VSIFReadL( &frameCol, 1, sizeof(frameCol), fp);
     416               8 :         CPL_MSBPTR16( &frameCol );
     417                 : 
     418                 : 
     419               8 :         if (newBoundaryId == 0)
     420                 :         {
     421               0 :             frameRow--;
     422               0 :             frameCol--;
     423                 :         }
     424                 :         else
     425                 :         {
     426                 :             /* Trick so that frames are numbered north to south */
     427               8 :             frameRow = (unsigned short)((entry->nVertFrames-1) - frameRow);
     428                 :         }
     429                 :    
     430               8 :         if (frameRow >= entry->nVertFrames)
     431                 :         {
     432                 :             CPLError( CE_Failure, CPLE_NotSupported, 
     433                 :                         "Invalid TOC file. Bad row num (%d) for frame file index %d.",
     434               0 :                         frameRow, i);
     435               0 :             RPFTOCFree(toc);
     436               0 :             return NULL;
     437                 :         }
     438                 :         
     439               8 :         if (frameCol >= entry->nHorizFrames)
     440                 :         {
     441                 :             CPLError( CE_Failure, CPLE_NotSupported, 
     442                 :                         "Invalid TOC file. Bad col num (%d) for frame file index %d.",
     443               0 :                         frameCol, i);
     444               0 :             RPFTOCFree(toc);
     445               0 :             return NULL;
     446                 :         }
     447                 : 
     448               8 :         frameEntry = &entry->frameEntries[frameRow * entry->nHorizFrames + frameCol ];
     449               8 :         frameEntry->frameRow = frameRow;
     450               8 :         frameEntry->frameCol = frameCol;
     451                 : 
     452               8 :         if (frameEntry->exists)
     453                 :         {
     454                 :             CPLError( CE_Failure, CPLE_NotSupported, 
     455                 :                       "Invalid TOC file. Frame entry(%d,%d) for frame file index %d is a duplicate.",
     456               0 :                       frameRow, frameCol, i);
     457               0 :             RPFTOCFree(toc);
     458               0 :             return NULL;
     459                 :         }
     460                 :         
     461               8 :         VSIFReadL( &offsetFrameFilePathName, 1, sizeof(offsetFrameFilePathName), fp);
     462               8 :         CPL_MSBPTR32( &offsetFrameFilePathName );
     463                 :         
     464                 : 
     465               8 :         VSIFReadL( frameEntry->filename, 1, 12, fp);
     466               8 :         frameEntry->filename[12] = '\0';
     467                 : 
     468                 :         /* Check if the filename is an overview or legend */
     469             104 :         for (j=0;j<12;j++)
     470                 :         {
     471             384 :             if (strcmp(&(frameEntry->filename[j]),".OVR") == 0 ||
     472              96 :                 strcmp(&(frameEntry->filename[j]),".ovr") == 0 ||
     473              96 :                 strcmp(&(frameEntry->filename[j]),".LGD") == 0 ||
     474              96 :                 strcmp(&(frameEntry->filename[j]),".lgd") == 0)
     475                 :             {
     476               0 :                 entry->isOverviewOrLegend = TRUE;
     477               0 :                 break;
     478                 :             }
     479                 :         }
     480                 :         
     481                 :         /* Extract series code */
     482               8 :         if (entry->seriesAbbreviation == NULL)
     483                 :         {
     484               8 :             const NITFSeries* series = NITFGetSeriesInfo(frameEntry->filename);
     485               8 :             if (series)
     486                 :             {
     487               8 :                 entry->seriesAbbreviation = series->abbreviation;
     488               8 :                 entry->seriesName = series->name;
     489                 :             }
     490                 :         }
     491                 : 
     492                 :         /* Get file geo reference */
     493               8 :         VSIFReadL( frameEntry->georef, 1, 6, fp);
     494               8 :         frameEntry->georef[6] = '\0';
     495                 : 
     496                 :         /* Go to start of pathname record */
     497                 :         /* New path_off offset from start of frame file index section of TOC?? */
     498                 :         /* Add pathoffset wrt frame file index table subsection (loc[3]) */
     499               8 :         if( VSIFSeekL( fp, frameFileIndexSubsectionPhysIndex + offsetFrameFilePathName, SEEK_SET ) != 0)
     500                 :         {
     501                 :             CPLError( CE_Failure, CPLE_NotSupported, 
     502                 :                     "Invalid TOC file. Unable to seek to frameFileIndexSubsectionPhysIndex + offsetFrameFilePathName(%d) at offset %d.",
     503               0 :                      i, frameFileIndexSubsectionPhysIndex + offsetFrameFilePathName);
     504               0 :             RPFTOCFree(toc);
     505               0 :             return NULL;
     506                 :         }
     507                 : 
     508               8 :         VSIFReadL( &pathLength, 1, sizeof(pathLength), fp);
     509               8 :         CPL_MSBPTR16( &pathLength );
     510                 :         
     511                 :         /* if nFrameFileIndexRecords == 65535 and pathLength == 65535 for each record,
     512                 :            this leads to 4 GB allocation... Protect against this case */
     513               8 :         if (pathLength > 256)
     514                 :         {
     515                 :             CPLError( CE_Failure, CPLE_NotSupported,
     516               0 :                       "Path length is big : %d. Probably corrupted TOC file.", (int)pathLength);
     517               0 :             RPFTOCFree(toc);
     518               0 :             return NULL;
     519                 :         }
     520                 :         
     521               8 :         frameEntry->directory = (char *)CPLMalloc(pathLength+1);
     522               8 :         VSIFReadL( frameEntry->directory, 1, pathLength, fp);
     523               8 :         frameEntry->directory[pathLength] = 0;
     524               8 :         if (pathLength > 0 && frameEntry->directory[pathLength-1] == '/')
     525               8 :             frameEntry->directory[pathLength-1] = 0;
     526                 :         
     527               8 :         if (frameEntry->directory[0] == '.' && frameEntry->directory[1] == '/')
     528               0 :             memmove(frameEntry->directory, frameEntry->directory+2, strlen(frameEntry->directory+2)+1);
     529                 :         
     530                 :         {
     531               8 :             char* baseDir = CPLStrdup(CPLGetDirname(pszFilename));
     532                 :             VSIStatBufL sStatBuf;
     533                 :             char* subdir;
     534               8 :             if (CPLIsFilenameRelative(frameEntry->directory) == FALSE)
     535               0 :                 subdir = CPLStrdup(frameEntry->directory);
     536              16 :             else if (frameEntry->directory[0] == '.' && frameEntry->directory[1] == 0)
     537               8 :                 subdir = CPLStrdup(baseDir);
     538                 :             else
     539               0 :                 subdir = CPLStrdup(CPLFormFilename(baseDir, frameEntry->directory, NULL));
     540                 : #if !defined(_WIN32) && !defined(_WIN32_CE)
     541               8 :             if( VSIStatL( subdir, &sStatBuf ) != 0 && subdir[strlen(baseDir)] != 0)
     542                 :             {
     543               0 :                 char* c = subdir + strlen(baseDir)+1;
     544               0 :                 while(*c)
     545                 :                 {
     546               0 :                     if (*c >= 'A' && *c <= 'Z')
     547               0 :                         *c += 'a' - 'A';
     548               0 :                     c++;
     549                 :                 }
     550                 :             }
     551                 : #endif
     552                 :             frameEntry->fullFilePath = CPLStrdup(CPLFormFilename(
     553                 :                     subdir,
     554               8 :                     frameEntry->filename, NULL));
     555               8 :             if( VSIStatL( frameEntry->fullFilePath, &sStatBuf ) != 0 )
     556                 :             {
     557                 : #if !defined(_WIN32) && !defined(_WIN32_CE)
     558               0 :                 char* c = frameEntry->fullFilePath + strlen(subdir)+1;
     559               0 :                 while(*c)
     560                 :                 {
     561               0 :                     if (*c >= 'A' && *c <= 'Z')
     562               0 :                         *c += 'a' - 'A';
     563               0 :                     c++;
     564                 :                 }
     565               0 :                 if( VSIStatL( frameEntry->fullFilePath, &sStatBuf ) != 0 )
     566                 : #endif
     567                 :                 {
     568               0 :                     frameEntry->fileExists = 0;
     569                 :                     CPLError( CE_Warning, CPLE_AppDefined, 
     570               0 :                         "File %s does not exist.", frameEntry->fullFilePath );
     571                 :                 }
     572                 : #if !defined(_WIN32) && !defined(_WIN32_CE)
     573                 :                 else
     574                 :                 {
     575               0 :                     frameEntry->fileExists = 1;
     576                 :                 }
     577                 : #endif
     578                 :             }
     579                 :             else
     580                 :             {
     581               8 :                 frameEntry->fileExists = 1;
     582                 :             }
     583               8 :             CPLFree(subdir);
     584               8 :             CPLFree(baseDir);
     585                 :         }
     586                 : 
     587               8 :         CPLDebug("RPFTOC", "Entry %d : %s,%s (%d, %d)", boundaryId, frameEntry->directory, frameEntry->filename, frameRow, frameCol);
     588                 : 
     589               8 :         frameEntry->exists = 1;
     590                 :     }
     591                 :     
     592               8 :     return toc;
     593                 : }
     594                 : 
     595                 : /************************************************************************/
     596                 : /*                        RPFTOCFree()                                 */
     597                 : /************************************************************************/
     598                 : 
     599               8 : void RPFTOCFree(RPFToc*  toc)
     600                 : {
     601                 :     int i, j;
     602               8 :     if (!toc) return;
     603                 : 
     604              16 :     for(i=0;i<toc->nEntries;i++)
     605                 :     {
     606              16 :         for(j=0;j<(int)(toc->entries[i].nVertFrames * toc->entries[i].nHorizFrames); j++)
     607                 :         {
     608               8 :             CPLFree(toc->entries[i].frameEntries[j].fullFilePath);
     609               8 :             CPLFree(toc->entries[i].frameEntries[j].directory);
     610                 :         }
     611               8 :         CPLFree(toc->entries[i].frameEntries);
     612                 :     }
     613                 : 
     614               8 :     CPLFree(toc->entries);
     615               8 :     CPLFree(toc);
     616                 : }

Generated by: LCOV version 1.7