Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Languages / Managed C++ / June 2005

Tip: Looking for answers? Try searching our database.

array of pointers to float

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Marc Pelletier - 06 Jun 2005 06:44 GMT
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
Marc Pelletier - 06 Jun 2005 22:59 GMT
Marc Pelletier <no.email@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
[quoted text clipped - 9 lines]
>       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
Hendrik Schober - 07 Jun 2005 14:33 GMT
> Marc Pelletier <no.email@please.com> wrote in news:Xns966CF17C7882Ampdd445@
> 207.46.248.16:
[quoted text clipped - 17 lines]
>
>      float Red[]    = ppInputArray[0];

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

> Marc

 Schobi

Signature

SpamTrap@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

Marc Pelletier - 07 Jun 2005 16:08 GMT
"Hendrik Schober" <SpamTrap@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
Hendrik Schober - 07 Jun 2005 16:22 GMT
> "Hendrik Schober" <SpamTrap@gmx.de> wrote in news:#OpbEX2aFHA.3400
> @tk2msftngp13.phx.gbl:
[quoted text clipped - 5 lines]
> 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

Signature

SpamTrap@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

Marc Pelletier - 07 Jun 2005 17:02 GMT
"Hendrik Schober" <SpamTrap@gmx.de> wrote in news:42a5bc89$0$18639
$14726298@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
Carl Daniel [VC++ MVP] - 07 Jun 2005 15:06 GMT
> Hello,
>
[quoted text clipped - 18 lines]
>      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
Marc Pelletier - 07 Jun 2005 16:00 GMT
Carl,

Thanks for your comments. I've replied below.

> <code>
> float** ppf = static_cast<float**>(ppInputArray);
[quoted text clipped - 5 lines]
> 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
[quoted text clipped - 3 lines]
> 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
[quoted text clipped - 16 lines]
> 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
Marc Pelletier - 07 Jun 2005 16:11 GMT
> 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
David Lowndes - 07 Jun 2005 23:04 GMT
>> 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
Signature

MVP VC++ FAQ: http://www.mvps.org/vcfaq

Carl Daniel [VC++ MVP] - 07 Jun 2005 23:32 GMT
>>> 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
Marc Pelletier - 08 Jun 2005 01:42 GMT
> 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

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.