[gdal-dev] Fwd: How to reuse memory pointer of GDAL Memory driver
Pol Monsó Purtí
lluna.nova at gmail.com
Mon Jun 6 07:16:42 PDT 2016
Thanks Even, the previous message was prematurely sent by error and the
corrected version held because it was to big (? probably a mishap with the
mail headers)
Yeah the numbands are 0. I stripped out irrellevant parts of code and I
missed to add that. To be sure I checked with the debugger, the dataset
object holds 0 then 3 after the addition.
My comment on the previous message was:
Premature sent with bad formatting.
Same result. Maybe something wrong with the rasters? I'll try initialising
them right there on the same function to be sure.
The access violation says Read access violation at 0x0. Does it mean I have
a null pointer somewhere? Should I pass more options to the addBand?
I've inspected the dataset, as well as its band member. Where should I find
the data pointer? The dimensions are correct.
What else could I check? maybe a data write to the mem driver?
I've indeed skipped all the memory leaks, I'll add them and get back to
you if I get a different message.
On Mon, Jun 6, 2016 at 4:10 PM, Even Rouault <even.rouault at spatialys.com>
wrote:
> See comments inline below
>
> >
> > The code:
> >
> >
> > GDALDriver *poDriver =
> > GetGDALDriverManager()->GetDriverByName(pszFormat);
> >
> >
> > if(!poDriver)
> >
> > {
> >
> > std::cerr << "Driver " << pszFormat << " couldn't be loaded."
> > << std::endl;
> >
> > return -4;
> >
> > }
> >
> >
> > poDstDS = poDriver->Create(
> > auxfilepath.string().c_str(),(int)width, (int)height,
> >
> > numbands, GDT_Byte, papszOptions);
>
>
> --> numbands should be replaced by 0, since you add the bands afterwards
>
> >
> >
> > if(poDstDS == NULL)
> >
> > {
> >
> >
> > std::cerr << "Failure when creating output orthoimage " << auxfilepath <<
> > std::endl;
> >
> > return -5;
> >
> > }
> >
> >
> > if(filepath.extension() == ".jpg")
> >
> > {
> >
> > char **papszOptions2 = NULL;
> >
> > for(unsigned int b = 0; b < RGBRasterBands::NUMBANDS; b++)
> >
> > {
> >
> > char* opts = (char*) malloc(1024);
> >
> > sprintf(opts, "%p",&abyRasters[b]);
>
> For portability, rather use CPLPrintPointer( char *pszBuffer, void
> *pValue, int
> nMaxLen ). See
> https://svn.osgeo.org/gdal/trunk/gdal/frmts/vrt/vrtdriver.cpp
> for an example how to use it
>
> >
> > papszOptions2 = CSLSetNameValue( papszOptions2,
> > "DATAPOINTER", opts );
> >
> > poDstDS->AddBand(GDT_Byte, papszOptions2);
>
>
> Missing CSLDestroy(papszOptions2)
>
> >
> > free(opts);
> >
> > }
> >
> > }
> >
> >
> > //jpeg write test:
> >
> > 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);
>
> Missing CSLDestroy(papszOptions2)
>
> >
> > if(jpeg_ds == NULL)
> >
> > {
> >
> > std::cout << "Failure when creating output orthoimage " <<
> > filepath << std::endl;
> >
> > return -5;
> >
> > }
> >
> >
> >
> > On Mon, Jun 6, 2016 at 2:58 PM, Even Rouault <even.rouault at spatialys.com
> >
> >
> > wrote:
> > > 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)*rasterMemory
> > > D
> > >
> > > > 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
>
> --
> Spatialys - Geospatial professional services
> http://www.spatialys.com
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osgeo.org/pipermail/gdal-dev/attachments/20160606/06f35502/attachment-0001.html>
More information about the gdal-dev
mailing list