Marc Pelletier wrote:
Hello,
I am having trouble implementing the following callback:
CNCSError CECWCompressor::WriteReadLine(UINT32 nNextLine, void
**ppInputArray)
where ppInputArray is a 3 by x array. The length of x is not known at
compile time.
I can't seem to dereference ppInputArray in a way that the compiler is
happy with. This is what I would like to do, but I get a 'Cannot
convert from void* to float[]' error.
float Red[] = ppInputArray[0];
float Green[] = ppInputArray[1];
float Blue[] = ppInputArray[2];
for ( UINT32 x = 0; x < pInfo->nSizeX; x++ ) {
rgb = image.GetPixel( x, nNextLine );
Red[x] = (float)GetRValue( rgb );
Green[x] = (float)GetGValue( rgb );
Blue[x] = (float)GetBValue( rgb );
}
<code>
float** ppf = static_cast<float**>(ppInputArray);
float* Red = ppf[0];
float* Green = ppf[1];
float* Blue = ppf[2];
for (...)
</code>
Note that this is an odd organization for an array of triples. In memory,
this will have all of the Red values, followed by all of the Blue values,
follwed by all of the Green values.
It seems unlikely to me that that's what you really wanted, since more
typically the RGB values of a particular triple will be adjacent in memory.
In that case, you would want something like:
<code>
float* pf = static_cast<float*>(*ppInputArray);
for (...)
pf[0] = (float)GetRValue(...);
pf[1] = (float)GetGValue(...);
pf[2] = (float)GetBValue(...);
pf += 3;
</code>
If you have any control over the defintion of this callback (i.e. control
over the caller of the code), I'd strongly recommend changing the signature
to avoid passing void** parameters. Instead, this callback really ought to
be defined something like:
struct rgb_t
{
float r;
float g;
float b;
};
CNCSError CECWCompressor::WriteReadLine(UINT32 nNextLine, rgb_t*
pInputArray);
But if you don't control the caller, or this is but one overload of a
general purpose mechanism (which I suspect it might be), then you're
probably stuck with the signature you've got.
One other comment: passing the input array as a double-indirect pointer
often implies that the called routine is expected to allocate the memory to
be filled and assign the pointer to the newly allocated memory through the
given pointer-to-pointer.
<code>
float* pf = (float*)malloc(3*sizeof(float)*???);
for (...)
pf[0] = (float)GetRValue(...);
pf[1] = (float)GetGValue(...);
pf[2] = (float)GetBValue(...);
pf += 3;
*ppInputArray = pf;
</code>
If you're not allocating the array in the callback, there's really no point
in passing a pointer to pointer parameter.
-cd