LCOV - code coverage report
Current view: directory - frmts/mem - memdataset.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 322 215 66.8 %
Date: 2012-04-28 Functions: 44 32 72.7 %

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

Generated by: LCOV version 1.7