3

I am doing the same as in [GDAL API]: can't save image in some formats

That is, saving a JPEG image with GDAL. I know I'd have to create a MEM buffer and then CreateCopy to JPEG. However, I'd like to avoid the allocation of two buffers since my image might be big and I use my own memory buffer.

Is there a way to pass the data memory address that I'd like to use to the MEM driver?

I've seen this mysterious article http://www.gdal.org/frmt_mem.html which references the DATAPOINTER option. I've seen another reference here which does

sprintf(filename,"MEM:::DATAPOINTER=%d,PIXELS=%d,LINES=%d,BANDS=1,DATATYPE=%d,PIXELOFFSET=0,LINEOFFSET=0,BANDOFFSET=0",datpt,pixels,lines,datatype);
dataset = GDALOpen(filename,GA_Update);

How would this translate to c++? Maybe

    papszOptions = CSLSetNameValue( papszOptions, "DATAPOINTER", datapointer );

and so on?

1 Answer 1

3

The issue was resolved in the gdal-dev mailing list, here's how:

  1. create the MEM driver and create the mem image with 0 bands
  2. Get the pointer to your allocated memory with CPLPrintPointer
  3. Use AddBand from the dataset to add the bands

e.g. (error checking omitted)

unsigned int numbands = 0;
char **papszOptions = NULL;
GDALDriver *poDriver  = GetGDALDriverManager()->GetDriverByName("MEM");

GDALDataset* poDstDS = poDriver->Create( "dummyname",(int)width, (int)height, numbands, GDT_Byte, papszOptions);

for(unsigned int b = 0; b < 3; b++)
{
    char szPtrValue[128] = { '\0' };
    int nRet = CPLPrintPointer( szPtrValue,
                                reinterpret_cast<void*>(abyRasters[b]),
                                sizeof(szPtrValue) );
    szPtrValue[nRet] = 0;
    papszOptions = CSLSetNameValue(papszOptions,
                                   "DATAPOINTER", szPtrValue);
    poDstDS->AddBand(GDT_Byte, papszOptions);
}
CSLDestroy(papszOptions);

//jpeg write test:
{
    char **papszOptions2 = NULL;
    papszOptions2 = CSLSetNameValue( papszOptions2, "QUALITY", "40" );
    GDALDriver* jpegDriver = GetGDALDriverManager()->GetDriverByName("JPEG");
    GDALDataset* jpeg_ds = jpegDriver->CreateCopy("somename.jpg", poDstDS, false, papszOptions2, GDALDummyProgress, NULL);
    CSLDestroy(papszOptions2);
    GDALClose( (GDALDatasetH) jpeg_ds );
}

GDALClose( (GDALDatasetH) poDstDS );

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.