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

Pol Monsó Purtí lluna.nova at gmail.com
Mon Jun 6 07:00:55 PDT 2016


Same result.

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);


    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]);

            papszOptions2 = CSLSetNameValue( papszOptions2,
"DATAPOINTER", opts );

            poDstDS->AddBand(GDT_Byte, 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);

    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)*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
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osgeo.org/pipermail/gdal-dev/attachments/20160606/c062de1d/attachment-0001.html>


More information about the gdal-dev mailing list