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                              

doxygen1.2.2 Dimitri van Heesch, © 1997-2000