/** Queue a new job. * * @param pfnFunc Function to run for the job. * @param pData User data to pass to the job function. * @return true in case of success. */ bool CPLWorkerThreadPool::SubmitJob( CPLThreadFunc pfnFunc, void* pData ) { CPLAssert( !aWT.empty() ); CPLWorkerThreadJob* psJob = static_cast<CPLWorkerThreadJob *>( VSI_MALLOC_VERBOSE(sizeof(CPLWorkerThreadJob))); if( psJob == nullptr ) return false; psJob->pfnFunc = pfnFunc; psJob->pData = pData; CPLList* psItem = static_cast<CPLList *>(VSI_MALLOC_VERBOSE(sizeof(CPLList))); if( psItem == nullptr ) { VSIFree(psJob); return false; } psItem->pData = psJob; CPLAcquireMutex(hMutex, 1000.0); psItem->psNext = psJobQueue; psJobQueue = psItem; nPendingJobs++; if( psWaitingWorkerThreadsList ) { CPLWorkerThread* psWorkerThread = static_cast<CPLWorkerThread *>(psWaitingWorkerThreadsList->pData); CPLAssert( psWorkerThread->bMarkedAsWaiting ); psWorkerThread->bMarkedAsWaiting = FALSE; CPLList* psNext = psWaitingWorkerThreadsList->psNext; CPLList* psToFree = psWaitingWorkerThreadsList; psWaitingWorkerThreadsList = psNext; nWaitingWorkerThreads--; // CPLAssert( // CPLListCount(psWaitingWorkerThreadsList) == nWaitingWorkerThreads); #if DEBUG_VERBOSE CPLDebug("JOB", "Waking up %p", psWorkerThread); #endif CPLAcquireMutex(psWorkerThread->hMutex, 1000.0); CPLReleaseMutex(hMutex); CPLCondSignal(psWorkerThread->hCond); CPLReleaseMutex(psWorkerThread->hMutex); CPLFree(psToFree); } else { CPLReleaseMutex(hMutex); } return true; }
static void OGR2SQLITE_ST_AsBinary(sqlite3_context* pContext, int argc, sqlite3_value** argv) { OGRGeometry* poGeom = OGR2SQLITE_GetGeom(pContext, argc, argv, NULL); if( poGeom != NULL ) { int nBLOBLen = poGeom->WkbSize(); GByte* pabyGeomBLOB = (GByte*) VSI_MALLOC_VERBOSE(nBLOBLen); if( pabyGeomBLOB != NULL ) { if( poGeom->exportToWkb(wkbNDR, pabyGeomBLOB) == OGRERR_NONE ) sqlite3_result_blob( pContext, pabyGeomBLOB, nBLOBLen, CPLFree); else { VSIFree(pabyGeomBLOB); sqlite3_result_null (pContext); } } else sqlite3_result_null (pContext); delete poGeom; } else sqlite3_result_null (pContext); }
CPLErr JPEGLSDataset::Uncompress() { if (bHasUncompressed) return CE_None; bHasUncompressed = TRUE; VSILFILE* fp = VSIFOpenL(osFilename, "rb"); if (!fp) return CE_Failure; VSIFSeekL(fp, 0, SEEK_END); int nFileSize = (int)VSIFTellL(fp) - nOffset; VSIFSeekL(fp, 0, SEEK_SET); GByte* pabyCompressedData = (GByte*)VSIMalloc(nFileSize); if (pabyCompressedData == NULL) { VSIFCloseL(fp); return CE_Failure; } VSIFSeekL(fp, nOffset, SEEK_SET); VSIFReadL(pabyCompressedData, 1, nFileSize, fp); VSIFCloseL(fp); fp = NULL; int nUncompressedSize = nRasterXSize * nRasterYSize * nBands * (GDALGetDataTypeSize(GetRasterBand(1)->GetRasterDataType()) / 8); pabyUncompressedData = (GByte*)VSI_MALLOC_VERBOSE(nUncompressedSize); if (pabyUncompressedData == NULL) { VSIFree(pabyCompressedData); return CE_Failure; } JLS_ERROR eError = JpegLsDecode( pabyUncompressedData, nUncompressedSize, pabyCompressedData, nFileSize, NULL); if (eError != OK) { CPLError( CE_Failure, CPLE_AppDefined, "Decompression of data failed : %s", JPEGLSGetErrorAsString(eError) ); VSIFree(pabyCompressedData); VSIFree(pabyUncompressedData); pabyUncompressedData = NULL; return CE_Failure; } VSIFree(pabyCompressedData); return CE_None; }
CPLErr JDEMRasterBand::IReadBlock( CPL_UNUSED int nBlockXOff, int nBlockYOff, void * pImage ) { JDEMDataset *poGDS = static_cast<JDEMDataset *>(poDS); if (pszRecord == nullptr) { if (bBufferAllocFailed) return CE_Failure; pszRecord = static_cast<char *>(VSI_MALLOC_VERBOSE(nRecordSize)); if (pszRecord == nullptr) { bBufferAllocFailed = true; return CE_Failure; } } CPL_IGNORE_RET_VAL( VSIFSeekL(poGDS->fp, 1011 + nRecordSize * nBlockYOff, SEEK_SET)); CPL_IGNORE_RET_VAL(VSIFReadL(pszRecord, 1, nRecordSize, poGDS->fp)); if( !EQUALN(reinterpret_cast<char *>(poGDS->abyHeader), pszRecord, 6) ) { CPLError(CE_Failure, CPLE_AppDefined, "JDEM Scanline corrupt. Perhaps file was not transferred " "in binary mode?"); return CE_Failure; } if( JDEMGetField(pszRecord + 6, 3) != nBlockYOff + 1 ) { CPLError(CE_Failure, CPLE_AppDefined, "JDEM scanline out of order, JDEM driver does not " "currently support partial datasets."); return CE_Failure; } for( int i = 0; i < nBlockXSize; i++ ) static_cast<float *>(pImage)[i] = JDEMGetField(pszRecord + 9 + 5 * i, 5) * 0.1f; return CE_None; }
void HFAEntry::LoadData() { if( pabyData != NULL || nDataSize == 0 ) return; if( nDataSize > INT_MAX - 1 ) { CPLError(CE_Failure, CPLE_AppDefined, "Invalid value for nDataSize = %u", nDataSize); return; } /* -------------------------------------------------------------------- */ /* Allocate buffer, and read data. */ /* -------------------------------------------------------------------- */ pabyData = static_cast<GByte *>(VSI_MALLOC_VERBOSE(nDataSize + 1)); if( pabyData == NULL ) { return; } if( VSIFSeekL( psHFA->fp, nDataPos, SEEK_SET ) < 0 ) { CPLError( CE_Failure, CPLE_FileIO, "VSIFSeekL() failed in HFAEntry::LoadData()." ); return; } if( VSIFReadL( pabyData, 1, nDataSize, psHFA->fp ) < 1 ) { CPLError( CE_Failure, CPLE_FileIO, "VSIFReadL() failed in HFAEntry::LoadData()." ); return; } // Make sure the buffer is always null terminated to avoid // issues when extracting strings from a corrupted file. pabyData[nDataSize] = '\0'; /* -------------------------------------------------------------------- */ /* Get the type corresponding to this entry. */ /* -------------------------------------------------------------------- */ poType = psHFA->poDictionary->FindType( szType ); if( poType == NULL ) return; }
GDALDataset * JPEGLSDataset::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(); /* -------------------------------------------------------------------- */ /* Some some rudimentary checks */ /* -------------------------------------------------------------------- */ if( nBands != 1 && nBands != 3 && nBands != 4 ) { CPLError( CE_Failure, CPLE_NotSupported, "JPGLS driver doesn't support %d bands. Must be 1 (grey), " "3 (RGB) or 4 bands.\n", nBands ); return NULL; } if (nBands == 1 && poSrcDS->GetRasterBand(1)->GetColorTable() != NULL) { CPLError( (bStrict) ? CE_Failure : CE_Warning, CPLE_NotSupported, "JPGLS driver ignores color table. " "The source raster band will be considered as grey level.\n" "Consider using color table expansion (-expand option in gdal_translate)\n"); if (bStrict) return NULL; } GDALDataType eDT = poSrcDS->GetRasterBand(1)->GetRasterDataType(); if( eDT != GDT_Byte && eDT != GDT_Int16 ) { CPLError( (bStrict) ? CE_Failure : CE_Warning, CPLE_NotSupported, "JPGLS driver doesn't support data type %s", GDALGetDataTypeName( poSrcDS->GetRasterBand(1)->GetRasterDataType()) ); if (bStrict) return NULL; } int nWordSize = GDALGetDataTypeSize(eDT) / 8; int nUncompressedSize = nXSize * nYSize * nBands * nWordSize; // FIXME? bug in charls-1.0beta ?. I needed a "+ something" to // avoid errors on byte.tif. int nCompressedSize = nUncompressedSize + 256; GByte* pabyDataCompressed = (GByte*)VSI_MALLOC_VERBOSE(nCompressedSize); GByte* pabyDataUncompressed = (GByte*)VSI_MALLOC_VERBOSE(nUncompressedSize); if (pabyDataCompressed == NULL || pabyDataUncompressed == NULL) { VSIFree(pabyDataCompressed); VSIFree(pabyDataUncompressed); return NULL; } CPLErr eErr; eErr = poSrcDS->RasterIO(GF_Read, 0, 0, nXSize, nYSize, pabyDataUncompressed, nXSize, nYSize, eDT, nBands, NULL, nBands * nWordSize, nBands * nWordSize * nXSize, nWordSize, NULL); if (eErr != CE_None) { VSIFree(pabyDataCompressed); VSIFree(pabyDataUncompressed); return NULL; } size_t nWritten = 0; JlsParameters sParams; memset(&sParams, 0, sizeof(sParams)); sParams.width = nXSize; sParams.height = nYSize; sParams.bitspersample = (eDT == GDT_Byte) ? 8 : 16; sParams.ilv = ILV_NONE; const char* pszINTERLEAVE = CSLFetchNameValue( papszOptions, "INTERLEAVE" ); if (pszINTERLEAVE) { if (EQUAL(pszINTERLEAVE, "PIXEL")) sParams.ilv = ILV_SAMPLE; else if (EQUAL(pszINTERLEAVE, "LINE")) sParams.ilv = ILV_LINE; else if (EQUAL(pszINTERLEAVE, "BAND")) sParams.ilv = ILV_NONE; else { CPLError(CE_Warning, CPLE_NotSupported, "Unsupported value for INTERLEAVE : %s. Defaulting to BAND", pszINTERLEAVE); } } const char* pszLOSSFACTOR = CSLFetchNameValue( papszOptions, "LOSS_FACTOR" ); if (pszLOSSFACTOR) { int nLOSSFACTOR = atoi(pszLOSSFACTOR); if (nLOSSFACTOR >= 0) sParams.allowedlossyerror = nLOSSFACTOR; } const char* pszNBITS = poSrcDS->GetRasterBand(1)->GetMetadataItem( "NBITS", "IMAGE_STRUCTURE" ); if (pszNBITS != NULL) { int nBits = atoi(pszNBITS); if (nBits != 8 && nBits != 16) sParams.bitspersample = nBits; } sParams.components = nBands; JLS_ERROR eError = JpegLsEncode(pabyDataCompressed, nCompressedSize, &nWritten, pabyDataUncompressed, nUncompressedSize, &sParams); VSIFree(pabyDataUncompressed); pabyDataUncompressed = NULL; if (eError != OK) { CPLError(CE_Failure, CPLE_AppDefined, "Compression of data failed : %s", JPEGLSGetErrorAsString(eError)); VSIFree(pabyDataCompressed); return NULL; } VSILFILE* fp = VSIFOpenL(pszFilename, "wb"); if (fp == NULL) { VSIFree(pabyDataCompressed); return NULL; } VSIFWriteL(pabyDataCompressed, 1, nWritten, fp); VSIFree(pabyDataCompressed); VSIFCloseL(fp); /* -------------------------------------------------------------------- */ /* Re-open dataset, and copy any auxiliary pam information. */ /* -------------------------------------------------------------------- */ JPEGLSDataset *poDS = (JPEGLSDataset *) GDALOpen( pszFilename, GA_ReadOnly ); if( poDS ) poDS->CloneInfo( poSrcDS, GCIF_PAM_DEFAULT ); return poDS; }
/* TODO: check if georeference is the same as for BLX files, WGS84 */ static GDALDataset * BLXCreateCopy( const char * pszFilename, GDALDataset *poSrcDS, int bStrict, char ** papszOptions, GDALProgressFunc pfnProgress, void * pProgressData ) { // -------------------------------------------------------------------- // Some rudimentary checks // -------------------------------------------------------------------- const int nBands = poSrcDS->GetRasterCount(); if( nBands != 1 ) { CPLError( CE_Failure, CPLE_NotSupported, "BLX driver doesn't support %d bands. Must be 1 (grey) ", nBands ); return NULL; } if( poSrcDS->GetRasterBand(1)->GetRasterDataType() != GDT_Int16 && bStrict ) { CPLError( CE_Failure, CPLE_NotSupported, "BLX driver doesn't support data type %s. " "Only 16 bit byte bands supported.\n", GDALGetDataTypeName( poSrcDS->GetRasterBand(1)->GetRasterDataType()) ); return NULL; } const int nXSize = poSrcDS->GetRasterXSize(); const int nYSize = poSrcDS->GetRasterYSize(); if( (nXSize % 128 != 0) || (nYSize % 128 != 0) ) { CPLError( CE_Failure, CPLE_NotSupported, "BLX driver doesn't support dimensions that are not a multiple of 128.\n"); return NULL; } // -------------------------------------------------------------------- // What options has the user selected? // -------------------------------------------------------------------- int zscale = 1; if( CSLFetchNameValue(papszOptions,"ZSCALE") != NULL ) { zscale = atoi(CSLFetchNameValue(papszOptions,"ZSCALE")); if( zscale < 1 ) { CPLError( CE_Failure, CPLE_IllegalArg, "ZSCALE=%s is not a legal value in the range >= 1.", CSLFetchNameValue(papszOptions,"ZSCALE") ); return NULL; } } int fillundef = 1; if( CSLFetchNameValue(papszOptions,"FILLUNDEF") != NULL && EQUAL(CSLFetchNameValue(papszOptions,"FILLUNDEF"),"NO") ) fillundef = 0; int fillundefval = 0; if( CSLFetchNameValue(papszOptions,"FILLUNDEFVAL") != NULL ) { fillundefval = atoi(CSLFetchNameValue(papszOptions,"FILLUNDEFVAL")); if( (fillundefval < -32768) || (fillundefval > 32767) ) { CPLError( CE_Failure, CPLE_IllegalArg, "FILLUNDEFVAL=%s is not a legal value in the range -32768, 32767.", CSLFetchNameValue(papszOptions,"FILLUNDEFVAL") ); return NULL; } } int endian = LITTLEENDIAN; if( CSLFetchNameValue(papszOptions,"BIGENDIAN") != NULL && !EQUAL(CSLFetchNameValue(papszOptions,"BIGENDIAN"),"NO") ) endian = BIGENDIAN; // -------------------------------------------------------------------- // Create the dataset. // -------------------------------------------------------------------- // Create a BLX context blxcontext_t *ctx = blx_create_context(); // Setup BLX parameters ctx->cell_rows = nYSize / ctx->cell_ysize; ctx->cell_cols = nXSize / ctx->cell_xsize; ctx->zscale = zscale; ctx->fillundef = fillundef; ctx->fillundefval = fillundefval; ctx->endian = endian; if(blxopen(ctx, pszFilename, "wb")) { CPLError( CE_Failure, CPLE_OpenFailed, "Unable to create blx file %s.\n", pszFilename ); blx_free_context(ctx); return NULL; } // -------------------------------------------------------------------- // Loop over image, copying image data. // -------------------------------------------------------------------- GInt16 *pabyTile = (GInt16 *) VSI_MALLOC_VERBOSE( sizeof(GInt16)*ctx->cell_xsize*ctx->cell_ysize ); if (pabyTile == NULL) { blxclose(ctx); blx_free_context(ctx); return NULL; } CPLErr eErr=CE_None; if( !pfnProgress( 0.0, NULL, pProgressData ) ) eErr = CE_Failure; for(int i=0; (i < ctx->cell_rows) && (eErr == CE_None); i++) for(int j=0; j < ctx->cell_cols; j++) { blxdata *celldata; GDALRasterBand * poBand = poSrcDS->GetRasterBand( 1 ); eErr = poBand->RasterIO( GF_Read, j*ctx->cell_xsize, i*ctx->cell_ysize, ctx->cell_xsize, ctx->cell_ysize, pabyTile, ctx->cell_xsize, ctx->cell_ysize, GDT_Int16, 0, 0, NULL ); if(eErr >= CE_Failure) break; celldata = pabyTile; if (blx_writecell(ctx, celldata, i, j) != 0) { eErr = CE_Failure; break; } if ( ! pfnProgress( 1.0 * (i * ctx->cell_cols + j) / (ctx->cell_rows * ctx->cell_cols), NULL, pProgressData )) { eErr = CE_Failure; break; } } pfnProgress( 1.0, NULL, pProgressData ); CPLFree( pabyTile ); double adfGeoTransform[6]; if( poSrcDS->GetGeoTransform( adfGeoTransform ) == CE_None ) { ctx->lon = adfGeoTransform[0]; ctx->lat = adfGeoTransform[3]; ctx->pixelsize_lon = adfGeoTransform[1]; ctx->pixelsize_lat = adfGeoTransform[5]; } blxclose(ctx); blx_free_context(ctx); if (eErr == CE_None) return reinterpret_cast<GDALDataset *>( GDALOpen( pszFilename, GA_ReadOnly ) ); return NULL; }
NITFDES *NITFDESAccess( NITFFile *psFile, int iSegment ) { NITFDES *psDES; char *pachHeader; NITFSegmentInfo *psSegInfo; char szDESID[26]; int nOffset; int bHasDESOFLW; int nDESSHL; /* -------------------------------------------------------------------- */ /* Verify segment, and return existing DES accessor if there */ /* is one. */ /* -------------------------------------------------------------------- */ if( iSegment < 0 || iSegment >= psFile->nSegmentCount ) return NULL; psSegInfo = psFile->pasSegmentInfo + iSegment; if( !EQUAL(psSegInfo->szSegmentType,"DE") ) return NULL; if( psSegInfo->hAccess != NULL ) return (NITFDES *) psSegInfo->hAccess; /* -------------------------------------------------------------------- */ /* Read the DES subheader. */ /* -------------------------------------------------------------------- */ if (psSegInfo->nSegmentHeaderSize < 200) { CPLError(CE_Failure, CPLE_AppDefined, "DES header too small"); return NULL; } pachHeader = (char*) VSI_MALLOC_VERBOSE(psSegInfo->nSegmentHeaderSize); if (pachHeader == NULL) { return NULL; } retry: if( VSIFSeekL( psFile->fp, psSegInfo->nSegmentHeaderStart, SEEK_SET ) != 0 || VSIFReadL( pachHeader, 1, psSegInfo->nSegmentHeaderSize, psFile->fp ) != psSegInfo->nSegmentHeaderSize ) { CPLError( CE_Failure, CPLE_FileIO, "Failed to read %u byte DES subheader from " CPL_FRMT_GUIB ".", psSegInfo->nSegmentHeaderSize, psSegInfo->nSegmentHeaderStart ); CPLFree(pachHeader); return NULL; } if (!STARTS_WITH_CI(pachHeader, "DE")) { if (STARTS_WITH_CI(pachHeader + 4, "DERegistered")) { /* BAO_46_Ed1/rpf/conc/concz10/000fz010.ona and cie are buggy */ CPLDebug("NITF", "Patching nSegmentHeaderStart and nSegmentStart for DE segment %d", iSegment); psSegInfo->nSegmentHeaderStart += 4; psSegInfo->nSegmentStart += 4; goto retry; } CPLError(CE_Failure, CPLE_AppDefined, "Invalid segment prefix for DE segment %d", iSegment); CPLFree(pachHeader); return NULL; } /* -------------------------------------------------------------------- */ /* Initialize DES object. */ /* -------------------------------------------------------------------- */ psDES = (NITFDES *) CPLCalloc(sizeof(NITFDES),1); psDES->psFile = psFile; psDES->iSegment = iSegment; psDES->pachHeader = pachHeader; psSegInfo->hAccess = psDES; /* -------------------------------------------------------------------- */ /* Collect a variety of information as metadata. */ /* -------------------------------------------------------------------- */ #define GetMD( length, name ) \ do { NITFExtractMetadata( &(psDES->papszMetadata), pachHeader, \ nOffset, length, \ "NITF_" #name ); \ nOffset += length; } while(0) nOffset = 2; GetMD( 25, DESID ); GetMD( 2, DESVER ); GetMD( 1, DECLAS ); GetMD( 2, DESCLSY ); GetMD( 11, DESCODE ); GetMD( 2, DESCTLH ); GetMD( 20, DESREL ); GetMD( 2, DESDCTP ); GetMD( 8, DESDCDT ); GetMD( 4, DESDCXM ); GetMD( 1, DESDG ); GetMD( 8, DESDGDT ); GetMD( 43, DESCLTX ); GetMD( 1, DESCATP ); GetMD( 40, DESCAUT ); GetMD( 1, DESCRSN ); GetMD( 8, DESSRDT ); GetMD( 15, DESCTLN ); /* Load DESID */ NITFGetField( szDESID, pachHeader, 2, 25); /* For NITF < 02.10, we cannot rely on DESID=TRE_OVERFLOW to detect */ /* if DESOFLW and DESITEM are present. So if the next 4 bytes are non */ /* numeric, we'll assume that DESOFLW is there */ bHasDESOFLW = STARTS_WITH_CI(szDESID, "TRE_OVERFLOW") || (!((pachHeader[nOffset+0] >= '0' && pachHeader[nOffset+0] <= '9') && (pachHeader[nOffset+1] >= '0' && pachHeader[nOffset+1] <= '9') && (pachHeader[nOffset+2] >= '0' && pachHeader[nOffset+2] <= '9') && (pachHeader[nOffset+3] >= '0' && pachHeader[nOffset+3] <= '9'))); if (bHasDESOFLW) { if ((int)psSegInfo->nSegmentHeaderSize < nOffset + 6 + 3 ) { CPLError(CE_Failure, CPLE_AppDefined, "DES header too small"); NITFDESDeaccess(psDES); return NULL; } GetMD( 6, DESOFLW ); GetMD( 3, DESITEM ); } if ((int)psSegInfo->nSegmentHeaderSize < nOffset + 4 ) { CPLError(CE_Failure, CPLE_AppDefined, "DES header too small"); NITFDESDeaccess(psDES); return NULL; } GetMD( 4, DESSHL ); nDESSHL = atoi(CSLFetchNameValue( psDES->papszMetadata, "NITF_DESSHL" ) ); if (nDESSHL < 0) { CPLError(CE_Failure, CPLE_AppDefined, "Invalid value for DESSHL"); NITFDESDeaccess(psDES); return NULL; } if ( (int)psSegInfo->nSegmentHeaderSize < nOffset + nDESSHL) { CPLError(CE_Failure, CPLE_AppDefined, "DES header too small"); NITFDESDeaccess(psDES); return NULL; } if (STARTS_WITH_CI(szDESID, "CSSHPA DES")) { if ( nDESSHL != 62 && nDESSHL != 80) { CPLError(CE_Failure, CPLE_AppDefined, "Invalid DESSHL for CSSHPA DES"); NITFDESDeaccess(psDES); return NULL; } GetMD( 25, SHAPE_USE ); GetMD( 10, SHAPE_CLASS ); if (nDESSHL == 80) GetMD( 18, CC_SOURCE ); GetMD( 3, SHAPE1_NAME ); GetMD( 6, SHAPE1_START ); GetMD( 3, SHAPE2_NAME ); GetMD( 6, SHAPE2_START ); GetMD( 3, SHAPE3_NAME ); GetMD( 6, SHAPE3_START ); } else if (STARTS_WITH_CI(szDESID, "XML_DATA_CONTENT")) { /* TODO : handle nDESSHL = 0005 and 0283 */ if (nDESSHL >= 5) { GetMD( 5, DESCRC ); if (nDESSHL >= 283) { GetMD( 8, DESSHFT ); GetMD( 20, DESSHDT ); GetMD( 40, DESSHRP ); GetMD( 60, DESSHSI ); GetMD( 10, DESSHSV ); GetMD( 20, DESSHSD ); GetMD( 120, DESSHTN ); if (nDESSHL >= 773) { GetMD( 125, DESSHLPG ); GetMD( 25, DESSHLPT ); GetMD( 20, DESSHLI ); GetMD( 120, DESSHLIN ); GetMD( 200, DESSHABS ); } } } } else if (STARTS_WITH_CI(szDESID, "CSATTA DES") && nDESSHL == 52) { GetMD( 12, ATT_TYPE ); GetMD( 14, DT_ATT ); GetMD( 8, DATE_ATT ); GetMD( 13, T0_ATT ); GetMD( 5, NUM_ATT ); } else if (nDESSHL > 0) GetMD( nDESSHL, DESSHF ); if ((int)psSegInfo->nSegmentHeaderSize > nOffset) { char* pszEscapedDESDATA = CPLEscapeString( pachHeader + nOffset, (int)psSegInfo->nSegmentHeaderSize - nOffset, CPLES_BackslashQuotable ); psDES->papszMetadata = CSLSetNameValue( psDES->papszMetadata, "NITF_DESDATA", pszEscapedDESDATA ); CPLFree(pszEscapedDESDATA); } else { #define TEN_MEGABYTES 10485760 if (psSegInfo->nSegmentSize > TEN_MEGABYTES) { const char* pszOffset = CPLSPrintf(CPL_FRMT_GUIB, psFile->pasSegmentInfo[iSegment].nSegmentStart); const char* pszSize = CPLSPrintf(CPL_FRMT_GUIB, psFile->pasSegmentInfo[iSegment].nSegmentSize); psDES->papszMetadata = CSLSetNameValue( psDES->papszMetadata, "NITF_DESDATA_OFFSET", pszOffset ); psDES->papszMetadata = CSLSetNameValue( psDES->papszMetadata, "NITF_DESDATA_LENGTH", pszSize); } else { char* pachData = (char*)VSI_MALLOC_VERBOSE((size_t)psSegInfo->nSegmentSize); if (pachData == NULL ) { /* nothing */ } else if( VSIFSeekL( psFile->fp, psSegInfo->nSegmentStart, SEEK_SET ) != 0 || VSIFReadL( pachData, 1, (size_t)psSegInfo->nSegmentSize, psFile->fp ) != psSegInfo->nSegmentSize ) { CPLDebug("NITF", "Failed to read " CPL_FRMT_GUIB" bytes DES data from " CPL_FRMT_GUIB ".", psSegInfo->nSegmentSize, psSegInfo->nSegmentStart ); } else { char* pszEscapedDESDATA = CPLEscapeString( pachData, (int)psSegInfo->nSegmentSize, CPLES_BackslashQuotable ); psDES->papszMetadata = CSLSetNameValue( psDES->papszMetadata, "NITF_DESDATA", pszEscapedDESDATA ); CPLFree(pszEscapedDESDATA); } CPLFree(pachData); } #ifdef notdef /* Disabled because might generate a huge amount of elements */ if (STARTS_WITH_CI(szDESID, "CSATTA DES")) { int nNumAtt = atoi(CSLFetchNameValueDef(psDES->papszMetadata, "NITF_NUM_ATT", "0")); if (nNumAtt * 8 * 4 == psSegInfo->nSegmentSize) { int nMDSize = CSLCount(psDES->papszMetadata); char** papszMD = (char**)VSIRealloc(psDES->papszMetadata, (nMDSize + nNumAtt * 4 + 1) * sizeof(char*)); if (papszMD) { int i, j; const GByte* pachDataIter = pachData; psDES->papszMetadata = papszMD; for(i=0;i<nNumAtt;i++) { char szAttrNameValue[64+1+256+1]; double dfVal; for(j=0;j<4;j++) { memcpy(&dfVal, pachDataIter, 8); CPL_MSBPTR64(&dfVal); pachDataIter += 8; CPLsprintf(szAttrNameValue, "NITF_ATT_Q%d_%d=%.16g", j+1, i, dfVal); papszMD[nMDSize + i * 4 + j] = CPLStrdup(szAttrNameValue); } } papszMD[nMDSize + nNumAtt * 4] = NULL; } } } #endif } return psDES; }
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 */ /* -------------------------------------------------------------------- */ const int nXSize = poSrcDS->GetRasterXSize(); const 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"); bool bCompress = false; if( pszCompressed ) bCompress = CPLTestBool(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 { const 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); const 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 */ /* -------------------------------------------------------------------- */ const int nXBlocks = (nXSize + nTileSize - 1) / nTileSize; const int nYBlocks = (nYSize + nTileSize - 1) / nTileSize; void* pTileBuffer = (void*) VSI_MALLOC_VERBOSE(nTileSize * nTileSize * (GDALGetDataTypeSize(eReqDT) / 8)); if (pTileBuffer == NULL) { VSIFCloseL(fp); return NULL; } CPLErr eErr = CE_None; for(int j=0;j<nYBlocks && eErr == CE_None;j++) { for(int i=0;i<nXBlocks && eErr == CE_None;i++) { const int nReqXSize = MIN(nTileSize, nXSize - i * nTileSize); const 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(int k=0;k<nReqYSize;k++) { int nLastVal = ((short*)pTileBuffer)[(nReqYSize - k - 1) * nReqXSize + 0]; GByte nWordSize = 1; for(int l=1;l<nReqXSize;l++) { const int nVal = ((short*)pTileBuffer)[(nReqYSize - k - 1) * nReqXSize + l]; const 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(int l=1;l<nReqXSize;l++) { const int nVal = ((short*)pTileBuffer)[(nReqYSize - k - 1) * nReqXSize + l]; const int nDiff = nVal - nLastVal; if (nWordSize == 1) { CPLAssert(nDiff >= -128 && nDiff <= 127); signed char chDiff = (signed 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(int 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(int 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(int 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); const int nVal = (int)fIntVal; const 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(int 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); signed char chDiff = (signed 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); }
/** Queue several jobs * * @param pfnFunc Function to run for the job. * @param apData User data instances to pass to the job function. * @return true in case of success. */ bool CPLWorkerThreadPool::SubmitJobs(CPLThreadFunc pfnFunc, const std::vector<void*>& apData) { CPLAssert( !aWT.empty() ); CPLAcquireMutex(hMutex, 1000.0); CPLList* psJobQueueInit = psJobQueue; bool bRet = true; for(size_t i=0;i<apData.size();i++) { CPLWorkerThreadJob* psJob = static_cast<CPLWorkerThreadJob*>( VSI_MALLOC_VERBOSE(sizeof(CPLWorkerThreadJob))); if( psJob == nullptr ) { bRet = false; break; } psJob->pfnFunc = pfnFunc; psJob->pData = apData[i]; CPLList* psItem = static_cast<CPLList *>(VSI_MALLOC_VERBOSE(sizeof(CPLList))); if( psItem == nullptr ) { VSIFree(psJob); bRet = false; break; } psItem->pData = psJob; psItem->psNext = psJobQueue; psJobQueue = psItem; nPendingJobs++; } if( !bRet ) { for( CPLList* psIter = psJobQueue; psIter != psJobQueueInit; ) { CPLList* psNext = psIter->psNext; VSIFree(psIter->pData); VSIFree(psIter); nPendingJobs--; psIter = psNext; } } CPLReleaseMutex(hMutex); if( !bRet ) return false; for(size_t i=0;i<apData.size();i++) { CPLAcquireMutex(hMutex, 1000.0); if( psWaitingWorkerThreadsList && psJobQueue ) { CPLWorkerThread* psWorkerThread; psWorkerThread = static_cast<CPLWorkerThread*>(psWaitingWorkerThreadsList->pData); CPLAssert( psWorkerThread->bMarkedAsWaiting ); psWorkerThread->bMarkedAsWaiting = FALSE; CPLList* psNext = psWaitingWorkerThreadsList->psNext; CPLList* psToFree = psWaitingWorkerThreadsList; psWaitingWorkerThreadsList = psNext; nWaitingWorkerThreads--; // CPLAssert( // CPLListCount(psWaitingWorkerThreadsList) == // nWaitingWorkerThreads); #if DEBUG_VERBOSE CPLDebug("JOB", "Waking up %p", psWorkerThread); #endif CPLAcquireMutex(psWorkerThread->hMutex, 1000.0); // CPLAssert(psWorkerThread->psNextJob == nullptr); // psWorkerThread->psNextJob = // (CPLWorkerThreadJob*)psJobQueue->pData; // psNext = psJobQueue->psNext; // CPLFree(psJobQueue); // psJobQueue = psNext; CPLReleaseMutex(hMutex); CPLCondSignal(psWorkerThread->hCond); CPLReleaseMutex(psWorkerThread->hMutex); CPLFree(psToFree); } else { CPLReleaseMutex(hMutex); break; } } return true; }
OGRLayer * OGRSQLiteExecuteSQL( GDALDataset* poDS, const char *pszStatement, OGRGeometry *poSpatialFilter, CPL_UNUSED const char *pszDialect ) { char* pszTmpDBName = (char*) CPLMalloc(256); snprintf(pszTmpDBName, 256, "/vsimem/ogr2sqlite/temp_%p.db", pszTmpDBName); OGRSQLiteDataSource* poSQLiteDS = NULL; int nRet; int bSpatialiteDB = FALSE; CPLString osOldVal; const char* pszOldVal = CPLGetConfigOption("OGR_SQLITE_STATIC_VIRTUAL_OGR", NULL); if( pszOldVal != NULL ) { osOldVal = pszOldVal; pszOldVal = osOldVal.c_str(); } /* -------------------------------------------------------------------- */ /* Create in-memory sqlite/spatialite DB */ /* -------------------------------------------------------------------- */ #ifdef HAVE_SPATIALITE /* -------------------------------------------------------------------- */ /* Creating an empty SpatiaLite DB (with spatial_ref_sys populated */ /* has a significant cost. So at the first attempt, let's make */ /* one and cache it for later use. */ /* -------------------------------------------------------------------- */ #if 1 static size_t nEmptyDBSize = 0; static GByte* pabyEmptyDB = NULL; { static CPLMutex* hMutex = NULL; CPLMutexHolder oMutexHolder(&hMutex); static int bTried = FALSE; if( !bTried && CPLTestBool(CPLGetConfigOption("OGR_SQLITE_DIALECT_USE_SPATIALITE", "YES")) ) { bTried = TRUE; char* pszCachedFilename = (char*) CPLMalloc(256); snprintf(pszCachedFilename, 256, "/vsimem/ogr2sqlite/reference_%p.db", pszCachedFilename); char** papszOptions = CSLAddString(NULL, "SPATIALITE=YES"); OGRSQLiteDataSource* poCachedDS = new OGRSQLiteDataSource(); nRet = poCachedDS->Create( pszCachedFilename, papszOptions ); CSLDestroy(papszOptions); papszOptions = NULL; delete poCachedDS; if( nRet ) { /* Note: the reference file keeps the ownership of the data, so that */ /* it gets released with VSICleanupFileManager() */ vsi_l_offset nEmptyDBSizeLarge = 0; pabyEmptyDB = VSIGetMemFileBuffer( pszCachedFilename, &nEmptyDBSizeLarge, FALSE ); nEmptyDBSize = static_cast<size_t>(nEmptyDBSizeLarge); } CPLFree( pszCachedFilename ); } } /* The following configuration option is useful mostly for debugging/testing */ if( pabyEmptyDB != NULL && CPLTestBool(CPLGetConfigOption("OGR_SQLITE_DIALECT_USE_SPATIALITE", "YES")) ) { GByte* pabyEmptyDBClone = (GByte*)VSI_MALLOC_VERBOSE(nEmptyDBSize); if( pabyEmptyDBClone == NULL ) { CPLFree(pszTmpDBName); return NULL; } memcpy(pabyEmptyDBClone, pabyEmptyDB, nEmptyDBSize); VSIFCloseL(VSIFileFromMemBuffer( pszTmpDBName, pabyEmptyDBClone, nEmptyDBSize, TRUE )); poSQLiteDS = new OGRSQLiteDataSource(); CPLSetThreadLocalConfigOption("OGR_SQLITE_STATIC_VIRTUAL_OGR", "NO"); nRet = poSQLiteDS->Open( pszTmpDBName, TRUE, NULL ); CPLSetThreadLocalConfigOption("OGR_SQLITE_STATIC_VIRTUAL_OGR", pszOldVal); if( !nRet ) { /* should not happen really ! */ delete poSQLiteDS; VSIUnlink(pszTmpDBName); CPLFree(pszTmpDBName); return NULL; } bSpatialiteDB = TRUE; } #else /* No caching version */ poSQLiteDS = new OGRSQLiteDataSource(); char** papszOptions = CSLAddString(NULL, "SPATIALITE=YES"); CPLSetThreadLocalConfigOption("OGR_SQLITE_STATIC_VIRTUAL_OGR", "NO"); nRet = poSQLiteDS->Create( pszTmpDBName, papszOptions ); CPLSetThreadLocalConfigOption("OGR_SQLITE_STATIC_VIRTUAL_OGR", pszOldVal); CSLDestroy(papszOptions); papszOptions = NULL; if( nRet ) { bSpatialiteDB = TRUE; } #endif else { delete poSQLiteDS; poSQLiteDS = NULL; #else // HAVE_SPATIALITE if( true ) { #endif // HAVE_SPATIALITE poSQLiteDS = new OGRSQLiteDataSource(); CPLSetThreadLocalConfigOption("OGR_SQLITE_STATIC_VIRTUAL_OGR", "NO"); nRet = poSQLiteDS->Create( pszTmpDBName, NULL ); CPLSetThreadLocalConfigOption("OGR_SQLITE_STATIC_VIRTUAL_OGR", pszOldVal); if( !nRet ) { delete poSQLiteDS; VSIUnlink(pszTmpDBName); CPLFree(pszTmpDBName); return NULL; } } /* -------------------------------------------------------------------- */ /* Attach the Virtual Table OGR2SQLITE module to it. */ /* -------------------------------------------------------------------- */ OGR2SQLITEModule* poModule = OGR2SQLITE_Setup(poDS, poSQLiteDS); sqlite3* hDB = poSQLiteDS->GetDB(); /* -------------------------------------------------------------------- */ /* Analysze the statement to determine which tables will be used. */ /* -------------------------------------------------------------------- */ std::set<LayerDesc> oSetLayers; std::set<CPLString> oSetSpatialIndex; CPLString osModifiedSQL; OGR2SQLITEGetPotentialLayerNames(pszStatement, oSetLayers, oSetSpatialIndex, osModifiedSQL); std::set<LayerDesc>::iterator oIter = oSetLayers.begin(); if( strcmp(pszStatement, osModifiedSQL.c_str()) != 0 ) CPLDebug("OGR", "Modified SQL: %s", osModifiedSQL.c_str()); pszStatement = osModifiedSQL.c_str(); /* do not use it anymore */ int bFoundOGRStyle = ( osModifiedSQL.ifind("OGR_STYLE") != std::string::npos ); /* -------------------------------------------------------------------- */ /* For each of those tables, create a Virtual Table. */ /* -------------------------------------------------------------------- */ OGRLayer* poSingleSrcLayer = NULL; for(; oIter != oSetLayers.end(); ++oIter) { const LayerDesc& oLayerDesc = *oIter; /*CPLDebug("OGR", "Layer desc : %s, %s, %s, %s", oLayerDesc.osOriginalStr.c_str(), oLayerDesc.osSubstitutedName.c_str(), oLayerDesc.osDSName.c_str(), oLayerDesc.osLayerName.c_str());*/ CPLString osSQL; OGRLayer* poLayer = NULL; CPLString osTableName; int nExtraDS; if( oLayerDesc.osDSName.size() == 0 ) { poLayer = poDS->GetLayerByName(oLayerDesc.osLayerName); /* Might be a false positive (unlikely) */ if( poLayer == NULL ) continue; osTableName = oLayerDesc.osLayerName; nExtraDS = -1; } else { OGRDataSource* poOtherDS = (OGRDataSource* ) OGROpen(oLayerDesc.osDSName, FALSE, NULL); if( poOtherDS == NULL ) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot open datasource '%s'", oLayerDesc.osDSName.c_str() ); delete poSQLiteDS; VSIUnlink(pszTmpDBName); CPLFree(pszTmpDBName); return NULL; } poLayer = poOtherDS->GetLayerByName(oLayerDesc.osLayerName); if( poLayer == NULL ) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot find layer '%s' in '%s'", oLayerDesc.osLayerName.c_str(), oLayerDesc.osDSName.c_str() ); delete poOtherDS; delete poSQLiteDS; VSIUnlink(pszTmpDBName); CPLFree(pszTmpDBName); return NULL; } osTableName = oLayerDesc.osSubstitutedName; nExtraDS = OGR2SQLITE_AddExtraDS(poModule, poOtherDS); } if( oSetLayers.size() == 1 ) poSingleSrcLayer = poLayer; osSQL.Printf("CREATE VIRTUAL TABLE \"%s\" USING VirtualOGR(%d,'%s',%d,%d)", OGRSQLiteEscapeName(osTableName).c_str(), nExtraDS, OGRSQLiteEscape(oLayerDesc.osLayerName).c_str(), bFoundOGRStyle, TRUE/*bExposeOGRNativeData*/); char* pszErrMsg = NULL; int rc = sqlite3_exec( hDB, osSQL.c_str(), NULL, NULL, &pszErrMsg ); if( rc != SQLITE_OK ) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot create virtual table for layer '%s' : %s", osTableName.c_str(), pszErrMsg); sqlite3_free(pszErrMsg); continue; } for(int i=0; i<poLayer->GetLayerDefn()->GetGeomFieldCount(); i++) { OGR2SQLITEDealWithSpatialColumn(poLayer, i, oLayerDesc, osTableName, poSQLiteDS, hDB, bSpatialiteDB, oSetLayers, oSetSpatialIndex); } } /* -------------------------------------------------------------------- */ /* Reload, so that virtual tables are recognized */ /* -------------------------------------------------------------------- */ poSQLiteDS->ReloadLayers(); /* -------------------------------------------------------------------- */ /* Prepare the statement. */ /* -------------------------------------------------------------------- */ /* This will speed-up layer creation */ /* ORDER BY are costly to evaluate and are not necessary to establish */ /* the layer definition. */ int bUseStatementForGetNextFeature = TRUE; int bEmptyLayer = FALSE; sqlite3_stmt *hSQLStmt = NULL; int rc = sqlite3_prepare( hDB, pszStatement, -1, &hSQLStmt, NULL ); if( rc != SQLITE_OK ) { CPLError( CE_Failure, CPLE_AppDefined, "In ExecuteSQL(): sqlite3_prepare(%s):\n %s", pszStatement, sqlite3_errmsg(hDB) ); if( hSQLStmt != NULL ) { sqlite3_finalize( hSQLStmt ); } delete poSQLiteDS; VSIUnlink(pszTmpDBName); CPLFree(pszTmpDBName); return NULL; } /* -------------------------------------------------------------------- */ /* Do we get a resultset? */ /* -------------------------------------------------------------------- */ rc = sqlite3_step( hSQLStmt ); if( rc != SQLITE_ROW ) { if ( rc != SQLITE_DONE ) { CPLError( CE_Failure, CPLE_AppDefined, "In ExecuteSQL(): sqlite3_step(%s):\n %s", pszStatement, sqlite3_errmsg(hDB) ); sqlite3_finalize( hSQLStmt ); delete poSQLiteDS; VSIUnlink(pszTmpDBName); CPLFree(pszTmpDBName); return NULL; } if( !STARTS_WITH_CI(pszStatement, "SELECT ") ) { sqlite3_finalize( hSQLStmt ); delete poSQLiteDS; VSIUnlink(pszTmpDBName); CPLFree(pszTmpDBName); return NULL; } bUseStatementForGetNextFeature = FALSE; bEmptyLayer = TRUE; } /* -------------------------------------------------------------------- */ /* Create layer. */ /* -------------------------------------------------------------------- */ OGRSQLiteSelectLayer *poLayer = NULL; poLayer = new OGRSQLiteExecuteSQLLayer( pszTmpDBName, poSQLiteDS, pszStatement, hSQLStmt, bUseStatementForGetNextFeature, bEmptyLayer ); if( poSpatialFilter != NULL ) poLayer->SetSpatialFilter( 0, poSpatialFilter ); if( poSingleSrcLayer != NULL ) poLayer->SetMetadata( poSingleSrcLayer->GetMetadata( "NATIVE_DATA" ), "NATIVE_DATA" ); return poLayer; } /************************************************************************/ /* OGRSQLiteGetReferencedLayers() */ /************************************************************************/ std::set<LayerDesc> OGRSQLiteGetReferencedLayers(const char* pszStatement) { /* -------------------------------------------------------------------- */ /* Analysze the statement to determine which tables will be used. */ /* -------------------------------------------------------------------- */ std::set<LayerDesc> oSetLayers; std::set<CPLString> oSetSpatialIndex; CPLString osModifiedSQL; OGR2SQLITEGetPotentialLayerNames(pszStatement, oSetLayers, oSetSpatialIndex, osModifiedSQL); return oSetLayers; }
CPLErr GDALRasterBlock::Internalize() { CPLAssert( pData == NULL ); void *pNewData = NULL; // This call will initialize the hRBLock mutex. Other call places can // only be called if we have go through there. const GIntBig nCurCacheMax = GDALGetCacheMax64(); // No risk of overflow as it is checked in GDALRasterBand::InitBlockInfo(). const int nSizeInBytes = GetBlockSize(); /* -------------------------------------------------------------------- */ /* Flush old blocks if we are nearing our memory limit. */ /* -------------------------------------------------------------------- */ bool bFirstIter = true; bool bLoopAgain = false; do { bLoopAgain = false; GDALRasterBlock* apoBlocksToFree[64] = { NULL }; int nBlocksToFree = 0; { TAKE_LOCK; if( bFirstIter ) nCacheUsed += nSizeInBytes; GDALRasterBlock *poTarget = poOldest; while( nCacheUsed > nCurCacheMax ) { while( poTarget != NULL ) { if( CPLAtomicCompareAndExchange( &(poTarget->nLockCount), 0, -1) ) break; poTarget = poTarget->poPrevious; } if( poTarget != NULL ) { if( bSleepsForBockCacheDebug ) CPLSleep(CPLAtof( CPLGetConfigOption( "GDAL_RB_INTERNALIZE_SLEEP_AFTER_DROP_LOCK", "0"))); GDALRasterBlock* _poPrevious = poTarget->poPrevious; poTarget->Detach_unlocked(); poTarget->GetBand()->UnreferenceBlock(poTarget); apoBlocksToFree[nBlocksToFree++] = poTarget; if( poTarget->GetDirty() ) { // Only free one dirty block at a time so that // other dirty blocks of other bands with the same // coordinates can be found with TryGetLockedBlock() bLoopAgain = nCacheUsed > nCurCacheMax; break; } if( nBlocksToFree == 64 ) { bLoopAgain = ( nCacheUsed > nCurCacheMax ); break; } poTarget = _poPrevious; } else { break; } } /* ------------------------------------------------------------------ */ /* Add this block to the list. */ /* ------------------------------------------------------------------ */ if( !bLoopAgain ) Touch_unlocked(); } bFirstIter = false; // Now free blocks we have detached and removed from their band. for( int i = 0; i < nBlocksToFree; ++i) { GDALRasterBlock * const poBlock = apoBlocksToFree[i]; if( poBlock->GetDirty() ) { CPLErr eErr = poBlock->Write(); if( eErr != CE_None ) { // Save the error for later reporting. poBlock->GetBand()->SetFlushBlockErr(eErr); } } // Try to recycle the data of an existing block. void* pDataBlock = poBlock->pData; if( pNewData == NULL && pDataBlock != NULL && poBlock->GetBlockSize() == nSizeInBytes ) { pNewData = pDataBlock; } else { VSIFree(poBlock->pData); } poBlock->pData = NULL; poBlock->GetBand()->AddBlockToFreeList(poBlock); } } while(bLoopAgain); if( pNewData == NULL ) { pNewData = VSI_MALLOC_VERBOSE( nSizeInBytes ); if( pNewData == NULL ) { return( CE_Failure ); } } pData = pNewData; return CE_None; }
OGRErr OGRMultiPoint::exportToWkt( char ** ppszDstText, OGRwkbVariant eWkbVariant ) const { size_t nMaxString = static_cast<size_t>(getNumGeometries()) * 22 + 130; size_t nRetLen = 0; /* -------------------------------------------------------------------- */ /* Return MULTIPOINT EMPTY if we get no valid points. */ /* -------------------------------------------------------------------- */ if( IsEmpty() ) { if( eWkbVariant == wkbVariantIso ) { if( (flags & OGR_G_3D) && (flags & OGR_G_MEASURED) ) *ppszDstText = CPLStrdup("MULTIPOINT ZM EMPTY"); else if( flags & OGR_G_MEASURED ) *ppszDstText = CPLStrdup("MULTIPOINT M EMPTY"); else if( flags & OGR_G_3D ) *ppszDstText = CPLStrdup("MULTIPOINT Z EMPTY"); else *ppszDstText = CPLStrdup("MULTIPOINT EMPTY"); } else *ppszDstText = CPLStrdup("MULTIPOINT EMPTY"); return OGRERR_NONE; } *ppszDstText = static_cast<char *>(VSI_MALLOC_VERBOSE( nMaxString )); if( *ppszDstText == NULL ) return OGRERR_NOT_ENOUGH_MEMORY; if( eWkbVariant == wkbVariantIso ) { if( (flags & OGR_G_3D) && (flags & OGR_G_MEASURED) ) snprintf( *ppszDstText, nMaxString, "%s ZM (", getGeometryName() ); else if( flags & OGR_G_MEASURED ) snprintf( *ppszDstText, nMaxString, "%s M (", getGeometryName() ); else if( flags & OGR_G_3D ) snprintf( *ppszDstText, nMaxString, "%s Z (", getGeometryName() ); else snprintf( *ppszDstText, nMaxString, "%s (", getGeometryName() ); } else snprintf( *ppszDstText, nMaxString, "%s (", getGeometryName() ); bool bMustWriteComma = false; for( int i = 0; i < getNumGeometries(); i++ ) { OGRPoint *poPoint = (OGRPoint *) getGeometryRef( i ); if( poPoint->IsEmpty() ) { CPLDebug("OGR", "OGRMultiPoint::exportToWkt() - skipping POINT EMPTY."); continue; } if( bMustWriteComma ) strcat( *ppszDstText + nRetLen, "," ); bMustWriteComma = true; nRetLen += strlen(*ppszDstText + nRetLen); if( nMaxString < nRetLen + 100 ) { nMaxString = nMaxString * 2; *ppszDstText = static_cast<char *>(CPLRealloc(*ppszDstText, nMaxString)); } if( eWkbVariant == wkbVariantIso ) { strcat( *ppszDstText + nRetLen, "(" ); nRetLen++; } OGRMakeWktCoordinateM( *ppszDstText + nRetLen, poPoint->getX(), poPoint->getY(), poPoint->getZ(), poPoint->getM(), poPoint->Is3D(), poPoint->IsMeasured() && (eWkbVariant == wkbVariantIso)); if( eWkbVariant == wkbVariantIso ) { strcat( *ppszDstText + nRetLen, ")" ); nRetLen++; } } strcat( *ppszDstText+nRetLen, ")" ); return OGRERR_NONE; }
static GDALDataset * DTEDCreateCopy( const char * pszFilename, GDALDataset *poSrcDS, int bStrict, char ** /* papszOptions */, GDALProgressFunc pfnProgress, void *pProgressData) { /* -------------------------------------------------------------------- */ /* Some some rudimentary checks */ /* -------------------------------------------------------------------- */ const int nBands = poSrcDS->GetRasterCount(); if (nBands == 0) { CPLError( CE_Failure, CPLE_NotSupported, "DTED driver does not support source dataset with zero band.\n"); return NULL; } if (nBands != 1) { CPLError( (bStrict) ? CE_Failure : CE_Warning, CPLE_NotSupported, "DTED driver only uses the first band of the dataset.\n"); if (bStrict) return NULL; } if( pfnProgress && !pfnProgress( 0.0, NULL, pProgressData ) ) return NULL; /* -------------------------------------------------------------------- */ /* Work out the level. */ /* -------------------------------------------------------------------- */ int nLevel; if( poSrcDS->GetRasterYSize() == 121 ) nLevel = 0; else if( poSrcDS->GetRasterYSize() == 1201 ) nLevel = 1; else if( poSrcDS->GetRasterYSize() == 3601 ) nLevel = 2; else { CPLError( CE_Warning, CPLE_AppDefined, "The source does not appear to be a properly formatted cell." ); nLevel = 1; } /* -------------------------------------------------------------------- */ /* Checks the input SRS */ /* -------------------------------------------------------------------- */ char* c = (char*)poSrcDS->GetProjectionRef(); OGRSpatialReference ogrsr_input; ogrsr_input.importFromWkt(&c); OGRSpatialReference ogrsr_wgs84; ogrsr_wgs84.SetWellKnownGeogCS( "WGS84" ); if ( ogrsr_input.IsSameGeogCS(&ogrsr_wgs84) == FALSE) { CPLError( CE_Warning, CPLE_AppDefined, "The source projection coordinate system is %s. Only WGS 84 is supported.\n" "The DTED driver will generate a file as if the source was WGS 84 projection coordinate system.", poSrcDS->GetProjectionRef() ); } /* -------------------------------------------------------------------- */ /* Work out the LL origin. */ /* -------------------------------------------------------------------- */ double adfGeoTransform[6]; poSrcDS->GetGeoTransform( adfGeoTransform ); int nLLOriginLat = (int) floor(adfGeoTransform[3] + poSrcDS->GetRasterYSize() * adfGeoTransform[5] + 0.5); int nLLOriginLong = (int) floor(adfGeoTransform[0] + 0.5); if (fabs(nLLOriginLat - (adfGeoTransform[3] + (poSrcDS->GetRasterYSize() - 0.5) * adfGeoTransform[5])) > 1e-10 || fabs(nLLOriginLong - (adfGeoTransform[0] + 0.5 * adfGeoTransform[1])) > 1e-10) { CPLError( CE_Warning, CPLE_AppDefined, "The corner coordinates of the source are not properly " "aligned on plain latitude/longitude boundaries."); } /* -------------------------------------------------------------------- */ /* Check horizontal source size. */ /* -------------------------------------------------------------------- */ int expectedXSize; if( ABS(nLLOriginLat) >= 80 ) expectedXSize = (poSrcDS->GetRasterYSize() - 1) / 6 + 1; else if( ABS(nLLOriginLat) >= 75 ) expectedXSize = (poSrcDS->GetRasterYSize() - 1) / 4 + 1; else if( ABS(nLLOriginLat) >= 70 ) expectedXSize = (poSrcDS->GetRasterYSize() - 1) / 3 + 1; else if( ABS(nLLOriginLat) >= 50 ) expectedXSize = (poSrcDS->GetRasterYSize() - 1) / 2 + 1; else expectedXSize = poSrcDS->GetRasterYSize(); if (poSrcDS->GetRasterXSize() != expectedXSize) { CPLError( CE_Warning, CPLE_AppDefined, "The horizontal source size is not conformant with the one " "expected by DTED Level %d at this latitude (%d pixels found instead of %d).", nLevel, poSrcDS->GetRasterXSize(), expectedXSize); } /* -------------------------------------------------------------------- */ /* Create the output dted file. */ /* -------------------------------------------------------------------- */ const char *pszError = DTEDCreate( pszFilename, nLevel, nLLOriginLat, nLLOriginLong ); if( pszError != NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "%s", pszError ); return NULL; } /* -------------------------------------------------------------------- */ /* Open the DTED file so we can output the data to it. */ /* -------------------------------------------------------------------- */ DTEDInfo *psDTED = DTEDOpen( pszFilename, "rb+", FALSE ); if( psDTED == NULL ) return NULL; /* -------------------------------------------------------------------- */ /* Read all the data in a single buffer. */ /* -------------------------------------------------------------------- */ GDALRasterBand *poSrcBand = poSrcDS->GetRasterBand( 1 ); GInt16 *panData = (GInt16 *) VSI_MALLOC_VERBOSE(sizeof(GInt16) * psDTED->nXSize * psDTED->nYSize); if (panData == NULL) { DTEDClose(psDTED); return NULL; } for( int iY = 0; iY < psDTED->nYSize; iY++ ) { if( poSrcBand->RasterIO( GF_Read, 0, iY, psDTED->nXSize, 1, (void *) (panData + iY * psDTED->nXSize), psDTED->nXSize, 1, GDT_Int16, 0, 0, NULL ) != CE_None ) { DTEDClose( psDTED ); CPLFree( panData ); return NULL; } if( pfnProgress && !pfnProgress(0.5 * (iY+1) / (double) psDTED->nYSize, NULL, pProgressData ) ) { CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated CreateCopy()" ); DTEDClose( psDTED ); CPLFree( panData ); return NULL; } } int bSrcBandHasNoData; double srcBandNoData = poSrcBand->GetNoDataValue(&bSrcBandHasNoData); /* -------------------------------------------------------------------- */ /* Write all the profiles. */ /* -------------------------------------------------------------------- */ GInt16 anProfData[3601]; int dfNodataCount=0; GByte iPartialCell; for( int iProfile = 0; iProfile < psDTED->nXSize; iProfile++ ) { for( int iY = 0; iY < psDTED->nYSize; iY++ ) { anProfData[iY] = panData[iProfile + iY * psDTED->nXSize]; if ( bSrcBandHasNoData && anProfData[iY] == srcBandNoData) { anProfData[iY] = DTED_NODATA_VALUE; dfNodataCount++; } else if ( anProfData[iY] == DTED_NODATA_VALUE ) dfNodataCount++; } DTEDWriteProfile( psDTED, iProfile, anProfData ); if( pfnProgress && !pfnProgress( 0.5 + 0.5 * (iProfile+1) / (double) psDTED->nXSize, NULL, pProgressData ) ) { CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated CreateCopy()" ); DTEDClose( psDTED ); CPLFree( panData ); return NULL; } } CPLFree( panData ); /* -------------------------------------------------------------------- */ /* Partial cell indicator: 0 for complete coverage; 1-99 for incomplete */ /* -------------------------------------------------------------------- */ char szPartialCell[3]; if ( dfNodataCount == 0 ) iPartialCell = 0; else { iPartialCell = (GByte)int(floor(100.0 - (dfNodataCount*100.0/(psDTED->nXSize * psDTED->nYSize)))); if (iPartialCell < 1) iPartialCell=1; } snprintf( szPartialCell, sizeof(szPartialCell), "%02d",iPartialCell); DTEDSetMetadata(psDTED, DTEDMD_PARTIALCELL_DSI, szPartialCell); /* -------------------------------------------------------------------- */ /* Try to copy any matching available metadata. */ /* -------------------------------------------------------------------- */ if( poSrcDS->GetMetadataItem( "DTED_VerticalAccuracy_UHL" ) != NULL ) DTEDSetMetadata( psDTED, DTEDMD_VERTACCURACY_UHL, poSrcDS->GetMetadataItem( "DTED_VerticalAccuracy_UHL" ) ); if( poSrcDS->GetMetadataItem( "DTED_VerticalAccuracy_ACC" ) != NULL ) DTEDSetMetadata( psDTED, DTEDMD_VERTACCURACY_ACC, poSrcDS->GetMetadataItem( "DTED_VerticalAccuracy_ACC" ) ); if( poSrcDS->GetMetadataItem( "DTED_SecurityCode_UHL" ) != NULL ) DTEDSetMetadata( psDTED, DTEDMD_SECURITYCODE_UHL, poSrcDS->GetMetadataItem( "DTED_SecurityCode_UHL" ) ); if( poSrcDS->GetMetadataItem( "DTED_SecurityCode_DSI" ) != NULL ) DTEDSetMetadata( psDTED, DTEDMD_SECURITYCODE_DSI, poSrcDS->GetMetadataItem( "DTED_SecurityCode_DSI" ) ); if( poSrcDS->GetMetadataItem( "DTED_UniqueRef_UHL" ) != NULL ) DTEDSetMetadata( psDTED, DTEDMD_UNIQUEREF_UHL, poSrcDS->GetMetadataItem( "DTED_UniqueRef_UHL" ) ); if( poSrcDS->GetMetadataItem( "DTED_UniqueRef_DSI" ) != NULL ) DTEDSetMetadata( psDTED, DTEDMD_UNIQUEREF_DSI, poSrcDS->GetMetadataItem( "DTED_UniqueRef_DSI" ) ); if( poSrcDS->GetMetadataItem( "DTED_DataEdition" ) != NULL ) DTEDSetMetadata( psDTED, DTEDMD_DATA_EDITION, poSrcDS->GetMetadataItem( "DTED_DataEdition" ) ); if( poSrcDS->GetMetadataItem( "DTED_MatchMergeVersion" ) != NULL ) DTEDSetMetadata( psDTED, DTEDMD_MATCHMERGE_VERSION, poSrcDS->GetMetadataItem( "DTED_MatchMergeVersion" ) ); if( poSrcDS->GetMetadataItem( "DTED_MaintenanceDate" ) != NULL ) DTEDSetMetadata( psDTED, DTEDMD_MAINT_DATE, poSrcDS->GetMetadataItem( "DTED_MaintenanceDate" ) ); if( poSrcDS->GetMetadataItem( "DTED_MatchMergeDate" ) != NULL ) DTEDSetMetadata( psDTED, DTEDMD_MATCHMERGE_DATE, poSrcDS->GetMetadataItem( "DTED_MatchMergeDate" ) ); if( poSrcDS->GetMetadataItem( "DTED_MaintenanceDescription" ) != NULL ) DTEDSetMetadata( psDTED, DTEDMD_MAINT_DESCRIPTION, poSrcDS->GetMetadataItem( "DTED_MaintenanceDescription" ) ); if( poSrcDS->GetMetadataItem( "DTED_Producer" ) != NULL ) DTEDSetMetadata( psDTED, DTEDMD_PRODUCER, poSrcDS->GetMetadataItem( "DTED_Producer" ) ); if( poSrcDS->GetMetadataItem( "DTED_VerticalDatum" ) != NULL ) DTEDSetMetadata( psDTED, DTEDMD_VERTDATUM, poSrcDS->GetMetadataItem( "DTED_VerticalDatum" ) ); if( poSrcDS->GetMetadataItem( "DTED_HorizontalDatum" ) != NULL ) DTEDSetMetadata( psDTED, DTEDMD_HORIZDATUM, poSrcDS->GetMetadataItem( "DTED_HorizontalDatum" ) ); if( poSrcDS->GetMetadataItem( "DTED_DigitizingSystem" ) != NULL ) DTEDSetMetadata( psDTED, DTEDMD_DIGITIZING_SYS, poSrcDS->GetMetadataItem( "DTED_DigitizingSystem" ) ); if( poSrcDS->GetMetadataItem( "DTED_CompilationDate" ) != NULL ) DTEDSetMetadata( psDTED, DTEDMD_COMPILATION_DATE, poSrcDS->GetMetadataItem( "DTED_CompilationDate" ) ); if( poSrcDS->GetMetadataItem( "DTED_HorizontalAccuracy" ) != NULL ) DTEDSetMetadata( psDTED, DTEDMD_HORIZACCURACY, poSrcDS->GetMetadataItem( "DTED_HorizontalAccuracy" ) ); if( poSrcDS->GetMetadataItem( "DTED_RelHorizontalAccuracy" ) != NULL ) DTEDSetMetadata( psDTED, DTEDMD_REL_HORIZACCURACY, poSrcDS->GetMetadataItem( "DTED_RelHorizontalAccuracy" ) ); if( poSrcDS->GetMetadataItem( "DTED_RelVerticalAccuracy" ) != NULL ) DTEDSetMetadata( psDTED, DTEDMD_REL_VERTACCURACY, poSrcDS->GetMetadataItem( "DTED_RelVerticalAccuracy" ) ); /* -------------------------------------------------------------------- */ /* Try to open the resulting DTED file. */ /* -------------------------------------------------------------------- */ DTEDClose( psDTED ); /* -------------------------------------------------------------------- */ /* Reopen and copy missing information into a PAM file. */ /* -------------------------------------------------------------------- */ GDALPamDataset *poDS = (GDALPamDataset *) GDALOpen( pszFilename, GA_ReadOnly ); if( poDS ) poDS->CloneInfo( poSrcDS, GCIF_PAM_DEFAULT ); return poDS; }
template<class T> int GDALComputeMedianCutPCTInternal( GDALRasterBandH hRed, GDALRasterBandH hGreen, GDALRasterBandH hBlue, GByte* pabyRedBand, GByte* pabyGreenBand, GByte* pabyBlueBand, int (*pfnIncludePixel)(int, int, void*), int nColors, int nBits, T* panHistogram, // NULL, or >= size (1<<nBits)^3 * sizeof(T) bytes. GDALColorTableH hColorTable, GDALProgressFunc pfnProgress, void * pProgressArg ) { VALIDATE_POINTER1( hRed, "GDALComputeMedianCutPCT", CE_Failure ); VALIDATE_POINTER1( hGreen, "GDALComputeMedianCutPCT", CE_Failure ); VALIDATE_POINTER1( hBlue, "GDALComputeMedianCutPCT", CE_Failure ); CPLErr err = CE_None; /* -------------------------------------------------------------------- */ /* Validate parameters. */ /* -------------------------------------------------------------------- */ const int nXSize = GDALGetRasterBandXSize( hRed ); const int nYSize = GDALGetRasterBandYSize( hRed ); if( GDALGetRasterBandXSize( hGreen ) != nXSize || GDALGetRasterBandYSize( hGreen ) != nYSize || GDALGetRasterBandXSize( hBlue ) != nXSize || GDALGetRasterBandYSize( hBlue ) != nYSize ) { CPLError(CE_Failure, CPLE_IllegalArg, "Green or blue band doesn't match size of red band."); return CE_Failure; } if( pfnIncludePixel != NULL ) { CPLError(CE_Failure, CPLE_IllegalArg, "GDALComputeMedianCutPCT() doesn't currently support " "pfnIncludePixel function."); return CE_Failure; } if( nColors <= 0 ) { CPLError(CE_Failure, CPLE_IllegalArg, "GDALComputeMedianCutPCT(): " "nColors must be strictly greater than 1."); return CE_Failure; } if( nColors > 256 ) { CPLError(CE_Failure, CPLE_IllegalArg, "GDALComputeMedianCutPCT(): " "nColors must be lesser than or equal to 256."); return CE_Failure; } if( pfnProgress == NULL ) pfnProgress = GDALDummyProgress; /* ==================================================================== */ /* STEP 1: create empty boxes. */ /* ==================================================================== */ if( static_cast<GUInt32>(nXSize) > std::numeric_limits<T>::max() / static_cast<GUInt32>(nYSize) ) { CPLError(CE_Warning, CPLE_AppDefined, "GDALComputeMedianCutPCTInternal() not called " "with large enough type"); } T nPixels = 0; if( nBits == 8 && pabyRedBand != NULL && pabyGreenBand != NULL && pabyBlueBand != NULL && static_cast<GUInt32>(nXSize) <= std::numeric_limits<T>::max() / static_cast<GUInt32>(nYSize) ) { nPixels = static_cast<T>(nXSize) * static_cast<T>(nYSize); } const int nCLevels = 1 << nBits; T* histogram = NULL; HashHistogram* psHashHistogram = NULL; if( panHistogram ) { if( nBits == 8 && static_cast<GUIntBig>(nXSize) * nYSize <= 65536 ) { // If the image is small enough, then the number of colors // will be limited and using a hashmap, rather than a full table // will be more efficient. histogram = NULL; psHashHistogram = (HashHistogram*)panHistogram; memset(psHashHistogram, 0xFF, sizeof(HashHistogram) * PRIME_FOR_65536); } else { histogram = panHistogram; memset(histogram, 0, nCLevels*nCLevels*nCLevels * sizeof(T)); } } else { histogram = static_cast<T*>( VSI_CALLOC_VERBOSE(nCLevels * nCLevels * nCLevels, sizeof(T))); if( histogram == NULL ) { return CE_Failure; } } Colorbox *box_list = static_cast<Colorbox *>(CPLMalloc(nColors*sizeof (Colorbox))); Colorbox *freeboxes = box_list; freeboxes[0].next = &freeboxes[1]; freeboxes[0].prev = NULL; for( int i = 1; i < nColors-1; ++i ) { freeboxes[i].next = &freeboxes[i+1]; freeboxes[i].prev = &freeboxes[i-1]; } freeboxes[nColors-1].next = NULL; freeboxes[nColors-1].prev = &freeboxes[nColors-2]; /* ==================================================================== */ /* Build histogram. */ /* ==================================================================== */ /* -------------------------------------------------------------------- */ /* Initialize the box datastructures. */ /* -------------------------------------------------------------------- */ Colorbox *ptr = freeboxes; freeboxes = ptr->next; if( freeboxes ) freeboxes->prev = NULL; Colorbox *usedboxes = NULL; // TODO(schwehr): What? ptr->next = usedboxes; usedboxes = ptr; if( ptr->next ) ptr->next->prev = ptr; ptr->rmin = 999; ptr->gmin = 999; ptr->bmin = 999; ptr->rmax = -1; ptr->gmax = -1; ptr->bmax = -1; ptr->total = static_cast<GUIntBig>(nXSize) * static_cast<GUIntBig>(nYSize); /* -------------------------------------------------------------------- */ /* Collect histogram. */ /* -------------------------------------------------------------------- */ // TODO(schwehr): Move these closer to usage after removing gotos. const int nColorShift = 8 - nBits; int nColorCounter = 0; GByte anRed[256] = {}; GByte anGreen[256] = {}; GByte anBlue[256] = {}; GByte *pabyRedLine = static_cast<GByte *>(VSI_MALLOC_VERBOSE(nXSize)); GByte *pabyGreenLine = static_cast<GByte *>(VSI_MALLOC_VERBOSE(nXSize)); GByte *pabyBlueLine = static_cast<GByte *>(VSI_MALLOC_VERBOSE(nXSize)); if( pabyRedLine == NULL || pabyGreenLine == NULL || pabyBlueLine == NULL ) { err = CE_Failure; goto end_and_cleanup; } for( int iLine = 0; iLine < nYSize; iLine++ ) { if( !pfnProgress( iLine / static_cast<double>(nYSize), "Generating Histogram", pProgressArg ) ) { CPLError( CE_Failure, CPLE_UserInterrupt, "User Terminated" ); err = CE_Failure; goto end_and_cleanup; } err = GDALRasterIO( hRed, GF_Read, 0, iLine, nXSize, 1, pabyRedLine, nXSize, 1, GDT_Byte, 0, 0 ); if( err == CE_None ) err = GDALRasterIO( hGreen, GF_Read, 0, iLine, nXSize, 1, pabyGreenLine, nXSize, 1, GDT_Byte, 0, 0 ); if( err == CE_None ) err = GDALRasterIO( hBlue, GF_Read, 0, iLine, nXSize, 1, pabyBlueLine, nXSize, 1, GDT_Byte, 0, 0 ); if( err != CE_None ) goto end_and_cleanup; for( int iPixel = 0; iPixel < nXSize; iPixel++ ) { const int nRed = pabyRedLine[iPixel] >> nColorShift; const int nGreen = pabyGreenLine[iPixel] >> nColorShift; const int nBlue = pabyBlueLine[iPixel] >> nColorShift; ptr->rmin = std::min(ptr->rmin, nRed); ptr->gmin = std::min(ptr->gmin, nGreen); ptr->bmin = std::min(ptr->bmin, nBlue); ptr->rmax = std::max(ptr->rmax, nRed); ptr->gmax = std::max(ptr->gmax, nGreen); ptr->bmax = std::max(ptr->bmax, nBlue); bool bFirstOccurrence; if( psHashHistogram ) { int* pnColor = FindAndInsertColorCount(psHashHistogram, MAKE_COLOR_CODE(nRed, nGreen, nBlue)); bFirstOccurrence = ( *pnColor == 0 ); (*pnColor)++; } else { T* pnColor = HISTOGRAM(histogram, nCLevels, nRed, nGreen, nBlue); bFirstOccurrence = ( *pnColor == 0 ); (*pnColor)++; } if( bFirstOccurrence) { if( nColorShift == 0 && nColorCounter < nColors ) { anRed[nColorCounter] = static_cast<GByte>(nRed); anGreen[nColorCounter] = static_cast<GByte>(nGreen); anBlue[nColorCounter] = static_cast<GByte>(nBlue); } nColorCounter++; } } } if( !pfnProgress( 1.0, "Generating Histogram", pProgressArg ) ) { CPLError( CE_Failure, CPLE_UserInterrupt, "User Terminated" ); err = CE_Failure; goto end_and_cleanup; } if( nColorShift == 0 && nColorCounter <= nColors ) { #if DEBUG_VERBOSE CPLDebug("MEDIAN_CUT", "%d colors found <= %d", nColorCounter, nColors); #endif for( int iColor = 0; iColor < nColorCounter; iColor++ ) { const GDALColorEntry sEntry = { static_cast<GByte>(anRed[iColor]), static_cast<GByte>(anGreen[iColor]), static_cast<GByte>(anBlue[iColor]), 255 }; GDALSetColorEntry( hColorTable, iColor, &sEntry ); } goto end_and_cleanup; } /* ==================================================================== */ /* STEP 3: continually subdivide boxes until no more free */ /* boxes remain or until all colors assigned. */ /* ==================================================================== */ while( freeboxes != NULL ) { ptr = largest_box(usedboxes); if( ptr != NULL ) splitbox(ptr, histogram, psHashHistogram, nCLevels, &freeboxes, &usedboxes, pabyRedBand, pabyGreenBand, pabyBlueBand, nPixels); else freeboxes = NULL; } /* ==================================================================== */ /* STEP 4: assign colors to all boxes */ /* ==================================================================== */ ptr = usedboxes; for( int i = 0; ptr != NULL; ++i, ptr = ptr->next ) { const GDALColorEntry sEntry = { static_cast<GByte>(((ptr->rmin + ptr->rmax) << nColorShift) / 2), static_cast<GByte>(((ptr->gmin + ptr->gmax) << nColorShift) / 2), static_cast<GByte>(((ptr->bmin + ptr->bmax) << nColorShift) / 2), 255 }; GDALSetColorEntry( hColorTable, i, &sEntry ); } end_and_cleanup: CPLFree( pabyRedLine ); CPLFree( pabyGreenLine ); CPLFree( pabyBlueLine ); // We're done with the boxes now. CPLFree(box_list); freeboxes = NULL; usedboxes = NULL; if( panHistogram == NULL ) CPLFree( histogram ); return err; }
//! @cond Doxygen_Suppress OGRErr OGRGeometryCollection::exportToWktInternal( char ** ppszDstText, OGRwkbVariant eWkbVariant, const char* pszSkipPrefix ) const { size_t nCumulativeLength = 0; OGRErr eErr = OGRERR_NONE; bool bMustWriteComma = false; /* -------------------------------------------------------------------- */ /* Build a list of strings containing the stuff for each Geom. */ /* -------------------------------------------------------------------- */ char **papszGeoms = nGeomCount ? static_cast<char **>(CPLCalloc(sizeof(char *), nGeomCount)) : nullptr; for( int iGeom = 0; iGeom < nGeomCount; iGeom++ ) { eErr = papoGeoms[iGeom]->exportToWkt(&(papszGeoms[iGeom]), eWkbVariant); if( eErr != OGRERR_NONE ) goto error; size_t nSkip = 0; if( pszSkipPrefix != nullptr && EQUALN(papszGeoms[iGeom], pszSkipPrefix, strlen(pszSkipPrefix)) && papszGeoms[iGeom][strlen(pszSkipPrefix)] == ' ' ) { nSkip = strlen(pszSkipPrefix) + 1; if( STARTS_WITH_CI(papszGeoms[iGeom] + nSkip, "ZM ") ) nSkip += 3; else if( STARTS_WITH_CI(papszGeoms[iGeom] + nSkip, "M ") ) nSkip += 2; if( STARTS_WITH_CI(papszGeoms[iGeom] + nSkip, "Z ") ) nSkip += 2; // Skip empty subgeoms. if( papszGeoms[iGeom][nSkip] != '(' ) { CPLDebug( "OGR", "OGRGeometryCollection::exportToWkt() - skipping %s.", papszGeoms[iGeom] ); CPLFree( papszGeoms[iGeom] ); papszGeoms[iGeom] = nullptr; continue; } } else if( eWkbVariant != wkbVariantIso ) { char *substr = nullptr; // TODO(schwehr): Looks dangerous. Cleanup. if( (substr = strstr(papszGeoms[iGeom], " Z")) != nullptr ) memmove(substr, substr + strlen(" Z"), 1 + strlen(substr + strlen(" Z"))); } nCumulativeLength += strlen(papszGeoms[iGeom] + nSkip); } /* -------------------------------------------------------------------- */ /* Return XXXXXXXXXXXXXXX EMPTY if we get no valid line string. */ /* -------------------------------------------------------------------- */ if( nCumulativeLength == 0 ) { CPLFree( papszGeoms ); CPLString osEmpty; if( eWkbVariant == wkbVariantIso ) { if( Is3D() && IsMeasured() ) osEmpty.Printf("%s ZM EMPTY", getGeometryName()); else if( IsMeasured() ) osEmpty.Printf("%s M EMPTY", getGeometryName()); else if( Is3D() ) osEmpty.Printf("%s Z EMPTY", getGeometryName()); else osEmpty.Printf("%s EMPTY", getGeometryName()); } else { osEmpty.Printf("%s EMPTY", getGeometryName()); } *ppszDstText = CPLStrdup(osEmpty); return OGRERR_NONE; } /* -------------------------------------------------------------------- */ /* Allocate the right amount of space for the aggregated string */ /* -------------------------------------------------------------------- */ *ppszDstText = static_cast<char *>( VSI_MALLOC_VERBOSE(nCumulativeLength + nGeomCount + 26)); if( *ppszDstText == nullptr ) { eErr = OGRERR_NOT_ENOUGH_MEMORY; goto error; } /* -------------------------------------------------------------------- */ /* Build up the string, freeing temporary strings as we go. */ /* -------------------------------------------------------------------- */ strcpy( *ppszDstText, getGeometryName() ); if( eWkbVariant == wkbVariantIso ) { if( (flags & OGR_G_3D) && (flags & OGR_G_MEASURED) ) strcat( *ppszDstText, " ZM" ); else if( flags & OGR_G_3D ) strcat( *ppszDstText, " Z" ); else if( flags & OGR_G_MEASURED ) strcat( *ppszDstText, " M" ); } strcat( *ppszDstText, " (" ); nCumulativeLength = strlen(*ppszDstText); for( int iGeom = 0; iGeom < nGeomCount; iGeom++ ) { if( papszGeoms[iGeom] == nullptr ) continue; if( bMustWriteComma ) (*ppszDstText)[nCumulativeLength++] = ','; bMustWriteComma = true; size_t nSkip = 0; if( pszSkipPrefix != nullptr && EQUALN(papszGeoms[iGeom], pszSkipPrefix, strlen(pszSkipPrefix)) && papszGeoms[iGeom][strlen(pszSkipPrefix)] == ' ' ) { nSkip = strlen(pszSkipPrefix) + 1; if( STARTS_WITH_CI(papszGeoms[iGeom] + nSkip, "ZM ") ) nSkip += 3; else if( STARTS_WITH_CI(papszGeoms[iGeom] + nSkip, "M ") ) nSkip += 2; else if( STARTS_WITH_CI(papszGeoms[iGeom] + nSkip, "Z ") ) nSkip += 2; } const size_t nGeomLength = strlen(papszGeoms[iGeom] + nSkip); memcpy( *ppszDstText + nCumulativeLength, papszGeoms[iGeom] + nSkip, nGeomLength ); nCumulativeLength += nGeomLength; VSIFree( papszGeoms[iGeom] ); } (*ppszDstText)[nCumulativeLength++] = ')'; (*ppszDstText)[nCumulativeLength] = '\0'; CPLFree( papszGeoms ); return OGRERR_NONE; error: for( int iGeom = 0; iGeom < nGeomCount; iGeom++ ) CPLFree( papszGeoms[iGeom] ); CPLFree( papszGeoms ); return eErr; }
NTFRecord::NTFRecord( FILE * fp ) : nType(99), nLength(0), pszData(NULL) { if( fp == NULL ) return; /* ==================================================================== */ /* Read lines until we get to one without a continuation mark. */ /* ==================================================================== */ char szLine[MAX_RECORD_LEN+3] = {}; int nNewLength = 0; do { nNewLength = ReadPhysicalLine( fp, szLine ); if( nNewLength == -1 || nNewLength == -2 ) break; while( nNewLength > 0 && szLine[nNewLength-1] == ' ' ) szLine[--nNewLength] = '\0'; if( nNewLength < 2 || szLine[nNewLength-1] != '%' ) { CPLError( CE_Failure, CPLE_AppDefined, "Corrupt NTF record, missing end '%%'." ); CPLFree( pszData ); pszData = NULL; break; } if( pszData == NULL ) { nLength = nNewLength - 2; pszData = (char *) VSI_MALLOC_VERBOSE(nLength+1); if (pszData == NULL) { return; } memcpy( pszData, szLine, nLength ); pszData[nLength] = '\0'; } else { if( !STARTS_WITH_CI(szLine, "00") || nNewLength < 4 ) { CPLError( CE_Failure, CPLE_AppDefined, "Invalid line"); VSIFree(pszData); pszData = NULL; return; } char* pszNewData = (char *) VSI_REALLOC_VERBOSE(pszData,nLength+(nNewLength-4)+1); if (pszNewData == NULL) { VSIFree(pszData); pszData = NULL; return; } pszData = pszNewData; memcpy( pszData+nLength, szLine+2, nNewLength-4 ); nLength += nNewLength-4; pszData[nLength] = '\0'; } } while( szLine[nNewLength-2] == '1' ); /* -------------------------------------------------------------------- */ /* Figure out the record type. */ /* -------------------------------------------------------------------- */ if( pszData != NULL ) { char szType[3]; strncpy( szType, pszData, 2 ); szType[2] = '\0'; nType = atoi(szType); } }
CPLErr IRISRasterBand::IReadBlock( CPL_UNUSED int nBlockXOff, int nBlockYOff, void * pImage ) { IRISDataset *poGDS = (IRISDataset *) poDS; //Every product type has it's own size. TODO: Move it like dataType int nDataLength = 1; if(poGDS->nDataTypeCode == 2){nDataLength=1;} else if(poGDS->nDataTypeCode == 37){nDataLength=2;} else if(poGDS->nDataTypeCode == 33){nDataLength=2;} else if(poGDS->nDataTypeCode == 32){nDataLength=1;} int i; //We allocate space for storing a record: if (pszRecord == NULL) { if (bBufferAllocFailed) return CE_Failure; pszRecord = (unsigned char *) VSI_MALLOC_VERBOSE(nBlockXSize*nDataLength); if (pszRecord == NULL) { bBufferAllocFailed = TRUE; return CE_Failure; } } //Prepare to read (640 is the header size in bytes) and read (the y axis in the IRIS files in the inverse direction) //The previous bands are also added as an offset VSIFSeekL( poGDS->fp, 640 + (vsi_l_offset)nDataLength*poGDS->GetRasterXSize()*poGDS->GetRasterYSize()*(this->nBand-1) + (vsi_l_offset)nBlockXSize*nDataLength*(poGDS->GetRasterYSize()-1-nBlockYOff), SEEK_SET ); if( (int)VSIFReadL( pszRecord, nBlockXSize*nDataLength, 1, poGDS->fp ) != 1 ) return CE_Failure; //If datatype is dbZ or dBT: //See point 3.3.3 at page 3.33 of the manual if(poGDS->nDataTypeCode == 2 || poGDS->nDataTypeCode == 1){ float fVal; for (i=0;i<nBlockXSize;i++){ fVal = (((float) *(pszRecord+i*nDataLength)) -64)/2.0f; if (fVal == 95.5f) fVal = -9999.0f; ((float *) pImage)[i] = fVal; } //If datatype is dbZ2 or dBT2: //See point 3.3.4 at page 3.33 of the manual } else if(poGDS->nDataTypeCode == 8 || poGDS->nDataTypeCode == 9){ float fVal; for (i=0;i<nBlockXSize;i++){ fVal = (((float) CPL_LSBUINT16PTR(pszRecord+i*nDataLength)) - 32768)/100.0f; if (fVal == 327.67f) fVal = -9999.0f; ((float *) pImage)[i] = fVal; } //Fliquid2 (Rain1 & Rainn products) //See point 3.3.11 at page 3.43 of the manual } else if(poGDS->nDataTypeCode == 37){ unsigned short nVal, nExp, nMantissa; float fVal2=0; for (i=0;i<nBlockXSize;i++){ nVal = CPL_LSBUINT16PTR(pszRecord+i*nDataLength); nExp = nVal>>12; nMantissa = nVal - (nExp<<12); if (nVal == 65535) fVal2 = -9999.0f; else if (nExp == 0) fVal2 = (float) nMantissa / 1000.0f; else fVal2 = (float)((nMantissa+4096)<<(nExp-1))/1000.0f; ((float *) pImage)[i] = fVal2; } //VIL2 (VIL products) //See point 3.3.41 at page 3.54 of the manual } else if(poGDS->nDataTypeCode == 33){
CPLWorkerThreadJob * CPLWorkerThreadPool::GetNextJob( CPLWorkerThread* psWorkerThread ) { while(true) { CPLAcquireMutex(hMutex, 1000.0); if( eState == CPLWTS_STOP ) { CPLReleaseMutex(hMutex); return nullptr; } CPLList* psTopJobIter = psJobQueue; if( psTopJobIter ) { psJobQueue = psTopJobIter->psNext; #if DEBUG_VERBOSE CPLDebug("JOB", "%p got a job", psWorkerThread); #endif CPLWorkerThreadJob* psJob = static_cast<CPLWorkerThreadJob*>(psTopJobIter->pData); CPLReleaseMutex(hMutex); CPLFree(psTopJobIter); return psJob; } if( !psWorkerThread->bMarkedAsWaiting ) { psWorkerThread->bMarkedAsWaiting = TRUE; nWaitingWorkerThreads++; CPLAssert(nWaitingWorkerThreads <= static_cast<int>(aWT.size())); CPLList* psItem = static_cast<CPLList *>(VSI_MALLOC_VERBOSE(sizeof(CPLList))); if( psItem == nullptr ) { eState = CPLWTS_ERROR; CPLCondSignal(hCond); CPLReleaseMutex(hMutex); return nullptr; } psItem->pData = psWorkerThread; psItem->psNext = psWaitingWorkerThreadsList; psWaitingWorkerThreadsList = psItem; #if DEBUG_VERBOSE CPLAssert(CPLListCount(psWaitingWorkerThreadsList) == nWaitingWorkerThreads); #endif } CPLCondSignal(hCond); CPLAcquireMutex(psWorkerThread->hMutex, 1000.0); #if DEBUG_VERBOSE CPLDebug("JOB", "%p sleeping", psWorkerThread); #endif CPLReleaseMutex(hMutex); CPLCondWait( psWorkerThread->hCond, psWorkerThread->hMutex ); // TODO(rouault): Explain or delete. // CPLWorkerThreadJob* psJob = psWorkerThread->psNextJob; // psWorkerThread->psNextJob = nullptr; CPLReleaseMutex(psWorkerThread->hMutex); // TODO(rouault): Explain or delete. // if( psJob ) // return psJob; } }
json_object* OGRPLScenesDataV1Dataset::RunRequest(const char* pszURL, int bQuiet404Error, const char* pszHTTPVerb, bool bExpectJSonReturn, const char* pszPostContent) { char** papszOptions = CSLAddString(GetBaseHTTPOptions(), nullptr); // We need to set it each time as CURL would reuse the previous value // if reusing the same connection papszOptions = CSLSetNameValue(papszOptions, "CUSTOMREQUEST", pszHTTPVerb); if( pszPostContent != nullptr ) { CPLString osHeaders = CSLFetchNameValueDef(papszOptions, "HEADERS", ""); if( !osHeaders.empty() ) osHeaders += "\r\n"; osHeaders += "Content-Type: application/json"; papszOptions = CSLSetNameValue(papszOptions, "HEADERS", osHeaders); papszOptions = CSLSetNameValue(papszOptions, "POSTFIELDS", pszPostContent); } papszOptions = CSLSetNameValue(papszOptions, "MAX_RETRY", "3"); CPLHTTPResult *psResult = nullptr; if( STARTS_WITH(m_osBaseURL, "/vsimem/") && STARTS_WITH(pszURL, "/vsimem/") ) { psResult = (CPLHTTPResult*) CPLCalloc(1, sizeof(CPLHTTPResult)); vsi_l_offset nDataLengthLarge = 0; CPLString osURL(pszURL); if( osURL[osURL.size()-1 ] == '/' ) osURL.resize(osURL.size()-1); if( pszPostContent != nullptr ) { osURL += "&POSTFIELDS="; osURL += pszPostContent; } CPLDebug("PLSCENES", "Fetching %s", osURL.c_str()); GByte* pabyBuf = VSIGetMemFileBuffer(osURL, &nDataLengthLarge, FALSE); size_t nDataLength = static_cast<size_t>(nDataLengthLarge); if( pabyBuf ) { psResult->pabyData = (GByte*) VSI_MALLOC_VERBOSE(1 + nDataLength); if( psResult->pabyData ) { memcpy(psResult->pabyData, pabyBuf, nDataLength); psResult->pabyData[nDataLength] = 0; } } else { psResult->pszErrBuf = CPLStrdup(CPLSPrintf("Error 404. Cannot find %s", osURL.c_str())); } } else { if( bQuiet404Error ) CPLPushErrorHandler(CPLQuietErrorHandler); psResult = CPLHTTPFetch( pszURL, papszOptions); if( bQuiet404Error ) CPLPopErrorHandler(); } CSLDestroy(papszOptions); if( pszPostContent != nullptr && m_bMustCleanPersistent ) { papszOptions = CSLSetNameValue(nullptr, "CLOSE_PERSISTENT", CPLSPrintf("PLSCENES:%p", this)); CPLHTTPDestroyResult(CPLHTTPFetch(m_osBaseURL, papszOptions)); CSLDestroy(papszOptions); m_bMustCleanPersistent = false; } if( psResult->pszErrBuf != nullptr ) { if( !(bQuiet404Error && strstr(psResult->pszErrBuf, "404")) ) { CPLError(CE_Failure, CPLE_AppDefined, "%s", psResult->pabyData ? (const char*) psResult->pabyData : psResult->pszErrBuf); } CPLHTTPDestroyResult(psResult); return nullptr; } if( !bExpectJSonReturn && (psResult->pabyData == nullptr || psResult->nDataLen == 0) ) { CPLHTTPDestroyResult(psResult); return nullptr; } if( psResult->pabyData == nullptr ) { CPLError(CE_Failure, CPLE_AppDefined, "Empty content returned by server"); CPLHTTPDestroyResult(psResult); return nullptr; } const char* pszText = reinterpret_cast<const char*>(psResult->pabyData); #ifdef DEBUG_VERBOSE CPLDebug("PLScenes", "%s", pszText); #endif json_object* poObj = nullptr; if( !OGRJSonParse(pszText, &poObj, true) ) { CPLHTTPDestroyResult(psResult); return nullptr; } CPLHTTPDestroyResult(psResult); if( json_object_get_type(poObj) != json_type_object ) { CPLError( CE_Failure, CPLE_AppDefined, "Return is not a JSON dictionary"); json_object_put(poObj); poObj = nullptr; } return poObj; }
int NITFDESGetTRE( NITFDES* psDES, int nOffset, char szTREName[7], char** ppabyTREData, int* pnFoundTRESize) { char szTREHeader[12]; char szTRETempName[7]; NITFSegmentInfo* psSegInfo; VSILFILE* fp; int nTRESize; memset(szTREName, '\0', 7); if (ppabyTREData) *ppabyTREData = NULL; if (pnFoundTRESize) *pnFoundTRESize = 0; if (nOffset < 0) return FALSE; if (psDES == NULL) return FALSE; if (CSLFetchNameValue(psDES->papszMetadata, "NITF_DESOFLW") == NULL) return FALSE; psSegInfo = psDES->psFile->pasSegmentInfo + psDES->iSegment; fp = psDES->psFile->fp; if ((size_t)nOffset >= psSegInfo->nSegmentSize) return FALSE; if( VSIFSeekL(fp, psSegInfo->nSegmentStart + nOffset, SEEK_SET) != 0 || VSIFReadL(szTREHeader, 1, 11, fp) != 11) { /* Some files have a nSegmentSize larger than what it is in reality */ /* So exit silently if we're at end of file */ if( VSIFSeekL(fp, 0, SEEK_END) != 0 || VSIFTellL(fp) == psSegInfo->nSegmentStart + nOffset) return FALSE; CPLError(CE_Failure, CPLE_FileIO, "Cannot get 11 bytes at offset " CPL_FRMT_GUIB ".", psSegInfo->nSegmentStart + nOffset ); return FALSE; } szTREHeader[11] = '\0'; memcpy(szTRETempName, szTREHeader, 6); szTRETempName[6] = '\0'; nTRESize = atoi(szTREHeader + 6); if (nTRESize < 0) { CPLError(CE_Failure, CPLE_AppDefined, "Invalid size (%d) for TRE %s", nTRESize, szTRETempName); return FALSE; } if ((size_t)(nOffset + 11 + nTRESize) > psSegInfo->nSegmentSize) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot read %s TRE. Not enough bytes : remaining %d, expected %d", szTRETempName, (int)(psSegInfo->nSegmentSize - (nOffset + 11)), nTRESize); return FALSE; } if (ppabyTREData) { /* Allocate one extra byte for the NULL terminating character */ *ppabyTREData = (char*) VSI_MALLOC_VERBOSE(nTRESize + 1); if (*ppabyTREData == NULL) { return FALSE; } (*ppabyTREData)[nTRESize] = '\0'; if ((int)VSIFReadL(*ppabyTREData, 1, nTRESize, fp) != nTRESize) { CPLError(CE_Failure, CPLE_FileIO, "Cannot get %d bytes at offset " CPL_FRMT_GUIB ".", nTRESize, VSIFTellL(fp) ); VSIFree(*ppabyTREData); *ppabyTREData = NULL; return FALSE; } } strcpy(szTREName, szTRETempName); if (pnFoundTRESize) *pnFoundTRESize = nTRESize; return TRUE; }
CPLErr NWT_GRDRasterBand::IReadBlock( CPL_UNUSED int nBlockXOff, int nBlockYOff, void *pImage ) { NWT_GRDDataset *poGDS = reinterpret_cast<NWT_GRDDataset *>( poDS ); if( nBlockXSize > INT_MAX / 2 ) return CE_Failure; const int nRecordSize = nBlockXSize * 2; unsigned short raw1; VSIFSeekL( poGDS->fp, 1024 + nRecordSize * static_cast<vsi_l_offset>( nBlockYOff ), SEEK_SET ); GByte *pabyRecord = reinterpret_cast<GByte *>( VSI_MALLOC_VERBOSE( nRecordSize ) ); if( pabyRecord == NULL ) return CE_Failure; if( (int)VSIFReadL( pabyRecord, 1, nRecordSize, poGDS->fp ) != nRecordSize ) { CPLFree( pabyRecord ); return CE_Failure; } if( nBand == 4 ) //Z values { for( int i = 0; i < nBlockXSize; i++ ) { memcpy( reinterpret_cast<void *>( &raw1 ), reinterpret_cast<void *>(pabyRecord + 2 * i), 2 ); CPL_LSBPTR16(&raw1); if( raw1 == 0 ) { reinterpret_cast<float *>( pImage )[i] = -1.e37f; // null value } else { reinterpret_cast<float *>( pImage )[i] = static_cast<float>( dfOffset + ((raw1 - 1) * dfScale) ); } } } else if( nBand == 1 ) // red values { for( int i = 0; i < nBlockXSize; i++ ) { memcpy( reinterpret_cast<void *>( &raw1 ), reinterpret_cast<void *>(pabyRecord + 2 * i), 2 ); CPL_LSBPTR16(&raw1); reinterpret_cast<char *>( pImage )[i] = poGDS->ColorMap[raw1 / 16].r; } } else if( nBand == 2 ) // green { for( int i = 0; i < nBlockXSize; i++ ) { memcpy( reinterpret_cast<void *> ( &raw1 ), reinterpret_cast<void *> ( pabyRecord + 2 * i ), 2 ); CPL_LSBPTR16(&raw1); reinterpret_cast<char *>( pImage )[i] = poGDS->ColorMap[raw1 / 16].g; } } else if( nBand == 3 ) // blue { for( int i = 0; i < nBlockXSize; i++ ) { memcpy( reinterpret_cast<void *>( &raw1 ), reinterpret_cast<void *>( pabyRecord + 2 * i ), 2 ); CPL_LSBPTR16(&raw1); reinterpret_cast<char *>( pImage )[i] = poGDS->ColorMap[raw1 / 16].b; } } else { CPLError( CE_Failure, CPLE_IllegalArg, "No band number %d", nBand ); CPLFree( pabyRecord ); return CE_Failure; } CPLFree( pabyRecord ); return CE_None; }
int NITFDESExtractShapefile(NITFDES* psDES, const char* pszRadixFileName) { NITFSegmentInfo* psSegInfo; const char* apszExt[3]; int anOffset[4]; int iShpFile; char* pszFilename; size_t nFilenameLen; if ( CSLFetchNameValue(psDES->papszMetadata, "NITF_SHAPE_USE") == NULL ) return FALSE; psSegInfo = psDES->psFile->pasSegmentInfo + psDES->iSegment; apszExt[0] = CSLFetchNameValue(psDES->papszMetadata, "NITF_SHAPE1_NAME"); anOffset[0] = atoi(CSLFetchNameValue(psDES->papszMetadata, "NITF_SHAPE1_START")); apszExt[1] = CSLFetchNameValue(psDES->papszMetadata, "NITF_SHAPE2_NAME"); anOffset[1] = atoi(CSLFetchNameValue(psDES->papszMetadata, "NITF_SHAPE2_START")); apszExt[2] = CSLFetchNameValue(psDES->papszMetadata, "NITF_SHAPE3_NAME"); anOffset[2] = atoi(CSLFetchNameValue(psDES->papszMetadata, "NITF_SHAPE3_START")); anOffset[3] = (int) psSegInfo->nSegmentSize; for(iShpFile = 0; iShpFile < 3; iShpFile ++) { if (!EQUAL(apszExt[iShpFile], "SHP") && !EQUAL(apszExt[iShpFile], "SHX") && !EQUAL(apszExt[iShpFile], "DBF")) return FALSE; if (anOffset[iShpFile] < 0 || anOffset[iShpFile] >= anOffset[iShpFile+1]) return FALSE; } nFilenameLen = strlen(pszRadixFileName) + 4 + 1; pszFilename = (char*) VSI_MALLOC_VERBOSE(nFilenameLen); if (pszFilename == NULL) return FALSE; for(iShpFile = 0; iShpFile < 3; iShpFile ++) { VSILFILE* fp; GByte* pabyBuffer; int nSize = anOffset[iShpFile+1] - anOffset[iShpFile]; pabyBuffer = (GByte*) VSI_MALLOC_VERBOSE(nSize); if (pabyBuffer == NULL) { VSIFree(pszFilename); return FALSE; } if( VSIFSeekL(psDES->psFile->fp, psSegInfo->nSegmentStart + anOffset[iShpFile], SEEK_SET) != 0 || VSIFReadL(pabyBuffer, 1, nSize, psDES->psFile->fp) != (size_t)nSize) { VSIFree(pabyBuffer); VSIFree(pszFilename); return FALSE; } snprintf(pszFilename, nFilenameLen, "%s.%s", pszRadixFileName, apszExt[iShpFile]); fp = VSIFOpenL(pszFilename, "wb"); if (fp == NULL) { VSIFree(pabyBuffer); VSIFree(pszFilename); return FALSE; } if( (int) VSIFWriteL(pabyBuffer, 1, nSize, fp) != nSize ) { CPL_IGNORE_RET_VAL_INT(VSIFCloseL(fp)); VSIFree(pabyBuffer); VSIFree(pszFilename); return FALSE; } CPL_IGNORE_RET_VAL_INT(VSIFCloseL(fp)); VSIFree(pabyBuffer); } VSIFree(pszFilename); return TRUE; }
CPLErr IRISRasterBand::IReadBlock( int /* nBlockXOff */, int nBlockYOff, void * pImage ) { IRISDataset *poGDS = static_cast<IRISDataset *>(poDS); // Every product type has its own size. TODO: Move it like dataType. int nDataLength = 1; if( poGDS->nDataTypeCode == 2 ) nDataLength = 1; else if( poGDS->nDataTypeCode == 8 ) nDataLength = 2; else if( poGDS->nDataTypeCode == 9 ) nDataLength = 2; else if( poGDS->nDataTypeCode == 37 ) nDataLength = 2; else if( poGDS->nDataTypeCode == 33 ) nDataLength = 2; else if( poGDS->nDataTypeCode == 32 ) nDataLength = 1; // We allocate space for storing a record: if( pszRecord == nullptr ) { if( bBufferAllocFailed ) return CE_Failure; pszRecord = static_cast<unsigned char *>( VSI_MALLOC_VERBOSE(nBlockXSize*nDataLength)); if( pszRecord == nullptr ) { bBufferAllocFailed = true; return CE_Failure; } } // Prepare to read (640 is the header size in bytes) and read (the // y axis in the IRIS files in the inverse direction). The // previous bands are also added as an offset VSIFSeekL( poGDS->fp, 640 + static_cast<vsi_l_offset>(nDataLength)*poGDS->GetRasterXSize()*poGDS->GetRasterYSize()*(this->nBand-1) + static_cast<vsi_l_offset>(nBlockXSize)*nDataLength*(poGDS->GetRasterYSize()-1-nBlockYOff), SEEK_SET ); if( static_cast<int>(VSIFReadL( pszRecord, nBlockXSize*nDataLength, 1, poGDS->fp )) != 1 ) return CE_Failure; // If datatype is dbZ or dBT: // See point 3.3.3 at page 3.33 of the manual. if( poGDS->nDataTypeCode == 2 || poGDS->nDataTypeCode == 1 ) { for( int i = 0; i < nBlockXSize; i++) { float fVal = ((*(pszRecord + i * nDataLength)) - 64.0f) / 2.0f; if( fVal == 95.5f ) fVal = -9999.0f; ((float *) pImage)[i] = fVal; } // If datatype is dbZ2 or dBT2: // See point 3.3.4 at page 3.33 of the manual. } else if( poGDS->nDataTypeCode == 8 || poGDS->nDataTypeCode == 9 ) { for( int i = 0; i < nBlockXSize; i++) { float fVal = (CPL_LSBUINT16PTR(pszRecord + i * nDataLength) - 32768.0f) / 100.0f; if( fVal == 327.67f ) fVal = -9999.0f; ((float *) pImage)[i] = fVal; } // Fliquid2 (Rain1 & Rainn products) // See point 3.3.11 at page 3.43 of the manual. } else if( poGDS->nDataTypeCode == 37 ) { for( int i = 0; i < nBlockXSize; i++) { const unsigned short nVal = CPL_LSBUINT16PTR(pszRecord+i*nDataLength); const unsigned short nExp = nVal>>12; const unsigned short nMantissa = nVal - (nExp<<12); float fVal2 = 0.0f; if( nVal == 65535 ) fVal2 = -9999.0f; else if( nExp == 0 ) fVal2 = nMantissa / 1000.0f; else fVal2 = ((nMantissa + 4096) << (nExp - 1)) / 1000.0f; ((float *) pImage)[i] = fVal2; } // VIL2 (VIL products) // See point 3.3.41 at page 3.54 of the manual. } else if( poGDS->nDataTypeCode == 33 )
OGRErr OGRPolygon::exportToWkt( char ** ppszDstText, OGRwkbVariant eWkbVariant ) const { bool bMustWriteComma = false; /* -------------------------------------------------------------------- */ /* If we have no valid exterior ring, return POLYGON EMPTY. */ /* -------------------------------------------------------------------- */ if( getExteriorRing() == NULL || getExteriorRing()->IsEmpty() ) { if( eWkbVariant == wkbVariantIso ) { if( (flags & OGR_G_3D) && (flags & OGR_G_MEASURED) ) *ppszDstText = CPLStrdup((CPLString(getGeometryName()) + " ZM EMPTY").c_str()); else if( flags & OGR_G_MEASURED ) *ppszDstText = CPLStrdup((CPLString(getGeometryName()) + " M EMPTY").c_str()); else if( flags & OGR_G_3D ) *ppszDstText = CPLStrdup((CPLString(getGeometryName()) + " Z EMPTY").c_str()); else *ppszDstText = CPLStrdup((CPLString(getGeometryName()) + " EMPTY").c_str()); } else *ppszDstText = CPLStrdup((CPLString(getGeometryName()) + " EMPTY").c_str()); return OGRERR_NONE; } /* -------------------------------------------------------------------- */ /* Build a list of strings containing the stuff for each ring. */ /* -------------------------------------------------------------------- */ char **papszRings = static_cast<char **>(CPLCalloc(sizeof(char *), oCC.nCurveCount)); size_t nCumulativeLength = 0; size_t nNonEmptyRings = 0; size_t *pnRingBeginning = static_cast<size_t *>(CPLCalloc(sizeof(size_t), oCC.nCurveCount)); OGRErr eErr; for( int iRing = 0; iRing < oCC.nCurveCount; iRing++ ) { OGRLinearRing* poLR = (OGRLinearRing*) oCC.papoCurves[iRing]; //poLR->setFlags( getFlags() ); poLR->set3D(Is3D()); poLR->setMeasured(IsMeasured()); if( poLR->getNumPoints() == 0 ) { papszRings[iRing] = NULL; continue; } eErr = poLR->exportToWkt( &(papszRings[iRing]), eWkbVariant ); if( eErr != OGRERR_NONE ) goto error; if( STARTS_WITH_CI(papszRings[iRing], "LINEARRING ZM (") ) pnRingBeginning[iRing] = 14; else if( STARTS_WITH_CI(papszRings[iRing], "LINEARRING M (") ) pnRingBeginning[iRing] = 13; else if( STARTS_WITH_CI(papszRings[iRing], "LINEARRING Z (") ) pnRingBeginning[iRing] = 13; else if( STARTS_WITH_CI(papszRings[iRing], "LINEARRING (") ) pnRingBeginning[iRing] = 11; else { CPLAssert(false); } nCumulativeLength += strlen(papszRings[iRing] + pnRingBeginning[iRing]); nNonEmptyRings++; } /* -------------------------------------------------------------------- */ /* Allocate exactly the right amount of space for the */ /* aggregated string. */ /* -------------------------------------------------------------------- */ *ppszDstText = (char *) VSI_MALLOC_VERBOSE( nCumulativeLength + nNonEmptyRings + strlen(getGeometryName()) + strlen(" ZM ()") + 1); if( *ppszDstText == NULL ) { eErr = OGRERR_NOT_ENOUGH_MEMORY; goto error; } /* -------------------------------------------------------------------- */ /* Build up the string, freeing temporary strings as we go. */ /* -------------------------------------------------------------------- */ if( eWkbVariant == wkbVariantIso ) { if( (flags & OGR_G_3D) && (flags & OGR_G_MEASURED) ) strcpy( *ppszDstText, (CPLString(getGeometryName()) + " ZM (").c_str() ); else if( flags & OGR_G_MEASURED ) strcpy( *ppszDstText, (CPLString(getGeometryName()) + " M (").c_str() ); else if( flags & OGR_G_3D ) strcpy( *ppszDstText, (CPLString(getGeometryName()) + " Z (").c_str() ); else strcpy( *ppszDstText, (CPLString(getGeometryName()) + " (").c_str() ); } else strcpy( *ppszDstText, (CPLString(getGeometryName()) + " (").c_str() ); nCumulativeLength = strlen(*ppszDstText); for( int iRing = 0; iRing < oCC.nCurveCount; iRing++ ) { if( papszRings[iRing] == NULL ) { CPLDebug( "OGR", "OGRPolygon::exportToWkt() - skipping empty ring."); continue; } if( bMustWriteComma ) (*ppszDstText)[nCumulativeLength++] = ','; bMustWriteComma = true; size_t nRingLen = strlen(papszRings[iRing] + pnRingBeginning[iRing]); memcpy( *ppszDstText + nCumulativeLength, papszRings[iRing] + pnRingBeginning[iRing], nRingLen ); nCumulativeLength += nRingLen; VSIFree( papszRings[iRing] ); } (*ppszDstText)[nCumulativeLength++] = ')'; (*ppszDstText)[nCumulativeLength] = '\0'; CPLFree( papszRings ); CPLFree( pnRingBeginning ); return OGRERR_NONE; error: for( int iRing = 0; iRing < oCC.nCurveCount; iRing++ ) CPLFree(papszRings[iRing]); CPLFree(papszRings); return eErr; }
CEOSRecord * CEOSReadRecord( CEOSImage *psImage ) { GByte abyHeader[12]; CEOSRecord *psRecord; GUInt32 nRecordNumUInt32, nLengthUInt32; /* -------------------------------------------------------------------- */ /* Read the standard CEOS header. */ /* -------------------------------------------------------------------- */ if( VSIFEofL( psImage->fpImage ) ) return NULL; if( VSIFReadL( abyHeader, 1, 12, psImage->fpImage ) != 12 ) { CPLError( CE_Failure, CPLE_FileIO, "Ran out of data reading CEOS record." ); return NULL; } /* -------------------------------------------------------------------- */ /* Extract this information. */ /* -------------------------------------------------------------------- */ psRecord = (CEOSRecord *) CPLMalloc(sizeof(CEOSRecord)); if( psImage->bLittleEndian ) { CPL_SWAP32PTR( abyHeader + 0 ); CPL_SWAP32PTR( abyHeader + 8 ); } nRecordNumUInt32 = (abyHeader[0] << 24) + (abyHeader[1] << 16) + (abyHeader[2] << 8) + abyHeader[3]; psRecord->nRecordType = (abyHeader[4] << 24) + (abyHeader[5] << 16) + (abyHeader[6] << 8) + abyHeader[7]; nLengthUInt32 = (abyHeader[8] << 24) + (abyHeader[9] << 16) + (abyHeader[10] << 8) + abyHeader[11]; /* -------------------------------------------------------------------- */ /* Does it look reasonable? We assume there can't be too many */ /* records and that the length must be between 12 and 200000. */ /* -------------------------------------------------------------------- */ if( nRecordNumUInt32 > 200000 || nLengthUInt32 < 12 || nLengthUInt32 > 200000 ) { CPLError( CE_Failure, CPLE_AppDefined, "CEOS record leader appears to be corrupt.\n" "Record Number = %u, Record Length = %u\n", nRecordNumUInt32, nLengthUInt32 ); CPLFree( psRecord ); return NULL; } psRecord->nRecordNum = (int)nRecordNumUInt32; psRecord->nLength = (int)nLengthUInt32; /* -------------------------------------------------------------------- */ /* Read the remainder of the record into a buffer. Ensure that */ /* the first 12 bytes gets moved into this buffer as well. */ /* -------------------------------------------------------------------- */ psRecord->pachData = (char *) VSI_MALLOC_VERBOSE(psRecord->nLength ); if( psRecord->pachData == NULL ) { CPLFree( psRecord ); return NULL; } memcpy( psRecord->pachData, abyHeader, 12 ); if( (int)VSIFReadL( psRecord->pachData + 12, 1, psRecord->nLength-12, psImage->fpImage ) != psRecord->nLength - 12 ) { CPLError( CE_Failure, CPLE_FileIO, "Short read on CEOS record data.\n" ); CPLFree( psRecord ); return NULL; } return psRecord; }