Trying to extract different types of data from a singe file.

Discussion in 'C++' started by JoeC, Aug 1, 2008.

  1. JoeC

    JoeC Guest

    I am trying to create a windows program that reads binary graphics as
    a resource. This has nothing to do with win32 but conversion of data
    with memcpy.

    graphic::graphic(UINT uiResID, HINSTANCE hinstance){
    size = 32;
    bitData.clear();
    void * p = NULL; // point to the data
    int end;
    BYTE data;

    static HGLOBAL hglob;


    HRSRC hRes =
    FindResource(hinstance,MAKEINTRESOURCE(uiResID),TEXT("BINARY"));

    if(hRes){
    hglob = LoadResource(hinstance,hRes);
    p = LockResource(hglob);
    memcpy((int*) &end, p, sizeof(int)); // puts the first but of
    data to int.

    for(int lp = 0; lp != end; lp++){
    bitData.push_back(0);
    }

    for(int lp = 0; lp != end; lp++){
    memcpy((BYTE*) &bitData[lp], p, sizeof(BYTE)); puts the rest
    of the data in BYTE type.
    }

    }
    set();
    create();
    }

    My question is how do I extract each but of data from p first to the
    int type with is the number of data bits then each bit of data to put
    into my bitData vector. I can't increase the pointer p++ to get to
    the next bit of data. This compiles and runs but does not extract the
    data for me.
    JoeC, Aug 1, 2008
    #1
    1. Advertising

  2. JoeC

    James Kanze Guest

    On Aug 1, 5:47 am, JoeC <> wrote:
    > I am trying to create a windows program that reads binary
    > graphics as a resource. This has nothing to do with win32 but
    > conversion of data with memcpy.


    memcpy doesn't convert; it just copies bits. If the original
    data came from an external source, that's generally not what is
    needed.

    > graphic::graphic(UINT uiResID, HINSTANCE hinstance){
    > size = 32;
    > bitData.clear();
    > void * p = NULL; // point to the data
    > int end;
    > BYTE data;


    > static HGLOBAL hglob;


    > HRSRC hRes =
    > FindResource(hinstance,MAKEINTRESOURCE(uiResID),TEXT("BINARY"));
    >
    > if(hRes){
    > hglob = LoadResource(hinstance,hRes);
    > p = LockResource(hglob);
    > memcpy((int*) &end, p, sizeof(int)); // puts the first but of
    > data to int.


    Note that you've got a reintepret_cast here. That's a sure sign
    that something is wrong.

    How are the integer values formatted in the file? Until you
    know that, you can't do anything reasonable.

    > for(int lp = 0; lp != end; lp++){
    > bitData.push_back(0);
    > }


    > for(int lp = 0; lp != end; lp++){
    > memcpy((BYTE*) &bitData[lp], p, sizeof(BYTE)); puts the rest
    > of the data in BYTE type.


    If BYTE is unsigned char, memcpy might just work. But did you
    really mean to not increment p in the loop? If so, this is
    just:

    bitData.insert( bitData.end(), end, *p ) ;

    would do the trick (without the previous loop. Otherwise,
    you could replace the two loops with:

    bitData.resize( end ) ;
    memcpy( &bitData[ 0 ], p, end ) ;

    (In both cases, of course, only if BYTE is unsigned char, and
    bitData is std::vector< BYTE >.)

    [...]
    > My question is how do I extract each but of data from p first
    > to the int type with is the number of data bits then each bit
    > of data to put into my bitData vector. I can't increase the
    > pointer p++ to get to the next bit of data.


    What is the format of the input? Until we know that, we can't
    really say anything. A lot of formats---almost all, I would
    imagine---do pack bitmaps as 8 bits to an unsigned char. If
    such is the case, and end gives the number of bits, you'll have
    to scale it before using it with memcpy or your loops. On the
    other hand, I wouldn't be surprised if some graphic formats have
    "bitmaps" that aren't actually bitmaps: bitmaps were the most
    basic graphic representation back in the days of black and
    white, where a pixel was one bit, but I would imagine that a lot
    of graphic formats today would use a string or an array of
    pixels, rather than a true bitmap.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
    James Kanze, Aug 1, 2008
    #2
    1. Advertising

  3. JoeC

    JoeC Guest

    On Aug 1, 4:41 am, James Kanze <> wrote:
    > On Aug 1, 5:47 am, JoeC <> wrote:
    >
    > > I am trying to create a windows program that reads binary
    > > graphics as a resource. This has nothing to do with win32 but
    > > conversion of data with memcpy.

    >
    > memcpy doesn't convert; it just copies bits. If the original
    > data came from an external source, that's generally not what is
    > needed.
    >
    > > graphic::graphic(UINT uiResID, HINSTANCE hinstance){
    > > size = 32;
    > > bitData.clear();
    > > void * p = NULL; // point to the data
    > > int end;
    > > BYTE data;
    > > static HGLOBAL hglob;
    > > HRSRC hRes =
    > > FindResource(hinstance,MAKEINTRESOURCE(uiResID),TEXT("BINARY"));

    >
    > > if(hRes){
    > > hglob = LoadResource(hinstance,hRes);
    > > p = LockResource(hglob);
    > > memcpy((int*) &end, p, sizeof(int)); // puts the first but of
    > > data to int.

    >
    > Note that you've got a reintepret_cast here. That's a sure sign
    > that something is wrong.
    >
    > How are the integer values formatted in the file? Until you
    > know that, you can't do anything reasonable.
    >
    > > for(int lp = 0; lp != end; lp++){
    > > bitData.push_back(0);
    > > }
    > > for(int lp = 0; lp != end; lp++){
    > > memcpy((BYTE*) &bitData[lp], p, sizeof(BYTE)); puts the rest
    > > of the data in BYTE type.

    >
    > If BYTE is unsigned char, memcpy might just work. But did you
    > really mean to not increment p in the loop? If so, this is
    > just:
    >
    > bitData.insert( bitData.end(), end, *p ) ;
    >
    > would do the trick (without the previous loop. Otherwise,
    > you could replace the two loops with:
    >
    > bitData.resize( end ) ;
    > memcpy( &bitData[ 0 ], p, end ) ;
    >
    > (In both cases, of course, only if BYTE is unsigned char, and
    > bitData is std::vector< BYTE >.)
    >
    > [...]
    >
    > > My question is how do I extract each but of data from p first
    > > to the int type with is the number of data bits then each bit
    > > of data to put into my bitData vector. I can't increase the
    > > pointer p++ to get to the next bit of data.

    >
    > What is the format of the input? Until we know that, we can't
    > really say anything. A lot of formats---almost all, I would
    > imagine---do pack bitmaps as 8 bits to an unsigned char. If
    > such is the case, and end gives the number of bits, you'll have
    > to scale it before using it with memcpy or your loops. On the
    > other hand, I wouldn't be surprised if some graphic formats have
    > "bitmaps" that aren't actually bitmaps: bitmaps were the most
    > basic graphic representation back in the days of black and
    > white, where a pixel was one bit, but I would imagine that a lot
    > of graphic formats today would use a string or an array of
    > pixels, rather than a true bitmap.
    >
    > --
    > James Kanze (GABI Software) email:
    > Conseils en informatique orientée objet/
    > Beratung in objektorientierter Datenverarbeitung
    > 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


    I created the binary files in the object the standard way:

    void graphic::save(std::eek:fstream& f){
    f.write((char*)&number, sizeof(int));
    for(int lp = 0; lp != (size * number); lp++){
    f.write((char*)&bitData[lp], sizeof(BYTE));
    }
    }

    void graphic::load(std::ifstream& f){
    f.read((char*)&number, sizeof(int));
    int end = size * number;

    for(int lp = 0; lp != end; lp++){
    bitData.push_back(0);
    }

    for(int lp = 0; lp != end; lp++){
    f.read((char*)&bitData[lp], sizeof(BYTE));
    }
    set();
    create();
    }

    I wrote a binary file.
    I can also read the data fine from a file. I am just trying to load
    in the binary files as a resource to make my program better so that I
    don't have to include graphics they can already be in the complied
    code. I hope this helps. I don't have good references for trying to
    extract data like this.
    JoeC, Aug 1, 2008
    #3
  4. JoeC

    James Kanze Guest

    On Aug 1, 5:56 pm, JoeC <> wrote:
    > On Aug 1, 4:41 am, James Kanze <> wrote:


    > I created the binary files in the object the standard way:


    > void graphic::save(std::eek:fstream& f){
    > f.write((char*)&number, sizeof(int));
    > for(int lp = 0; lp != (size * number); lp++){
    > f.write((char*)&bitData[lp], sizeof(BYTE));
    > }
    > }


    In other words, you have no idea of its format, and you don't
    know how to read it.

    > void graphic::load(std::ifstream& f){
    > f.read((char*)&number, sizeof(int));
    > int end = size * number;


    > for(int lp = 0; lp != end; lp++){
    > bitData.push_back(0);
    > }


    > for(int lp = 0; lp != end; lp++){
    > f.read((char*)&bitData[lp], sizeof(BYTE));
    > }
    > set();
    > create();
    > }


    > I wrote a binary file.


    But you don't know what you put into it. That doesn't advance
    us very much. (Note that there's a reinterpret_cast here as
    well. Bad sign.)

    > I can also read the data fine from a file.


    You can read the bits. You don't know what they mean.

    > I am just trying to load in the binary files as a resource to
    > make my program better so that I don't have to include
    > graphics they can already be in the complied code.


    So start by defining the format you want to use. Or use some
    pre-established format. (I tend to use XDR by default.)

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
    James Kanze, Aug 1, 2008
    #4
  5. JoeC

    JoeC Guest

    On Aug 1, 1:14 pm, James Kanze <> wrote:
    > On Aug 1, 5:56 pm, JoeC <> wrote:
    >
    > > On Aug 1, 4:41 am, James Kanze <> wrote:
    > > I created the binary files in the object the standard way:
    > > void graphic::save(std::eek:fstream& f){
    > > f.write((char*)&number, sizeof(int));
    > > for(int lp = 0; lp != (size * number); lp++){
    > > f.write((char*)&bitData[lp], sizeof(BYTE));
    > > }
    > > }

    >
    > In other words, you have no idea of its format, and you don't
    > know how to read it.
    >
    > > void graphic::load(std::ifstream& f){
    > > f.read((char*)&number, sizeof(int));
    > > int end = size * number;
    > > for(int lp = 0; lp != end; lp++){
    > > bitData.push_back(0);
    > > }
    > > for(int lp = 0; lp != end; lp++){
    > > f.read((char*)&bitData[lp], sizeof(BYTE));
    > > }
    > > set();
    > > create();
    > > }
    > > I wrote a binary file.

    >
    > But you don't know what you put into it. That doesn't advance
    > us very much. (Note that there's a reinterpret_cast here as
    > well. Bad sign.)
    >
    > > I can also read the data fine from a file.

    >
    > You can read the bits. You don't know what they mean.
    >
    > > I am just trying to load in the binary files as a resource to
    > > make my program better so that I don't have to include
    > > graphics they can already be in the complied code.

    >
    > So start by defining the format you want to use. Or use some
    > pre-established format. (I tend to use XDR by default.)
    >
    > --
    > James Kanze (GABI Software) email:
    > Conseils en informatique orientée objet/
    > Beratung in objektorientierter Datenverarbeitung
    > 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


    I didn't realize it was so complicated loading user created files as
    resources. That is beyond my skill level or knowledge of the
    language. Thanks for the help, I though that loading files was a
    standard operation. If not I will not make my graphics a resource.
    JoeC, Aug 2, 2008
    #5
  6. JoeC

    James Kanze Guest

    On Aug 2, 1:40 am, JoeC <> wrote:
    > On Aug 1, 1:14 pm, James Kanze <> wrote:


    > I didn't realize it was so complicated loading user created
    > files as resources.


    It's not that complicated, but... the language does not define
    any binary formats (probably because there are so many to choose
    from); when you do binary IO, you have to take charge of the
    formatting yourself.

    < That is beyond my skill level or knowledge of the
    > language. Thanks for the help, I though that loading files
    > was a standard operation.


    Reading a file is. But whether text or binary, you really have
    to define some sort of format. (Just outputting "file << i << j
    << k", where i, j and k are ints, won't give you something you
    are read back in either.)

    I might add that this is a basic software engineering problem,
    and not particular to C++.

    Anyway, your case is particularly simple, because you are
    dealing mainly with "bytes", i.e. with raw memory, where each
    byte is an element unto itself. Which is the exceptional case
    where memcpy works, and istream::read and ostream::write do
    everything. So you're only real problem is the initial length.
    For that, I'd use an unsigned (rather than signed), although in
    practice, unless you later have to port to very exotic machines,
    it doesn't matter, and XDR format, which is simply four bytes,
    high byte first, IOW:

    to write:

    void
    writeInt(
    std::eek:stream& dest,
    unsigned value )
    {
    dest.put( (value >> 24) & 0xFF ) ;
    dest.put( (value >> 16) & 0xFF ) ;
    dest.put( (value >> 8) & 0xFF ) ;
    dest.put( (value ) & 0xFF ) ;
    }

    to read:

    void
    readInt(
    std::istream& source ;
    unsigned& value )
    {
    unsigned result = 0 ;
    result |= dest.get() << 24 ;
    result |= dest.get() << 16 ;
    result |= dest.get() << 8 ;
    result |= dest.get() ;
    if ( dest ) {
    value = result ;
    }
    }

    > If not I will not make my graphics a resource.


    Is that portable?

    Do you need portability? I'm not too familiar with the Windows
    platform. But from what I understand, a resource can be bundled
    into the same file as your executable. Which is a definite
    advantage when it comes to deployment. (Under Unix, I have my
    own programs which serve more or less the same purpose: they
    convert the "resource" to C++ data declarations, which I then
    compile and link into the program. It's not the same thing, but
    it serves the same purpose: to make the entire application a
    single file, so you don't end up with a mixture of versions or
    something partially installed.)

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
    James Kanze, Aug 2, 2008
    #6
  7. JoeC

    JoeC Guest

    On Aug 2, 2:53 am, James Kanze <> wrote:
    > On Aug 2, 1:40 am, JoeC <> wrote:
    >
    > > On Aug 1, 1:14 pm, James Kanze <> wrote:
    > > I didn't realize it was so complicated loading user created
    > > files as resources.

    >
    > It's not that complicated, but... the language does not define
    > any binary formats (probably because there are so many to choose
    > from); when you do binary IO, you have to take charge of the
    > formatting yourself.
    >
    > < That is beyond my skill level or knowledge of the
    >
    > > language. Thanks for the help, I though that loading files
    > > was a standard operation.

    >
    > Reading a file is. But whether text or binary, you really have
    > to define some sort of format. (Just outputting "file << i << j
    > << k", where i, j and k are ints, won't give you something you
    > are read back in either.)
    >
    > I might add that this is a basic software engineering problem,
    > and not particular to C++.
    >
    > Anyway, your case is particularly simple, because you are
    > dealing mainly with "bytes", i.e. with raw memory, where each
    > byte is an element unto itself. Which is the exceptional case
    > where memcpy works, and istream::read and ostream::write do
    > everything. So you're only real problem is the initial length.
    > For that, I'd use an unsigned (rather than signed), although in
    > practice, unless you later have to port to very exotic machines,
    > it doesn't matter, and XDR format, which is simply four bytes,
    > high byte first, IOW:
    >
    > to write:
    >
    > void
    > writeInt(
    > std::eek:stream& dest,
    > unsigned value )
    > {
    > dest.put( (value >> 24) & 0xFF ) ;
    > dest.put( (value >> 16) & 0xFF ) ;
    > dest.put( (value >> 8) & 0xFF ) ;
    > dest.put( (value ) & 0xFF ) ;
    > }
    >
    > to read:
    >
    > void
    > readInt(
    > std::istream& source ;
    > unsigned& value )
    > {
    > unsigned result = 0 ;
    > result |= dest.get() << 24 ;
    > result |= dest.get() << 16 ;
    > result |= dest.get() << 8 ;
    > result |= dest.get() ;
    > if ( dest ) {
    > value = result ;
    > }
    > }
    >
    > > If not I will not make my graphics a resource.

    >
    > Is that portable?
    >
    > Do you need portability? I'm not too familiar with the Windows
    > platform. But from what I understand, a resource can be bundled
    > into the same file as your executable. Which is a definite
    > advantage when it comes to deployment. (Under Unix, I have my
    > own programs which serve more or less the same purpose: they
    > convert the "resource" to C++ data declarations, which I then
    > compile and link into the program. It's not the same thing, but
    > it serves the same purpose: to make the entire application a
    > single file, so you don't end up with a mixture of versions or
    > something partially installed.)
    >
    > --
    > James Kanze (GABI Software) email:
    > Conseils en informatique orientée objet/
    > Beratung in objektorientierter Datenverarbeitung
    > 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


    Thanks for the explanation, I will save all of this and try to work
    with my program. I can load in the files as binary files but trying
    to do it as resources is a but different. I was advised to use strcpy.
    JoeC, Aug 2, 2008
    #7
  8. JoeC

    James Kanze Guest

    On Aug 2, 8:04 pm, JoeC <> wrote:
    > On Aug 2, 2:53 am, James Kanze <> wrote:


    [...]
    > Thanks for the explanation, I will save all of this and try to
    > work with my program. I can load in the files as binary files
    > but trying to do it as resources is a but different. I was
    > advised to use strcpy.


    If you're working with binary data (i.e. your array really is a
    bitmap), strcpy will NOT work. At all. Don't listen to whoever
    told you that.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
    James Kanze, Aug 2, 2008
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Markus
    Replies:
    9
    Views:
    397
    Matt Parker
    Nov 26, 2005
  2. ramu
    Replies:
    2
    Views:
    323
    rlblaster
    Feb 20, 2006
  3. v4vijayakumar

    product and jre as singe executable

    v4vijayakumar, Sep 4, 2007, in forum: Java
    Replies:
    2
    Views:
    329
    Roedy Green
    Sep 5, 2007
  4. Praki

    singe thread per connection

    Praki, Jul 11, 2008, in forum: Java
    Replies:
    7
    Views:
    433
    Arne Vajhøj
    Jul 13, 2008
  5. Gary Roach
    Replies:
    0
    Views:
    111
    Gary Roach
    Sep 1, 2013
Loading...

Share This Page