GMLFeature *GMLReader::NextFeature() { if (!m_bReadStarted) { if (oParser == NULL) SetupParser(); if (fpGML == NULL) fpGML = VSIFOpenL(m_pszFilename, "rt"); m_bReadStarted = TRUE; } if (fpGML == NULL || m_bStopParsing) return NULL; if (nFeatureTabIndex < nFeatureTabLength) { return ppoFeatureTab[nFeatureTabIndex++]; } if (VSIFEofL(fpGML)) return NULL; char aBuf[BUFSIZ]; CPLFree(ppoFeatureTab); ppoFeatureTab = NULL; nFeatureTabLength = 0; nFeatureTabIndex = 0; int nDone; do { m_poGMLHandler->ResetDataHandlerCounter(); unsigned int nLen = (unsigned int)VSIFReadL( aBuf, 1, sizeof(aBuf), fpGML ); nDone = VSIFEofL(fpGML); if (XML_Parse(oParser, aBuf, nLen, nDone) == XML_STATUS_ERROR) { CPLError(CE_Failure, CPLE_AppDefined, "XML parsing of GML file failed : %s " "at line %d, column %d", XML_ErrorString(XML_GetErrorCode(oParser)), (int)XML_GetCurrentLineNumber(oParser), (int)XML_GetCurrentColumnNumber(oParser)); m_bStopParsing = TRUE; } if (!m_bStopParsing) m_bStopParsing = m_poGMLHandler->HasStoppedParsing(); } while (!nDone && !m_bStopParsing && nFeatureTabLength == 0); return (nFeatureTabLength) ? ppoFeatureTab[nFeatureTabIndex++] : NULL; }
OGRFeature *OGRJMLLayer::GetNextFeature() { if (!bHasReadSchema) LoadSchema(); if (bStopParsing) return nullptr; if (nFeatureTabIndex < nFeatureTabLength) { return ppoFeatureTab[nFeatureTabIndex++]; } if (VSIFEofL(fp)) return nullptr; char aBuf[BUFSIZ]; nFeatureTabLength = 0; nFeatureTabIndex = 0; nWithoutEventCounter = 0; int nDone = 0; do { nDataHandlerCounter = 0; unsigned int nLen = (unsigned int)VSIFReadL( aBuf, 1, sizeof(aBuf), fp ); nDone = VSIFEofL(fp); if (XML_Parse(oParser, aBuf, nLen, nDone) == XML_STATUS_ERROR) { CPLError(CE_Failure, CPLE_AppDefined, "XML parsing of JML file failed : %s " "at line %d, column %d", XML_ErrorString(XML_GetErrorCode(oParser)), (int)XML_GetCurrentLineNumber(oParser), (int)XML_GetCurrentColumnNumber(oParser)); bStopParsing = true; } nWithoutEventCounter ++; } while (!nDone && !bStopParsing && nFeatureTabLength == 0 && nWithoutEventCounter < 10); if (nWithoutEventCounter == 10) { CPLError( CE_Failure, CPLE_AppDefined, "Too much data inside one element. File probably corrupted"); bStopParsing = true; } return (nFeatureTabLength) ? ppoFeatureTab[nFeatureTabIndex++] : nullptr; }
int main( int nArgc, char ** papszArgv ) { const char *pszFilename; FILE *fp; CEOSRecord *psRecord; int nPosition = 0; if( nArgc > 1 ) pszFilename = papszArgv[1]; else pszFilename = "imag_01.dat"; fp = VSIFOpenL( pszFilename, "rb" ); if( fp == NULL ) { fprintf( stderr, "Can't open %s at all.\n", pszFilename ); exit( 1 ); } while( !VSIFEofL(fp) && (psRecord = CEOSReadRecord( fp )) != NULL ) { printf( "%9d:%4d:%8x:%d\n", nPosition, psRecord->nRecordNum, psRecord->nRecordType, psRecord->nLength ); CEOSDestroyRecord( psRecord ); nPosition = (int) VSIFTellL( fp ); } VSIFCloseL( fp ); exit( 0 ); }
void KML::parse() { std::size_t nDone = 0; std::size_t nLen = 0; char aBuf[BUFSIZ] = { 0 }; if( NULL == pKMLFile_ ) { sError_ = "No file given"; return; } if(poTrunk_ != NULL) { delete poTrunk_; poTrunk_ = NULL; } if(poCurrent_ != NULL) { delete poCurrent_; poCurrent_ = NULL; } XML_Parser oParser = OGRCreateExpatXMLParser(); XML_SetUserData(oParser, this); XML_SetElementHandler(oParser, startElement, endElement); XML_SetCharacterDataHandler(oParser, dataHandler); oCurrentParser = oParser; nWithoutEventCounter = 0; do { nDataHandlerCounter = 0; nLen = (int)VSIFReadL( aBuf, 1, sizeof(aBuf), pKMLFile_ ); nDone = VSIFEofL(pKMLFile_); if (XML_Parse(oParser, aBuf, nLen, nDone) == XML_STATUS_ERROR) { CPLError(CE_Failure, CPLE_AppDefined, "XML parsing of KML file failed : %s at line %d, column %d", XML_ErrorString(XML_GetErrorCode(oParser)), (int)XML_GetCurrentLineNumber(oParser), (int)XML_GetCurrentColumnNumber(oParser)); XML_ParserFree(oParser); VSIRewindL(pKMLFile_); return; } nWithoutEventCounter ++; } while (!nDone && nLen > 0 && nWithoutEventCounter < 10); XML_ParserFree(oParser); VSIRewindL(pKMLFile_); poCurrent_ = NULL; if (nWithoutEventCounter == 10) { CPLError(CE_Failure, CPLE_AppDefined, "Too much data inside one element. File probably corrupted"); } }
int VSISubFileHandle::Eof() { if (nSubregionSize != 0) return VSIFTellL( fp ) >= nSubregionOffset + nSubregionSize; else return VSIFEofL( fp ); }
void MoveOverwrite(VSILFILE *fpDest,VSILFILE *fpSource) { VSIRewindL(fpSource); VSIRewindL(fpDest); VSIFTruncateL(fpDest,0); char anBuf[0x10000]; while (!VSIFEofL(fpSource)) { size_t nSize=VSIFReadL(anBuf,1,0x10000,fpSource); size_t nLeft=nSize; while (nLeft>0) nLeft-=VSIFWriteL(anBuf+nSize-nLeft,1,nLeft,fpDest); } VSIFCloseL(fpSource); VSIFFlushL(fpDest); }
void OGRGTMDataSource::AppendTemporaryFiles() { if( fpOutput == NULL ) return; if (numTrackpoints != 0 || numTracks != 0) { void* pBuffer = CPLMalloc(2048); size_t bytes; // Append Trackpoints to the output file fpTmpTrackpoints = VSIFOpenL( pszTmpTrackpoints, "r" ); if (fpTmpTrackpoints != NULL) { while ( !VSIFEofL(fpTmpTrackpoints) ) { bytes = VSIFReadL(pBuffer, 1, 2048, fpTmpTrackpoints); VSIFWriteL(pBuffer, bytes, 1, fpOutput); } VSIFCloseL( fpTmpTrackpoints ); fpTmpTrackpoints = NULL; } // Append Tracks to the output file fpTmpTracks = VSIFOpenL( pszTmpTracks, "r" ); if (fpTmpTracks != NULL) { while ( !VSIFEofL(fpTmpTracks) ) { bytes = VSIFReadL(pBuffer, 1, 2048, fpTmpTracks); VSIFWriteL(pBuffer, bytes, 1, fpOutput); } VSIFCloseL( fpTmpTracks ); fpTmpTracks = NULL; } CPLFree(pBuffer); } }
void SerializeCeosRecordsFromFile(Link_t *record_list, VSILFILE *fp) { CeosRecord_t *crec; Link_t *Link; while(!VSIFEofL(fp)) { crec = HMalloc(sizeof(CeosRecord_t)); VSIFReadL(crec,sizeof(CeosRecord_t),1,fp); crec->Buffer = HMalloc(crec->Length * sizeof(char) ); VSIFReadL(crec->Buffer,sizeof(char),crec->Length,fp); Link = ceos2CreateLink(crec); AddLink(record_list,Link); } }
void OGRVFPLayer::LoadSchema() { oSchemaParser = OGRCreateExpatXMLParser(); XML_SetElementHandler(oSchemaParser, ::startElementLoadSchemaCbk, ::endElementLoadSchemaCbk); XML_SetCharacterDataHandler(oSchemaParser, ::dataHandlerLoadSchemaCbk); XML_SetUserData(oSchemaParser, this); VSIFSeekL( fpVFP, 0, SEEK_SET ); bStopParsing = FALSE; nWithoutEventCounter = 0; interestingDepthLevel = depthLevel = 0; inInterestingElement = FALSE; char aBuf[BUFSIZ]; int nDone; do { nDataHandlerCounter = 0; unsigned int nLen = (unsigned int)VSIFReadL( aBuf, 1, sizeof(aBuf), fpVFP ); nDone = VSIFEofL(fpVFP); if (XML_Parse(oSchemaParser, aBuf, nLen, nDone) == XML_STATUS_ERROR) { CPLError(CE_Failure, CPLE_AppDefined, "XML parsing of GPX file failed : %s at line %d, column %d", XML_ErrorString(XML_GetErrorCode(oSchemaParser)), (int)XML_GetCurrentLineNumber(oSchemaParser), (int)XML_GetCurrentColumnNumber(oSchemaParser)); bStopParsing = TRUE; break; } nWithoutEventCounter ++; } while (!nDone && !bStopParsing && nWithoutEventCounter < 10); if (nWithoutEventCounter == 10) { CPLError(CE_Failure, CPLE_AppDefined, "Too much data inside one element. File probably corrupted"); bStopParsing = TRUE; } XML_ParserFree(oSchemaParser); oSchemaParser = NULL; VSIFSeekL( fpVFP, 0, SEEK_SET ); }
int FileDataSource::DataSourceFeof() { return VSIFEofL( fp ); }
/** This function parses the whole file to build the schema */ void OGRSVGLayer::LoadSchema() { CPLAssert(poFeatureDefn == NULL); for(int i=0;i<poDS->GetLayerCount();i++) { OGRSVGLayer* poLayer = (OGRSVGLayer*)poDS->GetLayer(i); poLayer->poFeatureDefn = new OGRFeatureDefn( poLayer->osLayerName ); poLayer->poFeatureDefn->Reference(); poLayer->poFeatureDefn->SetGeomType(poLayer->GetGeomType()); poLayer->poFeatureDefn->GetGeomFieldDefn(0)->SetSpatialRef(poLayer->poSRS); } oSchemaParser = OGRCreateExpatXMLParser(); XML_SetElementHandler(oSchemaParser, ::startElementLoadSchemaCbk, ::endElementLoadSchemaCbk); XML_SetCharacterDataHandler(oSchemaParser, ::dataHandlerLoadSchemaCbk); XML_SetUserData(oSchemaParser, this); if (fpSVG == NULL) return; VSIFSeekL( fpSVG, 0, SEEK_SET ); inInterestingElement = FALSE; depthLevel = 0; nWithoutEventCounter = 0; bStopParsing = FALSE; char aBuf[BUFSIZ]; int nDone; do { nDataHandlerCounter = 0; unsigned int nLen = (unsigned int)VSIFReadL( aBuf, 1, sizeof(aBuf), fpSVG ); nDone = VSIFEofL(fpSVG); if (XML_Parse(oSchemaParser, aBuf, nLen, nDone) == XML_STATUS_ERROR) { CPLError(CE_Failure, CPLE_AppDefined, "XML parsing of SVG file failed : %s at line %d, column %d", XML_ErrorString(XML_GetErrorCode(oSchemaParser)), (int)XML_GetCurrentLineNumber(oSchemaParser), (int)XML_GetCurrentColumnNumber(oSchemaParser)); bStopParsing = TRUE; break; } nWithoutEventCounter ++; } while (!nDone && !bStopParsing && nWithoutEventCounter < 1000); if (nWithoutEventCounter == 1000) { CPLError(CE_Failure, CPLE_AppDefined, "Too much data inside one element. File probably corrupted"); bStopParsing = TRUE; } XML_ParserFree(oSchemaParser); oSchemaParser = NULL; VSIFSeekL( fpSVG, 0, SEEK_SET ); }
int TigerCompleteChain::GetShapeRecordId( int nChainId, int nTLID ) { CPLAssert( nChainId >= 0 && nChainId < GetFeatureCount() ); if( fpShape == NULL || panShapeRecordId == NULL ) return -1; /* -------------------------------------------------------------------- */ /* Do we already have the answer? */ /* -------------------------------------------------------------------- */ if( panShapeRecordId[nChainId] != 0 ) return panShapeRecordId[nChainId]; /* -------------------------------------------------------------------- */ /* If we don't already have this value, then search from the */ /* previous known record. */ /* -------------------------------------------------------------------- */ int iTestChain, nWorkingRecId; for( iTestChain = nChainId-1; iTestChain >= 0 && panShapeRecordId[iTestChain] <= 0; iTestChain-- ) {} if( iTestChain < 0 ) { iTestChain = -1; nWorkingRecId = 1; } else { nWorkingRecId = panShapeRecordId[iTestChain]+1; } /* -------------------------------------------------------------------- */ /* If we have non existent records following (-1's) we can */ /* narrow our search a bit. */ /* -------------------------------------------------------------------- */ while( panShapeRecordId[iTestChain+1] == -1 ) { iTestChain++; } /* -------------------------------------------------------------------- */ /* Read records up to the maximum distance that is possibly */ /* required, looking for our target TLID. */ /* -------------------------------------------------------------------- */ int nMaxChainToRead = nChainId - iTestChain; int nChainsRead = 0; char achShapeRec[OGR_TIGER_RECBUF_LEN]; int nShapeRecLen = psRT2Info->nRecordLength + nRecordLength - psRT1Info->nRecordLength; while( nChainsRead < nMaxChainToRead ) { if( VSIFSeekL( fpShape, (nWorkingRecId-1) * nShapeRecLen, SEEK_SET ) != 0 ) { CPLError( CE_Failure, CPLE_FileIO, "Failed to seek to %d of %s2", (nWorkingRecId-1) * nShapeRecLen, pszModule ); return -2; } if( VSIFReadL( achShapeRec, psRT2Info->nRecordLength, 1, fpShape ) != 1 ) { if( !VSIFEofL( fpShape ) ) { CPLError( CE_Failure, CPLE_FileIO, "Failed to read record %d of %s2", nWorkingRecId-1, pszModule ); return -2; } else return -1; } if( atoi(GetField(achShapeRec,6,15)) == nTLID ) { panShapeRecordId[nChainId] = nWorkingRecId; return nWorkingRecId; } if( atoi(GetField(achShapeRec,16,18)) == 1 ) { nChainsRead++; } nWorkingRecId++; } panShapeRecordId[nChainId] = -1; return -1; }
CEOSRecord * CEOSReadRecord( CEOSImage *psImage ) { GByte abyHeader[12]; CEOSRecord *psRecord; /* -------------------------------------------------------------------- */ /* Read the standard CEOS header. */ /* -------------------------------------------------------------------- */ if( VSIFEofL( psImage->fpImage ) ) return NULL; if( VSIFReadL( abyHeader, 1, 12, psImage->fpImage ) != 12 ) { CPLError( CE_Failure, CPLE_FileIO, "Ran out of data reading CEOS record." ); return NULL; } /* -------------------------------------------------------------------- */ /* Extract this information. */ /* -------------------------------------------------------------------- */ psRecord = (CEOSRecord *) CPLMalloc(sizeof(CEOSRecord)); if( psImage->bLittleEndian ) { CPL_SWAP32PTR( abyHeader + 0 ); CPL_SWAP32PTR( abyHeader + 8 ); } psRecord->nRecordNum = abyHeader[0] * 256 * 256 * 256 + abyHeader[1] * 256 * 256 + abyHeader[2] * 256 + abyHeader[3]; psRecord->nRecordType = abyHeader[4] * 256 * 256 * 256 + abyHeader[5] * 256 * 256 + abyHeader[6] * 256 + abyHeader[7]; psRecord->nLength = abyHeader[8] * 256 * 256 * 256 + abyHeader[9] * 256 * 256 + abyHeader[10] * 256 + abyHeader[11]; /* -------------------------------------------------------------------- */ /* Does it look reasonable? We assume there can't be too many */ /* records and that the length must be between 12 and 200000. */ /* -------------------------------------------------------------------- */ if( psRecord->nRecordNum < 0 || psRecord->nRecordNum > 200000 || psRecord->nLength < 12 || psRecord->nLength > 200000 ) { CPLError( CE_Failure, CPLE_AppDefined, "CEOS record leader appears to be corrupt.\n" "Record Number = %d, Record Length = %d\n", psRecord->nRecordNum, psRecord->nLength ); CPLFree( psRecord ); return NULL; } /* -------------------------------------------------------------------- */ /* Read the remainder of the record into a buffer. Ensure that */ /* the first 12 bytes gets moved into this buffer as well. */ /* -------------------------------------------------------------------- */ psRecord->pachData = (char *) VSIMalloc(psRecord->nLength ); if( psRecord->pachData == NULL ) { CPLError( CE_Failure, CPLE_OutOfMemory, "Out of memory allocated %d bytes for CEOS record data.\n" "Are you sure you aren't leaking CEOSRecords?\n", psRecord->nLength ); CPLFree( psRecord ); return NULL; } memcpy( psRecord->pachData, abyHeader, 12 ); if( (int)VSIFReadL( psRecord->pachData + 12, 1, psRecord->nLength-12, psImage->fpImage ) != psRecord->nLength - 12 ) { CPLError( CE_Failure, CPLE_FileIO, "Short read on CEOS record data.\n" ); CPLFree( psRecord ); return NULL; } return psRecord; }
GDALDataset *RDataset::Open( GDALOpenInfo * poOpenInfo ) { #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION if( poOpenInfo->pabyHeader == nullptr ) return nullptr; #else // During fuzzing, do not use Identify to reject crazy content. if( !Identify(poOpenInfo) ) return nullptr; #endif // Confirm the requested access is supported. if( poOpenInfo->eAccess == GA_Update ) { CPLError(CE_Failure, CPLE_NotSupported, "The R driver does not support update access to existing" " datasets."); return nullptr; } // Do we need to route the file through the decompression machinery? const bool bCompressed = memcmp(poOpenInfo->pabyHeader, "\037\213\b", 3) == 0; const CPLString osAdjustedFilename = std::string(bCompressed ? "/vsigzip/" : "") + poOpenInfo->pszFilename; // Establish this as a dataset and open the file using VSI*L. RDataset *poDS = new RDataset(); poDS->fp = VSIFOpenL(osAdjustedFilename, "r"); if( poDS->fp == nullptr ) { delete poDS; return nullptr; } poDS->bASCII = STARTS_WITH_CI( reinterpret_cast<char *>(poOpenInfo->pabyHeader), "RDA2\nA\n"); // Confirm this is a version 2 file. VSIFSeekL(poDS->fp, 7, SEEK_SET); if( poDS->ReadInteger() != R_LISTSXP ) { delete poDS; CPLError(CE_Failure, CPLE_OpenFailed, "It appears %s is not a version 2 R object file after all!", poOpenInfo->pszFilename); return nullptr; } // Skip the version values. poDS->ReadInteger(); poDS->ReadInteger(); // Confirm we have a numeric vector object in a pairlist. CPLString osObjName; int nObjCode = 0; if( !poDS->ReadPair(osObjName, nObjCode) ) { delete poDS; return nullptr; } if( nObjCode % 256 != R_REALSXP ) { delete poDS; CPLError(CE_Failure, CPLE_OpenFailed, "Failed to find expected numeric vector object."); return nullptr; } poDS->SetMetadataItem("R_OBJECT_NAME", osObjName); // Read the count. const int nValueCount = poDS->ReadInteger(); if( nValueCount < 0 ) { CPLError( CE_Failure, CPLE_AppDefined, "nValueCount < 0: %d", nValueCount); delete poDS; return nullptr; } poDS->nStartOfData = VSIFTellL(poDS->fp); // TODO(schwehr): Factor in the size of doubles. VSIStatBufL stat; const int dStatSuccess = VSIStatExL(osAdjustedFilename, &stat, VSI_STAT_SIZE_FLAG); if( dStatSuccess != 0 || static_cast<vsi_l_offset>(nValueCount) > stat.st_size - poDS->nStartOfData ) { CPLError( CE_Failure, CPLE_AppDefined, "Corrupt file. " "Object claims to be larger than available bytes. " "%d > " CPL_FRMT_GUIB, nValueCount, stat.st_size - poDS->nStartOfData); delete poDS; return nullptr; } // Read/Skip ahead to attributes. if( poDS->bASCII ) { poDS->padfMatrixValues = static_cast<double *>(VSIMalloc2(nValueCount, sizeof(double))); if (poDS->padfMatrixValues == nullptr) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot allocate %d doubles", nValueCount); delete poDS; return nullptr; } for( int iValue = 0; iValue < nValueCount; iValue++ ) poDS->padfMatrixValues[iValue] = poDS->ReadFloat(); } else { VSIFSeekL(poDS->fp, 8 * nValueCount, SEEK_CUR); } // Read pairs till we run out, trying to find a few items that // have special meaning to us. poDS->nRasterXSize = 0; poDS->nRasterYSize = 0; int nBandCount = 0; while( poDS->ReadPair(osObjName, nObjCode) && nObjCode != 254 ) { if( osObjName == "dim" && nObjCode % 256 == R_INTSXP ) { const int nCount = poDS->ReadInteger(); if( nCount == 2 ) { poDS->nRasterXSize = poDS->ReadInteger(); poDS->nRasterYSize = poDS->ReadInteger(); nBandCount = 1; } else if( nCount == 3 ) { poDS->nRasterXSize = poDS->ReadInteger(); poDS->nRasterYSize = poDS->ReadInteger(); nBandCount = poDS->ReadInteger(); } else { CPLError(CE_Failure, CPLE_AppDefined, "R 'dim' dimension wrong."); delete poDS; return nullptr; } } else if( nObjCode % 256 == R_REALSXP ) { int nCount = poDS->ReadInteger(); while( nCount > 0 && !VSIFEofL(poDS->fp) ) { nCount --; poDS->ReadFloat(); } } else if( nObjCode % 256 == R_INTSXP ) { int nCount = poDS->ReadInteger(); while( nCount > 0 && !VSIFEofL(poDS->fp) ) { nCount --; poDS->ReadInteger(); } } else if( nObjCode % 256 == R_STRSXP ) { int nCount = poDS->ReadInteger(); while( nCount > 0 && !VSIFEofL(poDS->fp) ) { nCount --; poDS->ReadString(); } } else if( nObjCode % 256 == R_CHARSXP ) { poDS->ReadString(); } } if( poDS->nRasterXSize == 0 ) { delete poDS; CPLError(CE_Failure, CPLE_AppDefined, "Failed to find dim dimension information for R dataset."); return nullptr; } if (!GDALCheckDatasetDimensions(poDS->nRasterXSize, poDS->nRasterYSize) || !GDALCheckBandCount(nBandCount, TRUE)) { delete poDS; return nullptr; } GIntBig result = 0; bool ok = SafeMult(nBandCount, poDS->nRasterXSize, &result); ok &= SafeMult(result, poDS->nRasterYSize, &result); if( !ok || nValueCount < result ) { CPLError(CE_Failure, CPLE_AppDefined, "Not enough pixel data."); delete poDS; return nullptr; } // Create the raster band object(s). for( int iBand = 0; iBand < nBandCount; iBand++ ) { GDALRasterBand *poBand = nullptr; if( poDS->bASCII ) poBand = new RRasterBand( poDS, iBand + 1, poDS->padfMatrixValues + iBand * poDS->nRasterXSize * poDS->nRasterYSize); else poBand = new RawRasterBand( poDS, iBand + 1, poDS->fp, poDS->nStartOfData + poDS->nRasterXSize * poDS->nRasterYSize * 8 * iBand, 8, poDS->nRasterXSize * 8, GDT_Float64, !CPL_IS_LSB, TRUE, FALSE); poDS->SetBand(iBand + 1, poBand); } // Initialize any PAM information. poDS->SetDescription(poOpenInfo->pszFilename); poDS->TryLoadXML(); // Check for overviews. poDS->oOvManager.Initialize(poDS, poOpenInfo->pszFilename); return poDS; }
int TigerCompleteChain::AddShapePoints( int nTLID, int nRecordId, OGRLineString * poLine, CPL_UNUSED int nSeqNum ) { int nShapeRecId; nShapeRecId = GetShapeRecordId( nRecordId, nTLID ); // -2 means an error occured. if( nShapeRecId == -2 ) return FALSE; // -1 means there are no extra shape vertices, but things worked fine. if( nShapeRecId == -1 ) return TRUE; /* -------------------------------------------------------------------- */ /* Read all the sequential records with the same TLID. */ /* -------------------------------------------------------------------- */ char achShapeRec[OGR_TIGER_RECBUF_LEN]; int nShapeRecLen = psRT2Info->nRecordLength + nRecordLength - psRT1Info->nRecordLength; for( ; TRUE; nShapeRecId++ ) { int nBytesRead = 0; if( VSIFSeekL( fpShape, (nShapeRecId-1) * nShapeRecLen, SEEK_SET ) != 0 ) { CPLError( CE_Failure, CPLE_FileIO, "Failed to seek to %d of %s2", (nShapeRecId-1) * nShapeRecLen, pszModule ); return FALSE; } nBytesRead = VSIFReadL( achShapeRec, 1, psRT2Info->nRecordLength, fpShape ); /* ** Handle case where the last record in the file is full. We will ** try to read another record but not find it. We require that we ** have found at least one shape record for this case though. */ if( nBytesRead <= 0 && VSIFEofL( fpShape ) && poLine->getNumPoints() > 0 ) break; if( nBytesRead != psRT2Info->nRecordLength ) { CPLError( CE_Failure, CPLE_FileIO, "Failed to read %d bytes of record %d of %s2 at offset %d", psRT2Info->nRecordLength, nShapeRecId, pszModule, (nShapeRecId-1) * nShapeRecLen ); return FALSE; } if( atoi(GetField(achShapeRec,6,15)) != nTLID ) break; /* -------------------------------------------------------------------- */ /* Translate the locations into OGRLineString vertices. */ /* -------------------------------------------------------------------- */ int iVertex; for( iVertex = 0; iVertex < 10; iVertex++ ) { int iStart = 19 + 19*iVertex; int nX = atoi(GetField(achShapeRec,iStart,iStart+9)); int nY = atoi(GetField(achShapeRec,iStart+10,iStart+18)); if( nX == 0 && nY == 0 ) break; poLine->addPoint( nX / 1000000.0, nY / 1000000.0 ); } /* -------------------------------------------------------------------- */ /* Don't get another record if this one was incomplete. */ /* -------------------------------------------------------------------- */ if( iVertex < 10 ) break; } return TRUE; }
int VSISubFileHandle::Eof() { return VSIFEofL( fp ); }
OGRFeature *OGRSVGLayer::GetNextFeature() { GetLayerDefn(); if (fpSVG == NULL) return NULL; if (bStopParsing) return NULL; #ifdef HAVE_EXPAT if (nFeatureTabIndex < nFeatureTabLength) { return ppoFeatureTab[nFeatureTabIndex++]; } if (VSIFEofL(fpSVG)) return NULL; char aBuf[BUFSIZ]; CPLFree(ppoFeatureTab); ppoFeatureTab = NULL; nFeatureTabLength = 0; nFeatureTabIndex = 0; nWithoutEventCounter = 0; iCurrentField = -1; int nDone; do { nDataHandlerCounter = 0; unsigned int nLen = (unsigned int) VSIFReadL( aBuf, 1, sizeof(aBuf), fpSVG ); nDone = VSIFEofL(fpSVG); if (XML_Parse(oParser, aBuf, nLen, nDone) == XML_STATUS_ERROR) { CPLError(CE_Failure, CPLE_AppDefined, "XML parsing of SVG file failed : %s at line %d, column %d", XML_ErrorString(XML_GetErrorCode(oParser)), (int)XML_GetCurrentLineNumber(oParser), (int)XML_GetCurrentColumnNumber(oParser)); bStopParsing = TRUE; break; } nWithoutEventCounter ++; } while (!nDone && nFeatureTabLength == 0 && !bStopParsing && nWithoutEventCounter < 1000); if (nWithoutEventCounter == 1000) { CPLError(CE_Failure, CPLE_AppDefined, "Too much data inside one element. File probably corrupted"); bStopParsing = TRUE; } return (nFeatureTabLength) ? ppoFeatureTab[nFeatureTabIndex++] : NULL; #else return NULL; #endif }
/** This function parses the beginning of the file to detect the fields */ void OGRJMLLayer::LoadSchema() { if (bHasReadSchema) return; bHasReadSchema = true; oParser = OGRCreateExpatXMLParser(); XML_SetElementHandler(oParser, ::startElementLoadSchemaCbk, ::endElementLoadSchemaCbk); XML_SetCharacterDataHandler(oParser, ::dataHandlerCbk); XML_SetUserData(oParser, this); VSIFSeekL( fp, 0, SEEK_SET ); char aBuf[BUFSIZ]; int nDone = 0; do { nDataHandlerCounter = 0; const unsigned int nLen = static_cast<unsigned int>( VSIFReadL( aBuf, 1, sizeof(aBuf), fp ) ); nDone = VSIFEofL(fp); if (XML_Parse(oParser, aBuf, nLen, nDone) == XML_STATUS_ERROR) { CPLError( CE_Failure, CPLE_AppDefined, "XML parsing of JML file failed : %s at line %d, " "column %d", XML_ErrorString(XML_GetErrorCode(oParser)), static_cast<int>(XML_GetCurrentLineNumber(oParser)), static_cast<int>(XML_GetCurrentColumnNumber(oParser)) ); bStopParsing = true; } nWithoutEventCounter ++; } while ( !nDone && !bStopParsing && !bSchemaFinished && nWithoutEventCounter < 10 ); XML_ParserFree(oParser); oParser = nullptr; if (nWithoutEventCounter == 10) { CPLError(CE_Failure, CPLE_AppDefined, "Too much data inside one element. File probably corrupted"); bStopParsing = true; } if( osCollectionElement.empty() || osFeatureElement.empty() || osGeometryElement.empty() ) { CPLError( CE_Failure, CPLE_AppDefined, "Missing CollectionElement, FeatureElement or " "GeometryElement" ); bStopParsing = true; } if( !osSRSName.empty() ) { if( osSRSName.find("http://www.opengis.net/gml/srs/epsg.xml#") == 0 ) { OGRSpatialReference* poSRS = new OGRSpatialReference(); poSRS->importFromEPSG(atoi(osSRSName.substr( strlen("http://www.opengis.net/gml/srs/epsg.xml#")).c_str())); poSRS->SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER); poFeatureDefn->GetGeomFieldDefn(0)->SetSpatialRef(poSRS); poSRS->Release(); } } nJCSGMLInputTemplateDepth = 0; nCollectionElementDepth = 0; nFeatureCollectionDepth = 0; nFeatureElementDepth = 0; nGeometryElementDepth = 0; nColumnDepth = 0; nNameDepth = 0; nTypeDepth = 0; nAttributeElementDepth = 0; ResetReading(); }
int OGRSVGDataSource::Open( const char * pszFilename, int bUpdateIn) { if (bUpdateIn) { CPLError(CE_Failure, CPLE_NotSupported, "OGR/SVG driver does not support opening a file in update mode"); return FALSE; } #ifdef HAVE_EXPAT pszName = CPLStrdup( pszFilename ); /* -------------------------------------------------------------------- */ /* Try to open the file. */ /* -------------------------------------------------------------------- */ CPLString osFilename(pszFilename); if (EQUAL(CPLGetExtension(pszFilename), "svgz") && strstr(pszFilename, "/vsigzip/") == NULL) { osFilename = CPLString("/vsigzip/") + pszFilename; pszFilename = osFilename.c_str(); } VSILFILE* fp = VSIFOpenL(pszFilename, "r"); if (fp == NULL) return FALSE; eValidity = SVG_VALIDITY_UNKNOWN; XML_Parser oParser = OGRCreateExpatXMLParser(); oCurrentParser = oParser; XML_SetUserData(oParser, this); XML_SetElementHandler(oParser, ::startElementValidateCbk, NULL); XML_SetCharacterDataHandler(oParser, ::dataHandlerValidateCbk); char aBuf[BUFSIZ]; int nDone; unsigned int nLen; int nCount = 0; /* Begin to parse the file and look for the <svg> element */ /* It *MUST* be the first element of an XML file */ /* So once we have read the first element, we know if we can */ /* handle the file or not with that driver */ do { nDataHandlerCounter = 0; nLen = (unsigned int) VSIFReadL( aBuf, 1, sizeof(aBuf), fp ); nDone = VSIFEofL(fp); if (XML_Parse(oParser, aBuf, nLen, nDone) == XML_STATUS_ERROR) { if (nLen <= BUFSIZ-1) aBuf[nLen] = 0; else aBuf[BUFSIZ-1] = 0; if (strstr(aBuf, "<?xml") && strstr(aBuf, "<svg")) { CPLError(CE_Failure, CPLE_AppDefined, "XML parsing of SVG file failed : %s at line %d, column %d", XML_ErrorString(XML_GetErrorCode(oParser)), (int)XML_GetCurrentLineNumber(oParser), (int)XML_GetCurrentColumnNumber(oParser)); } eValidity = SVG_VALIDITY_INVALID; break; } if (eValidity == SVG_VALIDITY_INVALID) { break; } else if (eValidity == SVG_VALIDITY_VALID) { break; } else { /* After reading 50 * BUFSIZE bytes, and not finding whether the file */ /* is SVG or not, we give up and fail silently */ nCount ++; if (nCount == 50) break; } } while (!nDone && nLen > 0 ); XML_ParserFree(oParser); VSIFCloseL(fp); if (eValidity == SVG_VALIDITY_VALID) { if (bIsCloudmade) { nLayers = 3; papoLayers =(OGRSVGLayer **) CPLRealloc(papoLayers, nLayers * sizeof(OGRSVGLayer*)); papoLayers[0] = new OGRSVGLayer( pszFilename, "points", SVG_POINTS, this ); papoLayers[1] = new OGRSVGLayer( pszFilename, "lines", SVG_LINES, this ); papoLayers[2] = new OGRSVGLayer( pszFilename, "polygons", SVG_POLYGONS, this ); } else { CPLDebug("SVG", "%s seems to be a SVG file, but not a Cloudmade vector one.", pszFilename); } } return (nLayers > 0); #else char aBuf[256]; VSILFILE* fp = VSIFOpenL(pszFilename, "r"); if (fp) { unsigned int nLen = (unsigned int)VSIFReadL( aBuf, 1, 255, fp ); aBuf[nLen] = 0; if (strstr(aBuf, "<?xml") && strstr(aBuf, "<svg") && strstr(aBuf, "http://cloudmade.com/")) { CPLError(CE_Failure, CPLE_NotSupported, "OGR/SVG driver has not been built with read support. " "Expat library required"); } VSIFCloseL(fp); } return FALSE; #endif }
CEOSRecord * CEOSReadRecord( CEOSImage *psImage ) { GByte abyHeader[12]; CEOSRecord *psRecord; GUInt32 nRecordNumUInt32, nLengthUInt32; /* -------------------------------------------------------------------- */ /* Read the standard CEOS header. */ /* -------------------------------------------------------------------- */ if( VSIFEofL( psImage->fpImage ) ) return NULL; if( VSIFReadL( abyHeader, 1, 12, psImage->fpImage ) != 12 ) { CPLError( CE_Failure, CPLE_FileIO, "Ran out of data reading CEOS record." ); return NULL; } /* -------------------------------------------------------------------- */ /* Extract this information. */ /* -------------------------------------------------------------------- */ psRecord = (CEOSRecord *) CPLMalloc(sizeof(CEOSRecord)); if( psImage->bLittleEndian ) { CPL_SWAP32PTR( abyHeader + 0 ); CPL_SWAP32PTR( abyHeader + 8 ); } nRecordNumUInt32 = (abyHeader[0] << 24) + (abyHeader[1] << 16) + (abyHeader[2] << 8) + abyHeader[3]; psRecord->nRecordType = (abyHeader[4] << 24) + (abyHeader[5] << 16) + (abyHeader[6] << 8) + abyHeader[7]; nLengthUInt32 = (abyHeader[8] << 24) + (abyHeader[9] << 16) + (abyHeader[10] << 8) + abyHeader[11]; /* -------------------------------------------------------------------- */ /* Does it look reasonable? We assume there can't be too many */ /* records and that the length must be between 12 and 200000. */ /* -------------------------------------------------------------------- */ if( nRecordNumUInt32 > 200000 || nLengthUInt32 < 12 || nLengthUInt32 > 200000 ) { CPLError( CE_Failure, CPLE_AppDefined, "CEOS record leader appears to be corrupt.\n" "Record Number = %u, Record Length = %u\n", nRecordNumUInt32, nLengthUInt32 ); CPLFree( psRecord ); return NULL; } psRecord->nRecordNum = (int)nRecordNumUInt32; psRecord->nLength = (int)nLengthUInt32; /* -------------------------------------------------------------------- */ /* Read the remainder of the record into a buffer. Ensure that */ /* the first 12 bytes gets moved into this buffer as well. */ /* -------------------------------------------------------------------- */ psRecord->pachData = (char *) VSI_MALLOC_VERBOSE(psRecord->nLength ); if( psRecord->pachData == NULL ) { CPLFree( psRecord ); return NULL; } memcpy( psRecord->pachData, abyHeader, 12 ); if( (int)VSIFReadL( psRecord->pachData + 12, 1, psRecord->nLength-12, psImage->fpImage ) != psRecord->nLength - 12 ) { CPLError( CE_Failure, CPLE_FileIO, "Short read on CEOS record data.\n" ); CPLFree( psRecord ); return NULL; } return psRecord; }
CPLErr GSAGDataset::ShiftFileContents( VSILFILE *fp, vsi_l_offset nShiftStart, int nShiftSize, const char *pszEOL ) { /* nothing to do for zero-shift */ if( nShiftSize == 0 ) return CE_None; /* make sure start location is sane */ if( nShiftStart < 0 || (nShiftSize < 0 && nShiftStart < static_cast<vsi_l_offset>(-nShiftSize)) ) nShiftStart = (nShiftSize > 0) ? 0 : -nShiftSize; /* get offset at end of file */ if( VSIFSeekL( fp, 0, SEEK_END ) != 0 ) { CPLError( CE_Failure, CPLE_FileIO, "Unable to seek to end of grid file.\n" ); return CE_Failure; } vsi_l_offset nOldEnd = VSIFTellL( fp ); /* If shifting past end, just zero-pad as necessary */ if( nShiftStart >= nOldEnd ) { if( nShiftSize < 0 ) { if( nShiftStart + nShiftSize >= nOldEnd ) return CE_None; if( VSIFSeekL( fp, nShiftStart + nShiftSize, SEEK_SET ) != 0 ) { CPLError( CE_Failure, CPLE_FileIO, "Unable to seek near end of file.\n" ); return CE_Failure; } /* ftruncate()? */ for( vsi_l_offset nPos = nShiftStart + nShiftSize; nPos > nOldEnd; nPos++ ) { if( VSIFWriteL( (void *)" ", 1, 1, fp ) != 1 ) { CPLError( CE_Failure, CPLE_FileIO, "Unable to write padding to grid file " "(Out of space?).\n" ); return CE_Failure; } } return CE_None; } else { for( vsi_l_offset nPos = nOldEnd; nPos < nShiftStart + nShiftSize; nPos++ ) { if( VSIFWriteL( (void *)" ", 1, 1, fp ) != 1 ) { CPLError( CE_Failure, CPLE_FileIO, "Unable to write padding to grid file " "(Out of space?).\n" ); return CE_Failure; } } return CE_None; } } /* prepare buffer for real shifting */ size_t nBufferSize = (1024 >= abs(nShiftSize)*2) ? 1024 : abs(nShiftSize)*2; char *pabyBuffer = (char *)VSIMalloc( nBufferSize ); if( pabyBuffer == NULL) { CPLError( CE_Failure, CPLE_OutOfMemory, "Unable to allocate space for shift buffer.\n" ); return CE_Failure; } if( VSIFSeekL( fp, nShiftStart, SEEK_SET ) != 0 ) { VSIFree( pabyBuffer ); CPLError( CE_Failure, CPLE_FileIO, "Unable to seek to start of shift in grid file.\n" ); return CE_Failure; } size_t nRead; size_t nOverlap = (nShiftSize > 0) ? nShiftSize : 0; /* If there is overlap, fill buffer with the overlap to start */ if( nOverlap > 0) { nRead = VSIFReadL( (void *)pabyBuffer, 1, nOverlap, fp ); if( nRead < nOverlap && !VSIFEofL( fp ) ) { VSIFree( pabyBuffer ); CPLError( CE_Failure, CPLE_FileIO, "Error reading grid file.\n" ); return CE_Failure; } /* overwrite the new space with ' ' */ if( VSIFSeekL( fp, nShiftStart, SEEK_SET ) != 0 ) { VSIFree( pabyBuffer ); CPLError( CE_Failure, CPLE_FileIO, "Unable to seek to start of shift in grid file.\n" ); return CE_Failure; } for( int iFill=0; iFill<nShiftSize; iFill++ ) { if( VSIFWriteL( (void *)" ", 1, 1, fp ) != 1 ) { VSIFree( pabyBuffer ); CPLError( CE_Failure, CPLE_FileIO, "Unable to write padding to grid file " "(Out of space?).\n" ); return CE_Failure; } } /* if we have already read the entire file, finish it off */ if( VSIFTellL( fp ) >= nOldEnd ) { if( VSIFWriteL( (void *)pabyBuffer, 1, nRead, fp ) != nRead ) { VSIFree( pabyBuffer ); CPLError( CE_Failure, CPLE_FileIO, "Unable to write to grid file (Out of space?).\n" ); return CE_Failure; } VSIFree( pabyBuffer ); return CE_None; } } /* iterate over the remainder of the file and shift as requested */ bool bEOF = false; while( !bEOF ) { nRead = VSIFReadL( (void *)(pabyBuffer+nOverlap), 1, nBufferSize - nOverlap, fp ); if( VSIFEofL( fp ) ) bEOF = true; else bEOF = false; if( nRead == 0 && !bEOF ) { VSIFree( pabyBuffer ); CPLError( CE_Failure, CPLE_FileIO, "Unable to read from grid file (possible corruption).\n"); return CE_Failure; } /* FIXME: Should use SEEK_CUR, review integer promotions... */ if( VSIFSeekL( fp, VSIFTellL(fp)-nRead+nShiftSize-nOverlap, SEEK_SET ) != 0 ) { VSIFree( pabyBuffer ); CPLError( CE_Failure, CPLE_FileIO, "Unable to seek in grid file (possible corruption).\n" ); return CE_Failure; } size_t nWritten = VSIFWriteL( (void *)pabyBuffer, 1, nRead, fp ); if( nWritten != nRead ) { VSIFree( pabyBuffer ); CPLError( CE_Failure, CPLE_FileIO, "Unable to write to grid file (out of space?).\n" ); return CE_Failure; } /* shift overlapped contents to the front of the buffer if necessary */ if( nOverlap > 0) memmove(pabyBuffer, pabyBuffer+nRead, nOverlap); } /* write the remainder of the buffer or overwrite leftovers and finish */ if( nShiftSize > 0 ) { size_t nTailSize = nOverlap; while( nTailSize > 0 && isspace( (unsigned char)pabyBuffer[nTailSize-1] ) ) nTailSize--; if( VSIFWriteL( (void *)pabyBuffer, 1, nTailSize, fp ) != nTailSize ) { VSIFree( pabyBuffer ); CPLError( CE_Failure, CPLE_FileIO, "Unable to write to grid file (out of space?).\n" ); return CE_Failure; } if( VSIFWriteL( (void *)pszEOL, 1, strlen(pszEOL), fp ) != strlen(pszEOL) ) { VSIFree( pabyBuffer ); CPLError( CE_Failure, CPLE_FileIO, "Unable to write to grid file (out of space?).\n" ); return CE_Failure; } } else { /* FIXME: ftruncate()? */ /* FIXME: Should use SEEK_CUR, review integer promotions... */ if( VSIFSeekL( fp, VSIFTellL(fp)-strlen(pszEOL), SEEK_SET ) != 0 ) { VSIFree( pabyBuffer ); CPLError( CE_Failure, CPLE_FileIO, "Unable to seek in grid file.\n" ); return CE_Failure; } for( int iPadding=0; iPadding<-nShiftSize; iPadding++ ) { if( VSIFWriteL( (void *)" ", 1, 1, fp ) != 1 ) { VSIFree( pabyBuffer ); CPLError( CE_Failure, CPLE_FileIO, "Error writing to grid file.\n" ); return CE_Failure; } } if( VSIFWriteL( (void *)pszEOL, 1, strlen(pszEOL), fp ) != strlen(pszEOL) ) { VSIFree( pabyBuffer ); CPLError( CE_Failure, CPLE_FileIO, "Unable to write to grid file (out of space?).\n" ); return CE_Failure; } } VSIFree( pabyBuffer ); return CE_None; }
void KML::checkValidity() { std::size_t nDone = 0; std::size_t nLen = 0; char aBuf[BUFSIZ] = { 0 }; if(poTrunk_ != NULL) { delete poTrunk_; poTrunk_ = NULL; } if(poCurrent_ != NULL) { delete poCurrent_; poCurrent_ = NULL; } if(pKMLFile_ == NULL) { this->sError_ = "No file given"; return; } XML_Parser oParser = OGRCreateExpatXMLParser(); XML_SetUserData(oParser, this); XML_SetElementHandler(oParser, startElementValidate, NULL); XML_SetCharacterDataHandler(oParser, dataHandlerValidate); int nCount = 0; oCurrentParser = oParser; /* Parses the file until we find the first element */ do { nDataHandlerCounter = 0; nLen = (int)VSIFReadL( aBuf, 1, sizeof(aBuf), pKMLFile_ ); nDone = VSIFEofL(pKMLFile_); if (XML_Parse(oParser, aBuf, nLen, nDone) == XML_STATUS_ERROR) { if (nLen <= BUFSIZ-1) aBuf[nLen] = 0; else aBuf[BUFSIZ-1] = 0; if (strstr(aBuf, "<?xml") && strstr(aBuf, "<kml")) { CPLError(CE_Failure, CPLE_AppDefined, "XML parsing of KML file failed : %s at line %d, column %d", XML_ErrorString(XML_GetErrorCode(oParser)), (int)XML_GetCurrentLineNumber(oParser), (int)XML_GetCurrentColumnNumber(oParser)); } validity = KML_VALIDITY_INVALID; XML_ParserFree(oParser); VSIRewindL(pKMLFile_); return; } nCount ++; /* After reading 50 * BUFSIZE bytes, and not finding whether the file */ /* is KML or not, we give up and fail silently */ } while (!nDone && nLen > 0 && validity == KML_VALIDITY_UNKNOWN && nCount < 50); XML_ParserFree(oParser); VSIRewindL(pKMLFile_); poCurrent_ = NULL; }
CPLErr RIKRasterBand::IReadBlock( int nBlockXOff, int nBlockYOff, void * pImage ) { RIKDataset *poRDS = (RIKDataset *) poDS; GByte *blockData; GUInt32 blocks; GUInt32 nBlockIndex; GUInt32 nBlockOffset; GUInt32 nBlockSize; blocks = poRDS->nHorBlocks * poRDS->nVertBlocks; nBlockIndex = nBlockXOff + nBlockYOff * poRDS->nHorBlocks; nBlockOffset = poRDS->pOffsets[nBlockIndex]; nBlockSize = poRDS->nFileSize; for( GUInt32 bi = nBlockIndex + 1; bi < blocks; bi++ ) { if( poRDS->pOffsets[bi] ) { nBlockSize = poRDS->pOffsets[bi]; break; } } nBlockSize -= nBlockOffset; GUInt32 pixels; pixels = poRDS->nBlockXSize * poRDS->nBlockYSize; if( !nBlockOffset || !nBlockSize #ifdef RIK_SINGLE_BLOCK || nBlockIndex != RIK_SINGLE_BLOCK #endif ) { for( GUInt32 i = 0; i < pixels; i++ ) ((GByte *) pImage)[i] = 0; return CE_None; } VSIFSeekL( poRDS->fp, nBlockOffset, SEEK_SET ); /* -------------------------------------------------------------------- */ /* Read uncompressed block. */ /* -------------------------------------------------------------------- */ if( poRDS->options == 0x00 || poRDS->options == 0x40 ) { VSIFReadL( pImage, 1, nBlockSize, poRDS->fp ); return CE_None; } // Read block to memory blockData = (GByte *) CPLMalloc(nBlockSize); VSIFReadL( blockData, 1, nBlockSize, poRDS->fp ); GUInt32 filePos = 0; GUInt32 imagePos = 0; /* -------------------------------------------------------------------- */ /* Read RLE block. */ /* -------------------------------------------------------------------- */ if( poRDS->options == 0x01 || poRDS->options == 0x41 ) do { GByte count = blockData[filePos++]; GByte color = blockData[filePos++]; for (GByte i = 0; i <= count; i++) { ((GByte *) pImage)[imagePos++] = color; } } while( filePos < nBlockSize && imagePos < pixels ); /* -------------------------------------------------------------------- */ /* Read LZW block. */ /* -------------------------------------------------------------------- */ else if( poRDS->options == 0x0b ) { const bool LZW_HAS_CLEAR_CODE = !!(blockData[4] & 0x80); const int LZW_MAX_BITS = blockData[4] & 0x1f; // Max 13 const int LZW_BITS_PER_PIXEL = 8; const int LZW_OFFSET = 5; const int LZW_CLEAR = 1 << LZW_BITS_PER_PIXEL; const int LZW_CODES = 1 << LZW_MAX_BITS; const int LZW_NO_SUCH_CODE = LZW_CODES + 1; int lastAdded = LZW_HAS_CLEAR_CODE ? LZW_CLEAR : LZW_CLEAR - 1; int codeBits = LZW_BITS_PER_PIXEL + 1; int code; int lastCode; GByte lastOutput; int bitsTaken = 0; int prefix[8192]; // only need LZW_CODES for size. GByte character[8192]; // only need LZW_CODES for size. int i; for( i = 0; i < LZW_CLEAR; i++ ) character[i] = (GByte)i; for( i = 0; i < LZW_CODES; i++ ) prefix[i] = LZW_NO_SUCH_CODE; filePos = LZW_OFFSET; GUInt32 fileAlign = LZW_OFFSET; int imageLine = poRDS->nBlockYSize - 1; GUInt32 lineBreak = poRDS->nBlockXSize; // 32 bit alignment lineBreak += 3; lineBreak &= 0xfffffffc; code = GetNextLZWCode( codeBits, blockData, filePos, fileAlign, bitsTaken ); OutputPixel( (GByte)code, pImage, poRDS->nBlockXSize, lineBreak, imageLine, imagePos ); lastOutput = (GByte)code; while( imageLine >= 0 && (imageLine || imagePos < poRDS->nBlockXSize) && filePos < nBlockSize ) try { lastCode = code; code = GetNextLZWCode( codeBits, blockData, filePos, fileAlign, bitsTaken ); if( VSIFEofL( poRDS->fp ) ) { CPLFree( blockData ); CPLError( CE_Failure, CPLE_AppDefined, "RIK decompression failed. " "Read past end of file.\n" ); return CE_Failure; } if( LZW_HAS_CLEAR_CODE && code == LZW_CLEAR ) { #if RIK_CLEAR_DEBUG CPLDebug( "RIK", "Clearing block %d\n" " x=%d y=%d\n" " pos=%d size=%d\n", nBlockIndex, imagePos, imageLine, filePos, nBlockSize ); #endif // Clear prefix table for( i = LZW_CLEAR; i < LZW_CODES; i++ ) prefix[i] = LZW_NO_SUCH_CODE; lastAdded = LZW_CLEAR; codeBits = LZW_BITS_PER_PIXEL + 1; filePos = fileAlign; bitsTaken = 0; code = GetNextLZWCode( codeBits, blockData, filePos, fileAlign, bitsTaken ); if( code > lastAdded ) { throw "Clear Error"; } OutputPixel( (GByte)code, pImage, poRDS->nBlockXSize, lineBreak, imageLine, imagePos ); lastOutput = (GByte)code; } else { // Set-up decoding GByte stack[8192]; // only need LZW_CODES for size. int stackPtr = 0; int decodeCode = code; if( code == lastAdded + 1 ) { // Handle special case *stack = lastOutput; stackPtr = 1; decodeCode = lastCode; } else if( code > lastAdded + 1 ) { throw "Too high code"; } // Decode i = 0; while( ++i < LZW_CODES && decodeCode >= LZW_CLEAR && decodeCode < LZW_NO_SUCH_CODE ) { stack[stackPtr++] = character[decodeCode]; decodeCode = prefix[decodeCode]; } stack[stackPtr++] = (GByte)decodeCode; if( i == LZW_CODES || decodeCode >= LZW_NO_SUCH_CODE ) { throw "Decode error"; } // Output stack lastOutput = stack[stackPtr - 1]; while( stackPtr != 0 && imagePos < pixels ) { OutputPixel( stack[--stackPtr], pImage, poRDS->nBlockXSize, lineBreak, imageLine, imagePos ); } // Add code to string table if( lastCode != LZW_NO_SUCH_CODE && lastAdded != LZW_CODES - 1 ) { prefix[++lastAdded] = lastCode; character[lastAdded] = lastOutput; } // Check if we need to use more bits if( lastAdded == (1 << codeBits) - 1 && codeBits != LZW_MAX_BITS ) { codeBits++; filePos = fileAlign; bitsTaken = 0; } } } catch (const char *errStr) { #if RIK_ALLOW_BLOCK_ERRORS CPLDebug( "RIK", "LZW Decompress Failed: %s\n" " blocks: %d\n" " blockindex: %d\n" " blockoffset: %X\n" " blocksize: %d\n", errStr, blocks, nBlockIndex, nBlockOffset, nBlockSize ); break; #else CPLFree( blockData ); CPLError( CE_Failure, CPLE_AppDefined, "RIK decompression failed. " "Corrupt image block." ); return CE_Failure; #endif } } /* -------------------------------------------------------------------- */ /* Read ZLIB block. */ /* -------------------------------------------------------------------- */ else if( poRDS->options == 0x0d ) { uLong destLen = pixels; Byte *upsideDown = (Byte *) CPLMalloc( pixels ); uncompress( upsideDown, &destLen, blockData, nBlockSize ); for (GUInt32 i = 0; i < poRDS->nBlockYSize; i++) { memcpy( ((Byte *)pImage) + poRDS->nBlockXSize * i, upsideDown + poRDS->nBlockXSize * (poRDS->nBlockYSize - i - 1), poRDS->nBlockXSize ); } CPLFree( upsideDown ); } CPLFree( blockData ); return CE_None; }
GDALDataset *RDataset::Open( GDALOpenInfo * poOpenInfo ) { if( !Identify( poOpenInfo ) ) return NULL; /* -------------------------------------------------------------------- */ /* Confirm the requested access is supported. */ /* -------------------------------------------------------------------- */ if( poOpenInfo->eAccess == GA_Update ) { CPLError( CE_Failure, CPLE_NotSupported, "The R driver does not support update access to existing" " datasets.\n" ); return NULL; } /* -------------------------------------------------------------------- */ /* Do we need to route the file through the decompression */ /* machinery? */ /* -------------------------------------------------------------------- */ CPLString osAdjustedFilename; if( memcmp(poOpenInfo->pabyHeader,"\037\213\b",3) == 0 ) osAdjustedFilename = "/vsigzip/"; osAdjustedFilename += poOpenInfo->pszFilename; /* -------------------------------------------------------------------- */ /* Establish this as a dataset and open the file using VSI*L. */ /* -------------------------------------------------------------------- */ RDataset *poDS = new RDataset(); poDS->fp = VSIFOpenL( osAdjustedFilename, "r" ); if( poDS->fp == NULL ) { delete poDS; return NULL; } poDS->bASCII = EQUALN((const char *)poOpenInfo->pabyHeader,"RDA2\nA\n",7); /* -------------------------------------------------------------------- */ /* Confirm this is a version 2 file. */ /* -------------------------------------------------------------------- */ VSIFSeekL( poDS->fp, 7, SEEK_SET ); if( poDS->ReadInteger() != R_LISTSXP ) { delete poDS; CPLError( CE_Failure, CPLE_OpenFailed, "It appears %s is not a version 2 R object file after all!", poOpenInfo->pszFilename ); return NULL; } /* -------------------------------------------------------------------- */ /* Skip the version values. */ /* -------------------------------------------------------------------- */ poDS->ReadInteger(); poDS->ReadInteger(); /* -------------------------------------------------------------------- */ /* Confirm we have a numeric vector object in a pairlist. */ /* -------------------------------------------------------------------- */ CPLString osObjName; int nObjCode; if( !poDS->ReadPair( osObjName, nObjCode ) ) { delete poDS; return NULL; } if( nObjCode % 256 != R_REALSXP ) { delete poDS; CPLError( CE_Failure, CPLE_OpenFailed, "Failed to find expected numeric vector object." ); return NULL; } poDS->SetMetadataItem( "R_OBJECT_NAME", osObjName ); /* -------------------------------------------------------------------- */ /* Read the count. */ /* -------------------------------------------------------------------- */ int nValueCount = poDS->ReadInteger(); poDS->nStartOfData = VSIFTellL( poDS->fp ); /* -------------------------------------------------------------------- */ /* Read/Skip ahead to attributes. */ /* -------------------------------------------------------------------- */ if( poDS->bASCII ) { poDS->padfMatrixValues = (double*) VSIMalloc2( nValueCount, sizeof(double) ); if (poDS->padfMatrixValues == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot allocate %d doubles", nValueCount); delete poDS; return NULL; } for( int iValue = 0; iValue < nValueCount; iValue++ ) poDS->padfMatrixValues[iValue] = poDS->ReadFloat(); } else { VSIFSeekL( poDS->fp, 8 * nValueCount, SEEK_CUR ); } /* -------------------------------------------------------------------- */ /* Read pairs till we run out, trying to find a few items that */ /* have special meaning to us. */ /* -------------------------------------------------------------------- */ poDS->nRasterXSize = poDS->nRasterYSize = 0; int nBandCount = 0; while( poDS->ReadPair( osObjName, nObjCode ) && nObjCode != 254 ) { if( osObjName == "dim" && nObjCode % 256 == R_INTSXP ) { int nCount = poDS->ReadInteger(); if( nCount == 2 ) { poDS->nRasterXSize = poDS->ReadInteger(); poDS->nRasterYSize = poDS->ReadInteger(); nBandCount = 1; } else if( nCount == 3 ) { poDS->nRasterXSize = poDS->ReadInteger(); poDS->nRasterYSize = poDS->ReadInteger(); nBandCount = poDS->ReadInteger(); } else { CPLError( CE_Failure, CPLE_AppDefined, "R 'dim' dimension wrong." ); delete poDS; return NULL; } } else if( nObjCode % 256 == R_REALSXP ) { int nCount = poDS->ReadInteger(); while( nCount-- > 0 && !VSIFEofL(poDS->fp) ) poDS->ReadFloat(); } else if( nObjCode % 256 == R_INTSXP ) { int nCount = poDS->ReadInteger(); while( nCount-- > 0 && !VSIFEofL(poDS->fp) ) poDS->ReadInteger(); } else if( nObjCode % 256 == R_STRSXP ) { int nCount = poDS->ReadInteger(); while( nCount-- > 0 && !VSIFEofL(poDS->fp) ) poDS->ReadString(); } else if( nObjCode % 256 == R_CHARSXP ) { poDS->ReadString(); } } if( poDS->nRasterXSize == 0 ) { delete poDS; CPLError( CE_Failure, CPLE_AppDefined, "Failed to find dim dimension information for R dataset." ); return NULL; } if (!GDALCheckDatasetDimensions(poDS->nRasterXSize, poDS->nRasterYSize) || !GDALCheckBandCount(nBandCount, TRUE)) { delete poDS; return NULL; } if( nValueCount < ((GIntBig) nBandCount) * poDS->nRasterXSize * poDS->nRasterYSize ) { CPLError( CE_Failure, CPLE_AppDefined, "Not enough pixel data." ); delete poDS; return NULL; } /* -------------------------------------------------------------------- */ /* Create the raster band object(s). */ /* -------------------------------------------------------------------- */ for( int iBand = 0; iBand < nBandCount; iBand++ ) { GDALRasterBand *poBand; if( poDS->bASCII ) poBand = new RRasterBand( poDS, iBand+1, poDS->padfMatrixValues + iBand * poDS->nRasterXSize * poDS->nRasterYSize ); else poBand = new RawRasterBand( poDS, iBand+1, poDS->fp, poDS->nStartOfData + poDS->nRasterXSize*poDS->nRasterYSize*8*iBand, 8, poDS->nRasterXSize * 8, GDT_Float64, !CPL_IS_LSB, TRUE, FALSE ); poDS->SetBand( iBand+1, poBand ); } /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ poDS->SetDescription( poOpenInfo->pszFilename ); poDS->TryLoadXML(); /* -------------------------------------------------------------------- */ /* Check for overviews. */ /* -------------------------------------------------------------------- */ poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename ); return( poDS ); }
GDALDataset *RIKDataset::Open( GDALOpenInfo * poOpenInfo ) { if( Identify(poOpenInfo) == FALSE ) return NULL; bool rik3header = false; if( EQUALN((const char *) poOpenInfo->pabyHeader, "RIK3", 4) ) { rik3header = true; VSIFSeekL( poOpenInfo->fpL, 4, SEEK_SET ); } else VSIFSeekL( poOpenInfo->fpL, 0, SEEK_SET ); /* -------------------------------------------------------------------- */ /* Read the map name. */ /* -------------------------------------------------------------------- */ char name[1024]; GUInt16 nameLength = GetRikString( poOpenInfo->fpL, name, sizeof(name) ); if( nameLength > sizeof(name) - 1 ) { return NULL; } if( !rik3header ) { if( nameLength == 0 || nameLength != strlen(name) ) return NULL; } /* -------------------------------------------------------------------- */ /* Read the header. */ /* -------------------------------------------------------------------- */ RIKHeader header; double metersPerPixel; const char *headerType = "RIK3"; if( rik3header ) { /* -------------------------------------------------------------------- */ /* RIK3 header. */ /* -------------------------------------------------------------------- */ // Read projection name char projection[1024]; GUInt16 projLength = GetRikString( poOpenInfo->fpL, projection, sizeof(projection) ); if( projLength > sizeof(projection) - 1 ) { // Unreasonable string length, assume wrong format return NULL; } // Read unknown string projLength = GetRikString( poOpenInfo->fpL, projection, sizeof(projection) ); // Read map north edge char tmpStr[16]; GUInt16 tmpLength = GetRikString( poOpenInfo->fpL, tmpStr, sizeof(tmpStr) ); if( tmpLength > sizeof(tmpStr) - 1 ) { // Unreasonable string length, assume wrong format return NULL; } header.fNorth = CPLAtof( tmpStr ); // Read map west edge tmpLength = GetRikString( poOpenInfo->fpL, tmpStr, sizeof(tmpStr) ); if( tmpLength > sizeof(tmpStr) - 1 ) { // Unreasonable string length, assume wrong format return NULL; } header.fWest = CPLAtof( tmpStr ); // Read binary values VSIFReadL( &header.iScale, 1, sizeof(header.iScale), poOpenInfo->fpL ); VSIFReadL( &header.iMPPNum, 1, sizeof(header.iMPPNum), poOpenInfo->fpL ); VSIFReadL( &header.iBlockWidth, 1, sizeof(header.iBlockWidth), poOpenInfo->fpL ); VSIFReadL( &header.iBlockHeight, 1, sizeof(header.iBlockHeight), poOpenInfo->fpL ); VSIFReadL( &header.iHorBlocks, 1, sizeof(header.iHorBlocks), poOpenInfo->fpL ); VSIFReadL( &header.iVertBlocks, 1, sizeof(header.iVertBlocks), poOpenInfo->fpL ); #ifdef CPL_MSB CPL_SWAP32PTR( &header.iScale ); CPL_SWAP32PTR( &header.iMPPNum ); CPL_SWAP32PTR( &header.iBlockWidth ); CPL_SWAP32PTR( &header.iBlockHeight ); CPL_SWAP32PTR( &header.iHorBlocks ); CPL_SWAP32PTR( &header.iVertBlocks ); #endif VSIFReadL( &header.iBitsPerPixel, 1, sizeof(header.iBitsPerPixel), poOpenInfo->fpL ); VSIFReadL( &header.iOptions, 1, sizeof(header.iOptions), poOpenInfo->fpL ); header.iUnknown = header.iOptions; VSIFReadL( &header.iOptions, 1, sizeof(header.iOptions), poOpenInfo->fpL ); header.fSouth = header.fNorth - header.iVertBlocks * header.iBlockHeight * header.iMPPNum; header.fEast = header.fWest + header.iHorBlocks * header.iBlockWidth * header.iMPPNum; metersPerPixel = header.iMPPNum; } else { /* -------------------------------------------------------------------- */ /* Old RIK header. */ /* -------------------------------------------------------------------- */ VSIFReadL( &header.iUnknown, 1, sizeof(header.iUnknown), poOpenInfo->fpL ); VSIFReadL( &header.fSouth, 1, sizeof(header.fSouth), poOpenInfo->fpL ); VSIFReadL( &header.fWest, 1, sizeof(header.fWest), poOpenInfo->fpL ); VSIFReadL( &header.fNorth, 1, sizeof(header.fNorth), poOpenInfo->fpL ); VSIFReadL( &header.fEast, 1, sizeof(header.fEast), poOpenInfo->fpL ); VSIFReadL( &header.iScale, 1, sizeof(header.iScale), poOpenInfo->fpL ); VSIFReadL( &header.iMPPNum, 1, sizeof(header.iMPPNum), poOpenInfo->fpL ); #ifdef CPL_MSB CPL_SWAP64PTR( &header.fSouth ); CPL_SWAP64PTR( &header.fWest ); CPL_SWAP64PTR( &header.fNorth ); CPL_SWAP64PTR( &header.fEast ); CPL_SWAP32PTR( &header.iScale ); CPL_SWAP32PTR( &header.iMPPNum ); #endif if (!CPLIsFinite(header.fSouth) | !CPLIsFinite(header.fWest) | !CPLIsFinite(header.fNorth) | !CPLIsFinite(header.fEast)) return NULL; bool offsetBounds; offsetBounds = header.fSouth < 4000000; header.iMPPDen = 1; if( offsetBounds ) { header.fSouth += 4002995; header.fNorth += 5004000; header.fWest += 201000; header.fEast += 302005; VSIFReadL( &header.iMPPDen, 1, sizeof(header.iMPPDen), poOpenInfo->fpL ); #ifdef CPL_MSB CPL_SWAP32PTR( &header.iMPPDen ); #endif headerType = "RIK1"; } else { headerType = "RIK2"; } metersPerPixel = header.iMPPNum / double(header.iMPPDen); VSIFReadL( &header.iBlockWidth, 1, sizeof(header.iBlockWidth), poOpenInfo->fpL ); VSIFReadL( &header.iBlockHeight, 1, sizeof(header.iBlockHeight), poOpenInfo->fpL ); VSIFReadL( &header.iHorBlocks, 1, sizeof(header.iHorBlocks), poOpenInfo->fpL ); #ifdef CPL_MSB CPL_SWAP32PTR( &header.iBlockWidth ); CPL_SWAP32PTR( &header.iBlockHeight ); CPL_SWAP32PTR( &header.iHorBlocks ); #endif if(( header.iBlockWidth > 2000 ) || ( header.iBlockWidth < 10 ) || ( header.iBlockHeight > 2000 ) || ( header.iBlockHeight < 10 )) return NULL; if( !offsetBounds ) { VSIFReadL( &header.iVertBlocks, 1, sizeof(header.iVertBlocks), poOpenInfo->fpL ); #ifdef CPL_MSB CPL_SWAP32PTR( &header.iVertBlocks ); #endif } if( offsetBounds || !header.iVertBlocks ) { header.iVertBlocks = (GUInt32) ceil( (header.fNorth - header.fSouth) / (header.iBlockHeight * metersPerPixel) ); } #if RIK_HEADER_DEBUG CPLDebug( "RIK", "Original vertical blocks %d\n", header.iVertBlocks ); #endif VSIFReadL( &header.iBitsPerPixel, 1, sizeof(header.iBitsPerPixel), poOpenInfo->fpL ); if( header.iBitsPerPixel != 8 ) { CPLError( CE_Failure, CPLE_OpenFailed, "File %s has unsupported number of bits per pixel.\n", poOpenInfo->pszFilename ); return NULL; } VSIFReadL( &header.iOptions, 1, sizeof(header.iOptions), poOpenInfo->fpL ); if( !header.iHorBlocks || !header.iVertBlocks ) return NULL; if( header.iOptions != 0x00 && // Uncompressed header.iOptions != 0x40 && // Uncompressed header.iOptions != 0x01 && // RLE header.iOptions != 0x41 && // RLE header.iOptions != 0x0B && // LZW header.iOptions != 0x0D ) // ZLIB { CPLError( CE_Failure, CPLE_OpenFailed, "File %s. Unknown map options.\n", poOpenInfo->pszFilename ); return NULL; } } /* -------------------------------------------------------------------- */ /* Read the palette. */ /* -------------------------------------------------------------------- */ GByte palette[768]; GUInt16 i; for( i = 0; i < 256; i++ ) { VSIFReadL( &palette[i * 3 + 2], 1, 1, poOpenInfo->fpL ); VSIFReadL( &palette[i * 3 + 1], 1, 1, poOpenInfo->fpL ); VSIFReadL( &palette[i * 3 + 0], 1, 1, poOpenInfo->fpL ); } /* -------------------------------------------------------------------- */ /* Find block offsets. */ /* -------------------------------------------------------------------- */ GUInt32 blocks; GUInt32 *offsets; blocks = header.iHorBlocks * header.iVertBlocks; offsets = (GUInt32 *)CPLMalloc( blocks * sizeof(GUInt32) ); if( !offsets ) { CPLError( CE_Failure, CPLE_OpenFailed, "File %s. Unable to allocate offset table.\n", poOpenInfo->pszFilename ); return NULL; } if( header.iOptions == 0x00 ) { offsets[0] = VSIFTellL( poOpenInfo->fpL ); for( GUInt32 i = 1; i < blocks; i++ ) { offsets[i] = offsets[i - 1] + header.iBlockWidth * header.iBlockHeight; } } else { for( GUInt32 i = 0; i < blocks; i++ ) { VSIFReadL( &offsets[i], 1, sizeof(offsets[i]), poOpenInfo->fpL ); #ifdef CPL_MSB CPL_SWAP32PTR( &offsets[i] ); #endif if( rik3header ) { GUInt32 blockSize; VSIFReadL( &blockSize, 1, sizeof(blockSize), poOpenInfo->fpL ); #ifdef CPL_MSB CPL_SWAP32PTR( &blockSize ); #endif } } } /* -------------------------------------------------------------------- */ /* Final checks. */ /* -------------------------------------------------------------------- */ // File size if( VSIFEofL( poOpenInfo->fpL ) ) { CPLError( CE_Failure, CPLE_OpenFailed, "File %s. Read past end of file.\n", poOpenInfo->pszFilename ); return NULL; } VSIFSeekL( poOpenInfo->fpL, 0, SEEK_END ); GUInt32 fileSize = VSIFTellL( poOpenInfo->fpL ); #if RIK_HEADER_DEBUG CPLDebug( "RIK", "File size %d\n", fileSize ); #endif // Make sure the offset table is valid GUInt32 lastoffset = 0; for( GUInt32 y = 0; y < header.iVertBlocks; y++) { for( GUInt32 x = 0; x < header.iHorBlocks; x++) { if( !offsets[x + y * header.iHorBlocks] ) { continue; } if( offsets[x + y * header.iHorBlocks] >= fileSize ) { if( !y ) { CPLError( CE_Failure, CPLE_OpenFailed, "File %s too short.\n", poOpenInfo->pszFilename ); return NULL; } header.iVertBlocks = y; break; } if( offsets[x + y * header.iHorBlocks] < lastoffset ) { if( !y ) { CPLError( CE_Failure, CPLE_OpenFailed, "File %s. Corrupt offset table.\n", poOpenInfo->pszFilename ); return NULL; } header.iVertBlocks = y; break; } lastoffset = offsets[x + y * header.iHorBlocks]; } } #if RIK_HEADER_DEBUG CPLDebug( "RIK", "first offset %d\n" "last offset %d\n", offsets[0], lastoffset ); #endif const char *compression = "RLE"; if( header.iOptions == 0x00 || header.iOptions == 0x40 ) compression = "Uncompressed"; if( header.iOptions == 0x0b ) compression = "LZW"; if( header.iOptions == 0x0d ) compression = "ZLIB"; CPLDebug( "RIK", "RIK file parameters:\n" " name: %s\n" " header: %s\n" " unknown: 0x%X\n" " south: %f\n" " west: %f\n" " north: %f\n" " east: %f\n" " original scale: %d\n" " meters per pixel: %f\n" " block width: %d\n" " block height: %d\n" " horizontal blocks: %d\n" " vertical blocks: %d\n" " bits per pixel: %d\n" " options: 0x%X\n" " compression: %s\n", name, headerType, header.iUnknown, header.fSouth, header.fWest, header.fNorth, header.fEast, header.iScale, metersPerPixel, header.iBlockWidth, header.iBlockHeight, header.iHorBlocks, header.iVertBlocks, header.iBitsPerPixel, header.iOptions, compression); /* -------------------------------------------------------------------- */ /* Create a corresponding GDALDataset. */ /* -------------------------------------------------------------------- */ RIKDataset *poDS; poDS = new RIKDataset(); poDS->fp = poOpenInfo->fpL; poOpenInfo->fpL = NULL; poDS->fTransform[0] = header.fWest - metersPerPixel / 2.0; poDS->fTransform[1] = metersPerPixel; poDS->fTransform[2] = 0.0; poDS->fTransform[3] = header.fNorth + metersPerPixel / 2.0; poDS->fTransform[4] = 0.0; poDS->fTransform[5] = -metersPerPixel; poDS->nBlockXSize = header.iBlockWidth; poDS->nBlockYSize = header.iBlockHeight; poDS->nHorBlocks = header.iHorBlocks; poDS->nVertBlocks = header.iVertBlocks; poDS->pOffsets = offsets; poDS->options = header.iOptions; poDS->nFileSize = fileSize; poDS->nRasterXSize = header.iBlockWidth * header.iHorBlocks; poDS->nRasterYSize = header.iBlockHeight * header.iVertBlocks; poDS->nBands = 1; GDALColorEntry oEntry; poDS->poColorTable = new GDALColorTable(); for( i = 0; i < 256; i++ ) { oEntry.c1 = palette[i * 3 + 2]; // Red oEntry.c2 = palette[i * 3 + 1]; // Green oEntry.c3 = palette[i * 3]; // Blue oEntry.c4 = 255; poDS->poColorTable->SetColorEntry( i, &oEntry ); } /* -------------------------------------------------------------------- */ /* Create band information objects. */ /* -------------------------------------------------------------------- */ poDS->SetBand( 1, new RIKRasterBand( poDS, 1 )); /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ poDS->SetDescription( poOpenInfo->pszFilename ); poDS->TryLoadXML(); /* -------------------------------------------------------------------- */ /* Check for external overviews. */ /* -------------------------------------------------------------------- */ poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename, poOpenInfo->GetSiblingFiles() ); /* -------------------------------------------------------------------- */ /* Confirm the requested access is supported. */ /* -------------------------------------------------------------------- */ if( poOpenInfo->eAccess == GA_Update ) { delete poDS; CPLError( CE_Failure, CPLE_NotSupported, "The RIK driver does not support update access to existing" " datasets.\n" ); return NULL; } return( poDS ); }
int OGRGPXDataSource::Open( const char * pszFilename, int bUpdateIn) { if (bUpdateIn) { CPLError(CE_Failure, CPLE_NotSupported, "OGR/GPX driver does not support opening a file in update mode"); return FALSE; } #ifdef HAVE_EXPAT pszName = CPLStrdup( pszFilename ); /* -------------------------------------------------------------------- */ /* Try to open the file. */ /* -------------------------------------------------------------------- */ VSILFILE* fp = VSIFOpenL(pszFilename, "r"); if (fp == NULL) return FALSE; validity = GPX_VALIDITY_UNKNOWN; CPLFree(pszVersion); pszVersion = NULL; bUseExtensions = FALSE; nElementsRead = 0; XML_Parser oParser = OGRCreateExpatXMLParser(); oCurrentParser = oParser; XML_SetUserData(oParser, this); XML_SetElementHandler(oParser, ::startElementValidateCbk, NULL); XML_SetCharacterDataHandler(oParser, ::dataHandlerValidateCbk); char aBuf[BUFSIZ]; int nDone; unsigned int nLen; int nCount = 0; /* Begin to parse the file and look for the <gpx> element */ /* It *MUST* be the first element of an XML file */ /* So once we have read the first element, we know if we can */ /* handle the file or not with that driver */ do { nDataHandlerCounter = 0; nLen = (unsigned int) VSIFReadL( aBuf, 1, sizeof(aBuf), fp ); nDone = VSIFEofL(fp); if (XML_Parse(oParser, aBuf, nLen, nDone) == XML_STATUS_ERROR) { if (nLen <= BUFSIZ-1) aBuf[nLen] = 0; else aBuf[BUFSIZ-1] = 0; if (strstr(aBuf, "<?xml") && strstr(aBuf, "<gpx")) { CPLError(CE_Failure, CPLE_AppDefined, "XML parsing of GPX file failed : %s at line %d, column %d", XML_ErrorString(XML_GetErrorCode(oParser)), (int)XML_GetCurrentLineNumber(oParser), (int)XML_GetCurrentColumnNumber(oParser)); } validity = GPX_VALIDITY_INVALID; break; } if (validity == GPX_VALIDITY_INVALID) { break; } else if (validity == GPX_VALIDITY_VALID) { /* If we have recognized the <gpx> element, now we try */ /* to recognize if they are <extensions> tags */ /* But we stop to look for after an arbitrary number of tags */ if (bUseExtensions) break; else if (nElementsRead > 200) break; } else { /* After reading 50 * BUFSIZE bytes, and not finding whether the file */ /* is GPX or not, we give up and fail silently */ nCount ++; if (nCount == 50) break; } } while (!nDone && nLen > 0 ); XML_ParserFree(oParser); VSIFCloseL(fp); if (validity == GPX_VALIDITY_VALID) { CPLDebug("GPX", "%s seems to be a GPX file.", pszFilename); if (bUseExtensions) CPLDebug("GPX", "It uses <extensions>"); if (pszVersion == NULL) { /* Default to 1.1 */ CPLError(CE_Warning, CPLE_AppDefined, "GPX schema version is unknown. " "The driver may not be able to handle the file correctly and will behave as if it is GPX 1.1."); pszVersion = CPLStrdup("1.1"); } else if (strcmp(pszVersion, "1.0") == 0 || strcmp(pszVersion, "1.1") == 0) { /* Fine */ } else { CPLError(CE_Warning, CPLE_AppDefined, "GPX schema version '%s' is not handled by the driver. " "The driver may not be able to handle the file correctly and will behave as if it is GPX 1.1.", pszVersion); } nLayers = 5; papoLayers = (OGRGPXLayer **) CPLRealloc(papoLayers, nLayers * sizeof(OGRGPXLayer*)); papoLayers[0] = new OGRGPXLayer( pszName, "waypoints", GPX_WPT, this, FALSE ); papoLayers[1] = new OGRGPXLayer( pszName, "routes", GPX_ROUTE, this, FALSE ); papoLayers[2] = new OGRGPXLayer( pszName, "tracks", GPX_TRACK, this, FALSE ); papoLayers[3] = new OGRGPXLayer( pszName, "route_points", GPX_ROUTE_POINT, this, FALSE ); papoLayers[4] = new OGRGPXLayer( pszName, "track_points", GPX_TRACK_POINT, this, FALSE ); } return (validity == GPX_VALIDITY_VALID); #else char aBuf[256]; VSILFILE* fp = VSIFOpenL(pszFilename, "r"); if (fp) { unsigned int nLen = (unsigned int)VSIFReadL( aBuf, 1, 255, fp ); aBuf[nLen] = 0; if (strstr(aBuf, "<?xml") && strstr(aBuf, "<gpx")) { CPLError(CE_Failure, CPLE_NotSupported, "OGR/GPX driver has not been built with read support. Expat library required"); } VSIFCloseL(fp); } return FALSE; #endif }
GDALDataset *AAIGDataset::CommonOpen( GDALOpenInfo *poOpenInfo, GridFormat eFormat ) { if( poOpenInfo->fpL == nullptr ) return nullptr; // Create a corresponding GDALDataset. AAIGDataset *poDS = nullptr; if (eFormat == FORMAT_AAIG) poDS = new AAIGDataset(); else poDS = new GRASSASCIIDataset(); const char *pszDataTypeOption = eFormat == FORMAT_AAIG ? "AAIGRID_DATATYPE" : "GRASSASCIIGRID_DATATYPE"; const char *pszDataType = CPLGetConfigOption(pszDataTypeOption, nullptr); if( pszDataType == nullptr ) pszDataType = CSLFetchNameValue(poOpenInfo->papszOpenOptions, "DATATYPE"); if (pszDataType != nullptr) { poDS->eDataType = GDALGetDataTypeByName(pszDataType); if (!(poDS->eDataType == GDT_Int32 || poDS->eDataType == GDT_Float32 || poDS->eDataType == GDT_Float64)) { CPLError(CE_Warning, CPLE_NotSupported, "Unsupported value for %s : %s", pszDataTypeOption, pszDataType); poDS->eDataType = GDT_Int32; pszDataType = nullptr; } } // Parse the header. if (!poDS->ParseHeader((const char *)poOpenInfo->pabyHeader, pszDataType)) { delete poDS; return nullptr; } poDS->fp = poOpenInfo->fpL; poOpenInfo->fpL = nullptr; // Find the start of real data. int nStartOfData = 0; for( int i = 2; true; i++ ) { if( poOpenInfo->pabyHeader[i] == '\0' ) { CPLError(CE_Failure, CPLE_AppDefined, "Couldn't find data values in ASCII Grid file."); delete poDS; return nullptr; } if( poOpenInfo->pabyHeader[i - 1] == '\n' || poOpenInfo->pabyHeader[i - 2] == '\n' || poOpenInfo->pabyHeader[i - 1] == '\r' || poOpenInfo->pabyHeader[i - 2] == '\r' ) { if( !isalpha(poOpenInfo->pabyHeader[i]) && poOpenInfo->pabyHeader[i] != '\n' && poOpenInfo->pabyHeader[i] != '\r') { nStartOfData = i; // Beginning of real data found. break; } } } // Recognize the type of data. CPLAssert(nullptr != poDS->fp); if( pszDataType == nullptr && poDS->eDataType != GDT_Float32 && poDS->eDataType != GDT_Float64) { // Allocate 100K chunk + 1 extra byte for NULL character. constexpr size_t nChunkSize = 1024 * 100; GByte *pabyChunk = static_cast<GByte *>( VSI_CALLOC_VERBOSE(nChunkSize + 1, sizeof(GByte))); if (pabyChunk == nullptr) { delete poDS; return nullptr; } pabyChunk[nChunkSize] = '\0'; if( VSIFSeekL(poDS->fp, nStartOfData, SEEK_SET) < 0 ) { delete poDS; VSIFree(pabyChunk); return nullptr; } // Scan for dot in subsequent chunks of data. while( !VSIFEofL(poDS->fp) ) { CPL_IGNORE_RET_VAL(VSIFReadL(pabyChunk, nChunkSize, 1, poDS->fp)); for( int i = 0; i < static_cast<int>(nChunkSize); i++) { GByte ch = pabyChunk[i]; if (ch == '.' || ch == ',' || ch == 'e' || ch == 'E') { poDS->eDataType = GDT_Float32; break; } } } // Deallocate chunk. VSIFree(pabyChunk); } // Create band information objects. AAIGRasterBand *band = new AAIGRasterBand(poDS, nStartOfData); poDS->SetBand(1, band); if (band->panLineOffset == nullptr) { delete poDS; return nullptr; } // Try to read projection file. char *const pszDirname = CPLStrdup(CPLGetPath(poOpenInfo->pszFilename)); char *const pszBasename = CPLStrdup(CPLGetBasename(poOpenInfo->pszFilename)); poDS->osPrjFilename = CPLFormFilename(pszDirname, pszBasename, "prj"); int nRet = 0; { VSIStatBufL sStatBuf; nRet = VSIStatL(poDS->osPrjFilename, &sStatBuf); } if( nRet != 0 && VSIIsCaseSensitiveFS(poDS->osPrjFilename) ) { poDS->osPrjFilename = CPLFormFilename(pszDirname, pszBasename, "PRJ"); VSIStatBufL sStatBuf; nRet = VSIStatL(poDS->osPrjFilename, &sStatBuf); } if( nRet == 0 ) { poDS->papszPrj = CSLLoad(poDS->osPrjFilename); CPLDebug("AAIGrid", "Loaded SRS from %s", poDS->osPrjFilename.c_str()); OGRSpatialReference oSRS; if( oSRS.importFromESRI(poDS->papszPrj) == OGRERR_NONE ) { // If geographic values are in seconds, we must transform. // Is there a code for minutes too? if( oSRS.IsGeographic() && EQUAL(OSR_GDS(poDS->papszPrj, "Units", ""), "DS") ) { poDS->adfGeoTransform[0] /= 3600.0; poDS->adfGeoTransform[1] /= 3600.0; poDS->adfGeoTransform[2] /= 3600.0; poDS->adfGeoTransform[3] /= 3600.0; poDS->adfGeoTransform[4] /= 3600.0; poDS->adfGeoTransform[5] /= 3600.0; } CPLFree(poDS->pszProjection); oSRS.exportToWkt(&(poDS->pszProjection)); } } CPLFree(pszDirname); CPLFree(pszBasename); // Initialize any PAM information. poDS->SetDescription(poOpenInfo->pszFilename); poDS->TryLoadXML(); // Check for external overviews. poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename, poOpenInfo->GetSiblingFiles()); return poDS; }
int OGRGeoRSSDataSource::Open( const char * pszFilename, int bUpdateIn) { if (bUpdateIn) { CPLError(CE_Failure, CPLE_NotSupported, "OGR/GeoRSS driver does not support opening a file in update mode"); return FALSE; } #ifdef HAVE_EXPAT pszName = CPLStrdup( pszFilename ); /* -------------------------------------------------------------------- */ /* Try to open the file. */ /* -------------------------------------------------------------------- */ VSILFILE* fp = VSIFOpenL(pszFilename, "r"); if (fp == NULL) return FALSE; validity = GEORSS_VALIDITY_UNKNOWN; XML_Parser oParser = OGRCreateExpatXMLParser(); XML_SetUserData(oParser, this); XML_SetElementHandler(oParser, ::startElementValidateCbk, NULL); XML_SetCharacterDataHandler(oParser, ::dataHandlerValidateCbk); oCurrentParser = oParser; char aBuf[BUFSIZ]; int nDone; unsigned int nLen; int nCount = 0; /* Begin to parse the file and look for the <rss> or <feed> element */ /* It *MUST* be the first element of an XML file */ /* So once we have read the first element, we know if we can */ /* handle the file or not with that driver */ do { nDataHandlerCounter = 0; nLen = (unsigned int) VSIFReadL( aBuf, 1, sizeof(aBuf), fp ); nDone = VSIFEofL(fp); if (XML_Parse(oParser, aBuf, nLen, nDone) == XML_STATUS_ERROR) { if (nLen <= BUFSIZ-1) aBuf[nLen] = 0; else aBuf[BUFSIZ-1] = 0; if (strstr(aBuf, "<?xml") && (strstr(aBuf, "<rss") || strstr(aBuf, "<feed") || strstr(aBuf, "<atom:feed"))) { CPLError(CE_Failure, CPLE_AppDefined, "XML parsing of GeoRSS file failed : %s at line %d, column %d", XML_ErrorString(XML_GetErrorCode(oParser)), (int)XML_GetCurrentLineNumber(oParser), (int)XML_GetCurrentColumnNumber(oParser)); } validity = GEORSS_VALIDITY_INVALID; break; } if (validity == GEORSS_VALIDITY_INVALID) { break; } else if (validity == GEORSS_VALIDITY_VALID) { break; } else { /* After reading 50 * BUFSIZ bytes, and not finding whether the file */ /* is GeoRSS or not, we give up and fail silently */ nCount ++; if (nCount == 50) break; } } while (!nDone && nLen > 0 ); XML_ParserFree(oParser); VSIFCloseL(fp); if (validity == GEORSS_VALIDITY_VALID) { CPLDebug("GeoRSS", "%s seems to be a GeoRSS file.", pszFilename); nLayers = 1; papoLayers = (OGRGeoRSSLayer **) CPLRealloc(papoLayers, nLayers * sizeof(OGRGeoRSSLayer*)); papoLayers[0] = new OGRGeoRSSLayer( pszName, "georss", this, NULL, FALSE ); } return (validity == GEORSS_VALIDITY_VALID); #else char aBuf[256]; VSILFILE* fp = VSIFOpenL(pszFilename, "r"); if (fp) { unsigned int nLen = (unsigned int)VSIFReadL( aBuf, 1, 255, fp ); aBuf[nLen] = 0; if (strstr(aBuf, "<?xml") && (strstr(aBuf, "<rss") || strstr(aBuf, "<atom:feed") || strstr(aBuf, "<feed"))) { CPLError(CE_Failure, CPLE_NotSupported, "OGR/GeoRSS driver has not been built with read support. Expat library required"); } VSIFCloseL(fp); } return FALSE; #endif }