Changeset 13698

Show
Ignore:
Timestamp:
02/05/08 12:34:42 (6 months ago)
Author:
warmerdam
Message:

handle very large attributes properly (#2196)

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/gdal/frmts/netcdf/netcdfdataset.cpp

    r12892 r13698  
    9191        return pszProjection; 
    9292    else 
    93         return ""
     93        return GDALPamDataset::GetProjectionRef()
    9494} 
    9595 
     
    104104        *pbSuccess = bNoDataSet; 
    105105 
    106     return dfNoDataValue; 
     106    if( bNoDataSet ) 
     107        return dfNoDataValue; 
     108    else 
     109        return GDALPamRasterBand::GetNoDataValue( pbSuccess ); 
    107110} 
    108111 
     
    898901/*      Enable GeoTransform                                             */ 
    899902/* -------------------------------------------------------------------- */ 
     903                /* ----------------------------------------------------------*/ 
     904                /*    In the following "actual_range" and "node_offset"      */ 
     905                /*    are attributes used by netCDF files created by GMT.    */ 
     906                /*    If we find them we know how to proceed. Else, use      */ 
     907                /*    the original algorithm.                                */ 
     908                /* --------------------------------------------------------- */ 
     909                double  dummy[2], xMinMax[2], yMinMax[2]; 
     910                int     node_offset = 0; 
     911 
    900912                poDS->bGotGeoTransform = TRUE; 
     913 
     914                nc_get_att_int (cdfid, NC_GLOBAL, "node_offset", &node_offset); 
     915 
     916                if (!nc_get_att_double (cdfid, nVarDimXID, "actual_range", dummy)) { 
     917                    xMinMax[0] = dummy[0];               
     918                    xMinMax[1] = dummy[1]; 
     919                } 
     920                else { 
     921                    xMinMax[0] = pdfXCoord[0]; 
     922                    xMinMax[1] = pdfXCoord[xdim-1]; 
     923                    node_offset = 0; 
     924                } 
     925 
     926                if (!nc_get_att_double (cdfid, nVarDimYID, "actual_range", dummy)) { 
     927                    yMinMax[0] = dummy[0];               
     928                    yMinMax[1] = dummy[1]; 
     929                } 
     930                else { 
     931                    yMinMax[0] = pdfYCoord[0];   
     932                    yMinMax[1] = pdfYCoord[ydim-1]; 
     933                    node_offset = 0; 
     934                } 
     935 
     936#ifdef notdef 
     937                // Check for reverse order of y-coordinate 
     938                if ( yMinMax[0] > yMinMax[1] ) { 
     939                    dummy[0] = yMinMax[1]; 
     940                    dummy[1] = yMinMax[0]; 
     941                    yMinMax[0] = dummy[0]; 
     942                    yMinMax[1] = dummy[1]; 
     943                } 
     944#endif 
     945 
     946                poDS->adfGeoTransform[0] = xMinMax[0]; 
     947                poDS->adfGeoTransform[2] = 0; 
     948                poDS->adfGeoTransform[3] = yMinMax[1]; 
     949                poDS->adfGeoTransform[4] = 0; 
     950                poDS->adfGeoTransform[1] = ( xMinMax[1] - xMinMax[0] ) /  
     951                    ( poDS->nRasterXSize + (node_offset - 1) ); 
     952                poDS->adfGeoTransform[5] = ( yMinMax[0] - yMinMax[1] ) /  
     953                    ( poDS->nRasterYSize + (node_offset - 1) ); 
     954 
     955/* -------------------------------------------------------------------- */ 
     956/*     Compute the center of the pixel                                  */ 
     957/* -------------------------------------------------------------------- */ 
     958                if ( !node_offset ) {   // Otherwise its already the pixel center 
     959                    poDS->adfGeoTransform[0] -= (poDS->adfGeoTransform[1] / 2); 
     960                    poDS->adfGeoTransform[3] -= (poDS->adfGeoTransform[5] / 2); 
     961                } 
     962 
     963                oSRS.exportToWkt( &(poDS->pszProjection) ); 
    901964                     
    902                 poDS->adfGeoTransform[0] = pdfXCoord[0]; 
    903                 poDS->adfGeoTransform[3] = pdfYCoord[0]; 
    904                 poDS->adfGeoTransform[2] = 0; 
    905                 poDS->adfGeoTransform[4] = 0; 
    906                 poDS->adfGeoTransform[1] = (( pdfXCoord[xdim-1] -  
    907                                               pdfXCoord[0] ) /  
    908                                             ( poDS->nRasterXSize - 1 )); 
    909  
    910                 poDS->adfGeoTransform[5] = (( pdfYCoord[ydim-1] -  
    911                                               pdfYCoord[0] ) /  
    912                                             ( poDS->nRasterYSize - 1 )); 
    913 /* -------------------------------------------------------------------- */ 
    914 /*     Compute the center of the pixel                                  */ 
    915 /* -------------------------------------------------------------------- */ 
    916                 poDS->adfGeoTransform[0] = pdfXCoord[0] 
    917                     - (poDS->adfGeoTransform[1] / 2); 
    918  
    919                 poDS->adfGeoTransform[3] = pdfYCoord[0] 
    920                     - (poDS->adfGeoTransform[5] / 2); 
    921  
    922                 oSRS.exportToWkt( &(poDS->pszProjection) ); 
    923965            }  
    924966        } 
     
    10401082        return CE_None; 
    10411083    else 
    1042         return CE_Failure
     1084        return GDALPamDataset::GetGeoTransform( padfTransform );
    10431085} 
    10441086 
     
    10711113/*                        ReadAttributes()                              */ 
    10721114/************************************************************************/ 
     1115CPLErr netCDFDataset::SafeStrcat(char** ppszDest, char* pszSrc, size_t* nDestSize) 
     1116{ 
     1117    /* Reallocate the data string until the content fits */ 
     1118    while(*nDestSize < (strlen(*ppszDest) + strlen(pszSrc) + 1)) { 
     1119        (*nDestSize) *= 2; 
     1120        *ppszDest = (char*) CPLRealloc((void*) *ppszDest, *nDestSize); 
     1121    } 
     1122    strcat(*ppszDest, pszSrc); 
     1123     
     1124    return CE_None; 
     1125} 
    10731126 
    10741127CPLErr netCDFDataset::ReadAttributes( int cdfid, int var) 
     
    10771130    char    szAttrName[ NC_MAX_NAME ]; 
    10781131    char    szVarName [ NC_MAX_NAME ]; 
    1079     char    szMetaName[ NC_MAX_NAME ]; 
    1080     char    szMetaTemp[ MAX_STR_LEN ]; 
     1132    char    szMetaName[ NC_MAX_NAME * 2 ]; 
     1133    char    *pszMetaTemp = NULL; 
     1134    size_t  nMetaTempSize; 
    10811135    nc_type nAttrType; 
    1082     size_t  nAttrLen,m; 
     1136    size_t  nAttrLen, m; 
    10831137    int     nbAttr; 
    1084     char    szTemp[ NC_MAX_NAME ]; 
     1138    char    szTemp[ MAX_STR_LEN ]; 
    10851139 
    10861140    nc_inq_varnatts( cdfid, var, &nbAttr ); 
     
    10921146    } 
    10931147 
    1094     for( int l=0; l < nbAttr; l++)
     1148    for( int l=0; l < nbAttr; l++)
    10951149         
    10961150        nc_inq_attname( cdfid, var, l, szAttrName); 
    10971151        sprintf( szMetaName, "%s#%s", szVarName, szAttrName  ); 
    1098         *szMetaTemp='\0'; 
    10991152        nc_inq_att( cdfid, var, szAttrName, &nAttrType, &nAttrLen ); 
    11001153         
     1154        /* Allocate guaranteed minimum size */ 
     1155        nMetaTempSize = nAttrLen + 1; 
     1156        pszMetaTemp = (char *) CPLCalloc( nMetaTempSize, sizeof( char )); 
     1157        *pszMetaTemp = '\0'; 
    11011158         
    11021159        switch (nAttrType) { 
    11031160        case NC_CHAR: 
    1104             char *pszTemp; 
    1105             pszTemp = (char *) CPLCalloc( nAttrLen+1, sizeof( char ) ); 
    1106             nc_get_att_text( cdfid, var, szAttrName,pszTemp ); 
    1107             pszTemp[nAttrLen]='\0'; 
    1108             strcpy(szMetaTemp,pszTemp); 
    1109             CPLFree(pszTemp); 
     1161                nc_get_att_text( cdfid, var, szAttrName, pszMetaTemp ); 
     1162                pszMetaTemp[nAttrLen]='\0'; 
    11101163            break; 
    11111164        case NC_SHORT: 
    11121165            short *psTemp; 
    1113              
    11141166            psTemp = (short *) CPLCalloc( nAttrLen, sizeof( short ) ); 
    11151167            nc_get_att_short( cdfid, var, szAttrName, psTemp ); 
    11161168            for(m=0; m < nAttrLen-1; m++) { 
    1117                sprintf( szTemp, "%d, ",psTemp[m] ); 
    1118                strcat(szMetaTemp,szTemp); 
     1169                    sprintf( szTemp, "%hd, ", psTemp[m] ); 
     1170                    SafeStrcat(&pszMetaTemp, szTemp, &nMetaTempSize); 
    11191171            } 
    1120             sprintf( szTemp, "%d",psTemp[m] ); 
     1172                sprintf( szTemp, "%hd", psTemp[m] ); 
     1173                SafeStrcat(&pszMetaTemp, szTemp, &nMetaTempSize); 
    11211174            CPLFree(psTemp); 
    1122             strcat(szMetaTemp,szTemp); 
    1123              
    11241175            break; 
    11251176        case NC_INT: 
    11261177            int *pnTemp; 
    1127              
    11281178            pnTemp = (int *) CPLCalloc( nAttrLen, sizeof( int ) ); 
    11291179            nc_get_att_int( cdfid, var, szAttrName, pnTemp ); 
    11301180            for(m=0; m < nAttrLen-1; m++) { 
    1131                sprintf( szTemp, "%d",pnTemp[m] ); 
    1132                strcat(szMetaTemp,szTemp); 
     1181                    sprintf( szTemp, "%d, ", pnTemp[m] ); 
     1182                    SafeStrcat(&pszMetaTemp, szTemp, &nMetaTempSize); 
    11331183            } 
    1134             sprintf( szTemp, "%d",pnTemp[m] ); 
     1184                    sprintf( szTemp, "%d", pnTemp[m] ); 
     1185                    SafeStrcat(&pszMetaTemp, szTemp, &nMetaTempSize); 
    11351186            CPLFree(pnTemp); 
    1136             strcat(szMetaTemp,szTemp); 
    11371187            break; 
    11381188        case NC_FLOAT: 
     
    11411191            nc_get_att_float( cdfid, var, szAttrName, pfTemp ); 
    11421192            for(m=0; m < nAttrLen-1; m++) { 
    1143                sprintf( szTemp, "%e",pfTemp[m] ); 
    1144                strcat(szMetaTemp,szTemp); 
     1193                    sprintf( szTemp, "%e, ", pfTemp[m] ); 
     1194                    SafeStrcat(&pszMetaTemp, szTemp, &nMetaTempSize); 
    11451195            } 
    1146             sprintf( szTemp, "%e",pfTemp[m] ); 
     1196                    sprintf( szTemp, "%e", pfTemp[m] ); 
     1197                    SafeStrcat(&pszMetaTemp,szTemp, &nMetaTempSize); 
    11471198            CPLFree(pfTemp); 
    1148             strcat(szMetaTemp,szTemp); 
    1149              
    11501199            break; 
    11511200        case NC_DOUBLE: 
     
    11541203            nc_get_att_double( cdfid, var, szAttrName, pdfTemp ); 
    11551204            for(m=0; m < nAttrLen-1; m++) { 
    1156                sprintf( szTemp, "%g",pdfTemp[m] ); 
    1157                strcat(szMetaTemp,szTemp); 
     1205                    sprintf( szTemp, "%g, ", pdfTemp[m] ); 
     1206                    SafeStrcat(&pszMetaTemp, szTemp, &nMetaTempSize); 
    11581207            } 
    1159             sprintf( szTemp, "%g",pdfTemp[m] ); 
     1208                    sprintf( szTemp, "%g", pdfTemp[m] ); 
     1209                    SafeStrcat(&pszMetaTemp, szTemp, &nMetaTempSize); 
    11601210            CPLFree(pdfTemp); 
    1161             strcat(szMetaTemp,szTemp); 
    1162              
    11631211            break; 
    11641212        default: 
     
    11681216        papszMetadata = CSLSetNameValue(papszMetadata,  
    11691217                                        szMetaName,  
    1170                                         szMetaTemp); 
     1218                                        pszMetaTemp); 
     1219        CPLFree(pszMetaTemp); 
     1220    } 
    11711221         
    1172     } 
    1173          
    11741222 
    11751223    return CE_None; 
    11761224 
    11771225} 
     1226 
    11781227 
    11791228/************************************************************************/ 
  • trunk/gdal/frmts/netcdf/netcdfdataset.h

    r12878 r13698  
    160160    static GDALDataset *Open( GDALOpenInfo * ); 
    161161 
     162    CPLErr      SafeStrcat(char**, char*, size_t*); 
    162163    CPLErr      ReadAttributes( int, int ); 
    163164