LCOV - code coverage report
Current view: top level - frmts/nitf - nitfdrivercore.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 95 100 95.0 %
Date: 2024-11-21 22:18:42 Functions: 7 7 100.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  NITF Read/Write Translator
       4             :  * Purpose:  NITFDataset and driver related implementations.
       5             :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       6             :  *
       7             :  ******************************************************************************
       8             :  * Copyright (c) 2002, Frank Warmerdam
       9             :  * Copyright (c) 2007-2013, Even Rouault <even dot rouault at spatialys.com>
      10             :  *
      11             :  * Portions Copyright (c) Her majesty the Queen in right of Canada as
      12             :  * represented by the Minister of National Defence, 2006.
      13             :  *
      14             :  * SPDX-License-Identifier: MIT
      15             :  ****************************************************************************/
      16             : 
      17             : #include "nitfdrivercore.h"
      18             : 
      19             : /************************************************************************/
      20             : /*                     NITFDriverIdentify()                             */
      21             : /************************************************************************/
      22             : 
      23       59032 : int NITFDriverIdentify(GDALOpenInfo *poOpenInfo)
      24             : 
      25             : {
      26       59032 :     const char *pszFilename = poOpenInfo->pszFilename;
      27             : 
      28             :     /* -------------------------------------------------------------------- */
      29             :     /*      Is this a dataset selector? If so, it is obviously NITF.        */
      30             :     /* -------------------------------------------------------------------- */
      31       59032 :     if (STARTS_WITH_CI(pszFilename, "NITF_IM:"))
      32          40 :         return TRUE;
      33             : 
      34             :     /* -------------------------------------------------------------------- */
      35             :     /*      Avoid that on Windows, JPEG_SUBFILE:x,y,z,data/../tmp/foo.ntf   */
      36             :     /*      to be recognized by the NITF driver, because                    */
      37             :     /*      'JPEG_SUBFILE:x,y,z,data' is considered as a (valid) directory  */
      38             :     /*      and thus the whole filename is evaluated as tmp/foo.ntf         */
      39             :     /* -------------------------------------------------------------------- */
      40       58992 :     if (STARTS_WITH_CI(pszFilename, "JPEG_SUBFILE:"))
      41         150 :         return FALSE;
      42             : 
      43             :     /* -------------------------------------------------------------------- */
      44             :     /*      First we check to see if the file has the expected header       */
      45             :     /*      bytes.                                                          */
      46             :     /* -------------------------------------------------------------------- */
      47       58842 :     if (poOpenInfo->nHeaderBytes < 4)
      48       49199 :         return FALSE;
      49             : 
      50        9643 :     if (!STARTS_WITH_CI((char *)poOpenInfo->pabyHeader, "NITF") &&
      51        8409 :         !STARTS_WITH_CI((char *)poOpenInfo->pabyHeader, "NSIF") &&
      52        8361 :         !STARTS_WITH_CI((char *)poOpenInfo->pabyHeader, "NITF"))
      53        8361 :         return FALSE;
      54             : 
      55             :     /* Check that it is not in fact a NITF A.TOC file, which is handled by the
      56             :      * RPFTOC driver */
      57     1222390 :     for (int i = 0; i < static_cast<int>(poOpenInfo->nHeaderBytes) -
      58             :                             static_cast<int>(strlen("A.TOC"));
      59             :          i++)
      60             :     {
      61     1221110 :         if (STARTS_WITH_CI((const char *)poOpenInfo->pabyHeader + i, "A.TOC"))
      62           0 :             return FALSE;
      63             :     }
      64             : 
      65        1282 :     return TRUE;
      66             : }
      67             : 
      68             : /************************************************************************/
      69             : /*                     NITFDriverSetCommonMetadata()                    */
      70             : /************************************************************************/
      71             : 
      72        1293 : void NITFDriverSetCommonMetadata(GDALDriver *poDriver)
      73             : {
      74        1293 :     poDriver->SetDescription(NITF_DRIVER_NAME);
      75        1293 :     poDriver->SetMetadataItem(GDAL_DCAP_RASTER, "YES");
      76        1293 :     poDriver->SetMetadataItem(GDAL_DMD_LONGNAME,
      77        1293 :                               "National Imagery Transmission Format");
      78             : 
      79        1293 :     poDriver->SetMetadataItem(GDAL_DMD_HELPTOPIC, "drivers/raster/nitf.html");
      80        1293 :     poDriver->SetMetadataItem(GDAL_DMD_EXTENSION, "ntf");
      81        1293 :     poDriver->SetMetadataItem(GDAL_DMD_SUBDATASETS, "YES");
      82        1293 :     poDriver->SetMetadataItem(GDAL_DMD_CREATIONDATATYPES,
      83        1293 :                               "Byte UInt16 Int16 UInt32 Int32 Float32");
      84             : 
      85        1293 :     poDriver->SetMetadataItem(
      86             :         GDAL_DMD_OPENOPTIONLIST,
      87             :         "<OpenOptionList>"
      88             :         "  <Option name='VALIDATE' type='boolean' description='Whether "
      89             :         "validation of metadata should be done' default='NO' />"
      90             :         "  <Option name='FAIL_IF_VALIDATION_ERROR' type='boolean' "
      91             :         "description='Whether a validation error should cause dataset opening "
      92             :         "to fail' default='NO' />"
      93        1293 :         "</OpenOptionList>");
      94             : 
      95        1293 :     poDriver->SetMetadataItem(GDAL_DCAP_VIRTUALIO, "YES");
      96             : 
      97        1293 :     poDriver->pfnIdentify = NITFDriverIdentify;
      98        1293 :     poDriver->SetMetadataItem(GDAL_DCAP_OPEN, "YES");
      99        1293 :     poDriver->SetMetadataItem(GDAL_DCAP_CREATE, "YES");
     100        1293 :     poDriver->SetMetadataItem(GDAL_DCAP_CREATECOPY, "YES");
     101        1293 : }
     102             : 
     103             : /************************************************************************/
     104             : /*                     RPFTOCDriverIdentify()                           */
     105             : /************************************************************************/
     106             : 
     107       57614 : int RPFTOCDriverIdentify(GDALOpenInfo *poOpenInfo)
     108             : 
     109             : {
     110       57614 :     const char *pszFilename = poOpenInfo->pszFilename;
     111             : 
     112             :     /* -------------------------------------------------------------------- */
     113             :     /*      Is this a sub-dataset selector? If so, it is obviously RPFTOC.  */
     114             :     /* -------------------------------------------------------------------- */
     115             : 
     116       57614 :     if (STARTS_WITH_CI(pszFilename, "NITF_TOC_ENTRY:"))
     117          14 :         return TRUE;
     118             : 
     119             :     /* -------------------------------------------------------------------- */
     120             :     /*      First we check to see if the file has the expected header       */
     121             :     /*      bytes.                                                          */
     122             :     /* -------------------------------------------------------------------- */
     123       57600 :     if (poOpenInfo->nHeaderBytes < 48)
     124       49407 :         return FALSE;
     125             : 
     126        8193 :     if (RPFTOCIsNonNITFFileTOC(poOpenInfo, pszFilename))
     127           6 :         return TRUE;
     128             : 
     129        8187 :     if (!STARTS_WITH_CI((char *)poOpenInfo->pabyHeader, "NITF") &&
     130        8183 :         !STARTS_WITH_CI((char *)poOpenInfo->pabyHeader, "NSIF") &&
     131        8182 :         !STARTS_WITH_CI((char *)poOpenInfo->pabyHeader, "NITF"))
     132        8182 :         return FALSE;
     133             : 
     134             :     /* If it is a NITF A.TOC file, it must contain A.TOC in its header */
     135        4846 :     for (int i = 0; i < static_cast<int>(poOpenInfo->nHeaderBytes) -
     136             :                             static_cast<int>(strlen("A.TOC"));
     137             :          i++)
     138             :     {
     139        4841 :         if (STARTS_WITH_CI((const char *)poOpenInfo->pabyHeader + i, "A.TOC"))
     140           0 :             return TRUE;
     141             :     }
     142             : 
     143           5 :     return FALSE;
     144             : }
     145             : 
     146             : /************************************************************************/
     147             : /*                          IsNonNITFFileTOC()                          */
     148             : /************************************************************************/
     149             : 
     150             : /* Check whether the file is a TOC file without NITF header */
     151        8203 : int RPFTOCIsNonNITFFileTOC(GDALOpenInfo *poOpenInfo, const char *pszFilename)
     152             : {
     153        8203 :     const char pattern[] = {0,   0,   '0', ' ', ' ', ' ', ' ', ' ',
     154             :                             ' ', ' ', 'A', '.', 'T', 'O', 'C'};
     155        8203 :     if (poOpenInfo)
     156             :     {
     157        8196 :         if (poOpenInfo->nHeaderBytes < 48)
     158           0 :             return FALSE;
     159        8196 :         return memcmp(pattern, poOpenInfo->pabyHeader, 15) == 0;
     160             :     }
     161             :     else
     162             :     {
     163           7 :         VSILFILE *fp = VSIFOpenL(pszFilename, "rb");
     164           7 :         if (fp == nullptr)
     165             :         {
     166           0 :             return FALSE;
     167             :         }
     168             : 
     169             :         char buffer[48];
     170          14 :         int ret = (VSIFReadL(buffer, 1, 48, fp) == 48) &&
     171           7 :                   memcmp(pattern, buffer, 15) == 0;
     172           7 :         CPL_IGNORE_RET_VAL(VSIFCloseL(fp));
     173           7 :         return ret;
     174             :     }
     175             : }
     176             : 
     177             : /************************************************************************/
     178             : /*                     RPFTOCDriverSetCommonMetadata()                  */
     179             : /************************************************************************/
     180             : 
     181        1293 : void RPFTOCDriverSetCommonMetadata(GDALDriver *poDriver)
     182             : {
     183        1293 :     poDriver->SetDescription(RPFTOC_DRIVER_NAME);
     184        1293 :     poDriver->SetMetadataItem(GDAL_DCAP_RASTER, "YES");
     185        1293 :     poDriver->SetMetadataItem(GDAL_DMD_LONGNAME,
     186        1293 :                               "Raster Product Format TOC format");
     187        1293 :     poDriver->SetMetadataItem(GDAL_DMD_HELPTOPIC, "drivers/raster/rpftoc.html");
     188        1293 :     poDriver->SetMetadataItem(GDAL_DMD_EXTENSION, "toc");
     189        1293 :     poDriver->SetMetadataItem(GDAL_DCAP_VIRTUALIO, "YES");
     190        1293 :     poDriver->SetMetadataItem(GDAL_DMD_SUBDATASETS, "YES");
     191        1293 :     poDriver->SetMetadataItem(GDAL_DCAP_OPEN, "YES");
     192        1293 :     poDriver->pfnIdentify = RPFTOCDriverIdentify;
     193        1293 : }
     194             : 
     195             : /************************************************************************/
     196             : /*                     ECRGTOCDriverIdentify()                          */
     197             : /************************************************************************/
     198             : 
     199       57625 : int ECRGTOCDriverIdentify(GDALOpenInfo *poOpenInfo)
     200             : 
     201             : {
     202       57625 :     const char *pszFilename = poOpenInfo->pszFilename;
     203             : 
     204             :     /* -------------------------------------------------------------------- */
     205             :     /*      Is this a sub-dataset selector? If so, it is obviously ECRGTOC. */
     206             :     /* -------------------------------------------------------------------- */
     207       57625 :     if (STARTS_WITH_CI(pszFilename, "ECRG_TOC_ENTRY:"))
     208          40 :         return TRUE;
     209             : 
     210             :     /* -------------------------------------------------------------------- */
     211             :     /*  First we check to see if the file has the expected header           */
     212             :     /*  bytes.                                                              */
     213             :     /* -------------------------------------------------------------------- */
     214       57585 :     const char *pabyHeader =
     215             :         reinterpret_cast<const char *>(poOpenInfo->pabyHeader);
     216       57585 :     if (pabyHeader == nullptr)
     217       48963 :         return FALSE;
     218             : 
     219        8622 :     if (strstr(pabyHeader, "<Table_of_Contents") != nullptr &&
     220          14 :         strstr(pabyHeader, "<file_header ") != nullptr)
     221          14 :         return TRUE;
     222             : 
     223        8608 :     if (strstr(pabyHeader, "<!DOCTYPE Table_of_Contents [") != nullptr)
     224           0 :         return TRUE;
     225             : 
     226        8608 :     return FALSE;
     227             : }
     228             : 
     229             : /************************************************************************/
     230             : /*                     ECRGTOCDriverSetCommonMetadata()                 */
     231             : /************************************************************************/
     232             : 
     233        1293 : void ECRGTOCDriverSetCommonMetadata(GDALDriver *poDriver)
     234             : {
     235        1293 :     poDriver->SetDescription(ECRGTOC_DRIVER_NAME);
     236        1293 :     poDriver->SetMetadataItem(GDAL_DCAP_RASTER, "YES");
     237        1293 :     poDriver->SetMetadataItem(GDAL_DMD_LONGNAME, "ECRG TOC format");
     238        1293 :     poDriver->SetMetadataItem(GDAL_DMD_HELPTOPIC,
     239        1293 :                               "drivers/raster/ecrgtoc.html");
     240        1293 :     poDriver->SetMetadataItem(GDAL_DMD_EXTENSION, "xml");
     241        1293 :     poDriver->SetMetadataItem(GDAL_DCAP_VIRTUALIO, "YES");
     242        1293 :     poDriver->SetMetadataItem(GDAL_DMD_SUBDATASETS, "YES");
     243        1293 :     poDriver->SetMetadataItem(GDAL_DCAP_OPEN, "YES");
     244        1293 :     poDriver->pfnIdentify = ECRGTOCDriverIdentify;
     245        1293 : }
     246             : 
     247             : /************************************************************************/
     248             : /*                    DeclareDeferredNITFPlugin()                       */
     249             : /************************************************************************/
     250             : 
     251             : #ifdef PLUGIN_FILENAME
     252             : void DeclareDeferredNITFPlugin()
     253             : {
     254             :     if (GDALGetDriverByName(NITF_DRIVER_NAME) != nullptr)
     255             :     {
     256             :         return;
     257             :     }
     258             : 
     259             :     {
     260             :         auto poDriver = new GDALPluginDriverProxy(PLUGIN_FILENAME);
     261             : #ifdef PLUGIN_INSTALLATION_MESSAGE
     262             :         poDriver->SetMetadataItem(GDAL_DMD_PLUGIN_INSTALLATION_MESSAGE,
     263             :                                   PLUGIN_INSTALLATION_MESSAGE);
     264             : #endif
     265             :         NITFDriverSetCommonMetadata(poDriver);
     266             :         GetGDALDriverManager()->DeclareDeferredPluginDriver(poDriver);
     267             :     }
     268             : 
     269             :     {
     270             :         auto poDriver = new GDALPluginDriverProxy(PLUGIN_FILENAME);
     271             : #ifdef PLUGIN_INSTALLATION_MESSAGE
     272             :         poDriver->SetMetadataItem(GDAL_DMD_PLUGIN_INSTALLATION_MESSAGE,
     273             :                                   PLUGIN_INSTALLATION_MESSAGE);
     274             : #endif
     275             :         RPFTOCDriverSetCommonMetadata(poDriver);
     276             :         GetGDALDriverManager()->DeclareDeferredPluginDriver(poDriver);
     277             :     }
     278             : 
     279             :     {
     280             :         auto poDriver = new GDALPluginDriverProxy(PLUGIN_FILENAME);
     281             : #ifdef PLUGIN_INSTALLATION_MESSAGE
     282             :         poDriver->SetMetadataItem(GDAL_DMD_PLUGIN_INSTALLATION_MESSAGE,
     283             :                                   PLUGIN_INSTALLATION_MESSAGE);
     284             : #endif
     285             :         ECRGTOCDriverSetCommonMetadata(poDriver);
     286             :         GetGDALDriverManager()->DeclareDeferredPluginDriver(poDriver);
     287             :     }
     288             : }
     289             : #endif

Generated by: LCOV version 1.14