int SRTMHGTDataset::Identify( GDALOpenInfo * poOpenInfo ) { const char* fileName = CPLGetFilename(poOpenInfo->pszFilename); if( strlen(fileName) < 11 || fileName[7] != '.' ) return FALSE; CPLString osLCFilename(CPLString(fileName).tolower()); if( (osLCFilename[0] != 'n' && osLCFilename[0] != 's') || (osLCFilename[3] != 'e' && osLCFilename[3] != 'w') ) return FALSE; if( !STARTS_WITH(fileName, "/vsizip/") && osLCFilename.endsWith(".hgt.zip") ) { CPLString osNewName("/vsizip/"); osNewName += poOpenInfo->pszFilename; osNewName += "/"; osNewName += CPLString(fileName).substr(0, 7); osNewName += ".hgt"; GDALOpenInfo oOpenInfo(osNewName, GA_ReadOnly); return Identify(&oOpenInfo); } if( !STARTS_WITH(fileName, "/vsizip/") && osLCFilename.endsWith(".srtmswbd.raw.zip") ) { CPLString osNewName("/vsizip/"); osNewName += poOpenInfo->pszFilename; osNewName += "/"; osNewName += CPLString(fileName).substr(0, 7); osNewName += ".raw"; GDALOpenInfo oOpenInfo(osNewName, GA_ReadOnly); return Identify(&oOpenInfo); } if( !osLCFilename.endsWith(".hgt") && !osLCFilename.endsWith(".raw") && !osLCFilename.endsWith(".hgt.gz") ) return FALSE; /* -------------------------------------------------------------------- */ /* We check the file size to see if it is */ /* SRTM1 (below or above lat 50) or SRTM 3 */ /* -------------------------------------------------------------------- */ VSIStatBufL fileStat; if(VSIStatL(poOpenInfo->pszFilename, &fileStat) != 0) return FALSE; if(fileStat.st_size != 3601 * 3601 && fileStat.st_size != 3601 * 3601 * 2 && fileStat.st_size != 1801 * 3601 * 2 && fileStat.st_size != 1201 * 1201 * 2 ) return FALSE; return TRUE; }
static CPLErr OGRTABDriverDelete( const char *pszDataSource ) { GDALDataset* poDS = NULL; { // Make sure that the file opened by GDALOpenInfo is closed // when the object goes out of scope GDALOpenInfo oOpenInfo(pszDataSource, GA_ReadOnly); poDS = OGRTABDriverOpen(&oOpenInfo); } if( poDS == NULL ) return CE_Failure; char** papszFileList = poDS->GetFileList(); delete poDS; char** papszIter = papszFileList; while( papszIter && *papszIter ) { VSIUnlink( *papszIter ); papszIter ++; } CSLDestroy(papszFileList); VSIStatBufL sStatBuf; if( VSIStatL( pszDataSource, &sStatBuf ) == 0 && VSI_ISDIR(sStatBuf.st_mode) ) { VSIRmdir( pszDataSource ); } return CE_None; }
GDALDataset *GDALWMSDataset::CreateCopy( const char * pszFilename, GDALDataset *poSrcDS, int bStrict, char ** papszOptions, GDALProgressFunc pfnProgress, void * pProgressData ) { if (poSrcDS->GetDriver() == NULL || !EQUAL(poSrcDS->GetDriver()->GetDescription(), "WMS")) { CPLError(CE_Failure, CPLE_NotSupported, "Source dataset must be a WMS dataset"); return NULL; } const char* pszXML = poSrcDS->GetMetadataItem("XML", "WMS"); if (pszXML == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot get XML definition of source WMS dataset"); return NULL; } VSILFILE* fp = VSIFOpenL(pszFilename, "wb"); if (fp == NULL) return NULL; VSIFWriteL(pszXML, 1, strlen(pszXML), fp); VSIFCloseL(fp); GDALOpenInfo oOpenInfo(pszFilename, GA_ReadOnly); return Open(&oOpenInfo); }
static CPLErr GNMDBDriverDelete( const char *pszDataSource ) { GDALOpenInfo oOpenInfo(pszDataSource, GA_Update); GNMDatabaseNetwork* poFN = new GNMDatabaseNetwork(); if( poFN->Open( &oOpenInfo ) != CE_None) { delete poFN; poFN = nullptr; return CE_Failure; } return poFN->Delete(); }
int SAFEDataset::Identify( GDALOpenInfo *poOpenInfo ) { /* Check for the case where we're trying to read the calibrated data: */ if (STARTS_WITH_CI(poOpenInfo->pszFilename, "SENTINEL1_CALIB:")) { return TRUE; } /* Check for the case where we're trying to read the subdatasets: */ if (STARTS_WITH_CI(poOpenInfo->pszFilename, "SENTINEL1_DS:")) { return TRUE; } /* Check for directory access when there is a manifest.safe file in the directory. */ if( poOpenInfo->bIsDirectory ) { VSIStatBufL sStat; CPLString osMDFilename = CPLFormCIFilename( poOpenInfo->pszFilename, "manifest.safe", nullptr ); if( VSIStatL( osMDFilename, &sStat ) == 0 && VSI_ISREG(sStat.st_mode) ) { GDALOpenInfo oOpenInfo( osMDFilename, GA_ReadOnly, nullptr ); return Identify(&oOpenInfo); } return FALSE; } /* otherwise, do our normal stuff */ if( !EQUAL(CPLGetFilename(poOpenInfo->pszFilename), "manifest.safe") ) return FALSE; if( poOpenInfo->nHeaderBytes < 100 ) return FALSE; if( strstr((const char *) poOpenInfo->pabyHeader, "<xfdu:XFDU" ) == nullptr) return FALSE; // This driver doesn't handle Sentinel-2 data if( strstr((const char *) poOpenInfo->pabyHeader, "sentinel-2" ) != nullptr) return FALSE; return TRUE; }
int OGRESRIFeatureServiceDataset::LoadPage() { CPLString osNewURL = CPLURLAddKVP(osURL, "resultOffset", CPLSPrintf(CPL_FRMT_GIB, nLastOffset)); OGRGeoJSONDataSource* poDS = NULL; poDS = new OGRGeoJSONDataSource(); GDALOpenInfo oOpenInfo(osNewURL, GA_ReadOnly); if( !poDS->Open( &oOpenInfo, GeoJSONGetSourceType( &oOpenInfo ) ) || poDS->GetLayerCount() == 0 ) { delete poDS; poDS= NULL; return FALSE; } delete poCurrent; poCurrent = poDS; return TRUE; }
static GDALDataset *OGRTABDriverOpen( GDALOpenInfo* poOpenInfo ) { OGRTABDataSource *poDS; if( OGRTABDriverIdentify(poOpenInfo) == FALSE ) { return NULL; } if (EQUAL(CPLGetExtension(poOpenInfo->pszFilename), "MIF") || EQUAL(CPLGetExtension(poOpenInfo->pszFilename), "MID") ) { if( poOpenInfo->eAccess == GA_Update ) return NULL; } #ifdef DEBUG /* For AFL, so that .cur_input is detected as the archive filename */ if( poOpenInfo->fpL != NULL && !STARTS_WITH(poOpenInfo->pszFilename, "/vsitar/") && EQUAL(CPLGetFilename(poOpenInfo->pszFilename), ".cur_input") ) { GDALOpenInfo oOpenInfo( (CPLString("/vsitar/") + poOpenInfo->pszFilename).c_str(), poOpenInfo->nOpenFlags ); oOpenInfo.papszOpenOptions = poOpenInfo->papszOpenOptions; return OGRTABDriverOpen(&oOpenInfo); } #endif poDS = new OGRTABDataSource(); if( poDS->Open( poOpenInfo, TRUE ) ) return poDS; else { delete poDS; return NULL; } }
GDALDataset * WEBPDataset::CreateCopy( const char * pszFilename, GDALDataset *poSrcDS, int bStrict, char ** papszOptions, GDALProgressFunc pfnProgress, void * pProgressData ) { int nBands = poSrcDS->GetRasterCount(); int nXSize = poSrcDS->GetRasterXSize(); int nYSize = poSrcDS->GetRasterYSize(); /* -------------------------------------------------------------------- */ /* WEBP library initialization */ /* -------------------------------------------------------------------- */ WebPPicture sPicture; if (!WebPPictureInit(&sPicture)) { CPLError(CE_Failure, CPLE_AppDefined, "WebPPictureInit() failed"); return NULL; } /* -------------------------------------------------------------------- */ /* Some some rudimentary checks */ /* -------------------------------------------------------------------- */ if( nXSize > 16383 || nYSize > 16383 ) { CPLError( CE_Failure, CPLE_NotSupported, "WEBP maximum image dimensions are 16383 x 16383."); return NULL; } if( nBands != 3 #if WEBP_ENCODER_ABI_VERSION >= 0x0100 && nBands != 4 #endif ) { CPLError( CE_Failure, CPLE_NotSupported, "WEBP driver doesn't support %d bands. Must be 3 (RGB) " #if WEBP_ENCODER_ABI_VERSION >= 0x0100 "or 4 (RGBA) " #endif "bands.", nBands ); return NULL; } GDALDataType eDT = poSrcDS->GetRasterBand(1)->GetRasterDataType(); if( eDT != GDT_Byte ) { CPLError( (bStrict) ? CE_Failure : CE_Warning, CPLE_NotSupported, "WEBP driver doesn't support data type %s. " "Only eight bit byte bands supported.", GDALGetDataTypeName( poSrcDS->GetRasterBand(1)->GetRasterDataType()) ); if (bStrict) return NULL; } /* -------------------------------------------------------------------- */ /* What options has the user selected? */ /* -------------------------------------------------------------------- */ float fQuality = 75.0f; const char* pszQUALITY = CSLFetchNameValue(papszOptions, "QUALITY"); if( pszQUALITY != NULL ) { fQuality = (float) CPLAtof(pszQUALITY); if( fQuality < 0.0f || fQuality > 100.0f ) { CPLError( CE_Failure, CPLE_IllegalArg, "%s=%s is not a legal value.", "QUALITY", pszQUALITY); return NULL; } } WebPPreset nPreset = WEBP_PRESET_DEFAULT; const char* pszPRESET = CSLFetchNameValueDef(papszOptions, "PRESET", "DEFAULT"); if (EQUAL(pszPRESET, "DEFAULT")) nPreset = WEBP_PRESET_DEFAULT; else if (EQUAL(pszPRESET, "PICTURE")) nPreset = WEBP_PRESET_PICTURE; else if (EQUAL(pszPRESET, "PHOTO")) nPreset = WEBP_PRESET_PHOTO; else if (EQUAL(pszPRESET, "PICTURE")) nPreset = WEBP_PRESET_PICTURE; else if (EQUAL(pszPRESET, "DRAWING")) nPreset = WEBP_PRESET_DRAWING; else if (EQUAL(pszPRESET, "ICON")) nPreset = WEBP_PRESET_ICON; else if (EQUAL(pszPRESET, "TEXT")) nPreset = WEBP_PRESET_TEXT; else { CPLError( CE_Failure, CPLE_IllegalArg, "%s=%s is not a legal value.", "PRESET", pszPRESET ); return NULL; } WebPConfig sConfig; if (!WebPConfigInitInternal(&sConfig, nPreset, fQuality, WEBP_ENCODER_ABI_VERSION)) { CPLError(CE_Failure, CPLE_AppDefined, "WebPConfigInit() failed"); return NULL; } #define FETCH_AND_SET_OPTION_INT(name, fieldname, minval, maxval) \ { \ const char* pszVal = CSLFetchNameValue(papszOptions, name); \ if (pszVal != NULL) \ { \ sConfig.fieldname = atoi(pszVal); \ if (sConfig.fieldname < minval || sConfig.fieldname > maxval) \ { \ CPLError( CE_Failure, CPLE_IllegalArg, \ "%s=%s is not a legal value.", name, pszVal ); \ return NULL; \ } \ } \ } FETCH_AND_SET_OPTION_INT("TARGETSIZE", target_size, 0, INT_MAX); const char* pszPSNR = CSLFetchNameValue(papszOptions, "PSNR"); if (pszPSNR) { sConfig.target_PSNR = CPLAtof(pszPSNR); if (sConfig.target_PSNR < 0) { CPLError( CE_Failure, CPLE_IllegalArg, "PSNR=%s is not a legal value.", pszPSNR ); return NULL; } } FETCH_AND_SET_OPTION_INT("METHOD", method, 0, 6); FETCH_AND_SET_OPTION_INT("SEGMENTS", segments, 1, 4); FETCH_AND_SET_OPTION_INT("SNS_STRENGTH", sns_strength, 0, 100); FETCH_AND_SET_OPTION_INT("FILTER_STRENGTH", filter_strength, 0, 100); FETCH_AND_SET_OPTION_INT("FILTER_SHARPNESS", filter_sharpness, 0, 7); FETCH_AND_SET_OPTION_INT("FILTER_TYPE", filter_type, 0, 1); FETCH_AND_SET_OPTION_INT("AUTOFILTER", autofilter, 0, 1); FETCH_AND_SET_OPTION_INT("PASS", pass, 1, 10); FETCH_AND_SET_OPTION_INT("PREPROCESSING", preprocessing, 0, 1); FETCH_AND_SET_OPTION_INT("PARTITIONS", partitions, 0, 3); #if WEBP_ENCODER_ABI_VERSION >= 0x0002 FETCH_AND_SET_OPTION_INT("PARTITION_LIMIT", partition_limit, 0, 100); #endif #if WEBP_ENCODER_ABI_VERSION >= 0x0100 sConfig.lossless = CSLFetchBoolean(papszOptions, "LOSSLESS", FALSE); if (sConfig.lossless) sPicture.use_argb = 1; #endif if (!WebPValidateConfig(&sConfig)) { CPLError(CE_Failure, CPLE_AppDefined, "WebPValidateConfig() failed"); return NULL; } /* -------------------------------------------------------------------- */ /* Allocate memory */ /* -------------------------------------------------------------------- */ GByte *pabyBuffer; pabyBuffer = (GByte *) VSIMalloc( nBands * nXSize * nYSize ); if (pabyBuffer == NULL) { return NULL; } /* -------------------------------------------------------------------- */ /* Create the dataset. */ /* -------------------------------------------------------------------- */ VSILFILE *fpImage; fpImage = VSIFOpenL( pszFilename, "wb" ); if( fpImage == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "Unable to create WEBP file %s.\n", pszFilename ); VSIFree(pabyBuffer); return NULL; } WebPUserData sUserData; sUserData.fp = fpImage; sUserData.pfnProgress = pfnProgress ? pfnProgress : GDALDummyProgress; sUserData.pProgressData = pProgressData; /* -------------------------------------------------------------------- */ /* WEBP library settings */ /* -------------------------------------------------------------------- */ sPicture.width = nXSize; sPicture.height = nYSize; sPicture.writer = WEBPDatasetWriter; sPicture.custom_ptr = &sUserData; #if WEBP_ENCODER_ABI_VERSION >= 0x0100 sPicture.progress_hook = WEBPDatasetProgressHook; #endif if (!WebPPictureAlloc(&sPicture)) { CPLError(CE_Failure, CPLE_AppDefined, "WebPPictureAlloc() failed"); VSIFree(pabyBuffer); VSIFCloseL( fpImage ); return NULL; } /* -------------------------------------------------------------------- */ /* Acquire source imagery. */ /* -------------------------------------------------------------------- */ CPLErr eErr = CE_None; eErr = poSrcDS->RasterIO( GF_Read, 0, 0, nXSize, nYSize, pabyBuffer, nXSize, nYSize, GDT_Byte, nBands, NULL, nBands, nBands * nXSize, 1, NULL ); /* -------------------------------------------------------------------- */ /* Import and write to file */ /* -------------------------------------------------------------------- */ #if WEBP_ENCODER_ABI_VERSION >= 0x0100 if (eErr == CE_None && nBands == 4) { if (!WebPPictureImportRGBA(&sPicture, pabyBuffer, nBands * nXSize)) { CPLError(CE_Failure, CPLE_AppDefined, "WebPPictureImportRGBA() failed"); eErr = CE_Failure; } } else #endif if (eErr == CE_None && !WebPPictureImportRGB(&sPicture, pabyBuffer, nBands * nXSize)) { CPLError(CE_Failure, CPLE_AppDefined, "WebPPictureImportRGB() failed"); eErr = CE_Failure; } if (eErr == CE_None && !WebPEncode(&sConfig, &sPicture)) { const char* pszErrorMsg = NULL; #if WEBP_ENCODER_ABI_VERSION >= 0x0100 switch(sPicture.error_code) { case VP8_ENC_ERROR_OUT_OF_MEMORY: pszErrorMsg = "Out of memory"; break; case VP8_ENC_ERROR_BITSTREAM_OUT_OF_MEMORY: pszErrorMsg = "Out of memory while flushing bits"; break; case VP8_ENC_ERROR_NULL_PARAMETER: pszErrorMsg = "A pointer parameter is NULL"; break; case VP8_ENC_ERROR_INVALID_CONFIGURATION: pszErrorMsg = "Configuration is invalid"; break; case VP8_ENC_ERROR_BAD_DIMENSION: pszErrorMsg = "Picture has invalid width/height"; break; case VP8_ENC_ERROR_PARTITION0_OVERFLOW: pszErrorMsg = "Partition is bigger than 512k. Try using less SEGMENTS, or increase PARTITION_LIMIT value"; break; case VP8_ENC_ERROR_PARTITION_OVERFLOW: pszErrorMsg = "Partition is bigger than 16M"; break; case VP8_ENC_ERROR_BAD_WRITE: pszErrorMsg = "Error while flusing bytes"; break; case VP8_ENC_ERROR_FILE_TOO_BIG: pszErrorMsg = "File is bigger than 4G"; break; case VP8_ENC_ERROR_USER_ABORT: pszErrorMsg = "User interrupted"; break; default: break; } #endif if (pszErrorMsg) CPLError(CE_Failure, CPLE_AppDefined, "WebPEncode() failed : %s", pszErrorMsg); else CPLError(CE_Failure, CPLE_AppDefined, "WebPEncode() failed"); eErr = CE_Failure; } /* -------------------------------------------------------------------- */ /* Cleanup and close. */ /* -------------------------------------------------------------------- */ CPLFree( pabyBuffer ); WebPPictureFree(&sPicture); VSIFCloseL( fpImage ); if( eErr != CE_None ) { VSIUnlink( pszFilename ); return NULL; } /* -------------------------------------------------------------------- */ /* Re-open dataset, and copy any auxiliary pam information. */ /* -------------------------------------------------------------------- */ GDALOpenInfo oOpenInfo(pszFilename, GA_ReadOnly); /* If outputing to stdout, we can't reopen it, so we'll return */ /* a fake dataset to make the caller happy */ CPLPushErrorHandler(CPLQuietErrorHandler); WEBPDataset *poDS = (WEBPDataset*) WEBPDataset::Open( &oOpenInfo ); CPLPopErrorHandler(); if( poDS ) { poDS->CloneInfo( poSrcDS, GCIF_PAM_DEFAULT ); return poDS; } return NULL; }
GDALDataset * WEBPDataset::CreateCopy( const char * pszFilename, GDALDataset *poSrcDS, int bStrict, char ** papszOptions, GDALProgressFunc pfnProgress, void * pProgressData ) { int nBands = poSrcDS->GetRasterCount(); int nXSize = poSrcDS->GetRasterXSize(); int nYSize = poSrcDS->GetRasterYSize(); /* -------------------------------------------------------------------- */ /* WEBP library initialization */ /* -------------------------------------------------------------------- */ WebPPicture sPicture; if (!WebPPictureInit(&sPicture)) { CPLError(CE_Failure, CPLE_AppDefined, "WebPPictureInit() failed"); return NULL; } /* -------------------------------------------------------------------- */ /* Some some rudimentary checks */ /* -------------------------------------------------------------------- */ if( nXSize > 16383 || nYSize > 16383 ) { CPLError( CE_Failure, CPLE_NotSupported, "WEBP maximum image dimensions are 16383 x 16383."); return NULL; } if( nBands != 3 ) { CPLError( CE_Failure, CPLE_NotSupported, "WEBP driver doesn't support %d bands. Must be 3 (RGB) bands.", nBands ); return NULL; } GDALDataType eDT = poSrcDS->GetRasterBand(1)->GetRasterDataType(); if( eDT != GDT_Byte ) { CPLError( (bStrict) ? CE_Failure : CE_Warning, CPLE_NotSupported, "WEBP driver doesn't support data type %s. " "Only eight bit byte bands supported.", GDALGetDataTypeName( poSrcDS->GetRasterBand(1)->GetRasterDataType()) ); if (bStrict) return NULL; } /* -------------------------------------------------------------------- */ /* What options has the user selected? */ /* -------------------------------------------------------------------- */ float fQuality = 75.0f; const char* pszQUALITY = CSLFetchNameValue(papszOptions, "QUALITY"); if( pszQUALITY != NULL ) { fQuality = (float) atof(pszQUALITY); if( fQuality < 0.0f || fQuality > 100.0f ) { CPLError( CE_Failure, CPLE_IllegalArg, "%s=%s is not a legal value.", "QUALITY", pszQUALITY); return NULL; } } WebPPreset nPreset = WEBP_PRESET_DEFAULT; const char* pszPRESET = CSLFetchNameValueDef(papszOptions, "PRESET", "DEFAULT"); if (EQUAL(pszPRESET, "DEFAULT")) nPreset = WEBP_PRESET_DEFAULT; else if (EQUAL(pszPRESET, "PICTURE")) nPreset = WEBP_PRESET_PICTURE; else if (EQUAL(pszPRESET, "PHOTO")) nPreset = WEBP_PRESET_PHOTO; else if (EQUAL(pszPRESET, "PICTURE")) nPreset = WEBP_PRESET_PICTURE; else if (EQUAL(pszPRESET, "DRAWING")) nPreset = WEBP_PRESET_DRAWING; else if (EQUAL(pszPRESET, "ICON")) nPreset = WEBP_PRESET_ICON; else if (EQUAL(pszPRESET, "TEXT")) nPreset = WEBP_PRESET_TEXT; else { CPLError( CE_Failure, CPLE_IllegalArg, "%s=%s is not a legal value.", "PRESET", pszPRESET ); return NULL; } WebPConfig sConfig; if (!WebPConfigInitInternal(&sConfig, nPreset, fQuality, WEBP_ENCODER_ABI_VERSION)) { CPLError(CE_Failure, CPLE_AppDefined, "WebPConfigInit() failed"); return NULL; } #define FETCH_AND_SET_OPTION_INT(name, fieldname, minval, maxval) \ { \ const char* pszVal = CSLFetchNameValue(papszOptions, name); \ if (pszVal != NULL) \ { \ sConfig.fieldname = atoi(pszVal); \ if (sConfig.fieldname < minval || sConfig.fieldname > maxval) \ { \ CPLError( CE_Failure, CPLE_IllegalArg, \ "%s=%s is not a legal value.", name, pszVal ); \ return NULL; \ } \ } \ } FETCH_AND_SET_OPTION_INT("TARGETSIZE", target_size, 0, INT_MAX); const char* pszPSNR = CSLFetchNameValue(papszOptions, "PSNR"); if (pszPSNR) { sConfig.target_PSNR = atof(pszPSNR); if (sConfig.target_PSNR < 0) { CPLError( CE_Failure, CPLE_IllegalArg, "PSNR=%s is not a legal value.", pszPSNR ); return NULL; } } FETCH_AND_SET_OPTION_INT("METHOD", method, 0, 6); FETCH_AND_SET_OPTION_INT("SEGMENTS", segments, 1, 4); FETCH_AND_SET_OPTION_INT("SNS_STRENGTH", sns_strength, 0, 100); FETCH_AND_SET_OPTION_INT("FILTER_STRENGTH", filter_strength, 0, 100); FETCH_AND_SET_OPTION_INT("FILTER_SHARPNESS", filter_sharpness, 0, 7); FETCH_AND_SET_OPTION_INT("FILTER_TYPE", filter_type, 0, 1); FETCH_AND_SET_OPTION_INT("AUTOFILTER", autofilter, 0, 1); FETCH_AND_SET_OPTION_INT("PASS", pass, 1, 10); FETCH_AND_SET_OPTION_INT("PREPROCESSING", preprocessing, 0, 1); FETCH_AND_SET_OPTION_INT("PARTITIONS", partitions, 0, 3); if (!WebPValidateConfig(&sConfig)) { CPLError(CE_Failure, CPLE_AppDefined, "WebPValidateConfig() failed"); return NULL; } /* -------------------------------------------------------------------- */ /* Allocate memory */ /* -------------------------------------------------------------------- */ GByte *pabyBuffer; pabyBuffer = (GByte *) VSIMalloc( 3 * nXSize * nYSize ); if (pabyBuffer == NULL) { return NULL; } /* -------------------------------------------------------------------- */ /* Create the dataset. */ /* -------------------------------------------------------------------- */ VSILFILE *fpImage; fpImage = VSIFOpenL( pszFilename, "wb" ); if( fpImage == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "Unable to create WEBP file %s.\n", pszFilename ); VSIFree(pabyBuffer); return NULL; } /* -------------------------------------------------------------------- */ /* WEBP library settings */ /* -------------------------------------------------------------------- */ sPicture.colorspace = 0; sPicture.width = nXSize; sPicture.height = nYSize; sPicture.writer = WEBPDatasetWriter; sPicture.custom_ptr = fpImage; if (!WebPPictureAlloc(&sPicture)) { CPLError(CE_Failure, CPLE_AppDefined, "WebPPictureAlloc() failed"); VSIFree(pabyBuffer); VSIFCloseL( fpImage ); return NULL; } /* -------------------------------------------------------------------- */ /* Acquire source imagery. */ /* -------------------------------------------------------------------- */ CPLErr eErr = CE_None; eErr = poSrcDS->RasterIO( GF_Read, 0, 0, nXSize, nYSize, pabyBuffer, nXSize, nYSize, GDT_Byte, 3, NULL, 3, 3 * nXSize, 1 ); /* -------------------------------------------------------------------- */ /* Import and write to file */ /* -------------------------------------------------------------------- */ if (eErr == CE_None && !WebPPictureImportRGB(&sPicture, pabyBuffer, 3 * nXSize)) { CPLError(CE_Failure, CPLE_AppDefined, "WebPPictureImportRGB() failed"); eErr = CE_Failure; } if (eErr == CE_None && !WebPEncode(&sConfig, &sPicture)) { CPLError(CE_Failure, CPLE_AppDefined, "WebPEncode() failed"); eErr = CE_Failure; } /* -------------------------------------------------------------------- */ /* Cleanup and close. */ /* -------------------------------------------------------------------- */ CPLFree( pabyBuffer ); WebPPictureFree(&sPicture); VSIFCloseL( fpImage ); if( eErr != CE_None ) { VSIUnlink( pszFilename ); return NULL; } /* -------------------------------------------------------------------- */ /* Re-open dataset, and copy any auxilary pam information. */ /* -------------------------------------------------------------------- */ GDALOpenInfo oOpenInfo(pszFilename, GA_ReadOnly); /* If outputing to stdout, we can't reopen it, so we'll return */ /* a fake dataset to make the caller happy */ CPLPushErrorHandler(CPLQuietErrorHandler); WEBPDataset *poDS = (WEBPDataset*) WEBPDataset::Open( &oOpenInfo ); CPLPopErrorHandler(); if( poDS ) { poDS->CloneInfo( poSrcDS, GCIF_PAM_DEFAULT ); return poDS; } return NULL; }
GDALDataset* SRTMHGTDataset::Open(GDALOpenInfo* poOpenInfo) { if (!Identify(poOpenInfo)) return nullptr; const char* fileName = CPLGetFilename(poOpenInfo->pszFilename); CPLString osLCFilename(CPLString(fileName).tolower()); if( !STARTS_WITH(fileName, "/vsizip/") && osLCFilename.endsWith(".hgt.zip") ) { CPLString osFilename ("/vsizip/"); osFilename += poOpenInfo->pszFilename; osFilename += "/"; osFilename += CPLString(fileName).substr(0, 7); osFilename += ".hgt"; GDALOpenInfo oOpenInfo(osFilename, poOpenInfo->eAccess); GDALDataset* poDS = Open(&oOpenInfo); if( poDS != nullptr ) { // override description with the main one poDS->SetDescription(poOpenInfo->pszFilename); } return poDS; } if( !STARTS_WITH(fileName, "/vsizip/") && osLCFilename.endsWith(".srtmswbd.raw.zip") ) { CPLString osFilename("/vsizip/"); osFilename += poOpenInfo->pszFilename; osFilename += "/"; osFilename += CPLString(fileName).substr(0, 7); osFilename += ".raw"; GDALOpenInfo oOpenInfo(osFilename, poOpenInfo->eAccess); GDALDataset* poDS = Open(&oOpenInfo); if( poDS != nullptr ) { // override description with the main one poDS->SetDescription(poOpenInfo->pszFilename); } return poDS; } char latLonValueString[4]; memset(latLonValueString, 0, 4); strncpy(latLonValueString, &fileName[1], 2); int southWestLat = atoi(latLonValueString); memset(latLonValueString, 0, 4); // cppcheck-suppress redundantCopy strncpy(latLonValueString, &fileName[4], 3); int southWestLon = atoi(latLonValueString); if(fileName[0] == 'N' || fileName[0] == 'n') /*southWestLat = southWestLat */; else if(fileName[0] == 'S' || fileName[0] == 's') southWestLat = southWestLat * -1; else return nullptr; if(fileName[3] == 'E' || fileName[3] == 'e') /*southWestLon = southWestLon */; else if(fileName[3] == 'W' || fileName[3] == 'w') southWestLon = southWestLon * -1; else return nullptr; /* -------------------------------------------------------------------- */ /* Create a corresponding GDALDataset. */ /* -------------------------------------------------------------------- */ SRTMHGTDataset* poDS = new SRTMHGTDataset(); poDS->fpImage = poOpenInfo->fpL; poOpenInfo->fpL = nullptr; VSIStatBufL fileStat; if(VSIStatL(poOpenInfo->pszFilename, &fileStat) != 0) { delete poDS; return nullptr; } int numPixels_x, numPixels_y; GDALDataType eDT = GDT_Int16; switch (fileStat.st_size) { case 3601 * 3601: numPixels_x = numPixels_y = 3601; eDT = GDT_Byte; break; case 3601 * 3601 * 2: numPixels_x = numPixels_y = 3601; break; case 1801 * 3601 * 2: numPixels_x = 1801; numPixels_y = 3601; break; case 1201 * 1201 * 2: numPixels_x = numPixels_y = 1201; break; default: numPixels_x = numPixels_y = 0; break; } poDS->eAccess = poOpenInfo->eAccess; #ifdef CPL_LSB if(poDS->eAccess == GA_Update && eDT == GDT_Int16) { poDS->panBuffer = reinterpret_cast<GInt16 *>( CPLMalloc(numPixels_x * sizeof(GInt16)) ); } #endif /* -------------------------------------------------------------------- */ /* Capture some information from the file that is of interest. */ /* -------------------------------------------------------------------- */ poDS->nRasterXSize = numPixels_x; poDS->nRasterYSize = numPixels_y; poDS->nBands = 1; poDS->adfGeoTransform[0] = southWestLon - 0.5 / (numPixels_x - 1); poDS->adfGeoTransform[1] = 1.0 / (numPixels_x-1); poDS->adfGeoTransform[2] = 0.0; poDS->adfGeoTransform[3] = southWestLat + 1 + 0.5 / (numPixels_y - 1); poDS->adfGeoTransform[4] = 0.0; poDS->adfGeoTransform[5] = -1.0 / (numPixels_y-1); poDS->SetMetadataItem( GDALMD_AREA_OR_POINT, GDALMD_AOP_POINT ); /* -------------------------------------------------------------------- */ /* Create band information object. */ /* -------------------------------------------------------------------- */ SRTMHGTRasterBand* tmpBand = new SRTMHGTRasterBand(poDS, 1, eDT); poDS->SetBand(1, tmpBand); /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ poDS->SetDescription(poOpenInfo->pszFilename); poDS->TryLoadXML(); /* -------------------------------------------------------------------- */ /* Support overviews. */ /* -------------------------------------------------------------------- */ poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename ); return poDS; }
GDALDataset* ECRGTOCDataset::Build(const char* pszTOCFilename, CPLXMLNode* psXML, CPLString osProduct, CPLString osDiscId, const char* pszOpenInfoFilename) { CPLXMLNode* psTOC = CPLGetXMLNode(psXML, "=Table_of_Contents"); if (psTOC == NULL) { CPLError(CE_Warning, CPLE_AppDefined, "Cannot find Table_of_Contents element"); return NULL; } double dfGlobalMinX = 0, dfGlobalMinY = 0, dfGlobalMaxX = 0, dfGlobalMaxY= 0; double dfGlobalPixelXSize = 0, dfGlobalPixelYSize = 0; int bGlobalExtentValid = FALSE; ECRGTOCDataset* poDS = new ECRGTOCDataset(); int nSubDatasets = 0; int bLookForSubDataset = osProduct.size() != 0 && osDiscId.size() != 0; int nCountSubDataset = 0; poDS->SetDescription( pszOpenInfoFilename ); poDS->papszFileList = poDS->GDALDataset::GetFileList(); for(CPLXMLNode* psIter1 = psTOC->psChild; psIter1 != NULL; psIter1 = psIter1->psNext) { if (!(psIter1->eType == CXT_Element && psIter1->pszValue != NULL && strcmp(psIter1->pszValue, "product") == 0)) continue; const char* pszProductTitle = CPLGetXMLValue(psIter1, "product_title", NULL); if (pszProductTitle == NULL) { CPLError(CE_Warning, CPLE_AppDefined, "Cannot find product_title attribute"); continue; } if (bLookForSubDataset && strcmp(pszProductTitle, osProduct.c_str()) != 0) continue; for(CPLXMLNode* psIter2 = psIter1->psChild; psIter2 != NULL; psIter2 = psIter2->psNext) { if (!(psIter2->eType == CXT_Element && psIter2->pszValue != NULL && strcmp(psIter2->pszValue, "disc") == 0)) continue; const char* pszDiscId = CPLGetXMLValue(psIter2, "id", NULL); if (pszDiscId == NULL) { CPLError(CE_Warning, CPLE_AppDefined, "Cannot find id attribute"); continue; } if (bLookForSubDataset && strcmp(pszDiscId, osDiscId.c_str()) != 0) continue; nCountSubDataset ++; CPLXMLNode* psFrameList = CPLGetXMLNode(psIter2, "frame_list"); if (psFrameList == NULL) { CPLError(CE_Warning, CPLE_AppDefined, "Cannot find frame_list element"); continue; } int nValidFrames = 0; std::vector<FrameDesc> aosFrameDesc; int nSubDatasetScale = -1; for(CPLXMLNode* psIter3 = psFrameList->psChild; psIter3 != NULL; psIter3 = psIter3->psNext) { if (!(psIter3->eType == CXT_Element && psIter3->pszValue != NULL && strcmp(psIter3->pszValue, "scale") == 0)) continue; const char* pszSize = CPLGetXMLValue(psIter3, "size", NULL); if (pszSize == NULL) { CPLError(CE_Warning, CPLE_AppDefined, "Cannot find size attribute"); continue; } int nScale = GetScaleFromString(pszSize); if (nScale <= 0) { CPLError(CE_Warning, CPLE_AppDefined, "Invalid scale %s", pszSize); continue; } if (nValidFrames == 0) nSubDatasetScale = nScale; else nSubDatasetScale = -1; for(CPLXMLNode* psIter4 = psIter3->psChild; psIter4 != NULL; psIter4 = psIter4->psNext) { if (!(psIter4->eType == CXT_Element && psIter4->pszValue != NULL && strcmp(psIter4->pszValue, "frame") == 0)) continue; const char* pszFrameName = CPLGetXMLValue(psIter4, "name", NULL); if (pszFrameName == NULL) { CPLError(CE_Warning, CPLE_AppDefined, "Cannot find name element"); continue; } if (strlen(pszFrameName) != 18) { CPLError(CE_Warning, CPLE_AppDefined, "Invalid value for name element : %s", pszFrameName); continue; } const char* pszFramePath = CPLGetXMLValue(psIter4, "frame_path", NULL); if (pszFramePath == NULL) { CPLError(CE_Warning, CPLE_AppDefined, "Cannot find frame_path element"); continue; } const char* pszFrameZone = CPLGetXMLValue(psIter4, "frame_zone", NULL); if (pszFrameZone == NULL) { CPLError(CE_Warning, CPLE_AppDefined, "Cannot find frame_zone element"); continue; } if (strlen(pszFrameZone) != 1) { CPLError(CE_Warning, CPLE_AppDefined, "Invalid value for frame_zone element : %s", pszFrameZone); continue; } char chZone = pszFrameZone[0]; int nZone = 0; if (chZone >= '1' && chZone <= '9') nZone = chZone - '0'; else if (chZone >= 'a' && chZone <= 'h') nZone = -(chZone - 'a' + 1); else if (chZone >= 'A' && chZone <= 'H') nZone = -(chZone - 'A' + 1); else if (chZone == 'j' || chZone == 'J') nZone = -9; else { CPLError(CE_Warning, CPLE_AppDefined, "Invalid value for frame_zone element : %s", pszFrameZone); continue; } if (nZone == 9 || nZone == -9) { CPLError(CE_Warning, CPLE_AppDefined, "Polar zones unhandled by current implementation"); continue; } double dfMinX = 0, dfMaxX = 0, dfMinY = 0, dfMaxY = 0, dfPixelXSize = 0, dfPixelYSize = 0; if (!GetExtent(pszFrameName, nScale, nZone, dfMinX, dfMaxX, dfMinY, dfMaxY, dfPixelXSize, dfPixelYSize)) { continue; } nValidFrames ++; const char* pszFullName = BuildFullName(pszTOCFilename, pszFramePath, pszFrameName); poDS->papszFileList = CSLAddString(poDS->papszFileList, pszFullName); if (!bGlobalExtentValid) { dfGlobalMinX = dfMinX; dfGlobalMinY = dfMinY; dfGlobalMaxX = dfMaxX; dfGlobalMaxY = dfMaxY; dfGlobalPixelXSize = dfPixelXSize; dfGlobalPixelYSize = dfPixelYSize; bGlobalExtentValid = TRUE; } else { if (dfMinX < dfGlobalMinX) dfGlobalMinX = dfMinX; if (dfMinY < dfGlobalMinY) dfGlobalMinY = dfMinY; if (dfMaxX > dfGlobalMaxX) dfGlobalMaxX = dfMaxX; if (dfMaxY > dfGlobalMaxY) dfGlobalMaxY = dfMaxY; if (dfPixelXSize < dfGlobalPixelXSize) dfGlobalPixelXSize = dfPixelXSize; if (dfPixelYSize < dfGlobalPixelYSize) dfGlobalPixelYSize = dfPixelYSize; } if (bLookForSubDataset) { FrameDesc frameDesc; frameDesc.pszName = pszFrameName; frameDesc.pszPath = pszFramePath; frameDesc.nScale = nScale; frameDesc.nZone = nZone; aosFrameDesc.push_back(frameDesc); } } } if (bLookForSubDataset) { delete poDS; if (nValidFrames == 0) return NULL; return ECRGTOCSubDataset::Build(pszProductTitle, pszDiscId, nSubDatasetScale, nCountSubDataset, pszTOCFilename, aosFrameDesc, dfGlobalMinX, dfGlobalMinY, dfGlobalMaxX, dfGlobalMaxY, dfGlobalPixelXSize, dfGlobalPixelYSize); } if (nValidFrames) { poDS->AddSubDataset(pszOpenInfoFilename, pszProductTitle, pszDiscId); nSubDatasets ++; } } } if (!bGlobalExtentValid) { delete poDS; return NULL; } if (nSubDatasets == 1) { const char* pszSubDatasetName = CSLFetchNameValue( poDS->GetMetadata("SUBDATASETS"), "SUBDATASET_1_NAME"); GDALOpenInfo oOpenInfo(pszSubDatasetName, GA_ReadOnly); delete poDS; GDALDataset* poRetDS = Open(&oOpenInfo); if (poRetDS) poRetDS->SetDescription(pszOpenInfoFilename); return poRetDS; } poDS->adfGeoTransform[0] = dfGlobalMinX; poDS->adfGeoTransform[1] = dfGlobalPixelXSize; poDS->adfGeoTransform[2] = 0.0; poDS->adfGeoTransform[3] = dfGlobalMaxY; poDS->adfGeoTransform[4] = 0.0; poDS->adfGeoTransform[5] = - dfGlobalPixelYSize; poDS->nRasterXSize = (int)(0.5 + (dfGlobalMaxX - dfGlobalMinX) / dfGlobalPixelXSize); poDS->nRasterYSize = (int)(0.5 + (dfGlobalMaxY - dfGlobalMinY) / dfGlobalPixelYSize); /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ poDS->TryLoadXML(); return poDS; }
int GDALDefaultOverviews::HaveMaskFile( char ** papszSiblingFiles, const char *pszBasename ) { /* -------------------------------------------------------------------- */ /* Have we already checked for masks? */ /* -------------------------------------------------------------------- */ if( bCheckedForMask ) return poMaskDS != NULL; if( papszSiblingFiles == NULL ) papszSiblingFiles = papszInitSiblingFiles; /* -------------------------------------------------------------------- */ /* Are we an overview? If so we need to find the corresponding */ /* overview in the base files mask file (if there is one). */ /* -------------------------------------------------------------------- */ if( poBaseDS != NULL && poBaseDS->oOvManager.HaveMaskFile() ) { int iOver, nOverviewCount = 0; GDALRasterBand *poBaseBand = poBaseDS->GetRasterBand(1); GDALRasterBand *poBaseMask = NULL; if( poBaseBand != NULL ) poBaseMask = poBaseBand->GetMaskBand(); if( poBaseMask ) nOverviewCount = poBaseMask->GetOverviewCount(); for( iOver = 0; iOver < nOverviewCount; iOver++ ) { GDALRasterBand *poOverBand = poBaseMask->GetOverview( iOver ); if (poOverBand == NULL) continue; if( poOverBand->GetXSize() == poDS->GetRasterXSize() && poOverBand->GetYSize() == poDS->GetRasterYSize() ) { poMaskDS = poOverBand->GetDataset(); break; } } bCheckedForMask = TRUE; bOwnMaskDS = FALSE; CPLAssert( poMaskDS != poDS ); return poMaskDS != NULL; } /* -------------------------------------------------------------------- */ /* Are we even initialized? If not, we apparently don't want */ /* to support overviews and masks. */ /* -------------------------------------------------------------------- */ if( poDS == NULL ) return FALSE; /* -------------------------------------------------------------------- */ /* Check for .msk file. */ /* -------------------------------------------------------------------- */ CPLString osMskFilename; bCheckedForMask = TRUE; if( pszBasename == NULL ) pszBasename = poDS->GetDescription(); // Don't bother checking for masks of masks. if( EQUAL(CPLGetExtension(pszBasename),"msk") ) return FALSE; osMskFilename.Printf( "%s.msk", pszBasename ); int bExists = CPLCheckForFile( (char *) osMskFilename.c_str(), papszSiblingFiles ); #if !defined(WIN32) if( !bExists && !papszSiblingFiles ) { osMskFilename.Printf( "%s.MSK", pszBasename ); bExists = CPLCheckForFile( (char *) osMskFilename.c_str(), papszSiblingFiles ); } #endif if( !bExists ) return FALSE; /* -------------------------------------------------------------------- */ /* Open the file. */ /* -------------------------------------------------------------------- */ GDALOpenInfo oOpenInfo(osMskFilename, poDS->GetAccess(), papszInitSiblingFiles); poMaskDS = (GDALDataset *) GDALOpenInternal( oOpenInfo, NULL ); CPLAssert( poMaskDS != poDS ); if( poMaskDS == NULL ) return FALSE; bOwnMaskDS = TRUE; return TRUE; }
void GDALDefaultOverviews::OverviewScan() { if( bCheckedForOverviews || poDS == NULL ) return; bCheckedForOverviews = true; CPLDebug( "GDAL", "GDALDefaultOverviews::OverviewScan()" ); /* -------------------------------------------------------------------- */ /* Open overview dataset if it exists. */ /* -------------------------------------------------------------------- */ int bExists; if( pszInitName == NULL ) pszInitName = CPLStrdup(poDS->GetDescription()); if( !EQUAL(pszInitName,":::VIRTUAL:::") ) { if( bInitNameIsOVR ) osOvrFilename = pszInitName; else osOvrFilename.Printf( "%s.ovr", pszInitName ); bExists = CPLCheckForFile( (char *) osOvrFilename.c_str(), papszInitSiblingFiles ); #if !defined(WIN32) if( !bInitNameIsOVR && !bExists && !papszInitSiblingFiles ) { osOvrFilename.Printf( "%s.OVR", pszInitName ); bExists = CPLCheckForFile( (char *) osOvrFilename.c_str(), papszInitSiblingFiles ); if( !bExists ) osOvrFilename.Printf( "%s.ovr", pszInitName ); } #endif if( bExists ) { GDALOpenInfo oOpenInfo(osOvrFilename, poDS->GetAccess(), papszInitSiblingFiles); poODS = (GDALDataset*) GDALOpenInternal( oOpenInfo, NULL ); } } /* -------------------------------------------------------------------- */ /* We didn't find that, so try and find a corresponding aux */ /* file. Check that we are the dependent file of the aux */ /* file. */ /* */ /* We only use the .aux file for overviews if they already have */ /* overviews existing, or if USE_RRD is set true. */ /* -------------------------------------------------------------------- */ if( !poODS && !EQUAL(pszInitName,":::VIRTUAL:::") ) { int bTryFindAssociatedAuxFile = TRUE; if( papszInitSiblingFiles ) { CPLString osAuxFilename = CPLResetExtension( pszInitName, "aux"); int iSibling = CSLFindString( papszInitSiblingFiles, CPLGetFilename(osAuxFilename) ); if( iSibling < 0 ) { osAuxFilename = pszInitName; osAuxFilename += ".aux"; iSibling = CSLFindString( papszInitSiblingFiles, CPLGetFilename(osAuxFilename) ); if( iSibling < 0 ) bTryFindAssociatedAuxFile = FALSE; } } if (bTryFindAssociatedAuxFile) { poODS = GDALFindAssociatedAuxFile( pszInitName, poDS->GetAccess(), poDS ); } if( poODS ) { int bUseRRD = CSLTestBoolean(CPLGetConfigOption("USE_RRD","NO")); bOvrIsAux = TRUE; if( GetOverviewCount(1) == 0 && !bUseRRD ) { bOvrIsAux = FALSE; GDALClose( poODS ); poODS = NULL; } else { osOvrFilename = poODS->GetDescription(); } } } /* -------------------------------------------------------------------- */ /* If we still don't have an overview, check to see if we have */ /* overview metadata referencing a remote (ie. proxy) or local */ /* subdataset overview dataset. */ /* -------------------------------------------------------------------- */ if( poODS == NULL ) { const char *pszProxyOvrFilename = poDS->GetMetadataItem( "OVERVIEW_FILE", "OVERVIEWS" ); if( pszProxyOvrFilename != NULL ) { if( EQUALN(pszProxyOvrFilename,":::BASE:::",10) ) { CPLString osPath = CPLGetPath(poDS->GetDescription()); osOvrFilename = CPLFormFilename( osPath, pszProxyOvrFilename+10, NULL ); } else osOvrFilename = pszProxyOvrFilename; CPLPushErrorHandler(CPLQuietErrorHandler); poODS = (GDALDataset *) GDALOpen(osOvrFilename,poDS->GetAccess()); CPLPopErrorHandler(); } } /* -------------------------------------------------------------------- */ /* If we have an overview dataset, then mark all the overviews */ /* with the base dataset Used later for finding overviews */ /* masks. Uggg. */ /* -------------------------------------------------------------------- */ if( poODS ) { int nOverviewCount = GetOverviewCount(1); int iOver; for( iOver = 0; iOver < nOverviewCount; iOver++ ) { GDALRasterBand *poBand = GetOverview( 1, iOver ); GDALDataset *poOverDS = NULL; if( poBand != NULL ) poOverDS = poBand->GetDataset(); if( poOverDS != NULL ) { poOverDS->oOvManager.poBaseDS = poDS; poOverDS->oOvManager.poDS = poOverDS; } } } }
GDALDataset* SIGDEMDataset::CreateCopy( const char * pszFilename, GDALDataset * poSrcDS, int /*bStrict*/, char ** /*papszOptions*/, GDALProgressFunc pfnProgress, void * pProgressData) { const int nBands = poSrcDS->GetRasterCount(); double adfGeoTransform[6] = { }; if (poSrcDS->GetGeoTransform(adfGeoTransform) != CE_None) { CPLError(CE_Failure, CPLE_NotSupported, "SIGDEM driver requires a valid GeoTransform."); return nullptr; } if (nBands != 1) { CPLError(CE_Failure, CPLE_NotSupported, "SIGDEM driver doesn't support %d bands. Must be 1 band.", nBands); return nullptr; } VSILFILE *fp = VSIFOpenL(pszFilename, "wb"); if (fp == nullptr) { CPLError(CE_Failure, CPLE_OpenFailed, "Attempt to create file `%s' failed.", pszFilename); return nullptr; } GDALRasterBand* band = poSrcDS->GetRasterBand(1); const char* pszProjection = poSrcDS->GetProjectionRef(); int32_t nCols = poSrcDS->GetRasterXSize(); int32_t nRows = poSrcDS->GetRasterYSize(); int32_t nCoordinateSystemId = GetCoordinateSystemId(pszProjection); SIGDEMHeader sHeader; sHeader.nCoordinateSystemId = nCoordinateSystemId; sHeader.dfMinX = adfGeoTransform[0]; const char* pszMin = band->GetMetadataItem("STATISTICS_MINIMUM"); if (pszMin == nullptr) { sHeader.dfMinZ = -10000; } else { sHeader.dfMinZ = CPLAtof(pszMin); } sHeader.dfMaxY = adfGeoTransform[3]; const char* pszMax = band->GetMetadataItem("STATISTICS_MAXIMUM"); if (pszMax == nullptr) { sHeader.dfMaxZ = 10000; } else { sHeader.dfMaxZ = CPLAtof(pszMax); } sHeader.nCols = poSrcDS->GetRasterXSize(); sHeader.nRows = poSrcDS->GetRasterYSize(); sHeader.dfXDim = adfGeoTransform[1]; sHeader.dfYDim = -adfGeoTransform[5]; sHeader.dfMaxX = sHeader.dfMinX + sHeader.nCols * sHeader.dfXDim; sHeader.dfMinY = sHeader.dfMaxY - sHeader.nRows * sHeader.dfYDim; sHeader.dfOffsetX = sHeader.dfMinX; sHeader.dfOffsetY = sHeader.dfMinY; if( !sHeader.Write(fp) ) { VSIUnlink(pszFilename); VSIFCloseL(fp); return nullptr; } // Write fill with all NO_DATA values int32_t* row = static_cast<int32_t*>(VSI_MALLOC2_VERBOSE(nCols, sizeof(int32_t))); if( !row ) { VSIUnlink(pszFilename); VSIFCloseL(fp); return nullptr; } std::fill(row, row + nCols, CPL_MSBWORD32(NO_DATA)); for (int i = 0; i < nRows; i++) { if( VSIFWriteL(row, CELL_SIZE_FILE, nCols, fp) != static_cast<size_t>(nCols) ) { VSIFree(row); VSIUnlink(pszFilename); VSIFCloseL(fp); return nullptr; } } VSIFree(row); if (VSIFCloseL(fp) != 0) { return nullptr; } if (nCoordinateSystemId <= 0) { if (!EQUAL(pszProjection, "")) { CPLString osPrjFilename = CPLResetExtension(pszFilename, "prj"); VSILFILE *fpProj = VSIFOpenL(osPrjFilename, "wt"); if (fpProj != nullptr) { OGRSpatialReference oSRS; oSRS.importFromWkt(pszProjection); oSRS.morphToESRI(); char *pszESRIProjection = nullptr; oSRS.exportToWkt(&pszESRIProjection); CPL_IGNORE_RET_VAL( VSIFWriteL(pszESRIProjection, 1, strlen(pszESRIProjection), fpProj)); CPL_IGNORE_RET_VAL(VSIFCloseL(fpProj)); CPLFree(pszESRIProjection); } else { CPLError(CE_Failure, CPLE_FileIO, "Unable to create file %s.", osPrjFilename.c_str()); } } } GDALOpenInfo oOpenInfo(pszFilename, GA_Update); GDALDataset * poDstDS = Open(&oOpenInfo); if (poDstDS != nullptr && GDALDatasetCopyWholeRaster(poSrcDS, poDstDS, nullptr, pfnProgress, pProgressData) == OGRERR_NONE) { return poDstDS; } else { VSIUnlink(pszFilename); return nullptr; } }
GDALDataset *CALSDataset::CreateCopy( const char *pszFilename, GDALDataset *poSrcDS, int bStrict, char ** /* papszOptionsUnused */, GDALProgressFunc pfnProgress, void *pProgressData ) { if( poSrcDS->GetRasterCount() == 0 || (bStrict && poSrcDS->GetRasterCount() != 1) ) { CPLError( CE_Failure, CPLE_NotSupported, "CALS driver only supports single band raster."); return NULL; } if( poSrcDS->GetRasterBand(1)-> GetMetadataItem("NBITS", "IMAGE_STRUCTURE") == NULL || !EQUAL(poSrcDS->GetRasterBand(1)-> GetMetadataItem("NBITS", "IMAGE_STRUCTURE"), "1") ) { CPLError( bStrict ? CE_Failure : CE_Warning, CPLE_NotSupported, "CALS driver only supports 1-bit."); if( bStrict ) return NULL; } if( poSrcDS->GetRasterXSize() > 999999 || poSrcDS->GetRasterYSize() > 999999 ) { CPLError( CE_Failure, CPLE_NotSupported, "CALS driver only supports datasets with dimension <= 999999."); return NULL; } GDALDriver* poGTiffDrv = static_cast<GDALDriver *>(GDALGetDriverByName("GTiff")); if( poGTiffDrv == NULL ) { CPLError( CE_Failure, CPLE_NotSupported, "CALS driver needs GTiff driver." ); return NULL; } // Write a in-memory TIFF with just the TIFF header to figure out // how large it will be. CPLString osTmpFilename(CPLSPrintf("/vsimem/cals/tmp_%p", poSrcDS)); char** papszOptions = NULL; papszOptions = CSLSetNameValue(papszOptions, "COMPRESS", "CCITTFAX4"); papszOptions = CSLSetNameValue(papszOptions, "NBITS", "1"); papszOptions = CSLSetNameValue(papszOptions, "BLOCKYSIZE", CPLSPrintf("%d", poSrcDS->GetRasterYSize())); papszOptions = CSLSetNameValue(papszOptions, "SPARSE_OK", "YES"); GDALDataset* poDS = poGTiffDrv->Create(osTmpFilename, poSrcDS->GetRasterXSize(), poSrcDS->GetRasterYSize(), 1, GDT_Byte, papszOptions); if( poDS == NULL ) { // Should not happen normally (except if CCITTFAX4 not available). CSLDestroy(papszOptions); return NULL; } const char INITIAL_PADDING[] = "12345"; // To adjust padding. poDS->SetMetadataItem("TIFFTAG_DOCUMENTNAME", INITIAL_PADDING); GDALClose(poDS); VSIStatBufL sStat; if( VSIStatL(osTmpFilename, &sStat) != 0 ) { // Shoudln't happen really. Just to make Coverity happy. CSLDestroy(papszOptions); return NULL; } int nTIFFHeaderSize = static_cast<int>(sStat.st_size); VSIUnlink(osTmpFilename); // Redo the same thing, but this time write it to the output file // and use a variable TIFF tag (TIFFTAG_DOCUMENTNAME) to enlarge the // header + the variable TIFF tag so that they are 2048 bytes large. char szBuffer[2048+1] = {}; memset(szBuffer, 'X', 2048 - nTIFFHeaderSize + strlen(INITIAL_PADDING)); szBuffer[2048 - nTIFFHeaderSize + strlen(INITIAL_PADDING)] = 0; GDALDataset* poTmpDS = new CALSWrapperSrcDataset(poSrcDS, szBuffer); poDS = poGTiffDrv->CreateCopy(pszFilename, poTmpDS, FALSE, papszOptions, pfnProgress, pProgressData ); delete poTmpDS; CSLDestroy(papszOptions); if( poDS == NULL ) return NULL; delete poDS; // Now replace the TIFF header by the CALS header. VSILFILE* fp = VSIFOpenL(pszFilename, "rb+"); if( fp == NULL ) return NULL; // Shoudln't happen normally. memset(szBuffer, ' ', 2048); CPLString osField; osField = "srcdocid: NONE"; memcpy(szBuffer, osField, osField.size()); osField = "dstdocid: NONE"; memcpy(szBuffer + 128, osField, osField.size()); osField = "txtfilid: NONE"; memcpy(szBuffer + 128*2, osField, osField.size()); osField = "figid: NONE"; memcpy(szBuffer + 128*3, osField, osField.size()); osField = "srcgph: NONE"; memcpy(szBuffer + 128*4, osField, osField.size()); osField = "doccls: NONE"; memcpy(szBuffer + 128*5, osField, osField.size()); osField = "rtype: 1"; memcpy(szBuffer + 128*6, osField, osField.size()); int nAngle1 = 0; int nAngle2 = 270; const char* pszPixelPath = poSrcDS->GetMetadataItem("PIXEL_PATH"); const char* pszLineProgression = poSrcDS->GetMetadataItem("LINE_PROGRESSION"); if( pszPixelPath && pszLineProgression ) { nAngle1 = atoi(pszPixelPath); nAngle2 = atoi(pszLineProgression); } osField = CPLSPrintf("rorient: %03d,%03d", nAngle1, nAngle2); memcpy(szBuffer + 128*7, osField, osField.size()); osField = CPLSPrintf("rpelcnt: %06d,%06d", poSrcDS->GetRasterXSize(), poSrcDS->GetRasterYSize()); memcpy(szBuffer + 128*8, osField, osField.size()); int nDensity = 200; const char* pszXRes = poSrcDS->GetMetadataItem("TIFFTAG_XRESOLUTION"); const char* pszYRes = poSrcDS->GetMetadataItem("TIFFTAG_YRESOLUTION"); const char* pszResUnit = poSrcDS->GetMetadataItem("TIFFTAG_RESOLUTIONUNIT"); if( pszXRes && pszYRes && pszResUnit && EQUAL(pszXRes, pszYRes) && atoi(pszResUnit) == 2 ) { nDensity = atoi(pszXRes); if( nDensity < 1 || nDensity > 9999 ) nDensity = 200; } osField = CPLSPrintf("rdensty: %04d", nDensity); memcpy(szBuffer + 128*9, osField, osField.size()); osField = "notes: NONE"; memcpy(szBuffer + 128*10, osField, osField.size()); VSIFWriteL(szBuffer, 1, 2048, fp); VSIFCloseL(fp); GDALOpenInfo oOpenInfo(pszFilename, GA_ReadOnly, NULL); return Open(&oOpenInfo); }
GDALDataset *OZIDataset::Open( GDALOpenInfo * poOpenInfo ) { if (!Identify(poOpenInfo)) return NULL; GByte abyHeader[14]; CPLString osImgFilename = poOpenInfo->pszFilename; int bIsMap = FALSE; if (EQUALN((const char*)poOpenInfo->pabyHeader, "OziExplorer Map Data File Version ", 34) ) { char** papszLines = CSLLoad2( poOpenInfo->pszFilename, 1000, 200, NULL ); if ( !papszLines || CSLCount(papszLines) < 5) { CSLDestroy(papszLines); return FALSE; } bIsMap = TRUE; osImgFilename = papszLines[2]; VSIStatBufL sStat; if (VSIStatL(osImgFilename, &sStat) != 0) { if (CPLIsFilenameRelative(osImgFilename)) { CPLString osPath = CPLGetPath(poOpenInfo->pszFilename); osImgFilename = CPLFormFilename(osPath, osImgFilename, NULL); } else { CPLString osPath = CPLGetPath(poOpenInfo->pszFilename); osImgFilename = CPLGetFilename(osImgFilename); osImgFilename = CPLFormFilename(osPath, osImgFilename, NULL); } } CSLDestroy(papszLines); GDALOpenInfo oOpenInfo(osImgFilename, GA_ReadOnly); if (!Identify(&oOpenInfo)) return NULL; memcpy(abyHeader, oOpenInfo.pabyHeader, 14); } else memcpy(abyHeader, poOpenInfo->pabyHeader, 14); int bOzi3 = (abyHeader[0] == 0x80 && abyHeader[1] == 0x77); VSILFILE* fp = VSIFOpenL(osImgFilename.c_str(), "rb"); if (fp == NULL) return NULL; OZIDataset* poDS = new OZIDataset(); poDS->fp = fp; if (bIsMap) { poDS->bReadMapFileSuccess = GDALLoadOziMapFile( poOpenInfo->pszFilename, poDS->adfGeoTransform, &poDS->pszWKT, &poDS->nGCPCount, &poDS->pasGCPs ); } GByte nRandomNumber = 0; GByte nKeyInit = 0; if (bOzi3) { VSIFSeekL(fp, 14, SEEK_SET); VSIFReadL(&nRandomNumber, 1, 1, fp); //printf("nRandomNumber = %d\n", nRandomNumber); if (nRandomNumber < 0x94) { delete poDS; return NULL; } VSIFSeekL(fp, 0x93, SEEK_CUR); VSIFReadL(&nKeyInit, 1, 1, fp); VSIFSeekL(fp, 0, SEEK_SET); VSIFReadL(abyHeader, 1, 14, fp); OZIDecrypt(abyHeader, 14, nKeyInit); if (!(abyHeader[6] == 0x40 && abyHeader[7] == 0x00 && abyHeader[8] == 0x01 && abyHeader[9] == 0x00 && abyHeader[10] == 0x36 && abyHeader[11] == 0x04 && abyHeader[12] == 0x00 && abyHeader[13] == 0x00)) { delete poDS; return NULL; } VSIFSeekL(fp, 14 + 1 + nRandomNumber, SEEK_SET); int nMagic = ReadInt(fp, bOzi3, nKeyInit); CPLDebug("OZI", "OZI version code : 0x%08X", nMagic); poDS->bOzi3 = bOzi3; } else { VSIFSeekL(fp, 14, SEEK_SET); } GByte abyHeader2[40], abyHeader2_Backup[40]; VSIFReadL(abyHeader2, 40, 1, fp); memcpy(abyHeader2_Backup, abyHeader2, 40); /* There's apparently a relationship between the nMagic number */ /* and the nKeyInit, but I'm too lazy to add switch/cases that might */ /* be not exhaustive, so let's try the 'brute force' attack !!! */ /* It is much so funny to be able to run one in a few microseconds :-) */ for(nKeyInit = 0; nKeyInit < 256; nKeyInit ++) { GByte* pabyHeader2 = abyHeader2; if (bOzi3) OZIDecrypt(abyHeader2, 40, nKeyInit); int nHeaderSize = ReadInt(&pabyHeader2); /* should be 40 */ poDS->nRasterXSize = ReadInt(&pabyHeader2); poDS->nRasterYSize = ReadInt(&pabyHeader2); int nDepth = ReadShort(&pabyHeader2); /* should be 1 */ int nBPP = ReadShort(&pabyHeader2); /* should be 8 */ ReadInt(&pabyHeader2); /* reserved */ ReadInt(&pabyHeader2); /* pixel number (height * width) : unused */ ReadInt(&pabyHeader2); /* reserved */ ReadInt(&pabyHeader2); /* reserved */ ReadInt(&pabyHeader2); /* ?? 0x100 */ ReadInt(&pabyHeader2); /* ?? 0x100 */ if (nHeaderSize != 40 || nDepth != 1 || nBPP != 8) { if (bOzi3) { if (nKeyInit != 255) { memcpy(abyHeader2, abyHeader2_Backup,40); continue; } else { CPLDebug("OZI", "Cannot decypher 2nd header. Sorry..."); delete poDS; return NULL; } } else { CPLDebug("OZI", "nHeaderSize = %d, nDepth = %d, nBPP = %d", nHeaderSize, nDepth, nBPP); delete poDS; return NULL; } } else break; } poDS->nKeyInit = nKeyInit; int nSeparator = ReadInt(fp); if (!bOzi3 && nSeparator != 0x77777777) { CPLDebug("OZI", "didn't get end of header2 marker"); delete poDS; return NULL; } poDS->nZoomLevelCount = ReadShort(fp); //CPLDebug("OZI", "nZoomLevelCount = %d", poDS->nZoomLevelCount); if (poDS->nZoomLevelCount < 0 || poDS->nZoomLevelCount >= 256) { CPLDebug("OZI", "nZoomLevelCount = %d", poDS->nZoomLevelCount); delete poDS; return NULL; } /* Skip array of zoom level percentage. We don't need it for GDAL */ VSIFSeekL(fp, sizeof(float) * poDS->nZoomLevelCount, SEEK_CUR); nSeparator = ReadInt(fp); if (!bOzi3 && nSeparator != 0x77777777) { /* Some files have 8 extra bytes before the marker. I'm not sure */ /* what they are used for. So just skeep them and hope that */ /* we'll find the marker */ nSeparator = ReadInt(fp); nSeparator = ReadInt(fp); if (nSeparator != 0x77777777) { CPLDebug("OZI", "didn't get end of zoom levels marker"); delete poDS; return NULL; } } VSIFSeekL(fp, 0, SEEK_END); vsi_l_offset nFileSize = VSIFTellL(fp); poDS->nFileSize = nFileSize; VSIFSeekL(fp, nFileSize - 4, SEEK_SET); int nZoomLevelTableOffset = ReadInt(fp, bOzi3, nKeyInit); if (nZoomLevelTableOffset < 0 || (vsi_l_offset)nZoomLevelTableOffset >= nFileSize) { CPLDebug("OZI", "nZoomLevelTableOffset = %d", nZoomLevelTableOffset); delete poDS; return NULL; } VSIFSeekL(fp, nZoomLevelTableOffset, SEEK_SET); poDS->panZoomLevelOffsets = (int*)CPLMalloc(sizeof(int) * poDS->nZoomLevelCount); int i; for(i=0;i<poDS->nZoomLevelCount;i++) { poDS->panZoomLevelOffsets[i] = ReadInt(fp, bOzi3, nKeyInit); if (poDS->panZoomLevelOffsets[i] < 0 || (vsi_l_offset)poDS->panZoomLevelOffsets[i] >= nFileSize) { CPLDebug("OZI", "panZoomLevelOffsets[%d] = %d", i, poDS->panZoomLevelOffsets[i]); delete poDS; return NULL; } } poDS->papoBands = (OZIRasterBand**)CPLCalloc(sizeof(OZIRasterBand*), poDS->nZoomLevelCount); for(i=0;i<poDS->nZoomLevelCount;i++) { VSIFSeekL(fp, poDS->panZoomLevelOffsets[i], SEEK_SET); int nW = ReadInt(fp, bOzi3, nKeyInit); int nH = ReadInt(fp, bOzi3, nKeyInit); short nTileX = ReadShort(fp, bOzi3, nKeyInit); short nTileY = ReadShort(fp, bOzi3, nKeyInit); if (i == 0 && (nW != poDS->nRasterXSize || nH != poDS->nRasterYSize)) { CPLDebug("OZI", "zoom[%d] inconsistant dimensions for zoom level 0 : nW=%d, nH=%d, nTileX=%d, nTileY=%d, nRasterXSize=%d, nRasterYSize=%d", i, nW, nH, nTileX, nTileY, poDS->nRasterXSize, poDS->nRasterYSize); delete poDS; return NULL; } /* Note (#3895): some files such as world.ozf2 provided with OziExplorer */ /* expose nTileY=33, but have nH=2048, so only require 32 tiles in vertical dimension. */ /* So there's apparently one extra and useless tile that will be ignored */ /* without causing apparent issues */ /* Some other files have more tile in horizontal direction than needed, so let's */ /* accept that. But in that case we really need to keep the nTileX value for IReadBlock() */ /* to work properly */ if ((nW + 63) / 64 > nTileX || (nH + 63) / 64 > nTileY) { CPLDebug("OZI", "zoom[%d] unexpected number of tiles : nW=%d, nH=%d, nTileX=%d, nTileY=%d", i, nW, nH, nTileX, nTileY); delete poDS; return NULL; } GDALColorTable* poColorTable = new GDALColorTable(); GByte abyColorTable[256*4]; VSIFReadL(abyColorTable, 1, 1024, fp); if (bOzi3) OZIDecrypt(abyColorTable, 1024, nKeyInit); int j; for(j=0;j<256;j++) { GDALColorEntry sEntry; sEntry.c1 = abyColorTable[4*j + 2]; sEntry.c2 = abyColorTable[4*j + 1]; sEntry.c3 = abyColorTable[4*j + 0]; sEntry.c4 = 255; poColorTable->SetColorEntry(j, &sEntry); } poDS->papoBands[i] = new OZIRasterBand(poDS, i, nW, nH, nTileX, poColorTable); if (i > 0) { GByte* pabyTranslationTable = poDS->papoBands[i]->GetIndexColorTranslationTo(poDS->papoBands[0], NULL, NULL); delete poDS->papoBands[i]->poColorTable; poDS->papoBands[i]->poColorTable = poDS->papoBands[0]->poColorTable->Clone(); poDS->papoBands[i]->pabyTranslationTable = pabyTranslationTable; } } poDS->SetBand(1, poDS->papoBands[0]); /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ poDS->SetDescription( poOpenInfo->pszFilename ); poDS->TryLoadXML(); /* -------------------------------------------------------------------- */ /* Support overviews. */ /* -------------------------------------------------------------------- */ poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename ); return( poDS ); }