CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 5 of 5
  1. #1
    Join Date
    Aug 2004
    Posts
    6

    Question for Bitmap Decoding

    Hi, I am trying to get the pixel info from a bitmap file but encountered some difficulties. The ones that I am trying is a monochrome (biBitCount == 1) and their header info are as follows:

    Test File ----------- (1) ----------- (2) --------- (3) ---------- (4) --------- (5) -------- (6)

    info got from bitmap header:

    bmWidth ---------- 84 ---------- 168 -------- 252 --------- 335 -------- 419 ------- 586
    bmHeight -------- 606 -------- 1211 ------ 1817 -------- 2422 ------- 3028 ----- 4239
    bmWidthBytes --- 12 ----------- 24 ---------- 32 ----------- 44 ---------- 56 -------- 76

    ==========================================================

    # bytes to get --- 12 ----------- 22 ---------- 32 ----------- 42 ---------- 54 ------- 74

    I know that Each line in the array of data for the bitmap must be LONG aligned (divisible by 4 bytes).

    Since I was decoding row by row, if taking the number of bytes specified as "bmWidthBytes" in the header for the entire row, and encoded the bit of each byte for the pixels (1 => white, 0 => black), only test file (1) and (3) got the image right, others would get a skewed result and some info missing at the bottom of image. This makes me think more bytes have been taken than necessary, which belong to the next row of image.

    If taking the number of bytes as "# bytes to get", then everything was OK. I got these with trial and error!

    Does any one see what is wrong and how to figure out the right number of bytes to take for the entire row? Thanks for any help in advance.

    Raymond
    Last edited by rayq; September 7th, 2004 at 11:38 AM.

  2. #2
    Join Date
    Nov 2001
    Location
    Beyond Juslibol
    Posts
    1,688

    Re: Question for Bitmap Decoding

    The bmWidthBytes values are the correct.

    I think the problem is in your processing code.

  3. #3
    Join Date
    Jan 2004
    Location
    Earth
    Posts
    567

    Re: Question for Bitmap Decoding

    Originally quoted by rayq
    I know that Each line in the array of data for the bitmap must be LONG aligned (divisible by 32).
    The number of bytes in each line in the bitmap must be evenly divisible by 4, if it isn't windows will pad the the line with either 1, 2 or 3 bytes to make it evenly divisible by 4.

    In the bitmap file header, the width is bytes 18 through 21 and the height is bytes 22 through 25. You have to take the bytes and create an unsigned long value to get the numbers. This can be done easily with the MAKEWORD and MAKELONG macros. The total size of the header is 54 bytes.

    One final note, the first line in the bitmap is the last line in the file.

    Hope that helps
    Last edited by TDM; September 3rd, 2004 at 09:19 PM.

  4. #4
    Join Date
    Aug 2004
    Posts
    6

    Re: Question for Bitmap Decoding

    Thanks for your replies!

    I don't see (or can't see) anything wrong with my code . below is what I wrote to deal with monochrome bitmap:




    {
    :
    CBitmap bitmap;
    bitmap.Attach(hBmp);

    // get info from bitmap file hdr.DIBSECTION ds;
    bitmap.GetObject(sizeof(ds), &ds);

    int width = ds.dsBmih.biWidth;
    int height = ds.dsBmih.biHeight;

    long imgSiz = ds.dsBmih.biSizeImage;
    BYTE *bmBits = new BYTE[imgSiz]; // To store bitmap pixels.
    // get bm bits from bitmap.
    bitmap->GetBitmapBits(imgSiz, bmBits);

    // to store indices to cgm color table
    USHORT *cellarray = new USHORT[width * height];

    int numwidthbytes = ds.dsBm.bmWidthBytes;

    // to store pixels of whole row
    BYTE *widthbyte = new BYTE[numwidthbytes];

    int row, col, cntr;
    for (row = 0, cntr = 0; row < height; row++)
    {
    // copy entire row bytes
    memcpy(widthbyte, &bmBits[row * 22], 22); // ***

    for (col = 0; col < width; col++)
    cellarray[cntr++] = set_Pixels(widthbyte[col / 8], col);
    }

    :
    :

    delete [] widthbyte;
    delete [] cellarray;
    delete [] bmBits;
    }




    // Decode bit info for exported pixel
    USHORT CgsCGMFile::set_Pixels(const BYTE bmbyte, const int col)
    {
    int bitpos = (col + 1) % 8;

    USHORT pixel = 0; // set to black

    switch (bitpos) // order from left to right
    {
    case 1: // 1xxx xxxx
    if (bmbyte & 0x80)
    pixel = 1; // set to white

    break;
    case 2: // x1xx xxxx
    if (bmbyte & 0x40)
    pixel = 1; // set to white
    break;
    case 3: // xx1x xxxx
    if (bmbyte & 0x20)
    pixel = 1; // set to white
    break;
    case 4: // xxx1 xxxx
    if (bmbyte & 0x10)
    pixel = 1; // set to white
    break;
    case 5: // xxxx 1xxx
    if (bmbyte & 0x08)
    pixel = 1; // set to white
    break;
    case 6: // xxxx x1xx
    if (bmbyte & 0x04)
    pixel = 1; // set to white
    break;
    case 7: // xxxx xx1x
    if (bmbyte & 0x02)
    pixel = 1; // set to white
    break;
    case 0: // xxxx xxx1
    if (bmbyte & 0x01)
    pixel = 1; // set to white
    break;
    default:
    break;
    }

    return pixel;
    }



    What I am working on is to convert bitmap to CGM format with cgmcell_array(). The array "cellarray" is to store pixel information for use in "cgmcell_array" function. The problem happened in the line (with comment // ***) inside the for loop. Note that I used "22" (for test (2)) not "numwidthbytes" (= ds.dsBm.bmWidthBytes) or "24" to get the correct result.

    Thanks for any help in advance.

    Raymond
    Last edited by rayq; September 7th, 2004 at 11:50 AM.

  5. #5
    Join Date
    Aug 2004
    Posts
    6

    Unhappy Any Help??? (NT)

    ......

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured