470,635 Members | 2,279 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 470,635 developers. It's quick & easy.

array of pointers to float

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

Every other permutation I can think of also cannot be converted for one
reason or another. How can I fill this structure?

Thanks for any help.

Marc Pelletier
Nov 17 '05 #1
11 2089
Marc Pelletier <no******@please.com> wrote in news:Xns966CF17C7882Ampdd445@
207.46.248.16:
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 );
}


Sorry, I should have mentioned that the compiler error is actually on the
first line above

float Red[] = ppInputArray[0];

cheers

Marc
Nov 17 '05 #2
Marc Pelletier <ma**@stopspam.goldak.ca> wrote:
Marc Pelletier <no******@please.com> wrote in news:Xns966CF17C7882Ampdd445@
207.46.248.16:
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 );
}

Sorry, I should have mentioned that the compiler error is actually on the
first line above

float Red[] = ppInputArray[0];


Hard to say anything if you don't even provide
the definition of 'ppInputArray'.
Marc


Schobi

--
Sp******@gmx.de is never read
I'm Schobi at suespammers dot org

"Coming back to where you started is not the same as never leaving"
Terry Pratchett

Nov 17 '05 #3
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


Nov 17 '05 #4
Carl,

Thanks for your comments. I've replied below.

"Carl Daniel [VC++ MVP]"
<cp*****************************@mvps.org.nospam > wrote in
news:#G*************@TK2MSFTNGP10.phx.gbl:
<code>
float** ppf = static_cast<float**>(ppInputArray);

float* Red = ppf[0];
float* Green = ppf[1];
float* Blue = ppf[2];

for (...)
</code>
This gives me an "error C2440: 'static_cast': cannot convert from
'void**' to 'float**'". I'm new to c++ and am surprised at how hard it is
to get the compiler to swallow this. What is the purpose of void pointers
if the compiler won't allow you to cast them? Is there a project option I
can use?

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:

This format (and library) is inherited from satellite imagery which can
have many bands. Its known as BIL or binary interleaved (I think). Its
from the ERMapper ECW/JPeg200 sdk.

...snip..
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.


Well this is interesting. I dont think this is the case as there are some
working examples for the C interface that don't allocate memory. In those
examples it is dereferenced like this:
float *pRed = ppInputArray[0];

but that won't compile in c++ either.

cheers

Marc
Nov 17 '05 #5
"Hendrik Schober" <Sp******@gmx.de> wrote in news:#OpbEX2aFHA.3400
@tk2msftngp13.phx.gbl:
Hard to say anything if you don't even provide
the definition of 'ppInputArray'.


Sorry, I could have been clearer. ppInputArray is a 3 (in my case) element
array of pointers to arrays of float. It represents storage for one line of
multiband raster data.

cheers

Marc
Nov 17 '05 #6
Marc Pelletier <ma**@stopspam.goldak.ca> wrote in
news:Xn*************************@207.46.248.16:
This gives me an "error C2440: 'static_cast': cannot convert from
'void**' to 'float**'". I'm new to c++ and am surprised at how hard it
is to get the compiler to swallow this. What is the purpose of void
pointers if the compiler won't allow you to cast them? Is there a
project option I can use?


I should probably also mention I am using visual studio .net 7.1.3088
cheers

Marc
Nov 17 '05 #7
Marc Pelletier <ma**@stopspam.goldak.ca> wrote:
"Hendrik Schober" <Sp******@gmx.de> wrote in news:#OpbEX2aFHA.3400
@tk2msftngp13.phx.gbl:
Hard to say anything if you don't even provide
the definition of 'ppInputArray'.
Sorry, I could have been clearer. ppInputArray is a 3 (in my case) element
array of pointers to arrays of float. It represents storage for one line of
multiband raster data.


That's an explanation of what you think
'ppInputArray' is, not the definition.
(Your answer to Carl's reply indicates
that it is not what you write above.)
Show the exact definition.
Marc


Schobi

--
Sp******@gmx.de is never read
I'm Schobi at suespammers dot org

"Coming back to where you started is not the same as never leaving"
Terry Pratchett
Nov 17 '05 #8
"Hendrik Schober" <Sp******@gmx.de> wrote in news:42a5bc89$0$18639
$1*******@news.sunsite.dk:
That's an explanation of what you think
'ppInputArray' is, not the definition.
(Your answer to Carl's reply indicates
that it is not what you write above.)
Show the exact definition.


Well... I'm not trying to be vague. The header file defines it as:
/**
* Read input line for compression.
* In progressive (pull) mode scanlines will be sequentially
* read by the overloaded WriteReadLine() method
* @param nNextLine Next input line to read
* @param ppInputArray Array of buffer pointers, one buffer for
each band
* @return CNCSError Write status code
*/
virtual CNCSError WriteReadLine(UINT32 nNextLine, void **ppInputArray);
My understanding of what it is comes from reading the examples. The
clearest use of this variable is in a C example that looks like this:
/*
** Read callback function - called once for each input line
*/
static BOOLEAN ReadCallback(NCSEcwCompressClient *pClient,
UINT32 nNextLine,
IEEE4 **ppInputArray)
{
ReadInfo *pRI = (ReadInfo*)pClient->pClientData;
UINT32 nBand;

for(nBand = 0; nBand < pClient->nInputBands; nBand++) {
UINT32 nCell;
IEEE4 *pLine = ppInputArray[nBand];

if(pClient->nInputBands == 1) {
/* 1 band, do a grid pattern */
for(nCell = 0; nCell < pClient->nInOutSizeX; nCell++) {
if(((nCell / 30) % 2 == nBand) || ((nNextLine / 30) % 2 ==
nBand)) {
pLine[nCell] = 1000.0f;
} else {
pLine[nCell] = 0.0f;
}
}
} else {
for(nCell = 0; nCell < pClient->nInOutSizeX; nCell++) {
if(((nCell / 30) % pClient->nInputBands == nBand) &&
((nNextLine / 30) % pClient->nInputBands == nBand)) {
pLine[nCell] = 1000.0f;
} else {
pLine[nCell] = 0.0f;
}
}
}
}
return(TRUE); /* would return FALSE on an error */

Hope this helps...

Marc
Nov 17 '05 #9
>> float** ppf = static_cast<float**>(ppInputArray);
This gives me an "error C2440: 'static_cast': cannot convert from
'void**' to 'float**'".


Try reinterpret_cast rather than static_cast.

Dave
--
MVP VC++ FAQ: http://www.mvps.org/vcfaq
Nov 17 '05 #10
"David Lowndes" <da****@example.invalid> wrote in message
news:je********************************@4ax.com...
float** ppf = static_cast<float**>(ppInputArray);

This gives me an "error C2440: 'static_cast': cannot convert from
'void**' to 'float**'".


Try reinterpret_cast rather than static_cast.


'zactly.

-cd
Nov 17 '05 #11
David Lowndes <da****@example.invalid> wrote in
news:je********************************@4ax.com:
Try reinterpret_cast rather than static_cast.


That works!

So does this
float *Red = (float *)(ppInputArray[0]);
float *Green = (float *)(ppInputArray[1]);
float *Blue = (float *)(ppInputArray[2]);

Thanks everyone.

cheers

Marc
Nov 17 '05 #12

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

19 posts views Thread by Steven T. Hatton | last post: by
6 posts views Thread by spasmous | last post: by
8 posts views Thread by Jimmy Petersen | last post: by
6 posts views Thread by c19h28o2 | last post: by
20 posts views Thread by Martin Jørgensen | last post: by
17 posts views Thread by kleary00 | last post: by
33 posts views Thread by Adam Chapman | last post: by
1 post views Thread by Korara | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.