CPLErr WEBPDataset::Uncompress() { if (bHasBeenUncompressed) return eUncompressErrRet; bHasBeenUncompressed = TRUE; eUncompressErrRet = CE_Failure; // To avoid excessive memory allocation attempts // Normally WebP images are no larger than 16383x16383*4 ~= 1 GB if( nRasterXSize > INT_MAX / (nRasterYSize * nBands) ) { CPLError(CE_Failure, CPLE_NotSupported, "Too large image"); return CE_Failure; } pabyUncompressed = reinterpret_cast<GByte*>( VSIMalloc3(nRasterXSize, nRasterYSize, nBands ) ); if (pabyUncompressed == nullptr) return CE_Failure; VSIFSeekL(fpImage, 0, SEEK_END); vsi_l_offset nSizeLarge = VSIFTellL(fpImage); if( nSizeLarge != static_cast<vsi_l_offset>( static_cast<uint32_t>( nSizeLarge ) ) ) return CE_Failure; VSIFSeekL(fpImage, 0, SEEK_SET); uint32_t nSize = static_cast<uint32_t>( nSizeLarge ); uint8_t* pabyCompressed = reinterpret_cast<uint8_t*>( VSIMalloc(nSize) ); if (pabyCompressed == nullptr) return CE_Failure; VSIFReadL(pabyCompressed, 1, nSize, fpImage); uint8_t* pRet; if (nBands == 4) pRet = WebPDecodeRGBAInto( pabyCompressed, static_cast<uint32_t>( nSize ), static_cast<uint8_t*>( pabyUncompressed), nRasterXSize * nRasterYSize * nBands, nRasterXSize * nBands ); else pRet = WebPDecodeRGBInto( pabyCompressed, static_cast<uint32_t>( nSize ), static_cast<uint8_t*>( pabyUncompressed ), nRasterXSize * nRasterYSize * nBands, nRasterXSize * nBands ); VSIFree(pabyCompressed); if (pRet == nullptr) { CPLError(CE_Failure, CPLE_AppDefined, "WebPDecodeRGBInto() failed"); return CE_Failure; } eUncompressErrRet = CE_None; return CE_None; }
int HF2Dataset::LoadBlockMap() { if (bHasLoaderBlockMap) return panBlockOffset != NULL; bHasLoaderBlockMap = TRUE; const int nXBlocks = (nRasterXSize + nTileSize - 1) / nTileSize; const int nYBlocks = (nRasterYSize + nTileSize - 1) / nTileSize; panBlockOffset = (vsi_l_offset*) VSIMalloc3(sizeof(vsi_l_offset), nXBlocks, nYBlocks); if (panBlockOffset == NULL) { return FALSE; } for(int j = 0; j < nYBlocks; j++) { for(int i = 0; i < nXBlocks; i++) { vsi_l_offset nOff = VSIFTellL(fp); panBlockOffset[(nYBlocks - 1 - j) * nXBlocks + i] = nOff; //VSIFSeekL(fp, 4 + 4, SEEK_CUR); float fScale, fOff; VSIFReadL(&fScale, 4, 1, fp); VSIFReadL(&fOff, 4, 1, fp); CPL_LSBPTR32(&fScale); CPL_LSBPTR32(&fOff); //printf("fScale = %f, fOff = %f\n", fScale, fOff); const int nCols = MIN(nTileSize, nRasterXSize - nTileSize *i); const int nLines = MIN(nTileSize, nRasterYSize - nTileSize *j); for(int k = 0; k < nLines; k++) { GByte nWordSize; if( VSIFReadL(&nWordSize, 1, 1, fp) != 1 ) { CPLError(CE_Failure, CPLE_FileIO, "File too short"); VSIFree(panBlockOffset); panBlockOffset = NULL; return FALSE; } //printf("nWordSize=%d\n", nWordSize); if (nWordSize == 1 || nWordSize == 2 || nWordSize == 4) VSIFSeekL(fp, static_cast<vsi_l_offset>(4 + nWordSize * (nCols - 1)), SEEK_CUR); else { CPLError(CE_Failure, CPLE_AppDefined, "Got unexpected byte depth (%d) for block (%d, %d) line %d", (int)nWordSize, i, j, k); VSIFree(panBlockOffset); panBlockOffset = NULL; return FALSE; } } } } return TRUE; }
CPLErr WEBPDataset::Uncompress() { if (bHasBeenUncompressed) return eUncompressErrRet; bHasBeenUncompressed = TRUE; eUncompressErrRet = CE_Failure; pabyUncompressed = reinterpret_cast<GByte*>( VSIMalloc3(nRasterXSize, nRasterYSize, nBands ) ); if (pabyUncompressed == NULL) return CE_Failure; VSIFSeekL(fpImage, 0, SEEK_END); vsi_l_offset nSizeLarge = VSIFTellL(fpImage); if( nSizeLarge != static_cast<vsi_l_offset>( static_cast<uint32_t>( nSizeLarge ) ) ) return CE_Failure; VSIFSeekL(fpImage, 0, SEEK_SET); uint32_t nSize = static_cast<uint32_t>( nSizeLarge ); uint8_t* pabyCompressed = reinterpret_cast<uint8_t*>( VSIMalloc(nSize) ); if (pabyCompressed == NULL) return CE_Failure; VSIFReadL(pabyCompressed, 1, nSize, fpImage); uint8_t* pRet; if (nBands == 4) pRet = WebPDecodeRGBAInto( pabyCompressed, static_cast<uint32_t>( nSize ), static_cast<uint8_t*>( pabyUncompressed), nRasterXSize * nRasterYSize * nBands, nRasterXSize * nBands ); else pRet = WebPDecodeRGBInto( pabyCompressed, static_cast<uint32_t>( nSize ), static_cast<uint8_t*>( pabyUncompressed ), nRasterXSize * nRasterYSize * nBands, nRasterXSize * nBands ); VSIFree(pabyCompressed); if (pRet == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "WebPDecodeRGBInto() failed"); return CE_Failure; } eUncompressErrRet = CE_None; return CE_None; }
CPLErr WEBPDataset::Uncompress() { if (bHasBeenUncompressed) return eUncompressErrRet; bHasBeenUncompressed = TRUE; eUncompressErrRet = CE_Failure; pabyUncompressed = (GByte*)VSIMalloc3(nRasterXSize, nRasterYSize, nBands); if (pabyUncompressed == NULL) return CE_Failure; VSIFSeekL(fpImage, 0, SEEK_END); vsi_l_offset nSize = VSIFTellL(fpImage); if (nSize != (vsi_l_offset)(uint32_t)nSize) return CE_Failure; VSIFSeekL(fpImage, 0, SEEK_SET); uint8_t* pabyCompressed = (uint8_t*)VSIMalloc(nSize); if (pabyCompressed == NULL) return CE_Failure; VSIFReadL(pabyCompressed, 1, nSize, fpImage); uint8_t* pRet; if (nBands == 4) pRet = WebPDecodeRGBAInto(pabyCompressed, (uint32_t)nSize, (uint8_t*)pabyUncompressed, nRasterXSize * nRasterYSize * nBands, nRasterXSize * nBands); else pRet = WebPDecodeRGBInto(pabyCompressed, (uint32_t)nSize, (uint8_t*)pabyUncompressed, nRasterXSize * nRasterYSize * nBands, nRasterXSize * nBands); VSIFree(pabyCompressed); if (pRet == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "WebPDecodeRGBInto() failed"); return CE_Failure; } eUncompressErrRet = CE_None; return CE_None; }
IntergraphRasterBand::IntergraphRasterBand( IntergraphDataset *poDS, int nBand, int nBandOffset, GDALDataType eType ) { this->poColorTable = new GDALColorTable(); this->poDS = poDS; this->nBand = nBand != 0 ? nBand : poDS->nBands; this->nTiles = 0; this->eDataType = eType; this->pabyBlockBuf = NULL; this->pahTiles = NULL; this->nRGBIndex = 0; this->nBandStart = nBandOffset; this->bTiled = FALSE; // -------------------------------------------------------------------- // Get Header Info // -------------------------------------------------------------------- memcpy(&hHeaderOne, &poDS->hHeaderOne, sizeof(hHeaderOne)); memcpy(&hHeaderTwo, &poDS->hHeaderTwo, sizeof(hHeaderTwo)); // -------------------------------------------------------------------- // Get the image start from Words to Follow (WTF) // -------------------------------------------------------------------- nDataOffset = nBandOffset + 2 + ( 2 * ( hHeaderOne.WordsToFollow + 1 ) ); // -------------------------------------------------------------------- // Get Color Tabel from Color Table Type (CTV) // -------------------------------------------------------------------- uint32 nEntries = hHeaderTwo.NumberOfCTEntries; if( nEntries > 0 ) { switch ( hHeaderTwo.ColorTableType ) { case EnvironVColorTable: INGR_GetEnvironVColors( poDS->fp, nBandOffset, nEntries, poColorTable ); if (poColorTable->GetColorEntryCount() == 0) return; break; case IGDSColorTable: INGR_GetIGDSColors( poDS->fp, nBandOffset, nEntries, poColorTable ); if (poColorTable->GetColorEntryCount() == 0) return; break; default: CPLDebug( "INGR", "Wrong Color table type (%d), number of colors (%d)", hHeaderTwo.ColorTableType, nEntries ); } } // -------------------------------------------------------------------- // Set Dimension // -------------------------------------------------------------------- nRasterXSize = hHeaderOne.PixelsPerLine; nRasterYSize = hHeaderOne.NumberOfLines; nBlockXSize = nRasterXSize; nBlockYSize = 1; // -------------------------------------------------------------------- // Get tile directory // -------------------------------------------------------------------- this->eFormat = (INGR_Format) hHeaderOne.DataTypeCode; this->bTiled = (hHeaderOne.DataTypeCode == TiledRasterData); if( bTiled ) { nTiles = INGR_GetTileDirectory( poDS->fp, nDataOffset, nRasterXSize, nRasterYSize, &hTileDir, &pahTiles ); if (nTiles == 0) return; eFormat = (INGR_Format) hTileDir.DataTypeCode; // ---------------------------------------------------------------- // Set blocks dimensions based on tiles // ---------------------------------------------------------------- nBlockXSize = MIN( hTileDir.TileSize, (uint32) nRasterXSize ); nBlockYSize = MIN( hTileDir.TileSize, (uint32) nRasterYSize ); } if (nBlockXSize <= 0 || nBlockYSize <= 0) { pabyBlockBuf = NULL; CPLError(CE_Failure, CPLE_AppDefined, "Invalid block dimensions"); return; } // -------------------------------------------------------------------- // Incomplete tiles have Block Offset greater than: // -------------------------------------------------------------------- nFullBlocksX = ( nRasterXSize / nBlockXSize ); nFullBlocksY = ( nRasterYSize / nBlockYSize ); // -------------------------------------------------------------------- // Get the Data Type from Format // -------------------------------------------------------------------- this->eDataType = INGR_GetDataType( (uint16) eFormat ); // -------------------------------------------------------------------- // Allocate buffer for a Block of data // -------------------------------------------------------------------- nBlockBufSize = nBlockXSize * nBlockYSize * GDALGetDataTypeSize( eDataType ) / 8; pabyBlockBuf = (GByte*) VSIMalloc3( nBlockXSize, nBlockYSize, GDALGetDataTypeSize( eDataType ) / 8); if (pabyBlockBuf == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot allocate %d bytes", nBlockBufSize); return; } // -------------------------------------------------------------------- // More Metadata Information // -------------------------------------------------------------------- SetMetadataItem( "FORMAT", INGR_GetFormatName( (uint16) eFormat ), "IMAGE_STRUCTURE" ); if( bTiled ) { SetMetadataItem( "TILESSIZE", CPLSPrintf ("%d", hTileDir.TileSize), "IMAGE_STRUCTURE" ); } else { SetMetadataItem( "TILED", "NO", "IMAGE_STRUCTURE" ); } SetMetadataItem( "ORIENTATION", INGR_GetOrientation( hHeaderOne.ScanlineOrientation ), "IMAGE_STRUCTURE" ); }
static int GeoLocLoadFullData( GDALGeoLocTransformInfo *psTransform ) { int nXSize, nYSize; int nXSize_XBand = GDALGetRasterXSize( psTransform->hDS_X ); int nYSize_XBand = GDALGetRasterYSize( psTransform->hDS_X ); int nXSize_YBand = GDALGetRasterXSize( psTransform->hDS_Y ); int nYSize_YBand = GDALGetRasterYSize( psTransform->hDS_Y ); if (nYSize_XBand == 1 && nYSize_YBand == 1) { nXSize = nXSize_XBand; nYSize = nXSize_YBand; } else { nXSize = nXSize_XBand; nYSize = nYSize_XBand; } psTransform->nGeoLocXSize = nXSize; psTransform->nGeoLocYSize = nYSize; psTransform->padfGeoLocY = (double *) VSIMalloc3(sizeof(double), nXSize, nYSize); psTransform->padfGeoLocX = (double *) VSIMalloc3(sizeof(double), nXSize, nYSize); if( psTransform->padfGeoLocX == NULL || psTransform->padfGeoLocY == NULL ) { CPLError(CE_Failure, CPLE_OutOfMemory, "GeoLocLoadFullData : Out of memory"); return FALSE; } if (nYSize_XBand == 1 && nYSize_YBand == 1) { /* Case of regular grid */ /* The XBAND contains the x coordinates for all lines */ /* The YBAND contains the y coordinates for all columns */ double* padfTempX = (double*)VSIMalloc2(nXSize, sizeof(double)); double* padfTempY = (double*)VSIMalloc2(nYSize, sizeof(double)); if (padfTempX == NULL || padfTempY == NULL) { CPLFree(padfTempX); CPLFree(padfTempY); CPLError(CE_Failure, CPLE_OutOfMemory, "GeoLocLoadFullData : Out of memory"); return FALSE; } CPLErr eErr = CE_None; eErr = GDALRasterIO( psTransform->hBand_X, GF_Read, 0, 0, nXSize, 1, padfTempX, nXSize, 1, GDT_Float64, 0, 0 ); int i,j; for(j=0;j<nYSize;j++) { memcpy( psTransform->padfGeoLocX + j * nXSize, padfTempX, nXSize * sizeof(double) ); } if (eErr == CE_None) { eErr = GDALRasterIO( psTransform->hBand_Y, GF_Read, 0, 0, nYSize, 1, padfTempY, nYSize, 1, GDT_Float64, 0, 0 ); for(j=0;j<nYSize;j++) { for(i=0;i<nXSize;i++) { psTransform->padfGeoLocY[j * nXSize + i] = padfTempY[j]; } } } CPLFree(padfTempX); CPLFree(padfTempY); if (eErr != CE_None) return FALSE; } else { if( GDALRasterIO( psTransform->hBand_X, GF_Read, 0, 0, nXSize, nYSize, psTransform->padfGeoLocX, nXSize, nYSize, GDT_Float64, 0, 0 ) != CE_None || GDALRasterIO( psTransform->hBand_Y, GF_Read, 0, 0, nXSize, nYSize, psTransform->padfGeoLocY, nXSize, nYSize, GDT_Float64, 0, 0 ) != CE_None ) return FALSE; } psTransform->dfNoDataX = GDALGetRasterNoDataValue( psTransform->hBand_X, &(psTransform->bHasNoData) ); return TRUE; }
static int GeoLocGenerateBackMap( GDALGeoLocTransformInfo *psTransform ) { int nXSize = psTransform->nGeoLocXSize; int nYSize = psTransform->nGeoLocYSize; int nMaxIter = 3; /* -------------------------------------------------------------------- */ /* Scan forward map for lat/long extents. */ /* -------------------------------------------------------------------- */ double dfMinX=0, dfMaxX=0, dfMinY=0, dfMaxY=0; int i, bInit = FALSE; for( i = nXSize * nYSize - 1; i >= 0; i-- ) { if( !psTransform->bHasNoData || psTransform->padfGeoLocX[i] != psTransform->dfNoDataX ) { if( bInit ) { dfMinX = MIN(dfMinX,psTransform->padfGeoLocX[i]); dfMaxX = MAX(dfMaxX,psTransform->padfGeoLocX[i]); dfMinY = MIN(dfMinY,psTransform->padfGeoLocY[i]); dfMaxY = MAX(dfMaxY,psTransform->padfGeoLocY[i]); } else { bInit = TRUE; dfMinX = dfMaxX = psTransform->padfGeoLocX[i]; dfMinY = dfMaxY = psTransform->padfGeoLocY[i]; } } } /* -------------------------------------------------------------------- */ /* Decide on resolution for backmap. We aim for slightly */ /* higher resolution than the source but we can't easily */ /* establish how much dead space there is in the backmap, so it */ /* is approximate. */ /* -------------------------------------------------------------------- */ double dfTargetPixels = (nXSize * nYSize * 1.3); double dfPixelSize = sqrt((dfMaxX - dfMinX) * (dfMaxY - dfMinY) / dfTargetPixels); int nBMXSize, nBMYSize; nBMYSize = psTransform->nBackMapHeight = (int) ((dfMaxY - dfMinY) / dfPixelSize + 1); nBMXSize= psTransform->nBackMapWidth = (int) ((dfMaxX - dfMinX) / dfPixelSize + 1); if (nBMXSize > INT_MAX / nBMYSize) { CPLError(CE_Failure, CPLE_AppDefined, "Int overflow : %d x %d", nBMXSize, nBMYSize); return FALSE; } dfMinX -= dfPixelSize/2.0; dfMaxY += dfPixelSize/2.0; psTransform->adfBackMapGeoTransform[0] = dfMinX; psTransform->adfBackMapGeoTransform[1] = dfPixelSize; psTransform->adfBackMapGeoTransform[2] = 0.0; psTransform->adfBackMapGeoTransform[3] = dfMaxY; psTransform->adfBackMapGeoTransform[4] = 0.0; psTransform->adfBackMapGeoTransform[5] = -dfPixelSize; /* -------------------------------------------------------------------- */ /* Allocate backmap, and initialize to nodata value (-1.0). */ /* -------------------------------------------------------------------- */ GByte *pabyValidFlag; pabyValidFlag = (GByte *) VSICalloc(nBMXSize, nBMYSize); psTransform->pafBackMapX = (float *) VSIMalloc3(nBMXSize, nBMYSize, sizeof(float)); psTransform->pafBackMapY = (float *) VSIMalloc3(nBMXSize, nBMYSize, sizeof(float)); if( pabyValidFlag == NULL || psTransform->pafBackMapX == NULL || psTransform->pafBackMapY == NULL ) { CPLError( CE_Failure, CPLE_OutOfMemory, "Unable to allocate %dx%d back-map for geolocation array transformer.", nBMXSize, nBMYSize ); CPLFree( pabyValidFlag ); return FALSE; } for( i = nBMXSize * nBMYSize - 1; i >= 0; i-- ) { psTransform->pafBackMapX[i] = -1.0; psTransform->pafBackMapY[i] = -1.0; } /* -------------------------------------------------------------------- */ /* Run through the whole geoloc array forward projecting and */ /* pushing into the backmap. */ /* Initialise to the nMaxIter+1 value so we can spot genuinely */ /* valid pixels in the hole-filling loop. */ /* -------------------------------------------------------------------- */ int iBMX, iBMY; int iX, iY; for( iY = 0; iY < nYSize; iY++ ) { for( iX = 0; iX < nXSize; iX++ ) { if( psTransform->bHasNoData && psTransform->padfGeoLocX[iX + iY * nXSize] == psTransform->dfNoDataX ) continue; i = iX + iY * nXSize; iBMX = (int) ((psTransform->padfGeoLocX[i] - dfMinX) / dfPixelSize); iBMY = (int) ((dfMaxY - psTransform->padfGeoLocY[i]) / dfPixelSize); if( iBMX < 0 || iBMY < 0 || iBMX >= nBMXSize || iBMY >= nBMYSize ) continue; psTransform->pafBackMapX[iBMX + iBMY * nBMXSize] = (float)(iX * psTransform->dfPIXEL_STEP + psTransform->dfPIXEL_OFFSET); psTransform->pafBackMapY[iBMX + iBMY * nBMXSize] = (float)(iY * psTransform->dfLINE_STEP + psTransform->dfLINE_OFFSET); pabyValidFlag[iBMX + iBMY * nBMXSize] = (GByte) (nMaxIter+1); } } /* -------------------------------------------------------------------- */ /* Now, loop over the backmap trying to fill in holes with */ /* nearby values. */ /* -------------------------------------------------------------------- */ int iIter; int nNumValid; for( iIter = 0; iIter < nMaxIter; iIter++ ) { nNumValid = 0; for( iBMY = 0; iBMY < nBMYSize; iBMY++ ) { for( iBMX = 0; iBMX < nBMXSize; iBMX++ ) { // if this point is already set, ignore it. if( pabyValidFlag[iBMX + iBMY*nBMXSize] ) { nNumValid++; continue; } int nCount = 0; double dfXSum = 0.0, dfYSum = 0.0; int nMarkedAsGood = nMaxIter - iIter; // left? if( iBMX > 0 && pabyValidFlag[iBMX-1+iBMY*nBMXSize] > nMarkedAsGood ) { dfXSum += psTransform->pafBackMapX[iBMX-1+iBMY*nBMXSize]; dfYSum += psTransform->pafBackMapY[iBMX-1+iBMY*nBMXSize]; nCount++; } // right? if( iBMX + 1 < nBMXSize && pabyValidFlag[iBMX+1+iBMY*nBMXSize] > nMarkedAsGood ) { dfXSum += psTransform->pafBackMapX[iBMX+1+iBMY*nBMXSize]; dfYSum += psTransform->pafBackMapY[iBMX+1+iBMY*nBMXSize]; nCount++; } // top? if( iBMY > 0 && pabyValidFlag[iBMX+(iBMY-1)*nBMXSize] > nMarkedAsGood ) { dfXSum += psTransform->pafBackMapX[iBMX+(iBMY-1)*nBMXSize]; dfYSum += psTransform->pafBackMapY[iBMX+(iBMY-1)*nBMXSize]; nCount++; } // bottom? if( iBMY + 1 < nBMYSize && pabyValidFlag[iBMX+(iBMY+1)*nBMXSize] > nMarkedAsGood ) { dfXSum += psTransform->pafBackMapX[iBMX+(iBMY+1)*nBMXSize]; dfYSum += psTransform->pafBackMapY[iBMX+(iBMY+1)*nBMXSize]; nCount++; } // top-left? if( iBMX > 0 && iBMY > 0 && pabyValidFlag[iBMX-1+(iBMY-1)*nBMXSize] > nMarkedAsGood ) { dfXSum += psTransform->pafBackMapX[iBMX-1+(iBMY-1)*nBMXSize]; dfYSum += psTransform->pafBackMapY[iBMX-1+(iBMY-1)*nBMXSize]; nCount++; } // top-right? if( iBMX + 1 < nBMXSize && iBMY > 0 && pabyValidFlag[iBMX+1+(iBMY-1)*nBMXSize] > nMarkedAsGood ) { dfXSum += psTransform->pafBackMapX[iBMX+1+(iBMY-1)*nBMXSize]; dfYSum += psTransform->pafBackMapY[iBMX+1+(iBMY-1)*nBMXSize]; nCount++; } // bottom-left? if( iBMX > 0 && iBMY + 1 < nBMYSize && pabyValidFlag[iBMX-1+(iBMY+1)*nBMXSize] > nMarkedAsGood ) { dfXSum += psTransform->pafBackMapX[iBMX-1+(iBMY+1)*nBMXSize]; dfYSum += psTransform->pafBackMapY[iBMX-1+(iBMY+1)*nBMXSize]; nCount++; } // bottom-right? if( iBMX + 1 < nBMXSize && iBMY + 1 < nBMYSize && pabyValidFlag[iBMX+1+(iBMY+1)*nBMXSize] > nMarkedAsGood ) { dfXSum += psTransform->pafBackMapX[iBMX+1+(iBMY+1)*nBMXSize]; dfYSum += psTransform->pafBackMapY[iBMX+1+(iBMY+1)*nBMXSize]; nCount++; } if( nCount > 0 ) { psTransform->pafBackMapX[iBMX + iBMY * nBMXSize] = (float)(dfXSum/nCount); psTransform->pafBackMapY[iBMX + iBMY * nBMXSize] = (float)(dfYSum/nCount); // genuinely valid points will have value iMaxIter+1 // On each iteration mark newly valid points with a // descending value so that it will not be used on the // current iteration only on subsequent ones. pabyValidFlag[iBMX+iBMY*nBMXSize] = (GByte) (nMaxIter - iIter); } } } if (nNumValid == nBMXSize * nBMYSize) break; } #ifdef notdef GDALDatasetH hBMDS = GDALCreate( GDALGetDriverByName( "GTiff" ), "backmap.tif", nBMXSize, nBMYSize, 2, GDT_Float32, NULL ); GDALSetGeoTransform( hBMDS, psTransform->adfBackMapGeoTransform ); GDALRasterIO( GDALGetRasterBand(hBMDS,1), GF_Write, 0, 0, nBMXSize, nBMYSize, psTransform->pafBackMapX, nBMXSize, nBMYSize, GDT_Float32, 0, 0 ); GDALRasterIO( GDALGetRasterBand(hBMDS,2), GF_Write, 0, 0, nBMXSize, nBMYSize, psTransform->pafBackMapY, nBMXSize, nBMYSize, GDT_Float32, 0, 0 ); GDALClose( hBMDS ); #endif CPLFree( pabyValidFlag ); return TRUE; }
GDALDataset *WEBPDataset::Open( GDALOpenInfo * poOpenInfo ) { if( !Identify( poOpenInfo ) ) return NULL; int nWidth, nHeight; if (!WebPGetInfo((const uint8_t*)poOpenInfo->pabyHeader, (uint32_t)poOpenInfo->nHeaderBytes, &nWidth, &nHeight)) return NULL; if( poOpenInfo->eAccess == GA_Update ) { CPLError( CE_Failure, CPLE_NotSupported, "The WEBP driver does not support update access to existing" " datasets.\n" ); return NULL; } /* -------------------------------------------------------------------- */ /* Open the file using the large file api. */ /* -------------------------------------------------------------------- */ VSILFILE* fpImage = VSIFOpenL( poOpenInfo->pszFilename, "rb" ); if( fpImage == NULL ) return NULL; GByte* pabyUncompressed = (GByte*)VSIMalloc3(nWidth, nHeight, 3); if (pabyUncompressed == NULL) { VSIFCloseL(fpImage); return NULL; } /* -------------------------------------------------------------------- */ /* Create a corresponding GDALDataset. */ /* -------------------------------------------------------------------- */ WEBPDataset *poDS; poDS = new WEBPDataset(); poDS->nRasterXSize = nWidth; poDS->nRasterYSize = nHeight; poDS->fpImage = fpImage; poDS->pabyUncompressed = pabyUncompressed; /* -------------------------------------------------------------------- */ /* Create band information objects. */ /* -------------------------------------------------------------------- */ for( int iBand = 0; iBand < 3; iBand++ ) poDS->SetBand( iBand+1, new WEBPRasterBand( poDS, iBand+1 ) ); /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ poDS->SetDescription( poOpenInfo->pszFilename ); poDS->TryLoadXML( poOpenInfo->papszSiblingFiles ); /* -------------------------------------------------------------------- */ /* Open overviews. */ /* -------------------------------------------------------------------- */ poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename, poOpenInfo->papszSiblingFiles ); return poDS; }
CPLErr HF2RasterBand::IReadBlock( int nBlockXOff, int nLineYOff, void * pImage ) { HF2Dataset *poGDS = (HF2Dataset *) poDS; // NOTE: the use of nBlockXSize for the y dimensions is intended const int nXBlocks = DIV_ROUND_UP(nRasterXSize, nBlockXSize); const int nYBlocks = DIV_ROUND_UP(nRasterYSize, nBlockXSize); if (!poGDS->LoadBlockMap()) return CE_Failure; if (pafBlockData == NULL) { pafBlockData = (float*)VSIMalloc3(nXBlocks * sizeof(float), poGDS->nTileSize, poGDS->nTileSize); if (pafBlockData == NULL) return CE_Failure; } nLineYOff = nRasterYSize - 1 - nLineYOff; const int nBlockYOff = nLineYOff / nBlockXSize; const int nYOffInTile = nLineYOff % nBlockXSize; if (nBlockYOff != nLastBlockYOff) { nLastBlockYOff = nBlockYOff; memset(pafBlockData, 0, nXBlocks * sizeof(float) * nBlockXSize * nBlockXSize); /* 4 * nBlockXSize is the upper bound */ void* pabyData = CPLMalloc( 4 * nBlockXSize ); for(int nxoff = 0; nxoff < nXBlocks; nxoff++) { VSIFSeekL(poGDS->fp, poGDS->panBlockOffset[(nYBlocks - 1 - nBlockYOff) * nXBlocks + nxoff], SEEK_SET); float fScale, fOff; VSIFReadL(&fScale, 4, 1, poGDS->fp); VSIFReadL(&fOff, 4, 1, poGDS->fp); CPL_LSBPTR32(&fScale); CPL_LSBPTR32(&fOff); const int nTileWidth = MIN(nBlockXSize, nRasterXSize - nxoff * nBlockXSize); const int nTileHeight = MIN(nBlockXSize, nRasterYSize - nBlockYOff * nBlockXSize); for(int j=0;j<nTileHeight;j++) { GByte nWordSize; VSIFReadL(&nWordSize, 1, 1, poGDS->fp); if (nWordSize != 1 && nWordSize != 2 && nWordSize != 4) { CPLError(CE_Failure, CPLE_AppDefined, "Unexpected word size : %d", (int)nWordSize); break; } GInt32 nVal; VSIFReadL(&nVal, 4, 1, poGDS->fp); CPL_LSBPTR32(&nVal); if( VSIFReadL(pabyData, static_cast<size_t>(nWordSize * (nTileWidth - 1)), 1, poGDS->fp) != 1 ) { CPLError(CE_Failure, CPLE_FileIO, "File too short"); CPLFree(pabyData); return CE_Failure; } #if defined(CPL_MSB) if (nWordSize > 1) GDALSwapWords(pabyData, nWordSize, nTileWidth - 1, nWordSize); #endif double dfVal = nVal * (double)fScale + fOff; if( dfVal > std::numeric_limits<float>::max() ) dfVal = std::numeric_limits<float>::max(); else if( dfVal < std::numeric_limits<float>::min() ) dfVal = std::numeric_limits<float>::min(); pafBlockData[nxoff * nBlockXSize * nBlockXSize + j * nBlockXSize + 0] = static_cast<float>(dfVal); for(int i=1;i<nTileWidth;i++) { int nInc; if (nWordSize == 1) nInc = ((signed char*)pabyData)[i-1]; else if (nWordSize == 2) nInc = ((GInt16*)pabyData)[i-1]; else nInc = ((GInt32*)pabyData)[i-1]; if( (nInc >= 0 && nVal > INT_MAX - nInc) || (nInc == INT_MIN && nVal < 0) || (nInc < 0 && nVal < INT_MIN - nInc ) ) { CPLError(CE_Failure, CPLE_FileIO, "int32 overflow"); CPLFree(pabyData); return CE_Failure; } nVal += nInc; dfVal = nVal * (double)fScale + fOff; if( dfVal > std::numeric_limits<float>::max() ) dfVal = std::numeric_limits<float>::max(); else if( dfVal < std::numeric_limits<float>::min() ) dfVal = std::numeric_limits<float>::min(); pafBlockData[nxoff * nBlockXSize * nBlockXSize + j * nBlockXSize + i] = static_cast<float>(dfVal); } } } CPLFree(pabyData); } const int nTileWidth = MIN(nBlockXSize, nRasterXSize - nBlockXOff * nBlockXSize); memcpy(pImage, pafBlockData + nBlockXOff * nBlockXSize * nBlockXSize + nYOffInTile * nBlockXSize, nTileWidth * sizeof(float)); return CE_None; }
CPLErr GeoRasterRasterBand::SetDefaultRAT( const GDALRasterAttributeTable *poRAT ) { GeoRasterDataset* poGDS = (GeoRasterDataset*) poDS; if( ! poRAT ) { return CE_Failure; } if( poDefaultRAT ) { delete poDefaultRAT; } poDefaultRAT = poRAT->Clone(); // ---------------------------------------------------------- // Check if RAT is just colortable and/or histogram // ---------------------------------------------------------- CPLString sColName = ""; int iCol = 0; int nColCount = poRAT->GetColumnCount(); for( iCol = 0; iCol < poRAT->GetColumnCount(); iCol++ ) { sColName = poRAT->GetNameOfCol( iCol ); if( EQUAL( sColName, "histogram" ) || EQUAL( sColName, "red" ) || EQUAL( sColName, "green" ) || EQUAL( sColName, "blue" ) || EQUAL( sColName, "opacity" ) ) { nColCount--; } } if( nColCount < 2 ) { return CE_None; } // ---------------------------------------------------------- // Format Table description // ---------------------------------------------------------- char szName[OWTEXT]; char szDescription[OWTEXT]; strcpy( szDescription, "( ID NUMBER" ); for( iCol = 0; iCol < poRAT->GetColumnCount(); iCol++ ) { strcpy( szName, poRAT->GetNameOfCol( iCol ) ); strcpy( szDescription, CPLSPrintf( "%s, %s", szDescription, szName ) ); if( poRAT->GetTypeOfCol( iCol ) == GFT_Integer ) { strcpy( szDescription, CPLSPrintf( "%s NUMBER", szDescription ) ); } if( poRAT->GetTypeOfCol( iCol ) == GFT_Real ) { strcpy( szDescription, CPLSPrintf( "%s FLOAT", szDescription ) ); } if( poRAT->GetTypeOfCol( iCol ) == GFT_String ) { strcpy( szDescription, CPLSPrintf( "%s VARCHAR2(%d)", szDescription, MAXLEN_VATSTR) ); } } strcpy( szDescription, CPLSPrintf( "%s )", szDescription ) ); // ---------------------------------------------------------- // Create VAT named based on RDT and RID and Layer (nBand) // ---------------------------------------------------------- if( ! pszVATName ) { pszVATName = CPLStrdup( CPLSPrintf( "RAT_%s_%d_%d", poGeoRaster->sDataTable.c_str(), poGeoRaster->nRasterId, nBand ) ); } // ---------------------------------------------------------- // Create VAT table // ---------------------------------------------------------- OWStatement* poStmt = poGeoRaster->poConnection->CreateStatement( CPLSPrintf( "DECLARE\n" " TAB VARCHAR2(68) := UPPER(:1);\n" " CNT NUMBER := 0;\n" "BEGIN\n" " EXECUTE IMMEDIATE 'SELECT COUNT(*) FROM USER_TABLES\n" " WHERE TABLE_NAME = :1' INTO CNT USING TAB;\n" "\n" " IF NOT CNT = 0 THEN\n" " EXECUTE IMMEDIATE 'DROP TABLE '||TAB||' PURGE';\n" " END IF;\n" "\n" " EXECUTE IMMEDIATE 'CREATE TABLE '||TAB||' %s';\n" "END;", szDescription ) ); poStmt->Bind( pszVATName ); if( ! poStmt->Execute() ) { delete poStmt; CPLError( CE_Failure, CPLE_AppDefined, "Create VAT Table Error!" ); return CE_Failure; } delete poStmt; // ---------------------------------------------------------- // Insert Data to VAT // ---------------------------------------------------------- int iEntry = 0; int nEntryCount = poRAT->GetRowCount(); int nColunsCount = poRAT->GetColumnCount(); int nVATStrSize = MAXLEN_VATSTR * poGeoRaster->poConnection->GetCharSize(); // --------------------------- // Allocate array of buffers // --------------------------- void** papWriteFields = (void**) VSIMalloc2(sizeof(void*), nColunsCount + 1); papWriteFields[0] = (void*) VSIMalloc3(sizeof(int), sizeof(int), nEntryCount ); // ID field for(iCol = 0; iCol < nColunsCount; iCol++) { if( poRAT->GetTypeOfCol( iCol ) == GFT_String ) { papWriteFields[iCol + 1] = (void*) VSIMalloc3(sizeof(char), nVATStrSize, nEntryCount ); } if( poRAT->GetTypeOfCol( iCol ) == GFT_Integer ) { papWriteFields[iCol + 1] = (void*) VSIMalloc3(sizeof(int), sizeof(int), nEntryCount ); } if( poRAT->GetTypeOfCol( iCol ) == GFT_Real ) { papWriteFields[iCol + 1] = (void*) VSIMalloc3(sizeof(double), sizeof(double), nEntryCount ); } } // --------------------------- // Load data to buffers // --------------------------- for( iEntry = 0; iEntry < nEntryCount; iEntry++ ) { ((int *)(papWriteFields[0]))[iEntry] = iEntry; // ID field for(iCol = 0; iCol < nColunsCount; iCol++) { if( poRAT->GetTypeOfCol( iCol ) == GFT_String ) { int nOffset = iEntry * nVATStrSize; char* pszTarget = ((char*)papWriteFields[iCol + 1]) + nOffset; const char *pszStrValue = poRAT->GetValueAsString(iEntry, iCol); int nLen = strlen( pszStrValue ); nLen = nLen > ( nVATStrSize - 1 ) ? nVATStrSize : ( nVATStrSize - 1 ); strncpy( pszTarget, pszStrValue, nLen ); pszTarget[nLen] = '\0'; } if( poRAT->GetTypeOfCol( iCol ) == GFT_Integer ) { ((int *)(papWriteFields[iCol + 1]))[iEntry] = poRAT->GetValueAsInt(iEntry, iCol); } if( poRAT->GetTypeOfCol( iCol ) == GFT_Real ) { ((double *)(papWriteFields[iCol]))[iEntry + 1] = poRAT->GetValueAsDouble(iEntry, iCol); } } } // --------------------------- // Prepare insert statement // --------------------------- CPLString osInsert = CPLSPrintf( "INSERT INTO %s VALUES (", pszVATName ); for( iCol = 0; iCol < ( nColunsCount + 1); iCol++ ) { if( iCol > 0 ) { osInsert.append(", "); } osInsert.append( CPLSPrintf(":%d", iCol + 1) ); } osInsert.append(")"); poStmt = poGeoRaster->poConnection->CreateStatement( osInsert.c_str() ); // --------------------------- // Bind buffers to columns // --------------------------- poStmt->Bind((int*) papWriteFields[0]); // ID field for(iCol = 0; iCol < nColunsCount; iCol++) { if( poRAT->GetTypeOfCol( iCol ) == GFT_String ) { poStmt->Bind( (char*) papWriteFields[iCol + 1], nVATStrSize ); } if( poRAT->GetTypeOfCol( iCol ) == GFT_Integer ) { poStmt->Bind( (int*) papWriteFields[iCol + 1]); } if( poRAT->GetTypeOfCol( iCol ) == GFT_Real ) { poStmt->Bind( (double*) papWriteFields[iCol + 1]); } } if( poStmt->Execute( iEntry ) ) { poGDS->poGeoRaster->SetVAT( nBand, pszVATName ); } else { CPLError( CE_Failure, CPLE_AppDefined, "Insert VAT Error!" ); } // --------------------------- // Clean up // --------------------------- for(iCol = 0; iCol < ( nColunsCount + 1); iCol++) { CPLFree( papWriteFields[iCol] ); } CPLFree( papWriteFields ); delete poStmt; return CE_None; }
static CPLErr GDALMultiFilter( GDALRasterBandH hTargetBand, GDALRasterBandH hTargetMaskBand, GDALRasterBandH hFiltMaskBand, int nIterations, GDALProgressFunc pfnProgress, void * pProgressArg ) { float *paf3PassLineBuf; GByte *pabyTMaskBuf; GByte *pabyFMaskBuf; float *pafThisPass, *pafLastPass, *pafSLastPass; int nBufLines = nIterations + 2; int iPassCounter = 0; int nNewLine; // the line being loaded this time (zero based scanline) int nXSize = GDALGetRasterBandXSize( hTargetBand ); int nYSize = GDALGetRasterBandYSize( hTargetBand ); CPLErr eErr = CE_None; /* -------------------------------------------------------------------- */ /* Report starting progress value. */ /* -------------------------------------------------------------------- */ if( !pfnProgress( 0.0, "Smoothing Filter...", pProgressArg ) ) { CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated" ); return CE_Failure; } /* -------------------------------------------------------------------- */ /* Allocate rotating buffers. */ /* -------------------------------------------------------------------- */ pabyTMaskBuf = (GByte *) VSIMalloc2(nXSize, nBufLines); pabyFMaskBuf = (GByte *) VSIMalloc2(nXSize, nBufLines); paf3PassLineBuf = (float *) VSIMalloc3(nXSize, nBufLines, 3 * sizeof(float)); if (pabyTMaskBuf == NULL || pabyFMaskBuf == NULL || paf3PassLineBuf == NULL) { CPLError(CE_Failure, CPLE_OutOfMemory, "Could not allocate enough memory for temporary buffers"); eErr = CE_Failure; goto end; } /* -------------------------------------------------------------------- */ /* Process rotating buffers. */ /* -------------------------------------------------------------------- */ for( nNewLine = 0; eErr == CE_None && nNewLine < nYSize+nIterations; nNewLine++ ) { /* -------------------------------------------------------------------- */ /* Rotate pass buffers. */ /* -------------------------------------------------------------------- */ iPassCounter = (iPassCounter + 1) % 3; pafSLastPass = paf3PassLineBuf + ((iPassCounter+0)%3) * nXSize*nBufLines; pafLastPass = paf3PassLineBuf + ((iPassCounter+1)%3) * nXSize*nBufLines; pafThisPass = paf3PassLineBuf + ((iPassCounter+2)%3) * nXSize*nBufLines; /* -------------------------------------------------------------------- */ /* Where does the new line go in the rotating buffer? */ /* -------------------------------------------------------------------- */ int iBufOffset = nNewLine % nBufLines; /* -------------------------------------------------------------------- */ /* Read the new data line if it is't off the bottom of the */ /* image. */ /* -------------------------------------------------------------------- */ if( nNewLine < nYSize ) { eErr = GDALRasterIO( hTargetMaskBand, GF_Read, 0, nNewLine, nXSize, 1, pabyTMaskBuf + nXSize * iBufOffset, nXSize, 1, GDT_Byte, 0, 0 ); if( eErr != CE_None ) break; eErr = GDALRasterIO( hFiltMaskBand, GF_Read, 0, nNewLine, nXSize, 1, pabyFMaskBuf + nXSize * iBufOffset, nXSize, 1, GDT_Byte, 0, 0 ); if( eErr != CE_None ) break; eErr = GDALRasterIO( hTargetBand, GF_Read, 0, nNewLine, nXSize, 1, pafThisPass + nXSize * iBufOffset, nXSize, 1, GDT_Float32, 0, 0 ); if( eErr != CE_None ) break; } /* -------------------------------------------------------------------- */ /* Loop over the loaded data, applying the filter to all loaded */ /* lines with neighbours. */ /* -------------------------------------------------------------------- */ int iFLine; for( iFLine = nNewLine-1; eErr == CE_None && iFLine >= nNewLine-nIterations; iFLine-- ) { int iLastOffset, iThisOffset, iNextOffset; iLastOffset = (iFLine-1) % nBufLines; iThisOffset = (iFLine ) % nBufLines; iNextOffset = (iFLine+1) % nBufLines; // default to preserving the old value. if( iFLine >= 0 ) memcpy( pafThisPass + iThisOffset * nXSize, pafLastPass + iThisOffset * nXSize, sizeof(float) * nXSize ); // currently this skips the first and last line. Eventually // we will enable these too. TODO if( iFLine < 1 || iFLine >= nYSize-1 ) { continue; } GDALFilterLine( pafSLastPass + iLastOffset * nXSize, pafLastPass + iThisOffset * nXSize, pafThisPass + iNextOffset * nXSize, pafThisPass + iThisOffset * nXSize, pabyTMaskBuf + iLastOffset * nXSize, pabyTMaskBuf + iThisOffset * nXSize, pabyTMaskBuf + iNextOffset * nXSize, pabyFMaskBuf + iThisOffset * nXSize, nXSize ); } /* -------------------------------------------------------------------- */ /* Write out the top data line that will be rolling out of our */ /* buffer. */ /* -------------------------------------------------------------------- */ int iLineToSave = nNewLine - nIterations; if( iLineToSave >= 0 && eErr == CE_None ) { iBufOffset = iLineToSave % nBufLines; eErr = GDALRasterIO( hTargetBand, GF_Write, 0, iLineToSave, nXSize, 1, pafThisPass + nXSize * iBufOffset, nXSize, 1, GDT_Float32, 0, 0 ); } /* -------------------------------------------------------------------- */ /* Report progress. */ /* -------------------------------------------------------------------- */ if( eErr == CE_None && !pfnProgress( (nNewLine+1) / (double) (nYSize+nIterations), "Smoothing Filter...", pProgressArg ) ) { CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated" ); eErr = CE_Failure; } } /* -------------------------------------------------------------------- */ /* Cleanup */ /* -------------------------------------------------------------------- */ end: CPLFree( pabyTMaskBuf ); CPLFree( pabyFMaskBuf ); CPLFree( paf3PassLineBuf ); return eErr; }
CPLErr RasterliteDataset::CreateOverviewLevel(const char * pszResampling, int nOvrFactor, char** papszOptions, GDALProgressFunc pfnProgress, void * pProgressData) { double dfXResolution = padfXResolutions[0] * nOvrFactor; double dfYResolution = padfXResolutions[0] * nOvrFactor; CPLString osSQL; int nOvrXSize = nRasterXSize / nOvrFactor; int nOvrYSize = nRasterYSize / nOvrFactor; if (nOvrXSize == 0 || nOvrYSize == 0) return CE_Failure; int bTiled = CSLTestBoolean(CSLFetchNameValueDef(papszOptions, "TILED", "YES")); int nBlockXSize, nBlockYSize; if (bTiled) { nBlockXSize = atoi(CSLFetchNameValueDef(papszOptions, "BLOCKXSIZE", "256")); nBlockYSize = atoi(CSLFetchNameValueDef(papszOptions, "BLOCKYSIZE", "256")); if (nBlockXSize < 64) nBlockXSize = 64; else if (nBlockXSize > 4096) nBlockXSize = 4096; if (nBlockYSize < 64) nBlockYSize = 64; else if (nBlockYSize > 4096) nBlockYSize = 4096; } else { nBlockXSize = nOvrXSize; nBlockYSize = nOvrYSize; } int nXBlocks = (nOvrXSize + nBlockXSize - 1) / nBlockXSize; int nYBlocks = (nOvrYSize + nBlockYSize - 1) / nBlockYSize; const char* pszDriverName = CSLFetchNameValueDef(papszOptions, "DRIVER", "GTiff"); if (EQUAL(pszDriverName, "MEM") || EQUAL(pszDriverName, "VRT")) { CPLError(CE_Failure, CPLE_AppDefined, "GDAL %s driver cannot be used as underlying driver", pszDriverName); return CE_Failure; } GDALDriverH hTileDriver = GDALGetDriverByName(pszDriverName); if (hTileDriver == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot load GDAL %s driver", pszDriverName); return CE_Failure; } GDALDriverH hMemDriver = GDALGetDriverByName("MEM"); if (hMemDriver == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot load GDAL MEM driver"); return CE_Failure; } GDALDataType eDataType = GetRasterBand(1)->GetRasterDataType(); int nDataTypeSize = GDALGetDataTypeSize(eDataType) / 8; GByte* pabyMEMDSBuffer = (GByte*)VSIMalloc3(nBlockXSize, nBlockYSize, nBands * nDataTypeSize); if (pabyMEMDSBuffer == NULL) { return CE_Failure; } CPLString osTempFileName; osTempFileName.Printf("/vsimem/%p", hDS); int nTileId = 0; int nBlocks = 0; int nTotalBlocks = nXBlocks * nYBlocks; CPLString osRasterLayer; osRasterLayer.Printf("%s_rasters", osTableName.c_str()); CPLString osMetatadataLayer; osMetatadataLayer.Printf("%s_metadata", osTableName.c_str()); OGRLayerH hRasterLayer = OGR_DS_GetLayerByName(hDS, osRasterLayer.c_str()); OGRLayerH hMetadataLayer = OGR_DS_GetLayerByName(hDS, osMetatadataLayer.c_str()); CPLString osSourceName = "unknown"; osSQL.Printf("SELECT source_name FROM \"%s\" WHERE " "%s LIMIT 1", osMetatadataLayer.c_str(), RasterliteGetPixelSizeCond(padfXResolutions[0], padfYResolutions[0]).c_str()); OGRLayerH hSQLLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL); if (hSQLLyr) { OGRFeatureH hFeat = OGR_L_GetNextFeature(hSQLLyr); if (hFeat) { const char* pszVal = OGR_F_GetFieldAsString(hFeat, 0); if (pszVal) osSourceName = pszVal; OGR_F_Destroy(hFeat); } OGR_DS_ReleaseResultSet(hDS, hSQLLyr); } /* -------------------------------------------------------------------- */ /* Compute up to which existing overview level we can use for */ /* computing the requested overview */ /* -------------------------------------------------------------------- */ int iLev; nLimitOvrCount = 0; for(iLev=1;iLev<nResolutions;iLev++) { if (!(padfXResolutions[iLev] < dfXResolution - 1e-10 && padfYResolutions[iLev] < dfYResolution - 1e-10)) { break; } nLimitOvrCount++; } /* -------------------------------------------------------------------- */ /* Allocate buffer for tile of previous overview level */ /* -------------------------------------------------------------------- */ GDALDataset* poPrevOvrLevel = (papoOverviews != NULL && iLev >= 2 && iLev <= nResolutions && papoOverviews[iLev-2]) ? papoOverviews[iLev-2] : this; double dfRatioPrevOvr = poPrevOvrLevel->GetRasterBand(1)->GetXSize() / nOvrXSize; int nPrevOvrBlockXSize = (int)(nBlockXSize * dfRatioPrevOvr + 0.5); int nPrevOvrBlockYSize = (int)(nBlockYSize * dfRatioPrevOvr + 0.5); GByte* pabyPrevOvrMEMDSBuffer = NULL; if( !EQUALN(pszResampling, "NEAR", 4)) { pabyPrevOvrMEMDSBuffer = (GByte*)VSIMalloc3(nPrevOvrBlockXSize, nPrevOvrBlockYSize, nBands * nDataTypeSize); if (pabyPrevOvrMEMDSBuffer == NULL) { VSIFree(pabyMEMDSBuffer); return CE_Failure; } } /* -------------------------------------------------------------------- */ /* Iterate over blocks to add data into raster and metadata tables */ /* -------------------------------------------------------------------- */ char** papszTileDriverOptions = RasterliteGetTileDriverOptions(papszOptions); OGR_DS_ExecuteSQL(hDS, "BEGIN", NULL, NULL); CPLErr eErr = CE_None; int nBlockXOff, nBlockYOff; for(nBlockYOff=0;eErr == CE_None && nBlockYOff<nYBlocks;nBlockYOff++) { for(nBlockXOff=0;eErr == CE_None && nBlockXOff<nXBlocks;nBlockXOff++) { GDALDatasetH hPrevOvrMemDS = NULL; /* -------------------------------------------------------------------- */ /* Create in-memory tile */ /* -------------------------------------------------------------------- */ int nReqXSize = nBlockXSize, nReqYSize = nBlockYSize; if ((nBlockXOff+1) * nBlockXSize > nOvrXSize) nReqXSize = nOvrXSize - nBlockXOff * nBlockXSize; if ((nBlockYOff+1) * nBlockYSize > nOvrYSize) nReqYSize = nOvrYSize - nBlockYOff * nBlockYSize; if( pabyPrevOvrMEMDSBuffer != NULL ) { int nPrevOvrReqXSize = (int)(nReqXSize * dfRatioPrevOvr + 0.5); int nPrevOvrReqYSize = (int)(nReqYSize * dfRatioPrevOvr + 0.5); eErr = RasterIO(GF_Read, nBlockXOff * nBlockXSize * nOvrFactor, nBlockYOff * nBlockYSize * nOvrFactor, nReqXSize * nOvrFactor, nReqYSize * nOvrFactor, pabyPrevOvrMEMDSBuffer, nPrevOvrReqXSize, nPrevOvrReqYSize, eDataType, nBands, NULL, 0, 0, 0, NULL); if (eErr != CE_None) { break; } hPrevOvrMemDS = GDALCreate(hMemDriver, "MEM:::", nPrevOvrReqXSize, nPrevOvrReqYSize, 0, eDataType, NULL); if (hPrevOvrMemDS == NULL) { eErr = CE_Failure; break; } int iBand; for(iBand = 0; iBand < nBands; iBand ++) { char** papszOptions = NULL; char szTmp[64]; memset(szTmp, 0, sizeof(szTmp)); CPLPrintPointer(szTmp, pabyPrevOvrMEMDSBuffer + iBand * nDataTypeSize * nPrevOvrReqXSize * nPrevOvrReqYSize, sizeof(szTmp)); papszOptions = CSLSetNameValue(papszOptions, "DATAPOINTER", szTmp); GDALAddBand(hPrevOvrMemDS, eDataType, papszOptions); CSLDestroy(papszOptions); } } else { eErr = RasterIO(GF_Read, nBlockXOff * nBlockXSize * nOvrFactor, nBlockYOff * nBlockYSize * nOvrFactor, nReqXSize * nOvrFactor, nReqYSize * nOvrFactor, pabyMEMDSBuffer, nReqXSize, nReqYSize, eDataType, nBands, NULL, 0, 0, 0, NULL); if (eErr != CE_None) { break; } } GDALDatasetH hMemDS = GDALCreate(hMemDriver, "MEM:::", nReqXSize, nReqYSize, 0, eDataType, NULL); if (hMemDS == NULL) { eErr = CE_Failure; break; } int iBand; for(iBand = 0; iBand < nBands; iBand ++) { char** papszOptions = NULL; char szTmp[64]; memset(szTmp, 0, sizeof(szTmp)); CPLPrintPointer(szTmp, pabyMEMDSBuffer + iBand * nDataTypeSize * nReqXSize * nReqYSize, sizeof(szTmp)); papszOptions = CSLSetNameValue(papszOptions, "DATAPOINTER", szTmp); GDALAddBand(hMemDS, eDataType, papszOptions); CSLDestroy(papszOptions); } if( hPrevOvrMemDS != NULL ) { for(iBand = 0; iBand < nBands; iBand ++) { GDALRasterBandH hDstOvrBand = GDALGetRasterBand(hMemDS, iBand+1); eErr = GDALRegenerateOverviews( GDALGetRasterBand(hPrevOvrMemDS, iBand+1), 1, &hDstOvrBand, pszResampling, NULL, NULL ); if( eErr != CE_None ) break; } GDALClose(hPrevOvrMemDS); } GDALDatasetH hOutDS = GDALCreateCopy(hTileDriver, osTempFileName.c_str(), hMemDS, FALSE, papszTileDriverOptions, NULL, NULL); GDALClose(hMemDS); if (hOutDS) GDALClose(hOutDS); else { eErr = CE_Failure; break; } /* -------------------------------------------------------------------- */ /* Insert new entry into raster table */ /* -------------------------------------------------------------------- */ vsi_l_offset nDataLength; GByte *pabyData = VSIGetMemFileBuffer( osTempFileName.c_str(), &nDataLength, FALSE); OGRFeatureH hFeat = OGR_F_Create( OGR_L_GetLayerDefn(hRasterLayer) ); OGR_F_SetFieldBinary(hFeat, 0, (int)nDataLength, pabyData); OGR_L_CreateFeature(hRasterLayer, hFeat); /* Query raster ID to set it as the ID of the associated metadata */ int nRasterID = (int)OGR_F_GetFID(hFeat); OGR_F_Destroy(hFeat); VSIUnlink(osTempFileName.c_str()); /* -------------------------------------------------------------------- */ /* Insert new entry into metadata table */ /* -------------------------------------------------------------------- */ hFeat = OGR_F_Create( OGR_L_GetLayerDefn(hMetadataLayer) ); OGR_F_SetFID(hFeat, nRasterID); OGR_F_SetFieldString(hFeat, 0, osSourceName); OGR_F_SetFieldInteger(hFeat, 1, nTileId ++); OGR_F_SetFieldInteger(hFeat, 2, nReqXSize); OGR_F_SetFieldInteger(hFeat, 3, nReqYSize); OGR_F_SetFieldDouble(hFeat, 4, dfXResolution); OGR_F_SetFieldDouble(hFeat, 5, dfYResolution); double minx, maxx, maxy, miny; minx = adfGeoTransform[0] + (nBlockXSize * nBlockXOff) * dfXResolution; maxx = adfGeoTransform[0] + (nBlockXSize * nBlockXOff + nReqXSize) * dfXResolution; maxy = adfGeoTransform[3] + (nBlockYSize * nBlockYOff) * (-dfYResolution); miny = adfGeoTransform[3] + (nBlockYSize * nBlockYOff + nReqYSize) * (-dfYResolution); OGRGeometryH hRectangle = OGR_G_CreateGeometry(wkbPolygon); OGRGeometryH hLinearRing = OGR_G_CreateGeometry(wkbLinearRing); OGR_G_AddPoint_2D(hLinearRing, minx, miny); OGR_G_AddPoint_2D(hLinearRing, minx, maxy); OGR_G_AddPoint_2D(hLinearRing, maxx, maxy); OGR_G_AddPoint_2D(hLinearRing, maxx, miny); OGR_G_AddPoint_2D(hLinearRing, minx, miny); OGR_G_AddGeometryDirectly(hRectangle, hLinearRing); OGR_F_SetGeometryDirectly(hFeat, hRectangle); OGR_L_CreateFeature(hMetadataLayer, hFeat); OGR_F_Destroy(hFeat); nBlocks++; if (pfnProgress && !pfnProgress(1.0 * nBlocks / nTotalBlocks, NULL, pProgressData)) eErr = CE_Failure; } } nLimitOvrCount = -1; if (eErr == CE_None) OGR_DS_ExecuteSQL(hDS, "COMMIT", NULL, NULL); else OGR_DS_ExecuteSQL(hDS, "ROLLBACK", NULL, NULL); VSIFree(pabyMEMDSBuffer); VSIFree(pabyPrevOvrMEMDSBuffer); CSLDestroy(papszTileDriverOptions); papszTileDriverOptions = NULL; /* -------------------------------------------------------------------- */ /* Update raster_pyramids table */ /* -------------------------------------------------------------------- */ if (eErr == CE_None) { OGRLayerH hRasterPyramidsLyr = OGR_DS_GetLayerByName(hDS, "raster_pyramids"); if (hRasterPyramidsLyr == NULL) { osSQL.Printf ("CREATE TABLE raster_pyramids (" "table_prefix TEXT NOT NULL," "pixel_x_size DOUBLE NOT NULL," "pixel_y_size DOUBLE NOT NULL," "tile_count INTEGER NOT NULL)"); OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL); /* Re-open the DB to take into account the new tables*/ OGRReleaseDataSource(hDS); hDS = RasterliteOpenSQLiteDB(osFileName.c_str(), GA_Update); hRasterPyramidsLyr = OGR_DS_GetLayerByName(hDS, "raster_pyramids"); if (hRasterPyramidsLyr == NULL) return CE_Failure; } OGRFeatureDefnH hFDefn = OGR_L_GetLayerDefn(hRasterPyramidsLyr); /* Insert base resolution into raster_pyramids if not already done */ int bHasBaseResolution = FALSE; osSQL.Printf("SELECT * FROM raster_pyramids WHERE " "table_prefix = '%s' AND %s", osTableName.c_str(), RasterliteGetPixelSizeCond(padfXResolutions[0], padfYResolutions[0]).c_str()); hSQLLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL); if (hSQLLyr) { OGRFeatureH hFeat = OGR_L_GetNextFeature(hSQLLyr); if (hFeat) { bHasBaseResolution = TRUE; OGR_F_Destroy(hFeat); } OGR_DS_ReleaseResultSet(hDS, hSQLLyr); } if (!bHasBaseResolution) { osSQL.Printf("SELECT COUNT(*) FROM \"%s\" WHERE %s", osMetatadataLayer.c_str(), RasterliteGetPixelSizeCond(padfXResolutions[0], padfYResolutions[0]).c_str()); int nBlocksMainRes = 0; hSQLLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL); if (hSQLLyr) { OGRFeatureH hFeat = OGR_L_GetNextFeature(hSQLLyr); if (hFeat) { nBlocksMainRes = OGR_F_GetFieldAsInteger(hFeat, 0); OGR_F_Destroy(hFeat); } OGR_DS_ReleaseResultSet(hDS, hSQLLyr); } OGRFeatureH hFeat = OGR_F_Create( hFDefn ); OGR_F_SetFieldString(hFeat, OGR_FD_GetFieldIndex(hFDefn, "table_prefix"), osTableName.c_str()); OGR_F_SetFieldDouble(hFeat, OGR_FD_GetFieldIndex(hFDefn, "pixel_x_size"), padfXResolutions[0]); OGR_F_SetFieldDouble(hFeat, OGR_FD_GetFieldIndex(hFDefn, "pixel_y_size"), padfYResolutions[0]); OGR_F_SetFieldInteger(hFeat, OGR_FD_GetFieldIndex(hFDefn, "tile_count"), nBlocksMainRes); OGR_L_CreateFeature(hRasterPyramidsLyr, hFeat); OGR_F_Destroy(hFeat); } OGRFeatureH hFeat = OGR_F_Create( hFDefn ); OGR_F_SetFieldString(hFeat, OGR_FD_GetFieldIndex(hFDefn, "table_prefix"), osTableName.c_str()); OGR_F_SetFieldDouble(hFeat, OGR_FD_GetFieldIndex(hFDefn, "pixel_x_size"), dfXResolution); OGR_F_SetFieldDouble(hFeat, OGR_FD_GetFieldIndex(hFDefn, "pixel_y_size"), dfYResolution); OGR_F_SetFieldInteger(hFeat, OGR_FD_GetFieldIndex(hFDefn, "tile_count"), nTotalBlocks); OGR_L_CreateFeature(hRasterPyramidsLyr, hFeat); OGR_F_Destroy(hFeat); } return eErr; }
static CPLErr ProcessLayer( OGRLayerH hSrcLayer, GDALDatasetH hDstDS, OGRGeometry *poClipSrc, GUInt32 nXSize, GUInt32 nYSize, int nBand, int& bIsXExtentSet, int& bIsYExtentSet, double& dfXMin, double& dfXMax, double& dfYMin, double& dfYMax, const char *pszBurnAttribute, const double dfIncreaseBurnValue, const double dfMultiplyBurnValue, GDALDataType eType, GDALGridAlgorithm eAlgorithm, void *pOptions, int bQuiet, GDALProgressFunc pfnProgress ) { /* -------------------------------------------------------------------- */ /* Get field index, and check. */ /* -------------------------------------------------------------------- */ int iBurnField = -1; if ( pszBurnAttribute ) { iBurnField = OGR_FD_GetFieldIndex( OGR_L_GetLayerDefn( hSrcLayer ), pszBurnAttribute ); if( iBurnField == -1 ) { printf( "Failed to find field %s on layer %s, skipping.\n", pszBurnAttribute, OGR_FD_GetName( OGR_L_GetLayerDefn( hSrcLayer ) ) ); return CE_Failure; } } /* -------------------------------------------------------------------- */ /* Collect the geometries from this layer, and build list of */ /* values to be interpolated. */ /* -------------------------------------------------------------------- */ OGRFeature *poFeat; std::vector<double> adfX, adfY, adfZ; OGR_L_ResetReading( hSrcLayer ); while( (poFeat = (OGRFeature *)OGR_L_GetNextFeature( hSrcLayer )) != NULL ) { OGRGeometry *poGeom = poFeat->GetGeometryRef(); double dfBurnValue = 0.0; if ( iBurnField >= 0 ) dfBurnValue = poFeat->GetFieldAsDouble( iBurnField ); ProcessCommonGeometry(poGeom, poClipSrc, iBurnField, dfBurnValue, dfIncreaseBurnValue, dfMultiplyBurnValue, adfX, adfY, adfZ); OGRFeature::DestroyFeature( poFeat ); } if ( adfX.size() == 0 ) { printf( "No point geometry found on layer %s, skipping.\n", OGR_FD_GetName( OGR_L_GetLayerDefn( hSrcLayer ) ) ); return CE_None; } /* -------------------------------------------------------------------- */ /* Compute grid geometry. */ /* -------------------------------------------------------------------- */ if ( !bIsXExtentSet || !bIsYExtentSet ) { OGREnvelope sEnvelope; OGR_L_GetExtent( hSrcLayer, &sEnvelope, TRUE ); if ( !bIsXExtentSet ) { dfXMin = sEnvelope.MinX; dfXMax = sEnvelope.MaxX; bIsXExtentSet = TRUE; } if ( !bIsYExtentSet ) { dfYMin = sEnvelope.MinY; dfYMax = sEnvelope.MaxY; bIsYExtentSet = TRUE; } } /* -------------------------------------------------------------------- */ /* Perform gridding. */ /* -------------------------------------------------------------------- */ const double dfDeltaX = ( dfXMax - dfXMin ) / nXSize; const double dfDeltaY = ( dfYMax - dfYMin ) / nYSize; if ( !bQuiet ) { printf( "Grid data type is \"%s\"\n", GDALGetDataTypeName(eType) ); printf( "Grid size = (%lu %lu).\n", (unsigned long)nXSize, (unsigned long)nYSize ); printf( "Corner coordinates = (%f %f)-(%f %f).\n", dfXMin - dfDeltaX / 2, dfYMax + dfDeltaY / 2, dfXMax + dfDeltaX / 2, dfYMin - dfDeltaY / 2 ); printf( "Grid cell size = (%f %f).\n", dfDeltaX, dfDeltaY ); printf( "Source point count = %lu.\n", (unsigned long)adfX.size() ); PrintAlgorithmAndOptions( eAlgorithm, pOptions ); printf("\n"); } GDALRasterBandH hBand = GDALGetRasterBand( hDstDS, nBand ); if (adfX.size() == 0) { // FIXME: Shoulda' set to nodata value instead GDALFillRaster( hBand, 0.0 , 0.0 ); return CE_None; } GUInt32 nXOffset, nYOffset; int nBlockXSize, nBlockYSize; int nDataTypeSize = GDALGetDataTypeSize(eType) / 8; // Try to grow the work buffer up to 16 MB if it is smaller GDALGetBlockSize( hBand, &nBlockXSize, &nBlockYSize ); const GUInt32 nDesiredBufferSize = 16*1024*1024; if( (GUInt32)nBlockXSize < nXSize && (GUInt32)nBlockYSize < nYSize && (GUInt32)nBlockXSize < nDesiredBufferSize / (nBlockYSize * nDataTypeSize) ) { int nNewBlockXSize = nDesiredBufferSize / (nBlockYSize * nDataTypeSize); nBlockXSize = (nNewBlockXSize / nBlockXSize) * nBlockXSize; if( (GUInt32)nBlockXSize > nXSize ) nBlockXSize = nXSize; } else if( (GUInt32)nBlockXSize == nXSize && (GUInt32)nBlockYSize < nYSize && (GUInt32)nBlockYSize < nDesiredBufferSize / (nXSize * nDataTypeSize) ) { int nNewBlockYSize = nDesiredBufferSize / (nXSize * nDataTypeSize); nBlockYSize = (nNewBlockYSize / nBlockYSize) * nBlockYSize; if( (GUInt32)nBlockYSize > nYSize ) nBlockYSize = nYSize; } CPLDebug("GDAL_GRID", "Work buffer: %d * %d", nBlockXSize, nBlockYSize); void *pData = VSIMalloc3( nBlockXSize, nBlockYSize, nDataTypeSize ); if( pData == NULL ) { CPLError(CE_Failure, CPLE_OutOfMemory, "Cannot allocate work buffer"); return CE_Failure; } GUInt32 nBlock = 0; GUInt32 nBlockCount = ((nXSize + nBlockXSize - 1) / nBlockXSize) * ((nYSize + nBlockYSize - 1) / nBlockYSize); CPLErr eErr = CE_None; for ( nYOffset = 0; nYOffset < nYSize && eErr == CE_None; nYOffset += nBlockYSize ) { for ( nXOffset = 0; nXOffset < nXSize && eErr == CE_None; nXOffset += nBlockXSize ) { void *pScaledProgress; pScaledProgress = GDALCreateScaledProgress( (double)nBlock / nBlockCount, (double)(nBlock + 1) / nBlockCount, pfnProgress, NULL ); nBlock ++; int nXRequest = nBlockXSize; if (nXOffset + nXRequest > nXSize) nXRequest = nXSize - nXOffset; int nYRequest = nBlockYSize; if (nYOffset + nYRequest > nYSize) nYRequest = nYSize - nYOffset; eErr = GDALGridCreate( eAlgorithm, pOptions, adfX.size(), &(adfX[0]), &(adfY[0]), &(adfZ[0]), dfXMin + dfDeltaX * nXOffset, dfXMin + dfDeltaX * (nXOffset + nXRequest), dfYMin + dfDeltaY * nYOffset, dfYMin + dfDeltaY * (nYOffset + nYRequest), nXRequest, nYRequest, eType, pData, GDALScaledProgress, pScaledProgress ); if( eErr == CE_None ) eErr = GDALRasterIO( hBand, GF_Write, nXOffset, nYOffset, nXRequest, nYRequest, pData, nXRequest, nYRequest, eType, 0, 0 ); GDALDestroyScaledProgress( pScaledProgress ); } } CPLFree( pData ); return eErr; }
// Copies GDAL Band to KEA Band if nOverview == -1 // Otherwise it is assumed we are writing to the specified overview static bool KEACopyRasterData( GDALRasterBand *pBand, kealib::KEAImageIO *pImageIO, int nBand, int nOverview, int nTotalBands, GDALProgressFunc pfnProgress, void *pProgressData) { // get some info kealib::KEADataType eKeaType = pImageIO->getImageBandDataType(nBand); unsigned int nBlockSize; if( nOverview == -1 ) nBlockSize = pImageIO->getImageBlockSize( nBand ); else nBlockSize = pImageIO->getOverviewBlockSize(nBand, nOverview); GDALDataType eGDALType = pBand->GetRasterDataType(); unsigned int nXSize = pBand->GetXSize(); unsigned int nYSize = pBand->GetYSize(); // allocate some space int nPixelSize = GDALGetDataTypeSize( eGDALType ) / 8; void *pData = VSIMalloc3( nPixelSize, nBlockSize, nBlockSize); if( pData == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "Unable to allocate memory" ); return false; } // for progress int nTotalBlocks = static_cast<int>(std::ceil( (double)nXSize / (double)nBlockSize ) * std::ceil( (double)nYSize / (double)nBlockSize )); int nBlocksComplete = 0; double dLastFraction = -1; // go through the image for( unsigned int nY = 0; nY < nYSize; nY += nBlockSize ) { // adjust for edge blocks unsigned int nysize = nBlockSize; unsigned int nytotalsize = nY + nBlockSize; if( nytotalsize > nYSize ) nysize -= (nytotalsize - nYSize); for( unsigned int nX = 0; nX < nXSize; nX += nBlockSize ) { // adjust for edge blocks unsigned int nxsize = nBlockSize; unsigned int nxtotalsize = nX + nBlockSize; if( nxtotalsize > nXSize ) nxsize -= (nxtotalsize - nXSize); // read in from GDAL if( pBand->RasterIO( GF_Read, nX, nY, nxsize, nysize, pData, nxsize, nysize, eGDALType, nPixelSize, nPixelSize * nBlockSize, NULL) != CE_None ) { CPLError( CE_Failure, CPLE_AppDefined, "Unable to read block at %d %d\n", nX, nY ); return false; } // write out to KEA if( nOverview == -1 ) pImageIO->writeImageBlock2Band( nBand, pData, nX, nY, nxsize, nysize, nBlockSize, nBlockSize, eKeaType); else pImageIO->writeToOverview( nBand, nOverview, pData, nX, nY, nxsize, nysize, nBlockSize, nBlockSize, eKeaType); // progress nBlocksComplete++; if( nOverview == -1 ) { double dFraction = (((double)nBlocksComplete / (double)nTotalBlocks) / (double)nTotalBands) + ((double)(nBand-1) * (1.0 / (double)nTotalBands)); if( dFraction != dLastFraction ) { if( !pfnProgress( dFraction, NULL, pProgressData ) ) { CPLFree( pData ); return false; } dLastFraction = dFraction; } } } } CPLFree( pData ); return true; }
GDALDataset *MEMDataset::Create( const char * pszFilename, int nXSize, int nYSize, int nBands, GDALDataType eType, char **papszOptions ) { /* -------------------------------------------------------------------- */ /* Do we want a pixel interleaved buffer? I mostly care about */ /* this to test pixel interleaved io in other contexts, but it */ /* could be useful to create a directly accessable buffer for */ /* some apps. */ /* -------------------------------------------------------------------- */ int bPixelInterleaved = FALSE; const char *pszOption = CSLFetchNameValue( papszOptions, "INTERLEAVE" ); if( pszOption && EQUAL(pszOption,"PIXEL") ) bPixelInterleaved = TRUE; /* -------------------------------------------------------------------- */ /* First allocate band data, verifying that we can get enough */ /* memory. */ /* -------------------------------------------------------------------- */ std::vector<GByte*> apbyBandData; int iBand; int nWordSize = GDALGetDataTypeSize(eType) / 8; int bAllocOK = TRUE; if( bPixelInterleaved ) { apbyBandData.push_back( (GByte *) VSIMalloc3( nWordSize * nBands, nXSize, nYSize ) ); if( apbyBandData[0] == NULL ) bAllocOK = FALSE; else { memset(apbyBandData[0], 0, ((size_t)nWordSize) * nBands * nXSize * nYSize); for( iBand = 1; iBand < nBands; iBand++ ) apbyBandData.push_back( apbyBandData[0] + iBand * nWordSize ); } } else { for( iBand = 0; iBand < nBands; iBand++ ) { apbyBandData.push_back( (GByte *) VSIMalloc3( nWordSize, nXSize, nYSize ) ); if( apbyBandData[iBand] == NULL ) { bAllocOK = FALSE; break; } memset(apbyBandData[iBand], 0, ((size_t)nWordSize) * nXSize * nYSize); } } if( !bAllocOK ) { for( iBand = 0; iBand < (int) apbyBandData.size(); iBand++ ) { if( apbyBandData[iBand] ) VSIFree( apbyBandData[iBand] ); } CPLError( CE_Failure, CPLE_OutOfMemory, "Unable to create band arrays ... out of memory." ); return NULL; } /* -------------------------------------------------------------------- */ /* Create the new GTiffDataset object. */ /* -------------------------------------------------------------------- */ MEMDataset *poDS; poDS = new MEMDataset(); poDS->nRasterXSize = nXSize; poDS->nRasterYSize = nYSize; poDS->eAccess = GA_Update; if( bPixelInterleaved ) poDS->SetMetadataItem( "INTERLEAVE", "PIXEL", "IMAGE_STRUCTURE" ); /* -------------------------------------------------------------------- */ /* Create band information objects. */ /* -------------------------------------------------------------------- */ for( iBand = 0; iBand < nBands; iBand++ ) { MEMRasterBand *poNewBand; if( bPixelInterleaved ) poNewBand = new MEMRasterBand( poDS, iBand+1, apbyBandData[iBand], eType, nWordSize * nBands, 0, iBand == 0 ); else poNewBand = new MEMRasterBand( poDS, iBand+1, apbyBandData[iBand], eType, 0, 0, TRUE ); poDS->SetBand( iBand+1, poNewBand ); } /* -------------------------------------------------------------------- */ /* Try to return a regular handle on the file. */ /* -------------------------------------------------------------------- */ return poDS; }
CPLErr GDALNoDataValuesMaskBand::IReadBlock( int nXBlockOff, int nYBlockOff, void * pImage ) { int iBand; GDALDataType eWrkDT; /* -------------------------------------------------------------------- */ /* Decide on a working type. */ /* -------------------------------------------------------------------- */ switch( poDS->GetRasterBand(1)->GetRasterDataType() ) { case GDT_Byte: eWrkDT = GDT_Byte; break; case GDT_UInt16: case GDT_UInt32: eWrkDT = GDT_UInt32; break; case GDT_Int16: case GDT_Int32: case GDT_CInt16: case GDT_CInt32: eWrkDT = GDT_Int32; break; case GDT_Float32: case GDT_CFloat32: eWrkDT = GDT_Float32; break; case GDT_Float64: case GDT_CFloat64: eWrkDT = GDT_Float64; break; default: CPLAssert( FALSE ); eWrkDT = GDT_Float64; break; } /* -------------------------------------------------------------------- */ /* Read the image data. */ /* -------------------------------------------------------------------- */ GByte *pabySrc; CPLErr eErr; int nBands = poDS->GetRasterCount(); pabySrc = (GByte *) VSIMalloc3( nBands * GDALGetDataTypeSize(eWrkDT)/8, nBlockXSize, nBlockYSize ); if (pabySrc == NULL) { CPLError( CE_Failure, CPLE_OutOfMemory, "GDALNoDataValuesMaskBand::IReadBlock: Out of memory for buffer." ); return CE_Failure; } int nXSizeRequest = nBlockXSize; if (nXBlockOff * nBlockXSize + nBlockXSize > nRasterXSize) nXSizeRequest = nRasterXSize - nXBlockOff * nBlockXSize; int nYSizeRequest = nBlockYSize; if (nYBlockOff * nBlockYSize + nBlockYSize > nRasterYSize) nYSizeRequest = nRasterYSize - nYBlockOff * nBlockYSize; if (nXSizeRequest != nBlockXSize || nYSizeRequest != nBlockYSize) { /* memset the whole buffer to avoid Valgrind warnings in case we can't */ /* fetch a full block */ memset(pabySrc, 0, nBands * GDALGetDataTypeSize(eWrkDT)/8 * nBlockXSize * nBlockYSize ); } int nBlockOffsetPixels = nBlockXSize * nBlockYSize; int nBandOffsetByte = (GDALGetDataTypeSize(eWrkDT)/8) * nBlockXSize * nBlockYSize; for(iBand=0;iBand<nBands;iBand++) { eErr = poDS->GetRasterBand(iBand + 1)->RasterIO( GF_Read, nXBlockOff * nBlockXSize, nYBlockOff * nBlockYSize, nXSizeRequest, nYSizeRequest, pabySrc + iBand * nBandOffsetByte, nXSizeRequest, nYSizeRequest, eWrkDT, 0, nBlockXSize * (GDALGetDataTypeSize(eWrkDT)/8), NULL); if( eErr != CE_None ) return eErr; } /* -------------------------------------------------------------------- */ /* Process different cases. */ /* -------------------------------------------------------------------- */ int i; switch( eWrkDT ) { case GDT_Byte: { GByte* pabyNoData = (GByte*) CPLMalloc(nBands * sizeof(GByte)); for(iBand=0;iBand<nBands;iBand++) { pabyNoData[iBand] = (GByte)padfNodataValues[iBand]; } for( i = nBlockXSize * nBlockYSize - 1; i >= 0; i-- ) { int nCountNoData = 0; for(iBand=0;iBand<nBands;iBand++) { if( pabySrc[i + iBand * nBlockOffsetPixels] == pabyNoData[iBand] ) nCountNoData ++; } if (nCountNoData == nBands) ((GByte *) pImage)[i] = 0; else ((GByte *) pImage)[i] = 255; } CPLFree(pabyNoData); } break; case GDT_UInt32: { GUInt32* panNoData = (GUInt32*) CPLMalloc(nBands * sizeof(GUInt32)); for(iBand=0;iBand<nBands;iBand++) { panNoData[iBand] = (GUInt32)padfNodataValues[iBand]; } for( i = nBlockXSize * nBlockYSize - 1; i >= 0; i-- ) { int nCountNoData = 0; for(iBand=0;iBand<nBands;iBand++) { if( ((GUInt32 *)pabySrc)[i + iBand * nBlockOffsetPixels] == panNoData[iBand] ) nCountNoData ++; } if (nCountNoData == nBands) ((GByte *) pImage)[i] = 0; else ((GByte *) pImage)[i] = 255; } CPLFree(panNoData); } break; case GDT_Int32: { GInt32* panNoData = (GInt32*) CPLMalloc(nBands * sizeof(GInt32)); for(iBand=0;iBand<nBands;iBand++) { panNoData[iBand] = (GInt32)padfNodataValues[iBand]; } for( i = nBlockXSize * nBlockYSize - 1; i >= 0; i-- ) { int nCountNoData = 0; for(iBand=0;iBand<nBands;iBand++) { if( ((GInt32 *)pabySrc)[i + iBand * nBlockOffsetPixels] == panNoData[iBand] ) nCountNoData ++; } if (nCountNoData == nBands) ((GByte *) pImage)[i] = 0; else ((GByte *) pImage)[i] = 255; } CPLFree(panNoData); } break; case GDT_Float32: { float* pafNoData = (float*) CPLMalloc(nBands * sizeof(float)); for(iBand=0;iBand<nBands;iBand++) { pafNoData[iBand] = (float)padfNodataValues[iBand]; } for( i = nBlockXSize * nBlockYSize - 1; i >= 0; i-- ) { int nCountNoData = 0; for(iBand=0;iBand<nBands;iBand++) { if( ((float *)pabySrc)[i + iBand * nBlockOffsetPixels] == pafNoData[iBand] ) nCountNoData ++; } if (nCountNoData == nBands) ((GByte *) pImage)[i] = 0; else ((GByte *) pImage)[i] = 255; } CPLFree(pafNoData); } break; case GDT_Float64: { double* padfNoData = (double*) CPLMalloc(nBands * sizeof(double)); for(iBand=0;iBand<nBands;iBand++) { padfNoData[iBand] = (double)padfNodataValues[iBand]; } for( i = nBlockXSize * nBlockYSize - 1; i >= 0; i-- ) { int nCountNoData = 0; for(iBand=0;iBand<nBands;iBand++) { if( ((double *)pabySrc)[i + iBand * nBlockOffsetPixels] == padfNoData[iBand] ) nCountNoData ++; } if (nCountNoData == nBands) ((GByte *) pImage)[i] = 0; else ((GByte *) pImage)[i] = 255; } CPLFree(padfNoData); } break; default: CPLAssert( FALSE ); break; } CPLFree( pabySrc ); return CE_None; }
CPLErr EpsilonRasterBand::IReadBlock( int nBlockXOff, int nBlockYOff, void * pImage) { EpsilonDataset* poGDS = (EpsilonDataset*) poDS; //CPLDebug("EPSILON", "IReadBlock(nBand=%d,nBlockXOff=%d,nBlockYOff=%d)", // nBand, nBlockXOff, nBlockYOff); int l_nBlocksPerRow = (poGDS->nRasterXSize + nBlockXSize - 1) / nBlockXSize; int nBlock = nBlockXOff + nBlockYOff * l_nBlocksPerRow; BlockDesc* psDesc = &poGDS->pasBlocks[nBlock]; #ifdef DEBUG int l_nBlocksPerColumn = (poGDS->nRasterYSize + nBlockYSize - 1) / nBlockYSize; CPLAssert(psDesc->x == nBlockXOff * nBlockXSize); CPLAssert(psDesc->y == nBlockYOff * nBlockYSize); CPLAssert(psDesc->w == (nBlockXOff < l_nBlocksPerRow - 1) ? nBlockXSize : poGDS->nRasterXSize - psDesc->x); CPLAssert(psDesc->h == (nBlockYOff < l_nBlocksPerColumn - 1) ? nBlockYSize : poGDS->nRasterYSize - psDesc->y); #endif poGDS->Seek(psDesc->offset); if (!poGDS->GetNextBlockData()) { memset(pImage, 0, nBlockXSize * nBlockYSize); return CE_Failure; } eps_block_header hdr; if (eps_read_block_header (poGDS->pabyBlockData, poGDS->nBlockDataSize, &hdr) != EPS_OK) { CPLError(CE_Warning, CPLE_AppDefined, "cannot read block header"); memset(pImage, 0, nBlockXSize * nBlockYSize); return CE_Failure; } if (hdr.chk_flag == EPS_BAD_CRC || hdr.crc_flag == EPS_BAD_CRC) { CPLError(CE_Warning, CPLE_AppDefined, "bad CRC"); memset(pImage, 0, nBlockXSize * nBlockYSize); return CE_Failure; } int w = GET_FIELD(hdr, w); int h = GET_FIELD(hdr, h); int i; if (poGDS->nBands == 1) { unsigned char ** pTempData = (unsigned char **) CPLMalloc(h * sizeof(unsigned char*)); for(i=0;i<h;i++) pTempData[i] = ((GByte*)pImage) + i * nBlockXSize; if (w != nBlockXSize || h != nBlockYSize) memset(pImage, 0, nBlockXSize * nBlockYSize); if (eps_decode_grayscale_block (pTempData, poGDS->pabyBlockData, &hdr) != EPS_OK) { CPLFree(pTempData); memset(pImage, 0, nBlockXSize * nBlockYSize); return CE_Failure; } CPLFree(pTempData); } else { if (poGDS->pabyRGBData == NULL) { poGDS->pabyRGBData = (GByte*) VSIMalloc3(nBlockXSize, nBlockYSize, 3); if (poGDS->pabyRGBData == NULL) { memset(pImage, 0, nBlockXSize * nBlockYSize); return CE_Failure; } } if (poGDS->nBufferedBlock == nBlock) { memcpy(pImage, poGDS->pabyRGBData + (nBand - 1) * nBlockXSize * nBlockYSize, nBlockXSize * nBlockYSize); return CE_None; } unsigned char ** pTempData[3]; int iBand; for(iBand=0;iBand<3;iBand++) { pTempData[iBand] = (unsigned char **) CPLMalloc(h * sizeof(unsigned char*)); for(i=0;i<h;i++) pTempData[iBand][i] = poGDS->pabyRGBData + iBand * nBlockXSize * nBlockYSize + i * nBlockXSize; } if (w != nBlockXSize || h != nBlockYSize) memset(poGDS->pabyRGBData, 0, 3 * nBlockXSize * nBlockYSize); if (eps_decode_truecolor_block (pTempData[0], pTempData[1], pTempData[2], poGDS->pabyBlockData, &hdr) != EPS_OK) { for(iBand=0;iBand<3;iBand++) CPLFree(pTempData[iBand]); memset(pImage, 0, nBlockXSize * nBlockYSize); return CE_Failure; } for(iBand=0;iBand<3;iBand++) CPLFree(pTempData[iBand]); poGDS->nBufferedBlock = nBlock; memcpy(pImage, poGDS->pabyRGBData + (nBand - 1) * nBlockXSize * nBlockYSize, nBlockXSize * nBlockYSize); if (nBand == 1) { int iOtherBand; for(iOtherBand=2;iOtherBand<=3;iOtherBand++) { GDALRasterBlock *poBlock = poGDS->GetRasterBand(iOtherBand)-> GetLockedBlockRef(nBlockXOff,nBlockYOff, TRUE); if (poBlock == NULL) break; GByte* pabySrcBlock = (GByte *) poBlock->GetDataRef(); if( pabySrcBlock == NULL ) { poBlock->DropLock(); break; } memcpy(pabySrcBlock, poGDS->pabyRGBData + (iOtherBand - 1) * nBlockXSize * nBlockYSize, nBlockXSize * nBlockYSize); poBlock->DropLock(); } } } return CE_None; }
static GDALDataset * EpsilonDatasetCreateCopy( const char * pszFilename, GDALDataset *poSrcDS, CPL_UNUSED int bStrict, char ** papszOptions, GDALProgressFunc pfnProgress, void * pProgressData ) { int nBands = poSrcDS->GetRasterCount(); if ((nBands != 1 && nBands != 3) || (nBands > 0 && poSrcDS->GetRasterBand(1)->GetColorTable() != NULL)) { CPLError(CE_Failure, CPLE_NotSupported, "The EPSILON driver only supports 1 band (grayscale) " "or 3 band (RGB) data"); return NULL; } /* -------------------------------------------------------------------- */ /* Fetch and check creation options */ /* -------------------------------------------------------------------- */ int nBlockXSize = atoi(CSLFetchNameValueDef(papszOptions, "BLOCKXSIZE", "256")); int nBlockYSize = atoi(CSLFetchNameValueDef(papszOptions, "BLOCKYSIZE", "256")); if ((nBlockXSize != 32 && nBlockXSize != 64 && nBlockXSize != 128 && nBlockXSize != 256 && nBlockXSize != 512 && nBlockXSize != 1024) || (nBlockYSize != 32 && nBlockYSize != 64 && nBlockYSize != 128 && nBlockYSize != 256 && nBlockYSize != 512 && nBlockYSize != 1024)) { CPLError(CE_Failure, CPLE_NotSupported, "Block size must be a power of 2 between 32 et 1024"); return NULL; } const char* pszFilter = CSLFetchNameValueDef(papszOptions, "FILTER", "daub97lift"); char** papszFBID = eps_get_fb_info(EPS_FB_ID); char** papszFBIDIter = papszFBID; int bFound = FALSE; int nIndexFB = 0; while(papszFBIDIter && *papszFBIDIter && !bFound) { if (strcmp(*papszFBIDIter, pszFilter) == 0) bFound = TRUE; else nIndexFB ++; papszFBIDIter ++; } eps_free_fb_info(papszFBID); if (!bFound) { CPLError(CE_Failure, CPLE_NotSupported, "FILTER='%s' not supported", pszFilter); return NULL; } int eMode = EPS_MODE_OTLPF; const char* pszMode = CSLFetchNameValueDef(papszOptions, "MODE", "OTLPF"); if (EQUAL(pszMode, "NORMAL")) eMode = EPS_MODE_NORMAL; else if (EQUAL(pszMode, "OTLPF")) eMode = EPS_MODE_OTLPF; else { CPLError(CE_Failure, CPLE_NotSupported, "MODE='%s' not supported", pszMode); return NULL; } char** papszFBType = eps_get_fb_info(EPS_FB_TYPE); int bIsBiOrthogonal = EQUAL(papszFBType[nIndexFB], "biorthogonal"); eps_free_fb_info(papszFBType); if (eMode == EPS_MODE_OTLPF && !bIsBiOrthogonal) { CPLError(CE_Failure, CPLE_NotSupported, "MODE=OTLPF can only be used with biorthogonal filters. " "Use MODE=NORMAL instead"); return NULL; } int bRasterliteOutput = CPLTestBool(CSLFetchNameValueDef(papszOptions, "RASTERLITE_OUTPUT", "NO")); int nYRatio = EPS_Y_RT; int nCbRatio = EPS_Cb_RT; int nCrRatio = EPS_Cr_RT; int eResample; if (CPLTestBool(CSLFetchNameValueDef(papszOptions, "RGB_RESAMPLE", "YES"))) eResample = EPS_RESAMPLE_420; else eResample = EPS_RESAMPLE_444; const char* pszTarget = CSLFetchNameValueDef(papszOptions, "TARGET", "96"); double dfReductionFactor = 1 - CPLAtof(pszTarget) / 100; if (dfReductionFactor > 1) dfReductionFactor = 1; else if (dfReductionFactor < 0) dfReductionFactor = 0; /* -------------------------------------------------------------------- */ /* Open file */ /* -------------------------------------------------------------------- */ VSILFILE* fp = VSIFOpenL(pszFilename, "wb"); if (fp == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot create %s", pszFilename); return NULL; } /* -------------------------------------------------------------------- */ /* Compute number of blocks, block size, etc... */ /* -------------------------------------------------------------------- */ int nXSize = poSrcDS->GetRasterXSize(); int nYSize = poSrcDS->GetRasterYSize(); if (eMode == EPS_MODE_OTLPF) { nBlockXSize ++; nBlockYSize ++; } int nXBlocks = (nXSize + nBlockXSize - 1) / nBlockXSize; int nYBlocks = (nYSize + nBlockYSize - 1) / nBlockYSize; int nBlocks = nXBlocks * nYBlocks; int nUncompressedFileSize = nXSize * nYSize * nBands; int nUncompressedBlockSize = nUncompressedFileSize / nBlocks; int nTargetBlockSize = (int) (dfReductionFactor * nUncompressedBlockSize); if (nBands == 1) nTargetBlockSize = MAX (nTargetBlockSize, EPS_MIN_GRAYSCALE_BUF + 1); else nTargetBlockSize = MAX (nTargetBlockSize, EPS_MIN_TRUECOLOR_BUF + 1); /* -------------------------------------------------------------------- */ /* Allocate work buffers */ /* -------------------------------------------------------------------- */ GByte* pabyBuffer = (GByte*)VSIMalloc3(nBlockXSize, nBlockYSize, nBands); if (pabyBuffer == NULL) { VSIFCloseL(fp); return NULL; } GByte* pabyOutBuf = (GByte*)VSIMalloc(nTargetBlockSize); if (pabyOutBuf == NULL) { VSIFree(pabyBuffer); VSIFCloseL(fp); return NULL; } GByte** apapbyRawBuffer[3]; int i, j; for(i=0;i<nBands;i++) { apapbyRawBuffer[i] = (GByte**) VSIMalloc(sizeof(GByte*) * nBlockYSize); for(j=0;j<nBlockYSize;j++) { apapbyRawBuffer[i][j] = pabyBuffer + (i * nBlockXSize + j) * nBlockYSize; } } if (bRasterliteOutput) { const char* pszHeader = RASTERLITE_WAVELET_HEADER; VSIFWriteL(pszHeader, 1, strlen(pszHeader) + 1, fp); } /* -------------------------------------------------------------------- */ /* Iterate over blocks */ /* -------------------------------------------------------------------- */ int nBlockXOff, nBlockYOff; CPLErr eErr = CE_None; for(nBlockYOff = 0; eErr == CE_None && nBlockYOff < nYBlocks; nBlockYOff ++) { for(nBlockXOff = 0; eErr == CE_None && nBlockXOff < nXBlocks; nBlockXOff ++) { int bMustMemset = FALSE; int nReqXSize = nBlockXSize, nReqYSize = nBlockYSize; if ((nBlockXOff+1) * nBlockXSize > nXSize) { bMustMemset = TRUE; nReqXSize = nXSize - nBlockXOff * nBlockXSize; } if ((nBlockYOff+1) * nBlockYSize > nYSize) { bMustMemset = TRUE; nReqYSize = nYSize - nBlockYOff * nBlockYSize; } if (bMustMemset) memset(pabyBuffer, 0, nBands * nBlockXSize * nBlockYSize); eErr = poSrcDS->RasterIO(GF_Read, nBlockXOff * nBlockXSize, nBlockYOff * nBlockYSize, nReqXSize, nReqYSize, pabyBuffer, nReqXSize, nReqYSize, GDT_Byte, nBands, NULL, 1, nBlockXSize, nBlockXSize * nBlockYSize, NULL); int nOutBufSize = nTargetBlockSize; if (eErr == CE_None && nBands == 1) { if (EPS_OK != eps_encode_grayscale_block(apapbyRawBuffer[0], nXSize, nYSize, nReqXSize, nReqYSize, nBlockXOff * nBlockXSize, nBlockYOff * nBlockYSize, pabyOutBuf, &nOutBufSize, (char*) pszFilter, eMode)) { CPLError( CE_Failure, CPLE_AppDefined, "Error occurred when encoding block (%d, %d)", nBlockXOff, nBlockYOff); eErr = CE_Failure; } } else if (eErr == CE_None) { if (EPS_OK != eps_encode_truecolor_block( apapbyRawBuffer[0], apapbyRawBuffer[1], apapbyRawBuffer[2], nXSize, nYSize, nReqXSize, nReqYSize, nBlockXOff * nBlockXSize, nBlockYOff * nBlockYSize, eResample, pabyOutBuf, &nOutBufSize, nYRatio, nCbRatio, nCrRatio, (char*) pszFilter, eMode)) { CPLError(CE_Failure, CPLE_AppDefined, "Error occurred when encoding block (%d, %d)", nBlockXOff, nBlockYOff); eErr = CE_Failure; } } if (eErr == CE_None) { if ((int)VSIFWriteL(pabyOutBuf, 1, nOutBufSize, fp) != nOutBufSize) eErr = CE_Failure; char chEPSMarker = EPS_MARKER; VSIFWriteL(&chEPSMarker, 1, 1, fp); if (pfnProgress && !pfnProgress( 1.0 * (nBlockYOff * nXBlocks + nBlockXOff + 1) / nBlocks, NULL, pProgressData)) { eErr = CE_Failure; } } } } if (bRasterliteOutput) { const char* pszFooter = RASTERLITE_WAVELET_FOOTER; VSIFWriteL(pszFooter, 1, strlen(pszFooter) + 1, fp); } /* -------------------------------------------------------------------- */ /* Cleanup work buffers */ /* -------------------------------------------------------------------- */ for(i=0;i<nBands;i++) { VSIFree(apapbyRawBuffer[i]); } VSIFree(pabyOutBuf); VSIFree(pabyBuffer); VSIFCloseL(fp); if (eErr != CE_None) return NULL; /* -------------------------------------------------------------------- */ /* Reopen the dataset, unless asked for not (Rasterlite optim) */ /* -------------------------------------------------------------------- */ return (GDALDataset*) GDALOpen(pszFilename, GA_ReadOnly); }
/***************************************************** * \brief Write a natural block of raster band data *****************************************************/ CPLErr PostGISRasterRasterBand::IWriteBlock(int nBlockXOff, int nBlockYOff, void * pImage) { int nPixelSize = GDALGetDataTypeSize(eDataType) / 8; int nNaturalBlockXSize = 0; int nNaturalBlockYSize = 0; int nDataSize = 0; int nBandMetaDataSize = 0; PostGISRasterDataset * poRDS = (PostGISRasterDataset *)poDS; CPLDebug("PostGIS_Raster", "PostGISRasterRasterBand::IWriteBlock(): Table %s.%s (%s), Srid : %d", pszSchema, pszTable, pszColumn,poRDS->nSrid); // How much data are we going to copy? GetBlockSize(&nNaturalBlockXSize, &nNaturalBlockYSize); nDataSize = nNaturalBlockXSize * nNaturalBlockYSize * nPixelSize; // Allocating space for band metadata nBandMetaDataSize = (nPixelSize + 1); char * pszBandMetadata = (char*) VSIMalloc2(2 * nBandMetaDataSize, sizeof (char)); // Allocate memory for all bands data, if needed if (!poRDS->pBufferToInsert) { CPLDebug("PostGIS_Raster", "PostGISRasterRasterBand::IWriteBlock(); " "Allocating memory for buffer to hold insert query data (%d characters)", 2 * (nDataSize + nBandMetaDataSize) * poRDS->nBandsToCopy); poRDS->pBufferToInsert = (char *)VSIMalloc3(poRDS->nBandsToCopy, 2 * (nDataSize + nBandMetaDataSize), sizeof(char)); poRDS->nPosToCopy = 0; poRDS->nBandsCopied = 0; } CPLDebug("PostGIS_Raster", "PostGISRasterRasterBand::IWriteBlock(): Block (%d x %d), Metadata %d. We are " "copying %d bytes", nNaturalBlockXSize, nNaturalBlockYSize, nBandMetaDataSize, nDataSize+nBandMetaDataSize); /** * Copy the band data into the dataset buffer. We will raise the query * after we have the data of all bands in the buffer. * * NOTE: At this point, datatype translation between src and dst has been * performed by IRasterIO. So, we can use band datatype for both, origin * and destination buffers. **/ // GDALCopyWords(pImage, eDataType, 0, // poRDS->pBufferToInsert + poRDS->nPosToCopy, eDataType, 0, nDataSize); char cPostGISQueryWKT = TranslateDataTypeGDALtoPostGIS(&eDataType); if(cPostGISQueryWKT == '\0'){ CPLDebug("PostGIS_Raster", "PostGISRasterRasterBand::IWriteBlock(): PostGIS Datatype id : %c", cPostGISQueryWKT); return CE_Failure; } CPLDebug("PostGIS_Raster", "PostGISRasterRasterBand::IWriteBlock(): HasNoDataValue = %s, NoDataValue = %f", bNoDataValueSet? "True" : "False", dfNoDataValue); /* Testing bNoDataValueSet :: Hack */ // bNoDataValueSet = 1; // dfNoDataValue = 0; if(bNoDataValueSet) pszBandMetadata[0] = '4'; else pszBandMetadata[0] = '0'; pszBandMetadata[1] = cPostGISQueryWKT; strcpy(pszBandMetadata + 2, CPLBinaryToHex(nPixelSize,(GByte *)&dfNoDataValue)); memcpy(poRDS->pBufferToInsert + poRDS->nPosToCopy, pszBandMetadata, nBandMetaDataSize * 2); poRDS->nPosToCopy += nBandMetaDataSize * 2; memcpy(poRDS->pBufferToInsert + poRDS->nPosToCopy, CPLBinaryToHex(nDataSize,(GByte *)pImage), nDataSize * 2); poRDS->nPosToCopy += nDataSize * 2; poRDS->pBufferToInsert[poRDS->nPosToCopy] = '\0'; poRDS->nBandsCopied++; // Check if we're done, to raise the insert query if (poRDS->nBandsToCopy == poRDS->nBandsCopied) { PGresult * poResult = NULL; CPLString osCommand; /* // hack pszSchema = "public"; pszTable = "newtable"; pszColumn = "rast"; */ // Raise insert query // TODO: The table may contain more fields // FIXME: For some reason, pszSchema, pszTable and pszColumn are NULL. // I think it's related with the fact we overwrote GDALDataset::IRasterIO, // and we delegate in default implementation. Here, poDS is a simple // GDALDataset *, not a PostGISRasterDataset * // FIXME: anyway, even hardcoding schema/table/column names here, we // still have an error: // ERROR: rt_raster_from_wkb: WKB version 10091 unsupported // This is caused because we're not correctly creating the hex string // representing PostGIS Raster. Version should be 0, and number 10091 // is being read instead. We're not including headers in the hex string, // just raster data. Need to fix this. osCommand.Printf("insert into %s.%s (%s) values('010000",pszSchema, pszTable, pszColumn); osCommand += CPLSPrintf("%s",CPLBinaryToHex(2, (GByte*)&poRDS->nBandsToCopy)); osCommand += CPLSPrintf("%s",CPLBinaryToHex(8, (GByte*)&poRDS->adfGeoTransform[GEOTRSFRM_WE_RES])); osCommand += CPLSPrintf("%s",CPLBinaryToHex(8, (GByte*)&poRDS->adfGeoTransform[GEOTRSFRM_NS_RES])); osCommand += CPLSPrintf("%s",CPLBinaryToHex(8, (GByte*)&poRDS->adfGeoTransform[GEOTRSFRM_TOPLEFT_X])); osCommand += CPLSPrintf("%s",CPLBinaryToHex(8, (GByte*)&poRDS->adfGeoTransform[GEOTRSFRM_TOPLEFT_Y])); osCommand += CPLSPrintf("%s",CPLBinaryToHex(8, (GByte*)&poRDS->adfGeoTransform[GEOTRSFRM_ROTATION_PARAM1])); osCommand += CPLSPrintf("%s",CPLBinaryToHex(8, (GByte*)&poRDS->adfGeoTransform[GEOTRSFRM_ROTATION_PARAM2])); osCommand += CPLSPrintf("%s",CPLBinaryToHex(4, (GByte*)&poRDS->nSrid)); osCommand += CPLSPrintf("%s",CPLBinaryToHex(2, (GByte*)&nNaturalBlockXSize)); osCommand += CPLSPrintf("%s",CPLBinaryToHex(2, (GByte*)&nNaturalBlockYSize)); osCommand += poRDS->pBufferToInsert; osCommand += "'::raster)"; CPLDebug("PostGIS_Raster", "PostGISRasterRasterBand::IWriteBlock: Insert " "query raised: %s", osCommand.c_str()); poResult = PQexec(poRDS->poConn, osCommand.c_str()); if (poResult == NULL || PQresultStatus(poResult) != PGRES_COMMAND_OK) { CPLError(CE_Failure, CPLE_AppDefined, "Error inserting raster data in %s.%s: %s", pszSchema, pszTable, PQerrorMessage(poRDS->poConn)); if (poResult != NULL) PQclear(poResult); // rollback poResult = PQexec(poRDS->poConn, "rollback"); if (poResult == NULL || PQresultStatus(poResult) != PGRES_COMMAND_OK) { CPLError(CE_Failure, CPLE_AppDefined, "Error rolling back transaction: %s", PQerrorMessage(poRDS->poConn)); } if (poResult != NULL) PQclear(poResult); } // Release memory VSIFree(poRDS->pBufferToInsert); poRDS->pBufferToInsert = NULL; } return CE_None; }
CPLErr HF2RasterBand::IReadBlock( int nBlockXOff, int nLineYOff, void * pImage ) { HF2Dataset *poGDS = (HF2Dataset *) poDS; int nXBlocks = (nRasterXSize + nBlockXSize - 1) / nBlockXSize; int nYBlocks = (nRasterYSize + nBlockXSize - 1) / nBlockXSize; if (!poGDS->LoadBlockMap()) return CE_Failure; if (pafBlockData == NULL) { pafBlockData = (float*)VSIMalloc3(nXBlocks * sizeof(float), poGDS->nTileSize, poGDS->nTileSize); if (pafBlockData == NULL) return CE_Failure; } nLineYOff = nRasterYSize - 1 - nLineYOff; int nBlockYOff = nLineYOff / nBlockXSize; int nYOffInTile = nLineYOff % nBlockXSize; if (nBlockYOff != nLastBlockYOff) { nLastBlockYOff = nBlockYOff; memset(pafBlockData, 0, nXBlocks * sizeof(float) * nBlockXSize * nBlockXSize); /* 4 * nBlockXSize is the upper bound */ void* pabyData = CPLMalloc( 4 * nBlockXSize ); int nxoff; for(nxoff = 0; nxoff < nXBlocks; nxoff++) { VSIFSeekL(poGDS->fp, poGDS->panBlockOffset[(nYBlocks - 1 - nBlockYOff) * nXBlocks + nxoff], SEEK_SET); float fScale, fOff; VSIFReadL(&fScale, 4, 1, poGDS->fp); VSIFReadL(&fOff, 4, 1, poGDS->fp); CPL_LSBPTR32(&fScale); CPL_LSBPTR32(&fOff); int nTileWidth = MIN(nBlockXSize, nRasterXSize - nxoff * nBlockXSize); int nTileHeight = MIN(nBlockXSize, nRasterYSize - nBlockYOff * nBlockXSize); int j; for(j=0;j<nTileHeight;j++) { GByte nWordSize; VSIFReadL(&nWordSize, 1, 1, poGDS->fp); if (nWordSize != 1 && nWordSize != 2 && nWordSize != 4) { CPLError(CE_Failure, CPLE_AppDefined, "Unexpected word size : %d", (int)nWordSize); break; } GInt32 nVal; VSIFReadL(&nVal, 4, 1, poGDS->fp); CPL_LSBPTR32(&nVal); VSIFReadL(pabyData, nWordSize * (nTileWidth - 1), 1, poGDS->fp); #if defined(CPL_MSB) if (nWordSize > 1) GDALSwapWords(pabyData, nWordSize, nTileWidth - 1, nWordSize); #endif pafBlockData[nxoff * nBlockXSize * nBlockXSize + j * nBlockXSize + 0] = nVal * fScale + fOff; int i; for(i=1;i<nTileWidth;i++) { if (nWordSize == 1) nVal += ((signed char*)pabyData)[i-1]; else if (nWordSize == 2) nVal += ((GInt16*)pabyData)[i-1]; else nVal += ((GInt32*)pabyData)[i-1]; pafBlockData[nxoff * nBlockXSize * nBlockXSize + j * nBlockXSize + i] = nVal * fScale + fOff; } } } CPLFree(pabyData); } int nTileWidth = MIN(nBlockXSize, nRasterXSize - nBlockXOff * nBlockXSize); memcpy(pImage, pafBlockData + nBlockXOff * nBlockXSize * nBlockXSize + nYOffInTile * nBlockXSize, nTileWidth * sizeof(float)); return CE_None; }
CPLErr VRTFilteredSource::RasterIO( int nXOff, int nYOff, int nXSize, int nYSize, void *pData, int nBufXSize, int nBufYSize, GDALDataType eBufType, GSpacing nPixelSpace, GSpacing nLineSpace, GDALRasterIOExtraArg* psExtraArg ) { /* -------------------------------------------------------------------- */ /* For now we don't support filtered access to non-full */ /* resolution requests. Just collect the data directly without */ /* any operator. */ /* -------------------------------------------------------------------- */ if( nBufXSize != nXSize || nBufYSize != nYSize ) { return VRTComplexSource::RasterIO( nXOff, nYOff, nXSize, nYSize, pData, nBufXSize, nBufYSize, eBufType, nPixelSpace, nLineSpace, psExtraArg ); } // The window we will actually request from the source raster band. double dfReqXOff, dfReqYOff, dfReqXSize, dfReqYSize; int nReqXOff, nReqYOff, nReqXSize, nReqYSize; // The window we will actual set _within_ the pData buffer. int nOutXOff, nOutYOff, nOutXSize, nOutYSize; if( !GetSrcDstWindow( nXOff, nYOff, nXSize, nYSize, nBufXSize, nBufYSize, &dfReqXOff, &dfReqYOff, &dfReqXSize, &dfReqYSize, &nReqXOff, &nReqYOff, &nReqXSize, &nReqYSize, &nOutXOff, &nOutYOff, &nOutXSize, &nOutYSize ) ) return CE_None; pData = ((GByte *)pData) + nPixelSpace * nOutXOff + nLineSpace * nOutYOff; /* -------------------------------------------------------------------- */ /* Determine the data type we want to request. We try to match */ /* the source or destination request, and if both those fail we */ /* fallback to the first supported type at least as expressive */ /* as the request. */ /* -------------------------------------------------------------------- */ GDALDataType eOperDataType = GDT_Unknown; int i; if( IsTypeSupported( eBufType ) ) eOperDataType = eBufType; if( eOperDataType == GDT_Unknown && IsTypeSupported( poRasterBand->GetRasterDataType() ) ) eOperDataType = poRasterBand->GetRasterDataType(); if( eOperDataType == GDT_Unknown ) { for( i = 0; i < nSupportedTypesCount; i++ ) { if( GDALDataTypeUnion( aeSupportedTypes[i], eBufType ) == aeSupportedTypes[i] ) { eOperDataType = aeSupportedTypes[i]; } } } if( eOperDataType == GDT_Unknown ) { eOperDataType = aeSupportedTypes[0]; for( i = 1; i < nSupportedTypesCount; i++ ) { if( GDALGetDataTypeSize( aeSupportedTypes[i] ) > GDALGetDataTypeSize( eOperDataType ) ) { eOperDataType = aeSupportedTypes[i]; } } } /* -------------------------------------------------------------------- */ /* Allocate the buffer of data into which our imagery will be */ /* read, with the extra edge pixels as well. This will be the */ /* source data fed into the filter. */ /* -------------------------------------------------------------------- */ int nPixelOffset, nLineOffset; int nExtraXSize = nOutXSize + 2 * nExtraEdgePixels; int nExtraYSize = nOutYSize + 2 * nExtraEdgePixels; GByte *pabyWorkData; // FIXME? : risk of multiplication overflow pabyWorkData = (GByte *) VSICalloc( nExtraXSize * nExtraYSize, (GDALGetDataTypeSize(eOperDataType) / 8) ); if( pabyWorkData == NULL ) { CPLError( CE_Failure, CPLE_OutOfMemory, "Work buffer allocation failed." ); return CE_Failure; } nPixelOffset = GDALGetDataTypeSize( eOperDataType ) / 8; nLineOffset = nPixelOffset * nExtraXSize; /* -------------------------------------------------------------------- */ /* Allocate the output buffer if the passed in output buffer is */ /* not of the same type as our working format, or if the passed */ /* in buffer has an unusual organization. */ /* -------------------------------------------------------------------- */ GByte *pabyOutData; if( nPixelSpace != nPixelOffset || nLineSpace != nLineOffset || eOperDataType != eBufType ) { pabyOutData = (GByte *) VSIMalloc3(nOutXSize, nOutYSize, nPixelOffset ); if( pabyOutData == NULL ) { CPLError( CE_Failure, CPLE_OutOfMemory, "Work buffer allocation failed." ); return CE_Failure; } } else pabyOutData = (GByte *) pData; /* -------------------------------------------------------------------- */ /* Figure out the extended window that we want to load. Note */ /* that we keep track of the file window as well as the amount */ /* we will need to edge fill past the edge of the source dataset. */ /* -------------------------------------------------------------------- */ int nTopFill=0, nLeftFill=0, nRightFill=0, nBottomFill=0; int nFileXOff, nFileYOff, nFileXSize, nFileYSize; nFileXOff = nReqXOff - nExtraEdgePixels; nFileYOff = nReqYOff - nExtraEdgePixels; nFileXSize = nExtraXSize; nFileYSize = nExtraYSize; if( nFileXOff < 0 ) { nLeftFill = -nFileXOff; nFileXOff = 0; nFileXSize -= nLeftFill; } if( nFileYOff < 0 ) { nTopFill = -nFileYOff; nFileYOff = 0; nFileYSize -= nTopFill; } if( nFileXOff + nFileXSize > poRasterBand->GetXSize() ) { nRightFill = nFileXOff + nFileXSize - poRasterBand->GetXSize(); nFileXSize -= nRightFill; } if( nFileYOff + nFileYSize > poRasterBand->GetYSize() ) { nBottomFill = nFileYOff + nFileYSize - poRasterBand->GetYSize(); nFileYSize -= nBottomFill; } /* -------------------------------------------------------------------- */ /* Load the data. */ /* -------------------------------------------------------------------- */ CPLErr eErr; eErr = VRTComplexSource::RasterIOInternal( nFileXOff, nFileYOff, nFileXSize, nFileYSize, pabyWorkData + nLineOffset * nTopFill + nPixelOffset * nLeftFill, nFileXSize, nFileYSize, eOperDataType, nPixelOffset, nLineOffset, psExtraArg ); if( eErr != CE_None ) { if( pabyWorkData != pData ) VSIFree( pabyWorkData ); return eErr; } /* -------------------------------------------------------------------- */ /* Fill in missing areas. Note that we replicate the edge */ /* valid values out. We don't using "mirroring" which might be */ /* more suitable for some times of filters. We also don't mark */ /* these pixels as "nodata" though perhaps we should. */ /* -------------------------------------------------------------------- */ if( nLeftFill != 0 || nRightFill != 0 ) { for( i = nTopFill; i < nExtraYSize - nBottomFill; i++ ) { if( nLeftFill != 0 ) GDALCopyWords( pabyWorkData + nPixelOffset * nLeftFill + i * nLineOffset, eOperDataType, 0, pabyWorkData + i * nLineOffset, eOperDataType, nPixelOffset, nLeftFill ); if( nRightFill != 0 ) GDALCopyWords( pabyWorkData + i * nLineOffset + nPixelOffset * (nExtraXSize - nRightFill - 1), eOperDataType, 0, pabyWorkData + i * nLineOffset + nPixelOffset * (nExtraXSize - nRightFill), eOperDataType, nPixelOffset, nRightFill ); } } for( i = 0; i < nTopFill; i++ ) { memcpy( pabyWorkData + i * nLineOffset, pabyWorkData + nTopFill * nLineOffset, nLineOffset ); } for( i = nExtraYSize - nBottomFill; i < nExtraYSize; i++ ) { memcpy( pabyWorkData + i * nLineOffset, pabyWorkData + (nExtraYSize - nBottomFill - 1) * nLineOffset, nLineOffset ); } /* -------------------------------------------------------------------- */ /* Filter the data. */ /* -------------------------------------------------------------------- */ eErr = FilterData( nOutXSize, nOutYSize, eOperDataType, pabyWorkData, pabyOutData ); VSIFree( pabyWorkData ); if( eErr != CE_None ) { if( pabyOutData != pData ) VSIFree( pabyOutData ); return eErr; } /* -------------------------------------------------------------------- */ /* Copy from work buffer to target buffer. */ /* -------------------------------------------------------------------- */ if( pabyOutData != pData ) { for( i = 0; i < nOutYSize; i++ ) { GDALCopyWords( pabyOutData + i * (nPixelOffset * nOutXSize), eOperDataType, nPixelOffset, ((GByte *) pData) + i * nLineSpace, eBufType, nPixelSpace, nOutXSize ); } VSIFree( pabyOutData ); } return CE_None; }
GDALDataset *WEBPDataset::Open( GDALOpenInfo * poOpenInfo ) { if( !Identify( poOpenInfo ) ) return NULL; int nWidth, nHeight; if (!WebPGetInfo((const uint8_t*)poOpenInfo->pabyHeader, (uint32_t)poOpenInfo->nHeaderBytes, &nWidth, &nHeight)) return NULL; int nBands = 3; #if WEBP_DECODER_ABI_VERSION >= 0x0002 WebPDecoderConfig config; if (!WebPInitDecoderConfig(&config)) return NULL; int bOK = WebPGetFeatures(poOpenInfo->pabyHeader, poOpenInfo->nHeaderBytes, &config.input) == VP8_STATUS_OK; if (config.input.has_alpha) nBands = 4; WebPFreeDecBuffer(&config.output); if (!bOK) return NULL; #endif if( poOpenInfo->eAccess == GA_Update ) { CPLError( CE_Failure, CPLE_NotSupported, "The WEBP driver does not support update access to existing" " datasets.\n" ); return NULL; } /* -------------------------------------------------------------------- */ /* Open the file using the large file api. */ /* -------------------------------------------------------------------- */ VSILFILE* fpImage = VSIFOpenL( poOpenInfo->pszFilename, "rb" ); if( fpImage == NULL ) return NULL; GByte* pabyUncompressed = (GByte*)VSIMalloc3(nWidth, nHeight, nBands); if (pabyUncompressed == NULL) { VSIFCloseL(fpImage); return NULL; } /* -------------------------------------------------------------------- */ /* Create a corresponding GDALDataset. */ /* -------------------------------------------------------------------- */ WEBPDataset *poDS; poDS = new WEBPDataset(); poDS->nRasterXSize = nWidth; poDS->nRasterYSize = nHeight; poDS->fpImage = fpImage; poDS->pabyUncompressed = pabyUncompressed; /* -------------------------------------------------------------------- */ /* Create band information objects. */ /* -------------------------------------------------------------------- */ for( int iBand = 0; iBand < nBands; iBand++ ) poDS->SetBand( iBand+1, new WEBPRasterBand( poDS, iBand+1 ) ); /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ poDS->SetDescription( poOpenInfo->pszFilename ); poDS->TryLoadXML( poOpenInfo->papszSiblingFiles ); /* -------------------------------------------------------------------- */ /* Open overviews. */ /* -------------------------------------------------------------------- */ poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename, poOpenInfo->papszSiblingFiles ); return poDS; }
CPLErr RasterliteDataset::CreateOverviewLevel(int nOvrFactor, GDALProgressFunc pfnProgress, void * pProgressData) { double dfXResolution = padfXResolutions[0] * nOvrFactor; double dfYResolution = padfXResolutions[0] * nOvrFactor; CPLString osSQL; int nBlockXSize = 256; int nBlockYSize = 256; int nOvrXSize = nRasterXSize / nOvrFactor; int nOvrYSize = nRasterYSize / nOvrFactor; if (nOvrXSize == 0 || nOvrYSize == 0) return CE_Failure; int nXBlocks = (nOvrXSize + nBlockXSize - 1) / nBlockXSize; int nYBlocks = (nOvrYSize + nBlockYSize - 1) / nBlockYSize; const char* pszDriverName = "GTiff"; GDALDriverH hTileDriver = GDALGetDriverByName(pszDriverName); if (hTileDriver == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot load GDAL %s driver", pszDriverName); return CE_Failure; } GDALDriverH hMemDriver = GDALGetDriverByName("MEM"); if (hMemDriver == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot load GDAL MEM driver"); return CE_Failure; } GDALDataType eDataType = GetRasterBand(1)->GetRasterDataType(); int nDataTypeSize = GDALGetDataTypeSize(eDataType) / 8; GByte* pabyMEMDSBuffer = (GByte*)VSIMalloc3(nBlockXSize, nBlockYSize, nBands * nDataTypeSize); if (pabyMEMDSBuffer == NULL) { return CE_Failure; } char** papszTileDriverOptions = NULL; CPLString osTempFileName; osTempFileName.Printf("/vsimem/%p", hDS); int nTileId = 0; int nBlocks = 0; int nTotalBlocks = nXBlocks * nYBlocks; CPLString osRasterLayer; osRasterLayer.Printf("%s_rasters", osTableName.c_str()); CPLString osMetatadataLayer; osMetatadataLayer.Printf("%s_metadata", osTableName.c_str()); OGRLayerH hRasterLayer = OGR_DS_GetLayerByName(hDS, osRasterLayer.c_str()); OGRLayerH hMetadataLayer = OGR_DS_GetLayerByName(hDS, osMetatadataLayer.c_str()); CPLString osSourceName = "unknown"; osSQL.Printf("SELECT source_name FROM \"%s\" WHERE " "pixel_x_size >= %.15f AND pixel_x_size <= %.15f AND " "pixel_y_size >= %.15f AND pixel_y_size <= %.15f LIMIT 1", osMetatadataLayer.c_str(), padfXResolutions[0] - 1e-15, padfXResolutions[0] + 1e-15, padfYResolutions[0] - 1e-15, padfYResolutions[0] + 1e-15); OGRLayerH hSQLLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL); if (hSQLLyr) { OGRFeatureH hFeat = OGR_L_GetNextFeature(hSQLLyr); if (hFeat) { const char* pszVal = OGR_F_GetFieldAsString(hFeat, 0); if (pszVal) osSourceName = pszVal; OGR_F_Destroy(hFeat); } OGR_DS_ReleaseResultSet(hDS, hSQLLyr); } /* -------------------------------------------------------------------- */ /* Compute up to which existing overview level we can use for */ /* computing the requested overview */ /* -------------------------------------------------------------------- */ int iLev; nLimitOvrCount = 0; for(iLev=1;iLev<nResolutions;iLev++) { if (!(padfXResolutions[iLev] < dfXResolution - 1e-10 && padfYResolutions[iLev] < dfYResolution - 1e-10)) { break; } nLimitOvrCount++; } /* -------------------------------------------------------------------- */ /* Iterate over blocks to add data into raster and metadata tables */ /* -------------------------------------------------------------------- */ OGR_DS_ExecuteSQL(hDS, "BEGIN", NULL, NULL); CPLErr eErr = CE_None; int nBlockXOff, nBlockYOff; for(nBlockYOff=0;eErr == CE_None && nBlockYOff<nYBlocks;nBlockYOff++) { for(nBlockXOff=0;eErr == CE_None && nBlockXOff<nXBlocks;nBlockXOff++) { /* -------------------------------------------------------------------- */ /* Create in-memory tile */ /* -------------------------------------------------------------------- */ int nReqXSize = nBlockXSize, nReqYSize = nBlockYSize; if ((nBlockXOff+1) * nBlockXSize > nOvrXSize) nReqXSize = nOvrXSize - nBlockXOff * nBlockXSize; if ((nBlockYOff+1) * nBlockYSize > nOvrYSize) nReqYSize = nOvrYSize - nBlockYOff * nBlockYSize; eErr = RasterIO(GF_Read, nBlockXOff * nBlockXSize * nOvrFactor, nBlockYOff * nBlockYSize * nOvrFactor, nReqXSize * nOvrFactor, nReqYSize * nOvrFactor, pabyMEMDSBuffer, nReqXSize, nReqYSize, eDataType, nBands, NULL, 0, 0, 0); if (eErr != CE_None) { break; } GDALDatasetH hMemDS = GDALCreate(hMemDriver, "MEM:::", nReqXSize, nReqYSize, 0, eDataType, NULL); if (hMemDS == NULL) { eErr = CE_Failure; break; } int iBand; for(iBand = 0; iBand < nBands; iBand ++) { char** papszOptions = NULL; char szTmp[64]; memset(szTmp, 0, sizeof(szTmp)); CPLPrintPointer(szTmp, pabyMEMDSBuffer + iBand * nDataTypeSize * nReqXSize * nReqYSize, sizeof(szTmp)); papszOptions = CSLSetNameValue(papszOptions, "DATAPOINTER", szTmp); GDALAddBand(hMemDS, eDataType, papszOptions); CSLDestroy(papszOptions); } GDALDatasetH hOutDS = GDALCreateCopy(hTileDriver, osTempFileName.c_str(), hMemDS, FALSE, papszTileDriverOptions, NULL, NULL); GDALClose(hMemDS); if (hOutDS) GDALClose(hOutDS); else { eErr = CE_Failure; break; } /* -------------------------------------------------------------------- */ /* Insert new entry into raster table */ /* -------------------------------------------------------------------- */ vsi_l_offset nDataLength; GByte *pabyData = VSIGetMemFileBuffer( osTempFileName.c_str(), &nDataLength, FALSE); OGRFeatureH hFeat = OGR_F_Create( OGR_L_GetLayerDefn(hRasterLayer) ); OGR_F_SetFieldBinary(hFeat, 0, (int)nDataLength, pabyData); OGR_L_CreateFeature(hRasterLayer, hFeat); /* Query raster ID to set it as the ID of the associated metadata */ int nRasterID = (int)OGR_F_GetFID(hFeat); OGR_F_Destroy(hFeat); VSIUnlink(osTempFileName.c_str()); /* -------------------------------------------------------------------- */ /* Insert new entry into metadata table */ /* -------------------------------------------------------------------- */ hFeat = OGR_F_Create( OGR_L_GetLayerDefn(hMetadataLayer) ); OGR_F_SetFID(hFeat, nRasterID); OGR_F_SetFieldString(hFeat, 0, osSourceName); OGR_F_SetFieldInteger(hFeat, 1, nTileId ++); OGR_F_SetFieldInteger(hFeat, 2, nReqXSize); OGR_F_SetFieldInteger(hFeat, 3, nReqYSize); OGR_F_SetFieldDouble(hFeat, 4, dfXResolution); OGR_F_SetFieldDouble(hFeat, 5, dfYResolution); double minx, maxx, maxy, miny; minx = adfGeoTransform[0] + (nBlockXSize * nBlockXOff) * dfXResolution; maxx = adfGeoTransform[0] + (nBlockXSize * nBlockXOff + nReqXSize) * dfXResolution; maxy = adfGeoTransform[3] + (nBlockYSize * nBlockYOff) * (-dfYResolution); miny = adfGeoTransform[3] + (nBlockYSize * nBlockYOff + nReqYSize) * (-dfYResolution); OGRGeometryH hRectangle = OGR_G_CreateGeometry(wkbPolygon); OGRGeometryH hLinearRing = OGR_G_CreateGeometry(wkbLinearRing); OGR_G_AddPoint_2D(hLinearRing, minx, miny); OGR_G_AddPoint_2D(hLinearRing, minx, maxy); OGR_G_AddPoint_2D(hLinearRing, maxx, maxy); OGR_G_AddPoint_2D(hLinearRing, maxx, miny); OGR_G_AddPoint_2D(hLinearRing, minx, miny); OGR_G_AddGeometryDirectly(hRectangle, hLinearRing); OGR_F_SetGeometryDirectly(hFeat, hRectangle); OGR_L_CreateFeature(hMetadataLayer, hFeat); OGR_F_Destroy(hFeat); nBlocks++; if (pfnProgress && !pfnProgress(1.0 * nBlocks / nTotalBlocks, NULL, pProgressData)) eErr = CE_Failure; } } nLimitOvrCount = -1; if (eErr == CE_None) OGR_DS_ExecuteSQL(hDS, "COMMIT", NULL, NULL); else OGR_DS_ExecuteSQL(hDS, "ROLLBACK", NULL, NULL); VSIFree(pabyMEMDSBuffer); /* -------------------------------------------------------------------- */ /* Update raster_pyramids table */ /* -------------------------------------------------------------------- */ if (eErr == CE_None) { OGRLayerH hRasterPyramidsLyr = OGR_DS_GetLayerByName(hDS, "raster_pyramids"); if (hRasterPyramidsLyr == NULL) { osSQL.Printf ("CREATE TABLE raster_pyramids (" "table_prefix TEXT NOT NULL," "pixel_x_size DOUBLE NOT NULL," "pixel_y_size DOUBLE NOT NULL," "tile_count INTEGER NOT NULL)"); OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL); /* Re-open the DB to take into account the new tables*/ OGRReleaseDataSource(hDS); CPLString osOldVal = CPLGetConfigOption("SQLITE_LIST_ALL_TABLES", "FALSE"); CPLSetThreadLocalConfigOption("SQLITE_LIST_ALL_TABLES", "TRUE"); hDS = OGROpen(osFileName.c_str(), TRUE, NULL); CPLSetThreadLocalConfigOption("SQLITE_LIST_ALL_TABLES", osOldVal.c_str()); } /* Insert base resolution into raster_pyramids if not already done */ int bHasBaseResolution = FALSE; osSQL.Printf("SELECT * FROM raster_pyramids WHERE " "table_prefix = '%s' AND pixel_x_size >= %.15f AND pixel_x_size <= %.15f AND " "pixel_y_size >= %.15f AND pixel_y_size <= %.15f", osTableName.c_str(), padfXResolutions[0] - 1e-15, padfXResolutions[0] + 1e-15, padfYResolutions[0] - 1e-15, padfYResolutions[0] + 1e-15); hSQLLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL); if (hSQLLyr) { OGRFeatureH hFeat = OGR_L_GetNextFeature(hSQLLyr); if (hFeat) { bHasBaseResolution = TRUE; OGR_F_Destroy(hFeat); } OGR_DS_ReleaseResultSet(hDS, hSQLLyr); } if (!bHasBaseResolution) { osSQL.Printf("SELECT COUNT(*) FROM \"%s\" WHERE " "pixel_x_size >= %.15f AND pixel_x_size <= %.15f AND " "pixel_y_size >= %.15f AND pixel_y_size <= %.15f", osMetatadataLayer.c_str(), padfXResolutions[0] - 1e-15, padfXResolutions[0] + 1e-15, padfYResolutions[0] - 1e-15, padfYResolutions[0] + 1e-15); int nBlocksMainRes = 0; hSQLLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL); if (hSQLLyr) { OGRFeatureH hFeat = OGR_L_GetNextFeature(hSQLLyr); if (hFeat) { nBlocksMainRes = OGR_F_GetFieldAsInteger(hFeat, 0); OGR_F_Destroy(hFeat); } OGR_DS_ReleaseResultSet(hDS, hSQLLyr); } osSQL.Printf("INSERT INTO raster_pyramids " "( table_prefix, pixel_x_size, pixel_y_size, tile_count ) " "VALUES ( '%s', %.18f, %.18f, %d )", osTableName.c_str(), padfXResolutions[0], padfYResolutions[0], nBlocksMainRes); OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL); } osSQL.Printf("INSERT INTO raster_pyramids " "( table_prefix, pixel_x_size, pixel_y_size, tile_count ) " "VALUES ( '%s', %.18f, %.18f, %d )", osTableName.c_str(), dfXResolution, dfYResolution, nTotalBlocks); OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL); } return eErr; }
CPLErr GDALNoDataMaskBand::IReadBlock( int nXBlockOff, int nYBlockOff, void * pImage ) { GDALDataType eWrkDT; /* -------------------------------------------------------------------- */ /* Decide on a working type. */ /* -------------------------------------------------------------------- */ switch( poParent->GetRasterDataType() ) { case GDT_Byte: eWrkDT = GDT_Byte; break; case GDT_UInt16: case GDT_UInt32: eWrkDT = GDT_UInt32; break; case GDT_Int16: case GDT_Int32: case GDT_CInt16: case GDT_CInt32: eWrkDT = GDT_Int32; break; case GDT_Float32: case GDT_CFloat32: eWrkDT = GDT_Float32; break; case GDT_Float64: case GDT_CFloat64: eWrkDT = GDT_Float64; break; default: CPLAssert( FALSE ); eWrkDT = GDT_Float64; break; } /* -------------------------------------------------------------------- */ /* Read the image data. */ /* -------------------------------------------------------------------- */ GByte *pabySrc; CPLErr eErr; pabySrc = (GByte *) VSIMalloc3( GDALGetDataTypeSize(eWrkDT)/8, nBlockXSize, nBlockYSize ); if (pabySrc == NULL) { CPLError( CE_Failure, CPLE_OutOfMemory, "GDALNoDataMaskBand::IReadBlock: Out of memory for buffer." ); return CE_Failure; } int nXSizeRequest = nBlockXSize; if (nXBlockOff * nBlockXSize + nBlockXSize > nRasterXSize) nXSizeRequest = nRasterXSize - nXBlockOff * nBlockXSize; int nYSizeRequest = nBlockYSize; if (nYBlockOff * nBlockYSize + nBlockYSize > nRasterYSize) nYSizeRequest = nRasterYSize - nYBlockOff * nBlockYSize; if (nXSizeRequest != nBlockXSize || nYSizeRequest != nBlockYSize) { /* memset the whole buffer to avoid Valgrind warnings in case we can't */ /* fetch a full block */ memset(pabySrc, 0, GDALGetDataTypeSize(eWrkDT)/8 * nBlockXSize * nBlockYSize ); } eErr = poParent->RasterIO( GF_Read, nXBlockOff * nBlockXSize, nYBlockOff * nBlockYSize, nXSizeRequest, nYSizeRequest, pabySrc, nXSizeRequest, nYSizeRequest, eWrkDT, 0, nBlockXSize * (GDALGetDataTypeSize(eWrkDT)/8), NULL ); if( eErr != CE_None ) { CPLFree(pabySrc); return eErr; } int bIsNoDataNan = CPLIsNan(dfNoDataValue); /* -------------------------------------------------------------------- */ /* Process different cases. */ /* -------------------------------------------------------------------- */ int i; switch( eWrkDT ) { case GDT_Byte: { GByte byNoData = (GByte) dfNoDataValue; for( i = nBlockXSize * nBlockYSize - 1; i >= 0; i-- ) { if( pabySrc[i] == byNoData ) ((GByte *) pImage)[i] = 0; else ((GByte *) pImage)[i] = 255; } } break; case GDT_UInt32: { GUInt32 nNoData = (GUInt32) dfNoDataValue; for( i = nBlockXSize * nBlockYSize - 1; i >= 0; i-- ) { if( ((GUInt32 *)pabySrc)[i] == nNoData ) ((GByte *) pImage)[i] = 0; else ((GByte *) pImage)[i] = 255; } } break; case GDT_Int32: { GInt32 nNoData = (GInt32) dfNoDataValue; for( i = nBlockXSize * nBlockYSize - 1; i >= 0; i-- ) { if( ((GInt32 *)pabySrc)[i] == nNoData ) ((GByte *) pImage)[i] = 0; else ((GByte *) pImage)[i] = 255; } } break; case GDT_Float32: { float fNoData = (float) dfNoDataValue; for( i = nBlockXSize * nBlockYSize - 1; i >= 0; i-- ) { float fVal =((float *)pabySrc)[i]; if( bIsNoDataNan && CPLIsNan(fVal)) ((GByte *) pImage)[i] = 0; else if( ARE_REAL_EQUAL(fVal, fNoData) ) ((GByte *) pImage)[i] = 0; else ((GByte *) pImage)[i] = 255; } } break; case GDT_Float64: { for( i = nBlockXSize * nBlockYSize - 1; i >= 0; i-- ) { double dfVal =((double *)pabySrc)[i]; if( bIsNoDataNan && CPLIsNan(dfVal)) ((GByte *) pImage)[i] = 0; else if( ARE_REAL_EQUAL(dfVal, dfNoDataValue) ) ((GByte *) pImage)[i] = 0; else ((GByte *) pImage)[i] = 255; } } break; default: CPLAssert( FALSE ); break; } CPLFree( pabySrc ); return CE_None; }
RPFToc* RPFTOCReadFromBuffer(const char* pszFilename, FILE* fp, const char* tocHeader) { int i, j; unsigned int locationSectionPhysicalLocation; unsigned short nSections; unsigned int boundaryRectangleSectionSubHeaderPhysIndex = 0, boundaryRectangleSectionSubHeaderLength = 0; unsigned int boundaryRectangleTablePhysIndex = 0, boundaryRectangleTableLength = 0; unsigned int frameFileIndexSectionSubHeaderPhysIndex = 0, frameFileIndexSectionSubHeaderLength = 0; unsigned int frameFileIndexSubsectionPhysIndex = 0, frameFileIndexSubsectionLength = 0; unsigned int boundaryRectangleTableOffset; unsigned short boundaryRectangleCount; unsigned int frameIndexTableOffset; unsigned int nFrameFileIndexRecords; unsigned short nFrameFilePathnameRecords; unsigned short frameFileIndexRecordLength; int newBoundaryId = 0; RPFToc* toc; tocHeader += 1; /* skip endian */ tocHeader += 2; /* skip header length */ tocHeader += 12; /* skip file name : this should be A.TOC (padded) */ tocHeader += 1; /* skip new */ tocHeader += 15; /* skip standard_num */ tocHeader += 8; /* skip standard_date */ tocHeader += 1; /* skip classification */ tocHeader += 2; /* skip country */ tocHeader += 2; /* skip release */ memcpy(&locationSectionPhysicalLocation, tocHeader, sizeof(unsigned int)); CPL_MSBPTR32(&locationSectionPhysicalLocation); if( VSIFSeekL( fp, locationSectionPhysicalLocation, SEEK_SET ) != 0) { CPLError( CE_Failure, CPLE_NotSupported, "Invalid TOC file. Unable to seek to locationSectionPhysicalLocation at offset %d.", locationSectionPhysicalLocation ); return NULL; } /* Skip location section length (4) and component location table offset (2)*/ VSIFSeekL( fp, 4 + 2, SEEK_CUR); /* How many sections: # of section location records */ VSIFReadL( &nSections, 1, sizeof(nSections), fp); CPL_MSBPTR16( &nSections ); /* Skip location record length(2) + component aggregate length(4) */ VSIFSeekL( fp, 2 + 4, SEEK_CUR); for (i = 0; i < nSections; i++) { unsigned short id; unsigned int sectionLength, physIndex; VSIFReadL( &id, 1, sizeof(id), fp); CPL_MSBPTR16( &id ); VSIFReadL( §ionLength, 1, sizeof(sectionLength), fp); CPL_MSBPTR32( §ionLength ); VSIFReadL( &physIndex, 1, sizeof(physIndex), fp); CPL_MSBPTR32( &physIndex ); if (id == LID_BoundaryRectangleSectionSubheader) { boundaryRectangleSectionSubHeaderPhysIndex = physIndex; boundaryRectangleSectionSubHeaderLength = sectionLength; } else if (id == LID_BoundaryRectangleTable) { boundaryRectangleTablePhysIndex = physIndex; boundaryRectangleTableLength = sectionLength; } else if (id == LID_FrameFileIndexSectionSubHeader) { frameFileIndexSectionSubHeaderPhysIndex = physIndex; frameFileIndexSectionSubHeaderLength = sectionLength; } else if (id == LID_FrameFileIndexSubsection) { frameFileIndexSubsectionPhysIndex = physIndex; frameFileIndexSubsectionLength = sectionLength; } } if (boundaryRectangleSectionSubHeaderPhysIndex == 0) { CPLError( CE_Failure, CPLE_NotSupported, "Invalid TOC file. Can't find LID_BoundaryRectangleSectionSubheader." ); return NULL; } if (boundaryRectangleTablePhysIndex == 0) { CPLError( CE_Failure, CPLE_NotSupported, "Invalid TOC file. Can't find LID_BoundaryRectangleTable." ); return NULL; } if (frameFileIndexSectionSubHeaderPhysIndex == 0) { CPLError( CE_Failure, CPLE_NotSupported, "Invalid TOC file. Can't find LID_FrameFileIndexSectionSubHeader." ); return NULL; } if (frameFileIndexSubsectionPhysIndex == 0) { CPLError( CE_Failure, CPLE_NotSupported, "Invalid TOC file. Can't find LID_FrameFileIndexSubsection." ); return NULL; } if( VSIFSeekL( fp, boundaryRectangleSectionSubHeaderPhysIndex, SEEK_SET ) != 0) { CPLError( CE_Failure, CPLE_NotSupported, "Invalid TOC file. Unable to seek to boundaryRectangleSectionSubHeaderPhysIndex at offset %d.", boundaryRectangleSectionSubHeaderPhysIndex ); return NULL; } VSIFReadL( &boundaryRectangleTableOffset, 1, sizeof(boundaryRectangleTableOffset), fp); CPL_MSBPTR32( &boundaryRectangleTableOffset ); VSIFReadL( &boundaryRectangleCount, 1, sizeof(boundaryRectangleCount), fp); CPL_MSBPTR16( &boundaryRectangleCount ); if( VSIFSeekL( fp, boundaryRectangleTablePhysIndex, SEEK_SET ) != 0) { CPLError( CE_Failure, CPLE_NotSupported, "Invalid TOC file. Unable to seek to boundaryRectangleTablePhysIndex at offset %d.", boundaryRectangleTablePhysIndex ); return NULL; } toc = (RPFToc*)CPLMalloc(sizeof(RPFToc)); toc->nEntries = boundaryRectangleCount; toc->entries = (RPFTocEntry*)CPLMalloc(boundaryRectangleCount * sizeof(RPFTocEntry)); memset(toc->entries, 0, boundaryRectangleCount * sizeof(RPFTocEntry)); for(i=0;i<toc->nEntries;i++) { toc->entries[i].isOverviewOrLegend = 0; VSIFReadL( toc->entries[i].type, 1, 5, fp); toc->entries[i].type[5] = 0; RPFTOCTrim(toc->entries[i].type); VSIFReadL( toc->entries[i].compression, 1, 5, fp); toc->entries[i].compression[5] = 0; RPFTOCTrim(toc->entries[i].compression); VSIFReadL( toc->entries[i].scale, 1, 12, fp); toc->entries[i].scale[12] = 0; RPFTOCTrim(toc->entries[i].scale); if (toc->entries[i].scale[0] == '1' && toc->entries[i].scale[1] == ':') { memmove(toc->entries[i].scale, toc->entries[i].scale+2, strlen(toc->entries[i].scale+2)+1); } VSIFReadL( toc->entries[i].zone, 1, 1, fp); toc->entries[i].zone[1] = 0; RPFTOCTrim(toc->entries[i].zone); VSIFReadL( toc->entries[i].producer, 1, 5, fp); toc->entries[i].producer[5] = 0; RPFTOCTrim(toc->entries[i].producer); VSIFReadL( &toc->entries[i].nwLat, 1, sizeof(double), fp); CPL_MSBPTR64( &toc->entries[i].nwLat); VSIFReadL( &toc->entries[i].nwLong, 1, sizeof(double), fp); CPL_MSBPTR64( &toc->entries[i].nwLong); VSIFReadL( &toc->entries[i].swLat, 1, sizeof(double), fp); CPL_MSBPTR64( &toc->entries[i].swLat); VSIFReadL( &toc->entries[i].swLong, 1, sizeof(double), fp); CPL_MSBPTR64( &toc->entries[i].swLong); VSIFReadL( &toc->entries[i].neLat, 1, sizeof(double), fp); CPL_MSBPTR64( &toc->entries[i].neLat); VSIFReadL( &toc->entries[i].neLong, 1, sizeof(double), fp); CPL_MSBPTR64( &toc->entries[i].neLong); VSIFReadL( &toc->entries[i].seLat, 1, sizeof(double), fp); CPL_MSBPTR64( &toc->entries[i].seLat); VSIFReadL( &toc->entries[i].seLong, 1, sizeof(double), fp); CPL_MSBPTR64( &toc->entries[i].seLong); VSIFReadL( &toc->entries[i].vertResolution, 1, sizeof(double), fp); CPL_MSBPTR64( &toc->entries[i].vertResolution); VSIFReadL( &toc->entries[i].horizResolution, 1, sizeof(double), fp); CPL_MSBPTR64( &toc->entries[i].horizResolution); VSIFReadL( &toc->entries[i].vertInterval, 1, sizeof(double), fp); CPL_MSBPTR64( &toc->entries[i].vertInterval); VSIFReadL( &toc->entries[i].horizInterval, 1, sizeof(double), fp); CPL_MSBPTR64( &toc->entries[i].horizInterval); VSIFReadL( &toc->entries[i].nVertFrames, 1, sizeof(int), fp); CPL_MSBPTR32( &toc->entries[i].nVertFrames ); VSIFReadL( &toc->entries[i].nHorizFrames, 1, sizeof(int), fp); CPL_MSBPTR32( &toc->entries[i].nHorizFrames ); toc->entries[i].frameEntries = (RPFTocFrameEntry*) VSIMalloc3(toc->entries[i].nVertFrames, toc->entries[i].nHorizFrames, sizeof(RPFTocFrameEntry)); if (toc->entries[i].frameEntries == NULL) { CPLError( CE_Failure, CPLE_OutOfMemory, "RPFTOCReadFromBuffer : Out of memory. Probably due to corrupted TOC file."); RPFTOCFree(toc); return NULL; } memset(toc->entries[i].frameEntries, 0, toc->entries[i].nVertFrames * toc->entries[i].nHorizFrames * sizeof(RPFTocFrameEntry)); CPLDebug("RPFTOC", "[%d] type=%s, compression=%s, scale=%s, zone=%s, producer=%s, nVertFrames=%d, nHorizFrames=%d", i, toc->entries[i].type, toc->entries[i].compression, toc->entries[i].scale, toc->entries[i].zone, toc->entries[i].producer, toc->entries[i].nVertFrames, toc->entries[i].nHorizFrames); } if( VSIFSeekL( fp, frameFileIndexSectionSubHeaderPhysIndex, SEEK_SET ) != 0) { CPLError( CE_Failure, CPLE_NotSupported, "Invalid TOC file. Unable to seek to frameFileIndexSectionSubHeaderPhysIndex at offset %d.", frameFileIndexSectionSubHeaderPhysIndex ); RPFTOCFree(toc); return NULL; } /* Skip 1 byte security classification */ VSIFSeekL( fp, 1, SEEK_CUR ); VSIFReadL( &frameIndexTableOffset, 1, sizeof(frameIndexTableOffset), fp); CPL_MSBPTR32( &frameIndexTableOffset ); VSIFReadL( &nFrameFileIndexRecords, 1, sizeof(nFrameFileIndexRecords), fp); CPL_MSBPTR32( &nFrameFileIndexRecords ); VSIFReadL( &nFrameFilePathnameRecords, 1, sizeof(nFrameFilePathnameRecords), fp); CPL_MSBPTR16( &nFrameFilePathnameRecords ); VSIFReadL( &frameFileIndexRecordLength, 1, sizeof(frameFileIndexRecordLength), fp); CPL_MSBPTR16( &frameFileIndexRecordLength ); for (i=0;i<(int)nFrameFileIndexRecords;i++) { RPFTocEntry* entry; RPFTocFrameEntry* frameEntry; unsigned short boundaryId, frameRow, frameCol; unsigned int offsetFrameFilePathName; unsigned short pathLength; if( VSIFSeekL( fp, frameFileIndexSubsectionPhysIndex + frameFileIndexRecordLength * i, SEEK_SET ) != 0) { CPLError( CE_Failure, CPLE_NotSupported, "Invalid TOC file. Unable to seek to frameFileIndexSubsectionPhysIndex(%d) at offset %d.", i, frameFileIndexSubsectionPhysIndex + frameFileIndexRecordLength * i); RPFTOCFree(toc); return NULL; } VSIFReadL( &boundaryId, 1, sizeof(boundaryId), fp); CPL_MSBPTR16( &boundaryId ); if (i == 0 && boundaryId == 0) newBoundaryId = 1; if (newBoundaryId == 0) boundaryId--; if (boundaryId >= toc->nEntries) { CPLError( CE_Failure, CPLE_NotSupported, "Invalid TOC file. Bad boundary id (%d) for frame file index %d.", boundaryId, i); RPFTOCFree(toc); return NULL; } entry = &toc->entries[boundaryId]; entry->boundaryId = boundaryId; VSIFReadL( &frameRow, 1, sizeof(frameRow), fp); CPL_MSBPTR16( &frameRow ); VSIFReadL( &frameCol, 1, sizeof(frameCol), fp); CPL_MSBPTR16( &frameCol ); if (newBoundaryId == 0) { frameRow--; frameCol--; } else { /* Trick so that frames are numbered north to south */ frameRow = (unsigned short)((entry->nVertFrames-1) - frameRow); } if (frameRow >= entry->nVertFrames) { CPLError( CE_Failure, CPLE_NotSupported, "Invalid TOC file. Bad row num (%d) for frame file index %d.", frameRow, i); RPFTOCFree(toc); return NULL; } if (frameCol >= entry->nHorizFrames) { CPLError( CE_Failure, CPLE_NotSupported, "Invalid TOC file. Bad col num (%d) for frame file index %d.", frameCol, i); RPFTOCFree(toc); return NULL; } frameEntry = &entry->frameEntries[frameRow * entry->nHorizFrames + frameCol ]; frameEntry->frameRow = frameRow; frameEntry->frameCol = frameCol; if (frameEntry->exists) { CPLError( CE_Failure, CPLE_NotSupported, "Invalid TOC file. Frame entry(%d,%d) for frame file index %d is a duplicate.", frameRow, frameCol, i); RPFTOCFree(toc); return NULL; } VSIFReadL( &offsetFrameFilePathName, 1, sizeof(offsetFrameFilePathName), fp); CPL_MSBPTR32( &offsetFrameFilePathName ); VSIFReadL( frameEntry->filename, 1, 12, fp); frameEntry->filename[12] = '\0'; /* Check if the filename is an overview or legend */ for (j=0;j<12;j++) { if (strcmp(&(frameEntry->filename[j]),".OVR") == 0 || strcmp(&(frameEntry->filename[j]),".ovr") == 0 || strcmp(&(frameEntry->filename[j]),".LGD") == 0 || strcmp(&(frameEntry->filename[j]),".lgd") == 0) { entry->isOverviewOrLegend = TRUE; break; } } /* Extract series code */ if (entry->seriesAbbreviation == NULL) { const NITFSeries* series = NITFGetSeriesInfo(frameEntry->filename); if (series) { entry->seriesAbbreviation = series->abbreviation; entry->seriesName = series->name; } } /* Get file geo reference */ VSIFReadL( frameEntry->georef, 1, 6, fp); frameEntry->georef[6] = '\0'; /* Go to start of pathname record */ /* New path_off offset from start of frame file index section of TOC?? */ /* Add pathoffset wrt frame file index table subsection (loc[3]) */ if( VSIFSeekL( fp, frameFileIndexSubsectionPhysIndex + offsetFrameFilePathName, SEEK_SET ) != 0) { CPLError( CE_Failure, CPLE_NotSupported, "Invalid TOC file. Unable to seek to frameFileIndexSubsectionPhysIndex + offsetFrameFilePathName(%d) at offset %d.", i, frameFileIndexSubsectionPhysIndex + offsetFrameFilePathName); RPFTOCFree(toc); return NULL; } VSIFReadL( &pathLength, 1, sizeof(pathLength), fp); CPL_MSBPTR16( &pathLength ); /* if nFrameFileIndexRecords == 65535 and pathLength == 65535 for each record, this leads to 4 GB allocation... Protect against this case */ if (pathLength > 256) { CPLError( CE_Failure, CPLE_NotSupported, "Path length is big : %d. Probably corrupted TOC file.", (int)pathLength); RPFTOCFree(toc); return NULL; } frameEntry->directory = (char *)CPLMalloc(pathLength+1); VSIFReadL( frameEntry->directory, 1, pathLength, fp); frameEntry->directory[pathLength] = 0; if (pathLength > 0 && frameEntry->directory[pathLength-1] == '/') frameEntry->directory[pathLength-1] = 0; if (frameEntry->directory[0] == '.' && frameEntry->directory[1] == '/') memmove(frameEntry->directory, frameEntry->directory+2, strlen(frameEntry->directory+2)+1); { char* baseDir = CPLStrdup(CPLGetDirname(pszFilename)); VSIStatBufL sStatBuf; char* subdir; if (CPLIsFilenameRelative(frameEntry->directory) == FALSE) subdir = CPLStrdup(frameEntry->directory); else if (frameEntry->directory[0] == '.' && frameEntry->directory[1] == 0) subdir = CPLStrdup(baseDir); else subdir = CPLStrdup(CPLFormFilename(baseDir, frameEntry->directory, NULL)); #if !defined(_WIN32) && !defined(_WIN32_CE) if( VSIStatL( subdir, &sStatBuf ) != 0 && subdir[strlen(baseDir)] != 0) { char* c = subdir + strlen(baseDir)+1; while(*c) { if (*c >= 'A' && *c <= 'Z') *c += 'a' - 'A'; c++; } } #endif frameEntry->fullFilePath = CPLStrdup(CPLFormFilename( subdir, frameEntry->filename, NULL)); if( VSIStatL( frameEntry->fullFilePath, &sStatBuf ) != 0 ) { #if !defined(_WIN32) && !defined(_WIN32_CE) char* c = frameEntry->fullFilePath + strlen(subdir)+1; while(*c) { if (*c >= 'A' && *c <= 'Z') *c += 'a' - 'A'; c++; } if( VSIStatL( frameEntry->fullFilePath, &sStatBuf ) != 0 ) #endif { frameEntry->fileExists = 0; CPLError( CE_Warning, CPLE_AppDefined, "File %s does not exist.", frameEntry->fullFilePath ); } #if !defined(_WIN32) && !defined(_WIN32_CE) else { frameEntry->fileExists = 1; } #endif } else { frameEntry->fileExists = 1; } CPLFree(subdir); CPLFree(baseDir); } CPLDebug("RPFTOC", "Entry %d : %s,%s (%d, %d)", boundaryId, frameEntry->directory, frameEntry->filename, frameRow, frameCol); frameEntry->exists = 1; } return toc; }
GDALDataset * RasterliteCreateCopy( const char * pszFilename, GDALDataset *poSrcDS, int bStrict, char ** papszOptions, GDALProgressFunc pfnProgress, void * pProgressData ) { int nBands = poSrcDS->GetRasterCount(); if (nBands == 0) { CPLError(CE_Failure, CPLE_NotSupported, "nBands == 0"); return NULL; } const char* pszDriverName = CSLFetchNameValueDef(papszOptions, "DRIVER", "GTiff"); GDALDriverH hTileDriver = GDALGetDriverByName(pszDriverName); if ( hTileDriver == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot load GDAL %s driver", pszDriverName); return NULL; } GDALDriverH hMemDriver = GDALGetDriverByName("MEM"); if (hMemDriver == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot load GDAL MEM driver"); return NULL; } int nXSize = GDALGetRasterXSize(poSrcDS); int nYSize = GDALGetRasterYSize(poSrcDS); double adfGeoTransform[6]; if (poSrcDS->GetGeoTransform(adfGeoTransform) != CE_None) { adfGeoTransform[0] = 0; adfGeoTransform[1] = 1; adfGeoTransform[2] = 0; adfGeoTransform[3] = 0; adfGeoTransform[4] = 0; adfGeoTransform[5] = -1; } else if (adfGeoTransform[2] != 0.0 || adfGeoTransform[4] != 0.0) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot use geotransform with rotational terms"); return NULL; } int bTiled = CSLTestBoolean(CSLFetchNameValueDef(papszOptions, "TILED", "YES")); int nBlockXSize, nBlockYSize; if (bTiled) { nBlockXSize = atoi(CSLFetchNameValueDef(papszOptions, "BLOCKXSIZE", "256")); nBlockYSize = atoi(CSLFetchNameValueDef(papszOptions, "BLOCKYSIZE", "256")); if (nBlockXSize < 64) nBlockXSize = 64; else if (nBlockXSize > 4096) nBlockXSize = 4096; if (nBlockYSize < 64) nBlockYSize = 64; else if (nBlockYSize > 4096) nBlockYSize = 4096; } else { nBlockXSize = nXSize; nBlockYSize = nYSize; } /* -------------------------------------------------------------------- */ /* Analyze arguments */ /* -------------------------------------------------------------------- */ CPLString osDBName; CPLString osTableName; VSIStatBuf sBuf; int bExists; /* Skip optionnal RASTERLITE: prefix */ const char* pszFilenameWithoutPrefix = pszFilename; if (EQUALN(pszFilename, "RASTERLITE:", 11)) pszFilenameWithoutPrefix += 11; char** papszTokens = CSLTokenizeStringComplex( pszFilenameWithoutPrefix, ", ", FALSE, FALSE ); int nTokens = CSLCount(papszTokens); if (nTokens == 0) { osDBName = pszFilenameWithoutPrefix; osTableName = CPLGetBasename(pszFilenameWithoutPrefix); } else { osDBName = papszTokens[0]; int i; for(i=1;i<nTokens;i++) { if (EQUALN(papszTokens[i], "table=", 6)) osTableName = papszTokens[i] + 6; else { CPLError(CE_Warning, CPLE_AppDefined, "Invalid option : %s", papszTokens[i]); } } } CSLDestroy(papszTokens); papszTokens = NULL; bExists = (VSIStat(osDBName.c_str(), &sBuf) == 0); if (osTableName.size() == 0) { if (bExists) { CPLError(CE_Failure, CPLE_AppDefined, "Database already exists. Explicit table name must be specified"); return NULL; } osTableName = CPLGetBasename(osDBName.c_str()); } CPLString osRasterLayer; osRasterLayer.Printf("%s_rasters", osTableName.c_str()); CPLString osMetatadataLayer; osMetatadataLayer.Printf("%s_metadata", osTableName.c_str()); /* -------------------------------------------------------------------- */ /* Create or open the SQLite DB */ /* -------------------------------------------------------------------- */ if (OGRGetDriverCount() == 0) OGRRegisterAll(); OGRSFDriverH hSQLiteDriver = OGRGetDriverByName("SQLite"); if (hSQLiteDriver == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot load OGR SQLite driver"); return NULL; } OGRDataSourceH hDS; CPLString osOldVal = CPLGetConfigOption("SQLITE_LIST_ALL_TABLES", "FALSE"); CPLSetConfigOption("SQLITE_LIST_ALL_TABLES", "TRUE"); if (!bExists) { char** papszOGROptions = CSLAddString(NULL, "SPATIALITE=YES"); hDS = OGR_Dr_CreateDataSource(hSQLiteDriver, osDBName.c_str(), papszOGROptions); CSLDestroy(papszOGROptions); } else { hDS = OGROpen(osDBName.c_str(), TRUE, NULL); } CPLSetConfigOption("SQLITE_LIST_ALL_TABLES", osOldVal.c_str()); if (hDS == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot load or create SQLite database"); return NULL; } CPLString osSQL; /* -------------------------------------------------------------------- */ /* Get the SRID for the SRS */ /* -------------------------------------------------------------------- */ int nSRSId = RasterliteInsertSRID(hDS, poSrcDS->GetProjectionRef()); /* -------------------------------------------------------------------- */ /* Create or wipe existing tables */ /* -------------------------------------------------------------------- */ int bWipeExistingData = CSLTestBoolean(CSLFetchNameValueDef(papszOptions, "WIPE", "NO")); hDS = RasterliteCreateTables(hDS, osTableName.c_str(), nSRSId, bWipeExistingData); if (hDS == NULL) return NULL; OGRLayerH hRasterLayer = OGR_DS_GetLayerByName(hDS, osRasterLayer.c_str()); OGRLayerH hMetadataLayer = OGR_DS_GetLayerByName(hDS, osMetatadataLayer.c_str()); if (hRasterLayer == NULL || hMetadataLayer == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot find metadata and/or raster tables"); OGRReleaseDataSource(hDS); return NULL; } /* -------------------------------------------------------------------- */ /* Check if there is overlapping data and warn the user */ /* -------------------------------------------------------------------- */ double minx = adfGeoTransform[0]; double maxx = adfGeoTransform[0] + nXSize * adfGeoTransform[1]; double maxy = adfGeoTransform[3]; double miny = adfGeoTransform[3] + nYSize * adfGeoTransform[5]; osSQL.Printf("SELECT COUNT(geometry) FROM \"%s\" " "WHERE rowid IN " "(SELECT pkid FROM \"idx_%s_metadata_geometry\" " "WHERE xmin < %.15f AND xmax > %.15f " "AND ymin < %.15f AND ymax > %.15f) " "AND pixel_x_size >= %.15f AND pixel_x_size <= %.15f AND " "pixel_y_size >= %.15f AND pixel_y_size <= %.15f", osMetatadataLayer.c_str(), osTableName.c_str(), maxx, minx, maxy, miny, adfGeoTransform[1] - 1e-15, adfGeoTransform[1] + 1e-15, - adfGeoTransform[5] - 1e-15, - adfGeoTransform[5] + 1e-15); int nOverlappingGeoms = 0; OGRLayerH hCountLyr = OGR_DS_ExecuteSQL(hDS, osSQL.c_str(), NULL, NULL); if (hCountLyr) { OGRFeatureH hFeat = OGR_L_GetNextFeature(hCountLyr); if (hFeat) { nOverlappingGeoms = OGR_F_GetFieldAsInteger(hFeat, 0); OGR_F_Destroy(hFeat); } OGR_DS_ReleaseResultSet(hDS, hCountLyr); } if (nOverlappingGeoms != 0) { CPLError(CE_Warning, CPLE_AppDefined, "Raster tiles already exist in the %s table within " "the extent of the data to be inserted in", osTableName.c_str()); } /* -------------------------------------------------------------------- */ /* Iterate over blocks to add data into raster and metadata tables */ /* -------------------------------------------------------------------- */ int nXBlocks = (nXSize + nBlockXSize - 1) / nBlockXSize; int nYBlocks = (nYSize + nBlockYSize - 1) / nBlockYSize; GDALDataType eDataType = poSrcDS->GetRasterBand(1)->GetRasterDataType(); int nDataTypeSize = GDALGetDataTypeSize(eDataType) / 8; GByte* pabyMEMDSBuffer = (GByte*)VSIMalloc3(nBlockXSize, nBlockYSize, nBands * nDataTypeSize); if (pabyMEMDSBuffer == NULL) { OGRReleaseDataSource(hDS); return NULL; } CPLString osTempFileName; osTempFileName.Printf("/vsimem/%p", hDS); int nTileId = 0; int nBlocks = 0; int nTotalBlocks = nXBlocks * nYBlocks; char** papszTileDriverOptions = RasterliteGetTileDriverOptions(papszOptions); OGR_DS_ExecuteSQL(hDS, "BEGIN", NULL, NULL); CPLErr eErr = CE_None; int nBlockXOff, nBlockYOff; for(nBlockYOff=0;eErr == CE_None && nBlockYOff<nYBlocks;nBlockYOff++) { for(nBlockXOff=0;eErr == CE_None && nBlockXOff<nXBlocks;nBlockXOff++) { /* -------------------------------------------------------------------- */ /* Create in-memory tile */ /* -------------------------------------------------------------------- */ int nReqXSize = nBlockXSize, nReqYSize = nBlockYSize; if ((nBlockXOff+1) * nBlockXSize > nXSize) nReqXSize = nXSize - nBlockXOff * nBlockXSize; if ((nBlockYOff+1) * nBlockYSize > nYSize) nReqYSize = nYSize - nBlockYOff * nBlockYSize; eErr = poSrcDS->RasterIO(GF_Read, nBlockXOff * nBlockXSize, nBlockYOff * nBlockYSize, nReqXSize, nReqYSize, pabyMEMDSBuffer, nReqXSize, nReqYSize, eDataType, nBands, NULL, 0, 0, 0); if (eErr != CE_None) { break; } GDALDatasetH hMemDS = GDALCreate(hMemDriver, "MEM:::", nReqXSize, nReqYSize, 0, eDataType, NULL); if (hMemDS == NULL) { eErr = CE_Failure; break; } int iBand; for(iBand = 0; iBand < nBands; iBand ++) { char** papszMEMDSOptions = NULL; char szTmp[64]; memset(szTmp, 0, sizeof(szTmp)); CPLPrintPointer(szTmp, pabyMEMDSBuffer + iBand * nDataTypeSize * nReqXSize * nReqYSize, sizeof(szTmp)); papszMEMDSOptions = CSLSetNameValue(papszMEMDSOptions, "DATAPOINTER", szTmp); GDALAddBand(hMemDS, eDataType, papszMEMDSOptions); CSLDestroy(papszMEMDSOptions); } GDALDatasetH hOutDS = GDALCreateCopy(hTileDriver, osTempFileName.c_str(), hMemDS, FALSE, papszTileDriverOptions, NULL, NULL); GDALClose(hMemDS); if (hOutDS) GDALClose(hOutDS); else { eErr = CE_Failure; break; } /* -------------------------------------------------------------------- */ /* Insert new entry into raster table */ /* -------------------------------------------------------------------- */ vsi_l_offset nDataLength; GByte *pabyData = VSIGetMemFileBuffer( osTempFileName.c_str(), &nDataLength, FALSE); OGRFeatureH hFeat = OGR_F_Create( OGR_L_GetLayerDefn(hRasterLayer) ); OGR_F_SetFieldBinary(hFeat, 0, (int)nDataLength, pabyData); OGR_L_CreateFeature(hRasterLayer, hFeat); /* Query raster ID to set it as the ID of the associated metadata */ int nRasterID = (int)OGR_F_GetFID(hFeat); OGR_F_Destroy(hFeat); VSIUnlink(osTempFileName.c_str()); /* -------------------------------------------------------------------- */ /* Insert new entry into metadata table */ /* -------------------------------------------------------------------- */ hFeat = OGR_F_Create( OGR_L_GetLayerDefn(hMetadataLayer) ); OGR_F_SetFID(hFeat, nRasterID); OGR_F_SetFieldString(hFeat, 0, GDALGetDescription(poSrcDS)); OGR_F_SetFieldInteger(hFeat, 1, nTileId ++); OGR_F_SetFieldInteger(hFeat, 2, nReqXSize); OGR_F_SetFieldInteger(hFeat, 3, nReqYSize); OGR_F_SetFieldDouble(hFeat, 4, adfGeoTransform[1]); OGR_F_SetFieldDouble(hFeat, 5, -adfGeoTransform[5]); minx = adfGeoTransform[0] + (nBlockXSize * nBlockXOff) * adfGeoTransform[1]; maxx = adfGeoTransform[0] + (nBlockXSize * nBlockXOff + nReqXSize) * adfGeoTransform[1]; maxy = adfGeoTransform[3] + (nBlockYSize * nBlockYOff) * adfGeoTransform[5]; miny = adfGeoTransform[3] + (nBlockYSize * nBlockYOff + nReqYSize) * adfGeoTransform[5]; OGRGeometryH hRectangle = OGR_G_CreateGeometry(wkbPolygon); OGRGeometryH hLinearRing = OGR_G_CreateGeometry(wkbLinearRing); OGR_G_AddPoint_2D(hLinearRing, minx, miny); OGR_G_AddPoint_2D(hLinearRing, minx, maxy); OGR_G_AddPoint_2D(hLinearRing, maxx, maxy); OGR_G_AddPoint_2D(hLinearRing, maxx, miny); OGR_G_AddPoint_2D(hLinearRing, minx, miny); OGR_G_AddGeometryDirectly(hRectangle, hLinearRing); OGR_F_SetGeometryDirectly(hFeat, hRectangle); OGR_L_CreateFeature(hMetadataLayer, hFeat); OGR_F_Destroy(hFeat); nBlocks++; if (pfnProgress && !pfnProgress(1.0 * nBlocks / nTotalBlocks, NULL, pProgressData)) eErr = CE_Failure; } } if (eErr == CE_None) OGR_DS_ExecuteSQL(hDS, "COMMIT", NULL, NULL); else OGR_DS_ExecuteSQL(hDS, "ROLLBACK", NULL, NULL); CSLDestroy(papszTileDriverOptions); VSIFree(pabyMEMDSBuffer); OGRReleaseDataSource(hDS); return (GDALDataset*) GDALOpen(pszFilename, GA_Update); }
int main( int argc, char ** argv ) { GDALDatasetH hSrcDS, hDstDS; GDALDataset * poSrcDS, *poDstDS = NULL; int i; int nRasterXSize, nRasterYSize; const char *pszSource=NULL, *pszDest=NULL, *pszFormat = "GTiff"; GDALDriverH hDriver; int *panBandList = NULL, nBandCount = 0, bDefBands = TRUE; GDALDataType eOutputType = GDT_Unknown; int nOXSize = 0, nOYSize = 0; char **papszCreateOptions = NULL; char **papszAsyncOptions = NULL; int anSrcWin[4]; int bQuiet = FALSE; GDALProgressFunc pfnProgress = GDALTermProgress; int iSrcFileArg = -1, iDstFileArg = -1; int bMulti = FALSE; double dfTimeout = -1.0; const char *pszOXSize = NULL, *pszOYSize = NULL; anSrcWin[0] = 0; anSrcWin[1] = 0; anSrcWin[2] = 0; anSrcWin[3] = 0; /* Check strict compilation and runtime library version as we use C++ API */ if (! GDAL_CHECK_VERSION(argv[0])) exit(1); /* -------------------------------------------------------------------- */ /* Register standard GDAL drivers, and process generic GDAL */ /* command options. */ /* -------------------------------------------------------------------- */ GDALAllRegister(); argc = GDALGeneralCmdLineProcessor( argc, &argv, 0 ); if( argc < 1 ) exit( -argc ); /* -------------------------------------------------------------------- */ /* Handle command line arguments. */ /* -------------------------------------------------------------------- */ for( i = 1; i < argc; i++ ) { if( EQUAL(argv[i], "--utility_version") ) { printf("%s was compiled against GDAL %s and is running against GDAL %s\n", argv[0], GDAL_RELEASE_NAME, GDALVersionInfo("RELEASE_NAME")); return 0; } else if( EQUAL(argv[i],"-of") && i < argc-1 ) pszFormat = argv[++i]; else if( EQUAL(argv[i],"-quiet") ) { bQuiet = TRUE; pfnProgress = GDALDummyProgress; } else if( EQUAL(argv[i],"-ot") && i < argc-1 ) { int iType; for( iType = 1; iType < GDT_TypeCount; iType++ ) { if( GDALGetDataTypeName((GDALDataType)iType) != NULL && EQUAL(GDALGetDataTypeName((GDALDataType)iType), argv[i+1]) ) { eOutputType = (GDALDataType) iType; } } if( eOutputType == GDT_Unknown ) { printf( "Unknown output pixel type: %s\n", argv[i+1] ); Usage(); GDALDestroyDriverManager(); exit( 2 ); } i++; } else if( EQUAL(argv[i],"-b") && i < argc-1 ) { if( atoi(argv[i+1]) < 1 ) { printf( "Unrecognizable band number (%s).\n", argv[i+1] ); Usage(); GDALDestroyDriverManager(); exit( 2 ); } nBandCount++; panBandList = (int *) CPLRealloc(panBandList, sizeof(int) * nBandCount); panBandList[nBandCount-1] = atoi(argv[++i]); if( panBandList[nBandCount-1] != nBandCount ) bDefBands = FALSE; } else if( EQUAL(argv[i],"-co") && i < argc-1 ) { papszCreateOptions = CSLAddString( papszCreateOptions, argv[++i] ); } else if( EQUAL(argv[i],"-ao") && i < argc-1 ) { papszAsyncOptions = CSLAddString( papszAsyncOptions, argv[++i] ); } else if( EQUAL(argv[i],"-to") && i < argc-1 ) { dfTimeout = atof(argv[++i] ); } else if( EQUAL(argv[i],"-outsize") && i < argc-2 ) { pszOXSize = argv[++i]; pszOYSize = argv[++i]; } else if( EQUAL(argv[i],"-srcwin") && i < argc-4 ) { anSrcWin[0] = atoi(argv[++i]); anSrcWin[1] = atoi(argv[++i]); anSrcWin[2] = atoi(argv[++i]); anSrcWin[3] = atoi(argv[++i]); } else if( EQUAL(argv[i],"-multi") ) { bMulti = TRUE; } else if( argv[i][0] == '-' ) { printf( "Option %s incomplete, or not recognised.\n\n", argv[i] ); Usage(); GDALDestroyDriverManager(); exit( 2 ); } else if( pszSource == NULL ) { iSrcFileArg = i; pszSource = argv[i]; } else if( pszDest == NULL ) { pszDest = argv[i]; iDstFileArg = i; } else { printf( "Too many command options.\n\n" ); Usage(); GDALDestroyDriverManager(); exit( 2 ); } } if( pszDest == NULL ) { Usage(); GDALDestroyDriverManager(); exit( 10 ); } if ( strcmp(pszSource, pszDest) == 0) { fprintf(stderr, "Source and destination datasets must be different.\n"); GDALDestroyDriverManager(); exit( 1 ); } /* -------------------------------------------------------------------- */ /* Attempt to open source file. */ /* -------------------------------------------------------------------- */ hSrcDS = GDALOpenShared( pszSource, GA_ReadOnly ); poSrcDS = (GDALDataset *) hSrcDS; if( hSrcDS == NULL ) { fprintf( stderr, "GDALOpen failed - %d\n%s\n", CPLGetLastErrorNo(), CPLGetLastErrorMsg() ); GDALDestroyDriverManager(); exit( 1 ); } /* -------------------------------------------------------------------- */ /* Collect some information from the source file. */ /* -------------------------------------------------------------------- */ nRasterXSize = GDALGetRasterXSize( hSrcDS ); nRasterYSize = GDALGetRasterYSize( hSrcDS ); if( !bQuiet ) printf( "Input file size is %d, %d\n", nRasterXSize, nRasterYSize ); if( anSrcWin[2] == 0 && anSrcWin[3] == 0 ) { anSrcWin[2] = nRasterXSize; anSrcWin[3] = nRasterYSize; } /* -------------------------------------------------------------------- */ /* Establish output size. */ /* -------------------------------------------------------------------- */ if( pszOXSize == NULL ) { nOXSize = anSrcWin[2]; nOYSize = anSrcWin[3]; } else { nOXSize = (int) ((pszOXSize[strlen(pszOXSize)-1]=='%' ? atof(pszOXSize)/100*anSrcWin[2] : atoi(pszOXSize))); nOYSize = (int) ((pszOYSize[strlen(pszOYSize)-1]=='%' ? atof(pszOYSize)/100*anSrcWin[3] : atoi(pszOYSize))); } /* -------------------------------------------------------------------- */ /* Build band list to translate */ /* -------------------------------------------------------------------- */ if( nBandCount == 0 ) { nBandCount = GDALGetRasterCount( hSrcDS ); if( nBandCount == 0 ) { fprintf( stderr, "Input file has no bands, and so cannot be translated.\n" ); GDALDestroyDriverManager(); exit(1 ); } panBandList = (int *) CPLMalloc(sizeof(int)*nBandCount); for( i = 0; i < nBandCount; i++ ) panBandList[i] = i+1; } else { for( i = 0; i < nBandCount; i++ ) { if( panBandList[i] < 1 || panBandList[i] > GDALGetRasterCount(hSrcDS) ) { fprintf( stderr, "Band %d requested, but only bands 1 to %d available.\n", panBandList[i], GDALGetRasterCount(hSrcDS) ); GDALDestroyDriverManager(); exit( 2 ); } } if( nBandCount != GDALGetRasterCount( hSrcDS ) ) bDefBands = FALSE; } /* -------------------------------------------------------------------- */ /* Verify source window. */ /* -------------------------------------------------------------------- */ if( anSrcWin[0] < 0 || anSrcWin[1] < 0 || anSrcWin[2] <= 0 || anSrcWin[3] <= 0 || anSrcWin[0] + anSrcWin[2] > GDALGetRasterXSize(hSrcDS) || anSrcWin[1] + anSrcWin[3] > GDALGetRasterYSize(hSrcDS) ) { fprintf( stderr, "-srcwin %d %d %d %d falls outside raster size of %dx%d\n" "or is otherwise illegal.\n", anSrcWin[0], anSrcWin[1], anSrcWin[2], anSrcWin[3], GDALGetRasterXSize(hSrcDS), GDALGetRasterYSize(hSrcDS) ); exit( 1 ); } /* -------------------------------------------------------------------- */ /* Find the output driver. */ /* -------------------------------------------------------------------- */ hDriver = GDALGetDriverByName( pszFormat ); if( hDriver == NULL ) { printf( "Output driver `%s' not recognised.\n", pszFormat ); } else if( GDALGetMetadataItem( hDriver, GDAL_DCAP_CREATE, NULL ) == NULL ) { printf( "Output driver '%s' does not support direct creation.\n", pszFormat ); hDriver = NULL; } if( hDriver == NULL ) { int iDr; printf( "The following format drivers are configured and support output:\n" ); for( iDr = 0; iDr < GDALGetDriverCount(); iDr++ ) { GDALDriverH hDriver = GDALGetDriver(iDr); if( GDALGetMetadataItem( hDriver, GDAL_DCAP_CREATE, NULL ) != NULL ) { printf( " %s: %s\n", GDALGetDriverShortName( hDriver ), GDALGetDriverLongName( hDriver ) ); } } printf( "\n" ); Usage(); GDALClose( hSrcDS ); CPLFree( panBandList ); GDALDestroyDriverManager(); CSLDestroy( argv ); CSLDestroy( papszCreateOptions ); exit( 1 ); } /* -------------------------------------------------------------------- */ /* Establish the pixel data type to use. */ /* -------------------------------------------------------------------- */ if( eOutputType == GDT_Unknown ) eOutputType = poSrcDS->GetRasterBand(1)->GetRasterDataType(); /* -------------------------------------------------------------------- */ /* Allocate one big buffer for the whole imagery area to */ /* transfer. */ /* -------------------------------------------------------------------- */ int nBytesPerPixel = nBandCount * (GDALGetDataTypeSize(eOutputType) / 8); void *pImage = VSIMalloc3( nOXSize, nOYSize, nBytesPerPixel ); if( pImage == NULL ) { printf( "Unable to allocate %dx%dx%d byte window buffer.\n", nOXSize, nOYSize, nBytesPerPixel ); exit( 1 ); } /* -------------------------------------------------------------------- */ /* Establish view window */ /* -------------------------------------------------------------------- */ GDALAsyncReader *poAsyncReq; int nPixelSpace = nBytesPerPixel; int nLineSpace = nBytesPerPixel * nOXSize; int nBandSpace = nBytesPerPixel / nBandCount; poAsyncReq = poSrcDS->BeginAsyncReader( anSrcWin[0], anSrcWin[1], anSrcWin[2], anSrcWin[3], pImage, nOXSize, nOYSize, eOutputType, nBandCount, panBandList, nPixelSpace, nLineSpace, nBandSpace, papszAsyncOptions ); if( poAsyncReq == NULL ) exit( 1 ); /* -------------------------------------------------------------------- */ /* Process until done or an error. */ /* -------------------------------------------------------------------- */ GDALAsyncStatusType eAStatus; CPLErr eErr = CE_None; int iMultiCounter = 0; hDstDS = NULL; do { /* ==================================================================== */ /* Create the output file, and initialize if needed. */ /* ==================================================================== */ if( hDstDS == NULL ) { CPLString osOutFilename = pszDest; if( bMulti ) osOutFilename.Printf( "%s_%d", pszDest, iMultiCounter++ ); hDstDS = GDALCreate( hDriver, osOutFilename, nOXSize, nOYSize, nBandCount, eOutputType, papszCreateOptions ); if (hDstDS == NULL) { exit(1); } poDstDS = (GDALDataset *) hDstDS; /* -------------------------------------------------------------------- */ /* Copy georeferencing. */ /* -------------------------------------------------------------------- */ double adfGeoTransform[6]; if( poSrcDS->GetGeoTransform( adfGeoTransform ) == CE_None ) { adfGeoTransform[0] += anSrcWin[0] * adfGeoTransform[1] + anSrcWin[1] * adfGeoTransform[2]; adfGeoTransform[3] += anSrcWin[0] * adfGeoTransform[4] + anSrcWin[1] * adfGeoTransform[5]; adfGeoTransform[1] *= anSrcWin[2] / (double) nOXSize; adfGeoTransform[2] *= anSrcWin[3] / (double) nOYSize; adfGeoTransform[4] *= anSrcWin[2] / (double) nOXSize; adfGeoTransform[5] *= anSrcWin[3] / (double) nOYSize; poDstDS->SetGeoTransform( adfGeoTransform ); } poDstDS->SetProjection( poSrcDS->GetProjectionRef() ); /* -------------------------------------------------------------------- */ /* Transfer generally applicable metadata. */ /* -------------------------------------------------------------------- */ poDstDS->SetMetadata( poSrcDS->GetMetadata() ); } /* ==================================================================== */ /* Fetch an update and write it to the output file. */ /* ==================================================================== */ int nUpXOff, nUpYOff, nUpXSize, nUpYSize; eAStatus = poAsyncReq->GetNextUpdatedRegion( dfTimeout, &nUpXOff, &nUpYOff, &nUpXSize, &nUpYSize ); if( eAStatus != GARIO_UPDATE && eAStatus != GARIO_COMPLETE ) continue; if( !bQuiet ) { printf( "Got %dx%d @ (%d,%d)\n", nUpXSize, nUpYSize, nUpXOff, nUpYOff ); } poAsyncReq->LockBuffer(); eErr = poDstDS->RasterIO( GF_Write, nUpXOff, nUpYOff, nUpXSize, nUpYSize, ((GByte *) pImage) + nUpXOff * nPixelSpace + nUpYOff * nLineSpace, nUpXSize, nUpYSize, eOutputType, nBandCount, NULL, nPixelSpace, nLineSpace, nBandSpace ); poAsyncReq->UnlockBuffer(); /* -------------------------------------------------------------------- */ /* In multi mode we will close this file and reopen another for */ /* the next request. */ /* -------------------------------------------------------------------- */ if( bMulti ) { GDALClose( hDstDS ); hDstDS = NULL; } else GDALFlushCache( hDstDS ); } while( eAStatus != GARIO_ERROR && eAStatus != GARIO_COMPLETE && eErr == CE_None ); poSrcDS->EndAsyncReader( poAsyncReq ); /* -------------------------------------------------------------------- */ /* Cleanup. */ /* -------------------------------------------------------------------- */ VSIFree( pImage ); if( hDstDS ) GDALClose( hDstDS ); GDALClose( hSrcDS ); CPLFree( panBandList ); CSLDestroy( argv ); CSLDestroy( papszCreateOptions ); CSLDestroy( papszAsyncOptions ); GDALDumpOpenDatasets( stderr ); GDALDestroyDriverManager(); }