array of pointers to float

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Marc Pelletier

    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)GetRValu e( rgb );
    Green[x] = (float)GetGValu e( rgb );
    Blue[x] = (float)GetBValu e( 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

    #2
    Re: array of pointers to float

    Marc Pelletier <no.email@pleas e.com> wrote in news:Xns966CF17 C7882Ampdd445@
    207.46.248.16:
    [color=blue]
    > 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)GetRValu e( rgb );
    > Green[x] = (float)GetGValu e( rgb );
    > Blue[x] = (float)GetBValu e( rgb );
    > }
    >[/color]

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

    float Red[] = ppInputArray[0];

    cheers

    Marc

    Comment

    • Hendrik Schober

      #3
      Re: array of pointers to float

      Marc Pelletier <marc@stopspam. goldak.ca> wrote:[color=blue]
      > Marc Pelletier <no.email@pleas e.com> wrote in news:Xns966CF17 C7882Ampdd445@
      > 207.46.248.16:
      >[color=green]
      > > 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)GetRValu e( rgb );
      > > Green[x] = (float)GetGValu e( rgb );
      > > Blue[x] = (float)GetBValu e( rgb );
      > > }
      > >[/color]
      >
      > Sorry, I should have mentioned that the compiler error is actually on the
      > first line above
      >
      > float Red[] = ppInputArray[0];[/color]

      Hard to say anything if you don't even provide
      the definition of 'ppInputArray'.
      [color=blue]
      > Marc[/color]

      Schobi

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



      Comment

      • Carl Daniel [VC++ MVP]

        #4
        Re: array of pointers to float

        Marc Pelletier wrote:[color=blue]
        > 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)GetRValu e( rgb );
        > Green[x] = (float)GetGValu e( rgb );
        > Blue[x] = (float)GetBValu e( rgb );
        > }[/color]

        <code>
        float** ppf = static_cast<flo at**>(ppInputAr ray);

        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<flo at*>(*ppInputAr ray);
        for (...)
        pf[0] = (float)GetRValu e(...);
        pf[1] = (float)GetGValu e(...);
        pf[2] = (float)GetBValu e(...);
        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)GetRValu e(...);
        pf[1] = (float)GetGValu e(...);
        pf[2] = (float)GetBValu e(...);
        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




        Comment

        • Marc Pelletier

          #5
          Re: array of pointers to float

          Carl,

          Thanks for your comments. I've replied below.

          "Carl Daniel [VC++ MVP]"
          <cpdaniel_remov e_this_and_nosp am@mvps.org.nos pam> wrote in
          news:#GhuZo2aFH A.760@TK2MSFTNG P10.phx.gbl:
          [color=blue]
          > <code>
          > float** ppf = static_cast<flo at**>(ppInputAr ray);
          >
          > float* Red = ppf[0];
          > float* Green = ppf[1];
          > float* Blue = ppf[2];
          >
          > for (...)
          > </code>[/color]

          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?

          [color=blue]
          > 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:
          >[/color]

          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..[color=blue]
          >
          > 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)GetRValu e(...);
          > pf[1] = (float)GetGValu e(...);
          > pf[2] = (float)GetBValu e(...);
          > 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.
          >[/color]

          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

          Comment

          • Marc Pelletier

            #6
            Re: array of pointers to float

            "Hendrik Schober" <SpamTrap@gmx.d e> wrote in news:#OpbEX2aFH A.3400
            @tk2msftngp13.p hx.gbl:
            [color=blue]
            > Hard to say anything if you don't even provide
            > the definition of 'ppInputArray'.
            >
            >[/color]

            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

            Comment

            • Marc Pelletier

              #7
              Re: array of pointers to float

              Marc Pelletier <marc@stopspam. goldak.ca> wrote in
              news:Xns966E5BA F3D6BCmmpp1234. dd@207.46.248.1 6:
              [color=blue]
              > 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?
              >
              >[/color]

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


              cheers

              Marc

              Comment

              • Hendrik Schober

                #8
                Re: array of pointers to float

                Marc Pelletier <marc@stopspam. goldak.ca> wrote:[color=blue]
                > "Hendrik Schober" <SpamTrap@gmx.d e> wrote in news:#OpbEX2aFH A.3400
                > @tk2msftngp13.p hx.gbl:
                >[color=green]
                > > Hard to say anything if you don't even provide
                > > the definition of 'ppInputArray'.
                > >
                > >[/color]
                >
                > 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.[/color]

                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.
                [color=blue]
                > Marc[/color]

                Schobi

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


                Comment

                • Marc Pelletier

                  #9
                  Re: array of pointers to float

                  "Hendrik Schober" <SpamTrap@gmx.d e> wrote in news:42a5bc89$0 $18639
                  $14726298@news. sunsite.dk:
                  [color=blue]
                  > 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.
                  >
                  >[/color]

                  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(U INT32 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(NC SEcwCompressCli ent *pClient,
                  UINT32 nNextLine,
                  IEEE4 **ppInputArray)
                  {
                  ReadInfo *pRI = (ReadInfo*)pCli ent->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

                  Comment

                  • David Lowndes

                    #10
                    Re: array of pointers to float

                    >> float** ppf = static_cast<flo at**>(ppInputAr ray);
                    [color=blue]
                    >This gives me an "error C2440: 'static_cast': cannot convert from
                    >'void**' to 'float**'".[/color]

                    Try reinterpret_cas t rather than static_cast.

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

                    Comment

                    • Carl Daniel [VC++ MVP]

                      #11
                      Re: array of pointers to float

                      "David Lowndes" <davidl@example .invalid> wrote in message
                      news:je6ca1dpg2 fpo2epei5kg7n26 87d7b4942@4ax.c om...[color=blue][color=green][color=darkred]
                      >>> float** ppf = static_cast<flo at**>(ppInputAr ray);[/color][/color]
                      >[color=green]
                      >>This gives me an "error C2440: 'static_cast': cannot convert from
                      >>'void**' to 'float**'".[/color]
                      >
                      > Try reinterpret_cas t rather than static_cast.[/color]

                      'zactly.

                      -cd


                      Comment

                      • Marc Pelletier

                        #12
                        Re: array of pointers to float

                        David Lowndes <davidl@example .invalid> wrote in
                        news:je6ca1dpg2 fpo2epei5kg7n26 87d7b4942@4ax.c om:
                        [color=blue]
                        > Try reinterpret_cas t rather than static_cast.
                        >
                        >[/color]

                        That works!

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

                        Thanks everyone.

                        cheers

                        Marc

                        Comment

                        Working...