Changeset 13829
- Timestamp:
- 02/21/08 14:09:39 (3 months ago)
- Files:
-
- branches/1.5/gdal/frmts/gsg/gsagdataset.cpp (modified) (20 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
branches/1.5/gdal/frmts/gsg/gsagdataset.cpp
r12155 r13829 85 85 86 86 static GDALDataset *Open( GDALOpenInfo * ); 87 static GDALDataset *Create( const char * pszFilename,88 int nXSize, int nYSize, int nBands,89 GDALDataType eType,90 char **papszParmList );91 87 static GDALDataset *CreateCopy( const char *pszFilename, 92 88 GDALDataset *poSrcDS, … … 124 120 125 121 vsi_l_offset *panLineOffset; 122 int nLastReadLine; 126 123 127 124 double *padfRowMinZ; … … 183 180 184 181 panLineOffset = 185 (vsi_l_offset *) CPLCalloc( poDS->nRasterYSize+1, sizeof(vsi_l_offset) );182 (vsi_l_offset *)VSICalloc( poDS->nRasterYSize+1, sizeof(vsi_l_offset) ); 186 183 if( panLineOffset == NULL ) 184 { 185 CPLError(CE_Failure, CPLE_OutOfMemory, 186 "GSAGRasterBand::GSAGRasterBand : Out of memory allocating %d * %d bytes", 187 poDS->nRasterYSize+1, sizeof(vsi_l_offset) ); 187 188 return; 188 189 panLineOffset[0] = nDataStart; 189 } 190 191 panLineOffset[poDS->nRasterYSize-1] = nDataStart; 192 nLastReadLine = poDS->nRasterYSize; 190 193 } 191 194 … … 304 307 305 308 if( nBlockYOff < 0 || nBlockYOff > nRasterYSize - 1 || nBlockXOff != 0 ) 306 return CE_Failure;309 return CE_Failure; 307 310 308 311 if( panLineOffset[nBlockYOff] == 0 ) 309 IReadBlock( nBlockXOff, nBlockYOff-1, NULL ); 312 { 313 // Discover the last read block 314 for ( int iFoundLine = nLastReadLine - 1; iFoundLine > nBlockYOff; iFoundLine--) 315 { 316 IReadBlock( nBlockXOff, iFoundLine, NULL); 317 } 318 } 310 319 311 320 if( panLineOffset[nBlockYOff] == 0 ) 312 return CE_Failure; 313 321 return CE_Failure; 314 322 if( VSIFSeekL( poGDS->fp, panLineOffset[nBlockYOff], SEEK_SET ) != 0 ) 315 323 { 316 CPLError( CE_Failure, CPLE_FileIO,317 "Can't seek to offset %ld to read grid row %d.",318 panLineOffset[nBlockYOff], nBlockYOff );319 return CE_Failure;324 CPLError( CE_Failure, CPLE_FileIO, 325 "Can't seek to offset %ld to read grid row %d.", 326 panLineOffset[nBlockYOff], nBlockYOff ); 327 return CE_Failure; 320 328 } 321 329 … … 325 333 size_t nCharsExamined = 0; 326 334 /* If we know the offsets, we can just read line directly */ 327 if( panLineOffset[nBlockYOff+1] != 0)328 { 329 assert(panLineOffset[nBlockYOff +1] > panLineOffset[nBlockYOff]);330 nLineBufSize = panLineOffset[nBlockYOff +1]331 - panLineOffset[nBlockYOff] + 1;335 if( (nBlockYOff > 0) && ( panLineOffset[nBlockYOff-1] != 0 ) ) 336 { 337 assert(panLineOffset[nBlockYOff-1] > panLineOffset[nBlockYOff]); 338 nLineBufSize = panLineOffset[nBlockYOff-1] 339 - panLineOffset[nBlockYOff] + 1; 332 340 } 333 341 else … … 413 421 414 422 while( *szStart == '\0' && 415 static_cast<size_t>(szStart - szLineBuf) < nCharsRead )423 static_cast<size_t>(szStart - szLineBuf) < nCharsRead ) 416 424 szStart++; 417 425 … … 435 443 } 436 444 else if( *szEnd == '\0' 437 || (*szEnd == '.' && *(szEnd+1) == '\0')438 || (*szEnd == '-' && *(szEnd+1) == '\0')439 || (*szEnd == '+' && *(szEnd+1) == '\0')440 || (*szEnd == 'E' && *(szEnd+1) == '\0')441 || (*szEnd == 'E' && *(szEnd+1) == '-' && *(szEnd+2) == '\0')442 || (*szEnd == 'E' && *(szEnd+1) == '+' && *(szEnd+2) == '\0')443 || (*szEnd == 'e' && *(szEnd+1) == '\0')444 || (*szEnd == 'e' && *(szEnd+1) == '-' && *(szEnd+2) == '\0')445 || (*szEnd == 'e' && *(szEnd+1) == '+' && *(szEnd+2) == '\0'))445 || (*szEnd == '.' && *(szEnd+1) == '\0') 446 || (*szEnd == '-' && *(szEnd+1) == '\0') 447 || (*szEnd == '+' && *(szEnd+1) == '\0') 448 || (*szEnd == 'E' && *(szEnd+1) == '\0') 449 || (*szEnd == 'E' && *(szEnd+1) == '-' && *(szEnd+2) == '\0') 450 || (*szEnd == 'E' && *(szEnd+1) == '+' && *(szEnd+2) == '\0') 451 || (*szEnd == 'e' && *(szEnd+1) == '\0') 452 || (*szEnd == 'e' && *(szEnd+1) == '-' && *(szEnd+2) == '\0') 453 || (*szEnd == 'e' && *(szEnd+1) == '+' && *(szEnd+2) == '\0')) 446 454 { 447 455 /* Number was interrupted by a nul character */ … … 510 518 if( *szEnd != '\0' && *szEnd != poGDS->szEOL[0] ) 511 519 CPLDebug( "GSAG", "Grid row %d does not end with a newline. " 512 "Possible skew.\n", nBlockYOff );520 "Possible skew.\n", nBlockYOff ); 513 521 514 522 while( isspace( *szEnd ) ) … … 520 528 nMaxLineSize = nCharsExamined + 1; 521 529 522 panLineOffset[nBlockYOff + 1] = panLineOffset[nBlockYOff] + nCharsExamined; 530 if( nBlockYOff > 0 ) 531 panLineOffset[nBlockYOff - 1] = 532 panLineOffset[nBlockYOff] + nCharsExamined; 533 534 nLastReadLine = nBlockYOff; 523 535 524 536 VSIFree( szLineBuf ); … … 551 563 || nMinZRow < 0 || nMaxZRow < 0 ) 552 564 { 553 padfRowMinZ = (double *)VSIMalloc( nRasterYSize *sizeof(double) );565 padfRowMinZ = (double *)VSIMalloc( nRasterYSize * sizeof(double) ); 554 566 if( padfRowMinZ == NULL ) 555 567 { … … 559 571 } 560 572 561 padfRowMaxZ = (double *)VSIMalloc( nRasterYSize *sizeof(double) );573 padfRowMaxZ = (double *)VSIMalloc( nRasterYSize * sizeof(double) ); 562 574 if( padfRowMaxZ == NULL ) 563 575 { … … 853 865 854 866 size_t nRead = VSIFReadL( pabyHeader, 1, nMAX_HEADER_SIZE-1, poDS->fp ); 855 pabyHeader[nRead +1] = '\0';856 } 857 858 const char *szErrorMsg ;867 pabyHeader[nRead] = '\0'; 868 } 869 870 const char *szErrorMsg = NULL; 859 871 const char *szStart = pabyHeader + 5; 860 872 char *szEnd; … … 880 892 poDS->nRasterXSize = INT_MAX; 881 893 } 894 else if ( nTemp == 0 ) 895 { 896 szErrorMsg = "Number of X axis grid columns is zero, which is invalid.\n"; 897 goto error; 898 } 882 899 else 883 900 { … … 898 915 "Number of Y axis grid rows not representable.\n" ); 899 916 poDS->nRasterYSize = INT_MAX; 917 } 918 else if ( nTemp == 0) 919 { 920 szErrorMsg = "Number of Y axis grid rows is zero, which is invalid.\n"; 921 goto error; 900 922 } 901 923 else … … 994 1016 { 995 1017 GSAGRasterBand *poBand = new GSAGRasterBand( poDS, 1, szEnd-pabyHeader ); 1018 if( poBand->panLineOffset == NULL ) 1019 { 1020 delete poBand; 1021 goto error; 1022 } 1023 996 1024 poBand->dfMinX = dfMinX; 997 1025 poBand->dfMaxX = dfMaxX; … … 1025 1053 delete poDS; 1026 1054 1027 CPLError( CE_Failure, CPLE_AppDefined, szErrorMsg ); 1055 if (szErrorMsg) 1056 CPLError( CE_Failure, CPLE_AppDefined, szErrorMsg ); 1028 1057 return NULL; 1029 1058 } … … 1441 1470 1442 1471 /************************************************************************/ 1443 /* Create() */1444 /************************************************************************/1445 1446 GDALDataset *GSAGDataset::Create( const char * pszFilename,1447 int nXSize, int nYSize, int nBands,1448 GDALDataType eType,1449 char **papszParmList )1450 1451 {1452 if( nXSize <= 0 || nYSize <= 0 )1453 {1454 CPLError( CE_Failure, CPLE_IllegalArg,1455 "Unable to create grid, both X and Y size must be "1456 "non-negative.\n" );1457 1458 return NULL;1459 }1460 1461 if( eType != GDT_Byte && eType != GDT_Float32 && eType != GDT_UInt161462 && eType != GDT_Int16 && eType != GDT_Float64 && eType != GDT_Int321463 && eType != GDT_UInt32 )1464 {1465 CPLError( CE_Failure, CPLE_AppDefined,1466 "Golden Software ASCII Grid only supports Byte, Int16, "1467 "Uint16, Int32, Uint32, Float32, and Float64 datatypes. "1468 "Unable to create with type %s.\n",1469 GDALGetDataTypeName( eType ) );1470 1471 return NULL;1472 }1473 1474 FILE *fp = VSIFOpenL( pszFilename, "w+b" );1475 1476 if( fp == NULL )1477 {1478 CPLError( CE_Failure, CPLE_OpenFailed,1479 "Attempt to create file '%s' failed.\n",1480 pszFilename );1481 return NULL;1482 }1483 1484 std::ostringstream ssHeader;1485 1486 ssHeader << "DSAA\x0D\x0A";1487 ssHeader << nXSize << " " << nYSize << "\x0D\x0A";1488 ssHeader << 0.0 << " " << nXSize << "\x0D\x0A";1489 ssHeader << 0.0 << " " << nYSize << "\x0D\x0A";1490 ssHeader << 0.0 << " " << 0.0 << "\x0D\x0A";1491 1492 if( VSIFWriteL( (void *)ssHeader.str().c_str(), 1, ssHeader.str().length(),1493 fp ) != ssHeader.str().length() )1494 {1495 VSIFCloseL( fp );1496 CPLError( CE_Failure, CPLE_FileIO,1497 "Unable to create copy, writing header failed.\n" );1498 return NULL;1499 }1500 1501 /* grid data, row major, max 10 values per line (to mimic Surfer) */1502 std::ostringstream ssOutStream;1503 ssOutStream.precision( nFIELD_PRECISION );1504 ssOutStream.setf( std::ios::uppercase );1505 ssOutStream << dfNODATA_VALUE << " ";1506 CPLString sOut = ssOutStream.str();1507 const char *szOut = sOut.c_str();1508 size_t nOutLen = sOut.length();1509 for( int iRow=0; iRow<nYSize; iRow++ )1510 {1511 for( int iLine=0; iLine<nXSize/10+1; iLine++ )1512 {1513 for( int iCol=0; iCol<10 && iLine*10+iCol<nXSize; iCol++ )1514 {1515 if( VSIFWriteL( szOut, 1, nOutLen, fp ) != nOutLen )1516 {1517 CPLError( CE_Failure, CPLE_FileIO,1518 "Unable to write grid cell. Disk full?\n" );1519 return NULL;1520 }1521 }1522 1523 if( VSIFWriteL( (void *)"\x0D\x0A", 1, 2, fp ) != 2 )1524 {1525 CPLError( CE_Failure, CPLE_FileIO,1526 "Unable to finish write of grid line. Disk full?\n" );1527 return NULL;1528 }1529 }1530 1531 if( VSIFWriteL( (void *)"\x0D\x0A", 1, 2, fp ) != 2 )1532 {1533 CPLError( CE_Failure, CPLE_FileIO,1534 "Unable to finish write of grid row. Disk full?\n" );1535 return NULL;1536 }1537 }1538 1539 VSIFCloseL( fp );1540 1541 return (GDALDataset *)GDALOpen( pszFilename, GA_Update );1542 }1543 1544 /************************************************************************/1545 1472 /* CreateCopy() */ 1546 1473 /************************************************************************/ … … 1633 1560 /* Copy band data. */ 1634 1561 /* -------------------------------------------------------------------- */ 1635 double *pdfData = (double *)VSIMalloc( nXSize * sizeof( double ) );1562 double *pdfData = (double *)VSIMalloc( nXSize * sizeof( double ) ); 1636 1563 if( pdfData == NULL ) 1637 1564 { … … 1649 1576 for( int iRow=0; iRow<nYSize; iRow++ ) 1650 1577 { 1651 CPLErr eErr = poSrcBand->RasterIO( GF_Read, 0, iRow,1578 CPLErr eErr = poSrcBand->RasterIO( GF_Read, 0, nYSize-iRow-1, 1652 1579 nXSize, 1, pdfData, 1653 1580 nXSize, 1, GDT_Float64, 0, 0 ); … … 1892 1819 "Float32 Float64" ); 1893 1820 1894 poDriver->pfnOpen = GSAGDataset::Open; 1895 poDriver->pfnCreate = GSAGDataset::Create; 1821 poDriver->pfnOpen = GSAGDataset::Open; 1896 1822 poDriver->pfnCreateCopy = GSAGDataset::CreateCopy; 1897 1823 poDriver->pfnDelete = GSAGDataset::Delete;
