Main Page Class Hierarchy Compound List File List Compound Members File Members Related Pages

# gdal_misc.cpp

    00001 /******************************************************************************
    00002  * $Id: gdal_misc_cpp-source.html,v 1.1 2000/09/25 20:50:11 warmerda Exp $
    00003  *
    00004  * Project:  GDAL Core
    00005  * Purpose:  Free standing functions for GDAL.
    00006  * Author:   Frank Warmerdam, warmerda@home.com
    00007  *
    00008  ******************************************************************************
    00009  * Copyright (c) 1999, Frank Warmerdam
    00010  *
    00011  * Permission is hereby granted, free of charge, to any person obtaining a
    00012  * copy of this software and associated documentation files (the "Software"),
    00013  * to deal in the Software without restriction, including without limitation
    00014  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
    00015  * and/or sell copies of the Software, and to permit persons to whom the
    00016  * Software is furnished to do so, subject to the following conditions:
    00017  *
    00018  * The above copyright notice and this permission notice shall be included
    00019  * in all copies or substantial portions of the Software.
    00020  *
    00021  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
    00022  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    00023  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
    00024  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    00025  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
    00026  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
    00027  * DEALINGS IN THE SOFTWARE.
    00028  ******************************************************************************
    00029  *
    00030  * $Log: gdal_misc_cpp-source.html,v $
    00030  * Revision 1.1  2000/09/25 20:50:11  warmerda
    00030  * New
    00030  *
    00031  * Revision 1.20  2000/08/18 15:24:48  warmerda
    00032  * added GDALTermProgress
    00033  *
    00034  * Revision 1.19  2000/08/09 16:25:42  warmerda
    00035  * don't crash if block is null
    00036  *
    00037  * Revision 1.18  2000/07/11 14:35:43  warmerda
    00038  * added documentation
    00039  *
    00040  * Revision 1.17  2000/07/05 17:53:33  warmerda
    00041  * Removed unused code related to nXCheck.
    00042  *
    00043  * Revision 1.16  2000/06/27 17:21:26  warmerda
    00044  * added GDALGetRasterSampleOverview
    00045  *
    00046  * Revision 1.15  2000/06/26 22:17:49  warmerda
    00047  * added scaled progress support
    00048  *
    00049  * Revision 1.14  2000/06/05 17:24:05  warmerda
    00050  * added real complex support
    00051  *
    00052  * Revision 1.13  2000/04/21 21:55:32  warmerda
    00053  * made more robust if block read fails
    00054  *
    00055  * Revision 1.12  2000/04/17 20:59:40  warmerda
    00056  * Removed printf.
    00057  *
    00058  * Revision 1.11  2000/04/17 20:59:14  warmerda
    00059  * fixed sampling bug
    00060  *
    00061  * Revision 1.10  2000/03/31 13:41:45  warmerda
    00062  * added gcp support functions
    00063  *
    00064  * Revision 1.9  2000/03/24 00:09:19  warmerda
    00065  * added sort-of random sampling
    00066  *
    00067  * Revision 1.8  2000/03/23 16:53:21  warmerda
    00068  * use overviews for approximate min/max
    00069  *
    00070  * Revision 1.7  2000/03/09 23:21:44  warmerda
    00071  * added GDALDummyProgress
    00072  *
    00073  * Revision 1.6  2000/03/06 21:59:44  warmerda
    00074  * added min/max calculate
    00075  *
    00076  * Revision 1.5  2000/03/06 02:20:15  warmerda
    00077  * added getname functions for colour interpretations
    00078  *
    00079  * Revision 1.4  1999/07/23 19:35:47  warmerda
    00080  * added GDALGetDataTypeName
    00081  *
    00082  * Revision 1.3  1999/05/17 02:00:45  vgough
    00083  * made pure_virtual C linkage
    00084  *
    00085  * Revision 1.2  1999/05/16 19:32:13  warmerda
    00086  * Added __pure_virtual.
    00087  *
    00088  * Revision 1.1  1998/12/06 02:50:16  warmerda
    00089  * New
    00090  *
    00091  */
    00092
    00093 #include "gdal_priv.h"
    00094
    00095 /************************************************************************/
    00096 /*                           __pure_virtual()                           */
    00097 /*                                                                      */
    00098 /*      The following is a gross hack to remove the last remaining      */
    00099 /*      dependency on the GNU C++ standard library.                     */
    00100 /************************************************************************/
    00101
    00102 #ifdef __GNUC__
    00103
    00104 extern "C"
    00105 void __pure_virtual()
    00106
    00107 {
    00108 }
    00109
    00110 #endif
    00111
    00112 /************************************************************************/
    00113 /*                        GDALGetDataTypeSize()                         */
    00114 /************************************************************************/
    00115 int GDALGetDataTypeSize( GDALDataType eDataType )
    00116
    00117 {
    00118     switch( eDataType )
    00119     {
    00120       case GDT_Byte:
    00121         return 8;
    00122
    00123       case GDT_UInt16:
    00124       case GDT_Int16:
    00125         return 16;
    00126
    00127       case GDT_UInt32:
    00128       case GDT_Int32:
    00129       case GDT_Float32:
    00130       case GDT_CInt16:
    00131         return 32;
    00132
    00133       case GDT_Float64:
    00134       case GDT_CInt32:
    00135       case GDT_CFloat32:
    00136         return 64;
    00137
    00138       case GDT_CFloat64:
    00139         return 128;
    00140
    00141       default:
    00142         CPLAssert( FALSE );
    00143         return 0;
    00144     }
    00145 }
    00146
    00147 /************************************************************************/
    00148 /*                       GDALDataTypeIsComplex()                        */
    00149 /************************************************************************/
    00150
    00151 int GDALDataTypeIsComplex( GDALDataType eDataType )
    00152
    00153 {
    00154     switch( eDataType )
    00155     {
    00156       case GDT_CInt16:
    00157       case GDT_CInt32:
    00158       case GDT_CFloat32:
    00159       case GDT_CFloat64:
    00160         return TRUE;
    00161
    00162       default:
    00163         return FALSE;
    00164     }
    00165 }
    00166
    00167 /************************************************************************/
    00168 /*                        GDALGetDataTypeName()                         */
    00169 /************************************************************************/
    00170
    00171 const char *GDALGetDataTypeName( GDALDataType eDataType )
    00172
    00173 {
    00174     switch( eDataType )
    00175     {
    00176       case GDT_Byte:
    00177         return "Byte";
    00178
    00179       case GDT_UInt16:
    00180         return "UInt16";
    00181
    00182       case GDT_Int16:
    00183         return "Int16";
    00184
    00185       case GDT_UInt32:
    00186         return "UInt32";
    00187
    00188       case GDT_Int32:
    00189         return "Int32";
    00190
    00191       case GDT_Float32:
    00192         return "Float32";
    00193
    00194       case GDT_Float64:
    00195         return "Float64";
    00196
    00197       case GDT_CInt16:
    00198         return "CInt16";
    00199
    00200       case GDT_CInt32:
    00201         return "CInt32";
    00202
    00203       case GDT_CFloat32:
    00204         return "CFloat32";
    00205
    00206       case GDT_CFloat64:
    00207         return "CFloat64";
    00208
    00209       default:
    00210         return NULL;
    00211     }
    00212 }
    00213
    00214 /************************************************************************/
    00215 /*                  GDALGetPaletteInterpretationName()                  */
    00216 /************************************************************************/
    00217
    00218 const char *GDALGetPaletteInterpretationName( GDALPaletteInterp eInterp )
    00219
    00220 {
    00221     switch( eInterp )
    00222     {
    00223       case GPI_Gray:
    00224         return "Gray";
    00225
    00226       case GPI_RGB:
    00227         return "RGB";
    00228
    00229       case GPI_CMYK:
    00230         return "CMYK";
    00231
    00232       case GPI_HLS:
    00233         return "HLS";
    00234
    00235       default:
    00236         return "Unknown";
    00237     }
    00238 }
    00239
    00240 /************************************************************************/
    00241 /*                   GDALGetColorInterpretationName()                   */
    00242 /************************************************************************/
    00243
    00244 const char *GDALGetColorInterpretationName( GDALColorInterp eInterp )
    00245
    00246 {
    00247     switch( eInterp )
    00248     {
    00249       case GCI_Undefined:
    00250         return "Undefined";
    00251
    00252       case GCI_GrayIndex:
    00253         return "Gray";
    00254
    00255       case GCI_PaletteIndex:
    00256         return "Palette";
    00257
    00258       case GCI_RedBand:
    00259         return "Red";
    00260
    00261       case GCI_GreenBand:
    00262         return "Green";
    00263
    00264       case GCI_BlueBand:
    00265         return "Blue";
    00266
    00267       case GCI_AlphaBand:
    00268         return "Alpha";
    00269
    00270       case GCI_HueBand:
    00271         return "Hue";
    00272
    00273       case GCI_SaturationBand:
    00274         return "Saturation";
    00275
    00276       case GCI_LightnessBand:
    00277         return "Lightness";
    00278
    00279       case GCI_CyanBand:
    00280         return "Cyan";
    00281
    00282       case GCI_MagentaBand:
    00283         return "Magenta";
    00284
    00285       case GCI_YellowBand:
    00286         return "Yellow";
    00287
    00288       case GCI_BlackBand:
    00289         return "Black";
    00290
    00291       default:
    00292         return "Unknown";
    00293     }
    00294 }
    00295
    00296 /************************************************************************/
    00297 /*                      GDALComputeRasterMinMax()                       */
    00298 /************************************************************************/
    00299
    00318 void GDALComputeRasterMinMax( GDALRasterBandH hBand, int bApproxOK,
    00319                               double adfMinMax[2] )
    00320
    00321 {
    00322     double       dfMin=0.0, dfMax=0.0;
    00323     GDALRasterBand *poBand;
    00324
    00325 /* -------------------------------------------------------------------- */
    00326 /*      Does the driver already know the min/max?                       */
    00327 /* -------------------------------------------------------------------- */
    00328     if( bApproxOK )
    00329     {
    00330         int          bSuccessMin, bSuccessMax;
    00331
    00332         dfMin = GDALGetRasterMinimum( hBand, &bSuccessMin );
    00333         dfMax = GDALGetRasterMaximum( hBand, &bSuccessMax );
    00334
    00335         if( bSuccessMin && bSuccessMax )
    00336         {
    00337             adfMinMax[0] = dfMin;
    00338             adfMinMax[1] = dfMax;
    00339             return;
    00340         }
    00341     }
    00342
    00343 /* -------------------------------------------------------------------- */
    00344 /*      If we have overview bands, use them for min/max.                */
    00345 /* -------------------------------------------------------------------- */
    00346     if( bApproxOK )
    00347         poBand = (GDALRasterBand *) GDALGetRasterSampleOverview( hBand, 2500 );
    00348     else
    00349         poBand = (GDALRasterBand *) hBand;
    00350
    00351 /* -------------------------------------------------------------------- */
    00352 /*      Figure out the ratio of blocks we will read to get an           */
    00353 /*      approximate value.                                              */
    00354 /* -------------------------------------------------------------------- */
    00355     int         nBlockXSize, nBlockYSize;
    00356     int         nBlocksPerRow, nBlocksPerColumn;
    00357     int         nSampleRate;
    00358     int         bGotNoDataValue, bFirstValue = TRUE;
    00359     double      dfNoDataValue;
    00360
    00361     dfNoDataValue = poBand->GetNoDataValue( &bGotNoDataValue );
    00362
    00363     poBand->GetBlockSize( &nBlockXSize, &nBlockYSize );
    00364     nBlocksPerRow = (poBand->GetXSize() + nBlockXSize - 1) / nBlockXSize;
    00365     nBlocksPerColumn = (poBand->GetYSize() + nBlockYSize - 1) / nBlockYSize;
    00366
    00367     if( bApproxOK )
    00368         nSampleRate =
    00369             (int) MAX(1,sqrt((double) nBlocksPerRow * nBlocksPerColumn));
    00370     else
    00371         nSampleRate = 1;
    00372
    00373     for( int iSampleBlock = 0;
    00374          iSampleBlock < nBlocksPerRow * nBlocksPerColumn;
    00375          iSampleBlock += nSampleRate )
    00376     {
    00377         double dfValue = 0.0;
    00378         int  iXBlock, iYBlock, nXCheck, nYCheck;
    00379         GDALRasterBlock *poBlock;
    00380
    00381         iYBlock = iSampleBlock / nBlocksPerRow;
    00382         iXBlock = iSampleBlock - nBlocksPerRow * iYBlock;
    00383
    00384         poBlock = poBand->GetBlockRef( iXBlock, iYBlock );
    00385         if( poBlock == NULL )
    00386             continue;
    00387
    00388         if( (iXBlock+1) * nBlockXSize > poBand->GetXSize() )
    00389             nXCheck = poBand->GetXSize() - iXBlock * nBlockXSize;
    00390         else
    00391             nXCheck = nBlockXSize;
    00392
    00393         if( (iYBlock+1) * nBlockYSize > poBand->GetYSize() )
    00394             nYCheck = poBand->GetYSize() - iYBlock * nBlockYSize;
    00395         else
    00396             nYCheck = nBlockYSize;
    00397
    00398         /* this isn't the fastest way to do this, but is easier for now */
    00399         for( int iY = 0; iY < nYCheck; iY++ )
    00400         {
    00401             for( int iX = 0; iX < nXCheck; iX++ )
    00402             {
    00403                 int    iOffset = iX + iY * nBlockXSize;
    00404
    00405                 switch( poBlock->GetDataType() )
    00406                 {
    00407                   case GDT_Byte:
    00408                     dfValue = ((GByte *) poBlock->GetDataRef())[iOffset];
    00409                     break;
    00410                   case GDT_UInt16:
    00411                     dfValue = ((GUInt16 *) poBlock->GetDataRef())[iOffset];
    00412                     break;
    00413                   case GDT_Int16:
    00414                     dfValue = ((GInt16 *) poBlock->GetDataRef())[iOffset];
    00415                     break;
    00416                   case GDT_UInt32:
    00417                     dfValue = ((GUInt32 *) poBlock->GetDataRef())[iOffset];
    00418                     break;
    00419                   case GDT_Int32:
    00420                     dfValue = ((GInt32 *) poBlock->GetDataRef())[iOffset];
    00421                     break;
    00422                   case GDT_Float32:
    00423                     dfValue = ((float *) poBlock->GetDataRef())[iOffset];
    00424                     break;
    00425                   case GDT_Float64:
    00426                     dfValue = ((double *) poBlock->GetDataRef())[iOffset];
    00427                     break;
    00428                   case GDT_CInt16:
    00429                     dfValue = ((GInt16 *) poBlock->GetDataRef())[iOffset*2];
    00430                     break;
    00431                   case GDT_CInt32:
    00432                     dfValue = ((GInt32 *) poBlock->GetDataRef())[iOffset*2];
    00433                     break;
    00434                   case GDT_CFloat32:
    00435                     dfValue = ((float *) poBlock->GetDataRef())[iOffset*2];
    00436                     break;
    00437                   case GDT_CFloat64:
    00438                     dfValue = ((double *) poBlock->GetDataRef())[iOffset*2];
    00439                     break;
    00440                   default:
    00441                     CPLAssert( FALSE );
    00442                 }
    00443
    00444                 if( bGotNoDataValue && dfValue == dfNoDataValue )
    00445                     continue;
    00446
    00447                 if( bFirstValue )
    00448                 {
    00449                     dfMin = dfMax = dfValue;
    00450                     bFirstValue = FALSE;
    00451                 }
    00452                 else
    00453                 {
    00454                     dfMin = MIN(dfMin,dfValue);
    00455                     dfMax = MAX(dfMax,dfValue);
    00456                 }
    00457             }
    00458         }
    00459     }
    00460
    00461     adfMinMax[0] = dfMin;
    00462     adfMinMax[1] = dfMax;
    00463 }
    00464
    00465 /************************************************************************/
    00466 /*                         GDALDummyProgress()                          */
    00467 /************************************************************************/
    00468
    00533 int GDALDummyProgress( double, const char *, void * )
    00534
    00535 {
    00536     return TRUE;
    00537 }
    00538
    00539 /************************************************************************/
    00540 /*                         GDALScaledProgress()                         */
    00541 /************************************************************************/
    00542 typedef struct {
    00543     GDALProgressFunc pfnProgress;
    00544     void *pData;
    00545     double dfMin;
    00546     double dfMax;
    00547 } GDALScaledProgressInfo;
    00548
    00549 int GDALScaledProgress( double dfComplete, const char *pszMessage,
    00550                         void *pData )
    00551
    00552 {
    00553     GDALScaledProgressInfo *psInfo = (GDALScaledProgressInfo *) pData;
    00554
    00555     return psInfo->pfnProgress( dfComplete * (psInfo->dfMax - psInfo->dfMin)
    00556                                 + psInfo->dfMin,
    00557                                 pszMessage, psInfo->pData );
    00558 }
    00559
    00560 /************************************************************************/
    00561 /*                      GDALCreateScaledProgress()                      */
    00562 /************************************************************************/
    00563
    00564 void *GDALCreateScaledProgress( double dfMin, double dfMax,
    00565                                 GDALProgressFunc pfnProgress,
    00566                                 void * pData )
    00567
    00568 {
    00569     GDALScaledProgressInfo *psInfo;
    00570
    00571     psInfo = (GDALScaledProgressInfo *)
    00572         CPLCalloc(sizeof(GDALScaledProgressInfo),1);
    00573
    00574     if( ABS(dfMin-dfMax) < 0.0000001 )
    00575         dfMax = dfMin + 0.01;
    00576
    00577     psInfo->pData = pData;
    00578     psInfo->pfnProgress = pfnProgress;
    00579     psInfo->dfMin = dfMin;
    00580     psInfo->dfMax = dfMax;
    00581
    00582     return (void *) psInfo;
    00583 }
    00584
    00585 /************************************************************************/
    00586 /*                     GDALDestroyScaledProgress()                      */
    00587 /************************************************************************/
    00588
    00589 void GDALDestroyScaledProgress( void * pData )
    00590
    00591 {
    00592     CPLFree( pData );
    00593 }
    00594
    00595 /************************************************************************/
    00596 /*                          GDALTermProgress()                          */
    00597 /************************************************************************/
    00598
    00599 int GDALTermProgress( double dfComplete, const char *pszMessage, void * )
    00600
    00601 {
    00602     static double dfLastComplete = -1.0;
    00603
    00604     if( dfLastComplete > dfComplete )
    00605     {
    00606         if( dfLastComplete > 1.0 )
    00607             dfLastComplete = -1.0;
    00608         else
    00609             dfLastComplete = dfComplete;
    00610     }
    00611
    00612     if( floor(dfLastComplete*10) != floor(dfComplete*10) )
    00613     {
    00614         int    nPercent = (int) floor(dfComplete*100);
    00615
    00616         if( nPercent == 0 && pszMessage != NULL )
    00617             fprintf( stdout, "%s:", pszMessage );
    00618
    00619         if( nPercent == 100 )
    00620             fprintf( stdout, "%d - done.\n", (int) floor(dfComplete*100) );
    00621         else
    00622         {
    00623             fprintf( stdout, "%d.", (int) floor(dfComplete*100) );
    00624             fflush( stdout );
    00625         }
    00626     }
    00627     else if( floor(dfLastComplete*30) != floor(dfComplete*30) )
    00628     {
    00629         fprintf( stdout, "." );
    00630         fflush( stdout );
    00631     }
    00632
    00633     dfLastComplete = dfComplete;
    00634
    00635     return TRUE;
    00636 }
    00637
    00638 /************************************************************************/
    00639 /*                    GDALGetRasterSampleOverview()                     */
    00640 /************************************************************************/
    00641
    00657 GDALRasterBandH GDALGetRasterSampleOverview( GDALRasterBandH hBand,
    00658                                              int nDesiredSamples )
    00659
    00660 {
    00661     int     nBestSamples;
    00662     GDALRasterBandH hBestBand = hBand;
    00663
    00664     nBestSamples = GDALGetRasterBandXSize(hBand)
    00665         * GDALGetRasterBandYSize(hBand);
    00666
    00667     for( int iOverview = 0;
    00668          iOverview < GDALGetOverviewCount( hBand );
    00669          iOverview++ )
    00670     {
    00671         GDALRasterBandH hOBand = GDALGetOverview( hBand, iOverview );
    00672         int    nOSamples;
    00673
    00674         nOSamples = GDALGetRasterBandXSize(hOBand)
    00675             * GDALGetRasterBandYSize(hOBand);
    00676
    00677         if( nOSamples < nBestSamples && nOSamples > nDesiredSamples )
    00678         {
    00679             nBestSamples = nOSamples;
    00680             hBestBand = hOBand;
    00681         }
    00682     }
    00683
    00684     return hBestBand;
    00685 }
    00686
    00687 /************************************************************************/
    00688 /*                     GDALGetRandomRasterSample()                      */
    00689 /************************************************************************/
    00690
    00691 int GDALGetRandomRasterSample( GDALRasterBandH hBand, int nSamples,
    00692                                float *pafSampleBuf )
    00693
    00694 {
    00695     GDALRasterBand *poBand;
    00696
    00697     poBand = (GDALRasterBand *) GDALGetRasterSampleOverview( hBand, nSamples );
    00698
    00699 /* -------------------------------------------------------------------- */
    00700 /*      Figure out the ratio of blocks we will read to get an           */
    00701 /*      approximate value.                                              */
    00702 /* -------------------------------------------------------------------- */
    00703     int         nBlockXSize, nBlockYSize;
    00704     int         nBlocksPerRow, nBlocksPerColumn;
    00705     int         nSampleRate;
    00706     int         bGotNoDataValue;
    00707     double      dfNoDataValue;
    00708     int         nActualSamples = 0;
    00709     int         nBlockSampleRate;
    00710
    00711     dfNoDataValue = poBand->GetNoDataValue( &bGotNoDataValue );
    00712
    00713     poBand->GetBlockSize( &nBlockXSize, &nBlockYSize );
    00714     nBlocksPerRow = (poBand->GetXSize() + nBlockXSize - 1) / nBlockXSize;
    00715     nBlocksPerColumn = (poBand->GetYSize() + nBlockYSize - 1) / nBlockYSize;
    00716
    00717     nSampleRate =
    00718         (int) MAX(1,sqrt((double) nBlocksPerRow * nBlocksPerColumn)-2.0);
    00719
    00720     if( nSampleRate == nBlocksPerRow && nSampleRate > 1 )
    00721         nSampleRate--;
    00722
    00723     nBlockSampleRate = MAX(1,(nBlockXSize * nBlockYSize) /
    00724         (nSamples / (nBlocksPerRow*nBlocksPerColumn / nSampleRate)));
    00725
    00726     for( int iSampleBlock = 0;
    00727          iSampleBlock < nBlocksPerRow * nBlocksPerColumn;
    00728          iSampleBlock += nSampleRate )
    00729     {
    00730         double dfValue = 0.0;
    00731         int  iXBlock, iYBlock, nYCheck, iOffset;
    00732         GDALRasterBlock *poBlock;
    00733
    00734         iYBlock = iSampleBlock / nBlocksPerRow;
    00735         iXBlock = iSampleBlock - nBlocksPerRow * iYBlock;
    00736
    00737         poBlock = poBand->GetBlockRef( iXBlock, iYBlock );
    00738         if( poBlock == NULL )
    00739             continue;
    00740
    00741         if( (iYBlock+1) * nBlockYSize > poBand->GetYSize() )
    00742             nYCheck = poBand->GetYSize() - iYBlock * nBlockYSize;
    00743         else
    00744             nYCheck = nBlockYSize;
    00745
    00746         /* this isn't the fastest way to do this, but is easier for now */
    00747         for( iOffset = nBlockXSize*nBlockYSize-1;
    00748              iOffset >= 0 && nActualSamples < nSamples;
    00749              iOffset -= nBlockSampleRate )
    00750         {
    00751             switch( poBlock->GetDataType() )
    00752             {
    00753               case GDT_Byte:
    00754                 dfValue = ((GByte *) poBlock->GetDataRef())[iOffset];
    00755                 break;
    00756               case GDT_UInt16:
    00757                 dfValue = ((GUInt16 *) poBlock->GetDataRef())[iOffset];
    00758                 break;
    00759               case GDT_Int16:
    00760                 dfValue = ((GInt16 *) poBlock->GetDataRef())[iOffset];
    00761                 break;
    00762               case GDT_UInt32:
    00763                 dfValue = ((GUInt32 *) poBlock->GetDataRef())[iOffset];
    00764                 break;
    00765               case GDT_Int32:
    00766                 dfValue = ((GInt32 *) poBlock->GetDataRef())[iOffset];
    00767                 break;
    00768               case GDT_Float32:
    00769                 dfValue = ((float *) poBlock->GetDataRef())[iOffset];
    00770                 break;
    00771               case GDT_Float64:
    00772                 dfValue = ((double *) poBlock->GetDataRef())[iOffset];
    00773                 break;
    00774               case GDT_CInt16:
    00775                 dfValue = ((GInt16 *) poBlock->GetDataRef())[iOffset*2];
    00776                 break;
    00777               case GDT_CInt32:
    00778                 dfValue = ((GInt32 *) poBlock->GetDataRef())[iOffset*2];
    00779                 break;
    00780               case GDT_CFloat32:
    00781                 dfValue = ((float *) poBlock->GetDataRef())[iOffset*2];
    00782                 break;
    00783               case GDT_CFloat64:
    00784                 dfValue = ((double *) poBlock->GetDataRef())[iOffset*2];
    00785                 break;
    00786               default:
    00787                 CPLAssert( FALSE );
    00788             }
    00789
    00790             if( bGotNoDataValue && dfValue == dfNoDataValue )
    00791                 continue;
    00792
    00793             pafSampleBuf[nActualSamples++] = dfValue;
    00794         }
    00795     }
    00796
    00797     return nActualSamples;
    00798 }
    00799
    00800 /************************************************************************/
    00801 /*                            GDALInitGCPs()                            */
    00802 /************************************************************************/
    00803
    00804 void GDALInitGCPs( int nCount, GDAL_GCP * psGCP )
    00805
    00806 {
    00807     for( int iGCP = 0; iGCP < nCount; iGCP++ )
    00808     {
    00809         memset( psGCP, 0, sizeof(GDAL_GCP) );
    00810         psGCP->pszId = CPLStrdup("");
    00811         psGCP->pszInfo = CPLStrdup("");
    00812         psGCP++;
    00813     }
    00814 }
    00815
    00816 /************************************************************************/
    00817 /*                           GDALDeinitGCPs()                           */
    00818 /************************************************************************/
    00819
    00820 void GDALDeinitGCPs( int nCount, GDAL_GCP * psGCP )
    00821
    00822 {
    00823     for( int iGCP = 0; iGCP < nCount; iGCP++ )
    00824     {
    00825         CPLFree( psGCP->pszId );
    00826         CPLFree( psGCP->pszInfo );
    00827         psGCP++;
    00828     }
    00829 }
    00830
    00831 /************************************************************************/
    00832 /*                         GDALDuplicateGCPs()                          */
    00833 /************************************************************************/
    00834
    00835 GDAL_GCP *GDALDuplicateGCPs( int nCount, const GDAL_GCP *pasGCPList )
    00836
    00837 {
    00838     GDAL_GCP    *pasReturn;
    00839
    00840     pasReturn = (GDAL_GCP *) CPLMalloc(sizeof(GDAL_GCP) * nCount);
    00841     GDALInitGCPs( nCount, pasReturn );
    00842
    00843     for( int iGCP = 0; iGCP < nCount; iGCP++ )
    00844     {
    00845         CPLFree( pasReturn[iGCP].pszId );
    00846         pasReturn[iGCP].pszId = CPLStrdup( pasGCPList[iGCP].pszId );
    00847
    00848         CPLFree( pasReturn[iGCP].pszInfo );
    00849         pasReturn[iGCP].pszInfo = CPLStrdup( pasGCPList[iGCP].pszInfo );
    00850
    00851         pasReturn[iGCP].dfGCPPixel = pasGCPList[iGCP].dfGCPPixel;
    00852         pasReturn[iGCP].dfGCPLine = pasGCPList[iGCP].dfGCPLine;
    00853         pasReturn[iGCP].dfGCPX = pasGCPList[iGCP].dfGCPX;
    00854         pasReturn[iGCP].dfGCPY = pasGCPList[iGCP].dfGCPY;
    00855         pasReturn[iGCP].dfGCPZ = pasGCPList[iGCP].dfGCPZ;
    00856     }
    00857
    00858     return pasReturn;
    00859 }
    00860