00001 00002 00003 00004 00005 00006 00007 00008 00009 00010 00011 00012 00013 00014 00015 00016 00017 00018 00019 00020 00021 00022 00023 00024 00025 00026 00027 00028 00029 00030 00030 00030 00030 00031 00032 00033 00034 00035 00036 00037 00038 00039 00040 00041 00042 00043 00044 00045 00046 00047 00048 00049 00050 00051 00052 00053 00054 00055 00056 00057 00058 00059 00060 00061 00062 00063 00064 00065 00066 00067 00068 00069 00070 00071 00072 00073 00074 00075 00076 00077 00078 00079 00080 00081 00082 00083 00084 00085 00086 00087 00088 00089 00090 00091
00092
00093 #include "gdal_priv.h"
00094
00095
00096
00097
00098
00099
00100
00101
00102 #ifdef __GNUC__
00103
00104 extern "C"
00105 void __pure_virtual()
00106
00107 {
00108 }
00109
00110 #endif
00111
00112
00113
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
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
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
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
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
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
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
00345
00346 if( bApproxOK )
00347 poBand = (GDALRasterBand *) GDALGetRasterSampleOverview( hBand, 2500 );
00348 else
00349 poBand = (GDALRasterBand *) hBand;
00350
00351
00352
00353
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
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
00467
00468
00533 int GDALDummyProgress( double, const char *, void * )
00534
00535 {
00536 return TRUE;
00537 }
00538
00539
00540
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
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
00587
00588
00589 void GDALDestroyScaledProgress( void * pData )
00590
00591 {
00592 CPLFree( pData );
00593 }
00594
00595
00596
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
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
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
00701
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
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
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
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
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