LCOV - code coverage report
Current view: directory - frmts/mem - memdataset.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 324 294 90.7 %
Date: 2012-12-26 Functions: 44 37 84.1 %

       1                 : /******************************************************************************
       2                 :  * $Id: memdataset.cpp 24378 2012-05-03 21:01:27Z rouault $
       3                 :  *
       4                 :  * Project:  Memory Array Translator
       5                 :  * Purpose:  Complete implementation.
       6                 :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 2000, Frank Warmerdam
      10                 :  *
      11                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      12                 :  * copy of this software and associated documentation files (the "Software"),
      13                 :  * to deal in the Software without restriction, including without limitation
      14                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      15                 :  * and/or sell copies of the Software, and to permit persons to whom the
      16                 :  * Software is furnished to do so, subject to the following conditions:
      17                 :  *
      18                 :  * The above copyright notice and this permission notice shall be included
      19                 :  * in all copies or substantial portions of the Software.
      20                 :  *
      21                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      22                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      23                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      24                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      25                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      26                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      27                 :  * DEALINGS IN THE SOFTWARE.
      28                 :  ****************************************************************************/
      29                 : 
      30                 : #include "memdataset.h"
      31                 : #include "cpl_string.h"
      32                 : 
      33                 : CPL_CVSID("$Id: memdataset.cpp 24378 2012-05-03 21:01:27Z rouault $");
      34                 : 
      35                 : /************************************************************************/
      36                 : /*                        MEMCreateRasterBand()                         */
      37                 : /************************************************************************/
      38                 : 
      39               7 : GDALRasterBandH MEMCreateRasterBand( GDALDataset *poDS, int nBand, 
      40                 :                                     GByte *pabyData, GDALDataType eType, 
      41                 :                                     int nPixelOffset, int nLineOffset, 
      42                 :                                     int bAssumeOwnership )
      43                 : 
      44                 : {
      45                 :     return (GDALRasterBandH) 
      46                 :         new MEMRasterBand( poDS, nBand, pabyData, eType, nPixelOffset, 
      47               7 :                            nLineOffset, bAssumeOwnership );
      48                 : }
      49                 : 
      50                 : /************************************************************************/
      51                 : /*                           MEMRasterBand()                            */
      52                 : /************************************************************************/
      53                 : 
      54            5519 : MEMRasterBand::MEMRasterBand( GDALDataset *poDS, int nBand,
      55                 :                               GByte *pabyDataIn, GDALDataType eTypeIn, 
      56                 :                               int nPixelOffsetIn, int nLineOffsetIn,
      57            5519 :                               int bAssumeOwnership, const char * pszPixelType)
      58                 : 
      59                 : {
      60                 :     //CPLDebug( "MEM", "MEMRasterBand(%p)", this );
      61                 : 
      62            5519 :     this->poDS = poDS;
      63            5519 :     this->nBand = nBand;
      64                 : 
      65            5519 :     this->eAccess = poDS->GetAccess();
      66                 : 
      67            5519 :     eDataType = eTypeIn;
      68                 : 
      69            5519 :     nBlockXSize = poDS->GetRasterXSize();
      70            5519 :     nBlockYSize = 1;
      71                 : 
      72            5519 :     if( nPixelOffsetIn == 0 )
      73            5224 :         nPixelOffsetIn = GDALGetDataTypeSize(eTypeIn) / 8;
      74                 : 
      75            5519 :     if( nLineOffsetIn == 0 )
      76            5230 :         nLineOffsetIn = nPixelOffsetIn * nBlockXSize;
      77                 : 
      78            5519 :     nPixelOffset = nPixelOffsetIn;
      79            5519 :     nLineOffset = nLineOffsetIn;
      80            5519 :     bOwnData = bAssumeOwnership;
      81                 : 
      82            5519 :     pabyData = pabyDataIn;
      83                 : 
      84            5519 :     bNoDataSet  = FALSE;
      85                 : 
      86            5519 :     poColorTable = NULL;
      87                 :     
      88            5519 :     eColorInterp = GCI_Undefined;
      89                 : 
      90            5519 :     papszCategoryNames = NULL;
      91            5519 :     dfOffset = 0.0;
      92            5519 :     dfScale = 1.0;
      93            5519 :     pszUnitType = NULL;
      94            5519 :     psSavedHistograms = NULL;
      95                 : 
      96            5519 :     if( pszPixelType && EQUAL(pszPixelType,"SIGNEDBYTE") )
      97               0 :         this->SetMetadataItem( "PIXELTYPE", "SIGNEDBYTE", "IMAGE_STRUCTURE" );
      98            5519 : }
      99                 : 
     100                 : /************************************************************************/
     101                 : /*                           ~MEMRasterBand()                           */
     102                 : /************************************************************************/
     103                 : 
     104            5519 : MEMRasterBand::~MEMRasterBand()
     105                 : 
     106                 : {
     107                 :     //CPLDebug( "MEM", "~MEMRasterBand(%p)", this );
     108            5519 :     if( bOwnData )
     109                 :     {
     110                 :         //CPLDebug( "MEM", "~MEMRasterBand() - free raw data." );
     111            5236 :         VSIFree( pabyData );
     112                 :     }
     113                 : 
     114            5519 :     if( poColorTable != NULL )
     115               2 :         delete poColorTable;
     116                 : 
     117            5519 :     CPLFree( pszUnitType );
     118            5519 :     CSLDestroy( papszCategoryNames );
     119                 : 
     120            5519 :     if (psSavedHistograms != NULL)
     121               1 :         CPLDestroyXMLNode(psSavedHistograms);
     122            5519 : }
     123                 : 
     124                 : 
     125                 : /************************************************************************/
     126                 : /*                             IReadBlock()                             */
     127                 : /************************************************************************/
     128                 : 
     129           17398 : CPLErr MEMRasterBand::IReadBlock( int nBlockXOff, int nBlockYOff,
     130                 :                                    void * pImage )
     131                 : 
     132                 : {
     133           17398 :     int     nWordSize = GDALGetDataTypeSize( eDataType ) / 8;
     134           17398 :     CPLAssert( nBlockXOff == 0 );
     135                 : 
     136           17398 :     if( nPixelOffset == nWordSize )
     137                 :     {
     138                 :         memcpy( pImage, 
     139                 :                 pabyData + nLineOffset*(size_t)nBlockYOff, 
     140           17098 :                 nPixelOffset * nBlockXSize );
     141                 :     }
     142                 :     else
     143                 :     {
     144             300 :         GByte *pabyCur = pabyData + nLineOffset * (size_t)nBlockYOff;
     145                 : 
     146           30300 :         for( int iPixel = 0; iPixel < nBlockXSize; iPixel++ )
     147                 :         {
     148                 :             memcpy( ((GByte *) pImage) + iPixel*nWordSize, 
     149                 :                     pabyCur + iPixel*nPixelOffset, 
     150           30000 :                     nWordSize );
     151                 :         }
     152                 :     }
     153                 : 
     154           17398 :     return CE_None;
     155                 : }
     156                 : 
     157                 : /************************************************************************/
     158                 : /*                            IWriteBlock()                             */
     159                 : /************************************************************************/
     160                 : 
     161           20159 : CPLErr MEMRasterBand::IWriteBlock( int nBlockXOff, int nBlockYOff,
     162                 :                                      void * pImage )
     163                 : 
     164                 : {
     165           20159 :     int     nWordSize = GDALGetDataTypeSize( eDataType ) / 8;
     166           20159 :     CPLAssert( nBlockXOff == 0 );
     167                 : 
     168           20159 :     if( nPixelOffset == nWordSize )
     169                 :     {
     170                 :         memcpy( pabyData+nLineOffset*(size_t)nBlockYOff, 
     171                 :                 pImage, 
     172           18859 :                 nPixelOffset * nBlockXSize );
     173                 :     }
     174                 :     else
     175                 :     {
     176            1300 :         GByte *pabyCur = pabyData + nLineOffset*(size_t)nBlockYOff;
     177                 : 
     178          491300 :         for( int iPixel = 0; iPixel < nBlockXSize; iPixel++ )
     179                 :         {
     180                 :             memcpy( pabyCur + iPixel*nPixelOffset, 
     181                 :                     ((GByte *) pImage) + iPixel*nWordSize, 
     182          490000 :                     nWordSize );
     183                 :         }
     184                 :     }
     185                 : 
     186           20159 :     return CE_None;
     187                 : }
     188                 : 
     189                 : /************************************************************************/
     190                 : /*                            GetNoDataValue()                          */
     191                 : /************************************************************************/
     192             280 : double MEMRasterBand::GetNoDataValue( int *pbSuccess )
     193                 : 
     194                 : {
     195             280 :     if( pbSuccess )
     196             279 :         *pbSuccess = bNoDataSet;
     197                 : 
     198             280 :     if( bNoDataSet )
     199               5 :         return dfNoData;
     200                 :     else
     201             275 :         return 0.0;
     202                 : }
     203                 : 
     204                 : /************************************************************************/
     205                 : /*                            SetNoDataValue()                          */
     206                 : /************************************************************************/
     207               2 : CPLErr MEMRasterBand::SetNoDataValue( double dfNewValue )
     208                 : {
     209               2 :     dfNoData = dfNewValue;
     210               2 :     bNoDataSet = TRUE;
     211                 : 
     212               2 :     return CE_None;
     213                 : }
     214                 : 
     215                 : /************************************************************************/
     216                 : /*                       GetColorInterpretation()                       */
     217                 : /************************************************************************/
     218                 : 
     219             262 : GDALColorInterp MEMRasterBand::GetColorInterpretation()
     220                 : 
     221                 : {
     222             262 :     if( poColorTable != NULL )
     223               1 :         return GCI_PaletteIndex;
     224                 :     else
     225             261 :         return eColorInterp;
     226                 : }
     227                 : 
     228                 : /************************************************************************/
     229                 : /*                       SetColorInterpretation()                       */
     230                 : /************************************************************************/
     231                 : 
     232              76 : CPLErr MEMRasterBand::SetColorInterpretation( GDALColorInterp eGCI )
     233                 : 
     234                 : {
     235              76 :     eColorInterp = eGCI;
     236                 : 
     237              76 :     return CE_None;
     238                 : }
     239                 : 
     240                 : /************************************************************************/
     241                 : /*                           GetColorTable()                            */
     242                 : /************************************************************************/
     243                 : 
     244             191 : GDALColorTable *MEMRasterBand::GetColorTable()
     245                 : 
     246                 : {
     247             191 :     return poColorTable;
     248                 : }
     249                 : 
     250                 : /************************************************************************/
     251                 : /*                           SetColorTable()                            */
     252                 : /************************************************************************/
     253                 : 
     254               2 : CPLErr MEMRasterBand::SetColorTable( GDALColorTable *poCT )
     255                 : 
     256                 : {
     257               2 :     if( poColorTable != NULL )
     258               0 :         delete poColorTable;
     259                 : 
     260               2 :     if( poCT == NULL )
     261               0 :         poColorTable = NULL;
     262                 :     else
     263               2 :         poColorTable = poCT->Clone();
     264                 : 
     265               2 :     return CE_None;
     266                 : }
     267                 : 
     268                 : /************************************************************************/
     269                 : /*                            GetUnitType()                             */
     270                 : /************************************************************************/
     271                 : 
     272             165 : const char *MEMRasterBand::GetUnitType()
     273                 : 
     274                 : {
     275             165 :     if( pszUnitType == NULL )
     276             162 :         return "";
     277                 :     else
     278               3 :         return pszUnitType;
     279                 : }
     280                 : 
     281                 : /************************************************************************/
     282                 : /*                            SetUnitType()                             */
     283                 : /************************************************************************/
     284                 : 
     285               1 : CPLErr MEMRasterBand::SetUnitType( const char *pszNewValue )
     286                 : 
     287                 : {
     288               1 :     CPLFree( pszUnitType );
     289                 :     
     290               1 :     if( pszNewValue == NULL )
     291               0 :         pszUnitType = NULL;
     292                 :     else
     293               1 :         pszUnitType = CPLStrdup(pszNewValue);
     294                 : 
     295               1 :     return CE_None;
     296                 : }
     297                 : 
     298                 : /************************************************************************/
     299                 : /*                             GetOffset()                              */
     300                 : /************************************************************************/
     301                 : 
     302             165 : double MEMRasterBand::GetOffset( int *pbSuccess )
     303                 : 
     304                 : {
     305             165 :     if( pbSuccess != NULL )
     306             128 :         *pbSuccess = TRUE;
     307                 : 
     308             165 :     return dfOffset;
     309                 : }
     310                 : 
     311                 : /************************************************************************/
     312                 : /*                             SetOffset()                              */
     313                 : /************************************************************************/
     314                 : 
     315               1 : CPLErr MEMRasterBand::SetOffset( double dfNewOffset )
     316                 : 
     317                 : {
     318               1 :     dfOffset = dfNewOffset;
     319               1 :     return CE_None;
     320                 : }
     321                 : 
     322                 : /************************************************************************/
     323                 : /*                              GetScale()                              */
     324                 : /************************************************************************/
     325                 : 
     326             165 : double MEMRasterBand::GetScale( int *pbSuccess )
     327                 : 
     328                 : {
     329             165 :     if( pbSuccess != NULL )
     330             128 :         *pbSuccess = TRUE;
     331                 : 
     332             165 :     return dfScale;
     333                 : }
     334                 : 
     335                 : /************************************************************************/
     336                 : /*                              SetScale()                              */
     337                 : /************************************************************************/
     338                 : 
     339               1 : CPLErr MEMRasterBand::SetScale( double dfNewScale )
     340                 : 
     341                 : {
     342               1 :     dfScale = dfNewScale;
     343               1 :     return CE_None;
     344                 : }
     345                 : 
     346                 : /************************************************************************/
     347                 : /*                          GetCategoryNames()                          */
     348                 : /************************************************************************/
     349                 : 
     350             164 : char **MEMRasterBand::GetCategoryNames()
     351                 : 
     352                 : {
     353             164 :     return papszCategoryNames;
     354                 : }
     355                 : 
     356                 : /************************************************************************/
     357                 : /*                          SetCategoryNames()                          */
     358                 : /************************************************************************/
     359                 : 
     360               1 : CPLErr MEMRasterBand::SetCategoryNames( char ** papszNewNames )
     361                 : 
     362                 : {
     363               1 :     CSLDestroy( papszCategoryNames );
     364               1 :     papszCategoryNames = CSLDuplicate( papszNewNames );
     365                 : 
     366               1 :     return CE_None;
     367                 : }
     368                 : 
     369                 : /************************************************************************/
     370                 : /*                        SetDefaultHistogram()                         */
     371                 : /************************************************************************/
     372                 : 
     373               3 : CPLErr MEMRasterBand::SetDefaultHistogram( double dfMin, double dfMax, 
     374                 :                                            int nBuckets, int *panHistogram)
     375                 : 
     376                 : {
     377                 :     CPLXMLNode *psNode;
     378                 : 
     379                 : /* -------------------------------------------------------------------- */
     380                 : /*      Do we have a matching histogram we should replace?              */
     381                 : /* -------------------------------------------------------------------- */
     382                 :     psNode = PamFindMatchingHistogram( psSavedHistograms, 
     383                 :                                        dfMin, dfMax, nBuckets,
     384               3 :                                        TRUE, TRUE );
     385               3 :     if( psNode != NULL )
     386                 :     {
     387                 :         /* blow this one away */
     388               1 :         CPLRemoveXMLChild( psSavedHistograms, psNode );
     389               1 :         CPLDestroyXMLNode( psNode );
     390                 :     }
     391                 : 
     392                 : /* -------------------------------------------------------------------- */
     393                 : /*      Translate into a histogram XML tree.                            */
     394                 : /* -------------------------------------------------------------------- */
     395                 :     CPLXMLNode *psHistItem;
     396                 : 
     397                 :     psHistItem = PamHistogramToXMLTree( dfMin, dfMax, nBuckets, 
     398               3 :                                         panHistogram, TRUE, FALSE );
     399                 : 
     400                 : /* -------------------------------------------------------------------- */
     401                 : /*      Insert our new default histogram at the front of the            */
     402                 : /*      histogram list so that it will be the default histogram.        */
     403                 : /* -------------------------------------------------------------------- */
     404                 : 
     405               3 :     if( psSavedHistograms == NULL )
     406                 :         psSavedHistograms = CPLCreateXMLNode( NULL, CXT_Element,
     407               1 :                                               "Histograms" );
     408                 :             
     409               3 :     psHistItem->psNext = psSavedHistograms->psChild;
     410               3 :     psSavedHistograms->psChild = psHistItem;
     411                 :     
     412               3 :     return CE_None;
     413                 : }
     414                 : /************************************************************************/
     415                 : /*                        GetDefaultHistogram()                         */
     416                 : /************************************************************************/
     417                 : 
     418                 : CPLErr 
     419               1 : MEMRasterBand::GetDefaultHistogram( double *pdfMin, double *pdfMax, 
     420                 :                                     int *pnBuckets, int **ppanHistogram, 
     421                 :                                     int bForce,
     422                 :                                     GDALProgressFunc pfnProgress, 
     423                 :                                     void *pProgressData )
     424                 :     
     425                 : {
     426               1 :     if( psSavedHistograms != NULL )
     427                 :     {
     428                 :         CPLXMLNode *psXMLHist;
     429                 : 
     430               2 :         for( psXMLHist = psSavedHistograms->psChild;
     431                 :              psXMLHist != NULL; psXMLHist = psXMLHist->psNext )
     432                 :         {
     433                 :             int bApprox, bIncludeOutOfRange;
     434                 : 
     435               1 :             if( psXMLHist->eType != CXT_Element
     436                 :                 || !EQUAL(psXMLHist->pszValue,"HistItem") )
     437               0 :                 continue;
     438                 : 
     439               1 :             if( PamParseHistogram( psXMLHist, pdfMin, pdfMax, pnBuckets, 
     440                 :                                    ppanHistogram, &bIncludeOutOfRange,
     441                 :                                    &bApprox ) )
     442               1 :                 return CE_None;
     443                 :             else
     444               0 :                 return CE_Failure;
     445                 :         }
     446                 :     }
     447                 : 
     448                 :     return GDALRasterBand::GetDefaultHistogram( pdfMin, pdfMax, pnBuckets, 
     449                 :                                                 ppanHistogram, bForce, 
     450               0 :                                                 pfnProgress,pProgressData);
     451                 : }
     452                 : 
     453                 : /************************************************************************/
     454                 : /* ==================================================================== */
     455                 : /*      MEMDataset                                                     */
     456                 : /* ==================================================================== */
     457                 : /************************************************************************/
     458                 : 
     459                 : 
     460                 : /************************************************************************/
     461                 : /*                            MEMDataset()                             */
     462                 : /************************************************************************/
     463                 : 
     464            5252 : MEMDataset::MEMDataset()
     465                 : 
     466                 : {
     467            5252 :     pszProjection = NULL;
     468            5252 :     bGeoTransformSet = FALSE;
     469            5252 :     adfGeoTransform[0] = 0.0;
     470            5252 :     adfGeoTransform[1] = 1.0;
     471            5252 :     adfGeoTransform[2] = 0.0;
     472            5252 :     adfGeoTransform[3] = 0.0;
     473            5252 :     adfGeoTransform[4] = 0.0;
     474            5252 :     adfGeoTransform[5] = -1.0;
     475                 : 
     476            5252 :     nGCPCount = 0;
     477            5252 :     pasGCPs = NULL;
     478            5252 : }
     479                 : 
     480                 : /************************************************************************/
     481                 : /*                            ~MEMDataset()                            */
     482                 : /************************************************************************/
     483                 : 
     484            5252 : MEMDataset::~MEMDataset()
     485                 : 
     486                 : {
     487            5252 :     FlushCache();
     488            5252 :     CPLFree( pszProjection );
     489                 : 
     490            5252 :     GDALDeinitGCPs( nGCPCount, pasGCPs );
     491            5252 :     CPLFree( pasGCPs );
     492            5252 : }
     493                 : 
     494                 : /************************************************************************/
     495                 : /*                          GetProjectionRef()                          */
     496                 : /************************************************************************/
     497                 : 
     498              90 : const char *MEMDataset::GetProjectionRef()
     499                 : 
     500                 : {
     501              90 :     if( pszProjection == NULL )
     502              81 :         return "";
     503                 :     else
     504               9 :         return pszProjection;
     505                 : }
     506                 : 
     507                 : /************************************************************************/
     508                 : /*                           SetProjection()                            */
     509                 : /************************************************************************/
     510                 : 
     511              83 : CPLErr MEMDataset::SetProjection( const char *pszProjectionIn )
     512                 : 
     513                 : {
     514              83 :     CPLFree( pszProjection );
     515              83 :     pszProjection = CPLStrdup( pszProjectionIn );
     516                 : 
     517              83 :     return CE_None;
     518                 : }
     519                 : 
     520                 : /************************************************************************/
     521                 : /*                          GetGeoTransform()                           */
     522                 : /************************************************************************/
     523                 : 
     524             164 : CPLErr MEMDataset::GetGeoTransform( double *padfGeoTransform )
     525                 : 
     526                 : {
     527             164 :     memcpy( padfGeoTransform, adfGeoTransform, sizeof(double) * 6 );
     528             164 :     if( bGeoTransformSet )
     529              87 :         return CE_None;
     530                 :     else
     531              77 :         return CE_Failure;
     532                 : }
     533                 : 
     534                 : /************************************************************************/
     535                 : /*                          SetGeoTransform()                           */
     536                 : /************************************************************************/
     537                 : 
     538              96 : CPLErr MEMDataset::SetGeoTransform( double *padfGeoTransform )
     539                 : 
     540                 : {
     541              96 :     memcpy( adfGeoTransform, padfGeoTransform, sizeof(double) * 6 );
     542              96 :     bGeoTransformSet = TRUE;
     543                 : 
     544              96 :     return CE_None;
     545                 : }
     546                 : 
     547                 : /************************************************************************/
     548                 : /*                          GetInternalHandle()                         */
     549                 : /************************************************************************/
     550                 : 
     551               0 : void *MEMDataset::GetInternalHandle( const char * pszRequest)
     552                 : 
     553                 : {
     554                 :     // check for MEMORYnnn string in pszRequest (nnnn can be up to 10 
     555                 :     // digits, or even omitted)
     556               0 :     if( EQUALN(pszRequest,"MEMORY",6))
     557                 :     {
     558               0 :         if(int BandNumber = CPLScanLong(&pszRequest[6], 10))
     559                 :         {
     560                 :             MEMRasterBand *RequestedRasterBand = 
     561               0 :                 (MEMRasterBand *)GetRasterBand(BandNumber);
     562                 : 
     563                 :             // we're within a MEMDataset so the only thing a RasterBand 
     564                 :             // could be is a MEMRasterBand
     565                 : 
     566               0 :             if( RequestedRasterBand != NULL )
     567                 :             {
     568                 :                 // return the internal band data pointer
     569               0 :                 return(RequestedRasterBand->GetData());
     570                 :             }
     571                 :         }
     572                 :     }
     573                 : 
     574               0 :     return NULL;
     575                 : }
     576                 : /************************************************************************/
     577                 : /*                            GetGCPCount()                             */
     578                 : /************************************************************************/
     579                 : 
     580              81 : int MEMDataset::GetGCPCount()
     581                 : 
     582                 : {
     583              81 :     return nGCPCount;
     584                 : }
     585                 : 
     586                 : /************************************************************************/
     587                 : /*                          GetGCPProjection()                          */
     588                 : /************************************************************************/
     589                 : 
     590               1 : const char *MEMDataset::GetGCPProjection()
     591                 : 
     592                 : {
     593               1 :     return osGCPProjection;
     594                 : }
     595                 : 
     596                 : /************************************************************************/
     597                 : /*                              GetGCPs()                               */
     598                 : /************************************************************************/
     599                 : 
     600               1 : const GDAL_GCP *MEMDataset::GetGCPs()
     601                 : 
     602                 : {
     603               1 :     return pasGCPs;
     604                 : }
     605                 : 
     606                 : /************************************************************************/
     607                 : /*                              SetGCPs()                               */
     608                 : /************************************************************************/
     609                 : 
     610               5 : CPLErr MEMDataset::SetGCPs( int nNewCount, const GDAL_GCP *pasNewGCPList,
     611                 :                             const char *pszGCPProjection )
     612                 : 
     613                 : {
     614               5 :     GDALDeinitGCPs( nGCPCount, pasGCPs );
     615               5 :     CPLFree( pasGCPs );
     616                 : 
     617               5 :     if( pszGCPProjection == NULL )
     618               0 :         osGCPProjection = "";
     619                 :     else
     620               5 :         osGCPProjection = pszGCPProjection;
     621                 : 
     622               5 :     nGCPCount = nNewCount;
     623               5 :     pasGCPs = GDALDuplicateGCPs( nGCPCount, pasNewGCPList );
     624                 : 
     625               5 :     return CE_None;
     626                 : }
     627                 : 
     628                 : /************************************************************************/
     629                 : /*                              AddBand()                               */
     630                 : /*                                                                      */
     631                 : /*      Add a new band to the dataset, allowing creation options to     */
     632                 : /*      specify the existing memory to use, otherwise create new        */
     633                 : /*      memory.                                                         */
     634                 : /************************************************************************/
     635                 : 
     636             278 : CPLErr MEMDataset::AddBand( GDALDataType eType, char **papszOptions )
     637                 : 
     638                 : {
     639             278 :     int nBandId = GetRasterCount() + 1;
     640                 :     GByte *pData;
     641             278 :     int   nPixelSize = (GDALGetDataTypeSize(eType) / 8);
     642                 : 
     643                 : /* -------------------------------------------------------------------- */
     644                 : /*      Do we need to allocate the memory ourselves?  This is the       */
     645                 : /*      simple case.                                                    */
     646                 : /* -------------------------------------------------------------------- */
     647             278 :     if( CSLFetchNameValue( papszOptions, "DATAPOINTER" ) == NULL )
     648                 :     {
     649                 : 
     650                 :         pData = (GByte *) 
     651               8 :             VSICalloc(nPixelSize * GetRasterXSize(), GetRasterYSize() );
     652                 : 
     653               8 :         if( pData == NULL )
     654                 :         {
     655                 :             CPLError( CE_Failure, CPLE_OutOfMemory,
     656               0 :                       "Unable to create band arrays ... out of memory." );
     657               0 :             return CE_Failure;
     658                 :         }
     659                 : 
     660                 :         SetBand( nBandId,
     661                 :                  new MEMRasterBand( this, nBandId, pData, eType, nPixelSize, 
     662               8 :                                     nPixelSize * GetRasterXSize(), TRUE ) );
     663                 : 
     664               8 :         return CE_None;
     665                 :     }
     666                 : 
     667                 : /* -------------------------------------------------------------------- */
     668                 : /*      Get layout of memory and other flags.                           */
     669                 : /* -------------------------------------------------------------------- */
     670                 :     const char *pszOption;
     671                 :     int nPixelOffset, nLineOffset;
     672                 :     const char *pszDataPointer;
     673                 : 
     674             270 :     pszDataPointer = CSLFetchNameValue(papszOptions,"DATAPOINTER");
     675                 :     pData = (GByte *) CPLScanPointer(pszDataPointer,
     676             270 :                                      strlen(pszDataPointer));
     677                 :     
     678             270 :     pszOption = CSLFetchNameValue(papszOptions,"PIXELOFFSET");
     679             270 :     if( pszOption == NULL )
     680             270 :         nPixelOffset = nPixelSize;
     681                 :     else
     682               0 :         nPixelOffset = atoi(pszOption);
     683                 : 
     684             270 :     pszOption = CSLFetchNameValue(papszOptions,"LINEOFFSET");
     685             270 :     if( pszOption == NULL )
     686             270 :         nLineOffset = GetRasterXSize() * nPixelOffset;
     687                 :     else
     688               0 :         nLineOffset = atoi(pszOption);
     689                 : 
     690                 :     SetBand( nBandId,
     691                 :              new MEMRasterBand( this, nBandId, pData, eType, 
     692             270 :                                 nPixelOffset, nLineOffset, FALSE ) );
     693                 : 
     694             270 :     return CE_None;
     695                 : }
     696                 : 
     697                 : /************************************************************************/
     698                 : /*                                Open()                                */
     699                 : /************************************************************************/
     700                 : 
     701            3635 : GDALDataset *MEMDataset::Open( GDALOpenInfo * poOpenInfo )
     702                 : 
     703                 : {
     704                 :     char    **papszOptions;
     705                 : 
     706                 : /* -------------------------------------------------------------------- */
     707                 : /*      Do we have the special filename signature for MEM format        */
     708                 : /*      description strings?                                            */
     709                 : /* -------------------------------------------------------------------- */
     710            3635 :     if( !EQUALN(poOpenInfo->pszFilename,"MEM:::",6) 
     711                 :         || poOpenInfo->fp != NULL )
     712            3632 :         return NULL;
     713                 : 
     714                 :     papszOptions = CSLTokenizeStringComplex(poOpenInfo->pszFilename+6, ",",
     715               3 :                                             TRUE, FALSE );
     716                 : 
     717                 : /* -------------------------------------------------------------------- */
     718                 : /*      Verify we have all required fields                              */
     719                 : /* -------------------------------------------------------------------- */
     720               3 :     if( CSLFetchNameValue( papszOptions, "PIXELS" ) == NULL
     721                 :         || CSLFetchNameValue( papszOptions, "LINES" ) == NULL
     722                 :         || CSLFetchNameValue( papszOptions, "DATAPOINTER" ) == NULL )
     723                 :     {
     724                 :         CPLError( CE_Failure, CPLE_AppDefined, 
     725                 :               "Missing required field (one of PIXELS, LINES or DATAPOINTER)\n"
     726               1 :               "Unable to access in-memory array." );
     727                 : 
     728               1 :         CSLDestroy( papszOptions );
     729               1 :         return NULL;
     730                 :     }
     731                 : 
     732                 : /* -------------------------------------------------------------------- */
     733                 : /*      Create the new MEMDataset object.                               */
     734                 : /* -------------------------------------------------------------------- */
     735                 :     MEMDataset *poDS;
     736                 : 
     737               2 :     poDS = new MEMDataset();
     738                 : 
     739               2 :     poDS->nRasterXSize = atoi(CSLFetchNameValue(papszOptions,"PIXELS"));
     740               2 :     poDS->nRasterYSize = atoi(CSLFetchNameValue(papszOptions,"LINES"));
     741               2 :     poDS->eAccess = GA_Update;
     742                 : 
     743                 : /* -------------------------------------------------------------------- */
     744                 : /*      Extract other information.                                      */
     745                 : /* -------------------------------------------------------------------- */
     746                 :     const char *pszOption;
     747                 :     GDALDataType eType;
     748                 :     int nBands, nPixelOffset, nLineOffset;
     749                 :     size_t nBandOffset;
     750                 :     const char *pszDataPointer;
     751                 :     GByte *pabyData;
     752                 : 
     753               2 :     pszOption = CSLFetchNameValue(papszOptions,"BANDS");
     754               2 :     if( pszOption == NULL )
     755               1 :         nBands = 1;
     756                 :     else
     757                 :     {
     758               1 :         nBands = atoi(pszOption);
     759                 :     }
     760                 : 
     761               2 :     if (!GDALCheckDatasetDimensions(poDS->nRasterXSize, poDS->nRasterYSize) ||
     762                 :         !GDALCheckBandCount(nBands, TRUE))
     763                 :     {
     764               0 :         CSLDestroy( papszOptions );
     765               0 :         delete poDS;
     766               0 :         return NULL;
     767                 :     }
     768                 : 
     769               2 :     pszOption = CSLFetchNameValue(papszOptions,"DATATYPE");
     770               2 :     if( pszOption == NULL )
     771               0 :         eType = GDT_Byte;
     772                 :     else
     773                 :     {
     774               2 :         if( atoi(pszOption) > 0 && atoi(pszOption) < GDT_TypeCount )
     775               0 :             eType = (GDALDataType) atoi(pszOption);
     776                 :         else
     777                 :         {
     778                 :             int iType;
     779                 :             
     780               2 :             eType = GDT_Unknown;
     781              14 :             for( iType = 0; iType < GDT_TypeCount; iType++ )
     782                 :             {
     783              14 :                 if( EQUAL(GDALGetDataTypeName((GDALDataType) iType),
     784                 :                           pszOption) )
     785                 :                 {
     786               2 :                     eType = (GDALDataType) iType;
     787               2 :                     break;
     788                 :                 }
     789                 :             }
     790                 :             
     791               2 :             if( eType == GDT_Unknown )
     792                 :             {
     793                 :                 CPLError( CE_Failure, CPLE_AppDefined,
     794                 :                           "DATATYPE=%s not recognised.", 
     795               0 :                           pszOption );
     796               0 :                 CSLDestroy( papszOptions );
     797               0 :                 delete poDS;
     798               0 :                 return NULL;
     799                 :             }
     800                 :         }
     801                 :     }
     802                 : 
     803               2 :     pszOption = CSLFetchNameValue(papszOptions,"PIXELOFFSET");
     804               2 :     if( pszOption == NULL )
     805               1 :         nPixelOffset = GDALGetDataTypeSize(eType) / 8;
     806                 :     else
     807               1 :         nPixelOffset = atoi(pszOption);
     808                 : 
     809               2 :     pszOption = CSLFetchNameValue(papszOptions,"LINEOFFSET");
     810               2 :     if( pszOption == NULL )
     811               1 :         nLineOffset = poDS->nRasterXSize * nPixelOffset;
     812                 :     else
     813               1 :         nLineOffset = atoi(pszOption);
     814                 : 
     815               2 :     pszOption = CSLFetchNameValue(papszOptions,"BANDOFFSET");
     816               2 :     if( pszOption == NULL )
     817               1 :         nBandOffset = nLineOffset * (size_t) poDS->nRasterYSize;
     818                 :     else
     819               1 :         nBandOffset = atoi(pszOption);
     820                 : 
     821               2 :     pszDataPointer = CSLFetchNameValue(papszOptions,"DATAPOINTER");
     822                 :     pabyData = (GByte *) CPLScanPointer( pszDataPointer, 
     823               2 :                                          strlen(pszDataPointer) );
     824                 : 
     825                 : /* -------------------------------------------------------------------- */
     826                 : /*      Create band information objects.                                */
     827                 : /* -------------------------------------------------------------------- */
     828               8 :     for( int iBand = 0; iBand < nBands; iBand++ )
     829                 :     {
     830                 :         poDS->SetBand( iBand+1, 
     831                 :                        new MEMRasterBand( poDS, iBand+1, 
     832                 :                                           pabyData + iBand * nBandOffset,
     833                 :                                           eType, nPixelOffset, nLineOffset, 
     834               2 :                                           FALSE ) );
     835                 :     }
     836                 : 
     837                 : /* -------------------------------------------------------------------- */
     838                 : /*      Try to return a regular handle on the file.                     */
     839                 : /* -------------------------------------------------------------------- */
     840               2 :     CSLDestroy( papszOptions );
     841               2 :     return poDS;
     842                 : }
     843                 : 
     844                 : /************************************************************************/
     845                 : /*                               Create()                               */
     846                 : /************************************************************************/
     847                 : 
     848            5252 : GDALDataset *MEMDataset::Create( const char * pszFilename,
     849                 :                                  int nXSize, int nYSize, int nBands,
     850                 :                                  GDALDataType eType,
     851                 :                                  char **papszOptions )
     852                 : 
     853                 : {
     854                 : 
     855                 : /* -------------------------------------------------------------------- */
     856                 : /*      Do we want a pixel interleaved buffer?  I mostly care about     */
     857                 : /*      this to test pixel interleaved io in other contexts, but it     */
     858                 : /*      could be useful to create a directly accessable buffer for      */
     859                 : /*      some apps.                                                      */
     860                 : /* -------------------------------------------------------------------- */
     861            5252 :     int bPixelInterleaved = FALSE;
     862            5252 :     const char *pszOption = CSLFetchNameValue( papszOptions, "INTERLEAVE" );
     863            5252 :     if( pszOption && EQUAL(pszOption,"PIXEL") )
     864               3 :         bPixelInterleaved = TRUE;
     865                 :         
     866                 : /* -------------------------------------------------------------------- */
     867                 : /*      First allocate band data, verifying that we can get enough      */
     868                 : /*      memory.                                                         */
     869                 : /* -------------------------------------------------------------------- */
     870            5252 :     std::vector<GByte*> apbyBandData;
     871                 :     int     iBand;
     872            5252 :     int         nWordSize = GDALGetDataTypeSize(eType) / 8;
     873            5252 :     int         bAllocOK = TRUE;
     874                 : 
     875            5252 :     if( bPixelInterleaved )
     876                 :     {
     877                 :         apbyBandData.push_back( 
     878               3 :             (GByte *) VSIMalloc3( nWordSize * nBands, nXSize, nYSize ) );
     879                 : 
     880               3 :         if( apbyBandData[0] == NULL )
     881               1 :             bAllocOK = FALSE;
     882                 :         else
     883                 :     {
     884               2 :             memset(apbyBandData[0], 0, ((size_t)nWordSize) * nBands * nXSize * nYSize);
     885               6 :             for( iBand = 1; iBand < nBands; iBand++ )
     886               4 :                 apbyBandData.push_back( apbyBandData[0] + iBand * nWordSize );
     887                 :         }
     888                 :     }
     889                 :         else
     890                 :         {
     891           10473 :             for( iBand = 0; iBand < nBands; iBand++ )
     892                 :             {
     893                 :             apbyBandData.push_back( 
     894            5225 :                 (GByte *) VSIMalloc3( nWordSize, nXSize, nYSize ) );
     895            5225 :             if( apbyBandData[iBand] == NULL )
     896                 :             {
     897               1 :                 bAllocOK = FALSE;
     898               1 :                 break;
     899                 :             }
     900            5224 :             memset(apbyBandData[iBand], 0, ((size_t)nWordSize) * nXSize * nYSize);
     901                 :         }
     902                 :             }
     903                 : 
     904            5252 :     if( !bAllocOK )
     905                 :     {
     906               4 :         for( iBand = 0; iBand < (int) apbyBandData.size(); iBand++ )
     907                 :         {
     908               2 :             if( apbyBandData[iBand] )
     909               0 :                 VSIFree( apbyBandData[iBand] );
     910                 :         }
     911                 :             CPLError( CE_Failure, CPLE_OutOfMemory,
     912               2 :                       "Unable to create band arrays ... out of memory." );
     913               2 :             return NULL;
     914                 :         }
     915                 : 
     916                 : /* -------------------------------------------------------------------- */
     917                 : /*      Create the new GTiffDataset object.                             */
     918                 : /* -------------------------------------------------------------------- */
     919                 :     MEMDataset *poDS;
     920                 : 
     921            5250 :     poDS = new MEMDataset();
     922                 : 
     923            5250 :     poDS->nRasterXSize = nXSize;
     924            5250 :     poDS->nRasterYSize = nYSize;
     925            5250 :     poDS->eAccess = GA_Update;
     926                 : 
     927           10500 :     const char *pszPixelType = CSLFetchNameValue( papszOptions, "PIXELTYPE" );
     928            5250 :     if( pszPixelType && EQUAL(pszPixelType,"SIGNEDBYTE") )
     929               0 :         poDS->SetMetadataItem( "PIXELTYPE", "SIGNEDBYTE", "IMAGE_STRUCTURE" );
     930                 : 
     931            5250 :     if( bPixelInterleaved )
     932               2 :         poDS->SetMetadataItem( "INTERLEAVE", "PIXEL", "IMAGE_STRUCTURE" );
     933                 : 
     934                 : /* -------------------------------------------------------------------- */
     935                 : /*      Create band information objects.                                */
     936                 : /* -------------------------------------------------------------------- */
     937           10480 :     for( iBand = 0; iBand < nBands; iBand++ )
     938                 :     {
     939                 :         MEMRasterBand *poNewBand;
     940                 : 
     941            5230 :         if( bPixelInterleaved )
     942                 :             poNewBand = new MEMRasterBand( poDS, iBand+1, apbyBandData[iBand],
     943                 :                                            eType, nWordSize * nBands, 0, 
     944               6 :                                            iBand == 0 );
     945                 :         else
     946                 :             poNewBand = new MEMRasterBand( poDS, iBand+1, apbyBandData[iBand],
     947            5224 :                                            eType, 0, 0, TRUE );
     948                 : 
     949            5230 :         poDS->SetBand( iBand+1, poNewBand );
     950                 :     }
     951                 : 
     952                 : /* -------------------------------------------------------------------- */
     953                 : /*      Try to return a regular handle on the file.                     */
     954                 : /* -------------------------------------------------------------------- */
     955            5250 :     return poDS;
     956                 : }
     957                 : 
     958                 : /************************************************************************/
     959                 : /*                     MEMDatasetIdentify()                             */
     960                 : /************************************************************************/
     961                 : 
     962           10205 : static int MEMDatasetIdentify( GDALOpenInfo * poOpenInfo )
     963                 : {
     964                 :     return (strncmp(poOpenInfo->pszFilename, "MEM:::", 6) == 0 &&
     965           10205 :             poOpenInfo->fp == NULL);
     966                 : }
     967                 : 
     968                 : /************************************************************************/
     969                 : /*                       MEMDatasetDelete()                             */
     970                 : /************************************************************************/
     971                 : 
     972             127 : static CPLErr MEMDatasetDelete(const char* fileName)
     973                 : {
     974                 :     /* Null implementation, so that people can Delete("MEM:::") */
     975             127 :     return CE_None;
     976                 : }
     977                 : 
     978                 : /************************************************************************/
     979                 : /*                          GDALRegister_MEM()                          */
     980                 : /************************************************************************/
     981                 : 
     982             582 : void GDALRegister_MEM()
     983                 : 
     984                 : {
     985                 :     GDALDriver  *poDriver;
     986                 : 
     987             582 :     if( GDALGetDriverByName( "MEM" ) == NULL )
     988                 :     {
     989             561 :         poDriver = new GDALDriver();
     990                 :         
     991             561 :         poDriver->SetDescription( "MEM" );
     992                 :         poDriver->SetMetadataItem( GDAL_DMD_LONGNAME, 
     993             561 :                                    "In Memory Raster" );
     994                 :         poDriver->SetMetadataItem( GDAL_DMD_CREATIONDATATYPES, 
     995             561 :                                    "Byte Int16 UInt16 Int32 UInt32 Float32 Float64 CInt16 CInt32 CFloat32 CFloat64" );
     996                 : 
     997                 :         poDriver->SetMetadataItem( GDAL_DMD_CREATIONOPTIONLIST, 
     998                 : "<CreationOptionList>"
     999                 : "   <Option name='INTERLEAVE' type='string-select' default='BAND'>"
    1000                 : "       <Value>BAND</Value>"
    1001                 : "       <Value>PIXEL</Value>"
    1002                 : "   </Option>"
    1003             561 : "</CreationOptionList>" );
    1004                 : 
    1005                 : /* Define GDAL_NO_OPEN_FOR_MEM_DRIVER macro to undefine Open() method for MEM driver. */
    1006                 : /* Otherwise, bad user input can trigger easily a GDAL crash as random pointers can be passed as a string. */
    1007                 : /* All code in GDAL tree using the MEM driver use the Create() method only, so Open() */
    1008                 : /* is not needed, except for esoteric uses */
    1009                 : #ifndef GDAL_NO_OPEN_FOR_MEM_DRIVER
    1010             561 :         poDriver->pfnOpen = MEMDataset::Open;
    1011             561 :         poDriver->pfnIdentify = MEMDatasetIdentify;
    1012                 : #endif
    1013             561 :         poDriver->pfnCreate = MEMDataset::Create;
    1014             561 :         poDriver->pfnDelete = MEMDatasetDelete;
    1015                 : 
    1016             561 :         GetGDALDriverManager()->RegisterDriver( poDriver );
    1017                 :     }
    1018             582 : }
    1019                 : 

Generated by: LCOV version 1.7