C syntax in DIB image size calculation: ">>" and "~"

C syntax in DIB image size calculation: ">>" and "~"

Post by <rfran.. » Mon, 20 Dec 1999 04:00:00


Vincent...
The symbol >> means shift bits to the right by the right argument number, in this case 3.  This is a binary function, so in binary terms this is what happens... let's say your number is 256, or
100000000 in binary notation.  Shifting the number to the right by 3 would result in 100000, or 32, or in human terms a division of the number by 2 to the 3rd, or 8, if you were shifting right by 4 you would effectively be dividing by 2 to the 4th, or 16.  

The symbol ~ is the ones complement operator... this simply inverts all binary bits.  in the case of 31 which is 00000000000000000000000000011111 in binary, the number becomes 11111111111111111111111111100000, or 4,294,967,246 in base 10.  

The bottom line is this whole algoritm simply aligns the number on a DWORD, or 4 byte boundary.  All of the results should be evenly divisible by 4.

Ex:  ImageWidth  = 101, Bitcount = 24

((((101 * 24) + 31) & ~31)>>3) =
 ( (2455 & ~31) >> 3) =
    (2455 & 4,294,967,246) >> 3 =
        2432 >> 3 =
            304

304 is evenly divisible by 4, or DWORD aligned.

Rick

Quote:>C syntax in DIB image size calculation: ">>" and "~"
>----------------------------------------------------------------
>Would you mind giving me a help to explain the following syntax?

>biSizeImage= ((((biWidth*biBitCount) + 31) & ~31) >>3) * biHeight;

>What is ">>" and "~"?
>Why not?
>biSizeImage= (biWidth*biBitCount / 8) * biHeight;

>This come from an article: SAMPLE: DIBs and Their Uses.
>biSizeImage is a member of structure of   BITMAPINFOHEADER.
>-----------------------------------------------------------------------
>The following is extracted from the article.

>biSizeImage should contain the size of the bitmap proper in bytes. I say
>"should " becasuse the field is not necessarily filled in. A call to
>GetDIBits to generate a DIB fills in this field, but a DIB created manually
>by an application might not have this filled in. Calculating the size of a
>bitmap is not hard:
>biSizeImage= ((((biWidth*biBitCount) + 31) & ~31) >>3) * biHeight;

>The crazy roundoffs and shifts account for the bitmap being DWORD-aligned at
>the end of every sacanline. When nonzeor, this field tells an application
>hwo much stroage space the DIB's bits need. The biSize Image field really
>becomes useful when dealing with an RLE bitmap, the size of which depends on
>how well the bitmap was encoded. If an RLE bitmap is to be passed around,
>the  biSizeImage field is essential.
>-------------------------------------------------------------------------


 
 
 

C syntax in DIB image size calculation: ">>" and "~"

Post by Cliff & Ami » Mon, 17 Jan 2000 04:00:00


Seems like that ~31 is unnecessary.  
Use this:
    biSizeImage = ((biBitCount * biWidth + 31) / 8) * biHeight
the ">> 3" and "/ 8" are pretty much interchangable, any optimizer worth anything will see that /8 is equivalent to >>3 and make the switch.  >>3 is faster than a true divide, which is unnecessary in this case.  

Hope this helps
Cliff

Reply to cliff underscore win at hotmail dot com.

    Vincent...
    The symbol >> means shift bits to the right by the right argument number, in this case 3.  This is a binary function, so in binary terms this is what happens... let's say your number is 256, or
    100000000 in binary notation.  Shifting the number to the right by 3 would result in 100000, or 32, or in human terms a division of the number by 2 to the 3rd, or 8, if you were shifting right by 4 you would effectively be dividing by 2 to the 4th, or 16.  

    The symbol ~ is the ones complement operator... this simply inverts all binary bits.  in the case of 31 which is 00000000000000000000000000011111 in binary, the number becomes 11111111111111111111111111100000, or 4,294,967,246 in base 10.  

    The bottom line is this whole algoritm simply aligns the number on a DWORD, or 4 byte boundary.  All of the results should be evenly divisible by 4.

    Ex:  ImageWidth  = 101, Bitcount = 24

    ((((101 * 24) + 31) & ~31)>>3) =
     ( (2455 & ~31) >> 3) =
        (2455 & 4,294,967,246) >> 3 =
            2432 >> 3 =
                304

    304 is evenly divisible by 4, or DWORD aligned.

    Rick

    >C syntax in DIB image size calculation: ">>" and "~"
    >----------------------------------------------------------------
    >Would you mind giving me a help to explain the following syntax?
    >
    >biSizeImage= ((((biWidth*biBitCount) + 31) & ~31) >>3) * biHeight;
    >
    >What is ">>" and "~"?
    >Why not?
    >biSizeImage= (biWidth*biBitCount / 8) * biHeight;
    >
    >This come from an article: SAMPLE: DIBs and Their Uses.
    >biSizeImage is a member of structure of   BITMAPINFOHEADER.
    >-----------------------------------------------------------------------
    >The following is extracted from the article.
    >
    >biSizeImage should contain the size of the bitmap proper in bytes. I say
    >"should " becasuse the field is not necessarily filled in. A call to
    >GetDIBits to generate a DIB fills in this field, but a DIB created manually
    >by an application might not have this filled in. Calculating the size of a
    >bitmap is not hard:
    >biSizeImage= ((((biWidth*biBitCount) + 31) & ~31) >>3) * biHeight;
    >
    >The crazy roundoffs and shifts account for the bitmap being DWORD-aligned at
    >the end of every sacanline. When nonzeor, this field tells an application
    >hwo much stroage space the DIB's bits need. The biSize Image field really
    >becomes useful when dealing with an RLE bitmap, the size of which depends on
    >how well the bitmap was encoded. If an RLE bitmap is to be passed around,
    >the  biSizeImage field is essential.
    >-------------------------------------------------------------------------
    >
    >
    >
    >
    >

 
 
 

C syntax in DIB image size calculation: ">>" and "~"

Post by Rick Franci » Sat, 29 Jan 2000 04:00:00


Cliff, with your approach you will end up with an image that is skewed to the right, assuming it is a bitmap with a bottom left origin.

The reason that your approach doesn't work is because it is not DWORD
aligned in the end.  If you use the same example numbers that I did your
result would be...
biSizeImage = ( ( (24 * 101)+31)/8 ) = 306.875 or 306 * whatever your image
height is.  This is not evenly divisible by 4, and is therefore not DWORD
aligned on each line.  You will end up with an image that is skewed to the
right, the left boundary of the image with follow a diagonal line up the
whole height of the image.  That is why they add 31 to the bitcount * width
and then the drop the last 5 bits of information, which is effectively what
the & ~31 does.

Could you replace the right shift by three with a /8, absolutely, there is
virtually no loss if you are only doing this once.

Rick Francis


  Seems like that ~31 is unnecessary.  
  Use this:
      biSizeImage = ((biBitCount * biWidth + 31) / 8) * biHeight
  the ">> 3" and "/ 8" are pretty much interchangable, any optimizer worth anything will see that /8 is equivalent to >>3 and make the switch.  >>3 is faster than a true divide, which is unnecessary in this case.  

  Hope this helps
  Cliff

  Reply to cliff underscore win at hotmail dot com.

    Vincent...
    The symbol >> means shift bits to the right by the right argument number, in this case 3.  This is a binary function, so in binary terms this is what happens... let's say your number is 256, or
    100000000 in binary notation.  Shifting the number to the right by 3 would result in 100000, or 32, or in human terms a division of the number by 2 to the 3rd, or 8, if you were shifting right by 4 you would effectively be dividing by 2 to the 4th, or 16.  

    The symbol ~ is the ones complement operator... this simply inverts all binary bits.  in the case of 31 which is 00000000000000000000000000011111 in binary, the number becomes 11111111111111111111111111100000, or 4,294,967,246 in base 10.  

    The bottom line is this whole algoritm simply aligns the number on a DWORD, or 4 byte boundary.  All of the results should be evenly divisible by 4.

    Ex:  ImageWidth  = 101, Bitcount = 24

    ((((101 * 24) + 31) & ~31)>>3) =
     ( (2455 & ~31) >> 3) =
        (2455 & 4,294,967,246) >> 3 =
            2432 >> 3 =
                304

    304 is evenly divisible by 4, or DWORD aligned.

    Rick

    >C syntax in DIB image size calculation: ">>" and "~"
    >----------------------------------------------------------------
    >Would you mind giving me a help to explain the following syntax?
    >
    >biSizeImage= ((((biWidth*biBitCount) + 31) & ~31) >>3) * biHeight;
    >
    >What is ">>" and "~"?
    >Why not?
    >biSizeImage= (biWidth*biBitCount / 8) * biHeight;
    >
    >This come from an article: SAMPLE: DIBs and Their Uses.
    >biSizeImage is a member of structure of   BITMAPINFOHEADER.
    >-----------------------------------------------------------------------
    >The following is extracted from the article.
    >
    >biSizeImage should contain the size of the bitmap proper in bytes. I say
    >"should " becasuse the field is not necessarily filled in. A call to
    >GetDIBits to generate a DIB fills in this field, but a DIB created manually
    >by an application might not have this filled in. Calculating the size of a
    >bitmap is not hard:
    >biSizeImage= ((((biWidth*biBitCount) + 31) & ~31) >>3) * biHeight;
    >
    >The crazy roundoffs and shifts account for the bitmap being DWORD-aligned at
    >the end of every sacanline. When nonzeor, this field tells an application
    >hwo much stroage space the DIB's bits need. The biSize Image field really
    >becomes useful when dealing with an RLE bitmap, the size of which depends on
    >how well the bitmap was encoded. If an RLE bitmap is to be passed around,
    >the  biSizeImage field is essential.
    >-------------------------------------------------------------------------
    >
    >
    >
    >
    >