[gdal-dev] Fwd: How to reuse memory pointer of GDAL Memory driver

Even Rouault even.rouault at spatialys.com
Mon Jun 6 05:58:15 PDT 2016


On Monday 06 June 2016 14:53:46 Pol Monsó Purtí wrote:
> Let's jump to particulars, at the end, the code.
> 
> If I set the DATAPOINTER to NULL the program crashes at CreateCopy with
> access violation. Same if I set it to the datapointer to &abyRaster[0] and
> add the remaining two bands.

Use the Create() method of GDALDriver with 0 bands and no options. I'm not 
sure how Open() and AddBand() play together.

> 
> The abyRasters are initialized to white color with memset. SO this piece of
> code should give me a white jpg square of widthxheight. I could set a
> complete MWE if necessary.
> 
> And, the code:
> 
>         char* filename = (char*) malloc(1024);
> 
>         sprintf(filename, "MEM:::DATAPOINTER=%p,PIXELS=%d,LINES=%d,BANDS=0",
> 
>                 NULL, width, height);
> 
>         poDstDS = (GDALDataset *) GDALOpen(filename,GA_Update);
> 
> 
>         free(filename);
> 
> 
>         for(unsigned int b = 0; b < RGBRasterBands::NUMBANDS; b++)
> 
>         {
> 
>             //assert(sizeof(long) == sizeof(void*));
> 
>             const void * address = static_cast<const void*>(&abyRasters[b]);
> 
>             std::stringstream ss;
> 
>             ss << address;
> 
>             const char * datapointer = ss.str().c_str();
> 
>             std::cout << "datapointer: " << datapointer << std::endl;
> 
>             papszOptions = CSLSetNameValue( papszOptions,
> "DATAPOINTER", datapointer );
> 
>             poDstDS->AddBand(GDT_Byte, papszOptions);
> 
> 
>         }
> 
>         char **papszOptions2 = NULL;
> 
>         papszOptions2 = CSLSetNameValue( papszOptions2, "QUALITY", "40" );
> 
> 
>         std::cout << "Copying to " << filepath << std::endl;
> 
>         GDALDriver* jpegDriver =
> GetGDALDriverManager()->GetDriverByName("JPEG");
> 
>         GDALDataset* jpeg_ds =
> jpegDriver->CreateCopy(filepath.string().c_str(), poDstDS, false,
> papszOptions2, GDALDummyProgress, NULL);
> 
>         if(jpeg_ds == NULL)
> 
>         {
> 
>             std::cout << "Failure when creating output orthoimage " <<
> filepath << std::endl;
> 
>             return -5;
> 
>         }
> 
> The abyRasters are allocated with
> 
>         for(int b = 0; b < RGBRasterBands::NUMBANDS; b++)
>         {
>             abyRasters.push_back(new
> GByte[rasterMemoryDimensions.width*rasterMemoryDimensions.height]());
>            
> memset(&abyRasters[b][0],QuickDrop::NODATAVALUE,sizeof(GByte)*rasterMemoryD
> imensions.width*rasterMemoryDimensions.height); }
> 
> 
> On Mon, Jun 6, 2016 at 12:35 PM, Pol Monsó Purtí <lluna.nova at gmail.com>
> 
> wrote:
> > Just one more question,
> > 
> > If i set the option BAND=0, what should the DATAPOINTER be? Does it become
> > optional?
> > 
> > Cheers
> > 
> > On Mon, Jun 6, 2016 at 10:55 AM, Even Rouault <even.rouault at spatialys.com>
> > 
> > wrote:
> >> On Monday 06 June 2016 10:45:47 Pol Monsó Purtí wrote:
> >> > THanks Mateusz,
> >> > 
> >> > You're right. I'm trying it as we speak.
> >> > 
> >> > In my case I have a std::vector<GByte*> of the 3 bands, where the
> >> > GByte*
> >> > are allocated in the heap with new GByte[width*height]. I guess that
> >> 
> >> won't
> >> 
> >> > work because the three bands have to be one single memory chunk, am I
> >> > right? I guess the only solution is to switch to single band float and
> >> > merge rgb to float. I'd prefer not having to refactor the rest of the
> >> 
> >> code.
> >> 
> >> > Is it possible to have a different address for each band?
> >> 
> >> Yes, create a dataset with 0 band and then add each band with the
> >> GDALDataset::AddBand() method
> >> 
> >> See http://gdal.org/frmt_mem.html :
> >> """The MEM format is one of the few that supports the AddBand() method.
> >> The
> >> AddBand() method supports DATAPOINTER, PIXELOFFSET and LINEOFFSET options
> >> to
> >> reference an existing memory array."""
> >> 
> >> > All this is to support jpg as output. All the operations are done in my
> >> > GByte array and it's only at the end that I create the dataset and
> >> 
> >> image.
> >> 
> >> > At the moment I create a Tiff and finally createcopy to jpg.
> >> > 
> >> > On Fri, Jun 3, 2016 at 9:10 PM, Mateusz Loskot <mateusz at loskot.net>
> >> 
> >> wrote:
> >> > > On 3 June 2016 at 20:45, Pol Monsó Purtí <lluna.nova at gmail.com>
> >> 
> >> wrote:
> >> > > > I've seen this mysterious article http://www.gdal.org/frmt_mem.html
> >> > > 
> >> > > which
> >> > > 
> >> > > > references the `DATAPOINTER` option. I've seen another reference
> >> > > > [here](
> >> > > 
> >> > > https://lists.osgeo.org/pipermail/gdal-dev/2006-November/010583.html)
> >> > > 
> >> > > > which does
> >> 
> >> sprintf(filename,"MEM:::DATAPOINTER=%d,PIXELS=%d,LINES=%d,BANDS=1,DATATYP
> >> E
> >> 
> >> 
> >> =%d,PIXELOFFSET=0,LINEOFFSET=0,BANDOFFSET=0",datpt,pixels,lines,datatype)
> >> ;>
> >> 
> >> > > >     dataset = GDALOpen(filename,GA_Update);
> >> > > > 
> >> > > > How would this translate to c++?
> >> > > 
> >> > > The line above is valid C++, isn't it.
> >> > > If you followed to Frank's answer [1], you'd see it slightly
> >> > > corrected
> >> > > but the technique remains the same.
> >> > > 
> >> > > [1]
> >> 
> >> https://lists.osgeo.org/pipermail/gdal-dev/2006-November/010603.html
> >> 
> >> > > Best regards,
> >> > > --
> >> > > Mateusz Loskot, http://mateusz.loskot.net
> >> 
> >> --
> >> Spatialys - Geospatial professional services
> >> http://www.spatialys.com

-- 
Spatialys - Geospatial professional services
http://www.spatialys.com


More information about the gdal-dev mailing list