예제 #1
0
CPLErr TSXRasterBand::IReadBlock( int nBlockXOff, int nBlockYOff,
                                  void * pImage )
{
    int nRequestYSize;

    /* Check if the last strip is partial so we can avoid over-requesting */
    if ( (nBlockYOff + 1) * nBlockYSize > nRasterYSize ) {
        nRequestYSize = nRasterYSize - nBlockYOff * nBlockYSize;
        memset( pImage, 0, (GDALGetDataTypeSize( eDataType ) / 8) *
            nBlockXSize * nBlockYSize);
    }
    else {
        nRequestYSize = nBlockYSize;
    }

    /* Read Complex Data */
    if ( eDataType == GDT_CInt16 ) {
        return poBand->RasterIO( GF_Read, nBlockXOff * nBlockXSize,
            nBlockYOff * nBlockYSize, nBlockXSize, nRequestYSize,
            pImage, nBlockXSize, nRequestYSize, GDT_CInt16, 1, NULL, 4,
            nBlockXSize * 4, 0, NULL );
    }

    // Detected Product
    return poBand->RasterIO( GF_Read, nBlockXOff * nBlockXSize,
                             nBlockYOff * nBlockYSize, nBlockXSize,
                             nRequestYSize, pImage, nBlockXSize, nRequestYSize,
                             GDT_UInt16, 1, NULL, 2, nBlockXSize * 2, 0, NULL );
}
예제 #2
0
파일: Tif_band.cpp 프로젝트: zjucsxxd/mrf
// Read from a RAM Tiff. This is rather generic
CPLErr DecompressTIF(buf_mgr &dst, buf_mgr &src, const ILImage &img)
{
    CPLString fname = uniq_memfname("mrf_tif_read");
    VSILFILE *fp = VSIFileFromMemBuffer(fname, (GByte *)(src.buffer), src.size, false);
    // Comes back opened, but we can't use it
    if (fp)
	VSIFCloseL(fp);
    else {
	CPLError(CE_Failure,CPLE_AppDefined,
	    CPLString().Printf("MRF: TIFF, can't open %s as a temp file", fname.c_str()));
        return CE_Failure;
    }
    GDALDataset *poTiff = reinterpret_cast<GDALDataset*>(GDALOpen(fname, GA_ReadOnly));
    if (!fp) {
	CPLError(CE_Failure,CPLE_AppDefined,
	    CPLString().Printf("MRF: TIFF, can't open page as a Tiff"));
        return CE_Failure;
    }

    CPLErr ret;
    // Bypass the GDAL caching
    if (img.pagesize.c == 1) {
	ret = poTiff->GetRasterBand(1)->ReadBlock(0,0,dst.buffer);
    } else {
	ret = poTiff->RasterIO(GF_Read,0,0,img.pagesize.x,img.pagesize.y, 
	    dst.buffer, img.pagesize.x, img.pagesize.y, img.dt, img.pagesize.c, 
	    NULL, 0,0,0);
    }
    GDALClose(poTiff);
    if (CE_None != ret)
	return ret;

    VSIUnlink(fname);
    return CE_None;
}
예제 #3
0
CPLErr GDALOverviewDataset::IRasterIO( GDALRWFlag eRWFlag,
                                       int nXOff, int nYOff, int nXSize, int nYSize,
                                       void * pData, int nBufXSize, int nBufYSize,
                                       GDALDataType eBufType,
                                       int nBandCount, int *panBandMap,
                                       GSpacing nPixelSpace, GSpacing nLineSpace,
                                       GSpacing nBandSpace,
                                       GDALRasterIOExtraArg* psExtraArg)

{
    int iBandIndex;
    CPLErr eErr = CE_None;

    /* In case the overview bands are really linked to a dataset, then issue */
    /* the request to that dataset */
    if( poOvrDS != NULL )
    {
        return poOvrDS->RasterIO(
                   eRWFlag, nXOff, nYOff, nXSize, nYSize, pData, nBufXSize, nBufYSize,
                   eBufType, nBandCount, panBandMap, nPixelSpace, nLineSpace, nBandSpace,
                   psExtraArg);
    }

    GDALProgressFunc  pfnProgressGlobal = psExtraArg->pfnProgress;
    void             *pProgressDataGlobal = psExtraArg->pProgressData;

    for( iBandIndex = 0;
            iBandIndex < nBandCount && eErr == CE_None;
            iBandIndex++ )
    {
        GDALOverviewBand *poBand = (GDALOverviewBand*) GetRasterBand(panBandMap[iBandIndex]);
        GByte *pabyBandData;

        if (poBand == NULL)
        {
            eErr = CE_Failure;
            break;
        }

        pabyBandData = ((GByte *) pData) + iBandIndex * nBandSpace;

        psExtraArg->pfnProgress = GDALScaledProgress;
        psExtraArg->pProgressData =
            GDALCreateScaledProgress( 1.0 * iBandIndex / nBandCount,
                                      1.0 * (iBandIndex + 1) / nBandCount,
                                      pfnProgressGlobal,
                                      pProgressDataGlobal );

        eErr = poBand->IRasterIO( eRWFlag, nXOff, nYOff, nXSize, nYSize,
                                  (void *) pabyBandData, nBufXSize, nBufYSize,
                                  eBufType, nPixelSpace, nLineSpace, psExtraArg );

        GDALDestroyScaledProgress( psExtraArg->pProgressData );
    }

    psExtraArg->pfnProgress = pfnProgressGlobal;
    psExtraArg->pProgressData = pProgressDataGlobal;

    return eErr;
}
예제 #4
0
//
// Uses GDAL to create a temporary TIF file, using the band create options
// copies the content to the destination buffer then erases the temp TIF
//
static CPLErr CompressTIF(buf_mgr &dst, buf_mgr &src, const ILImage &img, char **papszOptions)
{
    CPLErr ret;
    GDALDriver *poTiffDriver = GetGDALDriverManager()->GetDriverByName("GTiff");
    VSIStatBufL statb;
    CPLString fname = uniq_memfname("mrf_tif_write");

    GDALDataset *poTiff = poTiffDriver->Create(fname, img.pagesize.x, img.pagesize.y,
                                               img.pagesize.c, img.dt, papszOptions );

    // Read directly to avoid double caching in GDAL
    // Unfortunately not possible for multiple bands
    if (img.pagesize.c == 1) {
        ret = poTiff->GetRasterBand(1)->WriteBlock(0,0,src.buffer);
    } else {
        ret = poTiff->RasterIO(GF_Write, 0,0,img.pagesize.x,img.pagesize.y,
            src.buffer, img.pagesize.x, img.pagesize.y, img.dt, img.pagesize.c,
            NULL, 0,0,0
#if GDAL_VERSION_MAJOR >= 2
            ,NULL
#endif
            );
    }
    if (CE_None != ret) return ret;
    GDALClose(poTiff);

    // Check that we can read the file
    if (VSIStatL(fname, &statb))
    {
        CPLError(CE_Failure,CPLE_AppDefined,
            "MRF: TIFF, can't stat %s", fname.c_str());
        return CE_Failure;
    }

    if (size_t(statb.st_size) > dst.size)
    {
        CPLError(CE_Failure,CPLE_AppDefined,
            "MRF: TIFF, Tiff generated is too large");
        return CE_Failure;
    }

    VSILFILE *pf = VSIFOpenL(fname,"rb");
    if (pf == NULL)
    {
        CPLError(CE_Failure,CPLE_AppDefined,
            "MRF: TIFF, can't open %s", fname.c_str());
        return CE_Failure;
    }

    VSIFReadL(dst.buffer, static_cast<size_t>(statb.st_size), 1, pf);
    dst.size = static_cast<size_t>(statb.st_size);
    VSIFCloseL(pf);
    VSIUnlink(fname);

    return CE_None;
}
예제 #5
0
static GDALDataset*
createDataSetFromImage(const osg::Image* image, double minX, double minY, double maxX, double maxY, const std::string &projection)
{
    //Clone the incoming image
    osg::ref_ptr<osg::Image> clonedImage = new osg::Image(*image);

    //Flip the image
    clonedImage->flipVertical();  

    GDALDataset* srcDS = createMemDS(image->s(), image->t(), minX, minY, maxX, maxY, projection);

    //Write the image data into the memory dataset
    //If the image is already RGBA, just read all 4 bands in one call
    if (image->getPixelFormat() == GL_RGBA)
    {
        srcDS->RasterIO(GF_Write, 0, 0, clonedImage->s(), clonedImage->t(), (void*)clonedImage->data(), clonedImage->s(), clonedImage->t(), GDT_Byte, 4, NULL, 4, 4 * image->s(), 1);
    }
    else if (image->getPixelFormat() == GL_RGB)
    {    
        //OE_NOTICE << "[osgEarth::GeoData] Reprojecting RGB " << std::endl;
        //Read the read, green and blue bands
        srcDS->RasterIO(GF_Write, 0, 0, clonedImage->s(), clonedImage->t(), (void*)clonedImage->data(), clonedImage->s(), clonedImage->t(), GDT_Byte, 3, NULL, 3, 3 * image->s(), 1);

        //Initialize the alpha values to 255.
        unsigned char *alpha = new unsigned char[clonedImage->s() * clonedImage->t()];
        memset(alpha, 255, clonedImage->s() * clonedImage->t());

        GDALRasterBand* alphaBand = srcDS->GetRasterBand(4);
        alphaBand->RasterIO(GF_Write, 0, 0, clonedImage->s(), clonedImage->t(), alpha, clonedImage->s(),clonedImage->t(), GDT_Byte, 0, 0);

        delete[] alpha;
    }
    else
    {
        OE_WARN << LC << "createDataSetFromImage: unsupported pixel format " << std::hex << image->getPixelFormat() << std::endl;
    }
    srcDS->FlushCache();

    return srcDS;
}
예제 #6
0
// Read from a RAM Tiff. This is rather generic
static CPLErr DecompressTIF(buf_mgr &dst, buf_mgr &src, const ILImage &img)
{
    CPLString fname = uniq_memfname("mrf_tif_read");
    VSILFILE *fp = VSIFileFromMemBuffer(fname, (GByte *)(src.buffer), src.size, false);
    // Comes back opened, but we can't use it
    if (fp)
        VSIFCloseL(fp);
    else {
        CPLError(CE_Failure,CPLE_AppDefined,
            "MRF: TIFF, can't open %s as a temp file", fname.c_str());
        return CE_Failure;
    }
#if GDAL_VERSION_MAJOR >= 2
    const char* const apszAllowedDrivers[] = { "GTiff", NULL };
    GDALDataset *poTiff = reinterpret_cast<GDALDataset*>(GDALOpenEx(fname, GDAL_OF_RASTER, apszAllowedDrivers, NULL, NULL));
#else
    GDALDataset *poTiff = reinterpret_cast<GDALDataset*>(GDALOpen(fname, GA_ReadOnly));
#endif
    if (poTiff == NULL) {
        CPLError(CE_Failure,CPLE_AppDefined,
            "MRF: TIFF, can't open page as a Tiff");
        VSIUnlink(fname);
        return CE_Failure;
    }

    CPLErr ret;
    // Bypass the GDAL caching
    if (img.pagesize.c == 1) {
        ret = poTiff->GetRasterBand(1)->ReadBlock(0,0,dst.buffer);
    } else {
        ret = poTiff->RasterIO(GF_Read,0,0,img.pagesize.x,img.pagesize.y,
            dst.buffer, img.pagesize.x, img.pagesize.y, img.dt, img.pagesize.c,
            NULL, 0,0,0
#if GDAL_VERSION_MAJOR >= 2
            ,NULL
#endif
            );
    }
    GDALClose(poTiff);
    VSIUnlink(fname);

    return ret;
}
예제 #7
0
CPLErr PDSDataset::IRasterIO( GDALRWFlag eRWFlag,
                              int nXOff, int nYOff, int nXSize, int nYSize,
                              void * pData, int nBufXSize, int nBufYSize,
                              GDALDataType eBufType, 
                              int nBandCount, int *panBandMap,
                              int nPixelSpace, int nLineSpace, int nBandSpace)

{
    if( poCompressedDS != NULL )
        return poCompressedDS->RasterIO( eRWFlag, 
                                         nXOff, nYOff, nXSize, nYSize, 
                                         pData, nBufXSize, nBufYSize, 
                                         eBufType, nBandCount, panBandMap,
                                         nPixelSpace, nLineSpace, nBandSpace );
    else
        return RawDataset::IRasterIO( eRWFlag, 
                                      nXOff, nYOff, nXSize, nYSize, 
                                      pData, nBufXSize, nBufYSize, 
                                      eBufType, nBandCount, panBandMap,
                                      nPixelSpace, nLineSpace, nBandSpace );
}
예제 #8
0
int setImageLayerMemoryBuffer(InterColComm * icComm, char const * imageFile, ImageFromMemoryBuffer * imageLayer, uint8_t ** imageBufferPtr, size_t * imageBufferSizePtr)
{
   // Under MPI, only the root process (rank==0) uses imageFile, imageBufferPtr, or imageBufferSizePtr, but nonroot processes need to call it as well,
   // because the imegeBuffer is scattered to all processes during the call to ImageFromMemoryBuffer::setMemoryBuffer().
   int layerNx = imageLayer->getLayerLoc()->nxGlobal;
   int layerNy = imageLayer->getLayerLoc()->nyGlobal;
   int layerNf = imageLayer->getLayerLoc()->nf;
   int bufferNx, bufferNy, bufferNf;
   const uint8_t zeroVal = (uint8_t) 0;
   const uint8_t oneVal = (uint8_t) 255;
   int xStride, yStride, bandStride;
   int rank = icComm->commRank();
   if (rank==0) {
      // Doubleplusungood: much code duplication from PV::Image::readImage
      bool usingTempFile = false;
      char * path = NULL;
      if (strstr(imageFile, "://") != NULL) {
         printf("Image from URL \"%s\"\n", imageFile);
         usingTempFile = true;
         std::string pathstring = "/tmp/temp.XXXXXX";
         const char * ext = strrchr(imageFile, '.');
         if (ext) { pathstring += ext; }
         path = strdup(pathstring.c_str());
         int fid;
         fid=mkstemps(path, strlen(ext));
         if (fid<0) {
            fprintf(stderr,"Cannot create temp image file for image \"%s\".\n", imageFile);
            exit(EXIT_FAILURE);
         }   
         close(fid);
         std::string systemstring;
         if (strstr(imageFile, "s3://") != NULL) {
            systemstring = "aws s3 cp \'";
            systemstring += imageFile;
            systemstring += "\' ";
            systemstring += path;
         }   
         else { // URLs other than s3://
            systemstring = "wget -O ";
            systemstring += path;
            systemstring += " \'";
            systemstring += imageFile;
            systemstring += "\'";
         }   

         int const numAttempts = MAX_FILESYSTEMCALL_TRIES;
         for(int attemptNum = 0; attemptNum < numAttempts; attemptNum++){
            int status = system(systemstring.c_str());
            if(status != 0){ 
               if(attemptNum == numAttempts - 1){ 
                  fprintf(stderr, "download command \"%s\" failed: %s.  Exiting\n", systemstring.c_str(), strerror(errno));
                  exit(EXIT_FAILURE);
               }   
               else{
                  fprintf(stderr, "download command \"%s\" failed: %s.  Retrying %d out of %d.\n", systemstring.c_str(), strerror(errno), attemptNum+1, numAttempts);
                  sleep(1);
               }
            }
            else{
               break;
            }
         }
      }
      else {
         printf("Image from file \"%s\"\n", imageFile);
         path = strdup(imageFile);
      }
      GDALDataset * gdalDataset = PV_GDALOpen(path);
      if (gdalDataset==NULL)
      {
         fprintf(stderr, "setImageLayerMemoryBuffer: GDALOpen failed for image \"%s\".\n", imageFile);
         exit(EXIT_FAILURE);
      }
      int imageNx= gdalDataset->GetRasterXSize();
      int imageNy = gdalDataset->GetRasterYSize();
      int imageNf = GDALGetRasterCount(gdalDataset);
      // Need to rescale so that the the short side of the image equals the short side of the layer
      // ImageFromMemoryBuffer layer will handle the cropping.
      double xScaleFactor = (double)layerNx / (double) imageNx;
      double yScaleFactor = (double)layerNy / (double) imageNy;
      size_t imageBufferSize = *imageBufferSizePtr;
      uint8_t * imageBuffer = *imageBufferPtr;
      if (xScaleFactor < yScaleFactor) /* need to rescale so that bufferNy=layerNy and bufferNx>layerNx */
      {
         bufferNx = (int) round(imageNx * yScaleFactor);
         bufferNy = layerNy;
      }
      else {
         bufferNx = layerNx;
         bufferNy = (int) round(imageNy * xScaleFactor);
      }
      bufferNf = layerNf;
      size_t newImageBufferSize = (size_t)bufferNx * (size_t)bufferNy * (size_t)bufferNf;
      if (imageBuffer==NULL || newImageBufferSize != imageBufferSize)
      {
         imageBufferSize = newImageBufferSize;
         imageBuffer = (uint8_t *) realloc(imageBuffer, imageBufferSize*sizeof(uint8_t));
         if (imageBuffer==NULL)
         {
            fprintf(stderr, "setImageLayerMemoryBuffer: Unable to resize image buffer to %d-by-%d-by-%d for image \"%s\": %s\n",
                  bufferNx, bufferNy, bufferNf, imageFile, strerror(errno));
            exit(EXIT_FAILURE);
         }
      }

      bool isBinary = true;
      for (int iBand=0;iBand<imageNf; iBand++)
      {
         GDALRasterBandH hBand = GDALGetRasterBand(gdalDataset,iBand+1);
         char ** metadata = GDALGetMetadata(hBand, "Image_Structure");
         if(CSLCount(metadata) > 0){
            bool found = false;
            for(int i = 0; metadata[i] != NULL; i++){
               if(strcmp(metadata[i], "NBITS=1") == 0){
                  found = true;
                  isBinary &= true;
                  break;
               }
            }
            if(!found){
               isBinary &= false;
            }
         }
         else{
            isBinary = false;
         }
         GDALDataType dataType = gdalDataset->GetRasterBand(iBand+1)->GetRasterDataType(); // Why are we using both GDALGetRasterBand and GDALDataset::GetRasterBand?
         if (dataType != GDT_Byte)
         {
            fprintf(stderr, "setImageLayerMemoryBuffer: Image file \"%s\", band %d, is not GDT_Byte type.\n", imageFile, iBand+1);
            exit(EXIT_FAILURE);
         }
      }

#ifdef PV_USE_OPENMP_THREADS
#pragma omp parallel for
#endif
      for (size_t n=0; n < imageBufferSize; n++)
      {
         imageBuffer[n] = oneVal;
      }

      xStride = bufferNf;
      yStride = bufferNf * bufferNx;
      bandStride = 1;
      gdalDataset->RasterIO(GF_Read, 0/*xOffset*/, 0/*yOffset*/, imageNx, imageNy, imageBuffer, bufferNx, bufferNy,
            GDT_Byte, layerNf, NULL, xStride*sizeof(uint8_t), yStride*sizeof(uint8_t), bandStride*sizeof(uint8_t));

      GDALClose(gdalDataset);
      if (usingTempFile) {
         int rmstatus = remove(path);
         if (rmstatus) {
            fprintf(stderr, "remove(\"%s\") failed.  Exiting.\n", path);
            exit(EXIT_FAILURE);
         }    
      }
      free(path);

      *imageBufferPtr = imageBuffer;
      *imageBufferSizePtr = imageBufferSize;

      int buffersize[3];
      buffersize[0] = bufferNx;
      buffersize[1] = bufferNy;
      buffersize[2] = bufferNf;
      MPI_Bcast(buffersize, 3, MPI_INT, 0, icComm->communicator());
   }
   else {
      int buffersize[3];
      MPI_Bcast(buffersize, 3, MPI_INT, 0, icComm->communicator());
      bufferNx = buffersize[0];
      bufferNy = buffersize[1];
      bufferNf = buffersize[2];
      xStride = bufferNf;
      yStride = bufferNf * bufferNx;
      bandStride = 1;
   }
   imageLayer->setMemoryBuffer(*imageBufferPtr, bufferNy, bufferNx, bufferNf, xStride, yStride, bandStride, zeroVal, oneVal);
   return PV_SUCCESS;
}
예제 #9
0
int Image::scatterImageFileGDAL(const char * filename, int xOffset, int yOffset,
                         PV::Communicator * comm, const PVLayerLoc * loc, float * buf, bool autoResizeFlag)
{
   int status = 0;

#ifdef PV_USE_GDAL
   // const int maxBands = 3;

   const int nxProcs = comm->numCommColumns();
   const int nyProcs = comm->numCommRows();

   const int icRank = comm->commRank();

   const int nx = loc->nx;
   const int ny = loc->ny;

   const int numBands = loc->nf;
   int numTotal; // will be nx*ny*bandsInFile;

   const MPI_Comm mpi_comm = comm->communicator();
   GDALDataType dataType;
   char** metadata;
   char isBinary = true;

   if (icRank > 0) {
#ifdef PV_USE_MPI
      const int src = 0;
      const int tag = 13;

      MPI_Bcast(&dataType, 1, MPI_INT, 0, mpi_comm);
      MPI_Bcast(&isBinary, 1, MPI_CHAR, 0, mpi_comm);
      MPI_Bcast(&numTotal, 1, MPI_INT, 0, mpi_comm);
#ifdef DEBUG_OUTPUT
      fprintf(stderr, "[%2d]: scatterImageFileGDAL: received from 0, total number of bytes in buffer is %d\n", numTotal);
#endif // DEBUG_OUTPUT
      MPI_Recv(buf, numTotal, MPI_FLOAT, src, tag, mpi_comm, MPI_STATUS_IGNORE);
#ifdef DEBUG_OUTPUT
      int nf=numTotal/(nx*ny);
      assert( nf*nx*ny == numTotal );
      fprintf(stderr, "[%2d]: scatterImageFileGDAL: received from 0, nx==%d ny==%d nf==%d size==%d\n",
              comm->commRank(), nx, ny, nf, numTotal);
#endif // DEBUG_OUTPUT
#endif // PV_USE_MPI
   }
   else {
      GDALAllRegister();

      GDALDataset * dataset = PV_GDALOpen(filename); // (GDALDataset *) GDALOpen(filename, GA_ReadOnly);
      GDALRasterBand * poBand = dataset->GetRasterBand(1);
      dataType = poBand->GetRasterDataType();
#ifdef PV_USE_MPI
      MPI_Bcast(&dataType, 1, MPI_INT, 0, mpi_comm);
#endif // PV_USE_MPI

      // GDAL defines whether a band is binary, not whether the image as a whole is binary.
      // Set isBinary to false if any band is not binary (metadata doesn't have NBITS=1)
      for(int iBand = 0; iBand < GDALGetRasterCount(dataset); iBand++){
         GDALRasterBandH hBand = GDALGetRasterBand(dataset, iBand+1);
         metadata = GDALGetMetadata(hBand, "Image_Structure");
         if(CSLCount(metadata) > 0){
            bool found = false;
            for(int i = 0; metadata[i] != NULL; i++){
               if(strcmp(metadata[i], "NBITS=1") == 0){
                  found = true;
                  break;
               }
            }
            if(!found){
               isBinary = false;
            }
         }
         else{
            isBinary = false;
         }
      }
#ifdef PV_USE_MPI
      MPI_Bcast(&isBinary, 1, MPI_CHAR, 0, mpi_comm);
#endif // PV_USE_MPI

      if (dataset==NULL) return 1; // PV_GDALOpen prints an error message.
      int xImageSize = dataset->GetRasterXSize();
      int yImageSize = dataset->GetRasterYSize();
      const int bandsInFile = dataset->GetRasterCount();

      numTotal = nx * ny * bandsInFile;
#ifdef PV_USE_MPI
#ifdef DEBUG_OUTPUT
      fprintf(stderr, "[%2d]: scatterImageFileGDAL: broadcast from 0, total number of bytes in buffer is %d\n", numTotal);
#endif // DEBUG_OUTPUT
      MPI_Bcast(&numTotal, 1, MPI_INT, 0, mpi_comm);
#endif // PV_USE_MPI

      int xTotalSize = nx * nxProcs;
      int yTotalSize = ny * nyProcs;

      // if nf > bands of image, it will copy the gray image to each
      //band of layer
      assert(numBands == 1 || numBands == bandsInFile || (numBands > 1 && bandsInFile == 1));

      int dest = -1;
      const int tag = 13;

      float padValue_conv;
      if(dataType == GDT_Byte){
         padValue_conv = padValue * 255.0f;
      }
      else if(dataType == GDT_UInt16){
         padValue_conv = padValue * 65535.0f;
      }
      else{
         std::cout << "Image data type " << GDALGetDataTypeName(dataType) << " not implemented for image rescaling\n";
         exit(-1);
      }

      using std::min;
      using std::max;
      for( dest = nyProcs*nxProcs-1; dest >= 0; dest-- ) {

         //Need to clear buffer before reading, since we're skipping some of the buffer
#ifdef PV_USE_OPENMP_THREADS
#pragma omp parallel for
#endif
         for(int i = 0; i < nx * ny * bandsInFile; i++){ 
            //Fill with padValue
            buf[i] = padValue_conv;
         }


         int col = columnFromRank(dest,nyProcs,nxProcs);
         int row = rowFromRank(dest,nyProcs,nxProcs);
         int kx = nx * col;
         int ky = ny * row;


         //? For the auto resize flag, PV checks which side (x or y) is the shortest, relative to the
         //? hypercolumn size specified.  Then it determines the largest chunk it can possibly take
         //? from the image with the correct aspect ratio determined by hypercolumn.  It then
         //? determines the offset needed in the long dimension to center the cropped image,
         //? and reads in that portion of the image.  The offset can optionally be translated by
         //? offset{X,Y} specified in the params file (values can be positive or negative).
         //? If the specified offset takes the cropped image outside the image file, it uses the
         //? largest-magnitude offset that stays within the image file's borders.

         if (autoResizeFlag){

            if (xImageSize/(double)xTotalSize < yImageSize/(double)yTotalSize){
               int new_y = int(round(ny*xImageSize/(double)xTotalSize));
               int y_off = int(round((yImageSize - new_y*nyProcs)/2.0));

               int jitter_y = max(min(y_off,yOffset),-y_off);

               kx = xImageSize/nxProcs * col;
               ky = new_y * row;

               //fprintf(stderr, "kx = %d, ky = %d, nx = %d, new_y = %d", kx, ky, xImageSize/nxProcs, new_y);

               dataset->RasterIO(GF_Read, kx, ky + y_off + jitter_y, xImageSize/nxProcs, new_y, buf, nx, ny,
                     GDT_Float32, bandsInFile, NULL, bandsInFile*sizeof(float),
                     bandsInFile*nx*sizeof(float), sizeof(float));
            }
            else{
               int new_x = int(round(nx*yImageSize/(double)yTotalSize));
               int x_off = int(round((xImageSize - new_x*nxProcs)/2.0));

               int jitter_x = max(min(x_off,xOffset),-x_off);

               kx = new_x * col;
               ky = yImageSize/nyProcs * row;

               //fprintf(stderr, "kx = %d, ky = %d, new_x = %d, ny = %d, x_off = %d", kx, ky, new_x, yImageSize/nyProcs, x_off);
               dataset->RasterIO(GF_Read, kx + x_off + jitter_x, ky, new_x, yImageSize/nyProcs, buf, nx, ny,
                     GDT_Float32, bandsInFile, NULL, bandsInFile*sizeof(float),
                     bandsInFile*nx*sizeof(float),sizeof(float));
            }
         }//End autoResizeFlag
         else {
            //Need to calculate corner image pixels in globalres space
            //offset is in Image space
            int img_left = -xOffset;
            int img_top = -yOffset;
            int img_right = img_left + xImageSize;
            int img_bot = img_top + yImageSize;

            //Check if in bounds
            if(img_left >= kx+nx || img_right <= kx || img_top >= ky+ny || img_bot <= ky){
               //Do mpi_send to keep number of sends correct
               if(dest > 0){
                  MPI_Send(buf, numTotal, MPI_FLOAT, dest, tag, mpi_comm);
               }
               continue;
            }


            //start of the buffer on the left/top side
            int buf_left = img_left > kx ? img_left-kx : 0;
            int buf_top = img_top > ky ? img_top-ky : 0;
            int buf_right = img_right < kx+nx ? img_right-kx : nx;
            int buf_bot = img_bot < ky+ny ? img_bot-ky : ny;

            int buf_xSize = buf_right - buf_left; 
            int buf_ySize = buf_bot - buf_top;
            assert(buf_xSize > 0 && buf_ySize > 0);

            int buf_offset = buf_top * nx * bandsInFile + buf_left * bandsInFile;

            int img_offset_x = kx+xOffset;
            int img_offset_y = ky+yOffset;
            if(img_offset_x < 0){
               img_offset_x = 0;
            }
            if(img_offset_y < 0){
               img_offset_y = 0;
            }

            float* buf_start = buf + buf_offset;

            dataset->RasterIO(GF_Read, img_offset_x, img_offset_y, buf_xSize, buf_ySize, buf_start,
                  buf_xSize,
                  buf_ySize, GDT_Float32, bandsInFile, NULL,
                  bandsInFile*sizeof(float), bandsInFile*nx*sizeof(float), sizeof(float));

         }
#ifdef DEBUG_OUTPUT
         fprintf(stderr, "[%2d]: scatterImageFileGDAL: sending to %d xSize==%d"
               " ySize==%d bandsInFile==%d size==%d total(over all procs)==%d\n",
               comm->commRank(), dest, nx, ny, bandsInFile, numTotal,
               nx*ny*comm->commSize());
#endif // DEBUG_OUTPUT

#ifdef PV_USE_MPI
         if(dest > 0){
            MPI_Send(buf, numTotal, MPI_FLOAT, dest, tag, mpi_comm);
         }
#endif // PV_USE_MPI
      }

      GDALClose(dataset);

      //Moved to above for loop
      // get local image portion

      //? same logic as before, except this time we know that the row and column are 0

      //if (autoResizeFlag){

      //   if (xImageSize/(double)xTotalSize < yImageSize/(double)yTotalSize){
      //      int new_y = int(round(ny*xImageSize/(double)xTotalSize));
      //      int y_off = int(round((yImageSize - new_y*nyProcs)/2.0));

      //      int offset_y = max(min(y_off,yOffset),-y_off);

      //      //fprintf(stderr, "kx = %d, ky = %d, nx = %d, new_y = %d", 0, 0, xImageSize/nxProcs, new_y);
      //      dataset->RasterIO(GF_Read, 0, y_off + offset_y, xImageSize/nxProcs, new_y, buf, nx, ny,
      //                        GDT_Float32, bandsInFile, NULL, bandsInFile*sizeof(float),
      //                        bandsInFile*nx*sizeof(float), sizeof(float));
      //   }
      //   else{
      //      int new_x = int(round(nx*yImageSize/(double)yTotalSize));
      //      int x_off = int(round((xImageSize - new_x*nxProcs)/2.0));

      //      int offset_x = max(min(x_off,xOffset),-x_off);

      //      //fprintf(stderr, "xImageSize = %d, xTotalSize = %d, yImageSize = %d, yTotalSize = %d", xImageSize, xTotalSize, yImageSize, yTotalSize);
      //      //fprintf(stderr, "kx = %d, ky = %d, new_x = %d, ny = %d",
      //      //0, 0, new_x, yImageSize/nyProcs);
      //      dataset->RasterIO(GF_Read, x_off + offset_x, 0, new_x, yImageSize/nyProcs, buf, nx, ny,
      //                        GDT_Float32, bandsInFile, NULL, bandsInFile*sizeof(float),
      //                        bandsInFile*nx*sizeof(float),sizeof(float));
      //   }
      //}
      //else {

      //   //fprintf(stderr,"just checking");
      //    dataset->RasterIO(GF_Read, xOffset, yOffset, nx, ny, buf, nx, ny,
      //                      GDT_Float32, bandsInFile, NULL, bandsInFile*sizeof(float), bandsInFile*nx*sizeof(float), sizeof(float));
      //}

      //GDALClose(dataset);
   }
#else
   fprintf(stderr, GDAL_CONFIG_ERR_STR);
   exit(1);
#endif // PV_USE_GDAL

   if (status == 0) {
      if(!isBinary){
         float fac;
         if(dataType == GDT_Byte){
            fac = 1.0f / 255.0f;  // normalize to 1.0
         }
         else if(dataType == GDT_UInt16){
            fac = 1.0f / 65535.0f;  // normalize to 1.0
         }
         else{
            std::cout << "Image data type " << GDALGetDataTypeName(dataType) << " not implemented for image rescaling\n";
            exit(-1);
         }
         for( int n=0; n<numTotal; n++ ) {
            buf[n] *= fac;
         }
      }
   }
   return status;
}
예제 #10
0
int main(int argc, char* argv[])
{
    int i;
    int nThreads = CPLGetNumCPUs();
    std::vector<CPLJoinableThread*> apsThreads;
    Strategy eStrategy = STRATEGY_RANDOM;
    int bNewDatasetOption = FALSE;
    int nXSize = 5000;
    int nYSize = 5000;
    int nBands = 4;
    char** papszOptions = NULL;
    int bOnDisk = FALSE;
    std::vector<ThreadDescription> asThreadDescription;
    int bMemDriver = FALSE;
    GDALDataset* poMEMDS = NULL;
    int bMigrate = FALSE;
    int nMaxRequests = -1;

    argc = GDALGeneralCmdLineProcessor( argc, &argv, 0 );

    GDALAllRegister();

    for(i = 1; i < argc; i++)
    {
        if( EQUAL(argv[i], "-threads") && i + 1 < argc)
        {
            i ++;
            nThreads = atoi(argv[i]);
        }
        else if( EQUAL(argv[i], "-loops") && i + 1 < argc)
        {
            i ++;
            nLoops = atoi(argv[i]);
            if( nLoops <= 0 )
                nLoops = INT_MAX;
        }
        else if( EQUAL(argv[i], "-max_requests") && i + 1 < argc)
        {
            i ++;
            nMaxRequests = atoi(argv[i]);
        }
        else if( EQUAL(argv[i], "-strategy") && i + 1 < argc)
        {
            i ++;
            if( EQUAL(argv[i], "random") )
                eStrategy = STRATEGY_RANDOM;
            else if( EQUAL(argv[i], "line") )
                eStrategy = STRATEGY_LINE;
            else if( EQUAL(argv[i], "block") )
                eStrategy = STRATEGY_BLOCK;
            else
                Usage();
        }
        else if( EQUAL(argv[i], "-xsize") && i + 1 < argc)
        {
            i ++;
            nXSize = atoi(argv[i]);
            bNewDatasetOption = TRUE;
        }
        else if( EQUAL(argv[i], "-ysize") && i + 1 < argc)
        {
            i ++;
            nYSize = atoi(argv[i]);
            bNewDatasetOption = TRUE;
        }
        else if( EQUAL(argv[i], "-bands") && i + 1 < argc)
        {
            i ++;
            nBands = atoi(argv[i]);
            bNewDatasetOption = TRUE;
        }
        else if( EQUAL(argv[i], "-co") && i + 1 < argc)
        {
            i ++;
            papszOptions = CSLAddString(papszOptions, argv[i]);
            bNewDatasetOption = TRUE;
        }
        else if( EQUAL(argv[i], "-ondisk"))
        {
            bOnDisk = TRUE;
            bNewDatasetOption = TRUE;
        }
        else if( EQUAL(argv[i], "-check"))
        {
            bCheck = TRUE;
            bNewDatasetOption = TRUE;
        }
        else if( EQUAL(argv[i], "-memdriver"))
        {
            bMemDriver = TRUE;
            bNewDatasetOption = TRUE;
        }
        else if( EQUAL(argv[i], "-migrate"))
            bMigrate = TRUE;
        else if( argv[i][0] == '-' )
            Usage();
        else if( pszDataset == NULL )
            pszDataset = argv[i];
        else
        {
            Usage();
        }
    }

    if( pszDataset != NULL && bNewDatasetOption )
        Usage();

    CPLDebug("TEST", "Using %d threads", nThreads);

    int bCreatedDataset = FALSE;
    if( pszDataset == NULL )
    {
        bCreatedDataset = TRUE;
        if( bOnDisk )
            pszDataset = "/tmp/tmp.tif";
        else
            pszDataset = "/vsimem/tmp.tif";
        GDALDataset* poDS = ((GDALDriver*)GDALGetDriverByName((bMemDriver) ? "MEM" : "GTiff"))->Create(pszDataset,
                                nXSize, nYSize, nBands, GDT_Byte, papszOptions);
        if( bCheck )
        {
            GByte* pabyLine = (GByte*) VSIMalloc(nBands * nXSize);
            for(int iY=0;iY<nYSize;iY++)
            {
                for(int iX=0;iX<nXSize;iX++)
                {
                    for(int iBand=0;iBand<nBands;iBand++)
                    {
                        unsigned long seed = iBand * nXSize * nYSize + iY * nXSize + iX;
                        pabyLine[iBand * nXSize + iX] = (GByte)(myrand_r(&seed) & 0xff);
                    }
                }
                CPL_IGNORE_RET_VAL(poDS->RasterIO(GF_Write, 0, iY, nXSize, 1,
                               pabyLine, nXSize, 1,
                               GDT_Byte,
                               nBands, NULL,
                               0, 0, 0
#ifdef GDAL_COMPILATION
                               , NULL
#endif
                               ));
            }
            VSIFree(pabyLine);
        }
        if( bMemDriver ) 
            poMEMDS = poDS;
        else
            GDALClose(poDS);
    }
    else
    {
        bCheck = FALSE;
    }
    CSLDestroy(papszOptions);
    papszOptions = NULL;
    
    Request* psGlobalRequestLast = NULL;

    for(i = 0; i < nThreads; i++ )
    {
        GDALDataset* poDS;
        // Since GDAL 2.0, the MEM driver is thread-safe, i.e. does not use the block
        // cache, but only for operations not involving resampling, which is
        // the case here
        if( poMEMDS ) 
            poDS = poMEMDS;
        else
        {
            poDS = (GDALDataset*)GDALOpen(pszDataset, GA_ReadOnly);
            if( poDS == NULL )
                exit(1);
        }
        if( bMigrate )
        {
            Resource* psResource = (Resource*)CPLMalloc(sizeof(Resource));
            psResource->poDS = poDS;
            int nBufferSize;
            if( eStrategy == STRATEGY_RANDOM )
                nBufferSize = CreateRandomStrategyRequests(
                        poDS, nMaxRequests, psGlobalRequestList, psGlobalRequestLast);
            else if( eStrategy == STRATEGY_LINE )
                nBufferSize = CreateLineStrategyRequests(
                        poDS, nMaxRequests, psGlobalRequestList, psGlobalRequestLast);
            else
                nBufferSize = CreateBlockStrategyRequests(
                        poDS, nMaxRequests, psGlobalRequestList, psGlobalRequestLast);
            psResource->pBuffer = CPLMalloc(nBufferSize);
            PutResourceAtEnd(psResource);
        }
        else
        {
            ThreadDescription sThreadDescription;
            sThreadDescription.poDS = poDS;
            sThreadDescription.psRequestList = NULL;
            Request* psRequestLast = NULL;
            if( eStrategy == STRATEGY_RANDOM )
                sThreadDescription.nBufferSize = CreateRandomStrategyRequests(
                        poDS, nMaxRequests, sThreadDescription.psRequestList, psRequestLast);
            else if( eStrategy == STRATEGY_LINE )
                sThreadDescription.nBufferSize = CreateLineStrategyRequests(
                        poDS, nMaxRequests, sThreadDescription.psRequestList, psRequestLast);
            else
                sThreadDescription.nBufferSize = CreateBlockStrategyRequests(
                        poDS, nMaxRequests, sThreadDescription.psRequestList, psRequestLast);
            asThreadDescription.push_back(sThreadDescription);
        }
    }

    if( bCreatedDataset && poMEMDS == NULL && bOnDisk )
    {
        CPLPushErrorHandler(CPLQuietErrorHandler);
        VSIUnlink(pszDataset);
        CPLPopErrorHandler();
    }
    
    if( bMigrate )
    {
        psLock = CPLCreateLock(LOCK_SPIN);
    }

    for(i = 0; i < nThreads; i++ )
    {
        CPLJoinableThread* pThread;
        if( bMigrate )
            pThread = CPLCreateJoinableThread(ThreadFuncWithMigration, NULL);
        else
            pThread = CPLCreateJoinableThread(ThreadFuncDedicatedDataset,
                                              &(asThreadDescription[i]));
        apsThreads.push_back(pThread);
    }
    for(i = 0; i < nThreads; i++ )
    {
        CPLJoinThread(apsThreads[i]);
        if( !bMigrate && poMEMDS == NULL )
            GDALClose(asThreadDescription[i].poDS);
    }
    while( psGlobalResourceList != NULL )
    {
        CPLFree( psGlobalResourceList->pBuffer);
        if( poMEMDS == NULL )
            GDALClose(psGlobalResourceList->poDS);
        Resource* psNext = psGlobalResourceList->psNext;
        CPLFree( psGlobalResourceList );
        psGlobalResourceList = psNext;
    }

    if( psLock )
    {
        CPLDestroyLock( psLock );
    }

    if( bCreatedDataset && poMEMDS == NULL  )
    {
        CPLPushErrorHandler(CPLQuietErrorHandler);
        VSIUnlink(pszDataset);
        CPLPopErrorHandler();
    }
    if( poMEMDS )
        GDALClose(poMEMDS);

    assert( GDALGetCacheUsed64() == 0 );

    GDALDestroyDriverManager();
    CSLDestroy( argv );

    return 0;
}
예제 #11
0
int download(region regionFlag, satellite satFlag, data_layer dataFlag, data_format typeFlag){
  GDALDataset *poDataset = NULL;
  Mat imageBuffer, outputBuffer;
  double pixel2geo[6];
  double geo2pixel[6];
  uint64_t xmin, ymin;
  uint64_t xsize, ysize;
  char GIBS_XML[1000];
  char outFileName[100];
  int numChannel;

  // Get the data
    sprintf(GIBS_XML, wms_format, /* Region name    */ (regionFlag==NORTH)?"arctic":((regionFlag==NORMAL)?"geo":"antarctic"),
                                  /*Satellite  name */ (satFlag==TERRA)?"Terra":"Aqua",
                                  /*Data layer name */ (dataFlag==REFLECTANCE)?"CorrectedReflectance_TrueColor":"Data_No_Data",
                                                       year, month, day,
                                  /*Region EPSG code*/ (regionFlag==NORTH)?"EPSG3413":((regionFlag==NORMAL)?"EPSG4326":"EPSG3031"),
                                  /*Data Format     */ (typeFlag==JPG)?"jpg":"png",
                                  /*Region EPSG code*/ (regionFlag==NORTH)?arctic_bounds:((regionFlag==NORMAL)?normal_bounds:antarctic_bounds),
                                  /*Region EPSG code*/ (regionFlag==NORTH)?"EPSG:3413":((regionFlag==NORMAL)?"EPSG:4326":"EPSG:3031"),
                                                       (typeFlag==JPG)?3:4);
    printf("%s\n\n", GIBS_XML);
  // Open file
    poDataset = (GDALDataset*) GDALOpen(GIBS_XML, GA_ReadOnly);
    if(!poDataset){
      fprintf(stderr,"File cannot be opened!\n");return 1;
    }

  // Print some metadata
    xsize = poDataset->GetRasterXSize();
    ysize = poDataset->GetRasterYSize();
    numChannel = poDataset->GetRasterCount();

  // Calculate coordinates
    poDataset->GetGeoTransform(pixel2geo);
    GDALInvGeoTransform(pixel2geo, geo2pixel);

    double lat_offset, lon_offset;
    switch(regionFlag){
      case NORTH:
        xmin = (col-1)*4096;
        ymin = (6-row)*4096;
        break;
      case NORMAL:
        GDALApplyGeoTransform(geo2pixel, (col-20)*9.0, (row-9)*9.0, &lon_offset, &lat_offset);
        xmin = (int) lon_offset;
        ymin = (int) lat_offset;
      break;
      case SOUTH:
        xmin = (col-1)*4096;
        ymin = (6-row)*4096;
        break;
    }
    printf("Offset=(%lf,%lf)\n",lon_offset,lat_offset);

  // Read Image data
    ysize = 4096;
    xsize = 4096;

    imageBuffer.create(ysize, xsize, CV_8UC1);
    outputBuffer.create(ysize, xsize, (typeFlag==JPG)?CV_8UC3:CV_8UC4);
    outputBuffer.zeros(ysize, xsize, (typeFlag==JPG)?CV_8UC3:CV_8UC4);
    int bandArray[1];
    for(int i=0;i<((typeFlag==JPG)?3:4);i++){
      bandArray[0] = i+1;
      imageBuffer.zeros(ysize, xsize, CV_8U);
      poDataset->RasterIO(GF_Read, xmin, ymin, xsize, ysize,
                          (void*) imageBuffer.ptr(0), xsize, ysize,
                          GDT_Byte, 1, bandArray, 0, 0, 0);
      for(int x=0;x<xsize;x++){
        for(int y=0;y<ysize;y++){
            ((uint8_t*)(outputBuffer.data))[(y*xsize+x)*numChannel+(numChannel-i-1)] = ((uint8_t*)(imageBuffer.data))[y*xsize+x];
        }
      }
    }

    if(typeFlag==PNG){
      outputBuffer = (outputBuffer==0);
      outputBuffer.convertTo(outputBuffer, CV_8UC1, 1, 0);
    }

    sprintf(outFileName, "%s_r%02dc%02d.%04d%03d.%s%s250m.%s", (regionFlag==NORTH)?"RRArctic":((regionFlag==NORMAL)?"RRGlobal":"RRAntarctic"), row, col, year, daynum,
                                                          (satFlag==TERRA)?"terra":"aqua", (dataFlag==REFLECTANCE)?".":".opaque.", (typeFlag==JPG)?"jpg":"png");
    imwrite(outFileName, outputBuffer);
    printf("File %s is written\n", outFileName);
    return 0;
}
예제 #12
0
void wxGISRasterRGBRenderer::Draw(wxGISDataset* pRasterDataset, wxGISEnumDrawPhase DrawPhase, IDisplay* pDisplay, ITrackCancel* pTrackCancel)
{
	wxGISRasterDataset* pRaster = dynamic_cast<wxGISRasterDataset*>(pRasterDataset);
	if(!pRaster)
		return;
	IDisplayTransformation* pDisplayTransformation = pDisplay->GetDisplayTransformation();
	OGRSpatialReference* pDisplaySpatialReference = pDisplayTransformation->GetSpatialReference();
	OGRSpatialReference* pRasterSpatialReference = pRaster->GetSpatialReference();
	bool IsSpaRefSame(true);
	if(pDisplaySpatialReference && pDisplaySpatialReference)
		IsSpaRefSame = pDisplaySpatialReference->IsSame(pRasterSpatialReference);
	OGREnvelope VisibleBounds = pDisplayTransformation->GetVisibleBounds();
	OGREnvelope* pRasterExtent = pRaster->GetEnvelope();
	OGREnvelope RasterEnvelope, DisplayEnvelope;

	if(!IsSpaRefSame)
	{
		RasterEnvelope = TransformEnvelope(pRasterExtent, pRasterSpatialReference, pDisplaySpatialReference);
	}
	else
	{
		RasterEnvelope = *pRasterExtent;
	}
	bool IsZoomIn(false);
	//IsZoomIn = RasterEnvelope.Contains(VisibleBounds);
	IsZoomIn = RasterEnvelope.MaxX > VisibleBounds.MaxX || RasterEnvelope.MaxY > VisibleBounds.MaxY || RasterEnvelope.MinX < VisibleBounds.MinX || RasterEnvelope.MinY < VisibleBounds.MinY;
	if(IsZoomIn)
	{
		//intersect bounds
		OGREnvelope DrawBounds;
		DrawBounds.MinX = MAX(RasterEnvelope.MinX, VisibleBounds.MinX);
		DrawBounds.MinY = MAX(RasterEnvelope.MinY, VisibleBounds.MinY);
		DrawBounds.MaxX = MIN(RasterEnvelope.MaxX, VisibleBounds.MaxX);
		DrawBounds.MaxY = MIN(RasterEnvelope.MaxY, VisibleBounds.MaxY);

		OGRRawPoint OGRRawPoints[2];
		OGRRawPoints[0].x = DrawBounds.MinX;
		OGRRawPoints[0].y = DrawBounds.MinY;
		OGRRawPoints[1].x = DrawBounds.MaxX;
		OGRRawPoints[1].y = DrawBounds.MaxY;
		wxPoint* pDCPoints = pDisplayTransformation->TransformCoordWorld2DC(OGRRawPoints, 2);	

		if(!pDCPoints)
		{
			wxDELETEA(pDCPoints);
			return;
		}

		int nDCXOrig = pDCPoints[0].x;
		int nDCYOrig = pDCPoints[1].y;
		int nWidth = pDCPoints[1].x - pDCPoints[0].x;
		int nHeight = pDCPoints[0].y - pDCPoints[1].y;
		wxDELETEA(pDCPoints);

        if(nWidth <= 20 || nHeight <= 20)
			return;

		GDALDataset* pGDALDataset = pRaster->GetRaster();

		int nBandCount = pGDALDataset->GetRasterCount();
		//hack!
		int bands[3];
		if(nBandCount < 3)
		{
			bands[0] = 1;
			bands[1] = 1;
			bands[2] = 1;	
		}
		else
		{
			bands[0] = 1;
			bands[1] = 2;
			bands[2] = 3;		
		}

		double adfGeoTransform[6] = { 0, 0, 0, 0, 0, 0 };
        double adfReverseGeoTransform[6] = { 0, 0, 0, 0, 0, 0 };
		CPLErr err = pGDALDataset->GetGeoTransform(adfGeoTransform);
        bool bNoTransform(false);
        if(err != CE_None)
        {
            bNoTransform = true;
        }
        else
        {
            int nRes = GDALInvGeoTransform( adfGeoTransform, adfReverseGeoTransform );
        }

		//2. get image data from raster - draw part of the raster
		if(IsSpaRefSame)
		{
			double rMinX, rMinY, rMaxX, rMaxY;

            int nXSize = pGDALDataset->GetRasterXSize();
            int nYSize = pGDALDataset->GetRasterYSize();

            if(bNoTransform)
            {
                rMinX = DrawBounds.MinX;
                rMaxX = DrawBounds.MaxX;
                rMaxY = nYSize - DrawBounds.MinY;
                rMinY = nYSize - DrawBounds.MaxY;
            }
            else
            {
    			GDALApplyGeoTransform( adfReverseGeoTransform, DrawBounds.MinX, DrawBounds.MinY, &rMinX, &rMaxY );
	    		GDALApplyGeoTransform( adfReverseGeoTransform, DrawBounds.MaxX, DrawBounds.MaxY, &rMaxX, &rMinY );
            }
            //double rRealMinX, rRealMinY, rRealMaxX, rRealMaxY;
            //rRealMinX = MIN(rMinX, rMaxX);
            //rRealMinY = MIN(rMinY, rMaxY);
            //rRealMaxX = MAX(rMinX, rMaxX);
            //rRealMaxY = MAX(rMinY, rMaxY);

            double rImgWidth = rMaxX - rMinX;
            double rImgHeight = rMaxY - rMinY;
			int nImgWidth = ceil(rImgWidth) + 1;
			int nImgHeight = ceil(rImgHeight) + 1;
            
			//read in buffer
            int nMinX = floor(rMinX);
            int nMinY = floor(rMinY);
			if(nMinX < 0) nMinX = 0;
			if(nMinY < 0) nMinY = 0;

            if(nImgWidth > nXSize - nMinX) nImgWidth -= 1;
            if(nImgHeight > nYSize - nMinY) nImgHeight -= 1;

		    //create buffer
			int nWidthOut = nWidth > nImgWidth ? nImgWidth : (double)nWidth + 1.0  /*/ 1.2 / 2 * 2/ 1.5 + 1) / 2*/;
			int nHeightOut = nHeight > nImgHeight ? nImgHeight : (double)nHeight + 1.0  /*/ 1.2 / 2 * 2 / 1.5 + 1) / 2*/;
			double rImgWidthOut = nWidth > nImgWidth ? rImgWidth : (double)nWidthOut * rImgWidth / nImgWidth;
			double rImgHeightOut = nHeight > nImgHeight ? rImgHeight : (double)nHeightOut * rImgHeight / nImgHeight;


		    unsigned char* data = new unsigned char[nWidthOut * nHeightOut * 3];

		    err = pGDALDataset->AdviseRead(nMinX, nMinY, nImgWidth, nImgHeight, nWidthOut/*nImgWidth*/, nHeightOut/*nImgHeight*/, GDT_Byte, 3, bands, NULL);
		    if(err != CE_None)
		    {
			    wxDELETEA(data);//delete[](data);
			    return;
		    }

		    err = pGDALDataset->RasterIO(GF_Read, nMinX, nMinY, nImgWidth, nImgHeight, data, nWidthOut/*nImgWidth*/, nHeightOut/*nImgHeight*/, GDT_Byte, 3, bands, sizeof(unsigned char) * 3, 0, sizeof(unsigned char));
		    if(err != CE_None)
		    {
			    wxDELETEA(data);//delete[](data);
			    return;
		    }
		    //scale pTempData to data using interpolation methods
		    pDisplay->DrawBitmap(Scale(data, nWidthOut/*nImgWidth*/, nHeightOut/*nImgHeight*/, rImgWidthOut/*rImgWidth*/, rImgHeightOut/*rImgHeight*/, nWidth + 1 , nHeight + 1, rMinX - nMinX, rMinY - nMinY, /*enumGISQualityNearest*/enumGISQualityBilinear, pTrackCancel), nDCXOrig, nDCYOrig);

            wxDELETEA(data);
		}
		else
		{
		//void *hTransformArg = GDALCreateGenImgProjTransformer( hSrcDS, pszSrcWKT, NULL, pszDstWKT, FALSE, 0, 1 );
		//GDALDestroyGenImgProjTransformer( hTransformArg );
	////		//get new envelope - it may rotate
	////		OGRCoordinateTransformation *poCT = OGRCreateCoordinateTransformation( pDisplaySpatialReference, pRasterSpatialReference);
	//////		get real envelope
	//////		poCT->Transform(1, &pRasterExtent->MaxX, &pRasterExtent->MaxY);
	//////		poCT->Transform(1, &pRasterExtent->MinX, &pRasterExtent->MinY);
	//////		poCT->Transform(1, &pRasterExtent->MaxX, &pRasterExtent->MinY);
	//////		poCT->Transform(1, &pRasterExtent->MinX, &pRasterExtent->MaxY);
	////		OCTDestroyCoordinateTransformation(poCT);
		}
	}
	else
	{
		//1. convert newrasterenvelope to DC		
		OGRRawPoint OGRRawPoints[2];
		OGRRawPoints[0].x = RasterEnvelope.MinX;
		OGRRawPoints[0].y = RasterEnvelope.MinY;
		OGRRawPoints[1].x = RasterEnvelope.MaxX;
		OGRRawPoints[1].y = RasterEnvelope.MaxY;
		wxPoint* pDCPoints = pDisplayTransformation->TransformCoordWorld2DC(OGRRawPoints, 2);	

		//2. get image data from raster - buffer size = DC_X and DC_Y - draw full raster
		if(!pDCPoints)
		{
			wxDELETEA(pDCPoints);
			return;
		}
		int nDCXOrig = pDCPoints[0].x;
		int nDCYOrig = pDCPoints[1].y;
		int nWidth = pDCPoints[1].x - pDCPoints[0].x;
		int nHeight = pDCPoints[0].y - pDCPoints[1].y;
		delete[](pDCPoints);

		GDALDataset* pGDALDataset = pRaster->GetRaster();
		int nImgWidth = pGDALDataset->GetRasterXSize();
		int nImgHeight = pGDALDataset->GetRasterYSize();

		int nBandCount = pGDALDataset->GetRasterCount();
		//hack!
		int bands[3];
		if(nBandCount < 3)
		{
			bands[0] = 1;
			bands[1] = 1;
			bands[2] = 1;	
		}
		else
		{
			bands[0] = 1;
			bands[1] = 2;
			bands[2] = 3;		
		}

		//create buffer
		unsigned char* data = new unsigned char[nWidth * nHeight * 3];
		if(IsSpaRefSame)
		{
			//read in buffer
			CPLErr err = pGDALDataset->RasterIO(GF_Read, 0, 0, nImgWidth, nImgHeight, data, nWidth, nHeight, GDT_Byte, 3, bands, sizeof(unsigned char) * 3, 0, sizeof(unsigned char));
			if(err != CE_None)
			{
				wxDELETEA(data);
				return;
			}
		}
		else
		{
			//1. calc Width & Height of TempData with same aspect ratio of raster
			//2. create pTempData buffer
			unsigned char* pTempData;
			//3. fill data
			//4. for each pixel of data buffer get pixel from pTempData using OGRCreateCoordinateTransformation
			//delete[](data);
		}
		//3. draw //think about transparancy!
		wxImage ResultImage(nWidth, nHeight, data);
		pDisplay->DrawBitmap(ResultImage, nDCXOrig, nDCYOrig);

		//delete[](data);
	}
}
예제 #13
0
파일: mrf_band.cpp 프로젝트: RyanHun/mrf
/**
*\brief Fetch a block from the backing store dataset and keep a copy in the cache
*
* @xblk The X block number, zero based
* @yblk The Y block number, zero based
* @param tinfo The return, updated tinfo for this specific tile
*
*/
CPLErr GDALMRFRasterBand::FetchBlock(int xblk, int yblk, void *buffer)

{
    assert(!poDS->source.empty());
    CPLDebug("MRF_IB", "FetchBlock %d,%d,0,%d, level  %d\n", xblk, yblk, m_band, m_l);

    if (poDS->clonedSource)  // This is a clone
	return FetchClonedBlock(xblk, yblk, buffer);

    GDALDataset *poSrcDS;
    const GInt32 cstride = img.pagesize.c; // 1 if band separate
    ILSize req(xblk, yblk, 0, m_band / cstride, m_l);
    GUIntBig infooffset = IdxOffset(req, img);

    if ( NULL == (poSrcDS = poDS->GetSrcDS())) {
	CPLError( CE_Failure, CPLE_AppDefined, "MRF: Can't open source file %s", poDS->source.c_str());
	return CE_Failure;
    }

    // Scale to base resolution
    double scl = pow(poDS->scale, m_l);
    if ( 0 == m_l )
	scl = 1; // To allow for precision issues

    // Prepare parameters for RasterIO, they might be different from a full page
    int vsz = GDALGetDataTypeSize(eDataType)/8;
    int Xoff = int(xblk * img.pagesize.x * scl + 0.5);
    int Yoff = int(yblk * img.pagesize.y * scl + 0.5);
    int readszx = int(img.pagesize.x * scl + 0.5);
    int readszy = int(img.pagesize.y * scl + 0.5);

    // Compare with the full size and clip to the right and bottom if needed
    int clip=0;
    if (Xoff + readszx > poDS->full.size.x) {
	clip |= 1;
	readszx = poDS->full.size.x - Xoff;
    }
    if (Yoff + readszy > poDS->full.size.y) {
	clip |= 1;
	readszy = poDS->full.size.y - Yoff;
    }

    // This is where the whole page fits
    void *ob = buffer;
    if (cstride != 1) 
	ob = poDS->GetPBuffer();

    // Fill buffer with NoData if clipping
    if (clip)
	FillBlock(ob);

    // Use the dataset RasterIO to read one or all bands if interleaved
    CPLErr ret = poSrcDS->RasterIO(GF_Read, Xoff, Yoff, readszx, readszy,
	ob, pcount(readszx, int(scl)), pcount(readszy, int(scl)),
	eDataType, cstride, (1 == cstride)? &nBand: NULL,
	vsz * cstride, 	// pixel, line, band stride
	vsz * cstride * img.pagesize.x,
	(cstride != 1) ? vsz : vsz * img.pagesize.x * img.pagesize.y
#if GDAL_VERSION_MAJOR >= 2
	,NULL
#endif
	);

    if (ret != CE_None) return ret;

    // Might have the block in the pbuffer, mark it anyhow
    poDS->tile = req;
    buf_mgr filesrc;
    filesrc.buffer = (char *)ob;
    filesrc.size = static_cast<size_t>(img.pageSizeBytes);

    if (poDS->bypass_cache) { // No local caching, just return the data
	if (1 == cstride)
	    return CE_None;
	return RB(xblk, yblk, filesrc, buffer);
    }

    // Test to see if it needs to be written, or just marked as checked
    int success;
    double val = GetNoDataValue(&success);
    if (!success) val = 0.0;

    // TODO: test band by band if data is interleaved
    if (isAllVal(eDataType, ob, img.pageSizeBytes, val)) {
	// Mark it empty and checked, ignore the possible write error
	poDS->WriteTile((void *)1, infooffset, 0);
	return CE_None;
    }

    // Write the page in the local cache

    // Have to use a separate buffer for compression output.
    void *outbuff = VSIMalloc(poDS->pbsize);

    if (!outbuff) {
	CPLError(CE_Failure, CPLE_AppDefined, 
	    "Can't get buffer for writing page");
	// This is not really an error for a cache, the data is fine
	return CE_Failure;
    }

    buf_mgr filedst={(char *)outbuff, poDS->pbsize};
    Compress(filedst, filesrc);

    // Where the output is, in case we deflate
    void *usebuff = outbuff;
    if (deflatep) {
	usebuff = DeflateBlock( filedst, poDS->pbsize - filedst.size, deflate_flags);
	if (!usebuff) {
	    CPLError(CE_Failure,CPLE_AppDefined, "MRF: Deflate error");
	    return CE_Failure;
	}
    }

    // Write and update the tile index
    ret = poDS->WriteTile(usebuff, infooffset, filedst.size);
    CPLFree(outbuff);

    // If we hit an error or if unpaking is not needed
    if (ret != CE_None || cstride == 1)
	return ret;

    // data is already in filesrc buffer, deinterlace it in pixel blocks
    return RB(xblk, yblk, filesrc, buffer);
}
예제 #14
0
int meaningful_change(string cd_map_file, string result_file)
{
	GdalRasterApp cd_map;
	cd_map.open(cd_map_file.c_str());
	int iBandCount = cd_map.nBand();
	int iTileCountX = cd_map.getTileCountX();
	int iTileCountY = cd_map.getTileCountY();
	int iWidth = cd_map.width();
	int iHeight = cd_map.height();

	GDALDriver *poDriver;	//驱动,用于创建新的文件
	poDriver=GetGDALDriverManager()->GetDriverByName("GTIFF");
	char **papszMetadata = poDriver->GetMetadata();//获取格式类型
	GDALDataset *poDatasetNew;
	// 输出栅格
	poDatasetNew = poDriver->Create(result_file.c_str(), iWidth, iHeight, 1, GDT_Byte, papszMetadata);//根据文件路径文件名,图像宽,高,波段数,数据类型,文件类型,创建新的数据集				
	poDatasetNew->SetProjection(cd_map.getGetProjectionRef());
	poDatasetNew->SetGeoTransform(cd_map.getGeoTransform());//坐标赋值,与全色相同

	int nCount = 0;
	double norm_threshold = 20.0;
	int bgColor = 0;
	int fgColor = 255;
	for (int i = 0;i < iTileCountX;++i)
	{
		for (int j = 0;j < iTileCountY;++j)
		{
			GdalRasterApp::RasterBuf *pBuf = cd_map.getTileData(i, j, iBandCount);
			int bufWidth = pBuf->iBufWidth;
			int bufHeight = pBuf->iBufHeight;
			int bufBand = pBuf->iBandCount;
			int offsetX, offsetY;
			cd_map.getTileOffset(i, j, offsetX, offsetY);
			cv::Mat change_image(cv::Size(bufWidth, bufHeight), CV_8UC1, cv::Scalar(fgColor));

			//cv::Mat lbp_change(cv::Size(bufWidth, bufHeight), CV_8UC1);
			cv::Mat lbp_change = img_int2byte_band(pBuf, 0);
			//cv::Mat lbp_change = img_float2byte_band(pBuf, 0);
			//memcpy(lbp_change.data, pBuf->data, bufWidth*bufHeight);
			//cv::imwrite("E:\\minus.tif", lbp_change);
			int lbp_change_threshold = cvThresholdOtsu(lbp_change);

			int step = change_image.step;
			// change detection
			for (int row = 0; row < bufHeight; ++row) {
				for (int col = 0; col < bufWidth; ++col) {
					int lbp_change_ = lbp_change.data[row*lbp_change.step+col];
					// 判断是否变化很小
					if (lbp_change_ < lbp_change_threshold)
					{
						change_image.data[row*step+col] = bgColor;
						continue;
					}

					std::vector<double> change_vector(pFeatureBuf->iBandCount);
					for (int k = 0;k < pFeatureBuf->iBandCount;++k)
					{
						int pos = row * bufWidth * pFeatureBuf->iBandCount + col*pFeatureBuf->iBandCount + k;
						change_vector[k] = ((float*)pFeatureBuf->data)[pos];
					}

					//如果变化是否和样本相似
					for (int m = 0; m < (int)samples.size(); m++)
					{
						double angle_ = samples[m][0] - change_vector[0];
						double norm_ = samples[m][1] - change_vector[1];
						//double similarity = VectorSimilarity(samples[m], change_vector);
						//double distance = VectorDistance(samples[m], change_vector);
						//double angle = VectorAngle(samples[m], change_vector);
						//if (fabs(similarity) > similarityThreshold && distance < 15.0)
						//if (fabs(angle) < 10.0 && distance < 20.0)
						//if (fabs(similarity) < similarityThreshold)
						if (fabs(angle_) < similarityThreshold && fabs(norm_) < 10.0)
							//if (fabs(norm) < 10.0)
						{
							change_image.data[row*step+col] = bgColor;
							break;
						}
					}
				}
			}

			//RasterBuf2Opencv(pBuf, change_image);
			//cv::Mat change_image(bufHeight, bufWidth, CV_8U(bufBand));
			//int nBandDataSize = GDALGetDataTypeSize( pBuf->eDataType ) / 8;
			//memcpy(change_image.data, (GByte*)(pBuf->data), bufWidth*bufHeight*bufBand*nBandDataSize);
			//cvtColor( change_image, change_image, CV_BGR2GRAY );
			//int threshold = cvThresholdOtsu(change_image);
			//threshold = 60;
			//cv::threshold( change_image, change_image, threshold, 255, CV_THRESH_BINARY);
			//cv::Mat element = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(3, 3));
			//cv::morphologyEx(change_image, change_image, cv::MORPH_CLOSE, element);
			//element = cv::getStructuringElement(cv::MORPH_CROSS , cv::Size(7, 7));
			//cv::morphologyEx(change_image, change_image, cv::MORPH_OPEN, element);
			//element = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(7, 7));
			//cv::morphologyEx(change_image, change_image, cv::MORPH_OPEN, element);
			//cv::GaussianBlur(change_image, change_image, cv::Size(5,5), 1.5);
			//cv::morphologyEx(change_image, change_image, cv::MORPH_CLOSE, element);

			//cv::imwrite("E:\\test0.tif", change_image);
			cv::Mat element = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(2,2));
			//cv::morphologyEx(change_image, change_image, cv::MORPH_CLOSE, element);
			int nTemplate = sqrt(smallArea);
			nTemplate = nTemplate / 2 * 2 + 1;
			cv::medianBlur(change_image, change_image, nTemplate);
			//cv::imwrite("E:\\test1.tif", change_image);
			// 先闭运算
			nTemplate = nTemplate / 2;
			element = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(5,5));
			cv::morphologyEx(change_image, change_image, cv::MORPH_CLOSE, element);
			// 再开运算
			//element = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(10, 10));
			//cv::morphologyEx(change_image, change_image, cv::MORPH_OPEN, element);
			//cv::imwrite("E:\\test2.tif", change_image);
			BinaryRemoveSmall(change_image, change_image, smallArea, bgColor, fgColor);
			//cv::Mat tmpMat = change_image.clone();
			////cv::GaussianBlur(tmpMat, tmpMat, cv::Size(5,5), 1.5);
			//std::vector<std::vector<cv::Point> > contours;
			//std::vector<cv::Vec4i> hierarchy;
			//cv::findContours(tmpMat, contours, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, cv::Point(0, 0) );
			////for (std::vector<std::vector<cv::Point> >::iterator iter_Contours = contours.begin(); iter_Contours != contours.end();++iter_Contours)
			//int nContours = (int)contours.size();
			//for (int iContours = 0; iContours < nContours;++iContours)
			//{
			//	std::vector<cv::Point> contour = contours[iContours];
			//	double tempArea = fabs(cv::contourArea(contour));
			//	cv::Rect rect = cv::boundingRect(contour);
			//	//当连通域的中心点为白色,而且面积较小时,用黑色进行填充 
			//	if (tempArea < miniArea)
			//	{
			//		int pos_center = step*(rect.y+rect.height/2)+rect.x+rect.width/2;
			//		//if (255 == change_image.data[pos_center])
			//		{
			//			for(int y = rect.y;y<rect.y+rect.height;y++)
			//			{
			//				for(int x =rect.x;x<rect.x+rect.width;x++) 
			//				{
			//					int pos_ = y*step+x;
			//					if(255 == change_image.data[pos_])
			//					{
			//						change_image.data[pos_] = 0;
			//					}
			//				}
			//			}
			//		}
			//	}
			//}

			//cv::imwrite("E:\\test3.tif", change_image);
			////cv::imwrite("E:\\test.tif", change_image);

			if (_changeOutType::raster == outType)
			{
				// 输出栅格
				CPLErr gdal_err = poDatasetNew->RasterIO(GF_Write, offsetX, offsetY, bufWidth, bufHeight, change_image.data, bufWidth, bufHeight,\
					GDT_Byte, 1, 0, 0, 0, 0);
			}
			else if (_changeOutType::vector == outType)
			{
				// 输出矢量
				std::vector<std::vector<cv::Point> > contours;
				std::vector<cv::Vec4i> hierarchy;
				cv::findContours(change_image, contours, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, cv::Point(0, 0) );
				addContour2ShapeArea(contours, out_layer_file, raster_minus.getGeoTransform(), raster_minus.getGetProjectionRef(), nCount, raster_minus.getBufInfo()->iBufOffsetX, raster_minus.getBufInfo()->iBufOffsetY);
				nCount += (int)contours.size();
			}
			pBuf = NULL;
		}
	}
	raster_minus.close();
	raster_feature.close();
	poDatasetNew->FlushCache();
	GDALClose(poDatasetNew);
}
예제 #15
0
CPLErr SAFERasterBand::IReadBlock( int nBlockXOff, int nBlockYOff,
                                  void * pImage )

{
/* -------------------------------------------------------------------- */
/*      If the last strip is partial, we need to avoid                  */
/*      over-requesting.  We also need to initialize the extra part     */
/*      of the block to zero.                                           */
/* -------------------------------------------------------------------- */
    int nRequestYSize;
    if( (nBlockYOff + 1) * nBlockYSize > nRasterYSize )
    {
        nRequestYSize = nRasterYSize - nBlockYOff * nBlockYSize;
        memset( pImage, 0, (GDALGetDataTypeSize( eDataType ) / 8) *
            nBlockXSize * nBlockYSize );
    }
    else
    {
        nRequestYSize = nBlockYSize;
    }

/*-------------------------------------------------------------------- */
/*      If the input imagery is tiled, also need to avoid over-        */
/*      requesting in the X-direction.                                 */
/* ------------------------------------------------------------------- */
    int nRequestXSize;
    if( (nBlockXOff + 1) * nBlockXSize > nRasterXSize )
    {
        nRequestXSize = nRasterXSize - nBlockXOff * nBlockXSize;
        memset( pImage, 0, (GDALGetDataTypeSize( eDataType ) / 8) *
            nBlockXSize * nBlockYSize );
    }
    else
    {
        nRequestXSize = nBlockXSize;
    }
    if( eDataType == GDT_CInt16 && poBandFile->GetRasterCount() == 2 )
        return
            poBandFile->RasterIO( GF_Read,
                                  nBlockXOff * nBlockXSize,
                                  nBlockYOff * nBlockYSize,
                                  nRequestXSize, nRequestYSize,
                                  pImage, nRequestXSize, nRequestYSize,
                                  GDT_Int16,
                                  2, nullptr, 4, nBlockXSize * 4, 2, nullptr );

/* -------------------------------------------------------------------- */
/*      File has one sample marked as sample format void, a 32bits.     */
/* -------------------------------------------------------------------- */
    else if( eDataType == GDT_CInt16 && poBandFile->GetRasterCount() == 1 )
    {
        CPLErr eErr
            = poBandFile->RasterIO( GF_Read,
                                  nBlockXOff * nBlockXSize,
                                  nBlockYOff * nBlockYSize,
                                  nRequestXSize, nRequestYSize,
                                  pImage, nRequestXSize, nRequestYSize,
                                  GDT_UInt32,
                                  1, nullptr, 4, nBlockXSize * 4, 0, nullptr );

#ifdef CPL_LSB
        /* First, undo the 32bit swap. */
        GDALSwapWords( pImage, 4, nBlockXSize * nBlockYSize, 4 );

        /* Then apply 16 bit swap. */
        GDALSwapWords( pImage, 2, nBlockXSize * nBlockYSize * 2, 2 );
#endif

        return eErr;
    }

/* -------------------------------------------------------------------- */
/*      The 16bit case is straight forward.  The underlying file        */
/*      looks like a 16bit unsigned data too.                           */
/* -------------------------------------------------------------------- */
    else if( eDataType == GDT_UInt16 )
        return
            poBandFile->RasterIO( GF_Read,
                                  nBlockXOff * nBlockXSize,
                                  nBlockYOff * nBlockYSize,
                                  nRequestXSize, nRequestYSize,
                                  pImage, nRequestXSize, nRequestYSize,
                                  GDT_UInt16,
                                  1, nullptr, 2, nBlockXSize * 2, 0, nullptr );
    else if ( eDataType == GDT_Byte )
        return
            poBandFile->RasterIO( GF_Read,
                                  nBlockXOff * nBlockXSize,
                                  nBlockYOff * nBlockYSize,
                                  nRequestXSize, nRequestYSize,
                                  pImage, nRequestXSize, nRequestYSize,
                                  GDT_Byte,
                                  1, nullptr, 1, nBlockXSize, 0, nullptr );

    CPLAssert( false );
    return CE_Failure;
}
예제 #16
0
CPLErr GDALWMSRasterBand::ReadBlockFromFile(int x, int y, const char *file_name, int to_buffer_band, void *buffer, int advise_read) {
    CPLErr ret = CE_None;
    GDALDataset *ds = 0;
    GByte *color_table = NULL;
    int i;

    //CPLDebug("WMS", "ReadBlockFromFile: to_buffer_band=%d, (x,y)=(%d, %d)", to_buffer_band, x, y);

    /* expected size */
    const int esx = MIN(MAX(0, (x + 1) * nBlockXSize), nRasterXSize) - MIN(MAX(0, x * nBlockXSize), nRasterXSize);
    const int esy = MIN(MAX(0, (y + 1) * nBlockYSize), nRasterYSize) - MIN(MAX(0, y * nBlockYSize), nRasterYSize);
    ds = reinterpret_cast<GDALDataset*>(GDALOpen(file_name, GA_ReadOnly));
    if (ds != NULL) {
        int sx = ds->GetRasterXSize();
        int sy = ds->GetRasterYSize();
        bool accepted_as_no_alpha = false;  // if the request is for 4 bands but the wms returns 3  
        /* Allow bigger than expected so pre-tiled constant size images work on corners */
        if ((sx > nBlockXSize) || (sy > nBlockYSize) || (sx < esx) || (sy < esy)) {
            CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Incorrect size %d x %d of downloaded block, expected %d x %d, max %d x %d.",
                sx, sy, esx, esy, nBlockXSize, nBlockYSize);
            ret = CE_Failure;
        }
        if (ret == CE_None) {
            int nDSRasterCount = ds->GetRasterCount();
            if (nDSRasterCount != m_parent_dataset->nBands) {
                /* Maybe its an image with color table */
                bool accepted_as_ct = false;
                if ((eDataType == GDT_Byte) && (ds->GetRasterCount() == 1)) {
                    GDALRasterBand *rb = ds->GetRasterBand(1);
                    if (rb->GetRasterDataType() == GDT_Byte) {
                        GDALColorTable *ct = rb->GetColorTable();
                        if (ct != NULL) {
                            accepted_as_ct = true;
                            if (!advise_read) {
                                color_table = new GByte[256 * 4];
                                const int count = MIN(256, ct->GetColorEntryCount());
                                for (i = 0; i < count; ++i) {
                                    GDALColorEntry ce;
                                    ct->GetColorEntryAsRGB(i, &ce);
                                    color_table[i] = static_cast<GByte>(ce.c1);
                                    color_table[i + 256] = static_cast<GByte>(ce.c2);
                                    color_table[i + 512] = static_cast<GByte>(ce.c3);
                                    color_table[i + 768] = static_cast<GByte>(ce.c4);
                                }
                                for (i = count; i < 256; ++i) {
                                    color_table[i] = 0;
                                    color_table[i + 256] = 0;
                                    color_table[i + 512] = 0;
                                    color_table[i + 768] = 0;
                                }
                            }
                        }
                    }
                }

                if (nDSRasterCount == 4 && m_parent_dataset->nBands == 3)
                {
                    /* metacarta TMS service sometimes return a 4 band PNG instead of the expected 3 band... */
                }
                else if (!accepted_as_ct) {
                   if (ds->GetRasterCount()==3 && m_parent_dataset->nBands == 4 && (eDataType == GDT_Byte))
                   { // WMS returned a file with no alpha so we will fill the alpha band with "opaque" 
                      accepted_as_no_alpha = true;
                   }
                   else
                   {
                      CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Incorrect bands count %d in downloaded block, expected %d.",
                         nDSRasterCount, m_parent_dataset->nBands);
                      ret = CE_Failure;
                   }
                }
            }
        }
        if (!advise_read) {
            for (int ib = 1; ib <= m_parent_dataset->nBands; ++ib) {
                if (ret == CE_None) {
                    void *p = NULL;
                    GDALRasterBlock *b = NULL;
                    if ((buffer != NULL) && (ib == to_buffer_band)) {
                        p = buffer;
                    } else {
                        GDALWMSRasterBand *band = static_cast<GDALWMSRasterBand *>(m_parent_dataset->GetRasterBand(ib));
                        if (m_overview >= 0) band = static_cast<GDALWMSRasterBand *>(band->GetOverview(m_overview));
                        if (!band->IsBlockInCache(x, y)) {
                            b = band->GetLockedBlockRef(x, y, true);
                            if (b != NULL) {
                                p = b->GetDataRef();
                                if (p == NULL) {
                                  CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: GetDataRef returned NULL.");
                                  ret = CE_Failure;
                                }
                            }
                        }
                        else
                        {
                            //CPLDebug("WMS", "Band %d, block (x,y)=(%d, %d) already in cache", band->GetBand(), x, y);
                        }
                    }
                    if (p != NULL) {
                        int pixel_space = GDALGetDataTypeSize(eDataType) / 8;
                        int line_space = pixel_space * nBlockXSize;
                        if (color_table == NULL) {
                            if( ib <= ds->GetRasterCount()) {
                               if (ds->RasterIO(GF_Read, 0, 0, sx, sy, p, sx, sy, eDataType, 1, &ib, pixel_space, line_space, 0) != CE_None) {
                                   CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: RasterIO failed on downloaded block.");
                                   ret = CE_Failure;
                               }
                            }
                            else
                            {  // parent expects 4 bands but file only has 3 so generate a all "opaque" 4th band
                               if (accepted_as_no_alpha)
                               {
                                  // the file had 3 bands and we are reading band 4 (Alpha) so fill with 255 (no alpha)
                                  GByte *byte_buffer = reinterpret_cast<GByte *>(p);
                                  for (int y = 0; y < sy; ++y) {
                                     for (int x = 0; x < sx; ++x) {
                                        const int offset = x + y * line_space;
                                        byte_buffer[offset] = 255;  // fill with opaque
                                     }
                                  }
                               }
                               else
                               {  // we should never get here because this case was caught above
                                  CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Incorrect bands count %d in downloaded block, expected %d.",
                                     ds->GetRasterCount(), m_parent_dataset->nBands);
                                  ret = CE_Failure;
                               }     
                            }
                        } else if (ib <= 4) {
                            if (ds->RasterIO(GF_Read, 0, 0, sx, sy, p, sx, sy, eDataType, 1, NULL, pixel_space, line_space, 0) != CE_None) {
                                CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: RasterIO failed on downloaded block.");
                                ret = CE_Failure;
                            }
                            if (ret == CE_None) {
                                GByte *band_color_table = color_table + 256 * (ib - 1);
                                GByte *byte_buffer = reinterpret_cast<GByte *>(p);
                                for (int y = 0; y < sy; ++y) {
                                    for (int x = 0; x < sx; ++x) {
                                        const int offset = x + y * line_space;
                                        byte_buffer[offset] = band_color_table[byte_buffer[offset]];
                                    }
                                }
                            }
                        } else {
                            CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Color table supports at most 4 components.");
                            ret = CE_Failure;
                        }
                    }
                    if (b != NULL) {
                        b->DropLock();
                    }
                }
            }
        }
        GDALClose(ds);
    } else {
        CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: Unable to open downloaded block.");
        ret = CE_Failure;
    }

    if (color_table != NULL) {
        delete[] color_table;
    }

    return ret;
}
예제 #17
0
파일: Image.cpp 프로젝트: PetaVision/OpenPV
int Image::readImageFileGDAL(char const * filename, PVLayerLoc const * loc) {
   assert(parent->columnId()==0);

   GDALAllRegister();

   GDALDataset * dataset = PV_GDALOpen(filename);
   if (dataset==NULL) { return PV_FAILURE; } // PV_GDALOpen prints an error message.
   GDALRasterBand * poBand = dataset->GetRasterBand(1);
   GDALDataType dataType = poBand->GetRasterDataType();

   // GDAL defines whether a band is binary, not whether the image as a whole is binary.
   // Set isBinary to false if any band is not binary (metadata doesn't have NBITS=1)
   bool isBinary = true;
   for(int iBand = 0; iBand < GDALGetRasterCount(dataset); iBand++){
      GDALRasterBandH hBand = GDALGetRasterBand(dataset, iBand+1);
      char ** metadata = GDALGetMetadata(hBand, "Image_Structure");
      if(CSLCount(metadata) > 0){
         bool found = false;
         for(int i = 0; metadata[i] != NULL; i++){
            if(strcmp(metadata[i], "NBITS=1") == 0){
               found = true;
               break;
            }
         }
         if(!found){
            isBinary = false;
         }
      }
      else{
         isBinary = false;
      }
   }

   int const xImageSize = imageLoc.nxGlobal;
   int const yImageSize = imageLoc.nyGlobal;
   int const bandsInFile = imageLoc.nf;

   int numTotal = xImageSize * yImageSize * bandsInFile;

   dataset->RasterIO(GF_Read, 0, 0, xImageSize, yImageSize, imageData,
         xImageSize, yImageSize, GDT_Float32, bandsInFile, NULL,
         bandsInFile*sizeof(float), bandsInFile*xImageSize*sizeof(float), sizeof(float));


   GDALClose(dataset);
   if(!isBinary){
      pvadata_t fac;
      if(dataType == GDT_Byte){
         fac = 1.0f / 255.0f;  // normalize to 1.0
      }
      else if(dataType == GDT_UInt16){
         fac = 1.0f / 65535.0f;  // normalize to 1.0
      }
      else{
         pvError().printf("Image data type %s in file \"%s\" is not implemented.\n", GDALGetDataTypeName(dataType), filename);
      }
      for( int n=0; n<numTotal; n++ ) {
         imageData[n] *= fac;
      }
   }
   return EXIT_SUCCESS;
}
예제 #18
0
CPLErr GDALRasterizeLayers( GDALDatasetH hDS, 
                            int nBandCount, int *panBandList,
                            int nLayerCount, OGRLayerH *pahLayers,
                            GDALTransformerFunc pfnTransformer, 
                            void *pTransformArg, 
                            double *padfLayerBurnValues,
                            char **papszOptions,
                            GDALProgressFunc pfnProgress, 
                            void *pProgressArg )

{
    GDALDataType   eType;
    unsigned char *pabyChunkBuf;
    GDALDataset *poDS = (GDALDataset *) hDS;

    if( pfnProgress == NULL )
        pfnProgress = GDALDummyProgress;

/* -------------------------------------------------------------------- */
/*      Do some rudimentary arg checking.                               */
/* -------------------------------------------------------------------- */
    if( nBandCount == 0 || nLayerCount == 0 )
        return CE_None;

    // prototype band.
    GDALRasterBand *poBand = poDS->GetRasterBand( panBandList[0] );
    if (poBand == NULL)
        return CE_Failure;

    int bAllTouched = CSLFetchBoolean( papszOptions, "ALL_TOUCHED", FALSE );
    const char *pszOpt = CSLFetchNameValue( papszOptions, "BURN_VALUE_FROM" );
    GDALBurnValueSrc eBurnValueSource = GBV_UserBurnValue;
    if( pszOpt )
    {
        if( EQUAL(pszOpt,"Z"))
            eBurnValueSource = GBV_Z;
        /*else if( EQUAL(pszOpt,"M"))
            eBurnValueSource = GBV_M;*/
    }

/* -------------------------------------------------------------------- */
/*      Establish a chunksize to operate on.  The larger the chunk      */
/*      size the less times we need to make a pass through all the      */
/*      shapes.                                                         */
/* -------------------------------------------------------------------- */
    int         nYChunkSize, nScanlineBytes;
    const char  *pszYChunkSize =
        CSLFetchNameValue( papszOptions, "CHUNKYSIZE" );

    if( poBand->GetRasterDataType() == GDT_Byte )
        eType = GDT_Byte;
    else
        eType = GDT_Float32;

    nScanlineBytes = nBandCount * poDS->GetRasterXSize()
        * (GDALGetDataTypeSize(eType)/8);

    if ( pszYChunkSize && (nYChunkSize = atoi(pszYChunkSize)) )
        ;
    else
        nYChunkSize = GDALGetCacheMax() / nScanlineBytes;

    if( nYChunkSize < 1 )
        nYChunkSize = 1;
    if( nYChunkSize > poDS->GetRasterYSize() )
        nYChunkSize = poDS->GetRasterYSize();

    pabyChunkBuf = (unsigned char *) VSIMalloc(nYChunkSize * nScanlineBytes);
    if( pabyChunkBuf == NULL )
    {
        CPLError( CE_Failure, CPLE_OutOfMemory, 
                  "Unable to allocate rasterization buffer." );
        return CE_Failure;
    }

/* -------------------------------------------------------------------- */
/*      Read the image once for all layers if user requested to render  */
/*      the whole raster in single chunk.                               */
/* -------------------------------------------------------------------- */
    if ( nYChunkSize == poDS->GetRasterYSize() )
    {
        if ( poDS->RasterIO( GF_Read, 0, 0, poDS->GetRasterXSize(),
                             nYChunkSize, pabyChunkBuf,
                             poDS->GetRasterXSize(), nYChunkSize,
                             eType, nBandCount, panBandList, 0, 0, 0 )
             != CE_None )
        {
            CPLError( CE_Failure, CPLE_OutOfMemory, 
                      "Unable to read buffer." );
            CPLFree( pabyChunkBuf );
            return CE_Failure;
        }
    }

/* ==================================================================== */
/*      Read the specified layers transfoming and rasterizing           */
/*      geometries.                                                     */
/* ==================================================================== */
    CPLErr      eErr = CE_None;
    int         iLayer;
    const char  *pszBurnAttribute =
        CSLFetchNameValue( papszOptions, "ATTRIBUTE" );

    pfnProgress( 0.0, NULL, pProgressArg );

    for( iLayer = 0; iLayer < nLayerCount; iLayer++ )
    {
        int         iBurnField = -1;
        double      *padfBurnValues = NULL;
        OGRLayer    *poLayer = (OGRLayer *) pahLayers[iLayer];

        if ( !poLayer )
        {
            CPLError( CE_Warning, CPLE_AppDefined, 
                      "Layer element number %d is NULL, skipping.\n", iLayer );
            continue;
        }

/* -------------------------------------------------------------------- */
/*      If the layer does not contain any features just skip it.        */
/*      Do not force the feature count, so if driver doesn't know       */
/*      exact number of features, go down the normal way.               */
/* -------------------------------------------------------------------- */
        if ( poLayer->GetFeatureCount(FALSE) == 0 )
            continue;

        if ( pszBurnAttribute )
        {
            iBurnField =
                poLayer->GetLayerDefn()->GetFieldIndex( pszBurnAttribute );
            if ( iBurnField == -1 )
            {
                CPLError( CE_Warning, CPLE_AppDefined, 
                          "Failed to find field %s on layer %s, skipping.\n",
                          pszBurnAttribute, 
                          poLayer->GetLayerDefn()->GetName() );
                continue;
            }
        }
        else
            padfBurnValues = padfLayerBurnValues + iLayer * nBandCount;

/* -------------------------------------------------------------------- */
/*      If we have no transformer, create the one from input file       */
/*      projection. Note that each layer can be georefernced            */
/*      separately.                                                     */
/* -------------------------------------------------------------------- */
        int bNeedToFreeTransformer = FALSE;

        if( pfnTransformer == NULL )
        {
            char    *pszProjection = NULL;
            bNeedToFreeTransformer = TRUE;

            OGRSpatialReference *poSRS = poLayer->GetSpatialRef();
            if ( !poSRS )
            {
                CPLError( CE_Warning, CPLE_AppDefined, 
                          "Failed to fetch spatial reference on layer %s "
                          "to build transformer, assuming matching coordinate systems.\n",
                          poLayer->GetLayerDefn()->GetName() );
            }
            else
                poSRS->exportToWkt( &pszProjection );

            pTransformArg = 
                GDALCreateGenImgProjTransformer( NULL, pszProjection,
                                                 hDS, NULL, FALSE, 0.0, 0 );
            pfnTransformer = GDALGenImgProjTransform;

            CPLFree( pszProjection );
        }

        OGRFeature *poFeat;

        poLayer->ResetReading();

/* -------------------------------------------------------------------- */
/*      Loop over image in designated chunks.                           */
/* -------------------------------------------------------------------- */
        int     iY;
        for( iY = 0; 
             iY < poDS->GetRasterYSize() && eErr == CE_None; 
             iY += nYChunkSize )
        {
            int	nThisYChunkSize;

            nThisYChunkSize = nYChunkSize;
            if( nThisYChunkSize + iY > poDS->GetRasterYSize() )
                nThisYChunkSize = poDS->GetRasterYSize() - iY;

            // Only re-read image if not a single chunk is being rendered
            if ( nYChunkSize < poDS->GetRasterYSize() )
            {
                eErr = 
                    poDS->RasterIO( GF_Read, 0, iY,
                                    poDS->GetRasterXSize(), nThisYChunkSize, 
                                    pabyChunkBuf,
                                    poDS->GetRasterXSize(), nThisYChunkSize,
                                    eType, nBandCount, panBandList, 0, 0, 0 );
                if( eErr != CE_None )
                    break;
            }

            double *padfAttrValues = (double *) VSIMalloc(sizeof(double) * nBandCount);
            while( (poFeat = poLayer->GetNextFeature()) != NULL )
            {
                OGRGeometry *poGeom = poFeat->GetGeometryRef();

                if ( pszBurnAttribute )
                {
                    int         iBand;
                    double      dfAttrValue;

                    dfAttrValue = poFeat->GetFieldAsDouble( iBurnField );
                    for (iBand = 0 ; iBand < nBandCount ; iBand++)
                        padfAttrValues[iBand] = dfAttrValue;

                    padfBurnValues = padfAttrValues;
                }
                
                gv_rasterize_one_shape( pabyChunkBuf, iY,
                                        poDS->GetRasterXSize(),
                                        nThisYChunkSize,
                                        nBandCount, eType, bAllTouched, poGeom,
                                        padfBurnValues, eBurnValueSource,
                                        pfnTransformer, pTransformArg );

                delete poFeat;
            }
            VSIFree( padfAttrValues );

            // Only write image if not a single chunk is being rendered
            if ( nYChunkSize < poDS->GetRasterYSize() )
            {
                eErr = 
                    poDS->RasterIO( GF_Write, 0, iY,
                                    poDS->GetRasterXSize(), nThisYChunkSize, 
                                    pabyChunkBuf,
                                    poDS->GetRasterXSize(), nThisYChunkSize, 
                                    eType, nBandCount, panBandList, 0, 0, 0 );
            }

            poLayer->ResetReading();

            if( !pfnProgress((iY+nThisYChunkSize)/((double)poDS->GetRasterYSize()),
                             "", pProgressArg) )
            {
                CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated" );
                eErr = CE_Failure;
            }
        }

        if ( bNeedToFreeTransformer )
        {
            GDALDestroyTransformer( pTransformArg );
            pTransformArg = NULL;
            pfnTransformer = NULL;
        }
    }
    
/* -------------------------------------------------------------------- */
/*      Write out the image once for all layers if user requested       */
/*      to render the whole raster in single chunk.                     */
/* -------------------------------------------------------------------- */
    if ( nYChunkSize == poDS->GetRasterYSize() )
    {
        poDS->RasterIO( GF_Write, 0, 0,
                                poDS->GetRasterXSize(), nYChunkSize, 
                                pabyChunkBuf,
                                poDS->GetRasterXSize(), nYChunkSize, 
                                eType, nBandCount, panBandList, 0, 0, 0 );
    }

/* -------------------------------------------------------------------- */
/*      cleanup                                                         */
/* -------------------------------------------------------------------- */
    VSIFree( pabyChunkBuf );
    
    return eErr;
}
예제 #19
0
CPLErr GDALRasterizeGeometries( GDALDatasetH hDS, 
                                int nBandCount, int *panBandList,
                                int nGeomCount, OGRGeometryH *pahGeometries,
                                GDALTransformerFunc pfnTransformer, 
                                void *pTransformArg, 
                                double *padfGeomBurnValue,
                                char **papszOptions,
                                GDALProgressFunc pfnProgress, 
                                void *pProgressArg )

{
    GDALDataType   eType;
    int            nYChunkSize, nScanlineBytes;
    unsigned char *pabyChunkBuf;
    int            iY;
    GDALDataset *poDS = (GDALDataset *) hDS;

    if( pfnProgress == NULL )
        pfnProgress = GDALDummyProgress;

/* -------------------------------------------------------------------- */
/*      Do some rudimentary arg checking.                               */
/* -------------------------------------------------------------------- */
    if( nBandCount == 0 || nGeomCount == 0 )
        return CE_None;

    // prototype band.
    GDALRasterBand *poBand = poDS->GetRasterBand( panBandList[0] );
    if (poBand == NULL)
        return CE_Failure;

    int bAllTouched = CSLFetchBoolean( papszOptions, "ALL_TOUCHED", FALSE );
    const char *pszOpt = CSLFetchNameValue( papszOptions, "BURN_VALUE_FROM" );
    GDALBurnValueSrc eBurnValueSource = GBV_UserBurnValue;
    if( pszOpt )
    {
        if( EQUAL(pszOpt,"Z"))
            eBurnValueSource = GBV_Z;
        /*else if( EQUAL(pszOpt,"M"))
            eBurnValueSource = GBV_M;*/
    }

/* -------------------------------------------------------------------- */
/*      If we have no transformer, assume the geometries are in file    */
/*      georeferenced coordinates, and create a transformer to          */
/*      convert that to pixel/line coordinates.                         */
/*                                                                      */
/*      We really just need to apply an affine transform, but for       */
/*      simplicity we use the more general GenImgProjTransformer.       */
/* -------------------------------------------------------------------- */
    int bNeedToFreeTransformer = FALSE;

    if( pfnTransformer == NULL )
    {
        bNeedToFreeTransformer = TRUE;

        pTransformArg = 
            GDALCreateGenImgProjTransformer( NULL, NULL, hDS, NULL, 
                                             FALSE, 0.0, 0);
        pfnTransformer = GDALGenImgProjTransform;
    }

/* -------------------------------------------------------------------- */
/*      Establish a chunksize to operate on.  The larger the chunk      */
/*      size the less times we need to make a pass through all the      */
/*      shapes.                                                         */
/* -------------------------------------------------------------------- */
    if( poBand->GetRasterDataType() == GDT_Byte )
        eType = GDT_Byte;
    else
        eType = GDT_Float32;

    nScanlineBytes = nBandCount * poDS->GetRasterXSize()
        * (GDALGetDataTypeSize(eType)/8);
    nYChunkSize = 10000000 / nScanlineBytes;
    if( nYChunkSize > poDS->GetRasterYSize() )
        nYChunkSize = poDS->GetRasterYSize();

    pabyChunkBuf = (unsigned char *) VSIMalloc(nYChunkSize * nScanlineBytes);
    if( pabyChunkBuf == NULL )
    {
        CPLError( CE_Failure, CPLE_OutOfMemory, 
                  "Unable to allocate rasterization buffer." );
        return CE_Failure;
    }

/* ==================================================================== */
/*      Loop over image in designated chunks.                           */
/* ==================================================================== */
    CPLErr  eErr = CE_None;

    pfnProgress( 0.0, NULL, pProgressArg );

    for( iY = 0; 
         iY < poDS->GetRasterYSize() && eErr == CE_None; 
         iY += nYChunkSize )
    {
        int	nThisYChunkSize;
        int     iShape;

        nThisYChunkSize = nYChunkSize;
        if( nThisYChunkSize + iY > poDS->GetRasterYSize() )
            nThisYChunkSize = poDS->GetRasterYSize() - iY;

        eErr = 
            poDS->RasterIO(GF_Read, 
                           0, iY, poDS->GetRasterXSize(), nThisYChunkSize, 
                           pabyChunkBuf,poDS->GetRasterXSize(),nThisYChunkSize,
                           eType, nBandCount, panBandList,
                           0, 0, 0 );
        if( eErr != CE_None )
            break;

        for( iShape = 0; iShape < nGeomCount; iShape++ )
        {
            gv_rasterize_one_shape( pabyChunkBuf, iY,
                                    poDS->GetRasterXSize(), nThisYChunkSize,
                                    nBandCount, eType, bAllTouched,
                                    (OGRGeometry *) pahGeometries[iShape],
                                    padfGeomBurnValue + iShape*nBandCount,
                                    eBurnValueSource,
                                    pfnTransformer, pTransformArg );
        }

        eErr = 
            poDS->RasterIO( GF_Write, 0, iY,
                            poDS->GetRasterXSize(), nThisYChunkSize, 
                            pabyChunkBuf,
                            poDS->GetRasterXSize(), nThisYChunkSize, 
                            eType, nBandCount, panBandList, 0, 0, 0 );

        if( !pfnProgress((iY+nThisYChunkSize)/((double)poDS->GetRasterYSize()),
                         "", pProgressArg ) )
        {
            CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated" );
            eErr = CE_Failure;
        }
    }
    
/* -------------------------------------------------------------------- */
/*      cleanup                                                         */
/* -------------------------------------------------------------------- */
    VSIFree( pabyChunkBuf );
    
    if( bNeedToFreeTransformer )
        GDALDestroyTransformer( pTransformArg );

    return eErr;
}