Thread: Datatype Conversion

  1. #1
    Registered User carrotcake1029's Avatar
    Join Date
    Apr 2008
    Posts
    404

    Datatype Conversion

    I have written a program that will use the input of a bitmap image file. I have done this in the past in other programming languages, but have come to a stumbling block in C.

    Parts of the header, as you probably know are stored as DWORD and WORD data types. In order for my program to function correctly, I need to get these values preferably as an integer to be able to output to the command line.

    Right now I want to just output the size of the file. I checked out the 4 bytes that are supposed to have it and it does 0x2E 0x01 0x00 0x00, which in turn is actually 0x0000012E, which is correct. I just want an easy output.

    I was wondering if this was a simple task or if I will need to write a routine like I have in the past.

    Thanks for your time.

    Edit:
    If this is the easiest way to do it, just let me know.
    Code:
    int GetDWORD(char data[])
    {
    	return ((int)data[0] | ((int)data[1] << 8) | ((int) data[2] << 16) | ((int)data[3] << 24));
    }
    Last edited by carrotcake1029; 04-14-2008 at 06:51 PM.

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    1. Declare a pointer to int32_t or DWORD or whatever.
    2. Set it to point to the first byte of the size.
    3. Print the value of the dereferenced pointer.

    ETA: This assumes the endianness of the machine matches the endianness in the file, which you seemed to indicate was true.

  3. #3
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    better use unsigned types with bit operations - cast to unsigned int before shifting and return unsigned int
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  4. #4
    Registered User carrotcake1029's Avatar
    Join Date
    Apr 2008
    Posts
    404
    Hate to bump this but I am going nowhere fast. I am fairly new to C. I don't like my method to treating all data as char arrays.

    Could someone illustrate an example of the conversion of a DWORD (or unsigned long) into an integer. As far as I see it, DWORDs are 4 bytes, and ints are 2 (on my processor). I just can't seem to come up with a logical way to output this via printf just so I can monitor the data.

  5. #5
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by carrotcake1029 View Post
    Hate to bump this but I am going nowhere fast. I am fairly new to C. I don't like my method to treating all data as char arrays.

    Could someone illustrate an example of the conversion of a DWORD (or unsigned long) into an integer. As far as I see it, DWORDs are 4 bytes, and ints are 2 (on my processor). I just can't seem to come up with a logical way to output this via printf just so I can monitor the data.
    Which do you want to do? There's no reason to convert to an int, just to printf it; just use the appropriate format specifier. (If DWORD is typedef'ed as an unsigned long, then use %ul, for instance).

  6. #6
    Registered User carrotcake1029's Avatar
    Join Date
    Apr 2008
    Posts
    404
    Not sure if this is a compiler issue, but that doesn't seem to output it correctly (VS 2005).

    What is happening is I am reading the data from a bitmap file and am applying the header to a struct I have.
    Code:
    typedef unsigned long       DWORD;
    
    struct BITMAPFILEHEADER
    {
    	BYTE bfType[2]; 
    	DWORD bfSize; 
    	WORD bfReserved1; 
    	WORD bfReserved2; 
    	DWORD bfOffBits;
    };
    
    if((fp = fopen(input, "rb")) == NULL) return 0;
    
    fread(&bmfh, sizeof(bmfh), 1, fp);
    For my program, I am going to need to make use of some of these values. When I use &#37;ul as you suggested, I get a result of 0l, far from correct.

  7. #7
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Sanity check : is sizeof(struct BITMAPFILEHEADER) == 14? (I got that from 2+4+2+2+4, which is what it looks like it should be.) If not, you're reading into padding, or something equally nefarious. Other sanity check: after you read in, does bmfh.bfSize == 0L work out to true? If so, then you've actually got zeros.

  8. #8
    Registered User carrotcake1029's Avatar
    Join Date
    Apr 2008
    Posts
    404
    Good idea. It's size should be 14, but I am getting 16?

    And no, bmfh.bfSize != 0L. I actually have read the whole file into a byte array and outputted it. It definitely has a decimal value of 2000+.

    How can I solve this "reading into padding" issue. Where is this padding coming from?

  9. #9
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    The padding probably is between the byte array and the DWORD, since a 4-byte DWORD on a native 2-bit integer processor may well have an alignment requirement. If it's really a hardware requirement of your hardware, that just made your life more complicated. Check your compiler documentation to see if there's a "no padding" switch, but you may have to read in the first two bytes, then the rest in a second chunk.

    I wonder why whatever is in there didn't print with %ul. And I imagine %x would only print the first two bytes....

  10. #10
    Registered User carrotcake1029's Avatar
    Join Date
    Apr 2008
    Posts
    404
    Well, I changed the first variable of the struct to WORD, and in turn is supposed to return 19778 as a decimal, which it did. It just starts acting funky after that.

    I found out a way to rid the padding locally, but if you could be so kind, could you please explain what this means. I recognize them as some assembly functions, but I am not so gifted to be fluent.

    Code:
    #pragma pack(push,1)
    struct BITMAPFILEHEADER
    {
    	WORD bfType; 
    	DWORD bfSize; 
    	WORD bfReserved1; 
    	WORD bfReserved2; 
    	DWORD bfOffBits;
    };
    #pragma pack(pop)
    I get perfect results now. Hopefully this code can help others.

  11. #11
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    #pragma's are compiler-specific things, so that is specific to whatever compiler you're using. What it does is say "I know what I'm doing and 'pack' this structure together tightly."

    (Presumably, your machine has a native instruction to load four bytes at a time, if the address is aligned properly -- you might be able to move 8000-8003 in one go, and 8004-8007; but to do 8002-8005 you'd need to load the last half of the first segment (<- not really the right term) and the first half of the second in two steps. So everytime you access bfSize, it will take twice as long as otherwise. (Granted, that rarely is measurable unless you use bfSize a lot.))

  12. #12
    Registered User carrotcake1029's Avatar
    Join Date
    Apr 2008
    Posts
    404
    Thanks for the explanation and the time you have put forward. Hopefully I will be able to diagnose issues similar to this by myself now.

  13. #13
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Typically you shouldn't mess with padding at all. Compilers add them to optimize access to variables inside the struct.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Screwy Linker Error - VC2005
    By Tonto in forum C++ Programming
    Replies: 5
    Last Post: 06-19-2007, 02:39 PM
  2. Dikumud
    By maxorator in forum C++ Programming
    Replies: 1
    Last Post: 10-01-2005, 06:39 AM
  3. Header File Question(s)
    By AQWst in forum C++ Programming
    Replies: 10
    Last Post: 12-23-2004, 11:31 PM
  4. Do I have a scanf problem?
    By AQWst in forum C Programming
    Replies: 2
    Last Post: 11-26-2004, 06:18 PM
  5. Creation of Menu problem
    By AQWst in forum C Programming
    Replies: 8
    Last Post: 11-24-2004, 09:44 PM