LCOV - code coverage report
Current view: directory - frmts/nitf - nitfrasterband.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 371 307 82.7 %
Date: 2012-12-26 Functions: 55 33 60.0 %

       1                 : /******************************************************************************
       2                 :  * $Id: nitfrasterband.cpp 25194 2012-10-30 22:33:21Z rouault $
       3                 :  *
       4                 :  * Project:  NITF Read/Write Translator
       5                 :  * Purpose:  NITFRasterBand (and related proxy band) implementations.
       6                 :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 2002, Frank Warmerdam
      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                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      15                 :  * copy of this software and associated documentation files (the "Software"),
      16                 :  * to deal in the Software without restriction, including without limitation
      17                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      18                 :  * and/or sell copies of the Software, and to permit persons to whom the
      19                 :  * Software is furnished to do so, subject to the following conditions:
      20                 :  *
      21                 :  * The above copyright notice and this permission notice shall be included
      22                 :  * in all copies or substantial portions of the Software.
      23                 :  *
      24                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      25                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      26                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      27                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      28                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      29                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      30                 :  * DEALINGS IN THE SOFTWARE.
      31                 :  ****************************************************************************/
      32                 : 
      33                 : #include "nitfdataset.h"
      34                 : #include "cpl_string.h"
      35                 : #include "cpl_csv.h"
      36                 : 
      37                 : CPL_CVSID("$Id: nitfrasterband.cpp 25194 2012-10-30 22:33:21Z rouault $");
      38                 : 
      39                 : /************************************************************************/
      40                 : /*                       NITFMakeColorTable()                           */
      41                 : /************************************************************************/
      42                 : 
      43          210728 : static GDALColorTable* NITFMakeColorTable(NITFImage* psImage, NITFBandInfo *psBandInfo)
      44                 : {
      45          210728 :     GDALColorTable* poColorTable = NULL;
      46                 : 
      47          210728 :     if( psBandInfo->nSignificantLUTEntries > 0 )
      48                 :     {
      49                 :         int  iColor;
      50                 : 
      51              41 :         poColorTable = new GDALColorTable();
      52                 : 
      53            8264 :         for( iColor = 0; iColor < psBandInfo->nSignificantLUTEntries; iColor++)
      54                 :         {
      55                 :             GDALColorEntry sEntry;
      56                 : 
      57            8223 :             sEntry.c1 = psBandInfo->pabyLUT[  0 + iColor];
      58            8223 :             sEntry.c2 = psBandInfo->pabyLUT[256 + iColor];
      59            8223 :             sEntry.c3 = psBandInfo->pabyLUT[512 + iColor];
      60            8223 :             sEntry.c4 = 255;
      61                 : 
      62            8223 :             poColorTable->SetColorEntry( iColor, &sEntry );
      63                 :         }
      64                 : 
      65              41 :         if (psImage->bNoDataSet)
      66                 :         {
      67                 :             GDALColorEntry sEntry;
      68              31 :             sEntry.c1 = sEntry.c2 = sEntry.c3 = sEntry.c4 = 0;
      69              31 :             poColorTable->SetColorEntry( psImage->nNoDataValue, &sEntry );
      70                 :         }
      71                 :     }
      72                 : 
      73                 : /* -------------------------------------------------------------------- */
      74                 : /*      We create a color table for 1 bit data too...                   */
      75                 : /* -------------------------------------------------------------------- */
      76          210728 :     if( poColorTable == NULL && psImage->nBitsPerSample == 1 )
      77                 :     {
      78                 :         GDALColorEntry sEntry;
      79                 : 
      80              18 :         poColorTable = new GDALColorTable();
      81                 : 
      82              18 :         sEntry.c1 = 0;
      83              18 :         sEntry.c2 = 0;
      84              18 :         sEntry.c3 = 0;
      85              18 :         sEntry.c4 = 255;
      86              18 :         poColorTable->SetColorEntry( 0, &sEntry );
      87                 : 
      88              18 :         sEntry.c1 = 255;
      89              18 :         sEntry.c2 = 255;
      90              18 :         sEntry.c3 = 255;
      91              18 :         sEntry.c4 = 255;
      92              18 :         poColorTable->SetColorEntry( 1, &sEntry );
      93                 :     }
      94                 :     
      95          210728 :     return poColorTable;
      96                 : }
      97                 : 
      98                 : /************************************************************************/
      99                 : /* ==================================================================== */
     100                 : /*                        NITFProxyPamRasterBand                        */
     101                 : /* ==================================================================== */
     102                 : /************************************************************************/
     103                 : 
     104              56 : NITFProxyPamRasterBand::~NITFProxyPamRasterBand()
     105                 : {
     106              56 :     std::map<CPLString, char**>::iterator oIter = oMDMap.begin();
     107             116 :     while(oIter != oMDMap.end())
     108                 :     {
     109               4 :         CSLDestroy(oIter->second);
     110               4 :         oIter ++;
     111                 :     }
     112              56 : }
     113                 : 
     114                 : 
     115                 : #define RB_PROXY_METHOD_WITH_RET(retType, retErrValue, methodName, argList, argParams) \
     116                 : retType NITFProxyPamRasterBand::methodName argList \
     117                 : { \
     118                 :     retType ret; \
     119                 :     GDALRasterBand* _poSrcBand = RefUnderlyingRasterBand(); \
     120                 :     if (_poSrcBand) \
     121                 :     { \
     122                 :         ret = _poSrcBand->methodName argParams; \
     123                 :         UnrefUnderlyingRasterBand(_poSrcBand); \
     124                 :     } \
     125                 :     else \
     126                 :     { \
     127                 :         ret = retErrValue; \
     128                 :     } \
     129                 :     return ret; \
     130                 : }
     131                 : 
     132                 : 
     133                 : #define RB_PROXY_METHOD_WITH_RET_AND_CALL_OTHER_METHOD(retType, retErrValue, methodName, underlyingMethodName, argList, argParams) \
     134                 : retType NITFProxyPamRasterBand::methodName argList \
     135                 : { \
     136                 :     retType ret; \
     137                 :     GDALRasterBand* _poSrcBand = RefUnderlyingRasterBand(); \
     138                 :     if (_poSrcBand) \
     139                 :     { \
     140                 :         ret = _poSrcBand->underlyingMethodName argParams; \
     141                 :         UnrefUnderlyingRasterBand(_poSrcBand); \
     142                 :     } \
     143                 :     else \
     144                 :     { \
     145                 :         ret = retErrValue; \
     146                 :     } \
     147                 :     return ret; \
     148                 : }
     149                 : 
     150               4 : char      **NITFProxyPamRasterBand::GetMetadata( const char * pszDomain  )
     151                 : {
     152               4 :     GDALRasterBand* _poSrcBand = RefUnderlyingRasterBand();
     153               4 :     if (_poSrcBand)
     154                 :     {
     155                 :         /* Let's merge metadata of PAM and the underlying band */
     156                 :         /* PAM metadata should override underlying band metadata */
     157               4 :         char** papszMD = CSLDuplicate(_poSrcBand->GetMetadata( pszDomain ));
     158               4 :         papszMD = CSLMerge( papszMD, GDALPamRasterBand::GetMetadata(pszDomain) );
     159                 : 
     160               4 :         if (pszDomain == NULL)
     161               0 :             pszDomain = "";
     162                 : 
     163               4 :         std::map<CPLString, char**>::iterator oIter = oMDMap.find(pszDomain);
     164               4 :         if (oIter != oMDMap.end())
     165               0 :             CSLDestroy(oIter->second);
     166               4 :         oMDMap[pszDomain] = papszMD;
     167               4 :         UnrefUnderlyingRasterBand(_poSrcBand);
     168                 : 
     169               4 :         return papszMD;
     170                 :     }
     171                 : 
     172               0 :     return GDALPamRasterBand::GetMetadata(pszDomain);
     173                 : }
     174                 : 
     175                 : 
     176               4 : const char *NITFProxyPamRasterBand::GetMetadataItem( const char * pszName,
     177                 :                                                      const char * pszDomain )
     178                 : {
     179               4 :     const char* pszRet = GDALPamRasterBand::GetMetadataItem(pszName, pszDomain);
     180               4 :     if (pszRet)
     181               0 :         return pszRet;
     182                 : 
     183               4 :     GDALRasterBand* _poSrcBand = RefUnderlyingRasterBand();
     184               4 :     if (_poSrcBand)
     185                 :     {
     186               4 :         pszRet = _poSrcBand->GetMetadataItem( pszName, pszDomain );
     187               4 :         UnrefUnderlyingRasterBand(_poSrcBand);
     188                 :     }
     189                 : 
     190               4 :     return pszRet;
     191                 : }
     192                 : 
     193               2 : CPLErr NITFProxyPamRasterBand::GetStatistics( int bApproxOK, int bForce,
     194                 :                                       double *pdfMin, double *pdfMax,
     195                 :                                       double *pdfMean, double *pdfStdDev )
     196                 : {
     197                 :     CPLErr ret;
     198                 : 
     199                 : /* -------------------------------------------------------------------- */
     200                 : /*      Do we already have metadata items for the requested values?     */
     201                 : /* -------------------------------------------------------------------- */
     202               2 :     if( (pdfMin == NULL || GetMetadataItem("STATISTICS_MINIMUM") != NULL)
     203               0 :      && (pdfMax == NULL || GetMetadataItem("STATISTICS_MAXIMUM") != NULL)
     204               0 :      && (pdfMean == NULL || GetMetadataItem("STATISTICS_MEAN") != NULL)
     205               0 :      && (pdfStdDev == NULL || GetMetadataItem("STATISTICS_STDDEV") != NULL) )
     206                 :     {
     207                 :         return GDALPamRasterBand::GetStatistics( bApproxOK, bForce,
     208                 :                                                  pdfMin, pdfMax,
     209               0 :                                                  pdfMean, pdfStdDev);
     210                 :     }
     211                 : 
     212               2 :     GDALRasterBand* _poSrcBand = RefUnderlyingRasterBand();
     213               2 :     if (_poSrcBand)
     214                 :     {
     215                 :         ret = _poSrcBand->GetStatistics( bApproxOK, bForce,
     216               2 :                                          pdfMin, pdfMax, pdfMean, pdfStdDev);
     217               2 :         if (ret == CE_None)
     218                 :         {
     219                 :             /* Report underlying statistics at PAM level */
     220                 :             SetMetadataItem("STATISTICS_MINIMUM",
     221               2 :                             _poSrcBand->GetMetadataItem("STATISTICS_MINIMUM"));
     222                 :             SetMetadataItem("STATISTICS_MAXIMUM",
     223               2 :                             _poSrcBand->GetMetadataItem("STATISTICS_MAXIMUM"));
     224                 :             SetMetadataItem("STATISTICS_MEAN",
     225               2 :                             _poSrcBand->GetMetadataItem("STATISTICS_MEAN"));
     226                 :             SetMetadataItem("STATISTICS_STDDEV",
     227               2 :                             _poSrcBand->GetMetadataItem("STATISTICS_STDDEV"));
     228                 :         }
     229               2 :         UnrefUnderlyingRasterBand(_poSrcBand);
     230                 :     }
     231                 :     else
     232                 :     {
     233               0 :         ret = CE_Failure;
     234                 :     }
     235               2 :     return ret;
     236                 : }
     237                 : 
     238               0 : CPLErr NITFProxyPamRasterBand::ComputeStatistics( int bApproxOK,
     239                 :                                         double *pdfMin, double *pdfMax,
     240                 :                                         double *pdfMean, double *pdfStdDev,
     241                 :                                         GDALProgressFunc pfn, void *pProgressData )
     242                 : {
     243                 :     CPLErr ret;
     244               0 :     GDALRasterBand* _poSrcBand = RefUnderlyingRasterBand();
     245               0 :     if (_poSrcBand)
     246                 :     {
     247                 :         ret = _poSrcBand->ComputeStatistics( bApproxOK, pdfMin, pdfMax,
     248                 :                                              pdfMean, pdfStdDev,
     249               0 :                                              pfn, pProgressData);
     250               0 :         if (ret == CE_None)
     251                 :         {
     252                 :             /* Report underlying statistics at PAM level */
     253                 :             SetMetadataItem("STATISTICS_MINIMUM",
     254               0 :                             _poSrcBand->GetMetadataItem("STATISTICS_MINIMUM"));
     255                 :             SetMetadataItem("STATISTICS_MAXIMUM",
     256               0 :                             _poSrcBand->GetMetadataItem("STATISTICS_MAXIMUM"));
     257                 :             SetMetadataItem("STATISTICS_MEAN",
     258               0 :                             _poSrcBand->GetMetadataItem("STATISTICS_MEAN"));
     259                 :             SetMetadataItem("STATISTICS_STDDEV",
     260               0 :                             _poSrcBand->GetMetadataItem("STATISTICS_STDDEV"));
     261                 :         }
     262               0 :         UnrefUnderlyingRasterBand(_poSrcBand);
     263                 :     }
     264                 :     else
     265                 :     {
     266               0 :         ret = CE_Failure;
     267                 :     }
     268               0 :     return ret;
     269                 : }
     270                 : 
     271                 : 
     272                 : #define RB_PROXY_METHOD_GET_DBL_WITH_SUCCESS(methodName) \
     273                 : double NITFProxyPamRasterBand::methodName( int *pbSuccess ) \
     274                 : { \
     275                 :     int bSuccess = FALSE; \
     276                 :     double dfRet = GDALPamRasterBand::methodName(&bSuccess); \
     277                 :     if (bSuccess) \
     278                 :     { \
     279                 :         if (pbSuccess) \
     280                 :             *pbSuccess = TRUE; \
     281                 :         return dfRet; \
     282                 :     } \
     283                 :     GDALRasterBand* _poSrcBand = RefUnderlyingRasterBand(); \
     284                 :     if (_poSrcBand) \
     285                 :     { \
     286                 :         dfRet = _poSrcBand->methodName( pbSuccess ); \
     287                 :         UnrefUnderlyingRasterBand(_poSrcBand); \
     288                 :     } \
     289                 :     else \
     290                 :     { \
     291                 :         dfRet = 0; \
     292                 :     } \
     293                 :     return dfRet; \
     294                 : }
     295                 : 
     296               9 : RB_PROXY_METHOD_GET_DBL_WITH_SUCCESS(GetNoDataValue)
     297               0 : RB_PROXY_METHOD_GET_DBL_WITH_SUCCESS(GetMinimum)
     298               0 : RB_PROXY_METHOD_GET_DBL_WITH_SUCCESS(GetMaximum)
     299                 : 
     300               0 : RB_PROXY_METHOD_WITH_RET_AND_CALL_OTHER_METHOD(CPLErr, CE_Failure, IReadBlock, ReadBlock,
     301                 :                                 ( int nXBlockOff, int nYBlockOff, void* pImage),
     302                 :                                 (nXBlockOff, nYBlockOff, pImage) )
     303               0 : RB_PROXY_METHOD_WITH_RET_AND_CALL_OTHER_METHOD(CPLErr, CE_Failure, IWriteBlock, WriteBlock,
     304                 :                                 ( int nXBlockOff, int nYBlockOff, void* pImage),
     305                 :                                 (nXBlockOff, nYBlockOff, pImage) )
     306           10605 : RB_PROXY_METHOD_WITH_RET_AND_CALL_OTHER_METHOD(CPLErr, CE_Failure, IRasterIO, RasterIO,
     307                 :                         ( GDALRWFlag eRWFlag,
     308                 :                                 int nXOff, int nYOff, int nXSize, int nYSize,
     309                 :                                 void * pData, int nBufXSize, int nBufYSize,
     310                 :                                 GDALDataType eBufType,
     311                 :                                 int nPixelSpace,
     312                 :                                 int nLineSpace ),
     313                 :                         (eRWFlag, nXOff, nYOff, nXSize, nYSize,
     314                 :                                 pData, nBufXSize, nBufYSize, eBufType,
     315                 :                                 nPixelSpace, nLineSpace ) )
     316                 : 
     317              56 : RB_PROXY_METHOD_WITH_RET(CPLErr, CE_Failure, FlushCache, (), ())
     318                 : 
     319               0 : RB_PROXY_METHOD_WITH_RET(GDALColorInterp, GCI_Undefined, GetColorInterpretation, (), ())
     320               0 : RB_PROXY_METHOD_WITH_RET(GDALColorTable*, NULL, GetColorTable, (), ())
     321               0 : RB_PROXY_METHOD_WITH_RET(CPLErr, CE_Failure, Fill,
     322                 :                         (double dfRealValue, double dfImaginaryValue),
     323                 :                         (dfRealValue, dfImaginaryValue))
     324                 : 
     325               1 : RB_PROXY_METHOD_WITH_RET(CPLErr, CE_Failure, ComputeRasterMinMax,
     326                 :                         ( int arg1, double* arg2 ), (arg1, arg2))
     327                 : 
     328               0 : RB_PROXY_METHOD_WITH_RET(int, 0, HasArbitraryOverviews, (), ())
     329               2 : RB_PROXY_METHOD_WITH_RET(int, 0,  GetOverviewCount, (), ())
     330               2 : RB_PROXY_METHOD_WITH_RET(GDALRasterBand*, NULL,  GetOverview, (int arg1), (arg1))
     331               0 : RB_PROXY_METHOD_WITH_RET(GDALRasterBand*, NULL,  GetRasterSampleOverview,
     332                 :                         (int arg1), (arg1))
     333                 : 
     334               0 : RB_PROXY_METHOD_WITH_RET(CPLErr, CE_Failure, BuildOverviews,
     335                 :                         (const char * arg1, int arg2, int *arg3,
     336                 :                         GDALProgressFunc arg4, void * arg5),
     337                 :                         (arg1, arg2, arg3, arg4, arg5))
     338                 : 
     339               0 : RB_PROXY_METHOD_WITH_RET(CPLErr, CE_Failure, AdviseRead,
     340                 :                         ( int nXOff, int nYOff, int nXSize, int nYSize,
     341                 :                         int nBufXSize, int nBufYSize,
     342                 :                         GDALDataType eDT, char **papszOptions ),
     343                 :                         (nXOff, nYOff, nXSize, nYSize, nBufXSize, nBufYSize, eDT, papszOptions))
     344                 : 
     345               0 : RB_PROXY_METHOD_WITH_RET(GDALRasterBand*, NULL, GetMaskBand, (), ())
     346               6 : RB_PROXY_METHOD_WITH_RET(int, 0, GetMaskFlags, (), ())
     347               0 : RB_PROXY_METHOD_WITH_RET(CPLErr, CE_Failure, CreateMaskBand, ( int nFlags ), (nFlags))
     348                 : 
     349                 : 
     350                 : /************************************************************************/
     351                 : /*                 UnrefUnderlyingRasterBand()                        */
     352                 : /************************************************************************/
     353                 : 
     354           10691 : void NITFProxyPamRasterBand::UnrefUnderlyingRasterBand(GDALRasterBand* poUnderlyingRasterBand)
     355                 : {
     356           10691 : }
     357                 : 
     358                 : 
     359                 : /************************************************************************/
     360                 : /* ==================================================================== */
     361                 : /*                            NITFRasterBand                             */
     362                 : /* ==================================================================== */
     363                 : /************************************************************************/
     364                 : 
     365                 : /************************************************************************/
     366                 : /*                           NITFRasterBand()                           */
     367                 : /************************************************************************/
     368                 : 
     369          210724 : NITFRasterBand::NITFRasterBand( NITFDataset *poDS, int nBand )
     370                 : 
     371                 : {
     372          210724 :     NITFBandInfo *psBandInfo = poDS->psImage->pasBandInfo + nBand - 1;
     373                 : 
     374          210724 :     this->poDS = poDS;
     375          210724 :     this->nBand = nBand;
     376                 : 
     377          210724 :     this->eAccess = poDS->eAccess;
     378          210724 :     this->psImage = poDS->psImage;
     379                 : 
     380                 : /* -------------------------------------------------------------------- */
     381                 : /*      Translate data type(s).                                         */
     382                 : /* -------------------------------------------------------------------- */
     383          210724 :     if( psImage->nBitsPerSample <= 8 )
     384          210608 :         eDataType = GDT_Byte;
     385             143 :     else if( psImage->nBitsPerSample == 16 
     386                 :              && EQUAL(psImage->szPVType,"SI") )
     387              27 :         eDataType = GDT_Int16;
     388              89 :     else if( psImage->nBitsPerSample == 16 )
     389              12 :         eDataType = GDT_UInt16;
     390              77 :     else if( psImage->nBitsPerSample == 12 )
     391              18 :         eDataType = GDT_UInt16;
     392              71 :     else if( psImage->nBitsPerSample == 32 
     393                 :              && EQUAL(psImage->szPVType,"SI") )
     394              12 :         eDataType = GDT_Int32;
     395              61 :     else if( psImage->nBitsPerSample == 32 
     396                 :              && EQUAL(psImage->szPVType,"R") )
     397              14 :         eDataType = GDT_Float32;
     398              33 :     else if( psImage->nBitsPerSample == 32 )
     399              12 :         eDataType = GDT_UInt32;
     400              33 :     else if( psImage->nBitsPerSample == 64 
     401                 :              && EQUAL(psImage->szPVType,"R") )
     402              12 :         eDataType = GDT_Float64;
     403              18 :     else if( psImage->nBitsPerSample == 64
     404                 :               && EQUAL(psImage->szPVType,"C") )
     405               9 :         eDataType = GDT_CFloat32;
     406                 :     /* ERO : note I'm not sure if CFloat64 can be transmitted as NBPP is only 2 characters */
     407                 :     else
     408                 :     {
     409                 :         int bOpenUnderlyingDS = CSLTestBoolean(
     410               0 :                 CPLGetConfigOption("NITF_OPEN_UNDERLYING_DS", "YES"));
     411               0 :         if (!bOpenUnderlyingDS && psImage->nBitsPerSample > 8 && psImage->nBitsPerSample < 16)
     412                 :         {
     413               0 :             if (EQUAL(psImage->szPVType,"SI"))
     414               0 :                 eDataType = GDT_Int16;
     415                 :             else
     416               0 :                 eDataType = GDT_UInt16;
     417                 :         }
     418                 :         else
     419                 :         {
     420               0 :             eDataType = GDT_Unknown;
     421                 :             CPLError( CE_Warning, CPLE_AppDefined,
     422                 :                     "Unsupported combination of PVTYPE(%s) and NBPP(%d).",
     423               0 :                     psImage->szPVType, psImage->nBitsPerSample );
     424                 :         }
     425                 :     }
     426                 : 
     427                 : /* -------------------------------------------------------------------- */
     428                 : /*      Work out block size. If the image is all one big block we       */
     429                 : /*      handle via the scanline access API.                             */
     430                 : /* -------------------------------------------------------------------- */
     431          421234 :     if( psImage->nBlocksPerRow == 1 
     432                 :         && psImage->nBlocksPerColumn == 1
     433                 :         && psImage->nBitsPerSample >= 8
     434                 :         && EQUAL(psImage->szIC,"NC") )
     435                 :     {
     436          210510 :         bScanlineAccess = TRUE;
     437          210510 :         nBlockXSize = psImage->nBlockWidth;
     438          210510 :         nBlockYSize = 1;
     439                 :     }
     440                 :     else
     441                 :     {
     442             214 :         bScanlineAccess = FALSE;
     443             214 :         nBlockXSize = psImage->nBlockWidth;
     444             214 :         nBlockYSize = psImage->nBlockHeight;
     445                 :     }
     446                 : 
     447                 : /* -------------------------------------------------------------------- */
     448                 : /*      Do we have a color table?                                       */
     449                 : /* -------------------------------------------------------------------- */
     450                 :     poColorTable = NITFMakeColorTable(psImage,
     451          210724 :                                       psBandInfo);
     452                 : 
     453          210724 :     if( psImage->nBitsPerSample == 1 
     454                 :     ||  psImage->nBitsPerSample == 3
     455                 :     ||  psImage->nBitsPerSample == 5
     456                 :     ||  psImage->nBitsPerSample == 6
     457                 :     ||  psImage->nBitsPerSample == 7
     458                 :     ||  psImage->nBitsPerSample == 12 )
     459             102 :         SetMetadataItem( "NBITS", CPLString().Printf("%d", psImage->nBitsPerSample), "IMAGE_STRUCTURE" );
     460                 : 
     461          210724 :     pUnpackData = 0;
     462          210724 :     if (psImage->nBitsPerSample == 3
     463                 :     ||  psImage->nBitsPerSample == 5
     464                 :     ||  psImage->nBitsPerSample == 6
     465                 :     ||  psImage->nBitsPerSample == 7)
     466              64 :       pUnpackData = new GByte[((nBlockXSize*nBlockYSize+7)/8)*8];
     467          210724 : }
     468                 : 
     469                 : /************************************************************************/
     470                 : /*                          ~NITFRasterBand()                           */
     471                 : /************************************************************************/
     472                 : 
     473          210724 : NITFRasterBand::~NITFRasterBand()
     474                 : 
     475                 : {
     476          210724 :     if( poColorTable != NULL )
     477              55 :         delete poColorTable;
     478                 : 
     479          210724 :     delete[] pUnpackData;
     480          210724 : }
     481                 : 
     482                 : /************************************************************************/
     483                 : /*                             IReadBlock()                             */
     484                 : /************************************************************************/
     485                 : 
     486           23127 : CPLErr NITFRasterBand::IReadBlock( int nBlockXOff, int nBlockYOff,
     487                 :                                    void * pImage )
     488                 : 
     489                 : {
     490                 :     int  nBlockResult;
     491           23127 :     NITFDataset *poGDS = (NITFDataset *) poDS;
     492                 : 
     493                 : /* -------------------------------------------------------------------- */
     494                 : /*      Special case for JPEG blocks.                                   */
     495                 : /* -------------------------------------------------------------------- */
     496           23127 :     if( EQUAL(psImage->szIC,"C3") || EQUAL(psImage->szIC,"M3") )
     497                 :     {
     498              55 :         CPLErr eErr = poGDS->ReadJPEGBlock( nBlockXOff, nBlockYOff );
     499                 :         int nBlockBandSize = psImage->nBlockWidth*psImage->nBlockHeight*
     500              55 :                              (GDALGetDataTypeSize(eDataType)/8);
     501                 : 
     502              55 :         if( eErr != CE_None )
     503               0 :             return eErr;
     504                 : 
     505                 :         memcpy( pImage, 
     506                 :                 poGDS->pabyJPEGBlock + (nBand - 1) * nBlockBandSize, 
     507              55 :                 nBlockBandSize );
     508                 : 
     509              55 :         return eErr;
     510                 :     }
     511                 : 
     512                 : /* -------------------------------------------------------------------- */
     513                 : /*      Read the line/block                                             */
     514                 : /* -------------------------------------------------------------------- */
     515           23072 :     if( bScanlineAccess )
     516                 :     {
     517                 :         nBlockResult = 
     518           21047 :             NITFReadImageLine(psImage, nBlockYOff, nBand, pImage);
     519                 :     }
     520                 :     else
     521                 :     {
     522                 :         nBlockResult = 
     523            2025 :             NITFReadImageBlock(psImage, nBlockXOff, nBlockYOff, nBand, pImage);
     524                 :     }
     525                 : 
     526           23072 :     if( nBlockResult == BLKREAD_OK )
     527                 :     {
     528           22853 :         if( psImage->nBitsPerSample % 8 )
     529              72 :             Unpack((GByte*)pImage);
     530                 : 
     531           22853 :         return CE_None;
     532                 :     }
     533                 : 
     534             219 :     if( nBlockResult == BLKREAD_FAIL )
     535               0 :         return CE_Failure;
     536                 : 
     537                 : /* -------------------------------------------------------------------- */
     538                 : /*      If we got a null/missing block, try to fill it in with the      */
     539                 : /*      nodata value.  It seems this only really works properly for     */
     540                 : /*      8bit.                                                           */
     541                 : /* -------------------------------------------------------------------- */
     542             219 :     if( psImage->bNoDataSet )
     543                 :         memset( pImage, psImage->nNoDataValue, 
     544             219 :                 psImage->nWordSize*psImage->nBlockWidth*psImage->nBlockHeight);
     545                 :     else
     546                 :         memset( pImage, 0, 
     547               0 :                 psImage->nWordSize*psImage->nBlockWidth*psImage->nBlockHeight);
     548                 : 
     549             219 :     return CE_None;
     550                 : }
     551                 : 
     552                 : /************************************************************************/
     553                 : /*                            IWriteBlock()                             */
     554                 : /************************************************************************/
     555                 : 
     556            6654 : CPLErr NITFRasterBand::IWriteBlock( int nBlockXOff, int nBlockYOff,
     557                 :                                     void * pImage )
     558                 :     
     559                 : {
     560                 :     int  nBlockResult;
     561                 : 
     562                 : /* -------------------------------------------------------------------- */
     563                 : /*      Write the line/block                                            */
     564                 : /* -------------------------------------------------------------------- */
     565            6654 :     if( bScanlineAccess )
     566                 :     {
     567                 :         nBlockResult = 
     568            6009 :             NITFWriteImageLine(psImage, nBlockYOff, nBand, pImage);
     569                 :     }
     570                 :     else
     571                 :     {
     572                 :         nBlockResult = 
     573             645 :             NITFWriteImageBlock(psImage, nBlockXOff, nBlockYOff, nBand,pImage);
     574                 :     }
     575                 : 
     576            6654 :     if( nBlockResult == BLKREAD_OK )
     577            6654 :         return CE_None;
     578                 :     else
     579               0 :         return CE_Failure;
     580                 : }
     581                 : 
     582                 : /************************************************************************/
     583                 : /*                           GetNoDataValue()                           */
     584                 : /************************************************************************/
     585                 : 
     586              80 : double NITFRasterBand::GetNoDataValue( int *pbSuccess )
     587                 : 
     588                 : {
     589              80 :     if( pbSuccess != NULL )
     590              79 :         *pbSuccess = psImage->bNoDataSet;
     591                 : 
     592              80 :     if( psImage->bNoDataSet )
     593              19 :         return psImage->nNoDataValue;
     594                 :     else
     595              61 :         return GDALPamRasterBand::GetNoDataValue( pbSuccess );
     596                 : }
     597                 : 
     598                 : /************************************************************************/
     599                 : /*                       GetColorInterpretation()                       */
     600                 : /************************************************************************/
     601                 : 
     602             123 : GDALColorInterp NITFRasterBand::GetColorInterpretation()
     603                 : 
     604                 : {
     605             123 :     NITFBandInfo *psBandInfo = psImage->pasBandInfo + nBand - 1;
     606                 : 
     607             123 :     if( poColorTable != NULL )
     608              17 :         return GCI_PaletteIndex;
     609                 :     
     610             106 :     if( EQUAL(psBandInfo->szIREPBAND,"R") )
     611              16 :         return GCI_RedBand;
     612              90 :     if( EQUAL(psBandInfo->szIREPBAND,"G") )
     613              16 :         return GCI_GreenBand;
     614              74 :     if( EQUAL(psBandInfo->szIREPBAND,"B") )
     615              16 :         return GCI_BlueBand;
     616              58 :     if( EQUAL(psBandInfo->szIREPBAND,"M") )
     617              40 :         return GCI_GrayIndex;
     618              18 :     if( EQUAL(psBandInfo->szIREPBAND,"Y") )
     619               2 :         return GCI_YCbCr_YBand;
     620              16 :     if( EQUAL(psBandInfo->szIREPBAND,"Cb") )
     621               2 :         return GCI_YCbCr_CbBand;
     622              14 :     if( EQUAL(psBandInfo->szIREPBAND,"Cr") )
     623               2 :         return GCI_YCbCr_CrBand;
     624                 : 
     625              12 :     return GCI_Undefined;
     626                 : }
     627                 : 
     628                 : /************************************************************************/
     629                 : /*                     NITFSetColorInterpretation()                     */
     630                 : /************************************************************************/
     631                 : 
     632              24 : CPLErr NITFSetColorInterpretation( NITFImage *psImage, 
     633                 :                                    int nBand,
     634                 :                                    GDALColorInterp eInterp )
     635                 :     
     636                 : {
     637              24 :     NITFBandInfo *psBandInfo = psImage->pasBandInfo + nBand - 1;
     638              24 :     const char *pszREP = NULL;
     639                 :     GUIntBig nOffset;
     640                 : 
     641              24 :     if( eInterp == GCI_RedBand )
     642               8 :         pszREP = "R";
     643              16 :     else if( eInterp == GCI_GreenBand )
     644               8 :         pszREP = "G";
     645               8 :     else if( eInterp == GCI_BlueBand )
     646               8 :         pszREP = "B";
     647               0 :     else if( eInterp == GCI_GrayIndex )
     648               0 :         pszREP = "M";
     649               0 :     else if( eInterp == GCI_YCbCr_YBand )
     650               0 :         pszREP = "Y";
     651               0 :     else if( eInterp == GCI_YCbCr_CbBand )
     652               0 :         pszREP = "Cb";
     653               0 :     else if( eInterp == GCI_YCbCr_CrBand )
     654               0 :         pszREP = "Cr";
     655               0 :     else if( eInterp == GCI_Undefined )
     656               0 :         return CE_None;
     657                 : 
     658              24 :     if( pszREP == NULL )
     659                 :     {
     660                 :         CPLError( CE_Failure, CPLE_NotSupported, 
     661                 :                   "Requested color interpretation (%s) not supported in NITF.",
     662               0 :                   GDALGetColorInterpretationName( eInterp ) );
     663               0 :         return CE_Failure;
     664                 :     }
     665                 : 
     666                 : /* -------------------------------------------------------------------- */
     667                 : /*      Where does this go in the file?                                 */
     668                 : /* -------------------------------------------------------------------- */
     669              24 :     strcpy( psBandInfo->szIREPBAND, pszREP );
     670              24 :     nOffset = NITFIHFieldOffset( psImage, "IREPBAND" );
     671                 : 
     672              24 :     if( nOffset != 0 )
     673              24 :         nOffset += (nBand - 1) * 13;
     674                 :     
     675                 : /* -------------------------------------------------------------------- */
     676                 : /*      write it (space padded).                                        */
     677                 : /* -------------------------------------------------------------------- */
     678                 :     char szPadded[4];
     679              24 :     strcpy( szPadded, pszREP );
     680              24 :     strcat( szPadded, " " );
     681                 :     
     682              24 :     if( nOffset != 0 )
     683                 :     {
     684              24 :         if( VSIFSeekL( psImage->psFile->fp, nOffset, SEEK_SET ) != 0 
     685                 :             || VSIFWriteL( (void *) szPadded, 1, 2, psImage->psFile->fp ) != 2 )
     686                 :         {
     687                 :             CPLError( CE_Failure, CPLE_AppDefined, 
     688               0 :                       "IO failure writing new IREPBAND value to NITF file." );
     689               0 :             return CE_Failure;
     690                 :         }
     691                 :     }
     692                 :     
     693              24 :     return CE_None;
     694                 : }
     695                 : 
     696                 : /************************************************************************/
     697                 : /*                       SetColorInterpretation()                       */
     698                 : /************************************************************************/
     699                 : 
     700              21 : CPLErr NITFRasterBand::SetColorInterpretation( GDALColorInterp eInterp )
     701                 : 
     702                 : {
     703              21 :     return NITFSetColorInterpretation( psImage, nBand, eInterp );
     704                 : }
     705                 : 
     706                 : /************************************************************************/
     707                 : /*                           GetColorTable()                            */
     708                 : /************************************************************************/
     709                 : 
     710              36 : GDALColorTable *NITFRasterBand::GetColorTable()
     711                 : 
     712                 : {
     713              36 :     return poColorTable;
     714                 : }
     715                 : 
     716                 : /************************************************************************/
     717                 : /*                           SetColorTable()                            */
     718                 : /************************************************************************/
     719                 : 
     720               2 : CPLErr NITFRasterBand::SetColorTable( GDALColorTable *poNewCT )
     721                 : 
     722                 : {
     723               2 :     NITFDataset *poGDS = (NITFDataset *) poDS;
     724               2 :     if( poGDS->bInLoadXML )
     725               0 :         return GDALPamRasterBand::SetColorTable(poNewCT);
     726                 :         
     727               2 :     if( poNewCT == NULL )
     728               0 :         return CE_Failure;
     729                 : 
     730                 :     GByte abyNITFLUT[768];
     731                 :     int   i;
     732               2 :     int   nCount = MIN(256,poNewCT->GetColorEntryCount());
     733                 : 
     734               2 :     memset( abyNITFLUT, 0, 768 );
     735             135 :     for( i = 0; i < nCount; i++ )
     736                 :     {
     737                 :         GDALColorEntry sEntry;
     738                 : 
     739             133 :         poNewCT->GetColorEntryAsRGB( i, &sEntry );
     740             133 :         abyNITFLUT[i    ] = (GByte) sEntry.c1;
     741             133 :         abyNITFLUT[i+256] = (GByte) sEntry.c2;
     742             133 :         abyNITFLUT[i+512] = (GByte) sEntry.c3;
     743                 :     }
     744                 : 
     745               2 :     if( NITFWriteLUT( psImage, nBand, nCount, abyNITFLUT ) )
     746               2 :         return CE_None;
     747                 :     else
     748               0 :         return CE_Failure;
     749                 : }
     750                 : 
     751                 : /************************************************************************/
     752                 : /*                           Unpack()                                   */
     753                 : /************************************************************************/
     754                 : 
     755              72 : void NITFRasterBand::Unpack( GByte* pData )
     756                 : {
     757              72 :   long n = nBlockXSize*nBlockYSize;
     758                 :   long i;
     759                 :   long k;
     760                 : 
     761              72 :   GByte abyTempData[7] = {0, 0, 0, 0, 0, 0, 0};
     762              72 :   const GByte* pDataSrc = pData;
     763              72 :   if (n < psImage->nBitsPerSample &&
     764                 :       psImage->nBitsPerSample < 8)
     765                 :   {
     766              21 :       memcpy(abyTempData, pData, n);
     767              21 :       pDataSrc = abyTempData;
     768                 :   }
     769                 : 
     770              72 :   switch (psImage->nBitsPerSample)
     771                 :   {
     772                 :     case 1:
     773                 :     {
     774                 :       // unpack 1-bit in-place in reverse
     775         1050526 :       for (i = n; --i >= 0; )
     776         1050502 :         pData[i] = (pData[i>>3] & (0x80 >> (i&7))) != 0;
     777                 :        
     778              12 :       break;
     779                 :     }
     780                 :     case 2:
     781                 :     {
     782                 :       static const int s_Shift2[] = {6, 4, 2, 0};
     783                 :       // unpack 2-bit in-place in reverse
     784              52 :       for (i = n; --i >= 0; )
     785              36 :         pData[i] = (pData[i>>2] >> (GByte)s_Shift2[i&3]) & 0x03;
     786                 :        
     787               8 :       break;
     788                 :     }
     789                 :     case 4:
     790                 :     {
     791                 :       static const int s_Shift4[] = {4, 0};
     792                 :       // unpack 4-bit in-place in reverse
     793              52 :       for (i = n; --i >= 0; )
     794              36 :         pData[i] = (pData[i>>1] >> (GByte)s_Shift4[i&1]) & 0x0f;
     795                 :        
     796               8 :       break;
     797                 :     }
     798                 :     case 3:
     799                 :     {
     800                 :       // unpacks 8 pixels (3 bytes) at time
     801              16 :       for (i = 0, k = 0; i < n; i += 8, k += 3)
     802                 :       {
     803               8 :         pUnpackData[i+0] = ((pDataSrc[k+0] >> 5));
     804               8 :         pUnpackData[i+1] = ((pDataSrc[k+0] >> 2) & 0x07);
     805               8 :         pUnpackData[i+2] = ((pDataSrc[k+0] << 1) & 0x07) | (pDataSrc[k+1] >> 7);
     806               8 :         pUnpackData[i+3] = ((pDataSrc[k+1] >> 4) & 0x07);
     807               8 :         pUnpackData[i+4] = ((pDataSrc[k+1] >> 1) & 0x07);
     808               8 :         pUnpackData[i+5] = ((pDataSrc[k+1] << 2) & 0x07) | (pDataSrc[k+2] >> 6);
     809               8 :         pUnpackData[i+6] = ((pDataSrc[k+2] >> 3) & 0x07);
     810               8 :         pUnpackData[i+7] = ((pDataSrc[k+2]) & 0x7);
     811                 :       }
     812                 : 
     813               8 :       memcpy(pData, pUnpackData, n);
     814               8 :       break;
     815                 :     }
     816                 :     case 5:
     817                 :     {
     818                 :       // unpacks 8 pixels (5 bytes) at time
     819              16 :       for (i = 0, k = 0; i < n; i += 8, k += 5)
     820                 :       {
     821               8 :         pUnpackData[i+0] = ((pDataSrc[k+0] >> 3));
     822               8 :         pUnpackData[i+1] = ((pDataSrc[k+0] << 2) & 0x1f) | (pDataSrc[k+1] >> 6);
     823               8 :         pUnpackData[i+2] = ((pDataSrc[k+1] >> 1) & 0x1f);
     824               8 :         pUnpackData[i+3] = ((pDataSrc[k+1] << 4) & 0x1f) | (pDataSrc[k+2] >> 4);
     825               8 :         pUnpackData[i+4] = ((pDataSrc[k+2] << 1) & 0x1f) | (pDataSrc[k+3] >> 7);
     826               8 :         pUnpackData[i+5] = ((pDataSrc[k+3] >> 2) & 0x1f);
     827               8 :         pUnpackData[i+6] = ((pDataSrc[k+3] << 3) & 0x1f) | (pDataSrc[k+4] >> 5);
     828               8 :         pUnpackData[i+7] = ((pDataSrc[k+4]) & 0x1f);
     829                 :       }
     830                 : 
     831               8 :       memcpy(pData, pUnpackData, n);
     832               8 :       break;
     833                 :     }
     834                 :     case 6:
     835                 :     {
     836                 :       // unpacks 4 pixels (3 bytes) at time
     837              20 :       for (i = 0, k = 0; i < n; i += 4, k += 3)
     838                 :       {
     839              12 :         pUnpackData[i+0] = ((pDataSrc[k+0] >> 2));
     840              12 :         pUnpackData[i+1] = ((pDataSrc[k+0] << 4) & 0x3f) | (pDataSrc[k+1] >> 4);
     841              12 :         pUnpackData[i+2] = ((pDataSrc[k+1] << 2) & 0x3f) | (pDataSrc[k+2] >> 6);
     842              12 :         pUnpackData[i+3] = ((pDataSrc[k+2]) & 0x3f);
     843                 :       }
     844                 : 
     845               8 :       memcpy(pData, pUnpackData, n);
     846               8 :       break;
     847                 :     }
     848                 :     case 7:
     849                 :     {
     850                 :       // unpacks 8 pixels (7 bytes) at time
     851              16 :       for (i = 0, k = 0; i < n; i += 8, k += 7)
     852                 :       {
     853               8 :         pUnpackData[i+0] = ((pDataSrc[k+0] >> 1));
     854               8 :         pUnpackData[i+1] = ((pDataSrc[k+0] << 6) & 0x7f) | (pDataSrc[k+1] >> 2);
     855               8 :         pUnpackData[i+2] = ((pDataSrc[k+1] << 5) & 0x7f) | (pDataSrc[k+2] >> 3) ;
     856               8 :         pUnpackData[i+3] = ((pDataSrc[k+2] << 4) & 0x7f) | (pDataSrc[k+3] >> 4);
     857               8 :         pUnpackData[i+4] = ((pDataSrc[k+3] << 3) & 0x7f) | (pDataSrc[k+4] >> 5);
     858               8 :         pUnpackData[i+5] = ((pDataSrc[k+4] << 2) & 0x7f) | (pDataSrc[k+5] >> 6);
     859               8 :         pUnpackData[i+6] = ((pDataSrc[k+5] << 1) & 0x7f) | (pDataSrc[k+6] >> 7);
     860               8 :         pUnpackData[i+7] = ((pDataSrc[k+6]) & 0x7f);
     861                 :       }
     862                 : 
     863               8 :       memcpy(pData, pUnpackData, n);
     864               8 :       break;
     865                 :     }
     866                 :     case 12:
     867                 :     {
     868              12 :       GByte*   pabyImage = (GByte  *)pData;
     869              12 :       GUInt16* panImage  = (GUInt16*)pData;
     870         1048636 :       for (i = n; --i >= 0; )
     871                 :       {
     872         1048612 :         long iOffset = i*3 / 2;
     873         1048612 :         if (i % 2 == 0)
     874          524308 :           panImage[i] = pabyImage[iOffset] + (pabyImage[iOffset+1] & 0xf0) * 16;
     875                 :         else
     876          524304 :           panImage[i] = (pabyImage[iOffset]   & 0x0f) * 16
     877          524304 :                       + (pabyImage[iOffset+1] & 0xf0) / 16
     878         1048608 :                       + (pabyImage[iOffset+1] & 0x0f) * 256;
     879                 :       }
     880                 : 
     881                 :       break;
     882                 :     }
     883                 :   }
     884              72 : }
     885                 : 
     886                 : /************************************************************************/
     887                 : /* ==================================================================== */
     888                 : /*                       NITFWrapperRasterBand                          */
     889                 : /* ==================================================================== */
     890                 : /************************************************************************/
     891                 : 
     892                 : /************************************************************************/
     893                 : /*                      NITFWrapperRasterBand()                         */
     894                 : /************************************************************************/
     895                 : 
     896              56 : NITFWrapperRasterBand::NITFWrapperRasterBand( NITFDataset * poDS,
     897                 :                                               GDALRasterBand* poBaseBand,
     898              56 :                                               int nBand)
     899                 : {
     900              56 :     this->poDS = poDS;
     901              56 :     this->nBand = nBand;
     902              56 :     this->poBaseBand = poBaseBand;
     903              56 :     eDataType = poBaseBand->GetRasterDataType();
     904              56 :     poBaseBand->GetBlockSize(&nBlockXSize, &nBlockYSize);
     905              56 :     poColorTable = NULL;
     906              56 :     eInterp = poBaseBand->GetColorInterpretation();
     907                 :     bIsJPEG = poBaseBand->GetDataset() != NULL &&
     908              56 :               poBaseBand->GetDataset()->GetDriver() != NULL &&
     909             112 :               EQUAL(poBaseBand->GetDataset()->GetDriver()->GetDescription(), "JPEG");
     910              56 : }
     911                 : 
     912                 : /************************************************************************/
     913                 : /*                      ~NITFWrapperRasterBand()                        */
     914                 : /************************************************************************/
     915                 : 
     916              56 : NITFWrapperRasterBand::~NITFWrapperRasterBand()
     917                 : {
     918              56 :     if( poColorTable != NULL )
     919               4 :         delete poColorTable;
     920              56 : }
     921                 : 
     922                 : /************************************************************************/
     923                 : /*                     RefUnderlyingRasterBand()                        */
     924                 : /************************************************************************/
     925                 : 
     926                 : /* We don't need ref-counting. Just return the base band */
     927           10691 : GDALRasterBand* NITFWrapperRasterBand::RefUnderlyingRasterBand()
     928                 : {
     929           10691 :     return poBaseBand;
     930                 : }
     931                 : 
     932                 : /************************************************************************/
     933                 : /*                            GetColorTable()                           */
     934                 : /************************************************************************/
     935                 : 
     936              13 : GDALColorTable *NITFWrapperRasterBand::GetColorTable()
     937                 : {
     938              13 :     return poColorTable;
     939                 : }
     940                 : 
     941                 : /************************************************************************/
     942                 : /*                 SetColorTableFromNITFBandInfo()                      */
     943                 : /************************************************************************/
     944                 : 
     945               4 : void NITFWrapperRasterBand::SetColorTableFromNITFBandInfo()
     946                 : {
     947               4 :     NITFDataset* poGDS = (NITFDataset* )poDS;
     948                 :     poColorTable = NITFMakeColorTable(poGDS->psImage,
     949               4 :                                       poGDS->psImage->pasBandInfo + nBand - 1);
     950               4 : }
     951                 : 
     952                 : /************************************************************************/
     953                 : /*                        GetColorInterpretation()                      */
     954                 : /************************************************************************/
     955                 : 
     956              32 : GDALColorInterp NITFWrapperRasterBand::GetColorInterpretation()
     957                 : {
     958              32 :     return eInterp;
     959                 : }
     960                 : 
     961                 : /************************************************************************/
     962                 : /*                        SetColorInterpretation()                      */
     963                 : /************************************************************************/
     964                 : 
     965              50 : CPLErr NITFWrapperRasterBand::SetColorInterpretation( GDALColorInterp eInterp)
     966                 : {
     967              50 :     this->eInterp = eInterp;
     968              50 :     return CE_None;
     969                 : }
     970                 : 
     971                 : /************************************************************************/
     972                 : /*                          GetOverviewCount()                          */
     973                 : /************************************************************************/
     974                 : 
     975               5 : int NITFWrapperRasterBand::GetOverviewCount()
     976                 : {
     977               5 :     if( bIsJPEG )
     978                 :     {
     979               3 :         if( ((NITFDataset*)poDS)->ExposeUnderlyingJPEGDatasetOverviews() )
     980               0 :             return NITFProxyPamRasterBand::GetOverviewCount();
     981                 :         else
     982               3 :             return GDALPamRasterBand::GetOverviewCount();
     983                 :     }
     984                 :     else
     985               2 :         return NITFProxyPamRasterBand::GetOverviewCount();
     986                 : }
     987                 : 
     988                 : /************************************************************************/
     989                 : /*                             GetOverview()                            */
     990                 : /************************************************************************/
     991                 : 
     992               4 : GDALRasterBand * NITFWrapperRasterBand::GetOverview(int iOverview)
     993                 : {
     994               4 :     if( bIsJPEG )
     995                 :     {
     996               2 :         if( ((NITFDataset*)poDS)->ExposeUnderlyingJPEGDatasetOverviews() )
     997               0 :             return NITFProxyPamRasterBand::GetOverview(iOverview);
     998                 :         else
     999               2 :             return GDALPamRasterBand::GetOverview(iOverview);
    1000                 :     }
    1001                 :     else
    1002               2 :         return NITFProxyPamRasterBand::GetOverview(iOverview);
    1003                 : }

Generated by: LCOV version 1.7