LCOV - code coverage report
Current view: directory - frmts/mem - memdataset.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 280 148 52.9 %
Date: 2010-01-09 Functions: 38 24 63.2 %

       1                 : /******************************************************************************
       2                 :  * $Id: memdataset.cpp 17837 2009-10-15 21:20:09Z 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 17837 2009-10-15 21:20:09Z 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            5100 : MEMRasterBand::MEMRasterBand( GDALDataset *poDS, int nBand,
      55                 :                               GByte *pabyDataIn, GDALDataType eTypeIn, 
      56                 :                               int nPixelOffsetIn, int nLineOffsetIn,
      57            5100 :                               int bAssumeOwnership )
      58                 : 
      59                 : {
      60                 :     //CPLDebug( "MEM", "MEMRasterBand(%p)", this );
      61                 : 
      62            5100 :     this->poDS = poDS;
      63            5100 :     this->nBand = nBand;
      64                 : 
      65            5100 :     this->eAccess = poDS->GetAccess();
      66                 : 
      67            5100 :     eDataType = eTypeIn;
      68                 : 
      69            5100 :     nBlockXSize = poDS->GetRasterXSize();
      70            5100 :     nBlockYSize = 1;
      71                 : 
      72            5100 :     if( nPixelOffsetIn == 0 )
      73            5069 :         nPixelOffsetIn = GDALGetDataTypeSize(eTypeIn) / 8;
      74                 : 
      75            5100 :     if( nLineOffsetIn == 0 )
      76            5069 :         nLineOffsetIn = nPixelOffsetIn * nBlockXSize;
      77                 : 
      78            5100 :     nPixelOffset = nPixelOffsetIn;
      79            5100 :     nLineOffset = nLineOffsetIn;
      80            5100 :     bOwnData = bAssumeOwnership;
      81                 : 
      82            5100 :     pabyData = pabyDataIn;
      83                 : 
      84            5100 :     bNoDataSet  = FALSE;
      85                 : 
      86            5100 :     poColorTable = NULL;
      87                 :     
      88            5100 :     eColorInterp = GCI_Undefined;
      89                 : 
      90            5100 :     papszCategoryNames = NULL;
      91            5100 :     dfOffset = 0.0;
      92            5100 :     dfScale = 1.0;
      93            5100 :     pszUnitType = NULL;
      94            5100 : }
      95                 : 
      96                 : /************************************************************************/
      97                 : /*                           ~MEMRasterBand()                           */
      98                 : /************************************************************************/
      99                 : 
     100           10200 : MEMRasterBand::~MEMRasterBand()
     101                 : 
     102                 : {
     103                 :     //CPLDebug( "MEM", "~MEMRasterBand(%p)", this );
     104            5100 :     if( bOwnData )
     105                 :     {
     106                 :         //CPLDebug( "MEM", "~MEMRasterBand() - free raw data." );
     107            5071 :         VSIFree( pabyData );
     108                 :     }
     109                 : 
     110            5100 :     if( poColorTable != NULL )
     111               2 :         delete poColorTable;
     112                 : 
     113            5100 :     CPLFree( pszUnitType );
     114            5100 :     CSLDestroy( papszCategoryNames );
     115           10200 : }
     116                 : 
     117                 : 
     118                 : /************************************************************************/
     119                 : /*                             IReadBlock()                             */
     120                 : /************************************************************************/
     121                 : 
     122            4152 : CPLErr MEMRasterBand::IReadBlock( int nBlockXOff, int nBlockYOff,
     123                 :                                    void * pImage )
     124                 : 
     125                 : {
     126            4152 :     int     nWordSize = GDALGetDataTypeSize( eDataType ) / 8;
     127                 :     CPLAssert( nBlockXOff == 0 );
     128                 : 
     129            4152 :     if( nPixelOffset == nWordSize )
     130                 :     {
     131                 :         memcpy( pImage, 
     132                 :                 pabyData + nLineOffset*(size_t)nBlockYOff, 
     133            4152 :                 nPixelOffset * nBlockXSize );
     134                 :     }
     135                 :     else
     136                 :     {
     137               0 :         GByte *pabyCur = pabyData + nLineOffset * (size_t)nBlockYOff;
     138                 : 
     139               0 :         for( int iPixel = 0; iPixel < nBlockXSize; iPixel++ )
     140                 :         {
     141                 :             memcpy( ((GByte *) pImage) + iPixel*nWordSize, 
     142                 :                     pabyCur + iPixel*nPixelOffset, 
     143               0 :                     nWordSize );
     144                 :         }
     145                 :     }
     146                 : 
     147            4152 :     return CE_None;
     148                 : }
     149                 : 
     150                 : /************************************************************************/
     151                 : /*                            IWriteBlock()                             */
     152                 : /************************************************************************/
     153                 : 
     154            3754 : CPLErr MEMRasterBand::IWriteBlock( int nBlockXOff, int nBlockYOff,
     155                 :                                      void * pImage )
     156                 : 
     157                 : {
     158            3754 :     int     nWordSize = GDALGetDataTypeSize( eDataType ) / 8;
     159                 :     CPLAssert( nBlockXOff == 0 );
     160                 : 
     161            3754 :     if( nPixelOffset == nWordSize )
     162                 :     {
     163                 :         memcpy( pabyData+nLineOffset*(size_t)nBlockYOff, 
     164                 :                 pImage, 
     165            3754 :                 nPixelOffset * nBlockXSize );
     166                 :     }
     167                 :     else
     168                 :     {
     169               0 :         GByte *pabyCur = pabyData + nLineOffset*(size_t)nBlockYOff;
     170                 : 
     171               0 :         for( int iPixel = 0; iPixel < nBlockXSize; iPixel++ )
     172                 :         {
     173                 :             memcpy( pabyCur + iPixel*nPixelOffset, 
     174                 :                     ((GByte *) pImage) + iPixel*nWordSize, 
     175               0 :                     nWordSize );
     176                 :         }
     177                 :     }
     178                 : 
     179            3754 :     return CE_None;
     180                 : }
     181                 : 
     182                 : /************************************************************************/
     183                 : /*                            GetNoDataValue()                          */
     184                 : /************************************************************************/
     185               1 : double MEMRasterBand::GetNoDataValue( int *pbSuccess )
     186                 : 
     187                 : {
     188               1 :     if( pbSuccess )
     189               1 :         *pbSuccess = bNoDataSet;
     190                 : 
     191               1 :     if( bNoDataSet )
     192               1 :         return dfNoData;
     193                 :     else
     194               0 :         return 0.0;
     195                 : }
     196                 : 
     197                 : /************************************************************************/
     198                 : /*                            SetNoDataValue()                          */
     199                 : /************************************************************************/
     200               1 : CPLErr MEMRasterBand::SetNoDataValue( double dfNewValue )
     201                 : {
     202               1 :     dfNoData = dfNewValue;
     203               1 :     bNoDataSet = TRUE;
     204                 : 
     205               1 :     return CE_None;
     206                 : }
     207                 : 
     208                 : /************************************************************************/
     209                 : /*                       GetColorInterpretation()                       */
     210                 : /************************************************************************/
     211                 : 
     212              21 : GDALColorInterp MEMRasterBand::GetColorInterpretation()
     213                 : 
     214                 : {
     215              21 :     if( poColorTable != NULL )
     216               1 :         return GCI_PaletteIndex;
     217                 :     else
     218              20 :         return eColorInterp;
     219                 : }
     220                 : 
     221                 : /************************************************************************/
     222                 : /*                       SetColorInterpretation()                       */
     223                 : /************************************************************************/
     224                 : 
     225              20 : CPLErr MEMRasterBand::SetColorInterpretation( GDALColorInterp eGCI )
     226                 : 
     227                 : {
     228              20 :     eColorInterp = eGCI;
     229                 : 
     230              20 :     return CE_None;
     231                 : }
     232                 : 
     233                 : /************************************************************************/
     234                 : /*                           GetColorTable()                            */
     235                 : /************************************************************************/
     236                 : 
     237               0 : GDALColorTable *MEMRasterBand::GetColorTable()
     238                 : 
     239                 : {
     240               0 :     return poColorTable;
     241                 : }
     242                 : 
     243                 : /************************************************************************/
     244                 : /*                           SetColorTable()                            */
     245                 : /************************************************************************/
     246                 : 
     247               2 : CPLErr MEMRasterBand::SetColorTable( GDALColorTable *poCT )
     248                 : 
     249                 : {
     250               2 :     if( poColorTable != NULL )
     251               0 :         delete poColorTable;
     252                 : 
     253               2 :     if( poCT == NULL )
     254               0 :         poColorTable = NULL;
     255                 :     else
     256               2 :         poColorTable = poCT->Clone();
     257                 : 
     258               2 :     return CE_None;
     259                 : }
     260                 : 
     261                 : /************************************************************************/
     262                 : /*                            GetUnitType()                             */
     263                 : /************************************************************************/
     264                 : 
     265               0 : const char *MEMRasterBand::GetUnitType()
     266                 : 
     267                 : {
     268               0 :     if( pszUnitType == NULL )
     269               0 :         return "";
     270                 :     else
     271               0 :         return pszUnitType;
     272                 : }
     273                 : 
     274                 : /************************************************************************/
     275                 : /*                            SetUnitType()                             */
     276                 : /************************************************************************/
     277                 : 
     278               0 : CPLErr MEMRasterBand::SetUnitType( const char *pszNewValue )
     279                 : 
     280                 : {
     281               0 :     CPLFree( pszUnitType );
     282                 :     
     283               0 :     if( pszNewValue == NULL )
     284               0 :         pszUnitType = NULL;
     285                 :     else
     286               0 :         pszUnitType = CPLStrdup(pszNewValue);
     287                 : 
     288               0 :     return CE_None;
     289                 : }
     290                 : 
     291                 : /************************************************************************/
     292                 : /*                             GetOffset()                              */
     293                 : /************************************************************************/
     294                 : 
     295               0 : double MEMRasterBand::GetOffset( int *pbSuccess )
     296                 : 
     297                 : {
     298               0 :     if( pbSuccess != NULL )
     299               0 :         *pbSuccess = TRUE;
     300                 : 
     301               0 :     return dfOffset;
     302                 : }
     303                 : 
     304                 : /************************************************************************/
     305                 : /*                             SetOffset()                              */
     306                 : /************************************************************************/
     307                 : 
     308               0 : CPLErr MEMRasterBand::SetOffset( double dfNewOffset )
     309                 : 
     310                 : {
     311               0 :     dfOffset = dfNewOffset;
     312               0 :     return CE_None;
     313                 : }
     314                 : 
     315                 : /************************************************************************/
     316                 : /*                              GetScale()                              */
     317                 : /************************************************************************/
     318                 : 
     319               0 : double MEMRasterBand::GetScale( int *pbSuccess )
     320                 : 
     321                 : {
     322               0 :     if( pbSuccess != NULL )
     323               0 :         *pbSuccess = TRUE;
     324                 : 
     325               0 :     return dfScale;
     326                 : }
     327                 : 
     328                 : /************************************************************************/
     329                 : /*                              SetScale()                              */
     330                 : /************************************************************************/
     331                 : 
     332               0 : CPLErr MEMRasterBand::SetScale( double dfNewScale )
     333                 : 
     334                 : {
     335               0 :     dfScale = dfNewScale;
     336               0 :     return CE_None;
     337                 : }
     338                 : 
     339                 : /************************************************************************/
     340                 : /*                          GetCategoryNames()                          */
     341                 : /************************************************************************/
     342                 : 
     343               0 : char **MEMRasterBand::GetCategoryNames()
     344                 : 
     345                 : {
     346               0 :     return papszCategoryNames;
     347                 : }
     348                 : 
     349                 : /************************************************************************/
     350                 : /*                          SetCategoryNames()                          */
     351                 : /************************************************************************/
     352                 : 
     353               0 : CPLErr MEMRasterBand::SetCategoryNames( char ** papszNewNames )
     354                 : 
     355                 : {
     356               0 :     CSLDestroy( papszCategoryNames );
     357               0 :     papszCategoryNames = CSLDuplicate( papszNewNames );
     358                 : 
     359               0 :     return CE_None;
     360                 : }
     361                 : 
     362                 : /************************************************************************/
     363                 : /* ==================================================================== */
     364                 : /*      MEMDataset                                                     */
     365                 : /* ==================================================================== */
     366                 : /************************************************************************/
     367                 : 
     368                 : 
     369                 : /************************************************************************/
     370                 : /*                            MEMDataset()                             */
     371                 : /************************************************************************/
     372                 : 
     373            5060 : MEMDataset::MEMDataset()
     374                 : 
     375                 : {
     376            5060 :     pszProjection = NULL;
     377            5060 :     bGeoTransformSet = FALSE;
     378            5060 :     adfGeoTransform[0] = 0.0;
     379            5060 :     adfGeoTransform[1] = 1.0;
     380            5060 :     adfGeoTransform[2] = 0.0;
     381            5060 :     adfGeoTransform[3] = 0.0;
     382            5060 :     adfGeoTransform[4] = 0.0;
     383            5060 :     adfGeoTransform[5] = -1.0;
     384                 : 
     385            5060 :     nGCPCount = 0;
     386            5060 :     pasGCPs = NULL;
     387            5060 : }
     388                 : 
     389                 : /************************************************************************/
     390                 : /*                            ~MEMDataset()                            */
     391                 : /************************************************************************/
     392                 : 
     393           10120 : MEMDataset::~MEMDataset()
     394                 : 
     395                 : {
     396            5060 :     FlushCache();
     397            5060 :     CPLFree( pszProjection );
     398                 : 
     399            5060 :     GDALDeinitGCPs( nGCPCount, pasGCPs );
     400            5060 :     CPLFree( pasGCPs );
     401           10120 : }
     402                 : 
     403                 : /************************************************************************/
     404                 : /*                          GetProjectionRef()                          */
     405                 : /************************************************************************/
     406                 : 
     407               4 : const char *MEMDataset::GetProjectionRef()
     408                 : 
     409                 : {
     410               4 :     if( pszProjection == NULL )
     411               0 :         return "";
     412                 :     else
     413               4 :         return pszProjection;
     414                 : }
     415                 : 
     416                 : /************************************************************************/
     417                 : /*                           SetProjection()                            */
     418                 : /************************************************************************/
     419                 : 
     420              35 : CPLErr MEMDataset::SetProjection( const char *pszProjectionIn )
     421                 : 
     422                 : {
     423              35 :     CPLFree( pszProjection );
     424              35 :     pszProjection = CPLStrdup( pszProjectionIn );
     425                 : 
     426              35 :     return CE_None;
     427                 : }
     428                 : 
     429                 : /************************************************************************/
     430                 : /*                          GetGeoTransform()                           */
     431                 : /************************************************************************/
     432                 : 
     433              20 : CPLErr MEMDataset::GetGeoTransform( double *padfGeoTransform )
     434                 : 
     435                 : {
     436              20 :     memcpy( padfGeoTransform, adfGeoTransform, sizeof(double) * 6 );
     437              20 :     if( bGeoTransformSet )
     438              20 :         return CE_None;
     439                 :     else
     440               0 :         return CE_Failure;
     441                 : }
     442                 : 
     443                 : /************************************************************************/
     444                 : /*                          SetGeoTransform()                           */
     445                 : /************************************************************************/
     446                 : 
     447              41 : CPLErr MEMDataset::SetGeoTransform( double *padfGeoTransform )
     448                 : 
     449                 : {
     450              41 :     memcpy( adfGeoTransform, padfGeoTransform, sizeof(double) * 6 );
     451              41 :     bGeoTransformSet = TRUE;
     452                 : 
     453              41 :     return CE_None;
     454                 : }
     455                 : 
     456                 : /************************************************************************/
     457                 : /*                          GetInternalHandle()                         */
     458                 : /************************************************************************/
     459                 : 
     460               0 : void *MEMDataset::GetInternalHandle( const char * pszRequest)
     461                 : 
     462                 : {
     463                 :     // check for MEMORYnnn string in pszRequest (nnnn can be up to 10 
     464                 :     // digits, or even omitted)
     465               0 :     if( EQUALN(pszRequest,"MEMORY",6))
     466                 :     {
     467               0 :         if(int BandNumber = CPLScanLong(&pszRequest[6], 10))
     468                 :         {
     469                 :             MEMRasterBand *RequestedRasterBand = 
     470               0 :                 (MEMRasterBand *)GetRasterBand(BandNumber);
     471                 : 
     472                 :             // we're within a MEMDataset so the only thing a RasterBand 
     473                 :             // could be is a MEMRasterBand
     474                 : 
     475               0 :             if( RequestedRasterBand != NULL )
     476                 :             {
     477                 :                 // return the internal band data pointer
     478               0 :                 return(RequestedRasterBand->GetData());
     479                 :             }
     480                 :         }
     481                 :     }
     482                 : 
     483               0 :     return NULL;
     484                 : }
     485                 : /************************************************************************/
     486                 : /*                            GetGCPCount()                             */
     487                 : /************************************************************************/
     488                 : 
     489               0 : int MEMDataset::GetGCPCount()
     490                 : 
     491                 : {
     492               0 :     return nGCPCount;
     493                 : }
     494                 : 
     495                 : /************************************************************************/
     496                 : /*                          GetGCPProjection()                          */
     497                 : /************************************************************************/
     498                 : 
     499               0 : const char *MEMDataset::GetGCPProjection()
     500                 : 
     501                 : {
     502               0 :     return osGCPProjection;
     503                 : }
     504                 : 
     505                 : /************************************************************************/
     506                 : /*                              GetGCPs()                               */
     507                 : /************************************************************************/
     508                 : 
     509               0 : const GDAL_GCP *MEMDataset::GetGCPs()
     510                 : 
     511                 : {
     512               0 :     return pasGCPs;
     513                 : }
     514                 : 
     515                 : /************************************************************************/
     516                 : /*                              SetGCPs()                               */
     517                 : /************************************************************************/
     518                 : 
     519               0 : CPLErr MEMDataset::SetGCPs( int nNewCount, const GDAL_GCP *pasNewGCPList,
     520                 :                             const char *pszGCPProjection )
     521                 : 
     522                 : {
     523               0 :     GDALDeinitGCPs( nGCPCount, pasGCPs );
     524               0 :     CPLFree( pasGCPs );
     525                 : 
     526               0 :     if( pszGCPProjection == NULL )
     527               0 :         osGCPProjection = "";
     528                 :     else
     529               0 :         osGCPProjection = pszGCPProjection;
     530                 : 
     531               0 :     nGCPCount = nNewCount;
     532               0 :     pasGCPs = GDALDuplicateGCPs( nGCPCount, pasNewGCPList );
     533                 : 
     534               0 :     return CE_None;
     535                 : }
     536                 : 
     537                 : /************************************************************************/
     538                 : /*                              AddBand()                               */
     539                 : /*                                                                      */
     540                 : /*      Add a new band to the dataset, allowing creation options to     */
     541                 : /*      specify the existing memory to use, otherwise create new        */
     542                 : /*      memory.                                                         */
     543                 : /************************************************************************/
     544                 : 
     545              22 : CPLErr MEMDataset::AddBand( GDALDataType eType, char **papszOptions )
     546                 : 
     547                 : {
     548              22 :     int nBandId = GetRasterCount() + 1;
     549                 :     GByte *pData;
     550              22 :     int   nPixelSize = (GDALGetDataTypeSize(eType) / 8);
     551                 : 
     552                 : /* -------------------------------------------------------------------- */
     553                 : /*      Do we need to allocate the memory ourselves?  This is the       */
     554                 : /*      simple case.                                                    */
     555                 : /* -------------------------------------------------------------------- */
     556              22 :     if( CSLFetchNameValue( papszOptions, "DATAPOINTER" ) == NULL )
     557                 :     {
     558                 : 
     559                 :         pData = (GByte *) 
     560               0 :             VSICalloc(nPixelSize * GetRasterXSize(), GetRasterYSize() );
     561                 : 
     562               0 :         if( pData == NULL )
     563                 :         {
     564                 :             CPLError( CE_Failure, CPLE_OutOfMemory,
     565               0 :                       "Unable to create band arrays ... out of memory." );
     566               0 :             return CE_Failure;
     567                 :         }
     568                 : 
     569                 :         SetBand( nBandId,
     570                 :                  new MEMRasterBand( this, nBandId, pData, eType, nPixelSize, 
     571               0 :                                     nPixelSize * GetRasterXSize(), TRUE ) );
     572                 : 
     573               0 :         return CE_None;
     574                 :     }
     575                 : 
     576                 : /* -------------------------------------------------------------------- */
     577                 : /*      Get layout of memory and other flags.                           */
     578                 : /* -------------------------------------------------------------------- */
     579                 :     const char *pszOption;
     580                 :     int nPixelOffset, nLineOffset;
     581                 :     const char *pszDataPointer;
     582                 : 
     583              22 :     pszDataPointer = CSLFetchNameValue(papszOptions,"DATAPOINTER");
     584                 :     pData = (GByte *) CPLScanPointer(pszDataPointer,
     585              22 :                                      strlen(pszDataPointer));
     586                 :     
     587              22 :     pszOption = CSLFetchNameValue(papszOptions,"PIXELOFFSET");
     588              22 :     if( pszOption == NULL )
     589              22 :         nPixelOffset = nPixelSize;
     590                 :     else
     591               0 :         nPixelOffset = atoi(pszOption);
     592                 : 
     593              22 :     pszOption = CSLFetchNameValue(papszOptions,"LINEOFFSET");
     594              22 :     if( pszOption == NULL )
     595              22 :         nLineOffset = GetRasterXSize() * nPixelOffset;
     596                 :     else
     597               0 :         nLineOffset = atoi(pszOption);
     598                 : 
     599                 :     SetBand( nBandId,
     600                 :              new MEMRasterBand( this, nBandId, pData, eType, 
     601              22 :                                 nPixelOffset, nLineOffset, FALSE ) );
     602                 : 
     603              22 :     return CE_None;
     604                 : }
     605                 : 
     606                 : /************************************************************************/
     607                 : /*                                Open()                                */
     608                 : /************************************************************************/
     609                 : 
     610            1932 : GDALDataset *MEMDataset::Open( GDALOpenInfo * poOpenInfo )
     611                 : 
     612                 : {
     613                 :     char    **papszOptions;
     614                 : 
     615                 : /* -------------------------------------------------------------------- */
     616                 : /*      Do we have the special filename signature for MEM format        */
     617                 : /*      description strings?                                            */
     618                 : /* -------------------------------------------------------------------- */
     619            1932 :     if( !EQUALN(poOpenInfo->pszFilename,"MEM:::",6) 
     620                 :         || poOpenInfo->fp != NULL )
     621            1932 :         return NULL;
     622                 : 
     623                 :     papszOptions = CSLTokenizeStringComplex(poOpenInfo->pszFilename+6, ",",
     624               0 :                                             TRUE, FALSE );
     625                 : 
     626                 : /* -------------------------------------------------------------------- */
     627                 : /*      Verify we have all required fields                              */
     628                 : /* -------------------------------------------------------------------- */
     629               0 :     if( CSLFetchNameValue( papszOptions, "PIXELS" ) == NULL
     630                 :         || CSLFetchNameValue( papszOptions, "LINES" ) == NULL
     631                 :         || CSLFetchNameValue( papszOptions, "DATAPOINTER" ) == NULL )
     632                 :     {
     633                 :         CPLError( CE_Failure, CPLE_AppDefined, 
     634                 :               "Missing required field (one of PIXELS, LINES or DATAPOINTER)\n"
     635               0 :               "Unable to access in-memory array." );
     636                 : 
     637               0 :         CSLDestroy( papszOptions );
     638               0 :         return NULL;
     639                 :     }
     640                 : 
     641                 : /* -------------------------------------------------------------------- */
     642                 : /*      Create the new MEMDataset object.                               */
     643                 : /* -------------------------------------------------------------------- */
     644                 :     MEMDataset *poDS;
     645                 : 
     646               0 :     poDS = new MEMDataset();
     647                 : 
     648               0 :     poDS->nRasterXSize = atoi(CSLFetchNameValue(papszOptions,"PIXELS"));
     649               0 :     poDS->nRasterYSize = atoi(CSLFetchNameValue(papszOptions,"LINES"));
     650               0 :     poDS->eAccess = GA_Update;
     651                 : 
     652                 : /* -------------------------------------------------------------------- */
     653                 : /*      Extract other information.                                      */
     654                 : /* -------------------------------------------------------------------- */
     655                 :     const char *pszOption;
     656                 :     GDALDataType eType;
     657                 :     int nBands, nPixelOffset, nLineOffset;
     658                 :     size_t nBandOffset;
     659                 :     const char *pszDataPointer;
     660                 :     GByte *pabyData;
     661                 : 
     662               0 :     pszOption = CSLFetchNameValue(papszOptions,"BANDS");
     663               0 :     if( pszOption == NULL )
     664               0 :         nBands = 1;
     665                 :     else
     666                 :     {
     667               0 :         nBands = atoi(pszOption);
     668                 :     }
     669                 : 
     670               0 :     if (!GDALCheckDatasetDimensions(poDS->nRasterXSize, poDS->nRasterYSize) ||
     671                 :         !GDALCheckBandCount(nBands, TRUE))
     672                 :     {
     673               0 :         CSLDestroy( papszOptions );
     674               0 :         delete poDS;
     675               0 :         return NULL;
     676                 :     }
     677                 : 
     678               0 :     pszOption = CSLFetchNameValue(papszOptions,"DATATYPE");
     679               0 :     if( pszOption == NULL )
     680               0 :         eType = GDT_Byte;
     681                 :     else
     682                 :     {
     683               0 :         if( atoi(pszOption) > 0 && atoi(pszOption) < GDT_TypeCount )
     684               0 :             eType = (GDALDataType) atoi(pszOption);
     685                 :         else
     686                 :         {
     687                 :             int iType;
     688                 :             
     689               0 :             eType = GDT_Unknown;
     690               0 :             for( iType = 0; iType < GDT_TypeCount; iType++ )
     691                 :             {
     692               0 :                 if( EQUAL(GDALGetDataTypeName((GDALDataType) iType),
     693                 :                           pszOption) )
     694                 :                 {
     695               0 :                     eType = (GDALDataType) iType;
     696               0 :                     break;
     697                 :                 }
     698                 :             }
     699                 :             
     700               0 :             if( eType == GDT_Unknown )
     701                 :             {
     702                 :                 CPLError( CE_Failure, CPLE_AppDefined,
     703                 :                           "DATATYPE=%s not recognised.", 
     704               0 :                           pszOption );
     705               0 :                 CSLDestroy( papszOptions );
     706               0 :                 delete poDS;
     707               0 :                 return NULL;
     708                 :             }
     709                 :         }
     710                 :     }
     711                 : 
     712               0 :     pszOption = CSLFetchNameValue(papszOptions,"PIXELOFFSET");
     713               0 :     if( pszOption == NULL )
     714               0 :         nPixelOffset = GDALGetDataTypeSize(eType) / 8;
     715                 :     else
     716               0 :         nPixelOffset = atoi(pszOption);
     717                 : 
     718               0 :     pszOption = CSLFetchNameValue(papszOptions,"LINEOFFSET");
     719               0 :     if( pszOption == NULL )
     720               0 :         nLineOffset = poDS->nRasterXSize * nPixelOffset;
     721                 :     else
     722               0 :         nLineOffset = atoi(pszOption);
     723                 : 
     724               0 :     pszOption = CSLFetchNameValue(papszOptions,"BANDOFFSET");
     725               0 :     if( pszOption == NULL )
     726               0 :         nBandOffset = nLineOffset * (size_t) poDS->nRasterYSize;
     727                 :     else
     728               0 :         nBandOffset = atoi(pszOption);
     729                 : 
     730               0 :     pszDataPointer = CSLFetchNameValue(papszOptions,"DATAPOINTER");
     731                 :     pabyData = (GByte *) CPLScanPointer( pszDataPointer, 
     732               0 :                                          strlen(pszDataPointer) );
     733                 : 
     734                 : /* -------------------------------------------------------------------- */
     735                 : /*      Create band information objects.                                */
     736                 : /* -------------------------------------------------------------------- */
     737               0 :     for( int iBand = 0; iBand < nBands; iBand++ )
     738                 :     {
     739                 :         poDS->SetBand( iBand+1, 
     740                 :                        new MEMRasterBand( poDS, iBand+1, 
     741                 :                                           pabyData + iBand * nBandOffset,
     742                 :                                           eType, nPixelOffset, nLineOffset, 
     743               0 :                                           FALSE ) );
     744                 :     }
     745                 : 
     746                 : /* -------------------------------------------------------------------- */
     747                 : /*      Try to return a regular handle on the file.                     */
     748                 : /* -------------------------------------------------------------------- */
     749               0 :     CSLDestroy( papszOptions );
     750               0 :     return poDS;
     751                 : }
     752                 : 
     753                 : /************************************************************************/
     754                 : /*                               Create()                               */
     755                 : /************************************************************************/
     756                 : 
     757            5060 : GDALDataset *MEMDataset::Create( const char * pszFilename,
     758                 :                                  int nXSize, int nYSize, int nBands,
     759                 :                                  GDALDataType eType,
     760                 :                                  char ** /* notdef: papszParmList */ )
     761                 : 
     762                 : {
     763                 : /* -------------------------------------------------------------------- */
     764                 : /*      First allocate band data, verifying that we can get enough      */
     765                 : /*      memory.                                                         */
     766                 : /* -------------------------------------------------------------------- */
     767                 :     GByte   **papBandData;
     768                 :     int     iBand;
     769            5060 :     int         nWordSize = GDALGetDataTypeSize(eType) / 8;
     770                 : 
     771            5060 :     papBandData = (GByte **) VSICalloc(sizeof(void *),nBands);
     772            5060 :     if (papBandData == NULL)
     773                 :     {
     774                 :         CPLError( CE_Failure, CPLE_OutOfMemory,
     775               0 :                       "Unable to create band arrays ... out of memory." );
     776               0 :         return NULL;
     777                 :     }
     778                 : 
     779           10129 :     for( iBand = 0; iBand < nBands; iBand++ )
     780                 :     {
     781            5069 :         size_t nMulResult = ((size_t)nXSize) * nYSize;
     782            5069 :         if ( nMulResult / nXSize != (size_t)nYSize )
     783               0 :             papBandData[iBand] = NULL;
     784                 :         else
     785            5069 :             papBandData[iBand] = (GByte *) VSICalloc( nWordSize, nMulResult );
     786            5069 :         if( papBandData[iBand] == NULL )
     787                 :         {
     788               0 :             for( iBand = 0; iBand < nBands; iBand++ )
     789                 :             {
     790               0 :                 if( papBandData[iBand] )
     791               0 :                     VSIFree( papBandData[iBand] );
     792                 :             }
     793                 : 
     794               0 :             CPLFree( papBandData );
     795                 :             CPLError( CE_Failure, CPLE_OutOfMemory,
     796               0 :                       "Unable to create band arrays ... out of memory." );
     797               0 :             return NULL;
     798                 :         }
     799                 :     }
     800                 : 
     801                 : /* -------------------------------------------------------------------- */
     802                 : /*      Create the new GTiffDataset object.                             */
     803                 : /* -------------------------------------------------------------------- */
     804                 :     MEMDataset *poDS;
     805                 : 
     806            5060 :     poDS = new MEMDataset();
     807                 : 
     808            5060 :     poDS->nRasterXSize = nXSize;
     809            5060 :     poDS->nRasterYSize = nYSize;
     810            5060 :     poDS->eAccess = GA_Update;
     811                 : 
     812                 : /* -------------------------------------------------------------------- */
     813                 : /*      Create band information objects.                                */
     814                 : /* -------------------------------------------------------------------- */
     815           20258 :     for( iBand = 0; iBand < nBands; iBand++ )
     816                 :     {
     817                 :         poDS->SetBand( iBand+1, 
     818                 :                        new MEMRasterBand( poDS, iBand+1, papBandData[iBand],
     819            5069 :                                           eType, 0, 0, TRUE ) );
     820                 :     }
     821                 : 
     822            5060 :     CPLFree( papBandData );
     823                 : 
     824                 : /* -------------------------------------------------------------------- */
     825                 : /*      Try to return a regular handle on the file.                     */
     826                 : /* -------------------------------------------------------------------- */
     827            5060 :     return poDS;
     828                 : }
     829                 : 
     830                 : /************************************************************************/
     831                 : /*                     MEMDatasetIdentify()                             */
     832                 : /************************************************************************/
     833                 : 
     834            7730 : static int MEMDatasetIdentify( GDALOpenInfo * poOpenInfo )
     835                 : {
     836                 :     return (strncmp(poOpenInfo->pszFilename, "MEM:::", 6) == 0 &&
     837            7730 :             poOpenInfo->fp == NULL);
     838                 : }
     839                 : 
     840                 : /************************************************************************/
     841                 : /*                       MEMDatasetDelete()                             */
     842                 : /************************************************************************/
     843                 : 
     844               1 : static CPLErr MEMDatasetDelete(const char* fileName)
     845                 : {
     846                 :     /* Null implementation, so that people can Delete("MEM:::") */
     847               1 :     return CE_None;
     848                 : }
     849                 : 
     850                 : /************************************************************************/
     851                 : /*                          GDALRegister_MEM()                          */
     852                 : /************************************************************************/
     853                 : 
     854             338 : void GDALRegister_MEM()
     855                 : 
     856                 : {
     857                 :     GDALDriver  *poDriver;
     858                 : 
     859             338 :     if( GDALGetDriverByName( "MEM" ) == NULL )
     860                 :     {
     861             336 :         poDriver = new GDALDriver();
     862                 :         
     863             336 :         poDriver->SetDescription( "MEM" );
     864                 :         poDriver->SetMetadataItem( GDAL_DMD_LONGNAME, 
     865             336 :                                    "In Memory Raster" );
     866                 :         poDriver->SetMetadataItem( GDAL_DMD_CREATIONDATATYPES, 
     867             336 :                                    "Byte Int16 UInt16 Int32 UInt32 Float32 Float64 CInt16 CInt32 CFloat32 CFloat64" );
     868                 : 
     869                 : /* Define GDAL_NO_OPEN_FOR_MEM_DRIVER macro to undefine Open() method for MEM driver. */
     870                 : /* Otherwise, bad user input can trigger easily a GDAL crash as random pointers can be passed as a string. */
     871                 : /* All code in GDAL tree using the MEM driver use the Create() method only, so Open() */
     872                 : /* is not needed, except for esoteric uses */
     873                 : #ifndef GDAL_NO_OPEN_FOR_MEM_DRIVER
     874             336 :         poDriver->pfnOpen = MEMDataset::Open;
     875             336 :         poDriver->pfnIdentify = MEMDatasetIdentify;
     876                 : #endif
     877             336 :         poDriver->pfnCreate = MEMDataset::Create;
     878             336 :         poDriver->pfnDelete = MEMDatasetDelete;
     879                 : 
     880             336 :         GetGDALDriverManager()->RegisterDriver( poDriver );
     881                 :     }
     882             338 : }
     883                 : 

Generated by: LCOV version 1.7