Thread: How covert unsigned char[4] to unsigned integer?

  1. #16
    Programming Wraith GReaper's Avatar
    Join Date
    Apr 2009
    Location
    Greece
    Posts
    2,738
    Quote Originally Posted by Al3 View Post
    Only if his system is B/E.
    Oh, I didn't mean it that way. I was referring to the look & feel of the code, not its functionality. But you were correct to point that out.
    ( If I understood correctly, you meant Big Endian )
    Devoted my life to programming...

  2. #17
    Registered User Al3's Avatar
    Join Date
    Nov 2014
    Posts
    135
    Quote Originally Posted by GReaper View Post
    Oh, I didn't mean it that way. I was referring to the look & feel of the code, not its functionality. But you were correct to point that out.
    ( If I understood correctly, you meant Big Endian )
    Yes. Well I am a bit tired as well as not a native speaker and it is a bit hard for me to understand posters here as they are usually not native speakers too so I lost for a moment why is he now using unsigned char. But I got to sleep anyway. I guess I will find out that tomorrow.

  3. #18
    Registered User
    Join Date
    Sep 2014
    Posts
    235
    The code worked when I needed get number of header offset. It was small number. So when tried to load bigger numbers greater then 255 so it did not work. I am not sure if there is not some other problem. For example planes should be 1 and not 8 so I am not sure if the error is in the conversion or elsewhere.

  4. #19
    Programming Wraith GReaper's Avatar
    Join Date
    Apr 2009
    Location
    Greece
    Posts
    2,738
    Are you sure that you're reading everything in the right order?

    But your read*Bytes() functions are wrong, you don't need those ambersands(&) in there.
    Devoted my life to programming...

  5. #20
    Registered User Al3's Avatar
    Join Date
    Nov 2014
    Posts
    135
    Quote Originally Posted by barracuda View Post
    The code worked when I needed get number of header offset. It was small number. So when tried to load bigger numbers greater then 255 so it did not work. I am not sure if there is not some other problem. For example planes should be 1 and not 8 so I am not sure if the error is in the conversion or elsewhere.
    I told you that you have to copy more bytes if your number is 255+. Look at post #7

  6. #21
    Registered User
    Join Date
    Sep 2014
    Posts
    235
    Thanks for the notice. I removed the ampersands from within the functions and most of the numbers are correct not. At least bitmap size and width and height is correct. I must find why planes and palColors are not correct.

  7. #22
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    If you're still using post #10, then it's wrong.

    &item is a pointer to the parameter, not what it points to.

    Also, passing the 2 or 4 byte buffer n seems a waste of effort, unless you use the result elsewhere.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  8. #23
    Registered User
    Join Date
    Sep 2014
    Posts
    235
    Good notice, I fixed both functions. Now all values are fine. Thanks

    Notice:
    When I declare local variable
    Code:
    unsigned char n[4];
    is this declared every time when function is called? Maybe better use
    Code:
    static  unsigned char n[4];
    ?
    Last edited by barracuda; 02-12-2015 at 04:11 AM.

  9. #24
    Registered User
    Join Date
    Sep 2014
    Posts
    235
    I have found this

    Code:
    #define UINT16_SWAP_LE_BE_CONSTANT(val)        \
      ((uint16_t)                    \
       (                        \
        (uint16_t) ((uint16_t) (val) >> 8) |    \
        (uint16_t) ((uint16_t) (val) << 8)))
    
    #define UINT32_SWAP_LE_BE_CONSTANT(val)              \
      ((uint32_t)                          \
       (                              \
        (((uint32_t) (val) & (uint32_t) 0x000000ffU) << 24) | \
        (((uint32_t) (val) & (uint32_t) 0x0000ff00U) <<  8) | \
        (((uint32_t) (val) & (uint32_t) 0x00ff0000U) >>  8) | \
        (((uint32_t) (val) & (uint32_t) 0xff000000U) >> 24)))
    I expect that it converts uint32_t to little endian. Author of this code uses it to write data to binary file.

  10. #25
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    > is this declared every time when function is called? Maybe better use
    > static unsigned char n[4];
    No.

    On most machines, creating the local stack frame is a single instruction regardless of the number of local variables.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  11. #26
    Registered User
    Join Date
    Sep 2014
    Posts
    235
    Could you yet help me how to get first 2 bytes of the bitmap "BM" characters to member char magicNo[2]?

    readChars(fp, &bmpfile->header.magicNo, 2);

    I tried:
    Code:
    static int readChars(FILE * fp, char** item, size_t size)
    {
      size_t in;
      char n[size];
      in = fread(n, size, 1, fp);
      memcpy(item,n,size);
      if (!in) return -2;
      return in;
    }
    and
    Code:
    static int readChars(FILE * fp, char** item, size_t size)
    {
      size_t in;
      char n[size];
      in = fread(item, size, 1, fp);
    if (!in) return -2;
      return in;
    }
    None works

    If I delete one star, then I got this message:
    note: expected 'char *' but argument is of type 'char (*)[2]'|

    Hence is not clear to me how to pass the char array by reference
    Last edited by barracuda; 02-12-2015 at 06:50 AM.

  12. #27
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    > readChars(fp, &bmpfile->header.magicNo, 2);
    Drop the &, and all those double stars should be single stars.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  13. #28
    Registered User Al3's Avatar
    Join Date
    Nov 2014
    Posts
    135
    Like it goes, we will do your entire project. It looks to me that you are just being lazy not that you actually need help.
    But since I am in a mood as well as I have a loooooooong experience with BMPs. I can give you a "tip" as Salem loves to call it.

    As a magic identifier it will be poor to use non-magical values at all such as 'B' and 'M'.
    This magic identifier is 2 bytes long. So you can declare it as `uint_16` or even better `WORD` which is `unsigned short` and make it a constant, because it isn't really a value you can change.
    Code:
    const WORD id = 19778;
    The 19778 is the magic number that initializes the BMP image.
    All you have to do now, is to write it directly to the bmp stream
    Code:
    fwrite(&id, 1, sizeof id, fp);

  14. #29
    Registered User
    Join Date
    Sep 2014
    Posts
    364
    Quote Originally Posted by Al3 View Post
    Code:
    const WORD id = 19778;
    But this works only on little endians. On big endians the magic number will be 16973.

    A better way is to compare the ID byte by byte.
    Code:
    typedef union int_2byte_t {
        uint16_t full;
        uint8_t part[2];
    } int_2byte;
    
    …
        int_2byte bmp_id;
        if (fread(&bmp_id, sizeof(bmp_id), 1, filepointer) != 1) return -1;
        if (bmp_id.part[0] == 'B' && bmp_id.part[1] == 'M') {
            /* work with BMP */
        }
        else {
            fclose(filepointer);
            return -2;
        }
    …
    (not tested, free typed from my head)
    Last edited by WoodSTokk; 02-12-2015 at 09:47 AM.
    Other have classes, we are class

  15. #30
    Registered User Al3's Avatar
    Join Date
    Nov 2014
    Posts
    135
    That is an awful way. Endianness must be determined in an init function, once.
    Leave that aside, any extra and pointless operation performed is not a "better way"..
    If by better you mean easier, then no.
    If by better you mean faster, then again no.
    If by better you mean less error-prone then again... no your way isn't any better.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Howto extract a positive integer from an unsigned char array
    By GregoireLeGros in forum C++ Programming
    Replies: 13
    Last Post: 01-14-2015, 02:14 AM
  2. Unsigned char array to unsigned char?
    By Kishintai in forum C Programming
    Replies: 16
    Last Post: 04-26-2013, 01:37 PM
  3. Replies: 2
    Last Post: 10-06-2009, 09:37 AM
  4. Converting unsigned long array to unsigned char array
    By delvec28 in forum C Programming
    Replies: 2
    Last Post: 09-07-2009, 08:53 PM
  5. convert from an integer to an unsigned char
    By Landroid in forum C Programming
    Replies: 4
    Last Post: 05-02-2005, 01:43 AM