LCOV - code coverage report
Current view: top level - frmts/airsar - airsardataset.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 16 232 6.9 %
Date: 2024-05-04 12:52:34 Functions: 2 11 18.2 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  AirSAR Reader
       4             :  * Purpose:  Implements read support for AirSAR Polarimetric data.
       5             :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       6             :  *
       7             :  ******************************************************************************
       8             :  * Copyright (c) 2004, Frank Warmerdam <warmerdam@pobox.com>
       9             :  * Copyright (c) 2007-2009, Even Rouault <even dot rouault at spatialys.com>
      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 "cpl_conv.h"
      31             : #include "cpl_string.h"
      32             : #include "cpl_vsi.h"
      33             : #include "gdal_frmts.h"
      34             : #include "gdal_pam.h"
      35             : 
      36             : /************************************************************************/
      37             : /* ==================================================================== */
      38             : /*                              AirSARDataset                           */
      39             : /* ==================================================================== */
      40             : /************************************************************************/
      41             : 
      42             : class AirSARRasterBand;
      43             : 
      44             : class AirSARDataset final : public GDALPamDataset
      45             : {
      46             :     friend class AirSARRasterBand;
      47             : 
      48             :     VSILFILE *fp;
      49             : 
      50             :     int nLoadedLine;
      51             :     GByte *pabyCompressedLine;
      52             :     double *padfMatrix;
      53             : 
      54             :     int nDataStart;
      55             :     int nRecordLength;
      56             : 
      57             :     CPLErr LoadLine(int iLine);
      58             : 
      59             :     static char **ReadHeader(VSILFILE *fp, int nFileOffset,
      60             :                              const char *pszPrefix, int nMaxLines);
      61             : 
      62             :   public:
      63             :     AirSARDataset();
      64             :     ~AirSARDataset();
      65             : 
      66             :     static GDALDataset *Open(GDALOpenInfo *);
      67             : };
      68             : 
      69             : /************************************************************************/
      70             : /* ==================================================================== */
      71             : /*                            AirSARRasterBand                          */
      72             : /* ==================================================================== */
      73             : /************************************************************************/
      74             : 
      75             : class AirSARRasterBand final : public GDALPamRasterBand
      76             : {
      77             :   public:
      78             :     AirSARRasterBand(AirSARDataset *, int);
      79             :     ~AirSARRasterBand() override;
      80             : 
      81             :     CPLErr IReadBlock(int, int, void *) override;
      82             : };
      83             : 
      84             : /* locations of stokes matrix values within padfMatrix ... same order as they
      85             :    are computed in the document. */
      86             : 
      87             : constexpr int M11 = 0;
      88             : constexpr int M12 = 1;
      89             : constexpr int M13 = 2;
      90             : constexpr int M14 = 3;
      91             : constexpr int M23 = 4;
      92             : constexpr int M24 = 5;
      93             : constexpr int M33 = 6;
      94             : constexpr int M34 = 7;
      95             : constexpr int M44 = 8;
      96             : constexpr int M22 = 9;
      97             : 
      98             : /************************************************************************/
      99             : /*                          AirSARRasterBand()                          */
     100             : /************************************************************************/
     101             : 
     102           0 : AirSARRasterBand::AirSARRasterBand(AirSARDataset *poDSIn, int nBandIn)
     103             : 
     104             : {
     105           0 :     poDS = poDSIn;
     106           0 :     nBand = nBandIn;
     107             : 
     108           0 :     nBlockXSize = poDS->GetRasterXSize();
     109           0 :     nBlockYSize = 1;
     110             : 
     111           0 :     if (this->nBand == 2 || this->nBand == 3 || this->nBand == 5)
     112           0 :         eDataType = GDT_CFloat32;
     113             :     else
     114           0 :         eDataType = GDT_Float32;
     115             : 
     116           0 :     switch (nBand)
     117             :     {
     118           0 :         case 1:
     119           0 :             SetMetadataItem("POLARIMETRIC_INTERP", "Covariance_11");
     120           0 :             SetDescription("Covariance_11");
     121           0 :             eDataType = GDT_CFloat32;
     122           0 :             break;
     123             : 
     124           0 :         case 2:
     125           0 :             SetMetadataItem("POLARIMETRIC_INTERP", "Covariance_12");
     126           0 :             SetDescription("Covariance_12");
     127           0 :             eDataType = GDT_CFloat32;
     128           0 :             break;
     129             : 
     130           0 :         case 3:
     131           0 :             SetMetadataItem("POLARIMETRIC_INTERP", "Covariance_13");
     132           0 :             SetDescription("Covariance_13");
     133           0 :             eDataType = GDT_CFloat32;
     134           0 :             break;
     135             : 
     136           0 :         case 4:
     137           0 :             SetMetadataItem("POLARIMETRIC_INTERP", "Covariance_22");
     138           0 :             SetDescription("Covariance_22");
     139           0 :             eDataType = GDT_CFloat32;
     140           0 :             break;
     141             : 
     142           0 :         case 5:
     143           0 :             SetMetadataItem("POLARIMETRIC_INTERP", "Covariance_23");
     144           0 :             SetDescription("Covariance_23");
     145           0 :             eDataType = GDT_CFloat32;
     146           0 :             break;
     147             : 
     148           0 :         case 6:
     149           0 :             SetMetadataItem("POLARIMETRIC_INTERP", "Covariance_33");
     150           0 :             SetDescription("Covariance_33");
     151           0 :             eDataType = GDT_CFloat32;
     152           0 :             break;
     153             :     }
     154           0 : }
     155             : 
     156             : /************************************************************************/
     157             : /*                         ~AirSARRasterBand()                          */
     158             : /************************************************************************/
     159             : 
     160           0 : AirSARRasterBand::~AirSARRasterBand()
     161             : 
     162             : {
     163           0 : }
     164             : 
     165             : /************************************************************************/
     166             : /*                             IReadBlock()                             */
     167             : /************************************************************************/
     168             : 
     169           0 : CPLErr AirSARRasterBand::IReadBlock(int /* nBlockXOff */, int nBlockYOff,
     170             :                                     void *pImage)
     171             : {
     172           0 :     float *pafLine = (float *)pImage;
     173           0 :     const double SQRT_2 = 1.4142135623730951;
     174             : 
     175           0 :     CPLErr eErr = ((AirSARDataset *)poDS)->LoadLine(nBlockYOff);
     176           0 :     if (eErr != CE_None)
     177           0 :         return eErr;
     178             : 
     179           0 :     double *padfMatrix = ((AirSARDataset *)poDS)->padfMatrix;
     180             : 
     181           0 :     if (nBand == 1) /* C11 */
     182             :     {
     183           0 :         for (int iPixel = 0; iPixel < nRasterXSize; iPixel++)
     184             :         {
     185           0 :             double *m = padfMatrix + 10 * iPixel;
     186             : 
     187           0 :             pafLine[iPixel * 2 + 0] = (float)(m[M11] + m[M22] + 2 * m[M12]);
     188           0 :             pafLine[iPixel * 2 + 1] = 0.0;
     189             :         }
     190             :     }
     191           0 :     else if (nBand == 2) /* C12 */
     192             :     {
     193           0 :         for (int iPixel = 0; iPixel < nRasterXSize; iPixel++)
     194             :         {
     195           0 :             double *m = padfMatrix + 10 * iPixel;
     196             : 
     197             :             // real
     198           0 :             pafLine[iPixel * 2 + 0] = (float)(SQRT_2 * (m[M13] + m[M23]));
     199             : 
     200             :             // imaginary
     201           0 :             pafLine[iPixel * 2 + 1] = (float)(-SQRT_2 * (m[M24] + m[M14]));
     202             :         }
     203             :     }
     204           0 :     else if (nBand == 3) /* C13 */
     205             :     {
     206           0 :         for (int iPixel = 0; iPixel < nRasterXSize; iPixel++)
     207             :         {
     208           0 :             double *m = padfMatrix + 10 * iPixel;
     209             : 
     210             :             // real
     211           0 :             pafLine[iPixel * 2 + 0] = (float)(2 * m[M33] + m[M22] - m[M11]);
     212             : 
     213             :             // imaginary
     214           0 :             pafLine[iPixel * 2 + 1] = (float)(-2 * m[M34]);
     215             :         }
     216             :     }
     217           0 :     else if (nBand == 4) /* C22 */
     218             :     {
     219           0 :         for (int iPixel = 0; iPixel < nRasterXSize; iPixel++)
     220             :         {
     221           0 :             double *m = padfMatrix + 10 * iPixel;
     222             : 
     223           0 :             pafLine[iPixel * 2 + 0] = (float)(2 * (m[M11] - m[M22]));
     224           0 :             pafLine[iPixel * 2 + 1] = 0.0;
     225             :         }
     226             :     }
     227           0 :     else if (nBand == 5) /* C23 */
     228             :     {
     229           0 :         for (int iPixel = 0; iPixel < nRasterXSize; iPixel++)
     230             :         {
     231           0 :             double *m = padfMatrix + 10 * iPixel;
     232             : 
     233             :             // real
     234           0 :             pafLine[iPixel * 2 + 0] = (float)(SQRT_2 * (m[M13] - m[M23]));
     235             : 
     236             :             // imaginary
     237           0 :             pafLine[iPixel * 2 + 1] = (float)(SQRT_2 * (m[M24] - m[M14]));
     238             :         }
     239             :     }
     240           0 :     else if (nBand == 6) /* C33 */
     241             :     {
     242           0 :         for (int iPixel = 0; iPixel < nRasterXSize; iPixel++)
     243             :         {
     244           0 :             double *m = padfMatrix + 10 * iPixel;
     245             : 
     246           0 :             pafLine[iPixel * 2 + 0] = (float)(m[M11] + m[M22] - 2 * m[M12]);
     247           0 :             pafLine[iPixel * 2 + 1] = 0.0;
     248             :         }
     249             :     }
     250             : 
     251           0 :     return CE_None;
     252             : }
     253             : 
     254             : /************************************************************************/
     255             : /* ==================================================================== */
     256             : /*                              AirSARDataset                           */
     257             : /* ==================================================================== */
     258             : /************************************************************************/
     259             : 
     260             : /************************************************************************/
     261             : /*                           AirSARDataset()                            */
     262             : /************************************************************************/
     263             : 
     264           0 : AirSARDataset::AirSARDataset()
     265             :     : fp(nullptr), nLoadedLine(-1), pabyCompressedLine(nullptr),
     266           0 :       padfMatrix(nullptr), nDataStart(0), nRecordLength(0)
     267             : {
     268           0 : }
     269             : 
     270             : /************************************************************************/
     271             : /*                           ~AirSARDataset()                           */
     272             : /************************************************************************/
     273             : 
     274           0 : AirSARDataset::~AirSARDataset()
     275             : 
     276             : {
     277           0 :     FlushCache(true);
     278           0 :     CPLFree(pabyCompressedLine);
     279           0 :     CPLFree(padfMatrix);
     280             : 
     281           0 :     if (fp != nullptr)
     282             :     {
     283           0 :         VSIFCloseL(fp);
     284           0 :         fp = nullptr;
     285             :     }
     286           0 : }
     287             : 
     288             : /************************************************************************/
     289             : /*                              LoadLine()                              */
     290             : /************************************************************************/
     291             : 
     292           0 : CPLErr AirSARDataset::LoadLine(int iLine)
     293             : 
     294             : {
     295           0 :     if (iLine == nLoadedLine)
     296           0 :         return CE_None;
     297             : 
     298             :     /* -------------------------------------------------------------------- */
     299             :     /*      allocate working buffers if we don't have them already.         */
     300             :     /* -------------------------------------------------------------------- */
     301           0 :     if (pabyCompressedLine == nullptr)
     302             :     {
     303           0 :         pabyCompressedLine = (GByte *)VSI_MALLOC2_VERBOSE(nRasterXSize, 10);
     304             : 
     305           0 :         padfMatrix =
     306           0 :             (double *)VSI_MALLOC2_VERBOSE(10 * sizeof(double), nRasterXSize);
     307           0 :         if (pabyCompressedLine == nullptr || padfMatrix == nullptr)
     308             :         {
     309           0 :             CPLFree(pabyCompressedLine);
     310           0 :             CPLFree(padfMatrix);
     311           0 :             return CE_Failure;
     312             :         }
     313             :     }
     314             : 
     315           0 :     CPLAssert(nRecordLength == nRasterXSize * 10);
     316             : 
     317             :     /* -------------------------------------------------------------------- */
     318             :     /*      Load raw compressed data.                                       */
     319             :     /* -------------------------------------------------------------------- */
     320           0 :     if (VSIFSeekL(fp, nDataStart + iLine * nRecordLength, SEEK_SET) != 0 ||
     321           0 :         ((int)VSIFReadL(pabyCompressedLine, 10, nRasterXSize, fp)) !=
     322           0 :             nRasterXSize)
     323             :     {
     324           0 :         CPLError(CE_Failure, CPLE_FileIO,
     325             :                  "Error reading %d bytes for line %d at offset %d.\n%s",
     326           0 :                  nRasterXSize * 10, iLine, nDataStart + iLine * nRecordLength,
     327           0 :                  VSIStrerror(errno));
     328           0 :         return CE_Failure;
     329             :     }
     330             : 
     331             :     /* -------------------------------------------------------------------- */
     332             :     /*      Build stokes matrix                                             */
     333             :     /* -------------------------------------------------------------------- */
     334           0 :     for (int iPixel = 0; iPixel < nRasterXSize; iPixel++)
     335             :     {
     336           0 :         double *M = padfMatrix + 10 * iPixel;
     337           0 :         signed char *byte = (signed char *)pabyCompressedLine + 10 * iPixel - 1;
     338           0 :         const double gen_fac = 1.0;  // should we have a general scale factor?
     339             : 
     340           0 :         M[M11] = (byte[2] / 254.0 + 1.5) * pow(2.0, byte[1]) * gen_fac;
     341           0 :         M[M12] = byte[3] * M[M11] / 127.0;
     342           0 :         M[M13] = byte[4] * fabs((double)byte[4]) * M[M11] / (127 * 127);
     343           0 :         M[M14] = byte[5] * fabs((double)byte[5]) * M[M11] / (127 * 127);
     344           0 :         M[M23] = byte[6] * fabs((double)byte[6]) * M[M11] / (127 * 127);
     345           0 :         M[M24] = byte[7] * fabs((double)byte[7]) * M[M11] / (127 * 127);
     346           0 :         M[M33] = byte[8] * M[M11] / 127;
     347           0 :         M[M34] = byte[9] * M[M11] / 127;
     348           0 :         M[M44] = byte[10] * M[M11] / 127;
     349           0 :         M[M22] = M[M11] - M[M33] - M[M44];
     350             :     }
     351             : 
     352           0 :     return CE_None;
     353             : }
     354             : 
     355             : /************************************************************************/
     356             : /*                             ReadHeader()                             */
     357             : /*                                                                      */
     358             : /*      Read the AirSAR header.  We assume an equal sign separates      */
     359             : /*      the keyword name from the value.  If not, assume the last       */
     360             : /*      "blank delimited" word is the value and everything else is a    */
     361             : /*      keyword.                                                        */
     362             : /*                                                                      */
     363             : /*      The records are 50 characters each.  Read till we get an all    */
     364             : /*      blank record or some zero bytes.                                */
     365             : /************************************************************************/
     366             : 
     367           0 : char **AirSARDataset::ReadHeader(VSILFILE *fp, int nFileOffset,
     368             :                                  const char *pszPrefix, int nMaxLines)
     369             : 
     370             : {
     371           0 :     char **papszHeadInfo = nullptr;
     372             :     char szLine[51];
     373             : 
     374           0 :     VSIFSeekL(fp, nFileOffset, SEEK_SET);
     375             : 
     376             :     /* ==================================================================== */
     377             :     /*      Loop collecting one line at a time.                             */
     378             :     /* ==================================================================== */
     379           0 :     for (int iLine = 0; iLine < nMaxLines; iLine++)
     380             :     {
     381             :         /* --------------------------------------------------------------------
     382             :          */
     383             :         /*      Read a 50 byte header record. */
     384             :         /* --------------------------------------------------------------------
     385             :          */
     386           0 :         if (VSIFReadL(szLine, 1, 50, fp) != 50)
     387             :         {
     388           0 :             CPLError(CE_Failure, CPLE_FileIO,
     389             :                      "Read error collecting AirSAR header.");
     390           0 :             CSLDestroy(papszHeadInfo);
     391           0 :             return nullptr;
     392             :         }
     393             : 
     394           0 :         szLine[50] = '\0';
     395             : 
     396             :         /* --------------------------------------------------------------------
     397             :          */
     398             :         /*      Is it all spaces, or does it have a zero byte? */
     399             :         /* --------------------------------------------------------------------
     400             :          */
     401           0 :         bool bAllSpaces = true;
     402           0 :         bool bHasIllegalChars = false;
     403             : 
     404           0 :         for (int i = 0; i < 50; i++)
     405             :         {
     406           0 :             if (szLine[i] == '\0')
     407           0 :                 break;
     408             : 
     409           0 :             if (szLine[i] != ' ')
     410           0 :                 bAllSpaces = false;
     411             : 
     412           0 :             if (((unsigned char *)szLine)[i] > 127 ||
     413           0 :                 ((unsigned char *)szLine)[i] < 10)
     414           0 :                 bHasIllegalChars = true;
     415             :         }
     416             : 
     417           0 :         if (bAllSpaces || bHasIllegalChars)
     418             :             break;
     419             : 
     420             :         /* --------------------------------------------------------------------
     421             :          */
     422             :         /*      Find the pivot between the keyword name and value. */
     423             :         /* --------------------------------------------------------------------
     424             :          */
     425           0 :         int iPivot = -1;
     426             : 
     427           0 :         for (int i = 0; i < 50; i++)
     428             :         {
     429           0 :             if (szLine[i] == '=')
     430             :             {
     431           0 :                 iPivot = i;
     432           0 :                 break;
     433             :             }
     434             :         }
     435             : 
     436             :         // If no "=" found, split on first double white space
     437           0 :         if (iPivot == -1)
     438             :         {
     439           0 :             for (int i = 48; i >= 0; i--)
     440             :             {
     441           0 :                 if (szLine[i] == ' ' && szLine[i + 1] == ' ')
     442             :                 {
     443           0 :                     iPivot = i;
     444           0 :                     break;
     445             :                 }
     446             :             }
     447             :         }
     448             : 
     449           0 :         if (iPivot == -1)  // Yikes!
     450             :         {
     451           0 :             CPLDebug("AIRSAR", "No pivot in line `%s'.", szLine);
     452           0 :             CPLAssert(iPivot != -1);
     453           0 :             break;
     454             :         }
     455             : 
     456             :         /* --------------------------------------------------------------------
     457             :          */
     458             :         /*      Trace ahead to the first non-white space value character. */
     459             :         /* --------------------------------------------------------------------
     460             :          */
     461           0 :         int iValue = iPivot + 1;
     462             : 
     463           0 :         while (iValue < 50 && szLine[iValue] == ' ')
     464           0 :             iValue++;
     465             : 
     466             :         /* --------------------------------------------------------------------
     467             :          */
     468             :         /*      Strip any white space off the keyword. */
     469             :         /* --------------------------------------------------------------------
     470             :          */
     471           0 :         int iKeyEnd = iPivot - 1;
     472             : 
     473           0 :         while (iKeyEnd > 0 && szLine[iKeyEnd] == ' ')
     474           0 :             iKeyEnd--;
     475             : 
     476           0 :         szLine[iKeyEnd + 1] = '\0';
     477             : 
     478             :         /* --------------------------------------------------------------------
     479             :          */
     480             :         /*      Convert spaces or colons into underscores in the key name. */
     481             :         /* --------------------------------------------------------------------
     482             :          */
     483           0 :         for (int i = 0; szLine[i] != '\0'; i++)
     484             :         {
     485           0 :             if (szLine[i] == ' ' || szLine[i] == ':' || szLine[i] == ',')
     486           0 :                 szLine[i] = '_';
     487             :         }
     488             : 
     489             :         /* --------------------------------------------------------------------
     490             :          */
     491             :         /*      Prefix key name with provided prefix string. */
     492             :         /* --------------------------------------------------------------------
     493             :          */
     494             :         char szPrefixedKeyName[55];
     495             : 
     496           0 :         snprintf(szPrefixedKeyName, sizeof(szPrefixedKeyName), "%s_%s",
     497             :                  pszPrefix, szLine);
     498             : 
     499             :         papszHeadInfo =
     500           0 :             CSLSetNameValue(papszHeadInfo, szPrefixedKeyName, szLine + iValue);
     501             :     }
     502             : 
     503           0 :     return papszHeadInfo;
     504             : }
     505             : 
     506             : /************************************************************************/
     507             : /*                                Open()                                */
     508             : /************************************************************************/
     509             : 
     510       32964 : GDALDataset *AirSARDataset::Open(GDALOpenInfo *poOpenInfo)
     511             : 
     512             : {
     513       32964 :     if (poOpenInfo->fpL == nullptr || poOpenInfo->nHeaderBytes < 800)
     514       28835 :         return nullptr;
     515             : 
     516             :     /* -------------------------------------------------------------------- */
     517             :     /*      Check for AirSAR/ keyword.                                      */
     518             :     /* -------------------------------------------------------------------- */
     519        4129 :     if (!STARTS_WITH_CI((char *)poOpenInfo->pabyHeader,
     520             :                         "RECORD LENGTH IN BYTES"))
     521        4129 :         return nullptr;
     522             : 
     523           0 :     if (strstr((char *)poOpenInfo->pabyHeader, "COMPRESSED") == nullptr ||
     524           0 :         strstr((char *)poOpenInfo->pabyHeader, "JPL AIRCRAFT") == nullptr)
     525           0 :         return nullptr;
     526             : 
     527             :     /* -------------------------------------------------------------------- */
     528             :     /*      Parse the header fields.  We turn all the transform the         */
     529             :     /*      keywords by converting spaces to underscores so they will be    */
     530             :     /*      "well behaved" as metadata keywords.                            */
     531             :     /* -------------------------------------------------------------------- */
     532           0 :     char **papszMD = ReadHeader(poOpenInfo->fpL, 0, "MH", 20);
     533             : 
     534           0 :     if (papszMD == nullptr)
     535           0 :         return nullptr;
     536             : 
     537             :     /* -------------------------------------------------------------------- */
     538             :     /*      Confirm the requested access is supported.                      */
     539             :     /* -------------------------------------------------------------------- */
     540           0 :     if (poOpenInfo->eAccess == GA_Update)
     541             :     {
     542           0 :         CPLError(CE_Failure, CPLE_NotSupported,
     543             :                  "The AIRSAR driver does not support update access to existing"
     544             :                  " datasets.\n");
     545           0 :         CSLDestroy(papszMD);
     546           0 :         return nullptr;
     547             :     }
     548             :     /* -------------------------------------------------------------------- */
     549             :     /*      Create a corresponding GDALDataset.                             */
     550             :     /* -------------------------------------------------------------------- */
     551           0 :     AirSARDataset *poDS = new AirSARDataset();
     552             : 
     553             :     /* -------------------------------------------------------------------- */
     554             :     /*      Extract some key information.                                   */
     555             :     /* -------------------------------------------------------------------- */
     556             : 
     557           0 :     poDS->nRasterXSize =
     558           0 :         atoi(CSLFetchNameValue(papszMD, "MH_NUMBER_OF_SAMPLES_PER_RECORD"));
     559           0 :     poDS->nRasterYSize =
     560           0 :         atoi(CSLFetchNameValue(papszMD, "MH_NUMBER_OF_LINES_IN_IMAGE"));
     561             : 
     562           0 :     poDS->nRecordLength =
     563           0 :         atoi(CSLFetchNameValue(papszMD, "MH_RECORD_LENGTH_IN_BYTES"));
     564             : 
     565           0 :     poDS->nDataStart =
     566           0 :         atoi(CSLFetchNameValue(papszMD, "MH_BYTE_OFFSET_OF_FIRST_DATA_RECORD"));
     567             : 
     568             :     /* -------------------------------------------------------------------- */
     569             :     /*      Adopt the openinfo file pointer.                                */
     570             :     /* -------------------------------------------------------------------- */
     571           0 :     poDS->fp = poOpenInfo->fpL;
     572           0 :     poOpenInfo->fpL = nullptr;
     573             : 
     574             :     /* -------------------------------------------------------------------- */
     575             :     /*      Read and merge parameter header into metadata.  Prefix          */
     576             :     /*      parameter header values with PH_.                               */
     577             :     /* -------------------------------------------------------------------- */
     578           0 :     int nPHOffset = 0;
     579             : 
     580           0 :     if (CSLFetchNameValue(papszMD, "MH_BYTE_OFFSET_OF_PARAMETER_HEADER") !=
     581             :         nullptr)
     582             :     {
     583           0 :         nPHOffset = atoi(
     584             :             CSLFetchNameValue(papszMD, "MH_BYTE_OFFSET_OF_PARAMETER_HEADER"));
     585           0 :         char **papszPHInfo = ReadHeader(poDS->fp, nPHOffset, "PH", 100);
     586             : 
     587           0 :         papszMD = CSLInsertStrings(papszMD, CSLCount(papszMD), papszPHInfo);
     588             : 
     589           0 :         CSLDestroy(papszPHInfo);
     590             :     }
     591             : 
     592             :     /* -------------------------------------------------------------------- */
     593             :     /*      Read and merge calibration header into metadata.  Prefix        */
     594             :     /*      parameter header values with CH_.                               */
     595             :     /* -------------------------------------------------------------------- */
     596           0 :     if (nPHOffset != 0)
     597             :     {
     598             :         char **papszCHInfo =
     599           0 :             ReadHeader(poDS->fp, nPHOffset + poDS->nRecordLength, "CH", 18);
     600             : 
     601           0 :         papszMD = CSLInsertStrings(papszMD, CSLCount(papszMD), papszCHInfo);
     602             : 
     603           0 :         CSLDestroy(papszCHInfo);
     604             :     }
     605             : 
     606             :     /* -------------------------------------------------------------------- */
     607             :     /*      Assign metadata to dataset.                                     */
     608             :     /* -------------------------------------------------------------------- */
     609           0 :     poDS->SetMetadata(papszMD);
     610           0 :     CSLDestroy(papszMD);
     611             : 
     612             :     /* -------------------------------------------------------------------- */
     613             :     /*      Create band information objects.                                */
     614             :     /* -------------------------------------------------------------------- */
     615           0 :     poDS->SetBand(1, new AirSARRasterBand(poDS, 1));
     616           0 :     poDS->SetBand(2, new AirSARRasterBand(poDS, 2));
     617           0 :     poDS->SetBand(3, new AirSARRasterBand(poDS, 3));
     618           0 :     poDS->SetBand(4, new AirSARRasterBand(poDS, 4));
     619           0 :     poDS->SetBand(5, new AirSARRasterBand(poDS, 5));
     620           0 :     poDS->SetBand(6, new AirSARRasterBand(poDS, 6));
     621             : 
     622           0 :     poDS->SetMetadataItem("MATRIX_REPRESENTATION", "SYMMETRIZED_COVARIANCE");
     623             : 
     624             :     /* -------------------------------------------------------------------- */
     625             :     /*      Initialize any PAM information.                                 */
     626             :     /* -------------------------------------------------------------------- */
     627           0 :     poDS->SetDescription(poOpenInfo->pszFilename);
     628           0 :     poDS->TryLoadXML();
     629             : 
     630           0 :     poDS->oOvManager.Initialize(poDS, poOpenInfo->pszFilename);
     631             : 
     632           0 :     return poDS;
     633             : }
     634             : 
     635             : /************************************************************************/
     636             : /*                        GDALRegister_AirSAR()                         */
     637             : /************************************************************************/
     638             : 
     639        1520 : void GDALRegister_AirSAR()
     640             : 
     641             : {
     642        1520 :     if (GDALGetDriverByName("AirSAR") != nullptr)
     643         301 :         return;
     644             : 
     645        1219 :     GDALDriver *poDriver = new GDALDriver();
     646             : 
     647        1219 :     poDriver->SetDescription("AirSAR");
     648        1219 :     poDriver->SetMetadataItem(GDAL_DCAP_RASTER, "YES");
     649        1219 :     poDriver->SetMetadataItem(GDAL_DMD_LONGNAME, "AirSAR Polarimetric Image");
     650        1219 :     poDriver->SetMetadataItem(GDAL_DMD_HELPTOPIC, "drivers/raster/airsar.html");
     651             : 
     652        1219 :     poDriver->SetMetadataItem(GDAL_DCAP_VIRTUALIO, "YES");
     653             : 
     654        1219 :     poDriver->pfnOpen = AirSARDataset::Open;
     655             : 
     656        1219 :     GetGDALDriverManager()->RegisterDriver(poDriver);
     657             : }

Generated by: LCOV version 1.14