<div dir="ltr"><div><div>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)<br><br></div>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.<br><br></div><div>My comment on the previous message was:<br><br><blockquote>Premature sent with bad formatting.<br><br><div>Same result. Maybe something wrong with the rasters? I'll try initialising them right there on the same function to be sure.<br><br></div><div>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?<br><br></div><div>I've inspected the dataset, as well as its band member. Where should I find the data pointer? The dimensions are correct.<br><br></div>What else could I check? maybe a data write to the mem driver?<br></blockquote></div><div><br></div>I've indeed skipped all the memory leaks, I'll add them and get back to you if I get a different message.<br><br><br></div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Jun 6, 2016 at 4:10 PM, Even Rouault <span dir="ltr"><<a href="mailto:even.rouault@spatialys.com" target="_blank">even.rouault@spatialys.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">See comments inline below<br>
<span class=""><br>
><br>
> The code:<br>
><br>
><br>
> GDALDriver *poDriver =<br>
> GetGDALDriverManager()->GetDriverByName(pszFormat);<br>
><br>
><br>
> if(!poDriver)<br>
><br>
> {<br>
><br>
> std::cerr << "Driver " << pszFormat << " couldn't be loaded."<br>
> << std::endl;<br>
><br>
> return -4;<br>
><br>
> }<br>
><br>
><br>
> poDstDS = poDriver->Create(<br>
> auxfilepath.string().c_str(),(int)width, (int)height,<br>
><br>
> numbands, GDT_Byte, papszOptions);<br>
<br>
<br>
</span>--> numbands should be replaced by 0, since you add the bands afterwards<br>
<span class=""><br>
><br>
><br>
> if(poDstDS == NULL)<br>
><br>
> {<br>
><br>
><br>
> std::cerr << "Failure when creating output orthoimage " << auxfilepath <<<br>
> std::endl;<br>
><br>
> return -5;<br>
><br>
> }<br>
><br>
><br>
> if(filepath.extension() == ".jpg")<br>
><br>
> {<br>
><br>
> char **papszOptions2 = NULL;<br>
><br>
> for(unsigned int b = 0; b < RGBRasterBands::NUMBANDS; b++)<br>
><br>
> {<br>
><br>
> char* opts = (char*) malloc(1024);<br>
><br>
> sprintf(opts, "%p",&abyRasters[b]);<br>
<br>
</span>For portability, rather use CPLPrintPointer( char *pszBuffer, void *pValue, int<br>
nMaxLen ). See <a href="https://svn.osgeo.org/gdal/trunk/gdal/frmts/vrt/vrtdriver.cpp" rel="noreferrer" target="_blank">https://svn.osgeo.org/gdal/trunk/gdal/frmts/vrt/vrtdriver.cpp</a><br>
for an example how to use it<br>
<span class=""><br>
><br>
> papszOptions2 = CSLSetNameValue( papszOptions2,<br>
> "DATAPOINTER", opts );<br>
><br>
> poDstDS->AddBand(GDT_Byte, papszOptions2);<br>
<br>
<br>
</span>Missing CSLDestroy(papszOptions2)<br>
<span class=""><br>
><br>
> free(opts);<br>
><br>
> }<br>
><br>
> }<br>
><br>
><br>
> //jpeg write test:<br>
><br>
> char **papszOptions2 = NULL;<br>
><br>
> papszOptions2 = CSLSetNameValue( papszOptions2, "QUALITY", "40" );<br>
><br>
> std::cout << "Copying to " << filepath << std::endl;<br>
><br>
> GDALDriver* jpegDriver =<br>
> GetGDALDriverManager()->GetDriverByName("JPEG");<br>
><br>
> GDALDataset* jpeg_ds =<br>
> jpegDriver->CreateCopy(filepath.string().c_str(), poDstDS, false,<br>
> papszOptions2, GDALDummyProgress, NULL);<br>
<br>
</span>Missing CSLDestroy(papszOptions2)<br>
<div class="HOEnZb"><div class="h5"><br>
><br>
> if(jpeg_ds == NULL)<br>
><br>
> {<br>
><br>
> std::cout << "Failure when creating output orthoimage " <<<br>
> filepath << std::endl;<br>
><br>
> return -5;<br>
><br>
> }<br>
><br>
><br>
><br>
> On Mon, Jun 6, 2016 at 2:58 PM, Even Rouault <<a href="mailto:even.rouault@spatialys.com">even.rouault@spatialys.com</a>><br>
><br>
> wrote:<br>
> > On Monday 06 June 2016 14:53:46 Pol Monsó Purtí wrote:<br>
> > > Let's jump to particulars, at the end, the code.<br>
> > ><br>
> > > If I set the DATAPOINTER to NULL the program crashes at CreateCopy with<br>
> > > access violation. Same if I set it to the datapointer to &abyRaster[0]<br>
> ><br>
> > and<br>
> ><br>
> > > add the remaining two bands.<br>
> ><br>
> > Use the Create() method of GDALDriver with 0 bands and no options. I'm not<br>
> > sure how Open() and AddBand() play together.<br>
> ><br>
> > > The abyRasters are initialized to white color with memset. SO this piece<br>
> ><br>
> > of<br>
> ><br>
> > > code should give me a white jpg square of widthxheight. I could set a<br>
> > > complete MWE if necessary.<br>
> > ><br>
> > > And, the code:<br>
> > > char* filename = (char*) malloc(1024);<br>
> > ><br>
> > > sprintf(filename,<br>
> ><br>
> > "MEM:::DATAPOINTER=%p,PIXELS=%d,LINES=%d,BANDS=0",<br>
> ><br>
> > > NULL, width, height);<br>
> > ><br>
> > > poDstDS = (GDALDataset *) GDALOpen(filename,GA_Update);<br>
> > ><br>
> > ><br>
> > > free(filename);<br>
> > ><br>
> > ><br>
> > > for(unsigned int b = 0; b < RGBRasterBands::NUMBANDS; b++)<br>
> > ><br>
> > > {<br>
> > ><br>
> > > //assert(sizeof(long) == sizeof(void*));<br>
> > ><br>
> > > const void * address = static_cast<const<br>
> ><br>
> > void*>(&abyRasters[b]);<br>
> ><br>
> > > std::stringstream ss;<br>
> > ><br>
> > > ss << address;<br>
> > ><br>
> > > const char * datapointer = ss.str().c_str();<br>
> > ><br>
> > > std::cout << "datapointer: " << datapointer << std::endl;<br>
> > ><br>
> > > papszOptions = CSLSetNameValue( papszOptions,<br>
> > ><br>
> > > "DATAPOINTER", datapointer );<br>
> > ><br>
> > > poDstDS->AddBand(GDT_Byte, papszOptions);<br>
> > ><br>
> > > }<br>
> > ><br>
> > > char **papszOptions2 = NULL;<br>
> > ><br>
> > > papszOptions2 = CSLSetNameValue( papszOptions2, "QUALITY", "40"<br>
> ><br>
> > );<br>
> ><br>
> > > std::cout << "Copying to " << filepath << std::endl;<br>
> > ><br>
> > > GDALDriver* jpegDriver =<br>
> > ><br>
> > > GetGDALDriverManager()->GetDriverByName("JPEG");<br>
> > ><br>
> > > GDALDataset* jpeg_ds =<br>
> > ><br>
> > > jpegDriver->CreateCopy(filepath.string().c_str(), poDstDS, false,<br>
> > > papszOptions2, GDALDummyProgress, NULL);<br>
> > ><br>
> > > if(jpeg_ds == NULL)<br>
> > ><br>
> > > {<br>
> > ><br>
> > > std::cout << "Failure when creating output orthoimage " <<<br>
> > ><br>
> > > filepath << std::endl;<br>
> > ><br>
> > > return -5;<br>
> > ><br>
> > > }<br>
> > ><br>
> > > The abyRasters are allocated with<br>
> > ><br>
> > > for(int b = 0; b < RGBRasterBands::NUMBANDS; b++)<br>
> > > {<br>
> > ><br>
> > > abyRasters.push_back(new<br>
> > ><br>
> > > GByte[rasterMemoryDimensions.width*rasterMemoryDimensions.height]());<br>
> ><br>
> > memset(&abyRasters[b][0],QuickDrop::NODATAVALUE,sizeof(GByte)*rasterMemory<br>
> > D<br>
> ><br>
> > > imensions.width*rasterMemoryDimensions.height); }<br>
> > ><br>
> > ><br>
> > > On Mon, Jun 6, 2016 at 12:35 PM, Pol Monsó Purtí <<a href="mailto:lluna.nova@gmail.com">lluna.nova@gmail.com</a>><br>
> > ><br>
> > > wrote:<br>
> > > > Just one more question,<br>
> > > ><br>
> > > > If i set the option BAND=0, what should the DATAPOINTER be? Does it<br>
> ><br>
> > become<br>
> ><br>
> > > > optional?<br>
> > > ><br>
> > > > Cheers<br>
> > > ><br>
> > > > On Mon, Jun 6, 2016 at 10:55 AM, Even Rouault <<br>
> ><br>
> > <a href="mailto:even.rouault@spatialys.com">even.rouault@spatialys.com</a>><br>
> ><br>
> > > > wrote:<br>
> > > >> On Monday 06 June 2016 10:45:47 Pol Monsó Purtí wrote:<br>
> > > >> > THanks Mateusz,<br>
> > > >> ><br>
> > > >> > You're right. I'm trying it as we speak.<br>
> > > >> ><br>
> > > >> > In my case I have a std::vector<GByte*> of the 3 bands, where the<br>
> > > >> > GByte*<br>
> > > >> > are allocated in the heap with new GByte[width*height]. I guess<br>
> > > >> > that<br>
> > > >><br>
> > > >> won't<br>
> > > >><br>
> > > >> > work because the three bands have to be one single memory chunk, am<br>
> ><br>
> > I<br>
> ><br>
> > > >> > right? I guess the only solution is to switch to single band float<br>
> ><br>
> > and<br>
> ><br>
> > > >> > merge rgb to float. I'd prefer not having to refactor the rest of<br>
> ><br>
> > the<br>
> ><br>
> > > >> code.<br>
> > > >><br>
> > > >> > Is it possible to have a different address for each band?<br>
> > > >><br>
> > > >> Yes, create a dataset with 0 band and then add each band with the<br>
> > > >> GDALDataset::AddBand() method<br>
> > > >><br>
> > > >> See <a href="http://gdal.org/frmt_mem.html" rel="noreferrer" target="_blank">http://gdal.org/frmt_mem.html</a> :<br>
> > > >> """The MEM format is one of the few that supports the AddBand()<br>
> ><br>
> > method.<br>
> ><br>
> > > >> The<br>
> > > >> AddBand() method supports DATAPOINTER, PIXELOFFSET and LINEOFFSET<br>
> ><br>
> > options<br>
> ><br>
> > > >> to<br>
> > > >> reference an existing memory array."""<br>
> > > >><br>
> > > >> > All this is to support jpg as output. All the operations are done<br>
> ><br>
> > in my<br>
> ><br>
> > > >> > GByte array and it's only at the end that I create the dataset and<br>
> > > >><br>
> > > >> image.<br>
> > > >><br>
> > > >> > At the moment I create a Tiff and finally createcopy to jpg.<br>
> > > >> ><br>
> > > >> > On Fri, Jun 3, 2016 at 9:10 PM, Mateusz Loskot <<a href="mailto:mateusz@loskot.net">mateusz@loskot.net</a>><br>
> > > >><br>
> > > >> wrote:<br>
> > > >> > > On 3 June 2016 at 20:45, Pol Monsó Purtí <<a href="mailto:lluna.nova@gmail.com">lluna.nova@gmail.com</a>><br>
> > > >><br>
> > > >> wrote:<br>
> > > >> > > > I've seen this mysterious article<br>
> ><br>
> > <a href="http://www.gdal.org/frmt_mem.html" rel="noreferrer" target="_blank">http://www.gdal.org/frmt_mem.html</a><br>
> ><br>
> > > >> > > which<br>
> > > >> > ><br>
> > > >> > > > references the `DATAPOINTER` option. I've seen another<br>
> > > >> > > > reference<br>
> > > >> > > > [here](<br>
> ><br>
> > <a href="https://lists.osgeo.org/pipermail/gdal-dev/2006-November/010583.html" rel="noreferrer" target="_blank">https://lists.osgeo.org/pipermail/gdal-dev/2006-November/010583.html</a>)<br>
> ><br>
> > > >> > > > which does<br>
> ><br>
> > sprintf(filename,"MEM:::DATAPOINTER=%d,PIXELS=%d,LINES=%d,BANDS=1,DATATYP<br>
> ><br>
> > > >> E<br>
> ><br>
> > =%d,PIXELOFFSET=0,LINEOFFSET=0,BANDOFFSET=0",datpt,pixels,lines,datatype)<br>
> ><br>
> > > >> ;><br>
> > > >><br>
> > > >> > > > dataset = GDALOpen(filename,GA_Update);<br>
> > > >> > > ><br>
> > > >> > > > How would this translate to c++?<br>
> > > >> > ><br>
> > > >> > > The line above is valid C++, isn't it.<br>
> > > >> > > If you followed to Frank's answer [1], you'd see it slightly<br>
> > > >> > > corrected<br>
> > > >> > > but the technique remains the same.<br>
> > > >> > ><br>
> > > >> > > [1]<br>
> > > >><br>
> > > >> <a href="https://lists.osgeo.org/pipermail/gdal-dev/2006-November/010603.html" rel="noreferrer" target="_blank">https://lists.osgeo.org/pipermail/gdal-dev/2006-November/010603.html</a><br>
> > > >><br>
> > > >> > > Best regards,<br>
> > > >> > > --<br>
> > > >> > > Mateusz Loskot, <a href="http://mateusz.loskot.net" rel="noreferrer" target="_blank">http://mateusz.loskot.net</a><br>
> > > >><br>
> > > >> --<br>
> > > >> Spatialys - Geospatial professional services<br>
> > > >> <a href="http://www.spatialys.com" rel="noreferrer" target="_blank">http://www.spatialys.com</a><br>
> ><br>
> > --<br>
> > Spatialys - Geospatial professional services<br>
> > <a href="http://www.spatialys.com" rel="noreferrer" target="_blank">http://www.spatialys.com</a><br>
<br>
--<br>
Spatialys - Geospatial professional services<br>
<a href="http://www.spatialys.com" rel="noreferrer" target="_blank">http://www.spatialys.com</a><br>
</div></div></blockquote></div><br></div>