bool OGRDXFWriterDS::TransferUpdateHeader( VSILFILE *fpOut ) { oHeaderDS.ResetReadPointer( 0 ); /* -------------------------------------------------------------------- */ /* Copy header, inserting in new objects as needed. */ /* -------------------------------------------------------------------- */ char szLineBuf[257]; int nCode = 0; CPLString osSection; CPLString osTable; CPLString osEntity; while( (nCode = oHeaderDS.ReadValue( szLineBuf, sizeof(szLineBuf) )) != -1 && osSection != "ENTITIES" ) { if( nCode == 0 && EQUAL(szLineBuf,"ENDTAB") ) { // If we are at the end of the LAYER TABLE consider inserting // missing definitions. if( osTable == "LAYER" ) { if( !WriteNewLayerDefinitions( fp ) ) return false; } // If at the end of the BLOCK_RECORD TABLE consider inserting // missing definitions. if( osTable == "BLOCK_RECORD" && poBlocksLayer ) { if( !WriteNewBlockRecords( fp ) ) return false; } // If at the end of the LTYPE TABLE consider inserting // missing layer type definitions. if( osTable == "LTYPE" ) { if( !WriteNewLineTypeRecords( fp ) ) return false; } osTable = ""; } // If we are at the end of the BLOCKS section, consider inserting // supplementary blocks. if( nCode == 0 && osSection == "BLOCKS" && EQUAL(szLineBuf,"ENDSEC") && poBlocksLayer != NULL ) { if( !WriteNewBlockDefinitions( fp ) ) return false; } // We need to keep track of where $HANDSEED is so that we can // come back and fix it up when we have generated all entity ids. if( nCode == 9 && EQUAL(szLineBuf,"$HANDSEED") ) { if( !WriteValue( fpOut, nCode, szLineBuf ) ) return false; nCode = oHeaderDS.ReadValue( szLineBuf, sizeof(szLineBuf) ); // ensure we have room to overwrite with a longer value. while( strlen(szLineBuf) < 8 ) { memmove( szLineBuf+1, szLineBuf, strlen(szLineBuf)+1 ); szLineBuf[0] = '0'; } nHANDSEEDOffset = VSIFTellL( fpOut ); } // Patch EXTMIN with minx and miny if( nCode == 9 && EQUAL(szLineBuf,"$EXTMIN") ) { if( !WriteValue( fpOut, nCode, szLineBuf ) ) return false; nCode = oHeaderDS.ReadValue( szLineBuf, sizeof(szLineBuf) ); if (nCode == 10) { if( !WriteValue( fpOut, nCode, oGlobalEnvelope.MinX ) ) return false; nCode = oHeaderDS.ReadValue( szLineBuf, sizeof(szLineBuf) ); if (nCode == 20) { if( !WriteValue( fpOut, nCode, oGlobalEnvelope.MinY ) ) return false; continue; } } } // Patch EXTMAX with maxx and maxy if( nCode == 9 && EQUAL(szLineBuf,"$EXTMAX") ) { if( !WriteValue( fpOut, nCode, szLineBuf ) ) return false; nCode = oHeaderDS.ReadValue( szLineBuf, sizeof(szLineBuf) ); if (nCode == 10) { if( !WriteValue( fpOut, nCode, oGlobalEnvelope.MaxX ) ) return false; nCode = oHeaderDS.ReadValue( szLineBuf, sizeof(szLineBuf) ); if (nCode == 20) { if( !WriteValue( fpOut, nCode, oGlobalEnvelope.MaxY ) ) return false; continue; } } } // Copy over the source line. if( !WriteValue( fpOut, nCode, szLineBuf ) ) return false; // Track what entity we are in - that is the last "code 0" object. if( nCode == 0 ) osEntity = szLineBuf; // Track what section we are in. if( nCode == 0 && EQUAL(szLineBuf,"SECTION") ) { nCode = oHeaderDS.ReadValue( szLineBuf ); if( nCode == -1 ) break; if( !WriteValue( fpOut, nCode, szLineBuf ) ) return false; osSection = szLineBuf; } // Track what TABLE we are in. if( nCode == 0 && EQUAL(szLineBuf,"TABLE") ) { nCode = oHeaderDS.ReadValue( szLineBuf ); if( !WriteValue( fpOut, nCode, szLineBuf ) ) return false; osTable = szLineBuf; } // If we are starting the first layer, then capture // the layer contents while copying so we can duplicate // it for any new layer definitions. if( nCode == 0 && EQUAL(szLineBuf,"LAYER") && osTable == "LAYER" && aosDefaultLayerText.empty() ) { do { anDefaultLayerCode.push_back( nCode ); aosDefaultLayerText.push_back( szLineBuf ); if( nCode != 0 && !WriteValue( fpOut, nCode, szLineBuf ) ) return false; nCode = oHeaderDS.ReadValue( szLineBuf ); if( nCode == 2 && !EQUAL(szLineBuf,"0") ) { anDefaultLayerCode.resize(0); aosDefaultLayerText.resize(0); break; } } while( nCode != 0 ); oHeaderDS.UnreadValue(); } } return true; }
GDALDataset *E00GRIDDataset::Open( GDALOpenInfo * poOpenInfo ) { if (!Identify(poOpenInfo)) return NULL; /* -------------------------------------------------------------------- */ /* Find dataset characteristics */ /* -------------------------------------------------------------------- */ VSILFILE* fp = VSIFOpenL(poOpenInfo->pszFilename, "rb"); if (fp == NULL) return NULL; if (poOpenInfo->eAccess == GA_Update) { CPLError( CE_Failure, CPLE_NotSupported, "The E00GRID driver does not support update access to existing" " datasets.\n" ); VSIFCloseL(fp); return NULL; } /* -------------------------------------------------------------------- */ /* Create a corresponding GDALDataset. */ /* -------------------------------------------------------------------- */ E00GRIDDataset *poDS = new E00GRIDDataset(); if (strstr((const char*)poOpenInfo->pabyHeader, "\r\n") != NULL) poDS->nBytesEOL = 2; poDS->fp = fp; /* read EXP 0 or EXP 1 line */ const char* pszLine = CPLReadLine2L(fp, 81, NULL); if (pszLine == NULL) { CPLDebug("E00GRID", "Bad 1st line"); delete poDS; return NULL; } bool bCompressed = STARTS_WITH_CI(pszLine, "EXP 1"); E00ReadPtr e00ReadPtr = NULL; if (bCompressed) { VSIRewindL(fp); e00ReadPtr = E00ReadCallbackOpen(poDS, E00GRIDDataset::ReadNextLine, E00GRIDDataset::Rewind); if (e00ReadPtr == NULL) { delete poDS; return NULL; } E00ReadNextLine(e00ReadPtr); poDS->e00ReadPtr = e00ReadPtr; } /* skip GRD 2 line */ if (e00ReadPtr) pszLine = E00ReadNextLine(e00ReadPtr); else pszLine = CPLReadLine2L(fp, 81, NULL); if (pszLine == NULL || !STARTS_WITH_CI(pszLine, "GRD 2")) { CPLDebug("E00GRID", "Bad 2nd line"); delete poDS; return NULL; } /* read ncols, nrows and nodata value */ if (e00ReadPtr) pszLine = E00ReadNextLine(e00ReadPtr); else pszLine = CPLReadLine2L(fp, 81, NULL); if (pszLine == NULL || strlen(pszLine) < E00_INT_SIZE+E00_INT_SIZE+2+E00_DOUBLE_SIZE) { CPLDebug("E00GRID", "Bad 3rd line"); delete poDS; return NULL; } const int nRasterXSize = atoi(pszLine); const int nRasterYSize = atoi(pszLine + E00_INT_SIZE); if (!GDALCheckDatasetDimensions(nRasterXSize, nRasterYSize)) { delete poDS; return NULL; } GDALDataType eDT = GDT_Float32; if (STARTS_WITH_CI(pszLine + E00_INT_SIZE + E00_INT_SIZE, " 1")) eDT = GDT_Int32; else if (STARTS_WITH_CI(pszLine + E00_INT_SIZE + E00_INT_SIZE, " 2")) eDT = GDT_Float32; else { CPLDebug("E00GRID", "Unknown data type : %s", pszLine); } const double dfNoData = CPLAtof(pszLine + E00_INT_SIZE + E00_INT_SIZE + 2); /* read pixel size */ if (e00ReadPtr) pszLine = E00ReadNextLine(e00ReadPtr); else pszLine = CPLReadLine2L(fp, 81, NULL); if (pszLine == NULL || strlen(pszLine) < 2*E00_DOUBLE_SIZE) { CPLDebug("E00GRID", "Bad 4th line"); delete poDS; return NULL; } /* double dfPixelX = CPLAtof(pszLine); double dfPixelY = CPLAtof(pszLine + E00_DOUBLE_SIZE); */ /* read xmin, ymin */ if (e00ReadPtr) pszLine = E00ReadNextLine(e00ReadPtr); else pszLine = CPLReadLine2L(fp, 81, NULL); if (pszLine == NULL || strlen(pszLine) < 2*E00_DOUBLE_SIZE) { CPLDebug("E00GRID", "Bad 5th line"); delete poDS; return NULL; } const double dfMinX = CPLAtof(pszLine); const double dfMinY = CPLAtof(pszLine + E00_DOUBLE_SIZE); /* read xmax, ymax */ if (e00ReadPtr) pszLine = E00ReadNextLine(e00ReadPtr); else pszLine = CPLReadLine2L(fp, 81, NULL); if (pszLine == NULL || strlen(pszLine) < 2*E00_DOUBLE_SIZE) { CPLDebug("E00GRID", "Bad 6th line"); delete poDS; return NULL; } const double dfMaxX = CPLAtof(pszLine); const double dfMaxY = CPLAtof(pszLine + E00_DOUBLE_SIZE); poDS->nRasterXSize = nRasterXSize; poDS->nRasterYSize = nRasterYSize; poDS->dfNoData = dfNoData; poDS->adfGeoTransform[0] = dfMinX; poDS->adfGeoTransform[1] = (dfMaxX - dfMinX) / nRasterXSize; poDS->adfGeoTransform[2] = 0; poDS->adfGeoTransform[3] = dfMaxY; poDS->adfGeoTransform[4] = 0; poDS->adfGeoTransform[5] = - (dfMaxY - dfMinY) / nRasterYSize; poDS->nDataStart = VSIFTellL(fp); if (bCompressed) { poDS->panOffsets = (vsi_l_offset*) VSIMalloc2(sizeof(vsi_l_offset), nRasterYSize); if (poDS->panOffsets == NULL) { delete poDS; return NULL; } } /* -------------------------------------------------------------------- */ /* Create band information objects. */ /* -------------------------------------------------------------------- */ poDS->nBands = 1; for( int i = 0; i < poDS->nBands; i++ ) poDS->SetBand( i+1, new E00GRIDRasterBand( poDS, i+1, eDT ) ); /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ poDS->SetDescription( poOpenInfo->pszFilename ); poDS->TryLoadXML(); /* -------------------------------------------------------------------- */ /* Support overviews. */ /* -------------------------------------------------------------------- */ poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename ); return poDS; }
OGRErr OGRCSVLayer::CreateFeature( OGRFeature *poNewFeature ) { int iField; if( !bInWriteMode ) { CPLError( CE_Failure, CPLE_AppDefined, "The CreateFeature() operation is not permitted on a read-only CSV." ); return OGRERR_FAILURE; } /* If we need rewind, it means that we have just written a feature before */ /* so there's no point seeking to the end of the file, as we're already */ /* at the end */ int bNeedSeekEnd = !bNeedRewindBeforeRead; bNeedRewindBeforeRead = TRUE; /* -------------------------------------------------------------------- */ /* Write field names if we haven't written them yet. */ /* Write .csvt file if needed */ /* -------------------------------------------------------------------- */ if( bNew ) { OGRErr eErr = WriteHeader(); if (eErr != OGRERR_NONE) return eErr; bNeedSeekEnd = FALSE; } if (fpCSV == NULL) return OGRERR_FAILURE; /* -------------------------------------------------------------------- */ /* Make sure we are at the end of the file. */ /* -------------------------------------------------------------------- */ if (bNeedSeekEnd) { if (bFirstFeatureAppendedDuringSession) { /* Add a newline character to the end of the file if necessary */ bFirstFeatureAppendedDuringSession = FALSE; VSIFSeekL( fpCSV, 0, SEEK_END ); VSIFSeekL( fpCSV, VSIFTellL(fpCSV) - 1, SEEK_SET); char chLast; VSIFReadL( &chLast, 1, 1, fpCSV ); VSIFSeekL( fpCSV, 0, SEEK_END ); if (chLast != '\n') { if( bUseCRLF ) VSIFPutcL( 13, fpCSV ); VSIFPutcL( '\n', fpCSV ); } } else { VSIFSeekL( fpCSV, 0, SEEK_END ); } } /* -------------------------------------------------------------------- */ /* Write out the geometry */ /* -------------------------------------------------------------------- */ if (eGeometryFormat == OGR_CSV_GEOM_AS_WKT) { OGRGeometry *poGeom = poNewFeature->GetGeometryRef(); char* pszWKT = NULL; if (poGeom && poGeom->exportToWkt(&pszWKT) == OGRERR_NONE) { VSIFPrintfL( fpCSV, "\"%s\"", pszWKT); } else { VSIFPrintfL( fpCSV, "\"\""); } CPLFree(pszWKT); if (poFeatureDefn->GetFieldCount() > 0) VSIFPrintfL( fpCSV, "%c", chDelimiter); } else if (eGeometryFormat == OGR_CSV_GEOM_AS_XYZ || eGeometryFormat == OGR_CSV_GEOM_AS_XY || eGeometryFormat == OGR_CSV_GEOM_AS_YX) { OGRGeometry *poGeom = poNewFeature->GetGeometryRef(); if (poGeom && wkbFlatten(poGeom->getGeometryType()) == wkbPoint) { OGRPoint* poPoint = (OGRPoint*) poGeom; char szBuffer[75]; if (eGeometryFormat == OGR_CSV_GEOM_AS_XYZ ) OGRMakeWktCoordinate(szBuffer, poPoint->getX(), poPoint->getY(), poPoint->getZ(), 3); else if (eGeometryFormat == OGR_CSV_GEOM_AS_XY ) OGRMakeWktCoordinate(szBuffer, poPoint->getX(), poPoint->getY(), 0, 2); else OGRMakeWktCoordinate(szBuffer, poPoint->getY(), poPoint->getX(), 0, 2); char* pc = szBuffer; while(*pc != '\0') { if (*pc == ' ') *pc = chDelimiter; pc ++; } VSIFPrintfL( fpCSV, "%s", szBuffer ); } else { VSIFPrintfL( fpCSV, "%c", chDelimiter ); if (eGeometryFormat == OGR_CSV_GEOM_AS_XYZ) VSIFPrintfL( fpCSV, "%c", chDelimiter ); } if (poFeatureDefn->GetFieldCount() > 0) VSIFPrintfL( fpCSV, "%c", chDelimiter ); } /* -------------------------------------------------------------------- */ /* Write out all the field values. */ /* -------------------------------------------------------------------- */ int bNonEmptyLine = FALSE; for( iField = 0; iField < poFeatureDefn->GetFieldCount(); iField++ ) { char *pszEscaped; if( iField > 0 ) VSIFPrintfL( fpCSV, "%c", chDelimiter ); if (poFeatureDefn->GetFieldDefn(iField)->GetType() == OFTReal) { pszEscaped = CPLStrdup(poNewFeature->GetFieldAsString(iField)); /* Use point as decimal separator */ char* pszComma = strchr(pszEscaped, ','); if (pszComma) *pszComma = '.'; } else { pszEscaped = CPLEscapeString( poNewFeature->GetFieldAsString(iField), -1, CPLES_CSV ); } int nLen = (int)strlen(pszEscaped); bNonEmptyLine |= (nLen != 0); VSIFWriteL( pszEscaped, 1, nLen, fpCSV ); CPLFree( pszEscaped ); } if( poFeatureDefn->GetFieldCount() == 1 && !bNonEmptyLine ) VSIFPrintfL( fpCSV, "%c", chDelimiter ); if( bUseCRLF ) VSIFPutcL( 13, fpCSV ); VSIFPutcL( '\n', fpCSV ); return OGRERR_NONE; }
OGRFeature *OGRBNALayer::GetNextFeature() { OGRFeature *poFeature; BNARecord* record; int offset, line; if (failed || eof) return NULL; while(1) { int ok = FALSE; offset = (int) VSIFTellL(fpBNA); line = curLine; if (nNextFID < nFeatures) { VSIFSeekL( fpBNA, offsetAndLineFeaturesTable[nNextFID].offset, SEEK_SET ); curLine = offsetAndLineFeaturesTable[nNextFID].line; } record = BNA_GetNextRecord(fpBNA, &ok, &curLine, TRUE, bnaFeatureType); if (ok == FALSE) { BNA_FreeRecord(record); failed = TRUE; return NULL; } if (record == NULL) { /* end of file */ eof = TRUE; /* and we have finally build the whole index table */ partialIndexTable = FALSE; return NULL; } if (record->featureType == bnaFeatureType) { if (nNextFID >= nFeatures) { nFeatures++; offsetAndLineFeaturesTable = (OffsetAndLine*)CPLRealloc(offsetAndLineFeaturesTable, nFeatures * sizeof(OffsetAndLine)); offsetAndLineFeaturesTable[nFeatures-1].offset = offset; offsetAndLineFeaturesTable[nFeatures-1].line = line; } poFeature = BuildFeatureFromBNARecord(record, nNextFID++); BNA_FreeRecord(record); if( (m_poFilterGeom == NULL || FilterGeometry( poFeature->GetGeometryRef() ) ) && (m_poAttrQuery == NULL || m_poAttrQuery->Evaluate( poFeature )) ) { return poFeature; } delete poFeature; } else { BNA_FreeRecord(record); } } }
static void msTransformToGeospatialPDF(imageObj *img, mapObj *map, cairo_renderer *r) { /* We need a GDAL 1.10 PDF driver at runtime, but as far as the C API is concerned, GDAL 1.9 is */ /* largely sufficient. */ #if defined(USE_GDAL) && defined(GDAL_VERSION_NUM) && GDAL_VERSION_NUM >= 1900 GDALDatasetH hDS = NULL; const char* pszGEO_ENCODING = NULL; GDALDriverH hPDFDriver = NULL; const char* pszVirtualIO = NULL; int bVirtualIO = FALSE; char* pszTmpFilename = NULL; VSILFILE* fp = NULL; if (map == NULL) return; pszGEO_ENCODING = msGetOutputFormatOption(img->format, "GEO_ENCODING", NULL); if (pszGEO_ENCODING == NULL) return; msGDALInitialize(); hPDFDriver = GDALGetDriverByName("PDF"); if (hPDFDriver == NULL) return; /* When compiled against libpoppler, the PDF driver is VirtualIO capable */ /* but not, when it is compiled against libpodofo. */ pszVirtualIO = GDALGetMetadataItem( hPDFDriver, GDAL_DCAP_VIRTUALIO, NULL ); if (pszVirtualIO) bVirtualIO = CSLTestBoolean(pszVirtualIO); if (bVirtualIO) pszTmpFilename = msTmpFile(map, NULL, "/vsimem/mscairopdf/", "pdf"); else pszTmpFilename = msTmpFile(map, map->mappath, NULL, "pdf"); /* Copy content of outputStream buffer into file */ fp = VSIFOpenL(pszTmpFilename, "wb"); if (fp == NULL) { msFree(pszTmpFilename); return; } VSIFWriteL(r->outputStream->data, 1, r->outputStream->size, fp); VSIFCloseL(fp); fp = NULL; hDS = GDALOpen(pszTmpFilename, GA_Update); if ( hDS != NULL ) { char* pszWKT = msProjectionObj2OGCWKT( &(map->projection) ); if( pszWKT != NULL ) { double adfGeoTransform[6]; int i; /* Add user-specified options */ for( i = 0; i < img->format->numformatoptions; i++ ) { const char* pszOption = img->format->formatoptions[i]; if( strncasecmp(pszOption,"METADATA_ITEM:",14) == 0 ) { char* pszKey = NULL; const char* pszValue = CPLParseNameValue(pszOption + 14, &pszKey); if( pszKey != NULL ) { GDALSetMetadataItem(hDS, pszKey, pszValue, NULL); CPLFree(pszKey); } } } /* We need to rescale the geotransform because GDAL will not necessary */ /* open the PDF with the DPI that was used to generate it */ memcpy(adfGeoTransform, map->gt.geotransform, 6 * sizeof(double)); adfGeoTransform[1] = adfGeoTransform[1] * map->width / GDALGetRasterXSize(hDS); adfGeoTransform[5] = adfGeoTransform[5] * map->height / GDALGetRasterYSize(hDS); GDALSetGeoTransform(hDS, adfGeoTransform); GDALSetProjection(hDS, pszWKT); msFree( pszWKT ); pszWKT = NULL; CPLSetThreadLocalConfigOption("GDAL_PDF_GEO_ENCODING", pszGEO_ENCODING); GDALClose(hDS); hDS = NULL; CPLSetThreadLocalConfigOption("GDAL_PDF_GEO_ENCODING", NULL); /* We need to replace the buffer with the content of the GDAL file */ fp = VSIFOpenL(pszTmpFilename, "rb"); if( fp != NULL ) { int nFileSize; VSIFSeekL(fp, 0, SEEK_END); nFileSize = (int)VSIFTellL(fp); msBufferResize(r->outputStream, nFileSize); VSIFSeekL(fp, 0, SEEK_SET); VSIFReadL(r->outputStream->data, 1, nFileSize, fp); r->outputStream->size = nFileSize; VSIFCloseL(fp); fp = NULL; } } } if ( hDS != NULL ) GDALClose(hDS); VSIUnlink(pszTmpFilename); msFree(pszTmpFilename); #endif }
int DDFModule::Open( const char * pszFilename, int bFailQuietly ) { static const int nLeaderSize = 24; /* -------------------------------------------------------------------- */ /* Close the existing file if there is one. */ /* -------------------------------------------------------------------- */ if( fpDDF != NULL ) Close(); /* -------------------------------------------------------------------- */ /* Open the file. */ /* -------------------------------------------------------------------- */ fpDDF = VSIFOpenL( pszFilename, "rb" ); if( fpDDF == NULL ) { if( !bFailQuietly ) CPLError( CE_Failure, CPLE_OpenFailed, "Unable to open DDF file `%s'.", pszFilename ); return FALSE; } /* -------------------------------------------------------------------- */ /* Read the 24 byte leader. */ /* -------------------------------------------------------------------- */ char achLeader[nLeaderSize]; if( (int)VSIFReadL( achLeader, 1, nLeaderSize, fpDDF ) != nLeaderSize ) { CPL_IGNORE_RET_VAL(VSIFCloseL( fpDDF )); fpDDF = NULL; if( !bFailQuietly ) CPLError( CE_Failure, CPLE_FileIO, "Leader is short on DDF file `%s'.", pszFilename ); return FALSE; } /* -------------------------------------------------------------------- */ /* Verify that this appears to be a valid DDF file. */ /* -------------------------------------------------------------------- */ int i, bValid = TRUE; for( i = 0; i < nLeaderSize; i++ ) { if( achLeader[i] < 32 || achLeader[i] > 126 ) bValid = FALSE; } if( achLeader[5] != '1' && achLeader[5] != '2' && achLeader[5] != '3' ) bValid = FALSE; if( achLeader[6] != 'L' ) bValid = FALSE; if( achLeader[8] != '1' && achLeader[8] != ' ' ) bValid = FALSE; /* -------------------------------------------------------------------- */ /* Extract information from leader. */ /* -------------------------------------------------------------------- */ if( bValid ) { _recLength = DDFScanInt( achLeader+0, 5 ); _interchangeLevel = achLeader[5]; _leaderIden = achLeader[6]; _inlineCodeExtensionIndicator = achLeader[7]; _versionNumber = achLeader[8]; _appIndicator = achLeader[9]; _fieldControlLength = DDFScanInt(achLeader+10,2); _fieldAreaStart = DDFScanInt(achLeader+12,5); _extendedCharSet[0] = achLeader[17]; _extendedCharSet[1] = achLeader[18]; _extendedCharSet[2] = achLeader[19]; _extendedCharSet[3] = '\0'; _sizeFieldLength = DDFScanInt(achLeader+20,1); _sizeFieldPos = DDFScanInt(achLeader+21,1); _sizeFieldTag = DDFScanInt(achLeader+23,1); if( _recLength < nLeaderSize || _fieldControlLength == 0 || _fieldAreaStart < 24 || _sizeFieldLength == 0 || _sizeFieldPos == 0 || _sizeFieldTag == 0 ) { bValid = FALSE; } } /* -------------------------------------------------------------------- */ /* If the header is invalid, then clean up, report the error */ /* and return. */ /* -------------------------------------------------------------------- */ if( !bValid ) { CPL_IGNORE_RET_VAL(VSIFCloseL( fpDDF )); fpDDF = NULL; if( !bFailQuietly ) CPLError( CE_Failure, CPLE_AppDefined, "File `%s' does not appear to have\n" "a valid ISO 8211 header.\n", pszFilename ); return FALSE; } /* -------------------------------------------------------------------- */ /* Read the whole record info memory. */ /* -------------------------------------------------------------------- */ char *pachRecord; pachRecord = (char *) CPLMalloc(_recLength); memcpy( pachRecord, achLeader, nLeaderSize ); if( (int)VSIFReadL( pachRecord+nLeaderSize, 1, _recLength-nLeaderSize, fpDDF ) != _recLength - nLeaderSize ) { if( !bFailQuietly ) CPLError( CE_Failure, CPLE_FileIO, "Header record is short on DDF file `%s'.", pszFilename ); return FALSE; } /* -------------------------------------------------------------------- */ /* First make a pass counting the directory entries. */ /* -------------------------------------------------------------------- */ int nFieldEntryWidth, nFDCount = 0; nFieldEntryWidth = _sizeFieldLength + _sizeFieldPos + _sizeFieldTag; for( i = nLeaderSize; i < _recLength; i += nFieldEntryWidth ) { if( pachRecord[i] == DDF_FIELD_TERMINATOR ) break; nFDCount++; } /* -------------------------------------------------------------------- */ /* Allocate, and read field definitions. */ /* -------------------------------------------------------------------- */ for( i = 0; i < nFDCount; i++ ) { char szTag[128]; int nEntryOffset = nLeaderSize + i*nFieldEntryWidth; int nFieldLength, nFieldPos; DDFFieldDefn *poFDefn; strncpy( szTag, pachRecord+nEntryOffset, _sizeFieldTag ); szTag[_sizeFieldTag] = '\0'; nEntryOffset += _sizeFieldTag; nFieldLength = DDFScanInt( pachRecord+nEntryOffset, _sizeFieldLength ); nEntryOffset += _sizeFieldLength; nFieldPos = DDFScanInt( pachRecord+nEntryOffset, _sizeFieldPos ); if (_fieldAreaStart+nFieldPos < 0 || _recLength - (_fieldAreaStart+nFieldPos) < nFieldLength) { if( !bFailQuietly ) CPLError( CE_Failure, CPLE_FileIO, "Header record invalid on DDF file `%s'.", pszFilename ); CPLFree( pachRecord ); return FALSE; } poFDefn = new DDFFieldDefn(); if( poFDefn->Initialize( this, szTag, nFieldLength, pachRecord+_fieldAreaStart+nFieldPos ) ) AddField( poFDefn ); else delete poFDefn; } CPLFree( pachRecord ); /* -------------------------------------------------------------------- */ /* Record the current file offset, the beginning of the first */ /* data record. */ /* -------------------------------------------------------------------- */ nFirstRecordOffset = (long)VSIFTellL( fpDDF ); return TRUE; }
void GDALPamProxyDB::LoadDB() { /* -------------------------------------------------------------------- */ /* Open the database relating original names to proxy .aux.xml */ /* file names. */ /* -------------------------------------------------------------------- */ CPLString osDBName = CPLFormFilename( osProxyDBDir, "gdal_pam_proxy", "dat" ); FILE *fpDB = VSIFOpenL( osDBName, "r" ); nUpdateCounter = 0; if( fpDB == NULL ) return; /* -------------------------------------------------------------------- */ /* Read header, verify and extract update counter. */ /* -------------------------------------------------------------------- */ GByte abyHeader[100]; if( VSIFReadL( abyHeader, 1, 100, fpDB ) != 100 || strncmp( (const char *) abyHeader, "GDAL_PROXY", 10 ) != 0 ) { CPLError( CE_Failure, CPLE_AppDefined, "Problem reading %s header - short or corrupt?", osDBName.c_str() ); return; } nUpdateCounter = atoi((const char *) abyHeader + 10); /* -------------------------------------------------------------------- */ /* Read the file in one gulp. */ /* -------------------------------------------------------------------- */ int nBufLength; char *pszDBData; VSIFSeekL( fpDB, 0, SEEK_END ); nBufLength = (int) (VSIFTellL(fpDB) - 100); pszDBData = (char *) CPLCalloc(1,nBufLength+1); VSIFSeekL( fpDB, 100, SEEK_SET ); VSIFReadL( pszDBData, 1, nBufLength, fpDB ); VSIFCloseL( fpDB ); /* -------------------------------------------------------------------- */ /* Parse the list of in/out names. */ /* -------------------------------------------------------------------- */ int iNext = 0; while( iNext < nBufLength ) { CPLString osOriginal, osProxy; osOriginal.assign( pszDBData + iNext ); for( ; iNext < nBufLength && pszDBData[iNext] != '\0'; iNext++ ) {} if( iNext == nBufLength ) break; iNext++; osProxy = osProxyDBDir; osProxy += "/"; osProxy += pszDBData + iNext; for( ; iNext < nBufLength && pszDBData[iNext] != '\0'; iNext++ ) {} iNext++; aosOriginalFiles.push_back( osOriginal ); aosProxyFiles.push_back( osProxy ); } CPLFree( pszDBData ); }
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 = atof( 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 = atof( 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 ); }
CPLErr XYZRasterBand::IReadBlock( CPL_UNUSED int nBlockXOff, int nBlockYOff, void * pImage ) { XYZDataset *poGDS = (XYZDataset *) poDS; if (poGDS->fp == NULL) return CE_Failure; if( pImage ) { int bSuccess = FALSE; double dfNoDataValue = GetNoDataValue(&bSuccess); if( !bSuccess ) dfNoDataValue = 0.0; GDALCopyWords(&dfNoDataValue, GDT_Float64, 0, pImage, eDataType, GDALGetDataTypeSize(eDataType) / 8, nRasterXSize); } int nLineInFile = nBlockYOff * nBlockXSize; // only valid if bSameNumberOfValuesPerLine if ( (poGDS->bSameNumberOfValuesPerLine && poGDS->nDataLineNum > nLineInFile) || (!poGDS->bSameNumberOfValuesPerLine && (nLastYOff == -1 || nBlockYOff == 0)) ) { poGDS->nDataLineNum = 0; poGDS->nLineNum = 0; VSIFSeekL(poGDS->fp, 0, SEEK_SET); for(int i=0;i<poGDS->nCommentLineCount;i++) { CPLReadLine2L(poGDS->fp, 100, NULL); poGDS->nLineNum ++; } if (poGDS->bHasHeaderLine) { const char* pszLine = CPLReadLine2L(poGDS->fp, 100, 0); if (pszLine == NULL) return CE_Failure; poGDS->nLineNum ++; } } if( !poGDS->bSameNumberOfValuesPerLine && nBlockYOff != nLastYOff + 1 ) { int iY; if( nBlockYOff < nLastYOff ) { nLastYOff = -1; for(iY = 0; iY < nBlockYOff; iY++) { if( IReadBlock(0, iY, NULL) != CE_None ) return CE_Failure; } } else { for(iY = nLastYOff + 1; iY < nBlockYOff; iY++) { if( IReadBlock(0, iY, NULL) != CE_None ) return CE_Failure; } } } else if( poGDS->bSameNumberOfValuesPerLine ) { while(poGDS->nDataLineNum < nLineInFile) { const char* pszLine = CPLReadLine2L(poGDS->fp, 100, 0); if (pszLine == NULL) return CE_Failure; poGDS->nLineNum ++; const char* pszPtr = pszLine; char ch; int nCol = 0; int bLastWasSep = TRUE; while((ch = *pszPtr) != '\0') { if (ch == ' ') { if (!bLastWasSep) nCol ++; bLastWasSep = TRUE; } else if ((ch == ',' && poGDS->chDecimalSep != ',') || ch == '\t' || ch == ';') { nCol ++; bLastWasSep = TRUE; } else { bLastWasSep = FALSE; } pszPtr ++; } /* Skip empty line */ if (nCol == 0 && bLastWasSep) continue; poGDS->nDataLineNum ++; } } double dfExpectedY = poGDS->adfGeoTransform[3] + (0.5 + nBlockYOff) * poGDS->adfGeoTransform[5]; int idx = -1; while(TRUE) { int nCol; int bLastWasSep; do { vsi_l_offset nOffsetBefore = VSIFTellL(poGDS->fp); const char* pszLine = CPLReadLine2L(poGDS->fp, 100, 0); if (pszLine == NULL) { if( poGDS->bSameNumberOfValuesPerLine ) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot read line %d", poGDS->nLineNum + 1); return CE_Failure; } else { nLastYOff = nBlockYOff; return CE_None; } } poGDS->nLineNum ++; const char* pszPtr = pszLine; char ch; nCol = 0; bLastWasSep = TRUE; double dfX = 0.0, dfY = 0.0, dfZ = 0.0; int bUsefulColsFound = 0; while((ch = *pszPtr) != '\0') { if (ch == ' ') { if (!bLastWasSep) nCol ++; bLastWasSep = TRUE; } else if ((ch == ',' && poGDS->chDecimalSep != ',') || ch == '\t' || ch == ';') { nCol ++; bLastWasSep = TRUE; } else { if (bLastWasSep) { if (nCol == poGDS->nXIndex) { bUsefulColsFound ++; if( !poGDS->bSameNumberOfValuesPerLine ) dfX = CPLAtofDelim(pszPtr, poGDS->chDecimalSep); } else if (nCol == poGDS->nYIndex) { bUsefulColsFound ++; if( !poGDS->bSameNumberOfValuesPerLine ) dfY = CPLAtofDelim(pszPtr, poGDS->chDecimalSep); } else if( nCol == poGDS->nZIndex) { bUsefulColsFound ++; dfZ = CPLAtofDelim(pszPtr, poGDS->chDecimalSep); } } bLastWasSep = FALSE; } pszPtr ++; } nCol ++; if( bUsefulColsFound == 3 ) { if( poGDS->bSameNumberOfValuesPerLine ) { idx ++; } else { if( fabs(dfY - dfExpectedY) > 1e-8 ) { if( idx < 0 ) { CPLError(CE_Failure, CPLE_AppDefined, "At line %d, found %f instead of %f for nBlockYOff = %d", poGDS->nLineNum, dfY, dfExpectedY, nBlockYOff); return CE_Failure; } VSIFSeekL(poGDS->fp, nOffsetBefore, SEEK_SET); nLastYOff = nBlockYOff; poGDS->nLineNum --; return CE_None; } idx = (int)((dfX - 0.5 * poGDS->adfGeoTransform[1] - poGDS->adfGeoTransform[0]) / poGDS->adfGeoTransform[1] + 0.5); } CPLAssert(idx >= 0 && idx < nRasterXSize); if( pImage ) { if (eDataType == GDT_Float32) { ((float*)pImage)[idx] = (float)dfZ; } else if (eDataType == GDT_Int32) { ((GInt32*)pImage)[idx] = (GInt32)dfZ; } else if (eDataType == GDT_Int16) { ((GInt16*)pImage)[idx] = (GInt16)dfZ; } else { ((GByte*)pImage)[idx] = (GByte)dfZ; } } } /* Skip empty line */ } while (nCol == 1 && bLastWasSep); poGDS->nDataLineNum ++; if (nCol < poGDS->nMinTokens) return CE_Failure; if( idx + 1 == nRasterXSize ) break; } if( poGDS->bSameNumberOfValuesPerLine ) { CPLAssert(poGDS->nDataLineNum == (nBlockYOff + 1) * nBlockXSize); } nLastYOff = nBlockYOff; return CE_None; }
Track* GTM::fetchNextTrack() { /* Point to the actual track offset */ if ( VSIFSeekL(pGTMFile, actualTrackOffset, SEEK_SET) != 0) return nullptr; /* Read string length */ const unsigned short stringSize = readUShort(pGTMFile); /* Read name string */ char* pszName = (char*) VSI_MALLOC2_VERBOSE(sizeof(char), stringSize+1); if( pszName == nullptr ) return nullptr; if ( stringSize != 0 && !readFile( pszName, 1, sizeof(char) * stringSize ) ) { CPLFree(pszName); return nullptr; } pszName[stringSize] = '\0'; /* Read type */ const unsigned char type = readUChar(pGTMFile); /* Read color */ const int color = readInt(pGTMFile); Track* poTrack = new Track(pszName, type, color); CPLFree(pszName); /* Adjust actual Track offset */ actualTrackOffset = VSIFTellL(pGTMFile) + 7; ++trackFetched; /* Now, We read all trackpoints for this track */ double latitude = 0.0; double longitude = 0.0; GIntBig datetime = 0; unsigned char start = 0; float altitude = 0.0f; /* NOTE: Parameters are passed by reference */ if ( !readTrackPoints(latitude, longitude, datetime, start, altitude) ) { delete poTrack; return nullptr; } /* Check if it is the start, if not we have done something wrong */ if (start != 1) { delete poTrack; return nullptr; } poTrack->addPoint(longitude, latitude, datetime, altitude); do { /* NOTE: Parameters are passed by reference */ if ( !readTrackPoints(latitude, longitude, datetime, start, altitude) ) { delete poTrack; return nullptr; } if (start == 0) poTrack->addPoint(longitude, latitude, datetime, altitude); } while(start == 0 && trackpointFetched < ntcks); /* We have read one more than necessary, so we adjust the offset */ if (trackpointFetched < ntcks) { actualTrackpointOffset -= 25; --trackpointFetched; } return poTrack; }
/********************************************************************** * TABRawBinBlock::CommitToFile() * * Commit the current state of the binary block to the file to which * it has been previously attached. * * Derived classes may want to (optionally) reimplement this method if * they need to do special processing before committing the block to disk. * * For files created with bHardBlockSize=TRUE, a complete block of * the specified size is always written, otherwise only the number of * used bytes in the block will be written to disk. * * Returns 0 if successful or -1 if an error happened, in which case * CPLError() will have been called. **********************************************************************/ int TABRawBinBlock::CommitToFile() { int nStatus = 0; if (m_fp == NULL || m_nBlockSize <= 0 || m_pabyBuf == NULL || m_nFileOffset < 0) { CPLError(CE_Failure, CPLE_AssertionFailed, "TABRawBinBlock::CommitToFile(): Block has not been initialized yet!"); return -1; } /*---------------------------------------------------------------- * If block has not been modified, then just return... nothing to do. *---------------------------------------------------------------*/ if (!m_bModified) return 0; /*---------------------------------------------------------------- * Move the output file pointer to the right position... *---------------------------------------------------------------*/ if (VSIFSeekL(m_fp, m_nFileOffset, SEEK_SET) != 0) { /*------------------------------------------------------------ * Moving pointer failed... we may need to pad with zeros if * block destination is beyond current end of file. *-----------------------------------------------------------*/ int nCurPos = (int)VSIFTellL(m_fp); if (nCurPos < m_nFileOffset && VSIFSeekL(m_fp, 0L, SEEK_END) == 0 && (nCurPos = (int)VSIFTellL(m_fp)) < m_nFileOffset) { const GByte cZero = 0; while(nCurPos < m_nFileOffset && nStatus == 0) { if (VSIFWriteL(&cZero, 1, 1, m_fp) != 1) { CPLError(CE_Failure, CPLE_FileIO, "Failed writing 1 byte at offset %d.", nCurPos); nStatus = -1; break; } nCurPos++; } } if (nCurPos != m_nFileOffset) nStatus = -1; // Error message will follow below } /*---------------------------------------------------------------- * At this point we are ready to write to the file. * * If m_bHardBlockSize==FALSE, then we do not write a complete block; * we write only the part of the block that was used. *---------------------------------------------------------------*/ int numBytesToWrite = m_bHardBlockSize?m_nBlockSize:m_nSizeUsed; /*CPLDebug("MITAB", "Committing to offset %d", m_nFileOffset);*/ if (nStatus != 0 || VSIFWriteL(m_pabyBuf,sizeof(GByte), numBytesToWrite, m_fp) != (size_t)numBytesToWrite ) { CPLError(CE_Failure, CPLE_FileIO, "Failed writing %d bytes at offset %d.", numBytesToWrite, m_nFileOffset); return -1; } if( m_nFileOffset + numBytesToWrite > m_nFileSize ) { m_nFileSize = m_nFileOffset + numBytesToWrite; } VSIFFlushL(m_fp); m_bModified = FALSE; return 0; }
GDALDataset *NTv2Dataset::Create( const char * pszFilename, int nXSize, int nYSize, CPL_UNUSED int nBands, GDALDataType eType, char ** papszOptions ) { if( eType != GDT_Float32 ) { CPLError(CE_Failure, CPLE_AppDefined, "Attempt to create NTv2 file with unsupported data type '%s'.", GDALGetDataTypeName( eType ) ); return NULL; } /* -------------------------------------------------------------------- */ /* Are we extending an existing file? */ /* -------------------------------------------------------------------- */ VSILFILE *fp; GUInt32 nNumFile = 1; int bAppend = CSLFetchBoolean(papszOptions,"APPEND_SUBDATASET",FALSE); /* -------------------------------------------------------------------- */ /* Try to open or create file. */ /* -------------------------------------------------------------------- */ if( bAppend ) fp = VSIFOpenL( pszFilename, "rb+" ); else fp = VSIFOpenL( pszFilename, "wb" ); if( fp == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "Attempt to open/create file `%s' failed.\n", pszFilename ); return NULL; } /* -------------------------------------------------------------------- */ /* Create a file level header if we are creating new. */ /* -------------------------------------------------------------------- */ char achHeader[11*16]; const char *pszValue; if( !bAppend ) { memset( achHeader, 0, sizeof(achHeader) ); memcpy( achHeader + 0*16, "NUM_OREC", 8 ); achHeader[ 0*16 + 8] = 0xb; memcpy( achHeader + 1*16, "NUM_SREC", 8 ); achHeader[ 1*16 + 8] = 0xb; memcpy( achHeader + 2*16, "NUM_FILE", 8 ); achHeader[ 2*16 + 8] = 0x1; memcpy( achHeader + 3*16, "GS_TYPE ", 16 ); pszValue = CSLFetchNameValueDef( papszOptions, "GS_TYPE", "SECONDS"); memcpy( achHeader + 3*16+8, pszValue, MIN(16,strlen(pszValue)) ); memcpy( achHeader + 4*16, "VERSION ", 16 ); pszValue = CSLFetchNameValueDef( papszOptions, "VERSION", "" ); memcpy( achHeader + 4*16+8, pszValue, MIN(16,strlen(pszValue)) ); memcpy( achHeader + 5*16, "SYSTEM_F ", 16 ); pszValue = CSLFetchNameValueDef( papszOptions, "SYSTEM_F", "" ); memcpy( achHeader + 5*16+8, pszValue, MIN(16,strlen(pszValue)) ); memcpy( achHeader + 6*16, "SYSTEM_T ", 16 ); pszValue = CSLFetchNameValueDef( papszOptions, "SYSTEM_T", "" ); memcpy( achHeader + 6*16+8, pszValue, MIN(16,strlen(pszValue)) ); memcpy( achHeader + 7*16, "MAJOR_F ", 8); memcpy( achHeader + 8*16, "MINOR_F ", 8 ); memcpy( achHeader + 9*16, "MAJOR_T ", 8 ); memcpy( achHeader + 10*16, "MINOR_T ", 8 ); VSIFWriteL( achHeader, 1, sizeof(achHeader), fp ); } /* -------------------------------------------------------------------- */ /* Otherwise update the header with an increased subfile count, */ /* and advanced to the last record of the file. */ /* -------------------------------------------------------------------- */ else { VSIFSeekL( fp, 2*16 + 8, SEEK_SET ); VSIFReadL( &nNumFile, 1, 4, fp ); CPL_LSBPTR32( &nNumFile ); nNumFile++; CPL_LSBPTR32( &nNumFile ); VSIFSeekL( fp, 2*16 + 8, SEEK_SET ); VSIFWriteL( &nNumFile, 1, 4, fp ); vsi_l_offset nEnd; VSIFSeekL( fp, 0, SEEK_END ); nEnd = VSIFTellL( fp ); VSIFSeekL( fp, nEnd-16, SEEK_SET ); } /* -------------------------------------------------------------------- */ /* Write the grid header. */ /* -------------------------------------------------------------------- */ memset( achHeader, 0, sizeof(achHeader) ); memcpy( achHeader + 0*16, "SUB_NAME ", 16 ); pszValue = CSLFetchNameValueDef( papszOptions, "SUB_NAME", "" ); memcpy( achHeader + 0*16+8, pszValue, MIN(16,strlen(pszValue)) ); memcpy( achHeader + 1*16, "PARENT ", 16 ); pszValue = CSLFetchNameValueDef( papszOptions, "PARENT", "NONE" ); memcpy( achHeader + 1*16+8, pszValue, MIN(16,strlen(pszValue)) ); memcpy( achHeader + 2*16, "CREATED ", 16 ); pszValue = CSLFetchNameValueDef( papszOptions, "CREATED", "" ); memcpy( achHeader + 2*16+8, pszValue, MIN(16,strlen(pszValue)) ); memcpy( achHeader + 3*16, "UPDATED ", 16 ); pszValue = CSLFetchNameValueDef( papszOptions, "UPDATED", "" ); memcpy( achHeader + 3*16+8, pszValue, MIN(16,strlen(pszValue)) ); double dfValue; memcpy( achHeader + 4*16, "S_LAT ", 8 ); dfValue = 0; CPL_LSBPTR64( &dfValue ); memcpy( achHeader + 4*16 + 8, &dfValue, 8 ); memcpy( achHeader + 5*16, "N_LAT ", 8 ); dfValue = nYSize-1; CPL_LSBPTR64( &dfValue ); memcpy( achHeader + 5*16 + 8, &dfValue, 8 ); memcpy( achHeader + 6*16, "E_LONG ", 8 ); dfValue = -1*(nXSize-1); CPL_LSBPTR64( &dfValue ); memcpy( achHeader + 6*16 + 8, &dfValue, 8 ); memcpy( achHeader + 7*16, "W_LONG ", 8 ); dfValue = 0; CPL_LSBPTR64( &dfValue ); memcpy( achHeader + 7*16 + 8, &dfValue, 8 ); memcpy( achHeader + 8*16, "LAT_INC ", 8 ); dfValue = 1; CPL_LSBPTR64( &dfValue ); memcpy( achHeader + 8*16 + 8, &dfValue, 8 ); memcpy( achHeader + 9*16, "LONG_INC", 8 ); memcpy( achHeader + 9*16 + 8, &dfValue, 8 ); memcpy( achHeader + 10*16, "GS_COUNT", 8 ); GUInt32 nGSCount = nXSize * nYSize; CPL_LSBPTR32( &nGSCount ); memcpy( achHeader + 10*16+8, &nGSCount, 4 ); VSIFWriteL( achHeader, 1, sizeof(achHeader), fp ); /* -------------------------------------------------------------------- */ /* Write zeroed grid data. */ /* -------------------------------------------------------------------- */ int i; memset( achHeader, 0, 16 ); // Use -1 (0x000080bf) as the default error value. memset( achHeader + 10, 0x80, 1 ); memset( achHeader + 11, 0xbf, 1 ); memset( achHeader + 14, 0x80, 1 ); memset( achHeader + 15, 0xbf, 1 ); for( i = 0; i < nXSize * nYSize; i++ ) VSIFWriteL( achHeader, 1, 16, fp ); /* -------------------------------------------------------------------- */ /* Write the end record. */ /* -------------------------------------------------------------------- */ memset( achHeader, 0, 16 ); memcpy( achHeader, "END ", 8 ); VSIFWriteL( achHeader, 1, 16, fp ); VSIFCloseL( fp ); if( nNumFile == 1 ) return (GDALDataset *) GDALOpen( pszFilename, GA_Update ); else { CPLString osSubDSName; osSubDSName.Printf( "NTv2:%d:%s", nNumFile-1, pszFilename ); return (GDALDataset *) GDALOpen( osSubDSName, GA_Update ); } }
int OGRBNADataSource::Open( const char * pszFilename, int bUpdateIn) { int ok = FALSE; pszName = CPLStrdup( pszFilename ); bUpdate = bUpdateIn; /* -------------------------------------------------------------------- */ /* Determine what sort of object this is. */ /* -------------------------------------------------------------------- */ VSIStatBufL sStatBuf; if( VSIStatL( pszFilename, &sStatBuf ) != 0 ) return FALSE; // -------------------------------------------------------------------- // Does this appear to be a .bna file? // -------------------------------------------------------------------- if( !(EQUAL( CPLGetExtension(pszFilename), "bna" ) || ((EQUALN( pszFilename, "/vsigzip/", 9) || EQUALN( pszFilename, "/vsizip/", 8)) && (strstr( pszFilename, ".bna") || strstr( pszFilename, ".BNA")))) ) return FALSE; VSILFILE* fp = VSIFOpenL(pszFilename, "rb"); if (fp) { BNARecord* record; int curLine = 0; const char* layerRadixName[] = { "points", "polygons", "lines", "ellipses"}; OGRwkbGeometryType wkbGeomTypes[] = { wkbPoint, wkbMultiPolygon, wkbLineString, wkbPolygon }; int i; #if defined(BNA_FAST_DS_OPEN) record = BNA_GetNextRecord(fp, &ok, &curLine, FALSE, BNA_READ_NONE); BNA_FreeRecord(record); if (ok) { nLayers = 4; papoLayers = (OGRBNALayer **) CPLMalloc(nLayers * sizeof(OGRBNALayer*)); for(i=0;i<4;i++) papoLayers[i] = new OGRBNALayer( pszFilename, layerRadixName[i], (BNAFeatureType)i, wkbGeomTypes[i], FALSE, this ); } #else int nFeatures[4] = { 0, 0, 0, 0 }; OffsetAndLine* offsetAndLineFeaturesTable[4] = { NULL, NULL, NULL, NULL }; int nIDs[4] = {0, 0, 0, 0}; int partialIndexTable = TRUE; while(1) { int offset = VSIFTellL(fp); int line = curLine; record = BNA_GetNextRecord(fp, &ok, &curLine, FALSE, BNA_READ_NONE); if (ok == FALSE) { BNA_FreeRecord(record); if (line != 0) ok = TRUE; break; } if (record == NULL) { /* end of file */ ok = TRUE; /* and we have finally build the whole index table */ partialIndexTable = FALSE; break; } if (record->nIDs > nIDs[record->featureType]) nIDs[record->featureType] = record->nIDs; nFeatures[record->featureType]++; offsetAndLineFeaturesTable[record->featureType] = (OffsetAndLine*)CPLRealloc(offsetAndLineFeaturesTable[record->featureType], nFeatures[record->featureType] * sizeof(OffsetAndLine)); offsetAndLineFeaturesTable[record->featureType][nFeatures[record->featureType]-1].offset = offset; offsetAndLineFeaturesTable[record->featureType][nFeatures[record->featureType]-1].line = line; BNA_FreeRecord(record); } nLayers = (nFeatures[0] != 0) + (nFeatures[1] != 0) + (nFeatures[2] != 0) + (nFeatures[3] != 0); papoLayers = (OGRBNALayer **) CPLMalloc(nLayers * sizeof(OGRBNALayer*)); int iLayer = 0; for(i=0;i<4;i++) { if (nFeatures[i]) { papoLayers[iLayer] = new OGRBNALayer( pszFilename, layerRadixName[i], (BNAFeatureType)i, wkbGeomTypes[i], FALSE, this, nIDs[i]); papoLayers[iLayer]->SetFeatureIndexTable(nFeatures[i], offsetAndLineFeaturesTable[i], partialIndexTable); iLayer++; } } #endif VSIFCloseL(fp); } return ok; }
GDALJP2Box *GDALJP2Metadata::CreateGMLJP2( int nXSize, int nYSize ) { /* -------------------------------------------------------------------- */ /* This is a backdoor to let us embed a literal gmljp2 chunk */ /* supplied by the user as an external file. This is mostly */ /* for preparing test files with exotic contents. */ /* -------------------------------------------------------------------- */ if( CPLGetConfigOption( "GMLJP2OVERRIDE", NULL ) != NULL ) { VSILFILE *fp = VSIFOpenL( CPLGetConfigOption( "GMLJP2OVERRIDE",""), "r" ); char *pszGML = NULL; if( fp == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "Unable to open GMLJP2OVERRIDE file." ); return NULL; } VSIFSeekL( fp, 0, SEEK_END ); int nLength = (int) VSIFTellL( fp ); pszGML = (char *) CPLCalloc(1,nLength+1); VSIFSeekL( fp, 0, SEEK_SET ); VSIFReadL( pszGML, 1, nLength, fp ); VSIFCloseL( fp ); GDALJP2Box *apoGMLBoxes[2]; apoGMLBoxes[0] = GDALJP2Box::CreateLblBox( "gml.data" ); apoGMLBoxes[1] = GDALJP2Box::CreateLabelledXMLAssoc( "gml.root-instance", pszGML ); GDALJP2Box *poGMLData = GDALJP2Box::CreateAsocBox( 2, apoGMLBoxes); delete apoGMLBoxes[0]; delete apoGMLBoxes[1]; CPLFree( pszGML ); return poGMLData; } /* -------------------------------------------------------------------- */ /* Try do determine a PCS or GCS code we can use. */ /* -------------------------------------------------------------------- */ OGRSpatialReference oSRS; char *pszWKTCopy = (char *) pszProjection; int nEPSGCode = 0; char szSRSName[100]; int bNeedAxisFlip = FALSE; if( oSRS.importFromWkt( &pszWKTCopy ) != OGRERR_NONE ) return NULL; if( oSRS.IsProjected() ) { const char *pszAuthName = oSRS.GetAuthorityName( "PROJCS" ); if( pszAuthName != NULL && EQUAL(pszAuthName,"epsg") ) { nEPSGCode = atoi(oSRS.GetAuthorityCode( "PROJCS" )); } } else if( oSRS.IsGeographic() ) { const char *pszAuthName = oSRS.GetAuthorityName( "GEOGCS" ); if( pszAuthName != NULL && EQUAL(pszAuthName,"epsg") ) { nEPSGCode = atoi(oSRS.GetAuthorityCode( "GEOGCS" )); bNeedAxisFlip = TRUE; } } if( nEPSGCode != 0 ) sprintf( szSRSName, "urn:ogc:def:crs:EPSG::%d", nEPSGCode ); else strcpy( szSRSName, "gmljp2://xml/CRSDictionary.gml#ogrcrs1" ); /* -------------------------------------------------------------------- */ /* Prepare coverage origin and offset vectors. Take axis */ /* order into account if needed. */ /* -------------------------------------------------------------------- */ double adfOrigin[2]; double adfXVector[2]; double adfYVector[2]; adfOrigin[0] = adfGeoTransform[0] + adfGeoTransform[1] * 0.5 + adfGeoTransform[4] * 0.5; adfOrigin[1] = adfGeoTransform[3] + adfGeoTransform[2] * 0.5 + adfGeoTransform[5] * 0.5; adfXVector[0] = adfGeoTransform[1]; adfXVector[1] = adfGeoTransform[2]; adfYVector[0] = adfGeoTransform[4]; adfYVector[1] = adfGeoTransform[5]; if( bNeedAxisFlip && CSLTestBoolean( CPLGetConfigOption( "GDAL_IGNORE_AXIS_ORIENTATION", "FALSE" ) ) ) { bNeedAxisFlip = FALSE; CPLDebug( "GMLJP2", "Supressed axis flipping on write based on GDAL_IGNORE_AXIS_ORIENTATION." ); } if( bNeedAxisFlip ) { double dfTemp; CPLDebug( "GMLJP2", "Flipping GML coverage axis order." ); dfTemp = adfOrigin[0]; adfOrigin[0] = adfOrigin[1]; adfOrigin[1] = dfTemp; dfTemp = adfXVector[0]; adfXVector[0] = adfXVector[1]; adfXVector[1] = dfTemp; dfTemp = adfYVector[0]; adfYVector[0] = adfYVector[1]; adfYVector[1] = dfTemp; } /* -------------------------------------------------------------------- */ /* For now we hardcode for a minimal instance format. */ /* -------------------------------------------------------------------- */ CPLString osDoc; osDoc.Printf( "<gml:FeatureCollection\n" " xmlns:gml=\"http://www.opengis.net/gml\"\n" " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" " xsi:schemaLocation=\"http://www.opengeospatial.net/gml http://schemas.opengis.net/gml/3.1.1/profiles/gmlJP2Profile/1.0.0/gmlJP2Profile.xsd\">\n" " <gml:boundedBy>\n" " <gml:Null>withheld</gml:Null>\n" " </gml:boundedBy>\n" " <gml:featureMember>\n" " <gml:FeatureCollection>\n" " <gml:featureMember>\n" " <gml:RectifiedGridCoverage dimension=\"2\" gml:id=\"RGC0001\">\n" " <gml:rectifiedGridDomain>\n" " <gml:RectifiedGrid dimension=\"2\">\n" " <gml:limits>\n" " <gml:GridEnvelope>\n" " <gml:low>0 0</gml:low>\n" " <gml:high>%d %d</gml:high>\n" " </gml:GridEnvelope>\n" " </gml:limits>\n" " <gml:axisName>x</gml:axisName>\n" " <gml:axisName>y</gml:axisName>\n" " <gml:origin>\n" " <gml:Point gml:id=\"P0001\" srsName=\"%s\">\n" " <gml:pos>%.15g %.15g</gml:pos>\n" " </gml:Point>\n" " </gml:origin>\n" " <gml:offsetVector srsName=\"%s\">%.15g %.15g</gml:offsetVector>\n" " <gml:offsetVector srsName=\"%s\">%.15g %.15g</gml:offsetVector>\n" " </gml:RectifiedGrid>\n" " </gml:rectifiedGridDomain>\n" " <gml:rangeSet>\n" " <gml:File>\n" " <gml:fileName>gmljp2://codestream/0</gml:fileName>\n" " <gml:fileStructure>Record Interleaved</gml:fileStructure>\n" " </gml:File>\n" " </gml:rangeSet>\n" " </gml:RectifiedGridCoverage>\n" " </gml:featureMember>\n" " </gml:FeatureCollection>\n" " </gml:featureMember>\n" "</gml:FeatureCollection>\n", nXSize-1, nYSize-1, szSRSName, adfOrigin[0], adfOrigin[1], szSRSName, adfXVector[0], adfXVector[1], szSRSName, adfYVector[0], adfYVector[1] ); /* -------------------------------------------------------------------- */ /* If we need a user defined CRSDictionary entry, prepare it */ /* here. */ /* -------------------------------------------------------------------- */ CPLString osDictBox; if( nEPSGCode == 0 ) { char *pszGMLDef = NULL; if( oSRS.exportToXML( &pszGMLDef, NULL ) == OGRERR_NONE ) { osDictBox.Printf( "<gml:Dictionary gml:id=\"CRSU1\" \n" " xmlns:gml=\"http://www.opengis.net/gml\"\n" " xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n" " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n" " <gml:dictionaryEntry>\n" "%s\n" " </gml:dictionaryEntry>\n" "</gml:Dictionary>\n", pszGMLDef ); } CPLFree( pszGMLDef ); } /* -------------------------------------------------------------------- */ /* Setup the gml.data label. */ /* -------------------------------------------------------------------- */ GDALJP2Box *apoGMLBoxes[5]; int nGMLBoxes = 0; apoGMLBoxes[nGMLBoxes++] = GDALJP2Box::CreateLblBox( "gml.data" ); /* -------------------------------------------------------------------- */ /* Setup gml.root-instance. */ /* -------------------------------------------------------------------- */ apoGMLBoxes[nGMLBoxes++] = GDALJP2Box::CreateLabelledXMLAssoc( "gml.root-instance", osDoc ); /* -------------------------------------------------------------------- */ /* Add optional dictionary. */ /* -------------------------------------------------------------------- */ if( strlen(osDictBox) > 0 ) apoGMLBoxes[nGMLBoxes++] = GDALJP2Box::CreateLabelledXMLAssoc( "CRSDictionary.gml", osDictBox ); /* -------------------------------------------------------------------- */ /* Bundle gml.data boxes into an association. */ /* -------------------------------------------------------------------- */ GDALJP2Box *poGMLData = GDALJP2Box::CreateAsocBox( nGMLBoxes, apoGMLBoxes); /* -------------------------------------------------------------------- */ /* Cleanup working boxes. */ /* -------------------------------------------------------------------- */ while( nGMLBoxes > 0 ) delete apoGMLBoxes[--nGMLBoxes]; return poGMLData; }
int VSIIngestFile( VSILFILE* fp, const char* pszFilename, GByte** ppabyRet, vsi_l_offset* pnSize, GIntBig nMaxSize) { vsi_l_offset nDataLen = 0; int bFreeFP = FALSE; if( fp == NULL && pszFilename == NULL ) return FALSE; if( ppabyRet == NULL ) return FALSE; *ppabyRet = NULL; if( pnSize != NULL ) *pnSize = 0; if( NULL == fp ) { fp = VSIFOpenL( pszFilename, "rb" ); if( NULL == fp ) { CPLError( CE_Failure, CPLE_FileIO, "Cannot open file '%s'", pszFilename ); return FALSE; } bFreeFP = TRUE; } else VSIFSeekL(fp, 0, SEEK_SET); if( pszFilename == NULL || strcmp(pszFilename, "/vsistdin/") == 0 ) { vsi_l_offset nDataAlloc = 0; VSIFSeekL( fp, 0, SEEK_SET ); while(TRUE) { if( nDataLen + 8192 + 1 > nDataAlloc ) { nDataAlloc = (nDataAlloc * 4) / 3 + 8192 + 1; if( nDataAlloc > (vsi_l_offset)(size_t)nDataAlloc ) { CPLError( CE_Failure, CPLE_AppDefined, "Input file too large to be opened" ); VSIFree( *ppabyRet ); *ppabyRet = NULL; if( bFreeFP ) VSIFCloseL( fp ); return FALSE; } GByte* pabyNew = (GByte*)VSIRealloc(*ppabyRet, (size_t)nDataAlloc); if( pabyNew == NULL ) { CPLError( CE_Failure, CPLE_OutOfMemory, "Cannot allocated " CPL_FRMT_GIB " bytes", nDataAlloc ); VSIFree( *ppabyRet ); *ppabyRet = NULL; if( bFreeFP ) VSIFCloseL( fp ); return FALSE; } *ppabyRet = pabyNew; } int nRead = (int)VSIFReadL( *ppabyRet + nDataLen, 1, 8192, fp ); nDataLen += nRead; if ( nMaxSize >= 0 && nDataLen > (vsi_l_offset)nMaxSize ) { CPLError( CE_Failure, CPLE_AppDefined, "Input file too large to be opened" ); VSIFree( *ppabyRet ); *ppabyRet = NULL; if( pnSize != NULL ) *pnSize = 0; if( bFreeFP ) VSIFCloseL( fp ); return FALSE; } if( pnSize != NULL ) *pnSize += nRead; (*ppabyRet)[nDataLen] = '\0'; if( nRead == 0 ) break; } } else { VSIFSeekL( fp, 0, SEEK_END ); nDataLen = VSIFTellL( fp ); // With "large" VSI I/O API we can read data chunks larger than VSIMalloc // could allocate. Catch it here. if ( nDataLen > (vsi_l_offset)(size_t)nDataLen || (nMaxSize >= 0 && nDataLen > (vsi_l_offset)nMaxSize) ) { CPLError( CE_Failure, CPLE_AppDefined, "Input file too large to be opened" ); if( bFreeFP ) VSIFCloseL( fp ); return FALSE; } VSIFSeekL( fp, 0, SEEK_SET ); *ppabyRet = (GByte*)VSIMalloc((size_t)(nDataLen + 1)); if( NULL == *ppabyRet ) { CPLError( CE_Failure, CPLE_OutOfMemory, "Cannot allocated " CPL_FRMT_GIB " bytes", nDataLen + 1 ); if( bFreeFP ) VSIFCloseL( fp ); return FALSE; } (*ppabyRet)[nDataLen] = '\0'; if( ( nDataLen != VSIFReadL( *ppabyRet, 1, (size_t)nDataLen, fp ) ) ) { CPLError( CE_Failure, CPLE_FileIO, "Cannot read " CPL_FRMT_GIB " bytes", nDataLen ); VSIFree( *ppabyRet ); *ppabyRet = NULL; if( bFreeFP ) VSIFCloseL( fp ); return FALSE; } if( pnSize != NULL ) *pnSize = nDataLen; } if( bFreeFP ) VSIFCloseL( fp ); return TRUE; }
static vsi_l_offset USGSDEMGetCurrentFilePos( const Buffer* psBuffer ) { return VSIFTellL(psBuffer->fp) - psBuffer->buffer_size + psBuffer->cur_index; }
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 ); }
int USGSDEMDataset::LoadFromFile(VSILFILE *InDem) { // check for version of DEM format CPL_IGNORE_RET_VAL(VSIFSeekL(InDem, 864, 0)); // Read DEM into matrix const int nRow = ReadInt(InDem); const int nColumn = ReadInt(InDem); const bool bNewFormat = VSIFTellL(InDem) >= 1024 || nRow != 1 || nColumn != 1; if (bNewFormat) { CPL_IGNORE_RET_VAL(VSIFSeekL(InDem, 1024, 0)); // New Format int i = ReadInt(InDem); int j = ReadInt(InDem); if ( i != 1 || ( j != 1 && j != 0 ) ) // File OK? { CPL_IGNORE_RET_VAL(VSIFSeekL(InDem, 893, 0)); // Undocumented Format (39109h1.dem) i = ReadInt(InDem); j = ReadInt(InDem); if ( i != 1 || j != 1 ) // File OK? { CPLError( CE_Failure, CPLE_AppDefined, "Does not appear to be a USGS DEM file." ); return FALSE; } else nDataStartOffset = 893; } else nDataStartOffset = 1024; } else nDataStartOffset = 864; CPL_IGNORE_RET_VAL(VSIFSeekL(InDem, 156, 0)); const int nCoordSystem = ReadInt(InDem); const int iUTMZone = ReadInt(InDem); CPL_IGNORE_RET_VAL(VSIFSeekL(InDem, 528, 0)); const int nGUnit = ReadInt(InDem); const int nVUnit = ReadInt(InDem); // Vertical Units in meters if (nVUnit==1) pszUnits = "ft"; else pszUnits = "m"; CPL_IGNORE_RET_VAL(VSIFSeekL(InDem, 816, 0)); const double dxdelta = DConvert(InDem, 12); const double dydelta = DConvert(InDem, 12); if( dydelta == 0 ) return FALSE; fVRes = DConvert(InDem, 12); /* -------------------------------------------------------------------- */ /* Should we treat this as floating point, or GInt16. */ /* -------------------------------------------------------------------- */ if (nVUnit==1 || fVRes < 1.0) eNaturalDataFormat = GDT_Float32; else eNaturalDataFormat = GDT_Int16; /* -------------------------------------------------------------------- */ /* Read four corner coordinates. */ /* -------------------------------------------------------------------- */ CPL_IGNORE_RET_VAL(VSIFSeekL(InDem, 546, 0)); DPoint2 corners[4]; // SW, NW, NE, SE for (int i = 0; i < 4; i++) { corners[i].x = DConvert(InDem, 24); corners[i].y = DConvert(InDem, 24); } // find absolute extents of raw vales DPoint2 extent_min, extent_max; extent_min.x = std::min(corners[0].x, corners[1].x); extent_max.x = std::max(corners[2].x, corners[3].x); extent_min.y = std::min(corners[0].y, corners[3].y); extent_max.y = std::max(corners[1].y, corners[2].y); /* dElevMin = */ DConvert(InDem, 48); /* dElevMax = */ DConvert(InDem, 48); CPL_IGNORE_RET_VAL(VSIFSeekL(InDem, 858, 0)); const int nProfiles = ReadInt(InDem); /* -------------------------------------------------------------------- */ /* Collect the spatial reference system. */ /* -------------------------------------------------------------------- */ OGRSpatialReference sr; bool bNAD83 = true; // OLD format header ends at byte 864 if (bNewFormat) { // year of data compilation CPL_IGNORE_RET_VAL(VSIFSeekL(InDem, 876, 0)); char szDateBuffer[5]; CPL_IGNORE_RET_VAL(VSIFReadL(szDateBuffer, 4, 1, InDem)); /* szDateBuffer[4] = 0; */ // Horizontal datum // 1=North American Datum 1927 (NAD 27) // 2=World Geodetic System 1972 (WGS 72) // 3=WGS 84 // 4=NAD 83 // 5=Old Hawaii Datum // 6=Puerto Rico Datum CPL_IGNORE_RET_VAL(VSIFSeekL(InDem, 890, 0)); char szHorzDatum[3]; CPL_IGNORE_RET_VAL(VSIFReadL( szHorzDatum, 1, 2, InDem )); szHorzDatum[2] = '\0'; const int datum = atoi(szHorzDatum); switch (datum) { case 1: sr.SetWellKnownGeogCS( "NAD27" ); bNAD83 = false; break; case 2: sr.SetWellKnownGeogCS( "WGS72" ); break; case 3: sr.SetWellKnownGeogCS( "WGS84" ); break; case 4: sr.SetWellKnownGeogCS( "NAD83" ); break; case -9: break; default: sr.SetWellKnownGeogCS( "NAD27" ); break; } } else { sr.SetWellKnownGeogCS( "NAD27" ); bNAD83 = false; } if (nCoordSystem == 1) // UTM { if( iUTMZone >= -60 && iUTMZone <= 60 ) { sr.SetUTM( abs(iUTMZone), iUTMZone >= 0 ); if( nGUnit == 1 ) { sr.SetLinearUnitsAndUpdateParameters( SRS_UL_US_FOOT, CPLAtof(SRS_UL_US_FOOT_CONV) ); char szUTMName[128]; snprintf( szUTMName, sizeof(szUTMName), "UTM Zone %d, Northern Hemisphere, us-ft", iUTMZone ); sr.SetNode( "PROJCS", szUTMName ); } } } else if (nCoordSystem == 2) // state plane { if( nGUnit == 1 ) sr.SetStatePlane( iUTMZone, bNAD83, "Foot", CPLAtof(SRS_UL_US_FOOT_CONV) ); else sr.SetStatePlane( iUTMZone, bNAD83 ); } sr.exportToWkt( &pszProjection ); /* -------------------------------------------------------------------- */ /* For UTM we use the extents (really the UTM coordinates of */ /* the lat/long corners of the quad) to determine the size in */ /* pixels and lines, but we have to make the anchors be modulus */ /* the pixel size which what really gets used. */ /* -------------------------------------------------------------------- */ if (nCoordSystem == 1 // UTM || nCoordSystem == 2 // State Plane || nCoordSystem == -9999 ) // unknown { // expand extents modulus the pixel size. extent_min.y = floor(extent_min.y/dydelta) * dydelta; extent_max.y = ceil(extent_max.y/dydelta) * dydelta; // Forcibly compute X extents based on first profile and pixelsize. CPL_IGNORE_RET_VAL(VSIFSeekL(InDem, nDataStartOffset, 0)); /* njunk = */ ReadInt(InDem); /* njunk = */ ReadInt(InDem); /* njunk = */ ReadInt(InDem); /* njunk = */ ReadInt(InDem); const double dxStart = DConvert(InDem, 24); nRasterYSize = static_cast<int>( ( extent_max.y - extent_min.y ) / dydelta + 1.5 ); nRasterXSize = nProfiles; adfGeoTransform[0] = dxStart - dxdelta/2.0; adfGeoTransform[1] = dxdelta; adfGeoTransform[2] = 0.0; adfGeoTransform[3] = extent_max.y + dydelta/2.0; adfGeoTransform[4] = 0.0; adfGeoTransform[5] = -dydelta; } /* -------------------------------------------------------------------- */ /* Geographic -- use corners directly. */ /* -------------------------------------------------------------------- */ else { nRasterYSize = static_cast<int>( ( extent_max.y - extent_min.y ) / dydelta + 1.5 ); nRasterXSize = nProfiles; // Translate extents from arc-seconds to decimal degrees. adfGeoTransform[0] = (extent_min.x - dxdelta/2.0) / 3600.0; adfGeoTransform[1] = dxdelta / 3600.0; adfGeoTransform[2] = 0.0; adfGeoTransform[3] = (extent_max.y + dydelta/2.0) / 3600.0; adfGeoTransform[4] = 0.0; adfGeoTransform[5] = (-dydelta) / 3600.0; } if (!GDALCheckDatasetDimensions(nRasterXSize, nRasterYSize)) { return FALSE; } return TRUE; }
int NITFDESGetTRE( NITFDES* psDES, int nOffset, char szTREName[7], char** ppabyTREData, int* pnFoundTRESize) { char szTREHeader[12]; char szTRETempName[7]; NITFSegmentInfo* psSegInfo; VSILFILE* fp; int nTRESize; memset(szTREName, '\0', 7); if (ppabyTREData) *ppabyTREData = NULL; if (pnFoundTRESize) *pnFoundTRESize = 0; if (nOffset < 0) return FALSE; if (psDES == NULL) return FALSE; if (CSLFetchNameValue(psDES->papszMetadata, "NITF_DESOFLW") == NULL) return FALSE; psSegInfo = psDES->psFile->pasSegmentInfo + psDES->iSegment; fp = psDES->psFile->fp; if (nOffset >= psSegInfo->nSegmentSize) return FALSE; VSIFSeekL(fp, psSegInfo->nSegmentStart + nOffset, SEEK_SET); if (VSIFReadL(szTREHeader, 1, 11, fp) != 11) { /* Some files have a nSegmentSize larger than what is is in reality */ /* So exit silently if we're at end of file */ VSIFSeekL(fp, 0, SEEK_END); if (VSIFTellL(fp) == psSegInfo->nSegmentStart + nOffset) return FALSE; CPLError(CE_Failure, CPLE_FileIO, "Cannot get 11 bytes at offset " CPL_FRMT_GUIB ".", psSegInfo->nSegmentStart + nOffset ); return FALSE; } szTREHeader[11] = '\0'; memcpy(szTRETempName, szTREHeader, 6); szTRETempName[6] = '\0'; nTRESize = atoi(szTREHeader + 6); if (nTRESize < 0) { CPLError(CE_Failure, CPLE_AppDefined, "Invalid size (%d) for TRE %s", nTRESize, szTRETempName); return FALSE; } if (nOffset + 11 + nTRESize > psSegInfo->nSegmentSize) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot read %s TRE. Not enough bytes : remaining %d, expected %d", szTRETempName, (int)(psSegInfo->nSegmentSize - (nOffset + 11)), nTRESize); return FALSE; } if (ppabyTREData) { /* Allocate one extra byte for the NULL terminating character */ *ppabyTREData = (char*) VSIMalloc(nTRESize + 1); if (*ppabyTREData == NULL) { CPLError(CE_Failure, CPLE_OutOfMemory, "Cannot allocate %d bytes for TRE %s", nTRESize, szTRETempName); return FALSE; } (*ppabyTREData)[nTRESize] = '\0'; if ((int)VSIFReadL(*ppabyTREData, 1, nTRESize, fp) != nTRESize) { CPLError(CE_Failure, CPLE_FileIO, "Cannot get %d bytes at offset " CPL_FRMT_GUIB ".", nTRESize, VSIFTellL(fp) ); VSIFree(*ppabyTREData); *ppabyTREData = NULL; return FALSE; } } strcpy(szTREName, szTRETempName); if (pnFoundTRESize) *pnFoundTRESize = nTRESize; return TRUE; }
vsi_l_offset VSISubFileHandle::Tell() { return VSIFTellL( fp ) - nSubregionOffset; }
GDALDataset *GS7BGDataset::Open( GDALOpenInfo * poOpenInfo ) { if( !Identify(poOpenInfo) ) { return NULL; } /* ------------------------------------------------------------------- */ /* Create a corresponding GDALDataset. */ /* ------------------------------------------------------------------- */ GS7BGDataset *poDS = new GS7BGDataset(); /* ------------------------------------------------------------------- */ /* Open file with large file API. */ /* ------------------------------------------------------------------- */ poDS->eAccess = poOpenInfo->eAccess; if( poOpenInfo->eAccess == GA_ReadOnly ) poDS->fp = VSIFOpenL( poOpenInfo->pszFilename, "rb" ); else poDS->fp = VSIFOpenL( poOpenInfo->pszFilename, "r+b" ); if( poDS->fp == NULL ) { delete poDS; CPLError( CE_Failure, CPLE_OpenFailed, "VSIFOpenL(%s) failed unexpectedly.", poOpenInfo->pszFilename ); return NULL; } /* ------------------------------------------------------------------- */ /* Read the header. The Header section must be the first section */ /* in the file. */ /* ------------------------------------------------------------------- */ if( VSIFSeekL( poDS->fp, 0, SEEK_SET ) != 0 ) { delete poDS; CPLError( CE_Failure, CPLE_FileIO, "Unable to seek to start of grid file header.\n" ); return NULL; } GInt32 nTag; if( VSIFReadL( (void *)&nTag, sizeof(GInt32), 1, poDS->fp ) != 1 ) { delete poDS; CPLError( CE_Failure, CPLE_FileIO, "Unable to read Tag.\n" ); return NULL; } CPL_LSBPTR32( &nTag ); if(nTag != nHEADER_TAG) { delete poDS; CPLError( CE_Failure, CPLE_FileIO, "Header tag not found.\n" ); return NULL; } GUInt32 nSize; if( VSIFReadL( (void *)&nSize, sizeof(GUInt32), 1, poDS->fp ) != 1 ) { delete poDS; CPLError( CE_Failure, CPLE_FileIO, "Unable to read file section size.\n" ); return NULL; } CPL_LSBPTR32( &nSize ); GInt32 nVersion; if( VSIFReadL( (void *)&nVersion, sizeof(GInt32), 1, poDS->fp ) != 1 ) { delete poDS; CPLError( CE_Failure, CPLE_FileIO, "Unable to read file version.\n" ); return NULL; } CPL_LSBPTR32( &nVersion ); if(nVersion != 1 && nVersion != 2) { delete poDS; CPLError( CE_Failure, CPLE_FileIO, "Incorrect file version (%d).", nVersion ); return NULL; } // advance until the grid tag is found while(nTag != nGRID_TAG) { if( VSIFReadL( (void *)&nTag, sizeof(GInt32), 1, poDS->fp ) != 1 ) { delete poDS; CPLError( CE_Failure, CPLE_FileIO, "Unable to read Tag.\n" ); return NULL; } CPL_LSBPTR32( &nTag ); if( VSIFReadL( (void *)&nSize, sizeof(GUInt32), 1, poDS->fp ) != 1 ) { delete poDS; CPLError( CE_Failure, CPLE_FileIO, "Unable to read file section size.\n" ); return NULL; } CPL_LSBPTR32( &nSize ); if(nTag != nGRID_TAG) { if( VSIFSeekL( poDS->fp, nSize, SEEK_CUR ) != 0 ) { delete poDS; CPLError( CE_Failure, CPLE_FileIO, "Unable to seek to end of file section.\n" ); return NULL; } } } /* --------------------------------------------------------------------*/ /* Read the grid. */ /* --------------------------------------------------------------------*/ /* Parse number of Y axis grid rows */ GInt32 nRows; if( VSIFReadL( (void *)&nRows, sizeof(GInt32), 1, poDS->fp ) != 1 ) { delete poDS; CPLError( CE_Failure, CPLE_FileIO, "Unable to read raster Y size.\n" ); return NULL; } CPL_LSBPTR32( &nRows ); poDS->nRasterYSize = nRows; /* Parse number of X axis grid columns */ GInt32 nCols; if( VSIFReadL( (void *)&nCols, sizeof(GInt32), 1, poDS->fp ) != 1 ) { delete poDS; CPLError( CE_Failure, CPLE_FileIO, "Unable to read raster X size.\n" ); return NULL; } CPL_LSBPTR32( &nCols ); poDS->nRasterXSize = nCols; if (!GDALCheckDatasetDimensions(poDS->nRasterXSize, poDS->nRasterYSize)) { delete poDS; return NULL; } /* --------------------------------------------------------------------*/ /* Create band information objects. */ /* --------------------------------------------------------------------*/ GS7BGRasterBand *poBand = new GS7BGRasterBand( poDS, 1 ); poDS->SetBand( 1, poBand ); // find the min X Value of the grid double dfTemp; if( VSIFReadL( (void *)&dfTemp, sizeof(double), 1, poDS->fp ) != 1 ) { delete poDS; CPLError( CE_Failure, CPLE_FileIO, "Unable to read minimum X value.\n" ); return NULL; } CPL_LSBPTR64( &dfTemp ); poBand->dfMinX = dfTemp; // find the min Y value of the grid if( VSIFReadL( (void *)&dfTemp, sizeof(double), 1, poDS->fp ) != 1 ) { delete poDS; CPLError( CE_Failure, CPLE_FileIO, "Unable to read minimum X value.\n" ); return NULL; } CPL_LSBPTR64( &dfTemp ); poBand->dfMinY = dfTemp; // find the spacing between adjacent nodes in the X direction // (between columns) if( VSIFReadL( (void *)&dfTemp, sizeof(double), 1, poDS->fp ) != 1 ) { delete poDS; CPLError( CE_Failure, CPLE_FileIO, "Unable to read spacing in X value.\n" ); return NULL; } CPL_LSBPTR64( &dfTemp ); poBand->dfMaxX = poBand->dfMinX + (dfTemp * (nCols - 1)); // find the spacing between adjacent nodes in the Y direction // (between rows) if( VSIFReadL( (void *)&dfTemp, sizeof(double), 1, poDS->fp ) != 1 ) { delete poDS; CPLError( CE_Failure, CPLE_FileIO, "Unable to read spacing in Y value.\n" ); return NULL; } CPL_LSBPTR64( &dfTemp ); poBand->dfMaxY = poBand->dfMinY + (dfTemp * (nRows - 1)); // set the z min if( VSIFReadL( (void *)&dfTemp, sizeof(double), 1, poDS->fp ) != 1 ) { delete poDS; CPLError( CE_Failure, CPLE_FileIO, "Unable to read Z min value.\n" ); return NULL; } CPL_LSBPTR64( &dfTemp ); poBand->dfMinZ = dfTemp; // set the z max if( VSIFReadL( (void *)&dfTemp, sizeof(double), 1, poDS->fp ) != 1 ) { delete poDS; CPLError( CE_Failure, CPLE_FileIO, "Unable to read Z max value.\n" ); return NULL; } CPL_LSBPTR64( &dfTemp ); poBand->dfMaxZ = dfTemp; // read and ignore the rotation value //(This is not used in the current version). if( VSIFReadL( (void *)&dfTemp, sizeof(double), 1, poDS->fp ) != 1 ) { delete poDS; CPLError( CE_Failure, CPLE_FileIO, "Unable to read rotation value.\n" ); return NULL; } // read and set the cell blank value if( VSIFReadL( (void *)&dfTemp, sizeof(double), 1, poDS->fp ) != 1 ) { delete poDS; CPLError( CE_Failure, CPLE_FileIO, "Unable to Blank value.\n" ); return NULL; } CPL_LSBPTR64( &dfTemp ); poDS->dfNoData_Value = dfTemp; /* --------------------------------------------------------------------*/ /* Set the current offset of the grid data. */ /* --------------------------------------------------------------------*/ if( VSIFReadL( (void *)&nTag, sizeof(GInt32), 1, poDS->fp ) != 1 ) { delete poDS; CPLError( CE_Failure, CPLE_FileIO, "Unable to read Tag.\n" ); return NULL; } CPL_LSBPTR32( &nTag ); if(nTag != nDATA_TAG) { delete poDS; CPLError( CE_Failure, CPLE_FileIO, "Data tag not found.\n" ); return NULL; } if( VSIFReadL( (void *)&nSize, sizeof(GInt32), 1, poDS->fp ) != 1 ) { delete poDS; CPLError( CE_Failure, CPLE_FileIO, "Unable to data section size.\n" ); return NULL; } poDS->nData_Position = (size_t) VSIFTellL(poDS->fp); /* --------------------------------------------------------------------*/ /* 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 TerragenDataset::LoadFromFile() { GUInt16 nSize, xpts=0, ypts=0; m_dSCAL = 30.0; m_nDataOffset = 0; if(0 != VSIFSeekL(m_fp, 16, SEEK_SET)) return 0; char szTag[4]; if(!this->read_next_tag(szTag) || !tag_is(szTag, "SIZE")) return 0; if(!this->get(nSize) || !this->skip(2)) return 0; // Set dimensions to SIZE chunk. If we don't // encounter XPTS/YPTS chunks, we can assume // the terrain to be square. xpts = ypts = nSize+1; while(this->read_next_tag(szTag)) { if(this->tag_is(szTag, "XPTS")) { this->get(xpts); if(xpts < nSize || !this->skip(2)) return 0; continue; } if(this->tag_is(szTag, "YPTS")) { this->get(ypts); if(ypts < nSize || !this->skip(2)) return 0; continue; } if(this->tag_is(szTag, "SCAL")) { float sc[3]; this->get(sc[0]); this->get(sc[1]); this->get(sc[2]); m_dSCAL = sc[1]; continue; } if(this->tag_is(szTag, "CRAD")) { if(!this->skip(sizeof(float))) return 0; continue; } if(this->tag_is(szTag, "CRVM")) { if(!this->skip(sizeof(GUInt32))) return 0; continue; } if(this->tag_is(szTag, "ALTW")) { this->get(m_nHeightScale); this->get(m_nBaseHeight); m_nDataOffset = VSIFTellL(m_fp); if(!this->skip(xpts * ypts * sizeof(GInt16))) return 0; continue; } if(this->tag_is(szTag, "EOF ")) { break; } } if(xpts == 0 || ypts == 0 || m_nDataOffset == 0) return 0; nRasterXSize = xpts; nRasterYSize = ypts; // todo: sanity check: do we have enough pixels? // Cache realworld scaling and offset. m_dScale = m_dSCAL / 65536 * m_nHeightScale; m_dOffset = m_dSCAL * m_nBaseHeight; strcpy(m_szUnits, "m"); // Make our projection to have origin at the // NW corner, and groundscale to match elev scale // (i.e., uniform voxels). m_adfTransform[0] = 0.0; m_adfTransform[1] = m_dSCAL; m_adfTransform[2] = 0.0; m_adfTransform[3] = 0.0; m_adfTransform[4] = 0.0; m_adfTransform[5] = m_dSCAL; /* -------------------------------------------------------------------- */ /* Set projection. */ /* -------------------------------------------------------------------- */ // Terragen files as of Apr 2006 are partially georeferenced, // we can declare a local coordsys that uses meters. OGRSpatialReference sr; sr.SetLocalCS("Terragen world space"); if(OGRERR_NONE != sr.SetLinearUnits("m", 1.0)) return 0; if(OGRERR_NONE != sr.exportToWkt(&m_pszProjection)) return 0; return TRUE; }
int OGRGPXDataSource::Create( const char *pszFilename, char **papszOptions ) { if( fpOutput != NULL) { CPLAssert( FALSE ); return FALSE; } if (strcmp(pszFilename, "/dev/stdout") == 0) pszFilename = "/vsistdout/"; /* -------------------------------------------------------------------- */ /* Do not override exiting file. */ /* -------------------------------------------------------------------- */ VSIStatBufL sStatBuf; if( VSIStatL( pszFilename, &sStatBuf ) == 0 ) { CPLError(CE_Failure, CPLE_NotSupported, "You have to delete %s before being able to create it with the GPX driver", pszFilename); return FALSE; } /* -------------------------------------------------------------------- */ /* Create the output file. */ /* -------------------------------------------------------------------- */ pszName = CPLStrdup( pszFilename ); if( strcmp(pszName, "/vsistdout/") == 0 ) { bIsBackSeekable = FALSE; fpOutput = VSIFOpenL( pszFilename, "w" ); } else fpOutput = VSIFOpenL( pszFilename, "w+" ); if( fpOutput == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "Failed to create GPX file %s.", pszFilename ); return FALSE; } /* -------------------------------------------------------------------- */ /* End of line character. */ /* -------------------------------------------------------------------- */ const char *pszCRLFFormat = CSLFetchNameValue( papszOptions, "LINEFORMAT"); int bUseCRLF; if( pszCRLFFormat == NULL ) { #ifdef WIN32 bUseCRLF = TRUE; #else bUseCRLF = FALSE; #endif } else if( EQUAL(pszCRLFFormat,"CRLF") ) bUseCRLF = TRUE; else if( EQUAL(pszCRLFFormat,"LF") ) bUseCRLF = FALSE; else { CPLError( CE_Warning, CPLE_AppDefined, "LINEFORMAT=%s not understood, use one of CRLF or LF.", pszCRLFFormat ); #ifdef WIN32 bUseCRLF = TRUE; #else bUseCRLF = FALSE; #endif } pszEOL = (bUseCRLF) ? "\r\n" : "\n"; /* -------------------------------------------------------------------- */ /* Look at use extensions options. */ /* -------------------------------------------------------------------- */ const char* pszUseExtensions = CSLFetchNameValue( papszOptions, "GPX_USE_EXTENSIONS"); const char* pszExtensionsNSURL = NULL; if (pszUseExtensions && CSLTestBoolean(pszUseExtensions)) { bUseExtensions = TRUE; const char* pszExtensionsNSOption = CSLFetchNameValue( papszOptions, "GPX_EXTENSIONS_NS"); const char* pszExtensionsNSURLOption = CSLFetchNameValue( papszOptions, "GPX_EXTENSIONS_NS_URL"); if (pszExtensionsNSOption && pszExtensionsNSURLOption) { pszExtensionsNS = CPLStrdup(pszExtensionsNSOption); pszExtensionsNSURL = pszExtensionsNSURLOption; } else { pszExtensionsNS = CPLStrdup("ogr"); pszExtensionsNSURL = "http://osgeo.org/gdal"; } } /* -------------------------------------------------------------------- */ /* Output header of GPX file. */ /* -------------------------------------------------------------------- */ PrintLine("<?xml version=\"1.0\"?>"); VSIFPrintfL(fpOutput, "<gpx version=\"1.1\" creator=\"GDAL " GDAL_RELEASE_NAME "\" "); VSIFPrintfL(fpOutput, "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" "); if (bUseExtensions) VSIFPrintfL(fpOutput, "xmlns:%s=\"%s\" ", pszExtensionsNS, pszExtensionsNSURL); VSIFPrintfL(fpOutput, "xmlns=\"http://www.topografix.com/GPX/1/1\" "); PrintLine("xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd\">"); if (bIsBackSeekable) { /* Reserve space for <metadata><bounds/></metadata> */ char szMetadata[SPACE_FOR_METADATA+1]; memset(szMetadata, ' ', SPACE_FOR_METADATA); szMetadata[SPACE_FOR_METADATA] = '\0'; nOffsetBounds = (int) VSIFTellL(fpOutput); PrintLine("%s", szMetadata); } return TRUE; }
void GRIBRasterBand::FindPDSTemplate() { GRIBDataset *poGDS = (GRIBDataset *) poDS; /* -------------------------------------------------------------------- */ /* Collect section 4 octet information ... we read the file */ /* ourselves since the GRIB API does not appear to preserve all */ /* this for us. */ /* -------------------------------------------------------------------- */ GIntBig nOffset = VSIFTellL( poGDS->fp ); GByte abyHead[5]; GUInt32 nSectSize; VSIFSeekL( poGDS->fp, start+16, SEEK_SET ); VSIFReadL( abyHead, 5, 1, poGDS->fp ); while( abyHead[4] != 4 ) { memcpy( &nSectSize, abyHead, 4 ); CPL_MSBPTR32( &nSectSize ); if( VSIFSeekL( poGDS->fp, nSectSize-5, SEEK_CUR ) != 0 || VSIFReadL( abyHead, 5, 1, poGDS->fp ) != 1 ) break; } if( abyHead[4] == 4 ) { GUInt16 nCoordCount; GUInt16 nPDTN; CPLString osOctet; int i; GByte *pabyBody; memcpy( &nSectSize, abyHead, 4 ); CPL_MSBPTR32( &nSectSize ); pabyBody = (GByte *) CPLMalloc(nSectSize-5); VSIFReadL( pabyBody, 1, nSectSize-5, poGDS->fp ); memcpy( &nCoordCount, pabyBody + 5 - 5, 2 ); CPL_MSBPTR16( &nCoordCount ); memcpy( &nPDTN, pabyBody + 7 - 5, 2 ); CPL_MSBPTR16( &nPDTN ); SetMetadataItem( "GRIB_PDS_PDTN", CPLString().Printf( "%d", nPDTN ) ); for( i = 9; i < (int) nSectSize; i++ ) { char szByte[10]; if( i == 9 ) sprintf( szByte, "%d", pabyBody[i-5] ); else sprintf( szByte, " %d", pabyBody[i-5] ); osOctet += szByte; } SetMetadataItem( "GRIB_PDS_TEMPLATE_NUMBERS", osOctet ); CPLFree( pabyBody ); } VSIFSeekL( poGDS->fp, nOffset, SEEK_SET ); }
const char* E00GRIDDataset::ReadNextLine(void * ptr) { E00GRIDDataset* poDS = (E00GRIDDataset*) ptr; poDS->nPosBeforeReadLine = VSIFTellL(poDS->fp); return CPLReadLine2L(poDS->fp, 256, NULL); }
NITFLocation* NITFReadRPFLocationTable(VSILFILE* fp, int* pnLocCount) { GUInt16 nLocSectionLength; GUInt32 nLocSectionOffset; GUInt16 iLoc; GUInt16 nLocCount; GUInt16 nLocRecordLength; GUInt32 nLocComponentAggregateLength; NITFLocation* pasLocations = NULL; int bSuccess; GUIntBig nCurOffset; if (fp == NULL || pnLocCount == NULL) return NULL; *pnLocCount = 0; nCurOffset = VSIFTellL(fp); bSuccess = TRUE; nLocSectionLength = NITFReadMSBGUInt16(fp, &bSuccess); nLocSectionOffset = NITFReadMSBGUInt32(fp, &bSuccess); if (nLocSectionOffset != 14) { CPLDebug("NITF", "Unusual location section offset : %d", nLocSectionOffset); } nLocCount = NITFReadMSBGUInt16(fp, &bSuccess); if (!bSuccess || nLocCount == 0) { return NULL; } nLocRecordLength = NITFReadMSBGUInt16(fp, &bSuccess); if (nLocRecordLength != 10) { CPLError(CE_Failure, CPLE_AppDefined, "Did not get expected record length : %d", nLocRecordLength); return NULL; } nLocComponentAggregateLength = NITFReadMSBGUInt32(fp, &bSuccess); VSIFSeekL(fp, nCurOffset + nLocSectionOffset, SEEK_SET); pasLocations = (NITFLocation *) VSI_CALLOC_VERBOSE(sizeof(NITFLocation), nLocCount); if (pasLocations == NULL) { return NULL; } /* -------------------------------------------------------------------- */ /* Process the locations. */ /* -------------------------------------------------------------------- */ for( iLoc = 0; iLoc < nLocCount; iLoc++ ) { pasLocations[iLoc].nLocId = NITFReadMSBGUInt16(fp, &bSuccess); pasLocations[iLoc].nLocSize = NITFReadMSBGUInt32(fp, &bSuccess); pasLocations[iLoc].nLocOffset = NITFReadMSBGUInt32(fp, &bSuccess); } if (!bSuccess) { CPLFree(pasLocations); return NULL; } *pnLocCount = nLocCount; return pasLocations; }
void E00GRIDDataset::ReadMetadata() { if (bHasReadMetadata) return; bHasReadMetadata = TRUE; if (e00ReadPtr == NULL) { const int nRoundedBlockXSize = ((nRasterXSize + VALS_PER_LINE - 1) / VALS_PER_LINE) * VALS_PER_LINE; const vsi_l_offset nValsToSkip = (vsi_l_offset)nRasterYSize * nRoundedBlockXSize; const vsi_l_offset nLinesToSkip = nValsToSkip / VALS_PER_LINE; const int nBytesPerLine = VALS_PER_LINE * E00_FLOAT_SIZE + nBytesEOL; const vsi_l_offset nPos = nDataStart + nLinesToSkip * nBytesPerLine; VSIFSeekL(fp, nPos, SEEK_SET); } else { nLastYOff = -1; const unsigned int BUFFER_SIZE = 65536; const unsigned int NEEDLE_SIZE = 3*5; const unsigned int nToRead = BUFFER_SIZE - NEEDLE_SIZE; char* pabyBuffer = (char*)CPLCalloc(1, BUFFER_SIZE+NEEDLE_SIZE); int nRead; int bEOGFound = FALSE; VSIFSeekL(fp, 0, SEEK_END); vsi_l_offset nEndPos = VSIFTellL(fp); if (nEndPos > BUFFER_SIZE) nEndPos -= BUFFER_SIZE; else nEndPos = 0; VSIFSeekL(fp, nEndPos, SEEK_SET); #define GOTO_NEXT_CHAR() \ i ++; \ if (pabyBuffer[i] == 13 || pabyBuffer[i] == 10) \ { \ i++; \ if (pabyBuffer[i] == 10) \ i++; \ } \ while ((nRead = static_cast<int>(VSIFReadL(pabyBuffer, 1, nToRead, fp))) != 0) { int i; for(i = 0; i < nRead; i++) { if (pabyBuffer[i] == 'E') { GOTO_NEXT_CHAR(); if (pabyBuffer[i] == 'O') { GOTO_NEXT_CHAR(); if (pabyBuffer[i] == 'G') { GOTO_NEXT_CHAR(); if (pabyBuffer[i] == '~') { GOTO_NEXT_CHAR(); if (pabyBuffer[i] == '}') { bEOGFound = TRUE; break; } } } } } } if (bEOGFound) { VSIFSeekL(fp, VSIFTellL(fp) - nRead + i + 1, SEEK_SET); e00ReadPtr->iInBufPtr = 0; e00ReadPtr->szInBuf[0] = '\0'; break; } if (nEndPos == 0) break; if ((unsigned int)nRead == nToRead) { memmove(pabyBuffer + nToRead, pabyBuffer, NEEDLE_SIZE); if (nEndPos >= (vsi_l_offset)nToRead) nEndPos -= nToRead; else nEndPos = 0; VSIFSeekL(fp, nEndPos, SEEK_SET); } else break; } CPLFree(pabyBuffer); if (!bEOGFound) return; } const char* pszLine = NULL; bool bPRJFound = false; bool bStatsFound = false; while((pszLine = ReadLine()) != NULL) { if (STARTS_WITH_CI(pszLine, "PRJ 2")) { bPRJFound = true; while((pszLine = ReadLine()) != NULL) { if (EQUAL(pszLine, "EOP")) { break; } papszPrj = CSLAddString(papszPrj, pszLine); } OGRSpatialReference oSRS; if( oSRS.importFromESRI( papszPrj ) != OGRERR_NONE ) { CPLError( CE_Warning, CPLE_AppDefined, "Failed to parse PRJ section, ignoring." ); } else { char* pszWKT = NULL; if (oSRS.exportToWkt(&pszWKT) == OGRERR_NONE && pszWKT != NULL) osProjection = pszWKT; CPLFree(pszWKT); } if (bStatsFound) break; } else if (strcmp(pszLine, "STDV 8-1 254-1 15 3 60-1 -1 -1-1 4-") == 0) { bStatsFound = true; pszLine = ReadLine(); if (pszLine) { CPLString osStats = pszLine; pszLine = ReadLine(); if (pszLine) { osStats += pszLine; char** papszTokens = CSLTokenizeString(osStats); if (CSLCount(papszTokens) == 4) { dfMin = CPLAtof(papszTokens[0]); dfMax = CPLAtof(papszTokens[1]); dfMean = CPLAtof(papszTokens[2]); dfStddev = CPLAtof(papszTokens[3]); bHasStats = TRUE; } CSLDestroy(papszTokens); } } if (bPRJFound) break; } } }
GDALDataset *VRTDataset::Open( GDALOpenInfo * poOpenInfo ) { char *pszVRTPath = NULL; /* -------------------------------------------------------------------- */ /* Does this appear to be a virtual dataset definition XML */ /* file? */ /* -------------------------------------------------------------------- */ if( !Identify( poOpenInfo ) ) return NULL; /* -------------------------------------------------------------------- */ /* Try to read the whole file into memory. */ /* -------------------------------------------------------------------- */ char *pszXML; VSILFILE *fp = VSIFOpenL(poOpenInfo->pszFilename, "rb"); if( fp != NULL ) { unsigned int nLength; VSIFSeekL( fp, 0, SEEK_END ); nLength = (int) VSIFTellL( fp ); VSIFSeekL( fp, 0, SEEK_SET ); nLength = MAX(0,nLength); pszXML = (char *) VSIMalloc(nLength+1); if( pszXML == NULL ) { VSIFCloseL(fp); CPLError( CE_Failure, CPLE_OutOfMemory, "Failed to allocate %d byte buffer to hold VRT xml file.", nLength ); return NULL; } if( VSIFReadL( pszXML, 1, nLength, fp ) != nLength ) { VSIFCloseL(fp); CPLFree( pszXML ); CPLError( CE_Failure, CPLE_FileIO, "Failed to read %d bytes from VRT xml file.", nLength ); return NULL; } pszXML[nLength] = '\0'; pszVRTPath = CPLStrdup(CPLGetPath(poOpenInfo->pszFilename)); VSIFCloseL(fp); } /* -------------------------------------------------------------------- */ /* Or use the filename as the XML input. */ /* -------------------------------------------------------------------- */ else { pszXML = CPLStrdup( poOpenInfo->pszFilename ); } /* -------------------------------------------------------------------- */ /* Turn the XML representation into a VRTDataset. */ /* -------------------------------------------------------------------- */ VRTDataset *poDS = (VRTDataset *) OpenXML( pszXML, pszVRTPath, poOpenInfo->eAccess ); if( poDS != NULL ) poDS->bNeedsFlush = FALSE; CPLFree( pszXML ); CPLFree( pszVRTPath ); /* -------------------------------------------------------------------- */ /* Open overviews. */ /* -------------------------------------------------------------------- */ if( fp != NULL && poDS != NULL ) poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename ); return poDS; }
long FileDataSource::DataSourceFtell() { return VSIFTellL( fp ); }
int OGRARCGENDataSource::Open( const char * pszFilename, int bUpdateIn) { if (bUpdateIn) { return FALSE; } pszName = CPLStrdup( pszFilename ); // -------------------------------------------------------------------- // Does this appear to be a Arc/Info generate file? // -------------------------------------------------------------------- VSILFILE* fp = VSIFOpenL(pszFilename, "rb"); if (fp == NULL) return FALSE; /* Check that the first line is compatible with a generate file */ /* and in particular contain >= 32 && <= 127 bytes */ const char* pszLine; CPLPushErrorHandler(CPLQuietErrorHandler); pszLine = CPLReadLine2L(fp,256,NULL); CPLPopErrorHandler(); if (pszLine == NULL) { VSIFCloseL(fp); return FALSE; } const char* szPtr = pszLine; for(;*szPtr != '\0';szPtr++) { if (*szPtr < 32) { VSIFCloseL(fp); return FALSE; } } char** papszTokens = CSLTokenizeString2( pszLine, " ,", 0 ); int nTokens = CSLCount(papszTokens); CSLDestroy(papszTokens); if (nTokens != 1 && nTokens != 3 && nTokens != 4) { VSIFCloseL(fp); return FALSE; } /* Go to end of file, and count the number of END keywords */ /* If there's 1, it's a point layer */ /* If there's 2, it's a linestring or polygon layer */ VSIFSeekL( fp, 0, SEEK_END ); vsi_l_offset nSize = VSIFTellL(fp); if (nSize < 10) { VSIFCloseL(fp); return FALSE; } char szBuffer[10+1]; VSIFSeekL( fp, nSize - 10, SEEK_SET ); VSIFReadL( szBuffer, 1, 10, fp ); szBuffer[10] = '\0'; VSIFSeekL( fp, 0, SEEK_SET ); OGRwkbGeometryType eType; szPtr = szBuffer; const char* szEnd = strstr(szPtr, "END"); if (szEnd == NULL) szEnd = strstr(szPtr, "end"); if (szEnd == NULL) { VSIFCloseL(fp); return FALSE; } szPtr = szEnd + 3; szEnd = strstr(szPtr, "END"); if (szEnd == NULL) szEnd = strstr(szPtr, "end"); if (szEnd == NULL) { pszLine = CPLReadLine2L(fp,256,NULL); if (pszLine == NULL) { VSIFCloseL(fp); return FALSE; } char** papszTokens = CSLTokenizeString2( pszLine, " ,", 0 ); int nTokens = CSLCount(papszTokens); CSLDestroy(papszTokens); if (nTokens == 3) eType = wkbPoint; else if (nTokens == 4) eType = wkbPoint25D; else { VSIFCloseL(fp); return FALSE; } } else { int nLineNumber = 0; eType = wkbUnknown; CPLString osFirstX, osFirstY; CPLString osLastX, osLastY; int bIs3D = FALSE; while((pszLine = CPLReadLine2L(fp,256,NULL)) != NULL) { nLineNumber ++; if (nLineNumber == 2) { char** papszTokens = CSLTokenizeString2( pszLine, " ,", 0 ); int nTokens = CSLCount(papszTokens); if (nTokens == 2 || nTokens == 3) { if (nTokens == 3) bIs3D = TRUE; osFirstX = papszTokens[0]; osFirstY = papszTokens[1]; } CSLDestroy(papszTokens); if (nTokens != 2 && nTokens != 3) break; } else if (nLineNumber > 2) { if (EQUAL(pszLine, "END")) { if (osFirstX.compare(osLastX) == 0 && osFirstY.compare(osLastY) == 0) eType = (bIs3D) ? wkbPolygon25D : wkbPolygon; else eType = (bIs3D) ? wkbLineString25D : wkbLineString; break; } char** papszTokens = CSLTokenizeString2( pszLine, " ,", 0 ); int nTokens = CSLCount(papszTokens); if (nTokens == 2 || nTokens == 3) { osLastX = papszTokens[0]; osLastY = papszTokens[1]; } CSLDestroy(papszTokens); if (nTokens != 2 && nTokens != 3) break; } } if (eType == wkbUnknown) { VSIFCloseL(fp); return FALSE; } } VSIFSeekL( fp, 0, SEEK_SET ); nLayers = 1; papoLayers = (OGRLayer**) CPLMalloc(sizeof(OGRLayer*)); papoLayers[0] = new OGRARCGENLayer(pszName, fp, eType); return TRUE; }