int EnvisatFile_Create( EnvisatFile **self_ptr, const char *filename, const char *template_file ) { int template_size; char *template_data; VSILFILE *fp; /* * Try to open the template file, and read it into memory. */ fp = VSIFOpenL( template_file, "rb" ); if( fp == NULL ) { char error_buf[2048]; sprintf( error_buf, "Unable to open file \"%s\" in EnvisatFile_Create().", template_file ); SendError( error_buf ); return FAILURE; } VSIFSeekL( fp, 0, SEEK_END ); template_size = (int) VSIFTellL( fp ); template_data = (char *) malloc(template_size); VSIFSeekL( fp, 0, SEEK_SET ); VSIFReadL( template_data, template_size, 1, fp ); VSIFCloseL( fp ); /* * Try to write the template out to the new filename. */ fp = VSIFOpenL( filename, "wb" ); if( fp == NULL ) { char error_buf[2048]; sprintf( error_buf, "Unable to open file \"%s\" in EnvisatFile_Create().", filename ); SendError( error_buf ); return FAILURE; } VSIFWriteL( template_data, template_size, 1, fp ); VSIFCloseL( fp ); free( template_data ); /* * Now just open the file normally. */ return EnvisatFile_Open( self_ptr, filename, "r+" ); }
GDALDataset *PAuxDataset::Create( const char * pszFilename, int nXSize, int nYSize, int nBands, GDALDataType eType, char **papszOptions ) { const char *pszInterleave = CSLFetchNameValue( papszOptions, "INTERLEAVE" ); if( pszInterleave == NULL ) pszInterleave = "BAND"; /* -------------------------------------------------------------------- */ /* Verify input options. */ /* -------------------------------------------------------------------- */ if( eType != GDT_Byte && eType != GDT_Float32 && eType != GDT_UInt16 && eType != GDT_Int16 ) { CPLError( CE_Failure, CPLE_AppDefined, "Attempt to create PCI .Aux labelled dataset with an illegal\n" "data type (%s).\n", GDALGetDataTypeName(eType) ); return NULL; } /* -------------------------------------------------------------------- */ /* Sum the sizes of the band pixel types. */ /* -------------------------------------------------------------------- */ int nPixelSizeSum = 0; for( int iBand = 0; iBand < nBands; iBand++ ) nPixelSizeSum += GDALGetDataTypeSizeBytes(eType); /* -------------------------------------------------------------------- */ /* Try to create the file. */ /* -------------------------------------------------------------------- */ VSILFILE *fp = VSIFOpenL( pszFilename, "w" ); if( fp == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "Attempt to create file `%s' failed.\n", pszFilename ); return NULL; } /* -------------------------------------------------------------------- */ /* Just write out a couple of bytes to establish the binary */ /* file, and then close it. */ /* -------------------------------------------------------------------- */ CPL_IGNORE_RET_VAL(VSIFWriteL( "\0\0", 2, 1, fp )); CPL_IGNORE_RET_VAL(VSIFCloseL( fp )); /* -------------------------------------------------------------------- */ /* Create the aux filename. */ /* -------------------------------------------------------------------- */ char *pszAuxFilename = static_cast<char *>( CPLMalloc( strlen( pszFilename ) + 5 ) ); strcpy( pszAuxFilename, pszFilename );; for( int i = static_cast<int>(strlen(pszAuxFilename))-1; i > 0; i-- ) { if( pszAuxFilename[i] == '.' ) { pszAuxFilename[i] = '\0'; break; } } strcat( pszAuxFilename, ".aux" ); /* -------------------------------------------------------------------- */ /* Open the file. */ /* -------------------------------------------------------------------- */ fp = VSIFOpenL( pszAuxFilename, "wt" ); if( fp == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "Attempt to create file `%s' failed.\n", pszAuxFilename ); return NULL; } CPLFree( pszAuxFilename ); /* -------------------------------------------------------------------- */ /* We need to write out the original filename but without any */ /* path components in the AuxilaryTarget line. Do so now. */ /* -------------------------------------------------------------------- */ int iStart = static_cast<int>(strlen(pszFilename))-1; while( iStart > 0 && pszFilename[iStart-1] != '/' && pszFilename[iStart-1] != '\\' ) iStart--; CPL_IGNORE_RET_VAL(VSIFPrintfL( fp, "AuxilaryTarget: %s\n", pszFilename + iStart )); /* -------------------------------------------------------------------- */ /* Write out the raw definition for the dataset as a whole. */ /* -------------------------------------------------------------------- */ CPL_IGNORE_RET_VAL(VSIFPrintfL( fp, "RawDefinition: %d %d %d\n", nXSize, nYSize, nBands )); /* -------------------------------------------------------------------- */ /* Write out a definition for each band. We always write band */ /* sequential files for now as these are pretty efficiently */ /* handled by GDAL. */ /* -------------------------------------------------------------------- */ vsi_l_offset nImgOffset = 0; for( int iBand = 0; iBand < nBands; iBand++ ) { int nPixelOffset = 0; int nLineOffset = 0; vsi_l_offset nNextImgOffset = 0; /* -------------------------------------------------------------------- */ /* Establish our file layout based on supplied interleaving. */ /* -------------------------------------------------------------------- */ if( EQUAL(pszInterleave,"LINE") ) { nPixelOffset = GDALGetDataTypeSizeBytes(eType); nLineOffset = nXSize * nPixelSizeSum; nNextImgOffset = nImgOffset + nPixelOffset * nXSize; } else if( EQUAL(pszInterleave,"PIXEL") ) { nPixelOffset = nPixelSizeSum; nLineOffset = nXSize * nPixelOffset; nNextImgOffset = nImgOffset + GDALGetDataTypeSizeBytes(eType); } else /* default to band */ { nPixelOffset = GDALGetDataTypeSize(eType)/8; nLineOffset = nXSize * nPixelOffset; nNextImgOffset = nImgOffset + nYSize * static_cast<vsi_l_offset>( nLineOffset ); } /* -------------------------------------------------------------------- */ /* Write out line indicating layout. */ /* -------------------------------------------------------------------- */ const char *pszTypeName = NULL; if( eType == GDT_Float32 ) pszTypeName = "32R"; else if( eType == GDT_Int16 ) pszTypeName = "16S"; else if( eType == GDT_UInt16 ) pszTypeName = "16U"; else pszTypeName = "8U"; CPL_IGNORE_RET_VAL( VSIFPrintfL( fp, "ChanDefinition-%d: %s " CPL_FRMT_GIB " %d %d %s\n", iBand+1, pszTypeName, static_cast<GIntBig>( nImgOffset ), nPixelOffset, nLineOffset, #ifdef CPL_LSB "Swapped" #else "Unswapped" #endif ) ); nImgOffset = nNextImgOffset; } /* -------------------------------------------------------------------- */ /* Cleanup */ /* -------------------------------------------------------------------- */ CPL_IGNORE_RET_VAL(VSIFCloseL( fp )); return static_cast<GDALDataset *>( GDALOpen( pszFilename, GA_Update ) ); }
GDALDataset* HF2Dataset::CreateCopy( const char * pszFilename, GDALDataset *poSrcDS, int bStrict, char ** papszOptions, GDALProgressFunc pfnProgress, void * pProgressData ) { /* -------------------------------------------------------------------- */ /* Some some rudimentary checks */ /* -------------------------------------------------------------------- */ int nBands = poSrcDS->GetRasterCount(); if (nBands == 0) { CPLError( CE_Failure, CPLE_NotSupported, "HF2 driver does not support source dataset with zero band.\n"); return NULL; } if (nBands != 1) { CPLError( (bStrict) ? CE_Failure : CE_Warning, CPLE_NotSupported, "HF2 driver only uses the first band of the dataset.\n"); if (bStrict) return NULL; } if( pfnProgress && !pfnProgress( 0.0, NULL, pProgressData ) ) return NULL; /* -------------------------------------------------------------------- */ /* Get source dataset info */ /* -------------------------------------------------------------------- */ int nXSize = poSrcDS->GetRasterXSize(); int nYSize = poSrcDS->GetRasterYSize(); double adfGeoTransform[6]; poSrcDS->GetGeoTransform(adfGeoTransform); int bHasGeoTransform = !(adfGeoTransform[0] == 0 && adfGeoTransform[1] == 1 && adfGeoTransform[2] == 0 && adfGeoTransform[3] == 0 && adfGeoTransform[4] == 0 && adfGeoTransform[5] == 1); if (adfGeoTransform[2] != 0 || adfGeoTransform[4] != 0) { CPLError( CE_Failure, CPLE_NotSupported, "HF2 driver does not support CreateCopy() from skewed or rotated dataset.\n"); return NULL; } GDALDataType eSrcDT = poSrcDS->GetRasterBand(1)->GetRasterDataType(); GDALDataType eReqDT; float fVertPres = (float) 0.01; if (eSrcDT == GDT_Byte || eSrcDT == GDT_Int16) { fVertPres = 1; eReqDT = GDT_Int16; } else eReqDT = GDT_Float32; /* -------------------------------------------------------------------- */ /* Read creation options */ /* -------------------------------------------------------------------- */ const char* pszCompressed = CSLFetchNameValue(papszOptions, "COMPRESS"); int bCompress = FALSE; if (pszCompressed) bCompress = CSLTestBoolean(pszCompressed); const char* pszVerticalPrecision = CSLFetchNameValue(papszOptions, "VERTICAL_PRECISION"); if (pszVerticalPrecision) { fVertPres = (float) CPLAtofM(pszVerticalPrecision); if (fVertPres <= 0) { CPLError(CE_Warning, CPLE_AppDefined, "Unsupported value for VERTICAL_PRECISION. Defaulting to 0.01"); fVertPres = (float) 0.01; } if (eReqDT == GDT_Int16 && fVertPres > 1) eReqDT = GDT_Float32; } const char* pszBlockSize = CSLFetchNameValue(papszOptions, "BLOCKSIZE"); int nTileSize = 256; if (pszBlockSize) { nTileSize = atoi(pszBlockSize); if (nTileSize < 8 || nTileSize > 4096) { CPLError(CE_Warning, CPLE_AppDefined, "Unsupported value for BLOCKSIZE. Defaulting to 256"); nTileSize = 256; } } /* -------------------------------------------------------------------- */ /* Parse source dataset georeferencing info */ /* -------------------------------------------------------------------- */ int nExtendedHeaderLen = 0; if (bHasGeoTransform) nExtendedHeaderLen += 58; const char* pszProjectionRef = poSrcDS->GetProjectionRef(); int nDatumCode = -2; int nUTMZone = 0; int bNorth = FALSE; int nEPSGCode = 0; int nExtentUnits = 1; if (pszProjectionRef != NULL && pszProjectionRef[0] != '\0') { OGRSpatialReference oSRS; char* pszTemp = (char*) pszProjectionRef; if (oSRS.importFromWkt(&pszTemp) == OGRERR_NONE) { const char* pszValue = NULL; if( oSRS.GetAuthorityName( "GEOGCS|DATUM" ) != NULL && EQUAL(oSRS.GetAuthorityName( "GEOGCS|DATUM" ),"EPSG") ) nDatumCode = atoi(oSRS.GetAuthorityCode( "GEOGCS|DATUM" )); else if ((pszValue = oSRS.GetAttrValue("GEOGCS|DATUM")) != NULL) { if (strstr(pszValue, "WGS") && strstr(pszValue, "84")) nDatumCode = 6326; } nUTMZone = oSRS.GetUTMZone(&bNorth); } if( oSRS.GetAuthorityName( "PROJCS" ) != NULL && EQUAL(oSRS.GetAuthorityName( "PROJCS" ),"EPSG") ) nEPSGCode = atoi(oSRS.GetAuthorityCode( "PROJCS" )); if( oSRS.IsGeographic() ) { nExtentUnits = 0; } else { double dfLinear = oSRS.GetLinearUnits(); if( ABS(dfLinear - 0.3048) < 0.0000001 ) nExtentUnits = 2; else if( ABS(dfLinear - CPLAtof(SRS_UL_US_FOOT_CONV)) < 0.00000001 ) nExtentUnits = 3; else nExtentUnits = 1; } } if (nDatumCode != -2) nExtendedHeaderLen += 26; if (nUTMZone != 0) nExtendedHeaderLen += 26; if (nEPSGCode) nExtendedHeaderLen += 26; /* -------------------------------------------------------------------- */ /* Create target file */ /* -------------------------------------------------------------------- */ CPLString osFilename; if (bCompress) { osFilename = "/vsigzip/"; osFilename += pszFilename; } else osFilename = pszFilename; VSILFILE* fp = VSIFOpenL(osFilename.c_str(), "wb"); if (fp == NULL) { CPLError( CE_Failure, CPLE_AppDefined, "Cannot create %s", pszFilename ); return NULL; } /* -------------------------------------------------------------------- */ /* Write header */ /* -------------------------------------------------------------------- */ VSIFWriteL("HF2\0", 4, 1, fp); WriteShort(fp, 0); WriteInt(fp, nXSize); WriteInt(fp, nYSize); WriteShort(fp, (GInt16) nTileSize); WriteFloat(fp, fVertPres); float fHorizScale = (float) ((fabs(adfGeoTransform[1]) + fabs(adfGeoTransform[5])) / 2); WriteFloat(fp, fHorizScale); WriteInt(fp, nExtendedHeaderLen); /* -------------------------------------------------------------------- */ /* Write extended header */ /* -------------------------------------------------------------------- */ char szBlockName[16 + 1]; if (bHasGeoTransform) { VSIFWriteL("bin\0", 4, 1, fp); memset(szBlockName, 0, 16 + 1); strcpy(szBlockName, "georef-extents"); VSIFWriteL(szBlockName, 16, 1, fp); WriteInt(fp, 34); WriteShort(fp, (GInt16) nExtentUnits); WriteDouble(fp, adfGeoTransform[0]); WriteDouble(fp, adfGeoTransform[0] + nXSize * adfGeoTransform[1]); WriteDouble(fp, adfGeoTransform[3] + nYSize * adfGeoTransform[5]); WriteDouble(fp, adfGeoTransform[3]); } if (nUTMZone != 0) { VSIFWriteL("bin\0", 4, 1, fp); memset(szBlockName, 0, 16 + 1); strcpy(szBlockName, "georef-utm"); VSIFWriteL(szBlockName, 16, 1, fp); WriteInt(fp, 2); WriteShort(fp, (GInt16) ((bNorth) ? nUTMZone : -nUTMZone)); } if (nDatumCode != -2) { VSIFWriteL("bin\0", 4, 1, fp); memset(szBlockName, 0, 16 + 1); strcpy(szBlockName, "georef-datum"); VSIFWriteL(szBlockName, 16, 1, fp); WriteInt(fp, 2); WriteShort(fp, (GInt16) nDatumCode); } if (nEPSGCode != 0) { VSIFWriteL("bin\0", 4, 1, fp); memset(szBlockName, 0, 16 + 1); strcpy(szBlockName, "georef-epsg-prj"); VSIFWriteL(szBlockName, 16, 1, fp); WriteInt(fp, 2); WriteShort(fp, (GInt16) nEPSGCode); } /* -------------------------------------------------------------------- */ /* Copy imagery */ /* -------------------------------------------------------------------- */ int nXBlocks = (nXSize + nTileSize - 1) / nTileSize; int nYBlocks = (nYSize + nTileSize - 1) / nTileSize; void* pTileBuffer = (void*) VSIMalloc(nTileSize * nTileSize * (GDALGetDataTypeSize(eReqDT) / 8)); if (pTileBuffer == NULL) { CPLError( CE_Failure, CPLE_OutOfMemory, "Out of memory"); VSIFCloseL(fp); return NULL; } int i, j, k, l; CPLErr eErr = CE_None; for(j=0;j<nYBlocks && eErr == CE_None;j++) { for(i=0;i<nXBlocks && eErr == CE_None;i++) { int nReqXSize = MIN(nTileSize, nXSize - i * nTileSize); int nReqYSize = MIN(nTileSize, nYSize - j * nTileSize); eErr = poSrcDS->GetRasterBand(1)->RasterIO(GF_Read, i * nTileSize, MAX(0, nYSize - (j + 1) * nTileSize), nReqXSize, nReqYSize, pTileBuffer, nReqXSize, nReqYSize, eReqDT, 0, 0, NULL); if (eErr != CE_None) break; if (eReqDT == GDT_Int16) { WriteFloat(fp, 1); /* scale */ WriteFloat(fp, 0); /* offset */ for(k=0;k<nReqYSize;k++) { int nLastVal = ((short*)pTileBuffer)[(nReqYSize - k - 1) * nReqXSize + 0]; GByte nWordSize = 1; for(l=1;l<nReqXSize;l++) { int nVal = ((short*)pTileBuffer)[(nReqYSize - k - 1) * nReqXSize + l]; int nDiff = nVal - nLastVal; if (nDiff < -32768 || nDiff > 32767) { nWordSize = 4; break; } if (nDiff < -128 || nDiff > 127) nWordSize = 2; nLastVal = nVal; } VSIFWriteL(&nWordSize, 1, 1, fp); nLastVal = ((short*)pTileBuffer)[(nReqYSize - k - 1) * nReqXSize + 0]; WriteInt(fp, nLastVal); for(l=1;l<nReqXSize;l++) { int nVal = ((short*)pTileBuffer)[(nReqYSize - k - 1) * nReqXSize + l]; int nDiff = nVal - nLastVal; if (nWordSize == 1) { CPLAssert(nDiff >= -128 && nDiff <= 127); char chDiff = (char)nDiff; VSIFWriteL(&chDiff, 1, 1, fp); } else if (nWordSize == 2) { CPLAssert(nDiff >= -32768 && nDiff <= 32767); WriteShort(fp, (short)nDiff); } else { WriteInt(fp, nDiff); } nLastVal = nVal; } } } else { float fMinVal = ((float*)pTileBuffer)[0]; float fMaxVal = fMinVal; for(k=1;k<nReqYSize*nReqXSize;k++) { float fVal = ((float*)pTileBuffer)[k]; if (fVal < fMinVal) fMinVal = fVal; if (fVal > fMaxVal) fMaxVal = fVal; } float fIntRange = (fMaxVal - fMinVal) / fVertPres; float fScale = (fMinVal == fMaxVal) ? 1 : (fMaxVal - fMinVal) / fIntRange; float fOffset = fMinVal; WriteFloat(fp, fScale); /* scale */ WriteFloat(fp, fOffset); /* offset */ for(k=0;k<nReqYSize;k++) { float fLastVal = ((float*)pTileBuffer)[(nReqYSize - k - 1) * nReqXSize + 0]; float fIntLastVal = (fLastVal - fOffset) / fScale; CPLAssert(fIntLastVal >= -2147483648.0f && fIntLastVal <= 2147483647.0f); int nLastVal = (int)fIntLastVal; GByte nWordSize = 1; for(l=1;l<nReqXSize;l++) { float fVal = ((float*)pTileBuffer)[(nReqYSize - k - 1) * nReqXSize + l]; float fIntVal = (fVal - fOffset) / fScale; CPLAssert(fIntVal >= -2147483648.0f && fIntVal <= 2147483647.0f); int nVal = (int)fIntVal; int nDiff = nVal - nLastVal; CPLAssert((int)((GIntBig)nVal - nLastVal) == nDiff); if (nDiff < -32768 || nDiff > 32767) { nWordSize = 4; break; } if (nDiff < -128 || nDiff > 127) nWordSize = 2; nLastVal = nVal; } VSIFWriteL(&nWordSize, 1, 1, fp); fLastVal = ((float*)pTileBuffer)[(nReqYSize - k - 1) * nReqXSize + 0]; fIntLastVal = (fLastVal - fOffset) / fScale; nLastVal = (int)fIntLastVal; WriteInt(fp, nLastVal); for(l=1;l<nReqXSize;l++) { float fVal = ((float*)pTileBuffer)[(nReqYSize - k - 1) * nReqXSize + l]; float fIntVal = (fVal - fOffset) / fScale; int nVal = (int)fIntVal; int nDiff = nVal - nLastVal; CPLAssert((int)((GIntBig)nVal - nLastVal) == nDiff); if (nWordSize == 1) { CPLAssert(nDiff >= -128 && nDiff <= 127); char chDiff = (char)nDiff; VSIFWriteL(&chDiff, 1, 1, fp); } else if (nWordSize == 2) { CPLAssert(nDiff >= -32768 && nDiff <= 32767); WriteShort(fp, (short)nDiff); } else { WriteInt(fp, nDiff); } nLastVal = nVal; } } } if( pfnProgress && !pfnProgress( (j * nXBlocks + i + 1) * 1.0 / (nXBlocks * nYBlocks), NULL, pProgressData ) ) { eErr = CE_Failure; break; } } } CPLFree(pTileBuffer); VSIFCloseL(fp); if (eErr != CE_None) return NULL; return (GDALDataset*) GDALOpen(osFilename.c_str(), GA_ReadOnly); }
GDALDataset *VICARDataset::Open( GDALOpenInfo * poOpenInfo ) { /* -------------------------------------------------------------------- */ /* Does this look like a VICAR dataset? */ /* -------------------------------------------------------------------- */ if( !Identify( poOpenInfo ) ) return NULL; /* -------------------------------------------------------------------- */ /* Open the file using the large file API. */ /* -------------------------------------------------------------------- */ VSILFILE *fpQube = VSIFOpenL( poOpenInfo->pszFilename, "rb" ); if( fpQube == NULL ) return NULL; VICARDataset *poDS; poDS = new VICARDataset(); if( ! poDS->oKeywords.Ingest( fpQube, poOpenInfo->pabyHeader ) ) { VSIFCloseL( fpQube ); delete poDS; return NULL; } VSIFCloseL( fpQube ); CPLString osQubeFile; osQubeFile = poOpenInfo->pszFilename; GDALDataType eDataType = GDT_Byte; int nRows = -1; int nCols = -1; int nBands = 1; int nSkipBytes = 0; int bIsDTM = FALSE; char chByteOrder = 'M'; double dfNoData = 0.0; const char *value; /***** CHECK ENDIANNESS **************/ value = poDS->GetKeyword( "INTFMT" ); if (!EQUAL(value,"LOW") ) { CPLError( CE_Failure, CPLE_OpenFailed, "%s layout not supported. Abort\n\n", value); return FALSE; } value = poDS->GetKeyword( "REALFMT" ); if (!EQUAL(value,"RIEEE") ) { CPLError( CE_Failure, CPLE_OpenFailed, "%s layout not supported. Abort\n\n", value); return FALSE; } value = poDS->GetKeyword( "BREALFMT" ); if (EQUAL(value,"VAX") ) { chByteOrder = 'I'; } /************ CHECK INSTRUMENT *****************/ /************ ONLY HRSC TESTED *****************/ value = poDS->GetKeyword( "DTM.DTM_OFFSET" ); if (!EQUAL(value,"") ) { bIsDTM = TRUE; } value = poDS->GetKeyword( "BLTYPE" ); if (!EQUAL(value,"M94_HRSC") && bIsDTM==FALSE ) { CPLError( CE_Failure, CPLE_OpenFailed, "%s instrument not tested. Continue with caution!\n\n", value); } /*********** Grab layout type (BSQ, BIP, BIL) ************/ char szLayout[10] = "BSQ"; //default to band seq. value = poDS->GetKeyword( "ORG" ); if (EQUAL(value,"BSQ") ) { strcpy(szLayout,"BSQ"); nCols = atoi(poDS->GetKeyword("NS")); nRows = atoi(poDS->GetKeyword("NL")); nBands = atoi(poDS->GetKeyword("NB")); } else { CPLError( CE_Failure, CPLE_OpenFailed, "%s layout not supported. Abort\n\n", value); return FALSE; } /*********** Grab record bytes **********/ nSkipBytes = atoi(poDS->GetKeyword("NBB")); if (EQUAL( poDS->GetKeyword( "FORMAT" ), "BYTE" )) { eDataType = GDT_Byte; dfNoData = NULL1; } else if (EQUAL( poDS->GetKeyword( "FORMAT" ), "HALF" )) { eDataType = GDT_Int16; dfNoData = NULL2; chByteOrder = 'I'; } else if (EQUAL( poDS->GetKeyword( "FORMAT" ), "FULL" )) { eDataType = GDT_UInt32; dfNoData = 0; } else if (EQUAL( poDS->GetKeyword( "FORMAT" ), "REAL" )) { eDataType = GDT_Float32; dfNoData = NULL3; chByteOrder = 'I'; } else { printf("Could not find known VICAR label entries!\n"); delete poDS; return NULL; } if( nRows < 1 || nCols < 1 || nBands < 1 ) { CPLError( CE_Failure, CPLE_AppDefined, "File %s appears to be a VICAR file, but failed to find some required keywords.", poDS->GetDescription() ); return FALSE; } /* -------------------------------------------------------------------- */ /* Capture some information from the file that is of interest. */ /* -------------------------------------------------------------------- */ poDS->nRasterXSize = nCols; poDS->nRasterYSize = nRows; double dfULXMap=0.5; double dfULYMap = 0.5; double dfXDim = 1.0; double dfYDim = 1.0; double xulcenter = 0.0; double yulcenter = 0.0; value = poDS->GetKeyword("MAP.MAP_SCALE"); if (strlen(value) > 0 ) { dfXDim = CPLAtof(value); dfYDim = CPLAtof(value) * -1; dfXDim = dfXDim * 1000.0; dfYDim = dfYDim * 1000.0; } double dfSampleOffset_Shift; double dfLineOffset_Shift; double dfSampleOffset_Mult; double dfLineOffset_Mult; dfSampleOffset_Shift = CPLAtof(CPLGetConfigOption( "PDS_SampleProjOffset_Shift", "0.5" )); dfLineOffset_Shift = CPLAtof(CPLGetConfigOption( "PDS_LineProjOffset_Shift", "0.5" )); dfSampleOffset_Mult = CPLAtof(CPLGetConfigOption( "PDS_SampleProjOffset_Mult", "-1.0") ); dfLineOffset_Mult = CPLAtof( CPLGetConfigOption( "PDS_LineProjOffset_Mult", "1.0") ); /*********** Grab LINE_PROJECTION_OFFSET ************/ value = poDS->GetKeyword("MAP.LINE_PROJECTION_OFFSET"); if (strlen(value) > 0) { yulcenter = CPLAtof(value); dfULYMap = ((yulcenter + dfLineOffset_Shift) * -dfYDim * dfLineOffset_Mult); } /*********** Grab SAMPLE_PROJECTION_OFFSET ************/ value = poDS->GetKeyword("MAP.SAMPLE_PROJECTION_OFFSET"); if( strlen(value) > 0 ) { xulcenter = CPLAtof(value); dfULXMap = ((xulcenter + dfSampleOffset_Shift) * dfXDim * dfSampleOffset_Mult); } /* ==================================================================== */ /* Get the coordinate system. */ /* ==================================================================== */ int bProjectionSet = TRUE; double semi_major = 0.0; double semi_minor = 0.0; double iflattening = 0.0; double center_lat = 0.0; double center_lon = 0.0; double first_std_parallel = 0.0; double second_std_parallel = 0.0; OGRSpatialReference oSRS; /*********** Grab TARGET_NAME ************/ /**** This is the planets name i.e. MARS ***/ CPLString target_name = poDS->GetKeyword("MAP.TARGET_NAME"); /********** Grab MAP_PROJECTION_TYPE *****/ CPLString map_proj_name = poDS->GetKeyword( "MAP.MAP_PROJECTION_TYPE"); /****** Grab semi_major & convert to KM ******/ semi_major = CPLAtof(poDS->GetKeyword( "MAP.A_AXIS_RADIUS")) * 1000.0; /****** Grab semi-minor & convert to KM ******/ semi_minor = CPLAtof(poDS->GetKeyword( "MAP.C_AXIS_RADIUS")) * 1000.0; /*********** Grab CENTER_LAT ************/ center_lat = CPLAtof(poDS->GetKeyword( "MAP.CENTER_LATITUDE")); /*********** Grab CENTER_LON ************/ center_lon = CPLAtof(poDS->GetKeyword( "MAP.CENTER_LONGITUDE")); /********** Grab 1st std parallel *******/ first_std_parallel = CPLAtof(poDS->GetKeyword( "MAP.FIRST_STANDARD_PARALLEL")); /********** Grab 2nd std parallel *******/ second_std_parallel = CPLAtof(poDS->GetKeyword( "MAP.SECOND_STANDARD_PARALLEL")); /*** grab PROJECTION_LATITUDE_TYPE = "PLANETOCENTRIC" ****/ // Need to further study how ocentric/ographic will effect the gdal library. // So far we will use this fact to define a sphere or ellipse for some projections // Frank - may need to talk this over char bIsGeographic = TRUE; value = poDS->GetKeyword("MAP.COORDINATE_SYSTEM_NAME"); if (EQUAL( value, "PLANETOCENTRIC" )) bIsGeographic = FALSE; /** Set oSRS projection and parameters --- all PDS supported types added if apparently supported in oSRS "AITOFF", ** Not supported in GDAL?? "ALBERS", "BONNE", "BRIESEMEISTER", ** Not supported in GDAL?? "CYLINDRICAL EQUAL AREA", "EQUIDISTANT", "EQUIRECTANGULAR", "GNOMONIC", "HAMMER", ** Not supported in GDAL?? "HENDU", ** Not supported in GDAL?? "LAMBERT AZIMUTHAL EQUAL AREA", "LAMBERT CONFORMAL", "MERCATOR", "MOLLWEIDE", "OBLIQUE CYLINDRICAL", "ORTHOGRAPHIC", "SIMPLE CYLINDRICAL", "SINUSOIDAL", "STEREOGRAPHIC", "TRANSVERSE MERCATOR", "VAN DER GRINTEN", ** Not supported in GDAL?? "WERNER" ** Not supported in GDAL?? **/ CPLDebug( "PDS","using projection %s\n\n", map_proj_name.c_str()); if ((EQUAL( map_proj_name, "EQUIRECTANGULAR" )) || (EQUAL( map_proj_name, "SIMPLE_CYLINDRICAL" )) || (EQUAL( map_proj_name, "EQUIDISTANT" )) ) { oSRS.SetEquirectangular2 ( 0.0, center_lon, center_lat, 0, 0 ); } else if (EQUAL( map_proj_name, "ORTHOGRAPHIC" )) { oSRS.SetOrthographic ( center_lat, center_lon, 0, 0 ); } else if (EQUAL( map_proj_name, "SINUSOIDAL" )) { oSRS.SetSinusoidal ( center_lon, 0, 0 ); } else if (EQUAL( map_proj_name, "MERCATOR" )) { oSRS.SetMercator ( center_lat, center_lon, 1, 0, 0 ); } else if (EQUAL( map_proj_name, "STEREOGRAPHIC" )) { oSRS.SetStereographic ( center_lat, center_lon, 1, 0, 0 ); } else if (EQUAL( map_proj_name, "POLAR_STEREOGRAPHIC")) { oSRS.SetPS ( center_lat, center_lon, 1, 0, 0 ); } else if (EQUAL( map_proj_name, "TRANSVERSE_MERCATOR" )) { oSRS.SetTM ( center_lat, center_lon, 1, 0, 0 ); } else if (EQUAL( map_proj_name, "LAMBERT_CONFORMAL_CONIC" )) { oSRS.SetLCC ( first_std_parallel, second_std_parallel, center_lat, center_lon, 0, 0 ); } else if (EQUAL( map_proj_name, "LAMBERT_AZIMUTHAL_EQUAL_AREA" )) { oSRS.SetLAEA( center_lat, center_lon, 0, 0 ); } else if (EQUAL( map_proj_name, "CYLINDRICAL_EQUAL_AREA" )) { oSRS.SetCEA ( first_std_parallel, center_lon, 0, 0 ); } else if (EQUAL( map_proj_name, "MOLLWEIDE" )) { oSRS.SetMollweide ( center_lon, 0, 0 ); } else if (EQUAL( map_proj_name, "ALBERS" )) { oSRS.SetACEA ( first_std_parallel, second_std_parallel, center_lat, center_lon, 0, 0 ); } else if (EQUAL( map_proj_name, "BONNE" )) { oSRS.SetBonne ( first_std_parallel, center_lon, 0, 0 ); } else if (EQUAL( map_proj_name, "GNOMONIC" )) { oSRS.SetGnomonic ( center_lat, center_lon, 0, 0 ); } else if (EQUAL( map_proj_name, "OBLIQUE_CYLINDRICAL" )) { // hope Swiss Oblique Cylindrical is the same oSRS.SetSOC ( center_lat, center_lon, 0, 0 ); } else { CPLDebug( "VICAR", "Dataset projection %s is not supported. Continuing...", map_proj_name.c_str() ); bProjectionSet = FALSE; } if (bProjectionSet) { //Create projection name, i.e. MERCATOR MARS and set as ProjCS keyword CPLString proj_target_name = map_proj_name + " " + target_name; oSRS.SetProjCS(proj_target_name); //set ProjCS keyword //The geographic/geocentric name will be the same basic name as the body name //'GCS' = Geographic/Geocentric Coordinate System CPLString geog_name = "GCS_" + target_name; //The datum and sphere names will be the same basic name aas the planet CPLString datum_name = "D_" + target_name; CPLString sphere_name = target_name; // + "_IAU_IAG"); //Might not be IAU defined so don't add //calculate inverse flattening from major and minor axis: 1/f = a/(a-b) if ((semi_major - semi_minor) < 0.0000001) iflattening = 0; else iflattening = semi_major / (semi_major - semi_minor); //Set the body size but take into consideration which proj is being used to help w/ compatibility //Notice that most PDS projections are spherical based on the fact that ISIS/PICS are spherical //Set the body size but take into consideration which proj is being used to help w/ proj4 compatibility //The use of a Sphere, polar radius or ellipse here is based on how ISIS does it internally if ( ( (EQUAL( map_proj_name, "STEREOGRAPHIC" ) && (fabs(center_lat) == 90)) ) || (EQUAL( map_proj_name, "POLAR_STEREOGRAPHIC" ))) { if (bIsGeographic) { //Geograpraphic, so set an ellipse oSRS.SetGeogCS( geog_name, datum_name, sphere_name, semi_major, iflattening, "Reference_Meridian", 0.0 ); } else { //Geocentric, so force a sphere using the semi-minor axis. I hope... sphere_name += "_polarRadius"; oSRS.SetGeogCS( geog_name, datum_name, sphere_name, semi_minor, 0.0, "Reference_Meridian", 0.0 ); } } else if ( (EQUAL( map_proj_name, "SIMPLE_CYLINDRICAL" )) || (EQUAL( map_proj_name, "EQUIDISTANT" )) || (EQUAL( map_proj_name, "ORTHOGRAPHIC" )) || (EQUAL( map_proj_name, "STEREOGRAPHIC" )) || (EQUAL( map_proj_name, "SINUSOIDAL" )) ) { //isis uses the spherical equation for these projections so force a sphere oSRS.SetGeogCS( geog_name, datum_name, sphere_name, semi_major, 0.0, "Reference_Meridian", 0.0 ); } else if (EQUAL( map_proj_name, "EQUIRECTANGULAR" )) { //isis uses local radius as a sphere, which is pre-calculated in the PDS label as the semi-major sphere_name += "_localRadius"; oSRS.SetGeogCS( geog_name, datum_name, sphere_name, semi_major, 0.0, "Reference_Meridian", 0.0 ); } else { //All other projections: Mercator, Transverse Mercator, Lambert Conformal, etc. //Geographic, so set an ellipse if (bIsGeographic) { oSRS.SetGeogCS( geog_name, datum_name, sphere_name, semi_major, iflattening, "Reference_Meridian", 0.0 ); } else { //Geocentric, so force a sphere. I hope... oSRS.SetGeogCS( geog_name, datum_name, sphere_name, semi_major, 0.0, "Reference_Meridian", 0.0 ); } } // translate back into a projection string. char *pszResult = NULL; oSRS.exportToWkt( &pszResult ); poDS->osProjection = pszResult; CPLFree( pszResult ); } { poDS->bGotTransform = TRUE; poDS->adfGeoTransform[0] = dfULXMap; poDS->adfGeoTransform[1] = dfXDim; poDS->adfGeoTransform[2] = 0.0; poDS->adfGeoTransform[3] = dfULYMap; poDS->adfGeoTransform[4] = 0.0; poDS->adfGeoTransform[5] = dfYDim; } if( !poDS->bGotTransform ) poDS->bGotTransform = GDALReadWorldFile( osQubeFile, "psw", poDS->adfGeoTransform ); if( !poDS->bGotTransform ) poDS->bGotTransform = GDALReadWorldFile( osQubeFile, "wld", poDS->adfGeoTransform ); /* -------------------------------------------------------------------- */ /* Open target binary file. */ /* -------------------------------------------------------------------- */ if( poOpenInfo->eAccess == GA_ReadOnly ) poDS->fpImage = VSIFOpenL( osQubeFile, "r" ); else poDS->fpImage = VSIFOpenL( osQubeFile, "r+" ); if( poDS->fpImage == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "Failed to open %s with write permission.\n%s", osQubeFile.c_str(), VSIStrerror( errno ) ); delete poDS; return NULL; } poDS->eAccess = poOpenInfo->eAccess; /* -------------------------------------------------------------------- */ /* Compute the line offsets. */ /* -------------------------------------------------------------------- */ long int nItemSize = GDALGetDataTypeSize(eDataType)/8; long int nLineOffset=0, nPixelOffset=0, nBandOffset=0; nPixelOffset = nItemSize; nLineOffset = nPixelOffset * nCols + atoi(poDS->GetKeyword("NBB")) ; nBandOffset = nLineOffset * nRows; nSkipBytes = atoi(poDS->GetKeyword("LBLSIZE")); /* -------------------------------------------------------------------- */ /* Create band information objects. */ /* -------------------------------------------------------------------- */ int i; for( i = 0; i < nBands; i++ ) { GDALRasterBand *poBand; poBand = new RawRasterBand( poDS, i+1, poDS->fpImage, nSkipBytes + nBandOffset * i, nPixelOffset, nLineOffset, eDataType, #ifdef CPL_LSB chByteOrder == 'I' || chByteOrder == 'L', #else chByteOrder == 'M', #endif TRUE ); poDS->SetBand( i+1, poBand ); poBand->SetNoDataValue( dfNoData ); if (bIsDTM==TRUE) { poBand->SetScale( (double) CPLAtof(poDS->GetKeyword( "DTM.DTM_SCALING_FACTOR") ) ); poBand->SetOffset( (double) CPLAtof(poDS->GetKeyword( "DTM.DTM_OFFSET") ) ); const char* pszMin = poDS->GetKeyword( "DTM.DTM_MINIMUM_DN", NULL ); const char* pszMax = poDS->GetKeyword( "DTM.DTM_MAXIMUM_DN", NULL ); if (pszMin != NULL && pszMax != NULL ) poBand->SetStatistics(CPLAtofM(pszMin),CPLAtofM(pszMax),0,0); const char* pszNoData = poDS->GetKeyword( "DTM.DTM_MISSING_DN", NULL ); if (pszNoData != NULL ) poBand->SetNoDataValue( CPLAtofM(pszNoData) ); } else if (EQUAL( poDS->GetKeyword( "BLTYPE"), "M94_HRSC" )) { float scale=CPLAtof(poDS->GetKeyword("DLRTO8.REFLECTANCE_SCALING_FACTOR","-1.")); if (scale < 0.) { scale = CPLAtof(poDS->GetKeyword( "HRCAL.REFLECTANCE_SCALING_FACTOR","1.")); } poBand->SetScale( scale ); float offset=CPLAtof(poDS->GetKeyword("DLRTO8.REFLECTANCE_OFFSET","-1.")); if (offset < 0.) { offset = CPLAtof(poDS->GetKeyword( "HRCAL.REFLECTANCE_OFFSET","0.")); } poBand->SetOffset( offset ); } const char* pszMin = poDS->GetKeyword( "STATISTICS.MINIMUM", NULL ); const char* pszMax = poDS->GetKeyword( "STATISTICS.MAXIMUM", NULL ); const char* pszMean = poDS->GetKeyword( "STATISTICS.MEAN", NULL ); const char* pszStdDev = poDS->GetKeyword( "STATISTICS.STANDARD_DEVIATION", NULL ); if (pszMin != NULL && pszMax != NULL && pszMean != NULL && pszStdDev != NULL ) poBand->SetStatistics(CPLAtofM(pszMin),CPLAtofM(pszMax),CPLAtofM(pszMean),CPLAtofM(pszStdDev)); } /* -------------------------------------------------------------------- */ /* Instrument-specific keywords as metadata. */ /* -------------------------------------------------------------------- */ /****************** HRSC ******************************/ if (EQUAL( poDS->GetKeyword( "BLTYPE"), "M94_HRSC" ) ) { poDS->SetMetadataItem( "SPACECRAFT_NAME", poDS->GetKeyword( "M94_INSTRUMENT.INSTRUMENT_HOST_NAME") ); poDS->SetMetadataItem( "PRODUCT_TYPE", poDS->GetKeyword( "TYPE")); if (EQUAL( poDS->GetKeyword( "M94_INSTRUMENT.DETECTOR_ID"), "MEX_HRSC_SRC" )) { static const char *apszKeywords[] = { "M94_ORBIT.IMAGE_TIME", "FILE.EVENT_TYPE", "FILE.PROCESSING_LEVEL_ID", "M94_INSTRUMENT.DETECTOR_ID", "M94_CAMERAS.EXPOSURE_DURATION", "HRCONVER.INSTRUMENT_TEMPERATURE", NULL }; for( i = 0; apszKeywords[i] != NULL; i++ ) { const char *pszKeywordValue = poDS->GetKeyword( apszKeywords[i] ); if( pszKeywordValue != NULL ) poDS->SetMetadataItem( apszKeywords[i], pszKeywordValue ); } } else { static const char *apszKeywords[] = { "M94_ORBIT.START_TIME", "M94_ORBIT.STOP_TIME", "M94_INSTRUMENT.DETECTOR_ID", "M94_CAMERAS.MACROPIXEL_SIZE", "FILE.EVENT_TYPE", "M94_INSTRUMENT.MISSION_PHASE_NAME", "HRORTHO.SPICE_FILE_NAME", "HRCONVER.MISSING_FRAMES", "HRCONVER.OVERFLOW_FRAMES", "HRCONVER.ERROR_FRAMES", "HRFOOT.BEST_GROUND_SAMPLING_DISTANCE", "DLRTO8.RADIANCE_SCALING_FACTOR", "DLRTO8.RADIANCE_OFFSET", "DLRTO8.REFLECTANCE_SCALING_FACTOR", "DLRTO8.REFLECTANCE_OFFSET", "HRCAL.RADIANCE_SCALING_FACTOR", "HRCAL.RADIANCE_OFFSET", "HRCAL.REFLECTANCE_SCALING_FACTOR", "HRCAL.REFLECTANCE_OFFSET", "HRORTHO.DTM_NAME", "HRORTHO.EXTORI_FILE_NAME", "HRORTHO.GEOMETRIC_CALIB_FILE_NAME", NULL }; for( i = 0; apszKeywords[i] != NULL; i++ ) { const char *pszKeywordValue = poDS->GetKeyword( apszKeywords[i], NULL ); if( pszKeywordValue != NULL ) poDS->SetMetadataItem( apszKeywords[i], pszKeywordValue ); } } } if (bIsDTM==TRUE && EQUAL( poDS->GetKeyword( "MAP.TARGET_NAME"), "MARS" )) { poDS->SetMetadataItem( "SPACECRAFT_NAME", "MARS_EXPRESS" ); poDS->SetMetadataItem( "PRODUCT_TYPE", "DTM"); static const char *apszKeywords[] = { "DTM.DTM_MISSING_DN", "DTM.DTM_OFFSET", "DTM.DTM_SCALING_FACTOR", "DTM.DTM_A_AXIS_RADIUS", "DTM.DTM_B_AXIS_RADIUS", "DTM.DTM_C_AXIS_RADIUS", "DTM.DTM_DESC", "DTM.DTM_MINIMUM_DN", "DTM.DTM_MAXIMUM_DN", NULL }; for( i = 0; apszKeywords[i] != NULL; i++ ) { const char *pszKeywordValue = poDS->GetKeyword( apszKeywords[i] ); if( pszKeywordValue != NULL ) poDS->SetMetadataItem( apszKeywords[i], pszKeywordValue ); } } /****************** DAWN ******************************/ else if (EQUAL( poDS->GetKeyword( "INSTRUMENT_ID"), "FC2" )) { poDS->SetMetadataItem( "SPACECRAFT_NAME", "DAWN" ); static const char *apszKeywords[] = {"ORBIT_NUMBER","FILTER_NUMBER", "FRONT_DOOR_STATUS", "FIRST_LINE", "FIRST_LINE_SAMPLE", "PRODUCER_INSTITUTION_NAME", "SOURCE_FILE_NAME", "PROCESSING_LEVEL_ID", "TARGET_NAME", "LIMB_IN_IMAGE", "POLE_IN_IMAGE", "REFLECTANCE_SCALING_FACTOR", "SPICE_FILE_NAME", "SPACECRAFT_CENTRIC_LATITUDE", "SPACECRAFT_EASTERN_LONGITUDE", "FOOTPRINT_POSITIVE_LONGITUDE", NULL }; for( i = 0; apszKeywords[i] != NULL; i++ ) { const char *pszKeywordValue = poDS->GetKeyword( apszKeywords[i] ); if( pszKeywordValue != NULL ) poDS->SetMetadataItem( apszKeywords[i], pszKeywordValue ); } } else if (bIsDTM==TRUE && EQUAL( poDS->GetKeyword( "TARGET_NAME"), "VESTA" )) { poDS->SetMetadataItem( "SPACECRAFT_NAME", "DAWN" ); poDS->SetMetadataItem( "PRODUCT_TYPE", "DTM"); static const char *apszKeywords[] = { "DTM_MISSING_DN", "DTM_OFFSET", "DTM_SCALING_FACTOR", "DTM_A_AXIS_RADIUS", "DTM_B_AXIS_RADIUS", "DTM_C_AXIS_RADIUS", "DTM_MINIMUM_DN", "DTM_MAXIMUM_DN", "MAP_PROJECTION_TYPE", "COORDINATE_SYSTEM_NAME", "POSITIVE_LONGITUDE_DIRECTION", "MAP_SCALE", "CENTER_LONGITUDE", "LINE_PROJECTION_OFFSET", "SAMPLE_PROJECTION_OFFSET", NULL }; for( i = 0; apszKeywords[i] != NULL; i++ ) { const char *pszKeywordValue = poDS->GetKeyword( apszKeywords[i] ); if( pszKeywordValue != NULL ) poDS->SetMetadataItem( apszKeywords[i], pszKeywordValue ); } } /* -------------------------------------------------------------------- */ /* END Instrument-specific keywords as metadata. */ /* -------------------------------------------------------------------- */ if (EQUAL(poDS->GetKeyword( "EOL"), "1" )) poDS->SetMetadataItem( "END-OF-DATASET_LABEL", "PRESENT" ); poDS->SetMetadataItem( "CONVERSION_DETAILS", "http://www.lpi.usra.edu/meetings/lpsc2014/pdf/1088.pdf" ); poDS->SetMetadataItem( "PIXEL-SHIFT-BUG", "CORRECTED" ); /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ poDS->TryLoadXML(); /* -------------------------------------------------------------------- */ /* Check for overviews. */ /* -------------------------------------------------------------------- */ poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename ); return( poDS ); }
VSIVirtualHandle * VSISparseFileFilesystemHandler::Open( const char *pszFilename, const char *pszAccess ) { CPLAssert( EQUALN(pszFilename,"/vsisparse/", 11) ); if( !EQUAL(pszAccess,"r") && !EQUAL(pszAccess,"rb") ) { errno = EACCES; return NULL; } /* Arbitrary number */ if( GetRecCounter() == 32 ) return NULL; CPLString osSparseFilePath = pszFilename + 11; /* -------------------------------------------------------------------- */ /* Does this file even exist? */ /* -------------------------------------------------------------------- */ VSILFILE *fp = VSIFOpenL( osSparseFilePath, "r" ); if( fp == NULL ) return NULL; VSIFCloseL( fp ); /* -------------------------------------------------------------------- */ /* Read the XML file. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psXMLRoot = CPLParseXMLFile( osSparseFilePath ); if( psXMLRoot == NULL ) return NULL; /* -------------------------------------------------------------------- */ /* Setup the file handle on this file. */ /* -------------------------------------------------------------------- */ VSISparseFileHandle *poHandle = new VSISparseFileHandle(this); /* -------------------------------------------------------------------- */ /* Translate the desired fields out of the XML tree. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psRegion; for( psRegion = psXMLRoot->psChild; psRegion != NULL; psRegion = psRegion->psNext ) { if( psRegion->eType != CXT_Element ) continue; if( !EQUAL(psRegion->pszValue,"SubfileRegion") && !EQUAL(psRegion->pszValue,"ConstantRegion") ) continue; SFRegion oRegion; oRegion.osFilename = CPLGetXMLValue( psRegion, "Filename", "" ); if( atoi(CPLGetXMLValue( psRegion, "Filename.relative", "0" )) != 0 ) { CPLString osSFPath = CPLGetPath(osSparseFilePath); oRegion.osFilename = CPLFormFilename( osSFPath, oRegion.osFilename, NULL ); } oRegion.nDstOffset = CPLScanUIntBig( CPLGetXMLValue(psRegion,"DestinationOffset","0" ), 32 ); oRegion.nSrcOffset = CPLScanUIntBig( CPLGetXMLValue(psRegion,"SourceOffset","0" ), 32); oRegion.nLength = CPLScanUIntBig( CPLGetXMLValue(psRegion,"RegionLength","0" ), 32); oRegion.byValue = (GByte) atoi(CPLGetXMLValue(psRegion,"Value","0" )); poHandle->aoRegions.push_back( oRegion ); } /* -------------------------------------------------------------------- */ /* Get sparse file length, use maximum bound of regions if not */ /* explicit in file. */ /* -------------------------------------------------------------------- */ poHandle->nOverallLength = CPLScanUIntBig( CPLGetXMLValue(psXMLRoot,"Length","0" ), 32); if( poHandle->nOverallLength == 0 ) { unsigned int i; for( i = 0; i < poHandle->aoRegions.size(); i++ ) { poHandle->nOverallLength = MAX(poHandle->nOverallLength, poHandle->aoRegions[i].nDstOffset + poHandle->aoRegions[i].nLength); } } CPLDestroyXMLNode( psXMLRoot ); return poHandle; }
GDALDataset *IntergraphDataset::Create( const char *pszFilename, int nXSize, int nYSize, int nBands, GDALDataType eType, char **papszOptions ) { int nDeviceResolution = 1; const char *pszValue; const char *pszCompression = NULL; pszValue = CSLFetchNameValue(papszOptions, "RESOLUTION"); if( pszValue != NULL ) nDeviceResolution = -atoi( pszValue ); char *pszExtension = CPLStrlwr(CPLStrdup(CPLGetExtension(pszFilename))); if ( EQUAL( pszExtension, "rle" ) ) pszCompression = INGR_GetFormatName(RunLengthEncoded); CPLFree(pszExtension); if( eType != GDT_Byte && eType != GDT_Int16 && eType != GDT_Int32 && eType != GDT_UInt16 && eType != GDT_UInt32 && eType != GDT_Float32&& eType != GDT_Float64 ) { CPLError( CE_Failure, CPLE_AppDefined, "Data type not supported (%s)", GDALGetDataTypeName( eType ) ); return NULL; } // -------------------------------------------------------------------- // Fill headers with minimun information // -------------------------------------------------------------------- INGR_HeaderOne hHdr1; INGR_HeaderTwoA hHdr2; INGR_ColorTable256 hCTab; int i; memset(&hHdr1, 0, SIZEOF_HDR1); memset(&hHdr2, 0, SIZEOF_HDR2_A); memset(&hCTab, 0, SIZEOF_CTAB); hHdr1.HeaderType.Version = INGR_HEADER_VERSION; hHdr1.HeaderType.Type = INGR_HEADER_TYPE; hHdr1.HeaderType.Is2Dor3D = INGR_HEADER_2D; hHdr1.DataTypeCode = (uint16) INGR_GetFormat( eType, (pszCompression!=NULL)?pszCompression:"None" ); hHdr1.WordsToFollow = ( ( SIZEOF_HDR1 * 3 ) / 2 ) - 2; hHdr1.ApplicationType = GenericRasterImageFile; hHdr1.XViewOrigin = 0.0; hHdr1.YViewOrigin = 0.0; hHdr1.ZViewOrigin = 0.0; hHdr1.XViewExtent = 0.0; hHdr1.YViewExtent = 0.0; hHdr1.ZViewExtent = 0.0; for( i = 0; i < 15; i++ ) hHdr1.TransformationMatrix[i] = 0.0; hHdr1.TransformationMatrix[15] = 1.0; hHdr1.PixelsPerLine = nXSize; hHdr1.NumberOfLines = nYSize; hHdr1.DeviceResolution = nDeviceResolution; hHdr1.ScanlineOrientation = UpperLeftHorizontal; hHdr1.ScannableFlag = NoLineHeader; hHdr1.RotationAngle = 0.0; hHdr1.SkewAngle = 0.0; hHdr1.DataTypeModifier = 0; hHdr1.DesignFileName[0] = '\0'; hHdr1.DataBaseFileName[0] = '\0'; hHdr1.ParentGridFileName[0] = '\0'; hHdr1.FileDescription[0] = '\0'; hHdr1.Minimum = INGR_SetMinMax( eType, 0.0 ); hHdr1.Maximum = INGR_SetMinMax( eType, 0.0 ); hHdr1.GridFileVersion = 3; hHdr1.Reserved[0] = 0; hHdr1.Reserved[1] = 0; hHdr1.Reserved[2] = 0; hHdr2.Gain = 0; hHdr2.OffsetThreshold = 0; hHdr2.View1 = 0; hHdr2.View2 = 0; hHdr2.ViewNumber = 0; hHdr2.Reserved2 = 0; hHdr2.Reserved3 = 0; hHdr2.AspectRatio = nXSize / nYSize; hHdr2.CatenatedFilePointer = 0; hHdr2.ColorTableType = NoColorTable; hHdr2.NumberOfCTEntries = 0; hHdr2.Reserved8 = 0; for( i = 0; i < 110; i++ ) hHdr2.Reserved[i] = 0; hHdr2.ApplicationPacketLength = 0; hHdr2.ApplicationPacketPointer = 0; // -------------------------------------------------------------------- // RGB Composite assumption // -------------------------------------------------------------------- if( eType == GDT_Byte && nBands == 3 ) { hHdr1.DataTypeCode = Uncompressed24bit; } // -------------------------------------------------------------------- // Create output file with minimum header info // -------------------------------------------------------------------- VSILFILE *fp = VSIFOpenL( pszFilename, "wb+" ); if( fp == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "Attempt to create file %s' failed.\n", pszFilename ); return NULL; } GByte abyBuf[MAX(SIZEOF_HDR1,SIZEOF_CTAB)]; INGR_HeaderOneMemToDisk( &hHdr1, abyBuf ); VSIFWriteL( abyBuf, 1, SIZEOF_HDR1, fp ); INGR_HeaderTwoAMemToDisk( &hHdr2, abyBuf ); VSIFWriteL( abyBuf, 1, SIZEOF_HDR2_A, fp ); unsigned int n = 0; for( i = 0; i < 256; i++ ) { STRC2BUF( abyBuf, n, hCTab.Entry[i].v_red ); STRC2BUF( abyBuf, n, hCTab.Entry[i].v_green ); STRC2BUF( abyBuf, n, hCTab.Entry[i].v_blue ); } VSIFWriteL( abyBuf, 1, SIZEOF_CTAB, fp ); VSIFCloseL( fp ); // -------------------------------------------------------------------- // Returns a new IntergraphDataset from the created file // -------------------------------------------------------------------- return ( IntergraphDataset * ) GDALOpen( pszFilename, GA_Update ); }
int ISIS2Dataset::WriteLabel( CPLString osFilename, CPLString osRasterFile, CPLString sObjectTag, unsigned int nXSize, unsigned int nYSize, unsigned int nBands, GDALDataType eType, GUIntBig iRecords, const char * pszInterleaving, GUIntBig &iLabelRecords, CPL_UNUSED bool bRelaunch) { CPLDebug("ISIS2", "Write Label filename = %s, rasterfile = %s",osFilename.c_str(),osRasterFile.c_str()); bool bAttachedLabel = EQUAL(osRasterFile, ""); VSILFILE *fpLabel = VSIFOpenL( osFilename, "w" ); if( fpLabel == NULL ){ CPLError( CE_Failure, CPLE_FileIO, "Failed to create %s:\n%s", osFilename.c_str(), VSIStrerror( errno ) ); return FALSE; } unsigned int iLevel(0); unsigned int nWritingBytes(0); /* write common header */ nWritingBytes += ISIS2Dataset::WriteKeyword( fpLabel, iLevel, "PDS_VERSION_ID", "PDS3" ); nWritingBytes += ISIS2Dataset::WriteFormatting( fpLabel, ""); nWritingBytes += ISIS2Dataset::WriteFormatting( fpLabel, "/* File identification and structure */"); nWritingBytes += ISIS2Dataset::WriteKeyword( fpLabel, iLevel, "RECORD_TYPE", "FIXED_LENGTH" ); nWritingBytes += ISIS2Dataset::WriteKeyword( fpLabel, iLevel, "RECORD_BYTES", CPLString().Printf("%d",RECORD_SIZE)); nWritingBytes += ISIS2Dataset::WriteKeyword( fpLabel, iLevel, "FILE_RECORDS", CPLString().Printf(CPL_FRMT_GUIB,iRecords)); nWritingBytes += ISIS2Dataset::WriteKeyword( fpLabel, iLevel, "LABEL_RECORDS", CPLString().Printf(CPL_FRMT_GUIB,iLabelRecords)); if(!bAttachedLabel){ nWritingBytes += ISIS2Dataset::WriteKeyword( fpLabel, iLevel, "FILE_NAME", CPLGetFilename(osRasterFile)); } nWritingBytes += ISIS2Dataset::WriteFormatting( fpLabel, ""); nWritingBytes += ISIS2Dataset::WriteFormatting( fpLabel, "/* Pointers to Data Objects */"); if(bAttachedLabel){ nWritingBytes += ISIS2Dataset::WriteKeyword( fpLabel, iLevel, CPLString().Printf("^%s",sObjectTag.c_str()), CPLString().Printf(CPL_FRMT_GUIB,iLabelRecords+1)); }else{ nWritingBytes += ISIS2Dataset::WriteKeyword( fpLabel, iLevel, CPLString().Printf("^%s",sObjectTag.c_str()), CPLString().Printf("(\"%s\",1)",CPLGetFilename(osRasterFile))); } if(EQUAL(sObjectTag, "QUBE")){ ISIS2Dataset::WriteQUBE_Information(fpLabel, iLevel, nWritingBytes, nXSize, nYSize, nBands, eType, pszInterleaving); } nWritingBytes += ISIS2Dataset::WriteFormatting( fpLabel, "END"); // check if file record is correct unsigned int q = nWritingBytes/RECORD_SIZE; if( q <= iLabelRecords){ // correct we add space after the label end for complete from iLabelRecords unsigned int nSpaceBytesToWrite = (unsigned int) (iLabelRecords * RECORD_SIZE - nWritingBytes); VSIFPrintfL(fpLabel,"%*c", nSpaceBytesToWrite, ' '); }else{ iLabelRecords = q+1; ISIS2Dataset::WriteLabel(osFilename, osRasterFile, sObjectTag, nXSize, nYSize, nBands, eType, iRecords, pszInterleaving, iLabelRecords); } VSIFCloseL( fpLabel ); return TRUE; }
GDALDataset *GSBGDataset::Create( const char * pszFilename, int nXSize, int nYSize, int nBands, GDALDataType eType, char **papszParmList ) { if( nXSize <= 0 || nYSize <= 0 ) { CPLError( CE_Failure, CPLE_IllegalArg, "Unable to create grid, both X and Y size must be " "non-negative.\n" ); return NULL; } else if( nXSize > SHRT_MAX || nYSize > SHRT_MAX ) { CPLError( CE_Failure, CPLE_IllegalArg, "Unable to create grid, Golden Software Binary Grid format " "only supports sizes up to %dx%d. %dx%d not supported.\n", SHRT_MAX, SHRT_MAX, nXSize, nYSize ); return NULL; } if( eType != GDT_Byte && eType != GDT_Float32 && eType != GDT_UInt16 && eType != GDT_Int16 ) { CPLError( CE_Failure, CPLE_AppDefined, "Golden Software ASCII Grid only supports Byte, Int16, " "Uint16, and Float32 datatypes. Unable to create with " "type %s.\n", GDALGetDataTypeName( eType ) ); return NULL; } VSILFILE *fp = VSIFOpenL( pszFilename, "w+b" ); if( fp == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "Attempt to create file '%s' failed.\n", pszFilename ); return NULL; } CPLErr eErr = WriteHeader( fp, (GInt16) nXSize, (GInt16) nYSize, 0.0, nXSize, 0.0, nYSize, 0.0, 0.0 ); if( eErr != CE_None ) { VSIFCloseL( fp ); return NULL; } float fVal = fNODATA_VALUE; CPL_LSBPTR32( &fVal ); for( int iRow = 0; iRow < nYSize; iRow++ ) { for( int iCol=0; iCol<nXSize; iCol++ ) { if( VSIFWriteL( (void *)&fVal, 4, 1, fp ) != 1 ) { VSIFCloseL( fp ); CPLError( CE_Failure, CPLE_FileIO, "Unable to write grid cell. Disk full?\n" ); return NULL; } } } VSIFCloseL( fp ); return (GDALDataset *)GDALOpen( pszFilename, GA_Update ); }
GDALDataset *GSBGDataset::CreateCopy( const char *pszFilename, GDALDataset *poSrcDS, int bStrict, char **papszOptions, GDALProgressFunc pfnProgress, void *pProgressData ) { if( pfnProgress == NULL ) pfnProgress = GDALDummyProgress; int nBands = poSrcDS->GetRasterCount(); if (nBands == 0) { CPLError( CE_Failure, CPLE_NotSupported, "GSBG driver does not support source dataset with zero band.\n"); return NULL; } else if (nBands > 1) { if( bStrict ) { CPLError( CE_Failure, CPLE_NotSupported, "Unable to create copy, Golden Software Binary Grid " "format only supports one raster band.\n" ); return NULL; } else CPLError( CE_Warning, CPLE_NotSupported, "Golden Software Binary Grid format only supports one " "raster band, first band will be copied.\n" ); } GDALRasterBand *poSrcBand = poSrcDS->GetRasterBand( 1 ); if( poSrcBand->GetXSize() > SHRT_MAX || poSrcBand->GetYSize() > SHRT_MAX ) { CPLError( CE_Failure, CPLE_IllegalArg, "Unable to create grid, Golden Software Binary Grid format " "only supports sizes up to %dx%d. %dx%d not supported.\n", SHRT_MAX, SHRT_MAX, poSrcBand->GetXSize(), poSrcBand->GetYSize() ); return NULL; } if( !pfnProgress( 0.0, NULL, pProgressData ) ) { CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated\n" ); return NULL; } VSILFILE *fp = VSIFOpenL( pszFilename, "w+b" ); if( fp == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "Attempt to create file '%s' failed.\n", pszFilename ); return NULL; } GInt16 nXSize = (GInt16) poSrcBand->GetXSize(); GInt16 nYSize = (GInt16) poSrcBand->GetYSize(); double adfGeoTransform[6]; poSrcDS->GetGeoTransform( adfGeoTransform ); double dfMinX = adfGeoTransform[0] + adfGeoTransform[1] / 2; double dfMaxX = adfGeoTransform[1] * (nXSize - 0.5) + adfGeoTransform[0]; double dfMinY = adfGeoTransform[5] * (nYSize - 0.5) + adfGeoTransform[3]; double dfMaxY = adfGeoTransform[3] + adfGeoTransform[5] / 2; CPLErr eErr = WriteHeader( fp, nXSize, nYSize, dfMinX, dfMaxX, dfMinY, dfMaxY, 0.0, 0.0 ); if( eErr != CE_None ) { VSIFCloseL( fp ); return NULL; } /* -------------------------------------------------------------------- */ /* Copy band data. */ /* -------------------------------------------------------------------- */ float *pfData = (float *)VSIMalloc2( nXSize, sizeof( float ) ); if( pfData == NULL ) { VSIFCloseL( fp ); CPLError( CE_Failure, CPLE_OutOfMemory, "Unable to create copy, unable to allocate line buffer.\n" ); return NULL; } int bSrcHasNDValue; float fSrcNoDataValue = (float) poSrcBand->GetNoDataValue( &bSrcHasNDValue ); double dfMinZ = DBL_MAX; double dfMaxZ = -DBL_MAX; for( GInt16 iRow = nYSize - 1; iRow >= 0; iRow-- ) { eErr = poSrcBand->RasterIO( GF_Read, 0, iRow, nXSize, 1, pfData, nXSize, 1, GDT_Float32, 0, 0 ); if( eErr != CE_None ) { VSIFCloseL( fp ); VSIFree( pfData ); return NULL; } for( int iCol=0; iCol<nXSize; iCol++ ) { if( bSrcHasNDValue && pfData[iCol] == fSrcNoDataValue ) { pfData[iCol] = fNODATA_VALUE; } else { if( pfData[iCol] > dfMaxZ ) dfMaxZ = pfData[iCol]; if( pfData[iCol] < dfMinZ ) dfMinZ = pfData[iCol]; } CPL_LSBPTR32( pfData+iCol ); } if( VSIFWriteL( (void *)pfData, 4, nXSize, fp ) != static_cast<unsigned>(nXSize) ) { VSIFCloseL( fp ); VSIFree( pfData ); CPLError( CE_Failure, CPLE_FileIO, "Unable to write grid row. Disk full?\n" ); return NULL; } if( !pfnProgress( static_cast<double>(iRow)/nYSize, NULL, pProgressData ) ) { VSIFCloseL( fp ); VSIFree( pfData ); CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated" ); return NULL; } } VSIFree( pfData ); /* write out the min and max values */ eErr = WriteHeader( fp, nXSize, nYSize, dfMinX, dfMaxX, dfMinY, dfMaxY, dfMinZ, dfMaxZ ); if( eErr != CE_None ) { VSIFCloseL( fp ); return NULL; } VSIFCloseL( fp ); GDALPamDataset *poDstDS = (GDALPamDataset *)GDALOpen( pszFilename, GA_Update ); if( poDstDS == NULL ) { VSIUnlink( pszFilename ); CPLError( CE_Failure, CPLE_FileIO, "Unable to open copy of dataset.\n" ); return NULL; } else if( dynamic_cast<GSBGDataset *>(poDstDS) == NULL ) { VSIUnlink( pszFilename ); delete poDstDS; CPLError( CE_Failure, CPLE_FileIO, "Copy dataset not opened as Golden Surfer Binary Grid!?\n" ); return NULL; } GDALRasterBand *poDstBand = poSrcDS->GetRasterBand(1); if( poDstBand == NULL ) { VSIUnlink( pszFilename ); delete poDstDS; CPLError( CE_Failure, CPLE_FileIO, "Unable to open copy of raster band?\n" ); return NULL; } /* -------------------------------------------------------------------- */ /* Attempt to copy metadata. */ /* -------------------------------------------------------------------- */ if( !bStrict ) CPLPushErrorHandler( CPLQuietErrorHandler ); /* non-zero transform 2 or 4 or negative 1 or 5 not supported natively */ /*if( adfGeoTransform[2] != 0.0 || adfGeoTransform[4] != 0.0 || adfGeoTransform[1] < 0.0 || adfGeoTransform[5] < 0.0 ) poDstDS->GDALPamDataset::SetGeoTransform( adfGeoTransform );*/ const char *szProjectionRef = poSrcDS->GetProjectionRef(); if( *szProjectionRef != '\0' ) poDstDS->SetProjection( szProjectionRef ); char **pszMetadata = poSrcDS->GetMetadata(); if( pszMetadata != NULL ) poDstDS->SetMetadata( pszMetadata ); /* FIXME: Should the dataset description be copied as well, or is it * always the file name? */ poDstBand->SetDescription( poSrcBand->GetDescription() ); int bSuccess; double dfOffset = poSrcBand->GetOffset( &bSuccess ); if( bSuccess && dfOffset != 0.0 ) poDstBand->SetOffset( dfOffset ); double dfScale = poSrcBand->GetScale( &bSuccess ); if( bSuccess && dfScale != 1.0 ) poDstBand->SetScale( dfScale ); GDALColorInterp oColorInterp = poSrcBand->GetColorInterpretation(); if( oColorInterp != GCI_Undefined ) poDstBand->SetColorInterpretation( oColorInterp ); char **pszCatNames = poSrcBand->GetCategoryNames(); if( pszCatNames != NULL) poDstBand->SetCategoryNames( pszCatNames ); GDALColorTable *poColorTable = poSrcBand->GetColorTable(); if( poColorTable != NULL ) poDstBand->SetColorTable( poColorTable ); if( !bStrict ) CPLPopErrorHandler(); return poDstDS; }
GDALOpenInfo::GDALOpenInfo( const char * pszFilenameIn, GDALAccess eAccessIn, char **papszSiblingsIn ) { /* -------------------------------------------------------------------- */ /* Ensure that C: is treated as C:\ so we can stat it on */ /* Windows. Similar to what is done in CPLStat(). */ /* -------------------------------------------------------------------- */ #ifdef WIN32 if( strlen(pszFilenameIn) == 2 && pszFilenameIn[1] == ':' ) { char szAltPath[10]; strcpy( szAltPath, pszFilenameIn ); strcat( szAltPath, "\\" ); pszFilename = CPLStrdup( szAltPath ); } else #endif pszFilename = CPLStrdup( pszFilenameIn ); /* -------------------------------------------------------------------- */ /* Initialize. */ /* -------------------------------------------------------------------- */ nHeaderBytes = 0; pabyHeader = NULL; bIsDirectory = FALSE; bStatOK = FALSE; eAccess = eAccessIn; fp = NULL; #ifdef HAVE_READLINK int bHasRetried = FALSE; #endif /* -------------------------------------------------------------------- */ /* Collect information about the file. */ /* -------------------------------------------------------------------- */ VSIStatBufL sStat; #ifdef HAVE_READLINK retry: #endif if( VSIStatExL( pszFilename, &sStat, VSI_STAT_EXISTS_FLAG | VSI_STAT_NATURE_FLAG ) == 0 ) { bStatOK = TRUE; if( VSI_ISREG( sStat.st_mode ) ) { pabyHeader = (GByte *) CPLCalloc(1025,1); fp = VSIFOpen( pszFilename, "rb" ); if( fp != NULL ) { nHeaderBytes = (int) VSIFRead( pabyHeader, 1, 1024, fp ); VSIRewind( fp ); } /* XXX: ENOENT is used to catch the case of virtual filesystem * when we do not have a real file with such a name. Under some * circumstances EINVAL reported instead of ENOENT in Windows * (for filenames containing colon, e.g. "smth://name"). * See also: #2437 */ else if( errno == 27 /* "File to large" */ || errno == ENOENT || errno == EINVAL #ifdef EOVERFLOW || errno == EOVERFLOW #else || errno == 75 /* Linux EOVERFLOW */ || errno == 79 /* Solaris EOVERFLOW */ #endif ) { VSILFILE* fpL = VSIFOpenL( pszFilename, "rb" ); if( fpL != NULL ) { nHeaderBytes = (int) VSIFReadL( pabyHeader, 1, 1024, fpL ); VSIFCloseL( fpL ); } } } else if( VSI_ISDIR( sStat.st_mode ) ) bIsDirectory = TRUE; } #ifdef HAVE_READLINK else if (!bHasRetried) { /* If someone creates a file with "ln -sf /vsicurl/http://download.osgeo.org/gdal/data/gtiff/utm.tif my_remote_utm.tif" */ /* we will be able to open it by passing my_remote_utm.tif */ /* This helps a lot for GDAL based readers that only provide file explorers to open datasets */ char szPointerFilename[2048]; int nBytes = readlink(pszFilename, szPointerFilename, sizeof(szPointerFilename)); if (nBytes != -1) { szPointerFilename[MIN(nBytes, (int)sizeof(szPointerFilename)-1)] = 0; CPLFree(pszFilename); pszFilename = CPLStrdup(szPointerFilename); papszSiblingsIn = NULL; bHasRetried = TRUE; goto retry; } } #endif /* -------------------------------------------------------------------- */ /* Capture sibling list either from passed in values, or by */ /* scanning for them. */ /* -------------------------------------------------------------------- */ if( papszSiblingsIn != NULL ) { papszSiblingFiles = CSLDuplicate( papszSiblingsIn ); } else if( bStatOK && !bIsDirectory ) { const char* pszOptionVal = CPLGetConfigOption( "GDAL_DISABLE_READDIR_ON_OPEN", "NO" ); if (EQUAL(pszOptionVal, "EMPTY_DIR")) { papszSiblingFiles = CSLAddString( NULL, CPLGetFilename(pszFilename) ); } else if( CSLTestBoolean(pszOptionVal) ) { /* skip reading the directory */ papszSiblingFiles = NULL; } else { CPLString osDir = CPLGetDirname( pszFilename ); papszSiblingFiles = VSIReadDir( osDir ); /* Small optimization to avoid unnecessary stat'ing from PAux or ENVI */ /* drivers. The MBTiles driver needs no companion file. */ if( papszSiblingFiles == NULL && strncmp(pszFilename, "/vsicurl/", 9) == 0 && EQUAL(CPLGetExtension( pszFilename ),"mbtiles") ) { papszSiblingFiles = CSLAddString( NULL, CPLGetFilename(pszFilename) ); } } } else papszSiblingFiles = NULL; }
GDALDataset *GSBGDataset::Open( GDALOpenInfo * poOpenInfo ) { /* Check for signature */ if( poOpenInfo->nHeaderBytes < 4 || !EQUALN((const char *) poOpenInfo->pabyHeader,"DSBB",4) ) { return NULL; } /* -------------------------------------------------------------------- */ /* Create a corresponding GDALDataset. */ /* -------------------------------------------------------------------- */ GSBGDataset *poDS = new GSBGDataset(); /* -------------------------------------------------------------------- */ /* 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. */ /* -------------------------------------------------------------------- */ if( VSIFSeekL( poDS->fp, 4, SEEK_SET ) != 0 ) { delete poDS; CPLError( CE_Failure, CPLE_FileIO, "Unable to seek to start of grid file header.\n" ); return NULL; } /* Parse number of X axis grid rows */ GInt16 nTemp; if( VSIFReadL( (void *)&nTemp, 2, 1, poDS->fp ) != 1 ) { delete poDS; CPLError( CE_Failure, CPLE_FileIO, "Unable to read raster X size.\n" ); return NULL; } poDS->nRasterXSize = CPL_LSBWORD16( nTemp ); if( VSIFReadL( (void *)&nTemp, 2, 1, poDS->fp ) != 1 ) { delete poDS; CPLError( CE_Failure, CPLE_FileIO, "Unable to read raster Y size.\n" ); return NULL; } poDS->nRasterYSize = CPL_LSBWORD16( nTemp ); if (!GDALCheckDatasetDimensions(poDS->nRasterXSize, poDS->nRasterYSize)) { delete poDS; return NULL; } /* -------------------------------------------------------------------- */ /* Create band information objects. */ /* -------------------------------------------------------------------- */ GSBGRasterBand *poBand = new GSBGRasterBand( poDS, 1 ); double dfTemp; if( VSIFReadL( (void *)&dfTemp, 8, 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; if( VSIFReadL( (void *)&dfTemp, 8, 1, poDS->fp ) != 1 ) { delete poDS; CPLError( CE_Failure, CPLE_FileIO, "Unable to read maximum X value.\n" ); return NULL; } CPL_LSBPTR64( &dfTemp ); poBand->dfMaxX = dfTemp; if( VSIFReadL( (void *)&dfTemp, 8, 1, poDS->fp ) != 1 ) { delete poDS; CPLError( CE_Failure, CPLE_FileIO, "Unable to read minimum Y value.\n" ); return NULL; } CPL_LSBPTR64( &dfTemp ); poBand->dfMinY = dfTemp; if( VSIFReadL( (void *)&dfTemp, 8, 1, poDS->fp ) != 1 ) { delete poDS; CPLError( CE_Failure, CPLE_FileIO, "Unable to read maximum Y value.\n" ); return NULL; } CPL_LSBPTR64( &dfTemp ); poBand->dfMaxY = dfTemp; if( VSIFReadL( (void *)&dfTemp, 8, 1, poDS->fp ) != 1 ) { delete poDS; CPLError( CE_Failure, CPLE_FileIO, "Unable to read minimum Z value.\n" ); return NULL; } CPL_LSBPTR64( &dfTemp ); poBand->dfMinZ = dfTemp; if( VSIFReadL( (void *)&dfTemp, 8, 1, poDS->fp ) != 1 ) { delete poDS; CPLError( CE_Failure, CPLE_FileIO, "Unable to read maximum Z value.\n" ); return NULL; } CPL_LSBPTR64( &dfTemp ); poBand->dfMaxZ = dfTemp; poDS->SetBand( 1, poBand ); /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ poDS->SetDescription( poOpenInfo->pszFilename ); poDS->TryLoadXML(); /* -------------------------------------------------------------------- */ /* Check for external overviews. */ /* -------------------------------------------------------------------- */ poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename, poOpenInfo->papszSiblingFiles ); return poDS; }
int TigerFileBase::SetWriteModule( const char *pszExtension, CPL_UNUSED int nRecLen, OGRFeature *poFeature ) { /* -------------------------------------------------------------------- */ /* Work out what module we should be writing to. */ /* -------------------------------------------------------------------- */ const char *pszTargetModule = poFeature->GetFieldAsString( "MODULE" ); char szFullModule[30]; /* TODO/notdef: eventually more logic based on FILE and STATE/COUNTY can be inserted here. */ if( pszTargetModule == NULL ) return FALSE; sprintf( szFullModule, "%s.RT", pszTargetModule ); /* -------------------------------------------------------------------- */ /* Is this our current module? */ /* -------------------------------------------------------------------- */ if( pszModule != NULL && EQUAL(szFullModule,pszModule) ) return TRUE; /* -------------------------------------------------------------------- */ /* Cleanup the previous file, if any. */ /* -------------------------------------------------------------------- */ if( fpPrimary != NULL ) { VSIFCloseL( fpPrimary ); fpPrimary = NULL; } if( pszModule != NULL ) { CPLFree( pszModule ); pszModule = NULL; } /* -------------------------------------------------------------------- */ /* Is this a module we have never written to before? If so, we */ /* will try to blow away any existing files in this file set. */ /* -------------------------------------------------------------------- */ if( !poDS->CheckModule( szFullModule ) ) { poDS->DeleteModuleFiles( szFullModule ); poDS->AddModule( szFullModule ); } /* -------------------------------------------------------------------- */ /* Does this file already exist? */ /* -------------------------------------------------------------------- */ char *pszFilename; pszFilename = poDS->BuildFilename( szFullModule, pszExtension ); fpPrimary = VSIFOpenL( pszFilename, "ab" ); CPLFree(pszFilename); if( fpPrimary == NULL ) return FALSE; pszModule = CPLStrdup( szFullModule ); return TRUE; }
bool GTM::isValid() { // 2 bytes - version number // 10 bytes - "TrackMaker" string char buffer[13]; char* szHeader; short version; /* -------------------------------------------------------------------- */ /* If we aren't sure it is GTM, load a header chunk and check */ /* for signs it is GTM */ /* -------------------------------------------------------------------- */ size_t nRead = VSIFReadL( buffer, 1, sizeof(buffer)-1, pGTMFile ); if (nRead <= 0) { VSIFCloseL( pGTMFile ); pGTMFile = NULL; return FALSE; } buffer[12] = '\0'; /* -------------------------------------------------------------------- */ /* If it looks like a GZip header, this may be a .gtz file, so */ /* try opening with the /vsigzip/ prefix */ /* -------------------------------------------------------------------- */ if (buffer[0] == 0x1f && ((unsigned char*)buffer)[1] == 0x8b && strncmp(pszFilename, "/vsigzip/", strlen("/vsigzip/")) != 0) { char* pszGZIPFileName = (char*)CPLMalloc( strlen("/vsigzip/") + strlen(pszFilename) + 1); sprintf(pszGZIPFileName, "/vsigzip/%s", pszFilename); FILE* fp = VSIFOpenL(pszGZIPFileName, "rb"); if (fp) { FILE* pGTMFileOri = pGTMFile; pGTMFile = fp; if (isValid()) { VSIFCloseL(pGTMFileOri); return TRUE; } else { if (pGTMFile) VSIFCloseL(pGTMFile); pGTMFile = pGTMFileOri; } } CPLFree(pszGZIPFileName); } version = CPL_LSBINT16PTR(buffer); /*Skip string length */ szHeader = buffer + 2; if (version == 211 && strcmp(szHeader, "TrackMaker") == 0 ) { return TRUE; } return FALSE; }
static GDALDataset * EpsilonDatasetCreateCopy( const char * pszFilename, GDALDataset *poSrcDS, CPL_UNUSED int bStrict, char ** papszOptions, GDALProgressFunc pfnProgress, void * pProgressData ) { int nBands = poSrcDS->GetRasterCount(); if ((nBands != 1 && nBands != 3) || (nBands > 0 && poSrcDS->GetRasterBand(1)->GetColorTable() != NULL)) { CPLError(CE_Failure, CPLE_NotSupported, "The EPSILON driver only supports 1 band (grayscale) " "or 3 band (RGB) data"); return NULL; } /* -------------------------------------------------------------------- */ /* Fetch and check creation options */ /* -------------------------------------------------------------------- */ int nBlockXSize = atoi(CSLFetchNameValueDef(papszOptions, "BLOCKXSIZE", "256")); int nBlockYSize = atoi(CSLFetchNameValueDef(papszOptions, "BLOCKYSIZE", "256")); if ((nBlockXSize != 32 && nBlockXSize != 64 && nBlockXSize != 128 && nBlockXSize != 256 && nBlockXSize != 512 && nBlockXSize != 1024) || (nBlockYSize != 32 && nBlockYSize != 64 && nBlockYSize != 128 && nBlockYSize != 256 && nBlockYSize != 512 && nBlockYSize != 1024)) { CPLError(CE_Failure, CPLE_NotSupported, "Block size must be a power of 2 between 32 et 1024"); return NULL; } const char* pszFilter = CSLFetchNameValueDef(papszOptions, "FILTER", "daub97lift"); char** papszFBID = eps_get_fb_info(EPS_FB_ID); char** papszFBIDIter = papszFBID; int bFound = FALSE; int nIndexFB = 0; while(papszFBIDIter && *papszFBIDIter && !bFound) { if (strcmp(*papszFBIDIter, pszFilter) == 0) bFound = TRUE; else nIndexFB ++; papszFBIDIter ++; } eps_free_fb_info(papszFBID); if (!bFound) { CPLError(CE_Failure, CPLE_NotSupported, "FILTER='%s' not supported", pszFilter); return NULL; } int eMode = EPS_MODE_OTLPF; const char* pszMode = CSLFetchNameValueDef(papszOptions, "MODE", "OTLPF"); if (EQUAL(pszMode, "NORMAL")) eMode = EPS_MODE_NORMAL; else if (EQUAL(pszMode, "OTLPF")) eMode = EPS_MODE_OTLPF; else { CPLError(CE_Failure, CPLE_NotSupported, "MODE='%s' not supported", pszMode); return NULL; } char** papszFBType = eps_get_fb_info(EPS_FB_TYPE); int bIsBiOrthogonal = EQUAL(papszFBType[nIndexFB], "biorthogonal"); eps_free_fb_info(papszFBType); if (eMode == EPS_MODE_OTLPF && !bIsBiOrthogonal) { CPLError(CE_Failure, CPLE_NotSupported, "MODE=OTLPF can only be used with biorthogonal filters. " "Use MODE=NORMAL instead"); return NULL; } int bRasterliteOutput = CPLTestBool(CSLFetchNameValueDef(papszOptions, "RASTERLITE_OUTPUT", "NO")); int nYRatio = EPS_Y_RT; int nCbRatio = EPS_Cb_RT; int nCrRatio = EPS_Cr_RT; int eResample; if (CPLTestBool(CSLFetchNameValueDef(papszOptions, "RGB_RESAMPLE", "YES"))) eResample = EPS_RESAMPLE_420; else eResample = EPS_RESAMPLE_444; const char* pszTarget = CSLFetchNameValueDef(papszOptions, "TARGET", "96"); double dfReductionFactor = 1 - CPLAtof(pszTarget) / 100; if (dfReductionFactor > 1) dfReductionFactor = 1; else if (dfReductionFactor < 0) dfReductionFactor = 0; /* -------------------------------------------------------------------- */ /* Open file */ /* -------------------------------------------------------------------- */ VSILFILE* fp = VSIFOpenL(pszFilename, "wb"); if (fp == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot create %s", pszFilename); return NULL; } /* -------------------------------------------------------------------- */ /* Compute number of blocks, block size, etc... */ /* -------------------------------------------------------------------- */ int nXSize = poSrcDS->GetRasterXSize(); int nYSize = poSrcDS->GetRasterYSize(); if (eMode == EPS_MODE_OTLPF) { nBlockXSize ++; nBlockYSize ++; } int nXBlocks = (nXSize + nBlockXSize - 1) / nBlockXSize; int nYBlocks = (nYSize + nBlockYSize - 1) / nBlockYSize; int nBlocks = nXBlocks * nYBlocks; int nUncompressedFileSize = nXSize * nYSize * nBands; int nUncompressedBlockSize = nUncompressedFileSize / nBlocks; int nTargetBlockSize = (int) (dfReductionFactor * nUncompressedBlockSize); if (nBands == 1) nTargetBlockSize = MAX (nTargetBlockSize, EPS_MIN_GRAYSCALE_BUF + 1); else nTargetBlockSize = MAX (nTargetBlockSize, EPS_MIN_TRUECOLOR_BUF + 1); /* -------------------------------------------------------------------- */ /* Allocate work buffers */ /* -------------------------------------------------------------------- */ GByte* pabyBuffer = (GByte*)VSIMalloc3(nBlockXSize, nBlockYSize, nBands); if (pabyBuffer == NULL) { VSIFCloseL(fp); return NULL; } GByte* pabyOutBuf = (GByte*)VSIMalloc(nTargetBlockSize); if (pabyOutBuf == NULL) { VSIFree(pabyBuffer); VSIFCloseL(fp); return NULL; } GByte** apapbyRawBuffer[3]; int i, j; for(i=0;i<nBands;i++) { apapbyRawBuffer[i] = (GByte**) VSIMalloc(sizeof(GByte*) * nBlockYSize); for(j=0;j<nBlockYSize;j++) { apapbyRawBuffer[i][j] = pabyBuffer + (i * nBlockXSize + j) * nBlockYSize; } } if (bRasterliteOutput) { const char* pszHeader = RASTERLITE_WAVELET_HEADER; VSIFWriteL(pszHeader, 1, strlen(pszHeader) + 1, fp); } /* -------------------------------------------------------------------- */ /* Iterate over blocks */ /* -------------------------------------------------------------------- */ int nBlockXOff, nBlockYOff; CPLErr eErr = CE_None; for(nBlockYOff = 0; eErr == CE_None && nBlockYOff < nYBlocks; nBlockYOff ++) { for(nBlockXOff = 0; eErr == CE_None && nBlockXOff < nXBlocks; nBlockXOff ++) { int bMustMemset = FALSE; int nReqXSize = nBlockXSize, nReqYSize = nBlockYSize; if ((nBlockXOff+1) * nBlockXSize > nXSize) { bMustMemset = TRUE; nReqXSize = nXSize - nBlockXOff * nBlockXSize; } if ((nBlockYOff+1) * nBlockYSize > nYSize) { bMustMemset = TRUE; nReqYSize = nYSize - nBlockYOff * nBlockYSize; } if (bMustMemset) memset(pabyBuffer, 0, nBands * nBlockXSize * nBlockYSize); eErr = poSrcDS->RasterIO(GF_Read, nBlockXOff * nBlockXSize, nBlockYOff * nBlockYSize, nReqXSize, nReqYSize, pabyBuffer, nReqXSize, nReqYSize, GDT_Byte, nBands, NULL, 1, nBlockXSize, nBlockXSize * nBlockYSize, NULL); int nOutBufSize = nTargetBlockSize; if (eErr == CE_None && nBands == 1) { if (EPS_OK != eps_encode_grayscale_block(apapbyRawBuffer[0], nXSize, nYSize, nReqXSize, nReqYSize, nBlockXOff * nBlockXSize, nBlockYOff * nBlockYSize, pabyOutBuf, &nOutBufSize, (char*) pszFilter, eMode)) { CPLError( CE_Failure, CPLE_AppDefined, "Error occurred when encoding block (%d, %d)", nBlockXOff, nBlockYOff); eErr = CE_Failure; } } else if (eErr == CE_None) { if (EPS_OK != eps_encode_truecolor_block( apapbyRawBuffer[0], apapbyRawBuffer[1], apapbyRawBuffer[2], nXSize, nYSize, nReqXSize, nReqYSize, nBlockXOff * nBlockXSize, nBlockYOff * nBlockYSize, eResample, pabyOutBuf, &nOutBufSize, nYRatio, nCbRatio, nCrRatio, (char*) pszFilter, eMode)) { CPLError(CE_Failure, CPLE_AppDefined, "Error occurred when encoding block (%d, %d)", nBlockXOff, nBlockYOff); eErr = CE_Failure; } } if (eErr == CE_None) { if ((int)VSIFWriteL(pabyOutBuf, 1, nOutBufSize, fp) != nOutBufSize) eErr = CE_Failure; char chEPSMarker = EPS_MARKER; VSIFWriteL(&chEPSMarker, 1, 1, fp); if (pfnProgress && !pfnProgress( 1.0 * (nBlockYOff * nXBlocks + nBlockXOff + 1) / nBlocks, NULL, pProgressData)) { eErr = CE_Failure; } } } } if (bRasterliteOutput) { const char* pszFooter = RASTERLITE_WAVELET_FOOTER; VSIFWriteL(pszFooter, 1, strlen(pszFooter) + 1, fp); } /* -------------------------------------------------------------------- */ /* Cleanup work buffers */ /* -------------------------------------------------------------------- */ for(i=0;i<nBands;i++) { VSIFree(apapbyRawBuffer[i]); } VSIFree(pabyOutBuf); VSIFree(pabyBuffer); VSIFCloseL(fp); if (eErr != CE_None) return NULL; /* -------------------------------------------------------------------- */ /* Reopen the dataset, unless asked for not (Rasterlite optim) */ /* -------------------------------------------------------------------- */ return (GDALDataset*) GDALOpen(pszFilename, GA_ReadOnly); }
int msSaveImageGDAL( mapObj *map, imageObj *image, char *filename ) { int bFileIsTemporary = MS_FALSE; GDALDatasetH hMemDS, hOutputDS; GDALDriverH hMemDriver, hOutputDriver; int nBands = 1; int iLine; GByte *pabyAlphaLine = NULL; char **papszOptions = NULL; outputFormatObj *format = image->format; rasterBufferObj rb; GDALDataType eDataType = GDT_Byte; int bUseXmp = MS_FALSE; msGDALInitialize(); memset(&rb,0,sizeof(rasterBufferObj)); #ifdef USE_EXEMPI bUseXmp = msXmpPresent(map); #endif /* -------------------------------------------------------------------- */ /* Identify the proposed output driver. */ /* -------------------------------------------------------------------- */ msAcquireLock( TLOCK_GDAL ); hOutputDriver = GDALGetDriverByName( format->driver+5 ); if( hOutputDriver == NULL ) { msReleaseLock( TLOCK_GDAL ); msSetError( MS_MISCERR, "Failed to find %s driver.", "msSaveImageGDAL()", format->driver+5 ); return MS_FAILURE; } /* -------------------------------------------------------------------- */ /* We will need to write the output to a temporary file and */ /* then stream to stdout if no filename is passed. If the */ /* driver supports virtualio then we hold the temporary file in */ /* memory, otherwise we try to put it in a reasonable temporary */ /* file location. */ /* -------------------------------------------------------------------- */ if( filename == NULL ) { const char *pszExtension = format->extension; if( pszExtension == NULL ) pszExtension = "img.tmp"; if( bUseXmp == MS_FALSE && GDALGetMetadataItem( hOutputDriver, GDAL_DCAP_VIRTUALIO, NULL ) != NULL ) { CleanVSIDir( "/vsimem/msout" ); filename = msTmpFile(map, NULL, "/vsimem/msout/", pszExtension ); } if( filename == NULL && map != NULL) filename = msTmpFile(map, map->mappath,NULL,pszExtension); else if( filename == NULL ) { filename = msTmpFile(map, NULL, NULL, pszExtension ); } bFileIsTemporary = MS_TRUE; } /* -------------------------------------------------------------------- */ /* Establish the characteristics of our memory, and final */ /* dataset. */ /* -------------------------------------------------------------------- */ if( format->imagemode == MS_IMAGEMODE_RGB ) { nBands = 3; assert( MS_RENDERER_PLUGIN(format) && format->vtable->supports_pixel_buffer ); format->vtable->getRasterBufferHandle(image,&rb); } else if( format->imagemode == MS_IMAGEMODE_RGBA ) { pabyAlphaLine = (GByte *) calloc(image->width,1); if (pabyAlphaLine == NULL) { msReleaseLock( TLOCK_GDAL ); msSetError( MS_MEMERR, "Out of memory allocating %u bytes.\n", "msSaveImageGDAL()", image->width); return MS_FAILURE; } nBands = 4; assert( MS_RENDERER_PLUGIN(format) && format->vtable->supports_pixel_buffer ); format->vtable->getRasterBufferHandle(image,&rb); } else if( format->imagemode == MS_IMAGEMODE_INT16 ) { nBands = format->bands; eDataType = GDT_Int16; } else if( format->imagemode == MS_IMAGEMODE_FLOAT32 ) { nBands = format->bands; eDataType = GDT_Float32; } else if( format->imagemode == MS_IMAGEMODE_BYTE ) { nBands = format->bands; eDataType = GDT_Byte; } else { #ifdef USE_GD assert( format->imagemode == MS_IMAGEMODE_PC256 && format->renderer == MS_RENDER_WITH_GD ); #else { msReleaseLock( TLOCK_GDAL ); msSetError( MS_MEMERR, "GD not compiled in. This is a bug.", "msSaveImageGDAL()"); return MS_FAILURE; } #endif } /* -------------------------------------------------------------------- */ /* Create a memory dataset which we can use as a source for a */ /* CreateCopy(). */ /* -------------------------------------------------------------------- */ hMemDriver = GDALGetDriverByName( "MEM" ); if( hMemDriver == NULL ) { msReleaseLock( TLOCK_GDAL ); msSetError( MS_MISCERR, "Failed to find MEM driver.", "msSaveImageGDAL()" ); return MS_FAILURE; } hMemDS = GDALCreate( hMemDriver, "msSaveImageGDAL_temp", image->width, image->height, nBands, eDataType, NULL ); if( hMemDS == NULL ) { msReleaseLock( TLOCK_GDAL ); msSetError( MS_MISCERR, "Failed to create MEM dataset.", "msSaveImageGDAL()" ); return MS_FAILURE; } /* -------------------------------------------------------------------- */ /* Copy the gd image into the memory dataset. */ /* -------------------------------------------------------------------- */ for( iLine = 0; iLine < image->height; iLine++ ) { int iBand; for( iBand = 0; iBand < nBands; iBand++ ) { GDALRasterBandH hBand = GDALGetRasterBand( hMemDS, iBand+1 ); if( format->imagemode == MS_IMAGEMODE_INT16 ) { GDALRasterIO( hBand, GF_Write, 0, iLine, image->width, 1, image->img.raw_16bit + iLine * image->width + iBand * image->width * image->height, image->width, 1, GDT_Int16, 2, 0 ); } else if( format->imagemode == MS_IMAGEMODE_FLOAT32 ) { GDALRasterIO( hBand, GF_Write, 0, iLine, image->width, 1, image->img.raw_float + iLine * image->width + iBand * image->width * image->height, image->width, 1, GDT_Float32, 4, 0 ); } else if( format->imagemode == MS_IMAGEMODE_BYTE ) { GDALRasterIO( hBand, GF_Write, 0, iLine, image->width, 1, image->img.raw_byte + iLine * image->width + iBand * image->width * image->height, image->width, 1, GDT_Byte, 1, 0 ); } #ifdef USE_GD else if(format->renderer == MS_RENDER_WITH_GD) { gdImagePtr img = (gdImagePtr)image->img.plugin; GDALRasterIO( hBand, GF_Write, 0, iLine, image->width, 1, img->pixels[iLine], image->width, 1, GDT_Byte, 0, 0 ); } #endif else { GByte *pabyData; unsigned char *pixptr = NULL; assert( rb.type == MS_BUFFER_BYTE_RGBA ); switch(iBand) { case 0: pixptr = rb.data.rgba.r; break; case 1: pixptr = rb.data.rgba.g; break; case 2: pixptr = rb.data.rgba.b; break; case 3: pixptr = rb.data.rgba.a; break; } assert(pixptr); if( pixptr == NULL ) { msReleaseLock( TLOCK_GDAL ); msSetError( MS_MISCERR, "Missing RGB or A buffer.\n", "msSaveImageGDAL()" ); return MS_FAILURE; } pabyData = (GByte *)(pixptr + iLine*rb.data.rgba.row_step); if( rb.data.rgba.a == NULL || iBand == 3 ) { GDALRasterIO( hBand, GF_Write, 0, iLine, image->width, 1, pabyData, image->width, 1, GDT_Byte, rb.data.rgba.pixel_step, 0 ); } else { /* We need to un-pre-multiple RGB by alpha. */ GByte *pabyUPM = (GByte*) malloc(image->width); GByte *pabyAlpha= (GByte *)(rb.data.rgba.a + iLine*rb.data.rgba.row_step); int i; for( i = 0; i < image->width; i++ ) { int alpha = pabyAlpha[i*rb.data.rgba.pixel_step]; if( alpha == 0 ) pabyUPM[i] = 0; else { int result = (pabyData[i*rb.data.rgba.pixel_step] * 255) / alpha; if( result > 255 ) result = 255; pabyUPM[i] = result; } } GDALRasterIO( hBand, GF_Write, 0, iLine, image->width, 1, pabyUPM, image->width, 1, GDT_Byte, 1, 0 ); free( pabyUPM ); } } } } if( pabyAlphaLine != NULL ) free( pabyAlphaLine ); /* -------------------------------------------------------------------- */ /* Attach the palette if appropriate. */ /* -------------------------------------------------------------------- */ #ifdef USE_GD if( format->renderer == MS_RENDER_WITH_GD ) { GDALColorEntry sEntry; int iColor; GDALColorTableH hCT; gdImagePtr img = (gdImagePtr)image->img.plugin; hCT = GDALCreateColorTable( GPI_RGB ); for( iColor = 0; iColor < img->colorsTotal; iColor++ ) { sEntry.c1 = img->red[iColor]; sEntry.c2 = img->green[iColor]; sEntry.c3 = img->blue[iColor]; if( iColor == gdImageGetTransparent( img ) ) sEntry.c4 = 0; else if( iColor == 0 && gdImageGetTransparent( img ) == -1 && format->transparent ) sEntry.c4 = 0; else sEntry.c4 = 255; GDALSetColorEntry( hCT, iColor, &sEntry ); } GDALSetRasterColorTable( GDALGetRasterBand( hMemDS, 1 ), hCT ); GDALDestroyColorTable( hCT ); } else #endif if( format->imagemode == MS_IMAGEMODE_RGB ) { GDALSetRasterColorInterpretation( GDALGetRasterBand( hMemDS, 1 ), GCI_RedBand ); GDALSetRasterColorInterpretation( GDALGetRasterBand( hMemDS, 2 ), GCI_GreenBand ); GDALSetRasterColorInterpretation( GDALGetRasterBand( hMemDS, 3 ), GCI_BlueBand ); } else if( format->imagemode == MS_IMAGEMODE_RGBA ) { GDALSetRasterColorInterpretation( GDALGetRasterBand( hMemDS, 1 ), GCI_RedBand ); GDALSetRasterColorInterpretation( GDALGetRasterBand( hMemDS, 2 ), GCI_GreenBand ); GDALSetRasterColorInterpretation( GDALGetRasterBand( hMemDS, 3 ), GCI_BlueBand ); GDALSetRasterColorInterpretation( GDALGetRasterBand( hMemDS, 4 ), GCI_AlphaBand ); } /* -------------------------------------------------------------------- */ /* Assign the projection and coordinate system to the memory */ /* dataset. */ /* -------------------------------------------------------------------- */ if( map != NULL ) { char *pszWKT; GDALSetGeoTransform( hMemDS, map->gt.geotransform ); pszWKT = msProjectionObj2OGCWKT( &(map->projection) ); if( pszWKT != NULL ) { GDALSetProjection( hMemDS, pszWKT ); msFree( pszWKT ); } } /* -------------------------------------------------------------------- */ /* Possibly assign a nodata value. */ /* -------------------------------------------------------------------- */ if( msGetOutputFormatOption(format,"NULLVALUE",NULL) != NULL ) { int iBand; const char *nullvalue = msGetOutputFormatOption(format, "NULLVALUE",NULL); for( iBand = 0; iBand < nBands; iBand++ ) { GDALRasterBandH hBand = GDALGetRasterBand( hMemDS, iBand+1 ); GDALSetRasterNoDataValue( hBand, atof(nullvalue) ); } } /* -------------------------------------------------------------------- */ /* Try to save resolution in the output file. */ /* -------------------------------------------------------------------- */ if( image->resolution > 0 ) { char res[30]; sprintf( res, "%lf", image->resolution ); GDALSetMetadataItem( hMemDS, "TIFFTAG_XRESOLUTION", res, NULL ); GDALSetMetadataItem( hMemDS, "TIFFTAG_YRESOLUTION", res, NULL ); GDALSetMetadataItem( hMemDS, "TIFFTAG_RESOLUTIONUNIT", "2", NULL ); } /* -------------------------------------------------------------------- */ /* Create a disk image in the selected output format from the */ /* memory image. */ /* -------------------------------------------------------------------- */ papszOptions = (char**)calloc(sizeof(char *),(format->numformatoptions+1)); if (papszOptions == NULL) { msReleaseLock( TLOCK_GDAL ); msSetError( MS_MEMERR, "Out of memory allocating %u bytes.\n", "msSaveImageGDAL()", (unsigned int)(sizeof(char *)*(format->numformatoptions+1))); return MS_FAILURE; } memcpy( papszOptions, format->formatoptions, sizeof(char *) * format->numformatoptions ); hOutputDS = GDALCreateCopy( hOutputDriver, filename, hMemDS, FALSE, papszOptions, NULL, NULL ); free( papszOptions ); if( hOutputDS == NULL ) { GDALClose( hMemDS ); msReleaseLock( TLOCK_GDAL ); msSetError( MS_MISCERR, "Failed to create output %s file.\n%s", "msSaveImageGDAL()", format->driver+5, CPLGetLastErrorMsg() ); return MS_FAILURE; } /* closing the memory DS also frees all associated resources. */ GDALClose( hMemDS ); GDALClose( hOutputDS ); msReleaseLock( TLOCK_GDAL ); /* -------------------------------------------------------------------- */ /* Are we writing license info into the image? */ /* If so, add it to the temp file on disk now. */ /* -------------------------------------------------------------------- */ #ifdef USE_EXEMPI if ( bUseXmp == MS_TRUE ) { if( msXmpWrite(map, filename) == MS_FAILURE ) { /* Something bad happened. */ msSetError( MS_MISCERR, "XMP write to %s failed.\n%s", "msSaveImageGDAL()", filename); return MS_FAILURE; } } #endif /* -------------------------------------------------------------------- */ /* Is this supposed to be a temporary file? If so, stream to */ /* stdout and delete the file. */ /* -------------------------------------------------------------------- */ if( bFileIsTemporary ) { FILE *fp; unsigned char block[4000]; int bytes_read; if( msIO_needBinaryStdout() == MS_FAILURE ) return MS_FAILURE; /* We aren't sure how far back GDAL exports the VSI*L API, so we only use it if we suspect we need it. But we do need it if holding temporary file in memory. */ fp = VSIFOpenL( filename, "rb" ); if( fp == NULL ) { msSetError( MS_MISCERR, "Failed to open %s for streaming to stdout.", "msSaveImageGDAL()", filename ); return MS_FAILURE; } while( (bytes_read = VSIFReadL(block, 1, sizeof(block), fp)) > 0 ) msIO_fwrite( block, 1, bytes_read, stdout ); VSIFCloseL( fp ); VSIUnlink( filename ); CleanVSIDir( "/vsimem/msout" ); free( filename ); } return MS_SUCCESS; }
GDALDataset *LANDataset::Open( GDALOpenInfo * poOpenInfo ) { /* -------------------------------------------------------------------- */ /* We assume the user is pointing to the header (.pcb) file. */ /* Does this appear to be a pcb file? */ /* -------------------------------------------------------------------- */ if( poOpenInfo->nHeaderBytes < ERD_HEADER_SIZE || poOpenInfo->fp == NULL ) return NULL; if( !EQUALN((const char *)poOpenInfo->pabyHeader,"HEADER",6) && !EQUALN((const char *)poOpenInfo->pabyHeader,"HEAD74",6) ) return NULL; /* -------------------------------------------------------------------- */ /* Create a corresponding GDALDataset. */ /* -------------------------------------------------------------------- */ LANDataset *poDS; poDS = new LANDataset(); poDS->eAccess = poOpenInfo->eAccess; /* -------------------------------------------------------------------- */ /* Adopt the openinfo file pointer for use with this file. */ /* -------------------------------------------------------------------- */ if( poOpenInfo->eAccess == GA_ReadOnly ) poDS->fpImage = VSIFOpenL( poOpenInfo->pszFilename, "rb" ); else poDS->fpImage = VSIFOpenL( poOpenInfo->pszFilename, "rb+" ); if( poDS->fpImage == NULL ) return NULL; /* -------------------------------------------------------------------- */ /* Do we need to byte swap the headers to local machine order? */ /* -------------------------------------------------------------------- */ int bBigEndian = poOpenInfo->pabyHeader[8] == 0; int bNeedSwap; memcpy( poDS->pachHeader, poOpenInfo->pabyHeader, ERD_HEADER_SIZE ); #ifdef CPL_LSB bNeedSwap = bBigEndian; #else bNeedSwap = !bBigEndian; #endif if( bNeedSwap ) { CPL_SWAP16PTR( poDS->pachHeader + 6 ); CPL_SWAP16PTR( poDS->pachHeader + 8 ); CPL_SWAP32PTR( poDS->pachHeader + 16 ); CPL_SWAP32PTR( poDS->pachHeader + 20 ); CPL_SWAP32PTR( poDS->pachHeader + 24 ); CPL_SWAP32PTR( poDS->pachHeader + 28 ); CPL_SWAP16PTR( poDS->pachHeader + 88 ); CPL_SWAP16PTR( poDS->pachHeader + 90 ); CPL_SWAP16PTR( poDS->pachHeader + 106 ); CPL_SWAP32PTR( poDS->pachHeader + 108 ); CPL_SWAP32PTR( poDS->pachHeader + 112 ); CPL_SWAP32PTR( poDS->pachHeader + 116 ); CPL_SWAP32PTR( poDS->pachHeader + 120 ); CPL_SWAP32PTR( poDS->pachHeader + 124 ); } /* -------------------------------------------------------------------- */ /* Capture some information from the file that is of interest. */ /* -------------------------------------------------------------------- */ int nBandCount, nPixelOffset; GDALDataType eDataType; if( EQUALN(poDS->pachHeader,"HEADER",7) ) { poDS->nRasterXSize = (int) *((float *) (poDS->pachHeader + 16)); poDS->nRasterYSize = (int) *((float *) (poDS->pachHeader + 20)); } else { poDS->nRasterXSize = *((GInt32 *) (poDS->pachHeader + 16)); poDS->nRasterYSize = *((GInt32 *) (poDS->pachHeader + 20)); } if( *((GInt16 *) (poDS->pachHeader + 6)) == 0 ) { eDataType = GDT_Byte; nPixelOffset = 1; } else if( *((GInt16 *) (poDS->pachHeader + 6)) == 1 ) /* 4bit! */ { eDataType = GDT_Byte; nPixelOffset = -1; } else if( *((GInt16 *) (poDS->pachHeader + 6)) == 2 ) { nPixelOffset = 2; eDataType = GDT_Int16; } else { CPLError( CE_Failure, CPLE_AppDefined, "Unsupported pixel type (%d).", *((GInt16 *) (poDS->pachHeader + 6)) ); delete poDS; return NULL; } nBandCount = *((GInt16 *) (poDS->pachHeader + 8)); if (!GDALCheckDatasetDimensions(poDS->nRasterXSize, poDS->nRasterYSize) || !GDALCheckBandCount(nBandCount, FALSE)) { delete poDS; return NULL; } /* -------------------------------------------------------------------- */ /* Create band information object. */ /* -------------------------------------------------------------------- */ for( int iBand = 1; iBand <= nBandCount; iBand++ ) { if( nPixelOffset == -1 ) /* 4 bit case */ poDS->SetBand( iBand, new LAN4BitRasterBand( poDS, iBand ) ); else poDS->SetBand( iBand, new RawRasterBand( poDS, iBand, poDS->fpImage, ERD_HEADER_SIZE + (iBand-1) * nPixelOffset * poDS->nRasterXSize, nPixelOffset, poDS->nRasterXSize*nPixelOffset*nBandCount, eDataType, !bNeedSwap, TRUE )); } /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ poDS->SetDescription( poOpenInfo->pszFilename ); poDS->CheckForStatistics(); poDS->TryLoadXML(); /* -------------------------------------------------------------------- */ /* Check for overviews. */ /* -------------------------------------------------------------------- */ poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename ); /* -------------------------------------------------------------------- */ /* Try to interprete georeferencing. */ /* -------------------------------------------------------------------- */ poDS->adfGeoTransform[0] = *((float *) (poDS->pachHeader + 112)); poDS->adfGeoTransform[1] = *((float *) (poDS->pachHeader + 120)); poDS->adfGeoTransform[2] = 0.0; poDS->adfGeoTransform[3] = *((float *) (poDS->pachHeader + 116)); poDS->adfGeoTransform[4] = 0.0; poDS->adfGeoTransform[5] = - *((float *) (poDS->pachHeader + 124)); // adjust for center of pixel vs. top left corner of pixel. poDS->adfGeoTransform[0] -= poDS->adfGeoTransform[1] * 0.5; poDS->adfGeoTransform[3] -= poDS->adfGeoTransform[5] * 0.5; /* -------------------------------------------------------------------- */ /* If we didn't get any georeferencing, try for a worldfile. */ /* -------------------------------------------------------------------- */ if( poDS->adfGeoTransform[1] == 0.0 || poDS->adfGeoTransform[5] == 0.0 ) { if( !GDALReadWorldFile( poOpenInfo->pszFilename, NULL, poDS->adfGeoTransform ) ) GDALReadWorldFile( poOpenInfo->pszFilename, ".wld", poDS->adfGeoTransform ); } /* -------------------------------------------------------------------- */ /* Try to come up with something for the coordinate system. */ /* -------------------------------------------------------------------- */ int nCoordSys = *((GInt16 *) (poDS->pachHeader + 88)); if( nCoordSys == 0 ) { poDS->pszProjection = CPLStrdup(SRS_WKT_WGS84); } else if( nCoordSys == 1 ) { poDS->pszProjection = CPLStrdup("LOCAL_CS[\"UTM - Zone Unknown\",UNIT[\"Meter\",1]]"); } else if( nCoordSys == 2 ) { poDS->pszProjection = CPLStrdup("LOCAL_CS[\"State Plane - Zone Unknown\",UNIT[\"US survey foot\",0.3048006096012192]]"); } else { poDS->pszProjection = CPLStrdup("LOCAL_CS[\"Unknown\",UNIT[\"Meter\",1]]"); } /* -------------------------------------------------------------------- */ /* Check for a trailer file with a colormap in it. */ /* -------------------------------------------------------------------- */ char *pszPath = CPLStrdup(CPLGetPath(poOpenInfo->pszFilename)); char *pszBasename = CPLStrdup(CPLGetBasename(poOpenInfo->pszFilename)); const char *pszTRLFilename = CPLFormCIFilename( pszPath, pszBasename, "trl" ); FILE *fpTRL; fpTRL = VSIFOpenL( pszTRLFilename, "rb" ); if( fpTRL != NULL ) { char szTRLData[896]; int iColor; GDALColorTable *poCT; VSIFReadL( szTRLData, 1, 896, fpTRL ); VSIFCloseL( fpTRL ); poCT = new GDALColorTable(); for( iColor = 0; iColor < 256; iColor++ ) { GDALColorEntry sEntry; sEntry.c2 = ((GByte *) szTRLData)[iColor+128]; sEntry.c1 = ((GByte *) szTRLData)[iColor+128+256]; sEntry.c3 = ((GByte *) szTRLData)[iColor+128+512]; sEntry.c4 = 255; poCT->SetColorEntry( iColor, &sEntry ); // only 16 colors in 4bit files. if( nPixelOffset == -1 && iColor == 15 ) break; } poDS->GetRasterBand(1)->SetColorTable( poCT ); poDS->GetRasterBand(1)->SetColorInterpretation( GCI_PaletteIndex ); delete poCT; } CPLFree( pszPath ); CPLFree( pszBasename ); return( poDS ); }
CEOSImage * CEOSOpen( const char * pszFilename, const char * pszAccess ) { VSILFILE *fp; CEOSRecord *psRecord; CEOSImage *psImage; int nSeqNum, i; GByte abyHeader[16]; /* -------------------------------------------------------------------- */ /* Try to open the imagery file. */ /* -------------------------------------------------------------------- */ fp = VSIFOpenL( pszFilename, pszAccess ); if( fp == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "Failed to open CEOS file `%s' with access `%s'.\n", pszFilename, pszAccess ); return NULL; } /* -------------------------------------------------------------------- */ /* Create a CEOSImage structure, and initialize it. */ /* -------------------------------------------------------------------- */ psImage = (CEOSImage *) CPLCalloc(1,sizeof(CEOSImage)); psImage->fpImage = fp; psImage->nPixels = psImage->nLines = psImage->nBands = 0; /* -------------------------------------------------------------------- */ /* Preread info on the first record, to establish if it is */ /* little endian. */ /* -------------------------------------------------------------------- */ if( VSIFReadL( abyHeader, 16, 1, fp ) != 1 || VSIFSeekL( fp, 0, SEEK_SET ) < 0 ) { CEOSClose( psImage ); return NULL; } if( abyHeader[0] != 0 || abyHeader[1] != 0 ) psImage->bLittleEndian = TRUE; /* -------------------------------------------------------------------- */ /* Try to read the header record. */ /* -------------------------------------------------------------------- */ psRecord = CEOSReadRecord( psImage ); if( psRecord == NULL ) { CEOSClose( psImage ); return NULL; } if( psRecord->nRecordType != CRT_IMAGE_FDR ) { CPLError( CE_Failure, CPLE_AppDefined, "Got a %X type record, instead of the expected\n" "file descriptor record on file %s.\n", psRecord->nRecordType, pszFilename ); CEOSDestroyRecord( psRecord ); CEOSClose( psImage ); return NULL; } /* -------------------------------------------------------------------- */ /* The sequence number should be 2 indicating this is the */ /* imagery file. */ /* -------------------------------------------------------------------- */ nSeqNum = CEOSScanInt( psRecord->pachData + 44, 4 ); if( nSeqNum != 2 ) { CPLError( CE_Warning, CPLE_AppDefined, "Got a %d file sequence number, instead of the expected\n" "2 indicating imagery on file %s.\n" "Continuing to access anyways.\n", nSeqNum, pszFilename ); } /* -------------------------------------------------------------------- */ /* Extract various information. */ /* -------------------------------------------------------------------- */ psImage->nImageRecCount = CEOSScanInt( psRecord->pachData+180, 6 ); psImage->nImageRecLength = CEOSScanInt( psRecord->pachData+186, 6 ); psImage->nBitsPerPixel = CEOSScanInt( psRecord->pachData+216, 4 ); psImage->nBands = CEOSScanInt( psRecord->pachData+232, 4 ); psImage->nLines = CEOSScanInt( psRecord->pachData+236, 8 ); psImage->nPixels = CEOSScanInt( psRecord->pachData+248, 8 ); psImage->nPrefixBytes = CEOSScanInt( psRecord->pachData+276, 4 ); psImage->nSuffixBytes = CEOSScanInt( psRecord->pachData+288, 4 ); if( psImage->nImageRecLength <= 0 || psImage->nPrefixBytes < 0 || psImage->nBands > INT_MAX / psImage->nImageRecLength || (size_t)psImage->nBands > INT_MAX / sizeof(int)) { CEOSDestroyRecord( psRecord ); CEOSClose( psImage ); return NULL; } /* -------------------------------------------------------------------- */ /* Try to establish the layout of the imagery data. */ /* -------------------------------------------------------------------- */ psImage->nLineOffset = psImage->nBands * psImage->nImageRecLength; psImage->panDataStart = (int *) VSIMalloc(sizeof(int) * psImage->nBands); if( psImage->panDataStart == NULL ) { CEOSDestroyRecord( psRecord ); CEOSClose( psImage ); return NULL; } for( i = 0; i < psImage->nBands; i++ ) { psImage->panDataStart[i] = psRecord->nLength + i * psImage->nImageRecLength + 12 + psImage->nPrefixBytes; } CEOSDestroyRecord( psRecord ); return psImage; }
void LANDataset::CheckForStatistics() { /* -------------------------------------------------------------------- */ /* Do we have a statistics file? */ /* -------------------------------------------------------------------- */ osSTAFilename = CPLResetExtension(GetDescription(),"sta"); FILE *fpSTA = VSIFOpenL( osSTAFilename, "r" ); #ifndef WIN32 if( fpSTA == NULL ) { osSTAFilename = CPLResetExtension(GetDescription(),"STA"); fpSTA = VSIFOpenL( osSTAFilename, "r" ); } #endif if( fpSTA == NULL ) { osSTAFilename = ""; return; } /* -------------------------------------------------------------------- */ /* Read it one band at a time. */ /* -------------------------------------------------------------------- */ GByte abyBandInfo[1152]; int iBand; for( iBand = 0; iBand < nBands; iBand++ ) { if( VSIFReadL( abyBandInfo, 1152, 1, fpSTA ) != 1 ) break; int nBandNumber = abyBandInfo[7]; GDALRasterBand *poBand = GetRasterBand(nBandNumber); if( poBand == NULL ) break; float fMean, fStdDev; GInt16 nMin, nMax; if( poBand->GetRasterDataType() != GDT_Byte ) { memcpy( &nMin, abyBandInfo + 28, 2 ); memcpy( &nMax, abyBandInfo + 30, 2 ); CPL_LSBPTR16( &nMin ); CPL_LSBPTR16( &nMax ); } else { nMin = abyBandInfo[9]; nMax = abyBandInfo[8]; } memcpy( &fMean, abyBandInfo + 12, 4 ); memcpy( &fStdDev, abyBandInfo + 24, 4 ); CPL_LSBPTR32( &fMean ); CPL_LSBPTR32( &fStdDev ); poBand->SetStatistics( nMin, nMax, fMean, fStdDev ); } VSIFCloseL( fpSTA ); }
GDALDataset *IntergraphDataset::Open( GDALOpenInfo *poOpenInfo ) { if( poOpenInfo->nHeaderBytes < 1024 ) { return NULL; } // -------------------------------------------------------------------- // Assign Header Information // -------------------------------------------------------------------- INGR_HeaderOne hHeaderOne; INGR_HeaderOneDiskToMem( &hHeaderOne, (GByte*) poOpenInfo->pabyHeader); // -------------------------------------------------------------------- // Check Header Type (HTC) Version // -------------------------------------------------------------------- if( hHeaderOne.HeaderType.Version != INGR_HEADER_VERSION ) { return NULL; } // -------------------------------------------------------------------- // Check Header Type (HTC) 2D / 3D Flag // -------------------------------------------------------------------- if( ( hHeaderOne.HeaderType.Is2Dor3D != INGR_HEADER_2D ) && ( hHeaderOne.HeaderType.Is2Dor3D != INGR_HEADER_3D ) ) { return NULL; } // -------------------------------------------------------------------- // Check Header Type (HTC) Type Flag // -------------------------------------------------------------------- if( hHeaderOne.HeaderType.Type != INGR_HEADER_TYPE ) { return NULL; } // -------------------------------------------------------------------- // Check Grid File Version (VER) // -------------------------------------------------------------------- if( hHeaderOne.GridFileVersion != 1 && hHeaderOne.GridFileVersion != 2 && hHeaderOne.GridFileVersion != 3 ) { return NULL; } // -------------------------------------------------------------------- // Check Words To Follow (WTC) Minimum Value // -------------------------------------------------------------------- if( hHeaderOne.WordsToFollow < 254 ) { return NULL; } // -------------------------------------------------------------------- // Check Words To Follow (WTC) Integrity // -------------------------------------------------------------------- float fHeaderBlocks = (float) ( hHeaderOne.WordsToFollow + 2 ) / 256; if( ( fHeaderBlocks - (int) fHeaderBlocks ) != 0.0 ) { return NULL; } // -------------------------------------------------------------------- // Get Data Type Code (DTC) => Format Type // -------------------------------------------------------------------- INGR_Format eFormat = (INGR_Format) hHeaderOne.DataTypeCode; // -------------------------------------------------------------------- // We need to scan around the file, so we open it now. // -------------------------------------------------------------------- VSILFILE *fp; if( poOpenInfo->eAccess == GA_ReadOnly ) { fp = VSIFOpenL( poOpenInfo->pszFilename, "rb" ); } else { fp = VSIFOpenL( poOpenInfo->pszFilename, "r+b" ); } if( fp == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "%s", VSIStrerror( errno ) ); return NULL; } // -------------------------------------------------------------------- // Get Format Type from the tile directory // -------------------------------------------------------------------- if( hHeaderOne.DataTypeCode == TiledRasterData ) { INGR_TileHeader hTileDir; int nOffset = 2 + ( 2 * ( hHeaderOne.WordsToFollow + 1 ) ); GByte abyBuffer[SIZEOF_TDIR]; if( (VSIFSeekL( fp, nOffset, SEEK_SET ) == -1 ) || (VSIFReadL( abyBuffer, 1, SIZEOF_TDIR, fp ) == 0) ) { VSIFCloseL( fp ); CPLError( CE_Failure, CPLE_AppDefined, "Error reading tiles header" ); return NULL; } INGR_TileHeaderDiskToMem( &hTileDir, abyBuffer ); if( ! ( hTileDir.ApplicationType == 1 && hTileDir.SubTypeCode == 7 && ( hTileDir.WordsToFollow % 4 ) == 0 && hTileDir.PacketVersion == 1 && hTileDir.Identifier == 1 ) ) { CPLError( CE_Failure, CPLE_AppDefined, "Cannot recognize tiles header info"); VSIFCloseL( fp ); return NULL; } eFormat = (INGR_Format) hTileDir.DataTypeCode; } // -------------------------------------------------------------------- // Check Scannable Flag // -------------------------------------------------------------------- /* if (hHeaderOne.ScannableFlag == HasLineHeader) { CPLError( CE_Failure, CPLE_AppDefined, "Intergraph Raster Scannable Line Header not supported yet" ); VSIFCloseL( fp ); return NULL; } */ // -------------------------------------------------------------------- // Check supported Format Type // -------------------------------------------------------------------- if( eFormat != ByteInteger && eFormat != WordIntegers && eFormat != Integers32Bit && eFormat != FloatingPoint32Bit && eFormat != FloatingPoint64Bit && eFormat != RunLengthEncoded && eFormat != RunLengthEncodedC && eFormat != CCITTGroup4 && eFormat != AdaptiveRGB && eFormat != Uncompressed24bit && eFormat != AdaptiveGrayScale && eFormat != ContinuousTone && eFormat != JPEGGRAY && eFormat != JPEGRGB && eFormat != JPEGCYMK ) { CPLError( CE_Failure, CPLE_AppDefined, "Intergraph Raster Format %d ( \"%s\" ) not supported", hHeaderOne.DataTypeCode, INGR_GetFormatName( (uint16) eFormat ) ); VSIFCloseL( fp ); return NULL; } // ----------------------------------------------------------------- // Create a corresponding GDALDataset // ----------------------------------------------------------------- IntergraphDataset *poDS; poDS = new IntergraphDataset(); poDS->eAccess = poOpenInfo->eAccess; poDS->pszFilename = CPLStrdup( poOpenInfo->pszFilename ); poDS->fp = fp; // -------------------------------------------------------------------- // Get X Size from Pixels Per Line (PPL) // -------------------------------------------------------------------- poDS->nRasterXSize = hHeaderOne.PixelsPerLine; // -------------------------------------------------------------------- // Get Y Size from Number of Lines (NOL) // -------------------------------------------------------------------- poDS->nRasterYSize = hHeaderOne.NumberOfLines; if (poDS->nRasterXSize <= 0 || poDS->nRasterYSize <= 0) { CPLError( CE_Failure, CPLE_AppDefined, "Invalid dimensions : %d x %d", poDS->nRasterXSize, poDS->nRasterYSize); delete poDS; return NULL; } // -------------------------------------------------------------------- // Get Geo Transformation from Homogeneous Transformation Matrix (TRN) // -------------------------------------------------------------------- INGR_GetTransMatrix( &hHeaderOne, poDS->adfGeoTransform ); // -------------------------------------------------------------------- // Set Metadata Information // -------------------------------------------------------------------- poDS->SetMetadataItem( "VERSION", CPLSPrintf ( "%d", hHeaderOne.GridFileVersion ), "IMAGE_STRUCTURE" ); poDS->SetMetadataItem( "RESOLUTION", CPLSPrintf ( "%d", (hHeaderOne.DeviceResolution < 0)?-hHeaderOne.DeviceResolution:1) ); // -------------------------------------------------------------------- // Create Band Information // -------------------------------------------------------------------- int nBands = 0; int nBandOffset = 0; GByte abyBuf[MAX(SIZEOF_HDR1,SIZEOF_HDR2_A)]; do { VSIFSeekL( poDS->fp, nBandOffset, SEEK_SET ); VSIFReadL( abyBuf, 1, SIZEOF_HDR1, poDS->fp ); INGR_HeaderOneDiskToMem( &poDS->hHeaderOne, abyBuf ); VSIFReadL( abyBuf, 1, SIZEOF_HDR2_A, poDS->fp ); INGR_HeaderTwoADiskToMem( &poDS->hHeaderTwo, abyBuf ); switch( eFormat ) { case JPEGRGB: case JPEGCYMK: { IntergraphBitmapBand* poBand; nBands++; poDS->SetBand( nBands, poBand = new IntergraphBitmapBand( poDS, nBands, nBandOffset, 1 )); if (poBand->pabyBMPBlock == NULL) { delete poDS; return NULL; } nBands++; poDS->SetBand( nBands, poBand = new IntergraphBitmapBand( poDS, nBands, nBandOffset, 2 )); if (poBand->pabyBMPBlock == NULL) { delete poDS; return NULL; } nBands++; poDS->SetBand( nBands, poBand = new IntergraphBitmapBand( poDS, nBands, nBandOffset, 3 )); if (poBand->pabyBMPBlock == NULL) { delete poDS; return NULL; } break; } case JPEGGRAY: case CCITTGroup4: { IntergraphBitmapBand* poBand; nBands++; poDS->SetBand( nBands, poBand = new IntergraphBitmapBand( poDS, nBands, nBandOffset )); if (poBand->pabyBMPBlock == NULL) { delete poDS; return NULL; } break; } case RunLengthEncoded: case RunLengthEncodedC: case AdaptiveGrayScale: { IntergraphRLEBand* poBand; nBands++; poDS->SetBand( nBands, poBand = new IntergraphRLEBand( poDS, nBands, nBandOffset )); if (poBand->pabyBlockBuf == NULL || poBand->pabyRLEBlock == NULL) { delete poDS; return NULL; } break; } case AdaptiveRGB: case ContinuousTone: { IntergraphRLEBand* poBand; nBands++; poDS->SetBand( nBands, poBand = new IntergraphRLEBand( poDS, nBands, nBandOffset, 1 )); if (poBand->pabyBlockBuf == NULL || poBand->pabyRLEBlock == NULL) { delete poDS; return NULL; } nBands++; poDS->SetBand( nBands, poBand = new IntergraphRLEBand( poDS, nBands, nBandOffset, 2 )); if (poBand->pabyBlockBuf == NULL || poBand->pabyRLEBlock == NULL) { delete poDS; return NULL; } nBands++; poDS->SetBand( nBands, poBand = new IntergraphRLEBand( poDS, nBands, nBandOffset, 3 )); if (poBand->pabyBlockBuf == NULL || poBand->pabyRLEBlock == NULL) { delete poDS; return NULL; } break; } case Uncompressed24bit: { IntergraphRGBBand* poBand; nBands++; poDS->SetBand( nBands, poBand = new IntergraphRGBBand( poDS, nBands, nBandOffset, 1 )); if (poBand->pabyBlockBuf == NULL) { delete poDS; return NULL; } nBands++; poDS->SetBand( nBands, poBand = new IntergraphRGBBand( poDS, nBands, nBandOffset, 2 )); if (poBand->pabyBlockBuf == NULL) { delete poDS; return NULL; } nBands++; poDS->SetBand( nBands, poBand = new IntergraphRGBBand( poDS, nBands, nBandOffset, 3 )); if (poBand->pabyBlockBuf == NULL) { delete poDS; return NULL; } break; } default: { IntergraphRasterBand* poBand; nBands++; poDS->SetBand( nBands, poBand = new IntergraphRasterBand( poDS, nBands, nBandOffset )); if (poBand->pabyBlockBuf == NULL) { delete poDS; return NULL; } } } // ---------------------------------------------------------------- // Get next band offset from Catenated File Pointer (CFP) // ---------------------------------------------------------------- nBandOffset = poDS->hHeaderTwo.CatenatedFilePointer; } while( nBandOffset != 0 ); poDS->nBands = nBands; // -------------------------------------------------------------------- // Initialize any PAM information // -------------------------------------------------------------------- poDS->SetDescription( poOpenInfo->pszFilename ); poDS->TryLoadXML(); /* -------------------------------------------------------------------- */ /* Check for external overviews. */ /* -------------------------------------------------------------------- */ poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename ); return ( poDS ); }
GDALDataset *IDADataset::Open( GDALOpenInfo * poOpenInfo ) { /* -------------------------------------------------------------------- */ /* Is this an IDA file? */ /* -------------------------------------------------------------------- */ int nXSize, nYSize; GIntBig nExpectedFileSize, nActualFileSize; if( poOpenInfo->fpL == NULL ) return NULL; if( poOpenInfo->nHeaderBytes < 512 ) return NULL; // projection legal? if( poOpenInfo->pabyHeader[23] > 10 ) return NULL; // imagetype legal? if( (poOpenInfo->pabyHeader[22] > 14 && poOpenInfo->pabyHeader[22] < 100) || (poOpenInfo->pabyHeader[22] > 114 && poOpenInfo->pabyHeader[22] != 200 ) ) return NULL; nXSize = poOpenInfo->pabyHeader[30] + poOpenInfo->pabyHeader[31] * 256; nYSize = poOpenInfo->pabyHeader[32] + poOpenInfo->pabyHeader[33] * 256; if( nXSize == 0 || nYSize == 0 ) return NULL; // The file just be exactly the image size + header size in length. nExpectedFileSize = nXSize * nYSize + 512; VSIFSeekL( poOpenInfo->fpL, 0, SEEK_END ); nActualFileSize = VSIFTellL( poOpenInfo->fpL ); VSIRewindL( poOpenInfo->fpL ); if( nActualFileSize != nExpectedFileSize ) return NULL; /* -------------------------------------------------------------------- */ /* Create the dataset. */ /* -------------------------------------------------------------------- */ IDADataset *poDS = new IDADataset(); memcpy( poDS->abyHeader, poOpenInfo->pabyHeader, 512 ); /* -------------------------------------------------------------------- */ /* Parse various values out of the header. */ /* -------------------------------------------------------------------- */ poDS->nImageType = poOpenInfo->pabyHeader[22]; poDS->nProjection = poOpenInfo->pabyHeader[23]; poDS->nRasterYSize = poOpenInfo->pabyHeader[30] + poOpenInfo->pabyHeader[31] * 256; poDS->nRasterXSize = poOpenInfo->pabyHeader[32] + poOpenInfo->pabyHeader[33] * 256; strncpy( poDS->szTitle, (const char *) poOpenInfo->pabyHeader+38, 80 ); poDS->szTitle[80] = '\0'; int nLastTitleChar = strlen(poDS->szTitle)-1; while( nLastTitleChar > -1 && (poDS->szTitle[nLastTitleChar] == 10 || poDS->szTitle[nLastTitleChar] == 13 || poDS->szTitle[nLastTitleChar] == ' ') ) poDS->szTitle[nLastTitleChar--] = '\0'; poDS->dfLatCenter = tp2c( poOpenInfo->pabyHeader + 120 ); poDS->dfLongCenter = tp2c( poOpenInfo->pabyHeader + 126 ); poDS->dfXCenter = tp2c( poOpenInfo->pabyHeader + 132 ); poDS->dfYCenter = tp2c( poOpenInfo->pabyHeader + 138 ); poDS->dfDX = tp2c( poOpenInfo->pabyHeader + 144 ); poDS->dfDY = tp2c( poOpenInfo->pabyHeader + 150 ); poDS->dfParallel1 = tp2c( poOpenInfo->pabyHeader + 156 ); poDS->dfParallel2 = tp2c( poOpenInfo->pabyHeader + 162 ); poDS->ProcessGeoref(); poDS->SetMetadataItem( "TITLE", poDS->szTitle ); /* -------------------------------------------------------------------- */ /* Handle various image types. */ /* -------------------------------------------------------------------- */ /* GENERIC = 0 FEW S NDVI = 1 EROS NDVI = 6 ARTEMIS CUTOFF = 10 ARTEMIS RECODE = 11 ARTEMIS NDVI = 12 ARTEMIS FEWS = 13 ARTEMIS NEWNASA = 14 GENERIC DIFF = 100 FEW S NDVI DIFF = 101 EROS NDVI DIFF = 106 ARTEMIS CUTOFF DIFF = 110 ARTEMIS RECODE DIFF = 111 ARTEMIS NDVI DIFF = 112 ARTEMIS FEWS DIFF = 113 ARTEMIS NEWNASA DIFF = 114 CALCULATED =200 */ poDS->nMissing = 0; switch( poDS->nImageType ) { case 1: poDS->SetMetadataItem( "IMAGETYPE", "1, FEWS NDVI" ); poDS->dfM = 1/256.0; poDS->dfB = -82/256.0; break; case 6: poDS->SetMetadataItem( "IMAGETYPE", "6, EROS NDVI" ); poDS->dfM = 1/100.0; poDS->dfB = -100/100.0; break; case 10: poDS->SetMetadataItem( "IMAGETYPE", "10, ARTEMIS CUTOFF" ); poDS->dfM = 1.0; poDS->dfB = 0.0; poDS->nMissing = 254; break; case 11: poDS->SetMetadataItem( "IMAGETYPE", "11, ARTEMIS RECODE" ); poDS->dfM = 4.0; poDS->dfB = 0.0; poDS->nMissing = 254; break; case 12: /* ANDVI */ poDS->SetMetadataItem( "IMAGETYPE", "12, ARTEMIS NDVI" ); poDS->dfM = 4/500.0; poDS->dfB = -3/500.0 - 1.0; poDS->nMissing = 254; break; case 13: /* AFEWS */ poDS->SetMetadataItem( "IMAGETYPE", "13, ARTEMIS FEWS" ); poDS->dfM = 1/256.0; poDS->dfB = -82/256.0; poDS->nMissing = 254; break; case 14: /* NEWNASA */ poDS->SetMetadataItem( "IMAGETYPE", "13, ARTEMIS NEWNASA" ); poDS->dfM = 0.75/250.0; poDS->dfB = 0.0; poDS->nMissing = 254; break; case 101: /* NDVI_DIFF (FEW S) */ poDS->dfM = 1/128.0; poDS->dfB = -1.0; poDS->nMissing = 0; break; case 106: /* EROS_DIFF */ poDS->dfM = 1/50.0; poDS->dfB = -128/50.0; poDS->nMissing = 0; break; case 110: /* CUTOFF_DIFF */ poDS->dfM = 2.0; poDS->dfB = -128*2; poDS->nMissing = 254; break; case 111: /* RECODE_DIFF */ poDS->dfM = 8; poDS->dfB = -128*8; poDS->nMissing = 254; break; case 112: /* ANDVI_DIFF */ poDS->dfM = 8/1000.0; poDS->dfB = (-128*8)/1000.0; poDS->nMissing = 254; break; case 113: /* AFEWS_DIFF */ poDS->dfM = 1/128.0; poDS->dfB = -1; poDS->nMissing = 254; break; case 114: /* NEWNASA_DIFF */ poDS->dfM = 0.75/125.0; poDS->dfB = -128*poDS->dfM; poDS->nMissing = 254; break; case 200: /* we use the values from the header */ poDS->dfM = tp2c( poOpenInfo->pabyHeader + 171 ); poDS->dfB = tp2c( poOpenInfo->pabyHeader + 177 ); poDS->nMissing = poOpenInfo->pabyHeader[170]; break; default: poDS->dfM = 1.0; poDS->dfB = 0.0; break; } /* -------------------------------------------------------------------- */ /* Create the band. */ /* -------------------------------------------------------------------- */ if( poOpenInfo->eAccess == GA_ReadOnly ) { poDS->fpRaw = poOpenInfo->fpL; poOpenInfo->fpL = NULL; } else { poDS->fpRaw = VSIFOpenL( poOpenInfo->pszFilename, "rb+" ); poDS->eAccess = GA_Update; if( poDS->fpRaw == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "Failed to open %s for write access.", poOpenInfo->pszFilename ); return NULL; } } poDS->SetBand( 1, new IDARasterBand( poDS, poDS->fpRaw, poDS->nRasterXSize ) ); /* -------------------------------------------------------------------- */ /* Check for a color table. */ /* -------------------------------------------------------------------- */ poDS->SetDescription( poOpenInfo->pszFilename ); poDS->ReadColorTable(); /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ poDS->TryLoadXML(); /* -------------------------------------------------------------------- */ /* Check for overviews. */ /* -------------------------------------------------------------------- */ poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename ); return( poDS ); }
GDALDataset *ISIS2Dataset::Open( GDALOpenInfo * poOpenInfo ) { /* -------------------------------------------------------------------- */ /* Does this look like a CUBE or an IMAGE Primary Data Object? */ /* -------------------------------------------------------------------- */ if( !Identify( poOpenInfo ) ) return NULL; /* -------------------------------------------------------------------- */ /* Open the file using the large file API. */ /* -------------------------------------------------------------------- */ VSILFILE *fpQube = VSIFOpenL( poOpenInfo->pszFilename, "rb" ); if( fpQube == NULL ) return NULL; ISIS2Dataset *poDS; poDS = new ISIS2Dataset(); if( ! poDS->oKeywords.Ingest( fpQube, 0 ) ) { VSIFCloseL( fpQube ); delete poDS; return NULL; } VSIFCloseL( fpQube ); /* -------------------------------------------------------------------- */ /* We assume the user is pointing to the label (ie. .lab) file. */ /* -------------------------------------------------------------------- */ // QUBE can be inline or detached and point to an image name // ^QUBE = 76 // ^QUBE = ("ui31s015.img",6441<BYTES>) - has another label on the image // ^QUBE = "ui31s015.img" - which implies no label or skip value const char *pszQube = poDS->GetKeyword( "^QUBE" ); GUIntBig nQube = 0; int bByteLocation = FALSE; CPLString osTargetFile = poOpenInfo->pszFilename; if( pszQube[0] == '"' ) { CPLString osTPath = CPLGetPath(poOpenInfo->pszFilename); CPLString osFilename = pszQube; poDS->CleanString( osFilename ); osTargetFile = CPLFormCIFilename( osTPath, osFilename, NULL ); poDS->osExternalCube = osTargetFile; } else if( pszQube[0] == '(' ) { CPLString osTPath = CPLGetPath(poOpenInfo->pszFilename); CPLString osFilename = poDS->GetKeywordSub("^QUBE",1,""); poDS->CleanString( osFilename ); osTargetFile = CPLFormCIFilename( osTPath, osFilename, NULL ); poDS->osExternalCube = osTargetFile; nQube = atoi(poDS->GetKeywordSub("^QUBE",2,"1")); if( strstr(poDS->GetKeywordSub("^QUBE",2,"1"),"<BYTES>") != NULL ) bByteLocation = true; } else { nQube = atoi(pszQube); if( strstr(pszQube,"<BYTES>") != NULL ) bByteLocation = true; } /* -------------------------------------------------------------------- */ /* Check if file an ISIS2 header file? Read a few lines of text */ /* searching for something starting with nrows or ncols. */ /* -------------------------------------------------------------------- */ GDALDataType eDataType = GDT_Byte; OGRSpatialReference oSRS; //image parameters int nRows, nCols, nBands = 1; GUIntBig nSkipBytes = 0; int itype; int s_ix, s_iy, s_iz; // check SUFFIX_ITEMS params. int record_bytes; int bNoDataSet = FALSE; char chByteOrder = 'M'; //default to MSB //Georef parameters double dfULXMap=0.5; double dfULYMap = 0.5; double dfXDim = 1.0; double dfYDim = 1.0; double dfNoData = 0.0; double xulcenter = 0.0; double yulcenter = 0.0; //projection parameters int bProjectionSet = TRUE; double semi_major = 0.0; double semi_minor = 0.0; double iflattening = 0.0; double center_lat = 0.0; double center_lon = 0.0; double first_std_parallel = 0.0; double second_std_parallel = 0.0; VSILFILE *fp; /* -------------------------------------------------------------------- */ /* Checks to see if this is valid ISIS2 cube */ /* SUFFIX_ITEM tag in .cub file should be (0,0,0); no side-planes */ /* -------------------------------------------------------------------- */ s_ix = atoi(poDS->GetKeywordSub( "QUBE.SUFFIX_ITEMS", 1 )); s_iy = atoi(poDS->GetKeywordSub( "QUBE.SUFFIX_ITEMS", 2 )); s_iz = atoi(poDS->GetKeywordSub( "QUBE.SUFFIX_ITEMS", 3 )); if( s_ix != 0 || s_iy != 0 || s_iz != 0 ) { CPLError( CE_Failure, CPLE_OpenFailed, "*** ISIS 2 cube file has invalid SUFFIX_ITEMS parameters:\n" "*** gdal isis2 driver requires (0, 0, 0), thus no sideplanes or backplanes\n" "found: (%i, %i, %i)\n\n", s_ix, s_iy, s_iz ); delete poDS; return NULL; } /**************** end SUFFIX_ITEM check ***********************/ /*********** Grab layout type (BSQ, BIP, BIL) ************/ // AXIS_NAME = (SAMPLE,LINE,BAND) /***********************************************************/ const char *value; char szLayout[10] = "BSQ"; //default to band seq. value = poDS->GetKeyword( "QUBE.AXIS_NAME", "" ); if (EQUAL(value,"(SAMPLE,LINE,BAND)") ) strcpy(szLayout,"BSQ"); else if (EQUAL(value,"(BAND,LINE,SAMPLE)") ) strcpy(szLayout,"BIP"); else if (EQUAL(value,"(SAMPLE,BAND,LINE)") || EQUAL(value,"") ) strcpy(szLayout,"BSQ"); else { CPLError( CE_Failure, CPLE_OpenFailed, "%s layout not supported. Abort\n\n", value); delete poDS; return NULL; } /*********** Grab samples lines band ************/ nCols = atoi(poDS->GetKeywordSub("QUBE.CORE_ITEMS",1)); nRows = atoi(poDS->GetKeywordSub("QUBE.CORE_ITEMS",2)); nBands = atoi(poDS->GetKeywordSub("QUBE.CORE_ITEMS",3)); /*********** Grab Qube record bytes **********/ record_bytes = atoi(poDS->GetKeyword("RECORD_BYTES")); if (nQube > 0 && bByteLocation ) nSkipBytes = (nQube - 1); else if( nQube > 0 ) nSkipBytes = (nQube - 1) * record_bytes; else nSkipBytes = 0; /*********** Grab samples lines band ************/ CPLString osCoreItemType = poDS->GetKeyword( "QUBE.CORE_ITEM_TYPE" ); if( (EQUAL(osCoreItemType,"PC_INTEGER")) || (EQUAL(osCoreItemType,"PC_UNSIGNED_INTEGER")) || (EQUAL(osCoreItemType,"PC_REAL")) ) { chByteOrder = 'I'; } /******** Grab format type - isis2 only supports 8,16,32 *******/ itype = atoi(poDS->GetKeyword("QUBE.CORE_ITEM_BYTES","")); switch(itype) { case 1 : eDataType = GDT_Byte; dfNoData = NULL1; bNoDataSet = TRUE; break; case 2 : if( strstr(osCoreItemType,"UNSIGNED") != NULL ) { dfNoData = 0; eDataType = GDT_UInt16; } else { dfNoData = NULL2; eDataType = GDT_Int16; } bNoDataSet = TRUE; break; case 4 : eDataType = GDT_Float32; dfNoData = NULL3; bNoDataSet = TRUE; break; case 8 : eDataType = GDT_Float64; dfNoData = NULL3; bNoDataSet = TRUE; break; default : CPLError( CE_Failure, CPLE_AppDefined, "Itype of %d is not supported in ISIS 2.", itype); delete poDS; return NULL; } /*********** Grab Cellsize ************/ value = poDS->GetKeyword("QUBE.IMAGE_MAP_PROJECTION.MAP_SCALE"); if (strlen(value) > 0 ) { dfXDim = (float) CPLAtof(value) * 1000.0; /* convert from km to m */ dfYDim = (float) CPLAtof(value) * 1000.0 * -1; } /*********** Grab LINE_PROJECTION_OFFSET ************/ value = poDS->GetKeyword("QUBE.IMAGE_MAP_PROJECTION.LINE_PROJECTION_OFFSET"); if (strlen(value) > 0) { yulcenter = (float) CPLAtof(value); yulcenter = ((yulcenter) * dfYDim); dfULYMap = yulcenter - (dfYDim/2); } /*********** Grab SAMPLE_PROJECTION_OFFSET ************/ value = poDS->GetKeyword("QUBE.IMAGE_MAP_PROJECTION.SAMPLE_PROJECTION_OFFSET"); if( strlen(value) > 0 ) { xulcenter = (float) CPLAtof(value); xulcenter = ((xulcenter) * dfXDim); dfULXMap = xulcenter - (dfXDim/2); } /*********** Grab TARGET_NAME ************/ /**** This is the planets name i.e. MARS ***/ CPLString target_name = poDS->GetKeyword("QUBE.TARGET_NAME"); /*********** Grab MAP_PROJECTION_TYPE ************/ CPLString map_proj_name = poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.MAP_PROJECTION_TYPE"); poDS->CleanString( map_proj_name ); /*********** Grab SEMI-MAJOR ************/ semi_major = CPLAtof(poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.A_AXIS_RADIUS")) * 1000.0; /*********** Grab semi-minor ************/ semi_minor = CPLAtof(poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.C_AXIS_RADIUS")) * 1000.0; /*********** Grab CENTER_LAT ************/ center_lat = CPLAtof(poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.CENTER_LATITUDE")); /*********** Grab CENTER_LON ************/ center_lon = CPLAtof(poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.CENTER_LONGITUDE")); /*********** Grab 1st std parallel ************/ first_std_parallel = CPLAtof(poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.FIRST_STANDARD_PARALLEL")); /*********** Grab 2nd std parallel ************/ second_std_parallel = CPLAtof(poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.SECOND_STANDARD_PARALLEL")); /*** grab PROJECTION_LATITUDE_TYPE = "PLANETOCENTRIC" ****/ // Need to further study how ocentric/ographic will effect the gdal library. // So far we will use this fact to define a sphere or ellipse for some projections // Frank - may need to talk this over char bIsGeographic = TRUE; value = poDS->GetKeyword("CUBE.IMAGE_MAP_PROJECTION.PROJECTION_LATITUDE_TYPE"); if (EQUAL( value, "\"PLANETOCENTRIC\"" )) bIsGeographic = FALSE; CPLDebug("ISIS2","using projection %s", map_proj_name.c_str() ); //Set oSRS projection and parameters if ((EQUAL( map_proj_name, "EQUIRECTANGULAR_CYLINDRICAL" )) || (EQUAL( map_proj_name, "EQUIRECTANGULAR" )) || (EQUAL( map_proj_name, "SIMPLE_CYLINDRICAL" )) ) { oSRS.OGRSpatialReference::SetEquirectangular2 ( 0.0, center_lon, center_lat, 0, 0 ); } else if (EQUAL( map_proj_name, "ORTHOGRAPHIC" )) { oSRS.OGRSpatialReference::SetOrthographic ( center_lat, center_lon, 0, 0 ); } else if ((EQUAL( map_proj_name, "SINUSOIDAL" )) || (EQUAL( map_proj_name, "SINUSOIDAL_EQUAL-AREA" ))) { oSRS.OGRSpatialReference::SetSinusoidal ( center_lon, 0, 0 ); } else if (EQUAL( map_proj_name, "MERCATOR" )) { oSRS.OGRSpatialReference::SetMercator ( center_lat, center_lon, 1, 0, 0 ); } else if (EQUAL( map_proj_name, "POLAR_STEREOGRAPHIC" )) { oSRS.OGRSpatialReference::SetPS ( center_lat, center_lon, 1, 0, 0 ); } else if (EQUAL( map_proj_name, "TRANSVERSE_MERCATOR" )) { oSRS.OGRSpatialReference::SetTM ( center_lat, center_lon, 1, 0, 0 ); } else if (EQUAL( map_proj_name, "LAMBERT_CONFORMAL_CONIC" )) { oSRS.OGRSpatialReference::SetLCC ( first_std_parallel, second_std_parallel, center_lat, center_lon, 0, 0 ); } else if (EQUAL( map_proj_name, "") ) { /* no projection */ bProjectionSet = FALSE; } else { CPLDebug( "ISIS2", "Dataset projection %s is not supported. Continuing...", map_proj_name.c_str() ); bProjectionSet = FALSE; } if (bProjectionSet) { //Create projection name, i.e. MERCATOR MARS and set as ProjCS keyword CPLString proj_target_name = map_proj_name + " " + target_name; oSRS.SetProjCS(proj_target_name); //set ProjCS keyword //The geographic/geocentric name will be the same basic name as the body name //'GCS' = Geographic/Geocentric Coordinate System CPLString geog_name = "GCS_" + target_name; //The datum and sphere names will be the same basic name aas the planet CPLString datum_name = "D_" + target_name; CPLString sphere_name = target_name; // + "_IAU_IAG"); //Might not be IAU defined so don't add //calculate inverse flattening from major and minor axis: 1/f = a/(a-b) if ((semi_major - semi_minor) < 0.0000001) iflattening = 0; else iflattening = semi_major / (semi_major - semi_minor); //Set the body size but take into consideration which proj is being used to help w/ proj4 compatibility //The use of a Sphere, polar radius or ellipse here is based on how ISIS does it internally if ( ( (EQUAL( map_proj_name, "STEREOGRAPHIC" ) && (fabs(center_lat) == 90)) ) || (EQUAL( map_proj_name, "POLAR_STEREOGRAPHIC" ))) { if (bIsGeographic) { //Geograpraphic, so set an ellipse oSRS.SetGeogCS( geog_name, datum_name, sphere_name, semi_major, iflattening, "Reference_Meridian", 0.0 ); } else { //Geocentric, so force a sphere using the semi-minor axis. I hope... sphere_name += "_polarRadius"; oSRS.SetGeogCS( geog_name, datum_name, sphere_name, semi_minor, 0.0, "Reference_Meridian", 0.0 ); } } else if ( (EQUAL( map_proj_name, "SIMPLE_CYLINDRICAL" )) || (EQUAL( map_proj_name, "ORTHOGRAPHIC" )) || (EQUAL( map_proj_name, "STEREOGRAPHIC" )) || (EQUAL( map_proj_name, "SINUSOIDAL_EQUAL-AREA" )) || (EQUAL( map_proj_name, "SINUSOIDAL" )) ) { //isis uses the sphereical equation for these projections so force a sphere oSRS.SetGeogCS( geog_name, datum_name, sphere_name, semi_major, 0.0, "Reference_Meridian", 0.0 ); } else if ((EQUAL( map_proj_name, "EQUIRECTANGULAR_CYLINDRICAL" )) || (EQUAL( map_proj_name, "EQUIRECTANGULAR" )) ) { //Calculate localRadius using ISIS3 simple elliptical method // not the more standard Radius of Curvature method //PI = 4 * atan(1); double radLat, localRadius; if (center_lon == 0) { //No need to calculate local radius oSRS.SetGeogCS( geog_name, datum_name, sphere_name, semi_major, 0.0, "Reference_Meridian", 0.0 ); } else { radLat = center_lat * M_PI / 180; // in radians localRadius = semi_major * semi_minor / sqrt(pow(semi_minor*cos(radLat),2) + pow(semi_major*sin(radLat),2) ); sphere_name += "_localRadius"; oSRS.SetGeogCS( geog_name, datum_name, sphere_name, localRadius, 0.0, "Reference_Meridian", 0.0 ); CPLDebug( "ISIS2", "local radius: %f", localRadius); } } else { //All other projections: Mercator, Transverse Mercator, Lambert Conformal, etc. //Geographic, so set an ellipse if (bIsGeographic) { oSRS.SetGeogCS( geog_name, datum_name, sphere_name, semi_major, iflattening, "Reference_Meridian", 0.0 ); } else { //Geocentric, so force a sphere. I hope... oSRS.SetGeogCS( geog_name, datum_name, sphere_name, semi_major, 0.0, "Reference_Meridian", 0.0 ); } } // translate back into a projection string. char *pszResult = NULL; oSRS.exportToWkt( &pszResult ); poDS->osProjection = pszResult; CPLFree( pszResult ); } /* END ISIS2 Label Read */ /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ /* -------------------------------------------------------------------- */ /* Did we get the required keywords? If not we return with */ /* this never having been considered to be a match. This isn't */ /* an error! */ /* -------------------------------------------------------------------- */ if( nRows < 1 || nCols < 1 || nBands < 1 ) { delete poDS; return NULL; } /* -------------------------------------------------------------------- */ /* Capture some information from the file that is of interest. */ /* -------------------------------------------------------------------- */ poDS->nRasterXSize = nCols; poDS->nRasterYSize = nRows; /* -------------------------------------------------------------------- */ /* Open target binary file. */ /* -------------------------------------------------------------------- */ if( poOpenInfo->eAccess == GA_ReadOnly ) poDS->fpImage = VSIFOpenL( osTargetFile, "rb" ); else poDS->fpImage = VSIFOpenL( osTargetFile, "r+b" ); if( poDS->fpImage == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "Failed to open %s with write permission.\n%s", osTargetFile.c_str(), VSIStrerror( errno ) ); delete poDS; return NULL; } poDS->eAccess = poOpenInfo->eAccess; /* -------------------------------------------------------------------- */ /* Compute the line offset. */ /* -------------------------------------------------------------------- */ int nItemSize = GDALGetDataTypeSize(eDataType)/8; int nLineOffset, nPixelOffset, nBandOffset; if( EQUAL(szLayout,"BIP") ) { nPixelOffset = nItemSize * nBands; nLineOffset = nPixelOffset * nCols; nBandOffset = nItemSize; } else if( EQUAL(szLayout,"BSQ") ) { nPixelOffset = nItemSize; nLineOffset = nPixelOffset * nCols; nBandOffset = nLineOffset * nRows; } else /* assume BIL */ { nPixelOffset = nItemSize; nLineOffset = nItemSize * nBands * nCols; nBandOffset = nItemSize * nCols; } /* -------------------------------------------------------------------- */ /* Create band information objects. */ /* -------------------------------------------------------------------- */ int i; poDS->nBands = nBands;; for( i = 0; i < poDS->nBands; i++ ) { RawRasterBand *poBand; poBand = new RawRasterBand( poDS, i+1, poDS->fpImage, nSkipBytes + nBandOffset * i, nPixelOffset, nLineOffset, eDataType, #ifdef CPL_LSB chByteOrder == 'I' || chByteOrder == 'L', #else chByteOrder == 'M', #endif TRUE ); if( bNoDataSet ) poBand->SetNoDataValue( dfNoData ); poDS->SetBand( i+1, poBand ); // Set offset/scale values at the PAM level. poBand->SetOffset( CPLAtofM(poDS->GetKeyword("QUBE.CORE_BASE","0.0"))); poBand->SetScale( CPLAtofM(poDS->GetKeyword("QUBE.CORE_MULTIPLIER","1.0"))); } /* -------------------------------------------------------------------- */ /* Check for a .prj file. For isis2 I would like to keep this in */ /* -------------------------------------------------------------------- */ CPLString osPath, osName; osPath = CPLGetPath( poOpenInfo->pszFilename ); osName = CPLGetBasename(poOpenInfo->pszFilename); const char *pszPrjFile = CPLFormCIFilename( osPath, osName, "prj" ); fp = VSIFOpenL( pszPrjFile, "r" ); if( fp != NULL ) { char **papszLines; OGRSpatialReference oSRS; VSIFCloseL( fp ); papszLines = CSLLoad( pszPrjFile ); if( oSRS.importFromESRI( papszLines ) == OGRERR_NONE ) { char *pszResult = NULL; oSRS.exportToWkt( &pszResult ); poDS->osProjection = pszResult; CPLFree( pszResult ); } CSLDestroy( papszLines ); } if( dfULXMap != 0.5 || dfULYMap != 0.5 || dfXDim != 1.0 || dfYDim != 1.0 ) { poDS->bGotTransform = TRUE; poDS->adfGeoTransform[0] = dfULXMap; poDS->adfGeoTransform[1] = dfXDim; poDS->adfGeoTransform[2] = 0.0; poDS->adfGeoTransform[3] = dfULYMap; poDS->adfGeoTransform[4] = 0.0; poDS->adfGeoTransform[5] = dfYDim; } if( !poDS->bGotTransform ) poDS->bGotTransform = GDALReadWorldFile( poOpenInfo->pszFilename, "cbw", poDS->adfGeoTransform ); if( !poDS->bGotTransform ) poDS->bGotTransform = GDALReadWorldFile( poOpenInfo->pszFilename, "wld", poDS->adfGeoTransform ); /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ poDS->SetDescription( poOpenInfo->pszFilename ); poDS->TryLoadXML(); /* -------------------------------------------------------------------- */ /* Check for overviews. */ /* -------------------------------------------------------------------- */ poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename ); return( poDS ); }
OGRCSVLayer::OGRCSVLayer( const char *pszLayerNameIn, VSILFILE * fp, const char *pszFilename, int bNew, int bInWriteMode, char chDelimiter, const char* pszNfdcGeomField, const char* pszGeonamesGeomFieldPrefix) { fpCSV = fp; iWktGeomReadField = -1; iNfdcLatitudeS = iNfdcLongitudeS = -1; iLatitudeField = iLongitudeField = -1; this->bInWriteMode = bInWriteMode; this->bNew = bNew; this->pszFilename = CPLStrdup(pszFilename); this->chDelimiter = chDelimiter; bFirstFeatureAppendedDuringSession = TRUE; bUseCRLF = FALSE; bNeedRewindBeforeRead = FALSE; eGeometryFormat = OGR_CSV_GEOM_NONE; nNextFID = 1; poFeatureDefn = new OGRFeatureDefn( pszLayerNameIn ); poFeatureDefn->Reference(); poFeatureDefn->SetGeomType( wkbNone ); bCreateCSVT = FALSE; bDontHonourStrings = FALSE; nTotalFeatures = -1; /* -------------------------------------------------------------------- */ /* If this is not a new file, read ahead to establish if it is */ /* already in CRLF (DOS) mode, or just a normal unix CR mode. */ /* -------------------------------------------------------------------- */ if( !bNew && bInWriteMode ) { int nBytesRead = 0; char chNewByte; while( nBytesRead < 10000 && VSIFReadL( &chNewByte, 1, 1, fpCSV ) == 1 ) { if( chNewByte == 13 ) { bUseCRLF = TRUE; break; } } VSIRewindL( fpCSV ); } /* -------------------------------------------------------------------- */ /* Check if the first record seems to be field definitions or */ /* not. We assume it is field definitions if none of the */ /* values are strictly numeric. */ /* -------------------------------------------------------------------- */ char **papszTokens = NULL; int nFieldCount=0, iField; if( !bNew ) { papszTokens = OGRCSVReadParseLineL( fpCSV, chDelimiter, FALSE ); nFieldCount = CSLCount( papszTokens ); bHasFieldNames = TRUE; } else bHasFieldNames = FALSE; for( iField = 0; iField < nFieldCount && bHasFieldNames; iField++ ) { const char *pszToken = papszTokens[iField]; int bAllNumeric = TRUE; if (*pszToken != '\0') { while( *pszToken != '\0' && bAllNumeric ) { if( *pszToken != '.' && *pszToken != '-' && (*pszToken < '0' || *pszToken > '9') ) bAllNumeric = FALSE; pszToken++; } if( bAllNumeric ) bHasFieldNames = FALSE; } } if( !bNew && !bHasFieldNames ) VSIRewindL( fpCSV ); /* -------------------------------------------------------------------- */ /* Search a csvt file for types */ /* -------------------------------------------------------------------- */ char** papszFieldTypes = NULL; if (!bNew) { char* dname = strdup(CPLGetDirname(pszFilename)); char* fname = strdup(CPLGetBasename(pszFilename)); VSILFILE* fpCSVT = VSIFOpenL(CPLFormFilename(dname, fname, ".csvt"), "r"); free(dname); free(fname); if (fpCSVT!=NULL) { VSIRewindL(fpCSVT); papszFieldTypes = OGRCSVReadParseLineL(fpCSVT, ',', FALSE); VSIFCloseL(fpCSVT); } } /* -------------------------------------------------------------------- */ /* Build field definitions. */ /* -------------------------------------------------------------------- */ for( iField = 0; iField < nFieldCount; iField++ ) { char *pszFieldName = NULL; char szFieldNameBuffer[100]; if( bHasFieldNames ) { pszFieldName = papszTokens[iField]; // trim white space. while( *pszFieldName == ' ' ) pszFieldName++; while( pszFieldName[0] != '\0' && pszFieldName[strlen(pszFieldName)-1] == ' ' ) pszFieldName[strlen(pszFieldName)-1] = '\0'; if (*pszFieldName == '\0') pszFieldName = NULL; } if (pszFieldName == NULL) { pszFieldName = szFieldNameBuffer; sprintf( szFieldNameBuffer, "field_%d", iField+1 ); } OGRFieldDefn oField(pszFieldName, OFTString); if (papszFieldTypes!=NULL && iField<CSLCount(papszFieldTypes)) { char* pszLeftParenthesis = strchr(papszFieldTypes[iField], '('); if (pszLeftParenthesis && pszLeftParenthesis != papszFieldTypes[iField] && pszLeftParenthesis[1] >= '0' && pszLeftParenthesis[1] <= '9') { int nWidth = 0; int nPrecision = 0; char* pszDot = strchr(pszLeftParenthesis, '.'); if (pszDot) *pszDot = 0; *pszLeftParenthesis = 0; if (pszLeftParenthesis[-1] == ' ') pszLeftParenthesis[-1] = 0; nWidth = atoi(pszLeftParenthesis+1); if (pszDot) nPrecision = atoi(pszDot+1); oField.SetWidth(nWidth); oField.SetPrecision(nPrecision); } if (EQUAL(papszFieldTypes[iField], "Integer")) oField.SetType(OFTInteger); else if (EQUAL(papszFieldTypes[iField], "Real")) oField.SetType(OFTReal); else if (EQUAL(papszFieldTypes[iField], "String")) oField.SetType(OFTString); else if (EQUAL(papszFieldTypes[iField], "Date")) oField.SetType(OFTDate); else if (EQUAL(papszFieldTypes[iField], "Time")) oField.SetType(OFTTime); else if (EQUAL(papszFieldTypes[iField], "DateTime")) oField.SetType(OFTDateTime); else CPLError(CE_Warning, CPLE_NotSupported, "Unknown type : %s", papszFieldTypes[iField]); } if( EQUAL(oField.GetNameRef(),"WKT") && oField.GetType() == OFTString && iWktGeomReadField == -1 ) { iWktGeomReadField = iField; poFeatureDefn->SetGeomType( wkbUnknown ); } /*http://www.faa.gov/airports/airport_safety/airportdata_5010/menu/index.cfm specific */ if ( pszNfdcGeomField != NULL && EQUALN(oField.GetNameRef(), pszNfdcGeomField, strlen(pszNfdcGeomField)) && EQUAL(oField.GetNameRef() + strlen(pszNfdcGeomField), "LatitudeS") ) iNfdcLatitudeS = iField; else if ( pszNfdcGeomField != NULL && EQUALN(oField.GetNameRef(), pszNfdcGeomField, strlen(pszNfdcGeomField)) && EQUAL(oField.GetNameRef() + strlen(pszNfdcGeomField), "LongitudeS") ) iNfdcLongitudeS = iField; /* GNIS specific */ else if ( pszGeonamesGeomFieldPrefix != NULL && EQUALN(oField.GetNameRef(), pszGeonamesGeomFieldPrefix, strlen(pszGeonamesGeomFieldPrefix)) && (EQUAL(oField.GetNameRef() + strlen(pszGeonamesGeomFieldPrefix), "_LAT_DEC") || EQUAL(oField.GetNameRef() + strlen(pszGeonamesGeomFieldPrefix), "_LATITUDE_DEC") || EQUAL(oField.GetNameRef() + strlen(pszGeonamesGeomFieldPrefix), "_LATITUDE")) ) { oField.SetType(OFTReal); iLatitudeField = iField; } else if ( pszGeonamesGeomFieldPrefix != NULL && EQUALN(oField.GetNameRef(), pszGeonamesGeomFieldPrefix, strlen(pszGeonamesGeomFieldPrefix)) && (EQUAL(oField.GetNameRef() + strlen(pszGeonamesGeomFieldPrefix), "_LONG_DEC") || EQUAL(oField.GetNameRef() + strlen(pszGeonamesGeomFieldPrefix), "_LONGITUDE_DEC") || EQUAL(oField.GetNameRef() + strlen(pszGeonamesGeomFieldPrefix), "_LONGITUDE")) ) { oField.SetType(OFTReal); iLongitudeField = iField; } poFeatureDefn->AddFieldDefn( &oField ); } if ( iNfdcLatitudeS != -1 && iNfdcLongitudeS != -1 ) { bDontHonourStrings = TRUE; poFeatureDefn->SetGeomType( wkbPoint ); } else if ( iLatitudeField != -1 && iLongitudeField != -1 ) { poFeatureDefn->SetGeomType( wkbPoint ); } CSLDestroy( papszTokens ); CSLDestroy( papszFieldTypes ); }
size_t VSISparseFileHandle::Read( void * pBuffer, size_t nSize, size_t nCount ) { /* -------------------------------------------------------------------- */ /* Find what region we are in, searching linearly from the */ /* start. */ /* -------------------------------------------------------------------- */ unsigned int iRegion; for( iRegion = 0; iRegion < aoRegions.size(); iRegion++ ) { if( nCurOffset >= aoRegions[iRegion].nDstOffset && nCurOffset < aoRegions[iRegion].nDstOffset + aoRegions[iRegion].nLength ) break; } /* -------------------------------------------------------------------- */ /* Default to zeroing the buffer if no corresponding region was */ /* found. */ /* -------------------------------------------------------------------- */ if( iRegion == aoRegions.size() ) { memset( pBuffer, 0, nSize * nCount ); nCurOffset += nSize * nSize; return nCount; } /* -------------------------------------------------------------------- */ /* If this request crosses region boundaries, split it into two */ /* requests. */ /* -------------------------------------------------------------------- */ size_t nReturnCount = nCount; GUIntBig nBytesRequested = nSize * nCount; GUIntBig nBytesAvailable = aoRegions[iRegion].nDstOffset + aoRegions[iRegion].nLength; if( nCurOffset + nBytesRequested > nBytesAvailable ) { size_t nExtraBytes = (size_t) (nCurOffset + nBytesRequested - nBytesAvailable); // Recurse to get the rest of the request. GUIntBig nCurOffsetSave = nCurOffset; nCurOffset += nBytesRequested - nExtraBytes; size_t nBytesRead = this->Read( ((char *) pBuffer) + nBytesRequested - nExtraBytes, 1, nExtraBytes ); nCurOffset = nCurOffsetSave; if( nBytesRead < nExtraBytes ) nReturnCount -= (nExtraBytes-nBytesRead) / nSize; nBytesRequested -= nExtraBytes; } /* -------------------------------------------------------------------- */ /* Handle a constant region. */ /* -------------------------------------------------------------------- */ if( aoRegions[iRegion].osFilename.size() == 0 ) { memset( pBuffer, aoRegions[iRegion].byValue, (size_t) nBytesRequested ); } /* -------------------------------------------------------------------- */ /* Otherwise handle as a file. */ /* -------------------------------------------------------------------- */ else { if( aoRegions[iRegion].fp == NULL ) { if( !aoRegions[iRegion].bTriedOpen ) { aoRegions[iRegion].fp = VSIFOpenL( aoRegions[iRegion].osFilename, "r" ); if( aoRegions[iRegion].fp == NULL ) { CPLDebug( "/vsisparse/", "Failed to open '%s'.", aoRegions[iRegion].osFilename.c_str() ); } aoRegions[iRegion].bTriedOpen = TRUE; } if( aoRegions[iRegion].fp == NULL ) { return 0; } } if( VSIFSeekL( aoRegions[iRegion].fp, nCurOffset - aoRegions[iRegion].nDstOffset + aoRegions[iRegion].nSrcOffset, SEEK_SET ) != 0 ) return 0; poFS->IncRecCounter(); size_t nBytesRead = VSIFReadL( pBuffer, 1, (size_t) nBytesRequested, aoRegions[iRegion].fp ); poFS->DecRecCounter(); if( nBytesAvailable < nBytesRequested ) nReturnCount = nBytesRead / nSize; } nCurOffset += nReturnCount * nSize; return nReturnCount; }
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( !bHasFieldNames ) { bHasFieldNames = TRUE; bNeedSeekEnd = FALSE; for(int iFile=0;iFile<((bCreateCSVT) ? 2 : 1);iFile++) { VSILFILE* fpCSVT = NULL; if (bCreateCSVT && iFile == 0) { char* pszDirName = CPLStrdup(CPLGetDirname(pszFilename)); char* pszBaseName = CPLStrdup(CPLGetBasename(pszFilename)); fpCSVT = VSIFOpenL(CPLFormFilename(pszDirName, pszBaseName, ".csvt"), "wb"); CPLFree(pszDirName); CPLFree(pszBaseName); } else { if( strncmp(pszFilename, "/vsistdout/", 11) == 0 || strncmp(pszFilename, "/vsizip/", 8) == 0 ) fpCSV = VSIFOpenL( pszFilename, "wb" ); else fpCSV = VSIFOpenL( pszFilename, "w+b" ); if( fpCSV == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "Failed to create %s:\n%s", pszFilename, VSIStrerror( errno ) ); return NULL; } } if (eGeometryFormat == OGR_CSV_GEOM_AS_WKT) { if (fpCSV) VSIFPrintfL( fpCSV, "%s", "WKT"); if (fpCSVT) VSIFPrintfL( fpCSVT, "%s", "String"); if (poFeatureDefn->GetFieldCount() > 0) { if (fpCSV) VSIFPrintfL( fpCSV, "%c", chDelimiter ); if (fpCSVT) VSIFPrintfL( fpCSVT, "%s", ","); } } else if (eGeometryFormat == OGR_CSV_GEOM_AS_XYZ) { if (fpCSV) VSIFPrintfL( fpCSV, "X%cY%cZ", chDelimiter, chDelimiter); if (fpCSVT) VSIFPrintfL( fpCSVT, "%s", "Real,Real,Real"); if (poFeatureDefn->GetFieldCount() > 0) { if (fpCSV) VSIFPrintfL( fpCSV, "%c", chDelimiter ); if (fpCSVT) VSIFPrintfL( fpCSVT, "%s", ","); } } else if (eGeometryFormat == OGR_CSV_GEOM_AS_XY) { if (fpCSV) VSIFPrintfL( fpCSV, "X%cY", chDelimiter); if (fpCSVT) VSIFPrintfL( fpCSVT, "%s", "Real,Real"); if (poFeatureDefn->GetFieldCount() > 0) { if (fpCSV) VSIFPrintfL( fpCSV, "%c", chDelimiter ); if (fpCSVT) VSIFPrintfL( fpCSVT, "%s", ","); } } else if (eGeometryFormat == OGR_CSV_GEOM_AS_YX) { if (fpCSV) VSIFPrintfL( fpCSV, "Y%cX", chDelimiter); if (fpCSVT) VSIFPrintfL( fpCSVT, "%s", "Real,Real"); if (poFeatureDefn->GetFieldCount() > 0) { if (fpCSV) VSIFPrintfL( fpCSV, "%c", chDelimiter ); if (fpCSVT) VSIFPrintfL( fpCSVT, "%s", ","); } } for( iField = 0; iField < poFeatureDefn->GetFieldCount(); iField++ ) { char *pszEscaped; if( iField > 0 ) { if (fpCSV) VSIFPrintfL( fpCSV, "%c", chDelimiter ); if (fpCSVT) VSIFPrintfL( fpCSVT, "%s", ","); } pszEscaped = CPLEscapeString( poFeatureDefn->GetFieldDefn(iField)->GetNameRef(), -1, CPLES_CSV ); if (fpCSV) VSIFPrintfL( fpCSV, "%s", pszEscaped ); CPLFree( pszEscaped ); if (fpCSVT) { switch( poFeatureDefn->GetFieldDefn(iField)->GetType() ) { case OFTInteger: VSIFPrintfL( fpCSVT, "%s", "Integer"); break; case OFTReal: VSIFPrintfL( fpCSVT, "%s", "Real"); break; case OFTDate: VSIFPrintfL( fpCSVT, "%s", "Date"); break; case OFTTime: VSIFPrintfL( fpCSVT, "%s", "Time"); break; case OFTDateTime: VSIFPrintfL( fpCSVT, "%s", "DateTime"); break; default: VSIFPrintfL( fpCSVT, "%s", "String"); break; } int nWidth = poFeatureDefn->GetFieldDefn(iField)->GetWidth(); int nPrecision = poFeatureDefn->GetFieldDefn(iField)->GetPrecision(); if (nWidth != 0) { if (nPrecision != 0) VSIFPrintfL( fpCSVT, "(%d.%d)", nWidth, nPrecision); else VSIFPrintfL( fpCSVT, "(%d)", nWidth); } } } if( bUseCRLF ) { if (fpCSV) VSIFPutcL( 13, fpCSV ); if (fpCSVT) VSIFPutcL( 13, fpCSVT ); } if (fpCSV) VSIFPutcL( '\n', fpCSV ); if (fpCSVT) VSIFPutcL( '\n', fpCSVT ); if (fpCSVT) VSIFCloseL(fpCSVT); } } 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. */ /* -------------------------------------------------------------------- */ for( iField = 0; iField < poFeatureDefn->GetFieldCount(); iField++ ) { char *pszEscaped; if( iField > 0 ) VSIFPrintfL( fpCSV, "%c", chDelimiter ); pszEscaped = CPLEscapeString( poNewFeature->GetFieldAsString(iField), -1, CPLES_CSV ); if (poFeatureDefn->GetFieldDefn(iField)->GetType() == OFTReal) { /* Use point as decimal separator */ char* pszComma = strchr(pszEscaped, ','); if (pszComma) *pszComma = '.'; } VSIFWriteL( pszEscaped, 1, strlen(pszEscaped), fpCSV ); CPLFree( pszEscaped ); } if( bUseCRLF ) VSIFPutcL( 13, fpCSV ); VSIFPutcL( '\n', fpCSV ); return OGRERR_NONE; }
GDALDataset *PAuxDataset::Open( GDALOpenInfo * poOpenInfo ) { if( poOpenInfo->nHeaderBytes < 1 ) return NULL; /* -------------------------------------------------------------------- */ /* If this is an .aux file, fetch out and form the name of the */ /* file it references. */ /* -------------------------------------------------------------------- */ CPLString osTarget = poOpenInfo->pszFilename; if( EQUAL(CPLGetExtension( poOpenInfo->pszFilename ),"aux") && STARTS_WITH_CI(reinterpret_cast<char *>( poOpenInfo->pabyHeader ), "AuxilaryTarget: ") ) { const char *pszSrc = reinterpret_cast<const char *>( poOpenInfo->pabyHeader+16 ); char szAuxTarget[1024] = { '\0' }; for( int i = 0; i < static_cast<int>( sizeof(szAuxTarget) ) - 1 && pszSrc[i] != 10 && pszSrc[i] != 13 && pszSrc[i] != '\0'; i++ ) { szAuxTarget[i] = pszSrc[i]; } szAuxTarget[sizeof(szAuxTarget) - 1] = '\0'; const std::string osPath(CPLGetPath(poOpenInfo->pszFilename)); osTarget = CPLFormFilename(osPath.c_str(), szAuxTarget, NULL); } /* -------------------------------------------------------------------- */ /* Now we need to tear apart the filename to form a .aux */ /* filename. */ /* -------------------------------------------------------------------- */ CPLString osAuxFilename = CPLResetExtension(osTarget,"aux"); /* -------------------------------------------------------------------- */ /* Do we have a .aux file? */ /* -------------------------------------------------------------------- */ char** papszSiblingFiles = poOpenInfo->GetSiblingFiles(); if( papszSiblingFiles != NULL && CSLFindString( papszSiblingFiles, CPLGetFilename(osAuxFilename) ) == -1 ) { return NULL; } VSILFILE *fp = VSIFOpenL( osAuxFilename, "r" ); if( fp == NULL ) { osAuxFilename = CPLResetExtension(osTarget,"AUX"); fp = VSIFOpenL( osAuxFilename, "r" ); } if( fp == NULL ) return NULL; /* -------------------------------------------------------------------- */ /* Is this file a PCI .aux file? Check the first line for the */ /* telltale AuxilaryTarget keyword. */ /* */ /* At this point we should be verifying that it refers to our */ /* binary file, but that is a pretty involved test. */ /* -------------------------------------------------------------------- */ const char *pszLine = CPLReadLineL( fp ); CPL_IGNORE_RET_VAL(VSIFCloseL( fp )); if( pszLine == NULL || (!STARTS_WITH_CI(pszLine, "AuxilaryTarget") && !STARTS_WITH_CI(pszLine, "AuxiliaryTarget")) ) { return NULL; } /* -------------------------------------------------------------------- */ /* Create a corresponding GDALDataset. */ /* -------------------------------------------------------------------- */ PAuxDataset *poDS = new PAuxDataset(); /* -------------------------------------------------------------------- */ /* Load the .aux file into a string list suitable to be */ /* searched with CSLFetchNameValue(). */ /* -------------------------------------------------------------------- */ poDS->papszAuxLines = CSLLoad( osAuxFilename ); poDS->pszAuxFilename = CPLStrdup(osAuxFilename); /* -------------------------------------------------------------------- */ /* Find the RawDefinition line to establish overall parameters. */ /* -------------------------------------------------------------------- */ pszLine = CSLFetchNameValue(poDS->papszAuxLines, "RawDefinition"); // It seems PCI now writes out .aux files without RawDefinition in // some cases. See bug 947. if( pszLine == NULL ) { delete poDS; return NULL; } char **papszTokens = CSLTokenizeString(pszLine); if( CSLCount(papszTokens) < 3 ) { CPLError( CE_Failure, CPLE_AppDefined, "RawDefinition missing or corrupt in %s.", poOpenInfo->pszFilename ); delete poDS; CSLDestroy( papszTokens ); return NULL; } poDS->nRasterXSize = atoi(papszTokens[0]); poDS->nRasterYSize = atoi(papszTokens[1]); poDS->nBands = atoi(papszTokens[2]); poDS->eAccess = poOpenInfo->eAccess; CSLDestroy( papszTokens ); if (!GDALCheckDatasetDimensions(poDS->nRasterXSize, poDS->nRasterYSize) || !GDALCheckBandCount(poDS->nBands, FALSE)) { delete poDS; return NULL; } /* -------------------------------------------------------------------- */ /* Open the file. */ /* -------------------------------------------------------------------- */ if( poOpenInfo->eAccess == GA_Update ) { poDS->fpImage = VSIFOpenL( osTarget, "rb+" ); if( poDS->fpImage == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "File %s is missing or read-only, check permissions.", osTarget.c_str() ); delete poDS; return NULL; } } else { poDS->fpImage = VSIFOpenL( osTarget, "rb" ); if( poDS->fpImage == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "File %s is missing or unreadable.", osTarget.c_str() ); delete poDS; return NULL; } } /* -------------------------------------------------------------------- */ /* Collect raw definitions of each channel and create */ /* corresponding bands. */ /* -------------------------------------------------------------------- */ int iBand = 0; for( int i = 0; i < poDS->nBands; i++ ) { char szDefnName[32] = { '\0' }; snprintf( szDefnName, sizeof(szDefnName), "ChanDefinition-%d", i+1 ); pszLine = CSLFetchNameValue(poDS->papszAuxLines, szDefnName); if (pszLine == NULL) { continue; } papszTokens = CSLTokenizeString(pszLine); if( CSLCount(papszTokens) < 4 ) { // Skip the band with broken description CSLDestroy( papszTokens ); continue; } GDALDataType eType = GDT_Unknown; if( EQUAL(papszTokens[0],"16U") ) eType = GDT_UInt16; else if( EQUAL(papszTokens[0],"16S") ) eType = GDT_Int16; else if( EQUAL(papszTokens[0],"32R") ) eType = GDT_Float32; else eType = GDT_Byte; bool bNative = true; if( CSLCount(papszTokens) > 4 ) { #ifdef CPL_LSB bNative = EQUAL(papszTokens[4], "Swapped"); #else bNative = EQUAL(papszTokens[4], "Unswapped"); #endif } const vsi_l_offset nBandOffset = CPLScanUIntBig( papszTokens[1], static_cast<int>(strlen(papszTokens[1])) ); const int nPixelOffset = atoi(papszTokens[2]); const int nLineOffset = atoi(papszTokens[3]); if (nPixelOffset <= 0 || nLineOffset <= 0) { // Skip the band with broken offsets. CSLDestroy( papszTokens ); continue; } poDS->SetBand( iBand+1, new PAuxRasterBand( poDS, iBand+1, poDS->fpImage, nBandOffset, nPixelOffset, nLineOffset, eType, bNative ) ); iBand++; CSLDestroy( papszTokens ); } poDS->nBands = iBand; /* -------------------------------------------------------------------- */ /* Get the projection. */ /* -------------------------------------------------------------------- */ const char *pszMapUnits = CSLFetchNameValue( poDS->papszAuxLines, "MapUnits" ); const char *pszProjParms = CSLFetchNameValue( poDS->papszAuxLines, "ProjParms" ); if( pszMapUnits != NULL ) poDS->pszProjection = poDS->PCI2WKT( pszMapUnits, pszProjParms ); /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ poDS->SetDescription( osTarget ); poDS->TryLoadXML(); /* -------------------------------------------------------------------- */ /* Check for overviews. */ /* -------------------------------------------------------------------- */ poDS->oOvManager.Initialize( poDS, osTarget ); poDS->ScanForGCPs(); poDS->bAuxUpdated = FALSE; return poDS; }
OGRDataSource *OGRVRTDriver::Open( const char * pszFilename, int bUpdate ) { OGRVRTDataSource *poDS; char *pszXML = NULL; /* -------------------------------------------------------------------- */ /* Are we being passed the XML definition directly? */ /* Skip any leading spaces/blanks. */ /* -------------------------------------------------------------------- */ const char *pszTestXML = pszFilename; while( *pszTestXML != '\0' && isspace( (unsigned char)*pszTestXML ) ) pszTestXML++; if( EQUALN(pszTestXML,"<OGRVRTDataSource>",18) ) { pszXML = CPLStrdup(pszTestXML); } /* -------------------------------------------------------------------- */ /* Open file and check if it contains appropriate XML. */ /* -------------------------------------------------------------------- */ else { FILE *fp; char achHeader[18]; fp = VSIFOpenL( pszFilename, "rb" ); if( fp == NULL ) return NULL; if( VSIFReadL( achHeader, sizeof(achHeader), 1, fp ) != 1 ) { VSIFCloseL( fp ); return NULL; } if( !EQUALN(achHeader,"<OGRVRTDataSource>",18) ) { VSIFCloseL( fp ); return NULL; } /* -------------------------------------------------------------------- */ /* It is the right file, now load the full XML definition. */ /* -------------------------------------------------------------------- */ int nLen; VSIFSeekL( fp, 0, SEEK_END ); nLen = (int) VSIFTellL( fp ); VSIFSeekL( fp, 0, SEEK_SET ); pszXML = (char *) VSIMalloc(nLen+1); if (pszXML == NULL) { VSIFCloseL( fp ); return NULL; } pszXML[nLen] = '\0'; if( ((int) VSIFReadL( pszXML, 1, nLen, fp )) != nLen ) { CPLFree( pszXML ); VSIFCloseL( fp ); return NULL; } VSIFCloseL( fp ); } /* -------------------------------------------------------------------- */ /* Parse the XML. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psTree = CPLParseXMLString( pszXML ); CPLFree( pszXML ); if( psTree == NULL ) return NULL; /* -------------------------------------------------------------------- */ /* Create a virtual datasource configured based on this XML input. */ /* -------------------------------------------------------------------- */ poDS = new OGRVRTDataSource(); if( !poDS->Initialize( psTree, pszFilename, bUpdate ) ) { CPLDestroyXMLNode( psTree ); delete poDS; return NULL; } CPLDestroyXMLNode( psTree ); return poDS; }
GDALDataset *HF2Dataset::Open( GDALOpenInfo * poOpenInfo ) { CPLString osOriginalFilename(poOpenInfo->pszFilename); if (!Identify(poOpenInfo)) return NULL; GDALOpenInfo* poOpenInfoToDelete = NULL; /* GZipped .hf2 files are common, so automagically open them */ /* if the /vsigzip/ has not been explicitly passed */ CPLString osFilename(poOpenInfo->pszFilename); if ((EQUAL(CPLGetExtension(poOpenInfo->pszFilename), "hfz") || (strlen(poOpenInfo->pszFilename) > 6 && EQUAL(poOpenInfo->pszFilename + strlen(poOpenInfo->pszFilename) - 6, "hf2.gz"))) && !EQUALN(poOpenInfo->pszFilename, "/vsigzip/", 9)) { osFilename = "/vsigzip/"; osFilename += poOpenInfo->pszFilename; poOpenInfo = poOpenInfoToDelete = new GDALOpenInfo(osFilename.c_str(), GA_ReadOnly, poOpenInfo->GetSiblingFiles()); } /* -------------------------------------------------------------------- */ /* Parse header */ /* -------------------------------------------------------------------- */ int nXSize, nYSize; memcpy(&nXSize, poOpenInfo->pabyHeader + 6, 4); CPL_LSBPTR32(&nXSize); memcpy(&nYSize, poOpenInfo->pabyHeader + 10, 4); CPL_LSBPTR32(&nYSize); GUInt16 nTileSize; memcpy(&nTileSize, poOpenInfo->pabyHeader + 14, 2); CPL_LSBPTR16(&nTileSize); float fVertPres, fHorizScale; memcpy(&fVertPres, poOpenInfo->pabyHeader + 16, 4); CPL_LSBPTR32(&fVertPres); memcpy(&fHorizScale, poOpenInfo->pabyHeader + 20, 4); CPL_LSBPTR32(&fHorizScale); GUInt32 nExtendedHeaderLen; memcpy(&nExtendedHeaderLen, poOpenInfo->pabyHeader + 24, 4); CPL_LSBPTR32(&nExtendedHeaderLen); delete poOpenInfoToDelete; poOpenInfoToDelete = NULL; if (nTileSize < 8) return NULL; if (nXSize <= 0 || nXSize > INT_MAX - nTileSize || nYSize <= 0 || nYSize > INT_MAX - nTileSize) return NULL; /* To avoid later potential int overflows */ if (nExtendedHeaderLen > 1024 * 65536) return NULL; if (!GDALCheckDatasetDimensions(nXSize, nYSize)) { return NULL; } /* -------------------------------------------------------------------- */ /* Parse extended blocks */ /* -------------------------------------------------------------------- */ VSILFILE* fp = VSIFOpenL(osFilename.c_str(), "rb"); if (fp == NULL) return NULL; VSIFSeekL(fp, 28, SEEK_SET); int bHasExtent = FALSE; double dfMinX = 0, dfMaxX = 0, dfMinY = 0, dfMaxY = 0; int bHasUTMZone = FALSE; GInt16 nUTMZone = 0; int bHasEPSGDatumCode = FALSE; GInt16 nEPSGDatumCode = 0; int bHasEPSGCode = FALSE; GInt16 nEPSGCode = 0; int bHasRelativePrecision = FALSE; float fRelativePrecision = 0; char szApplicationName[256]; szApplicationName[0] = 0; GUInt32 nExtendedHeaderOff = 0; while(nExtendedHeaderOff < nExtendedHeaderLen) { char pabyBlockHeader[24]; VSIFReadL(pabyBlockHeader, 24, 1, fp); char szBlockName[16 + 1]; memcpy(szBlockName, pabyBlockHeader + 4, 16); szBlockName[16] = 0; GUInt32 nBlockSize; memcpy(&nBlockSize, pabyBlockHeader + 20, 4); CPL_LSBPTR32(&nBlockSize); if (nBlockSize > 65536) break; nExtendedHeaderOff += 24 + nBlockSize; if (strcmp(szBlockName, "georef-extents") == 0 && nBlockSize == 34) { char pabyBlockData[34]; VSIFReadL(pabyBlockData, 34, 1, fp); memcpy(&dfMinX, pabyBlockData + 2, 8); CPL_LSBPTR64(&dfMinX); memcpy(&dfMaxX, pabyBlockData + 2 + 8, 8); CPL_LSBPTR64(&dfMaxX); memcpy(&dfMinY, pabyBlockData + 2 + 8 + 8, 8); CPL_LSBPTR64(&dfMinY); memcpy(&dfMaxY, pabyBlockData + 2 + 8 + 8 + 8, 8); CPL_LSBPTR64(&dfMaxY); bHasExtent = TRUE; } else if (strcmp(szBlockName, "georef-utm") == 0 && nBlockSize == 2) { VSIFReadL(&nUTMZone, 2, 1, fp); CPL_LSBPTR16(&nUTMZone); CPLDebug("HF2", "UTM Zone = %d", nUTMZone); bHasUTMZone = TRUE; } else if (strcmp(szBlockName, "georef-datum") == 0 && nBlockSize == 2) { VSIFReadL(&nEPSGDatumCode, 2, 1, fp); CPL_LSBPTR16(&nEPSGDatumCode); CPLDebug("HF2", "EPSG Datum Code = %d", nEPSGDatumCode); bHasEPSGDatumCode = TRUE; } else if (strcmp(szBlockName, "georef-epsg-prj") == 0 && nBlockSize == 2) { VSIFReadL(&nEPSGCode, 2, 1, fp); CPL_LSBPTR16(&nEPSGCode); CPLDebug("HF2", "EPSG Code = %d", nEPSGCode); bHasEPSGCode = TRUE; } else if (strcmp(szBlockName, "precis-rel") == 0 && nBlockSize == 4) { VSIFReadL(&fRelativePrecision, 4, 1, fp); CPL_LSBPTR32(&fRelativePrecision); bHasRelativePrecision = TRUE; } else if (strcmp(szBlockName, "app-name") == 0 && nBlockSize < 256) { VSIFReadL(szApplicationName, nBlockSize, 1, fp); szApplicationName[nBlockSize] = 0; } else { CPLDebug("HF2", "Skipping block %s", szBlockName); VSIFSeekL(fp, nBlockSize, SEEK_CUR); } } /* -------------------------------------------------------------------- */ /* Create a corresponding GDALDataset. */ /* -------------------------------------------------------------------- */ HF2Dataset *poDS; poDS = new HF2Dataset(); poDS->fp = fp; poDS->nRasterXSize = nXSize; poDS->nRasterYSize = nYSize; poDS->nTileSize = nTileSize; CPLDebug("HF2", "nXSize = %d, nYSize = %d, nTileSize = %d", nXSize, nYSize, nTileSize); if (bHasExtent) { poDS->adfGeoTransform[0] = dfMinX; poDS->adfGeoTransform[3] = dfMaxY; poDS->adfGeoTransform[1] = (dfMaxX - dfMinX) / nXSize; poDS->adfGeoTransform[5] = -(dfMaxY - dfMinY) / nYSize; } else { poDS->adfGeoTransform[1] = fHorizScale; poDS->adfGeoTransform[5] = fHorizScale; } if (bHasEPSGCode) { OGRSpatialReference oSRS; if (oSRS.importFromEPSG(nEPSGCode) == OGRERR_NONE) oSRS.exportToWkt(&poDS->pszWKT); } else { int bHasSRS = FALSE; OGRSpatialReference oSRS; oSRS.SetGeogCS("unknown", "unknown", "unknown", SRS_WGS84_SEMIMAJOR, SRS_WGS84_INVFLATTENING); if (bHasEPSGDatumCode) { if (nEPSGDatumCode == 23 || nEPSGDatumCode == 6326) { bHasSRS = TRUE; oSRS.SetWellKnownGeogCS("WGS84"); } else if (nEPSGDatumCode >= 6000) { char szName[32]; sprintf( szName, "EPSG:%d", nEPSGDatumCode-2000 ); oSRS.SetWellKnownGeogCS( szName ); bHasSRS = TRUE; } } if (bHasUTMZone && ABS(nUTMZone) >= 1 && ABS(nUTMZone) <= 60) { bHasSRS = TRUE; oSRS.SetUTM(ABS(nUTMZone), nUTMZone > 0); } if (bHasSRS) oSRS.exportToWkt(&poDS->pszWKT); } /* -------------------------------------------------------------------- */ /* Create band information objects. */ /* -------------------------------------------------------------------- */ poDS->nBands = 1; int i; for( i = 0; i < poDS->nBands; i++ ) { poDS->SetBand( i+1, new HF2RasterBand( poDS, i+1, GDT_Float32 ) ); poDS->GetRasterBand(i+1)->SetUnitType("m"); } if (szApplicationName[0] != '\0') poDS->SetMetadataItem("APPLICATION_NAME", szApplicationName); poDS->SetMetadataItem("VERTICAL_PRECISION", CPLString().Printf("%f", fVertPres)); if (bHasRelativePrecision) poDS->SetMetadataItem("RELATIVE_VERTICAL_PRECISION", CPLString().Printf("%f", fRelativePrecision)); /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ poDS->SetDescription( osOriginalFilename.c_str() ); poDS->TryLoadXML(); /* -------------------------------------------------------------------- */ /* Support overviews. */ /* -------------------------------------------------------------------- */ poDS->oOvManager.Initialize( poDS, osOriginalFilename.c_str() ); return( poDS ); }
int OGRGPSBabelDataSource::Open( const char * pszDatasourceName, int bUpdateIn) { int bExplicitFeatures = FALSE; int bWaypoints = TRUE, bTracks = TRUE, bRoutes = TRUE; if (bUpdateIn) { CPLError(CE_Failure, CPLE_NotSupported, "OGR/GPSBabel driver does not support opening a file in update mode"); return FALSE; } if (!EQUALN(pszDatasourceName, "GPSBABEL:", 9)) { VSILFILE* fp = VSIFOpenL(pszDatasourceName, "rb"); if (fp == NULL) return FALSE; char szHeader[1024 + 1]; memset(szHeader, 0, 1024+1); VSIFReadL(szHeader, 1, 1024, fp); if (memcmp(szHeader, "MsRcd", 5) == 0) pszGPSBabelDriverName = CPLStrdup("mapsource"); else if (memcmp(szHeader, "MsRcf", 5) == 0) pszGPSBabelDriverName = CPLStrdup("gdb"); else if (strstr(szHeader, "<osm") != NULL) pszGPSBabelDriverName = CPLStrdup("osm"); else if (strstr(szHeader, "$GPGSA") != NULL || strstr(szHeader, "$GPGGA") != NULL) pszGPSBabelDriverName = CPLStrdup("nmea"); else if (EQUALN(szHeader, "OziExplorer",11)) pszGPSBabelDriverName = CPLStrdup("ozi"); else if (strstr(szHeader, "Grid") && strstr(szHeader, "Datum") && strstr(szHeader, "Header")) pszGPSBabelDriverName = CPLStrdup("garmin_txt"); else if (szHeader[0] == 13 && szHeader[10] == 'M' && szHeader[11] == 'S' && (szHeader[12] >= '0' && szHeader[12] <= '9') && (szHeader[13] >= '0' && szHeader[13] <= '9') && szHeader[12] * 10 + szHeader[13] >= 30 && (szHeader[14] == 1 || szHeader[14] == 2) && szHeader[15] == 0 && szHeader[16] == 0 && szHeader[17] == 0) pszGPSBabelDriverName = CPLStrdup("mapsend"); else if (strstr(szHeader, "$PMGNWPL") != NULL || strstr(szHeader, "$PMGNRTE") != NULL) pszGPSBabelDriverName = CPLStrdup("magellan"); VSIFCloseL(fp); if (pszGPSBabelDriverName == NULL) { return FALSE; } pszFilename = CPLStrdup(pszDatasourceName); } pszName = CPLStrdup( pszDatasourceName ); if (pszGPSBabelDriverName == NULL) { const char* pszSep = strchr(pszDatasourceName + 9, ':'); if (pszSep == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "Wrong syntax. Expected GPSBabel:driver_name:file_name"); return FALSE; } pszGPSBabelDriverName = CPLStrdup(pszDatasourceName + 9); *(strchr(pszGPSBabelDriverName, ':')) = '\0'; /* A bit of validation to avoid command line injection */ if (!IsValidDriverName(pszGPSBabelDriverName)) return FALSE; /* Parse optionnal features= option */ if (EQUALN(pszSep+1, "features=", 9)) { const char* pszNextSep = strchr(pszSep+1, ':'); if (pszNextSep == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "Wrong syntax. Expected GPSBabel:driver_name[,options]*:[features=waypoints,tracks,routes:]file_name"); return FALSE; } char* pszFeatures = CPLStrdup(pszSep+1+9); *strchr(pszFeatures, ':') = 0; char** papszTokens = CSLTokenizeString(pszFeatures); char** papszIter = papszTokens; int bErr = FALSE; bExplicitFeatures = TRUE; bWaypoints = bTracks = bRoutes = FALSE; while(papszIter && *papszIter) { if (EQUAL(*papszIter, "waypoints")) bWaypoints = TRUE; else if (EQUAL(*papszIter, "tracks")) bTracks = TRUE; else if (EQUAL(*papszIter, "routes")) bRoutes = TRUE; else { CPLError(CE_Failure, CPLE_AppDefined, "Wrong value for 'features' options"); bErr = TRUE; } papszIter ++; } CSLDestroy(papszTokens); CPLFree(pszFeatures); if (bErr) return FALSE; pszSep = pszNextSep; } pszFilename = CPLStrdup(pszSep+1); } const char* pszOptionUseTempFile = CPLGetConfigOption("USE_TEMPFILE", NULL); if (pszOptionUseTempFile && CSLTestBoolean(pszOptionUseTempFile)) osTmpFileName = CPLGenerateTempFilename(NULL); else osTmpFileName.Printf("/vsimem/ogrgpsbabeldatasource_%p", this); int bRet = FALSE; if (IsSpecialFile(pszFilename)) { /* Special file : don't try to open it */ char** argv = GetArgv(bExplicitFeatures, bWaypoints, bRoutes, bTracks, pszGPSBabelDriverName, pszFilename); VSILFILE* tmpfp = VSIFOpenL(osTmpFileName.c_str(), "wb"); bRet = (CPLSpawn(argv, NULL, tmpfp, TRUE) == 0); VSIFCloseL(tmpfp); tmpfp = NULL; CSLDestroy(argv); argv = NULL; } else { VSILFILE* fp = VSIFOpenL(pszFilename, "rb"); if (fp == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot open file %s", pszFilename); return FALSE; } char** argv = GetArgv(bExplicitFeatures, bWaypoints, bRoutes, bTracks, pszGPSBabelDriverName, "-"); VSILFILE* tmpfp = VSIFOpenL(osTmpFileName.c_str(), "wb"); CPLPushErrorHandler(CPLQuietErrorHandler); bRet = (CPLSpawn(argv, fp, tmpfp, TRUE) == 0); CPLPopErrorHandler(); CSLDestroy(argv); argv = NULL; CPLErr nLastErrorType = CPLGetLastErrorType(); int nLastErrorNo = CPLGetLastErrorNo(); CPLString osLastErrorMsg = CPLGetLastErrorMsg(); VSIFCloseL(tmpfp); tmpfp = NULL; VSIFCloseL(fp); fp = NULL; if (!bRet) { if (strstr(osLastErrorMsg.c_str(), "This format cannot be used in piped commands") == NULL) { CPLError(nLastErrorType, nLastErrorNo, "%s", osLastErrorMsg.c_str()); } else { VSIStatBuf sStatBuf; if (VSIStat(pszFilename, &sStatBuf) != 0) { CPLError(CE_Failure, CPLE_NotSupported, "Driver %s only supports real (non virtual) files", pszGPSBabelDriverName); return FALSE; } /* Try without piping in */ argv = GetArgv(bExplicitFeatures, bWaypoints, bRoutes, bTracks, pszGPSBabelDriverName, pszFilename); tmpfp = VSIFOpenL(osTmpFileName.c_str(), "wb"); bRet = (CPLSpawn(argv, NULL, tmpfp, TRUE) == 0); VSIFCloseL(tmpfp); tmpfp = NULL; CSLDestroy(argv); argv = NULL; } } } if (bRet) { poGPXDS = OGRSFDriverRegistrar::Open(osTmpFileName.c_str()); if (poGPXDS) { OGRLayer* poLayer; if (bWaypoints) { poLayer = poGPXDS->GetLayerByName("waypoints"); if (poLayer != NULL && poLayer->GetFeatureCount() != 0) apoLayers[nLayers++] = poLayer; } if (bRoutes) { poLayer = poGPXDS->GetLayerByName("routes"); if (poLayer != NULL && poLayer->GetFeatureCount() != 0) apoLayers[nLayers++] = poLayer; poLayer = poGPXDS->GetLayerByName("route_points"); if (poLayer != NULL && poLayer->GetFeatureCount() != 0) apoLayers[nLayers++] = poLayer; } if (bTracks) { poLayer = poGPXDS->GetLayerByName("tracks"); if (poLayer != NULL && poLayer->GetFeatureCount() != 0) apoLayers[nLayers++] = poLayer; poLayer = poGPXDS->GetLayerByName("track_points"); if (poLayer != NULL && poLayer->GetFeatureCount() != 0) apoLayers[nLayers++] = poLayer; } } } return nLayers > 0; }
int OGRIdrisiDataSource::Open( const char * pszFilename ) { pszName = CPLStrdup( pszFilename ); VSILFILE* fpVCT = VSIFOpenL(pszFilename, "rb"); if (fpVCT == NULL) return FALSE; char* pszWTKString = NULL; // -------------------------------------------------------------------- // Look for .vdc file // -------------------------------------------------------------------- const char* pszVDCFilename = CPLResetExtension(pszFilename, "vdc"); VSILFILE* fpVDC = VSIFOpenL(pszVDCFilename, "rb"); if (fpVDC == NULL) { pszVDCFilename = CPLResetExtension(pszFilename, "VDC"); fpVDC = VSIFOpenL(pszVDCFilename, "rb"); } char** papszVDC = NULL; if (fpVDC != NULL) { VSIFCloseL(fpVDC); fpVDC = NULL; CPLPushErrorHandler(CPLQuietErrorHandler); papszVDC = CSLLoad2(pszVDCFilename, 1024, 256, NULL); CPLPopErrorHandler(); CPLErrorReset(); } OGRwkbGeometryType eType = wkbUnknown; if (papszVDC != NULL) { CSLSetNameValueSeparator( papszVDC, ":" ); const char *pszVersion = CSLFetchNameValue( papszVDC, "file format " ); if( pszVersion == NULL || !EQUAL( pszVersion, "IDRISI Vector A.1" ) ) { CSLDestroy( papszVDC ); VSIFCloseL(fpVCT); return FALSE; } const char *pszRefSystem = CSLFetchNameValue( papszVDC, "ref. system " ); const char *pszRefUnits = CSLFetchNameValue( papszVDC, "ref. units " ); if (pszRefSystem != NULL && pszRefUnits != NULL) IdrisiGeoReference2Wkt( pszFilename, pszRefSystem, pszRefUnits, &pszWTKString); } GByte chType; if (VSIFReadL(&chType, 1, 1, fpVCT) != 1) { VSIFCloseL(fpVCT); CSLDestroy( papszVDC ); return FALSE; } if (chType == 1) eType = wkbPoint; else if (chType == 2) eType = wkbLineString; else if (chType == 3) eType = wkbPolygon; else { CPLError(CE_Failure, CPLE_AppDefined, "Unsupport geometry type : %d", (int)chType); VSIFCloseL(fpVCT); CSLDestroy( papszVDC ); return FALSE; } const char *pszMinX = CSLFetchNameValue( papszVDC, "min. X " ); const char *pszMaxX = CSLFetchNameValue( papszVDC, "max. X " ); const char *pszMinY = CSLFetchNameValue( papszVDC, "min. Y " ); const char *pszMaxY = CSLFetchNameValue( papszVDC, "max. Y " ); OGRIdrisiLayer* poLayer = new OGRIdrisiLayer(pszFilename, CPLGetBasename(pszFilename), fpVCT, eType, pszWTKString); papoLayers = (OGRLayer**) CPLMalloc(sizeof(OGRLayer*)); papoLayers[nLayers ++] = poLayer; if (pszMinX != NULL && pszMaxX != NULL && pszMinY != NULL && pszMaxY != NULL) { poLayer->SetExtent(CPLAtof(pszMinX), CPLAtof(pszMinY), CPLAtof(pszMaxX), CPLAtof(pszMaxY)); } CPLFree(pszWTKString); CSLDestroy( papszVDC ); return TRUE; }
int EnvisatFile_Open( EnvisatFile **self_ptr, const char *filename, const char *mode ) { VSILFILE *fp; EnvisatFile *self; char mph_data[1248]; char *sph_data, *ds_data; int sph_size, num_dsd, dsd_size, i; *self_ptr = NULL; /* * Check for legal mode argument. Force to be binary for correct * operation on DOS file systems. */ if( strcmp(mode,"r") == 0 ) mode = "rb"; else if( strcmp(mode,"r+") == 0 ) mode = "rb+"; else { SendError( "Illegal mode value used in EnvisatFile_Open(), only " "\"r\" and \"r+\" are supported." ); return FAILURE; } /* * Try to open the file, and report failure. */ fp = VSIFOpenL( filename, mode ); if( fp == NULL ) { char error_buf[2048]; sprintf( error_buf, "Unable to open file \"%s\" in EnvisatFile_Open().", filename ); SendError( error_buf ); return FAILURE; } /* * Create, and initialize the EnvisatFile structure. */ self = (EnvisatFile *) calloc(sizeof(EnvisatFile),1); if( self == NULL ) return FAILURE; self->fp = fp; self->filename = strdup( filename ); self->header_dirty = 0; self->updatable = (strcmp(mode,"rb+") == 0); /* * Read the MPH, and process it as a group of name/value pairs. */ if( VSIFReadL( mph_data, 1, MPH_SIZE, fp ) != MPH_SIZE ) { free( self ); SendError( "VSIFReadL() for mph failed." ); return FAILURE; } mph_data[MPH_SIZE] = '\0'; if( S_NameValueList_Parse( mph_data, 0, &(self->mph_count), &(self->mph_entries) ) == FAILURE ) return FAILURE; /* * Is this an incomplete level 0 file? */ if( EnvisatFile_GetKeyValueAsInt( self, MPH, "SPH_SIZE", -1 ) == 0 && strncmp(EnvisatFile_GetKeyValueAsString( self, MPH, "PRODUCT", ""), "ASA_IM__0P", 10) == 0 ) { if( EnvisatFile_SetupLevel0( self ) == FAILURE ) { EnvisatFile_Close( self ); return FAILURE; } else { *self_ptr = self; return SUCCESS; } } /* * Read the SPH, and process it as a group of name/value pairs. */ sph_size = EnvisatFile_GetKeyValueAsInt( self, MPH, "SPH_SIZE", 0 ); if( sph_size == 0 ) { SendError( "File does not appear to have SPH," " SPH_SIZE not set, or zero." ); return FAILURE; } sph_data = (char *) malloc(sph_size + 1 ); if( sph_data == NULL ) return FAILURE; if( (int) VSIFReadL( sph_data, 1, sph_size, fp ) != sph_size ) { free( self ); SendError( "VSIFReadL() for sph failed." ); return FAILURE; } sph_data[sph_size] = '\0'; ds_data = strstr(sph_data,"DS_NAME"); if( ds_data != NULL ) { self->dsd_offset = (int) (ds_data - sph_data) + MPH_SIZE; *(ds_data-1) = '\0'; } if( S_NameValueList_Parse( sph_data, MPH_SIZE, &(self->sph_count), &(self->sph_entries) ) == FAILURE ) return FAILURE; /* * Parse the Dataset Definitions. */ num_dsd = EnvisatFile_GetKeyValueAsInt( self, MPH, "NUM_DSD", 0 ); dsd_size = EnvisatFile_GetKeyValueAsInt( self, MPH, "DSD_SIZE", 0 ); if( num_dsd > 0 && ds_data == NULL ) { SendError( "DSDs indicated in MPH, but not found in SPH." ); return FAILURE; } self->ds_info = (EnvisatDatasetInfo **) calloc(sizeof(EnvisatDatasetInfo*),num_dsd); if( self->ds_info == NULL ) return FAILURE; for( i = 0; i < num_dsd; i++ ) { int dsdh_count = 0; EnvisatNameValue **dsdh_entries = NULL; char *dsd_data; EnvisatDatasetInfo *ds_info; /* * We parse each DSD grouping into a name/value list. */ dsd_data = ds_data + i * dsd_size; dsd_data[dsd_size-1] = '\0'; if( S_NameValueList_Parse( dsd_data, 0, &dsdh_count, &dsdh_entries ) == FAILURE ) return FAILURE; /* * Then build the dataset into structure from that. */ ds_info = (EnvisatDatasetInfo *) calloc(sizeof(EnvisatDatasetInfo),1); ds_info->ds_name = strdup( S_NameValueList_FindValue( "DS_NAME", dsdh_count, dsdh_entries, "" )); ds_info->ds_type = strdup( S_NameValueList_FindValue( "DS_TYPE", dsdh_count, dsdh_entries, "" )); ds_info->filename = strdup( S_NameValueList_FindValue( "FILENAME", dsdh_count, dsdh_entries, "" )); ds_info->ds_offset = atoi( S_NameValueList_FindValue( "DS_OFFSET", dsdh_count, dsdh_entries, "0" )); ds_info->ds_size = atoi( S_NameValueList_FindValue( "DS_SIZE", dsdh_count, dsdh_entries, "0" )); ds_info->num_dsr = atoi( S_NameValueList_FindValue( "NUM_DSR", dsdh_count, dsdh_entries, "0" )); ds_info->dsr_size = atoi( S_NameValueList_FindValue( "DSR_SIZE", dsdh_count, dsdh_entries, "0" )); S_NameValueList_Destroy( &dsdh_count, &dsdh_entries ); self->ds_info[i] = ds_info; self->ds_count++; } free( sph_data ); /* * Return successfully. */ *self_ptr = self; return SUCCESS; }