Skip to main content
gamedev.net
🔒 Locked

Bitmaps

Started by MattCarpenter 18 replies 1k views
Original Post
MattCarpenter
MattCarpenter
Hey, Im using some AVI functions to get a specified frame from an AVI video. That function returns a pointer to a BITMAPINFO object. Looks like this: LPBITMAPINFO mybitmap = (LPBITMAPINFO)AVIStreamGetFrame(blablabla); The problem though, is I cant find where the pixel data is stored in this bitmap structure thing :s Ive tried using mybitmap->bmiColors[pixeloffset].rgbRed, rgbBlue, and rgbGreen to get the color values value for a certian offset, but I guess the bmiColors structure does not contain the pixel data because I get about 10 colors and the rest is black. (btw, I calculate the offset for a pixel like this: offset=imagewidth*y+x) So, my question, How do I obtain the pixel values from a pointer to a LPBITMAPINFO object? Thanks Or could it be that the bmiColors array doesn''t contain just the linear pixel color values?
//att
Burning_Ice
Burning_Ice
are you sure you are supposed to somehow get pixel data with this function?
a BITMAPINFO structure is what the name says...it just contains information about the bitmap, like size and stuff in the structures bmiHeader part.
the bmiColors part just contains color info. In a 24 bit bmp it is NULL, that's propably where your errors come from.

but a BITMAPINFO structure contains not the actual image data. perhaps you should check the docs of your AVI Api again.

Edit: Actually i just did it myself and the prototype for the function according to MSDN is
STDAPI_(LPVOID) AVIStreamGetFrame(
PGETFRAME pgf,
LONG lPos
);

so don't try converting the void* to a BITMAPINFO* there. It says the void* points to a packed DIB.




Runicsoft -- home of my open source Function Parser and more

[edited by - Burning_Ice on November 28, 2002 4:25:00 PM]
niyaw
niyaw
quote:
Original post by Burning_Ice
a BITMAPINFO structure is what the name says...it just contains information about the bitmap, like size and stuff in the structures bmiHeader part.


this is correct. however, a pointer to bitmapinfo structure can also be used to get to the bitmap bits, which you missed.
quote:

the bmiColors part just contains color info. In a 24 bit bmp it is NULL, that''s propably where your errors come from.
[quote]
since it''s a variable-length array, and not a pointer, it can never be null.
[quote]
but a BITMAPINFO structure contains not the actual image data.


it doesn''t; image data immediately follows it.
quote:
msdn: bitmapinfo
A bitmap is packed when the bitmap array immediately follows the BITMAPINFO header.


quote:

perhaps you should check the docs of your AVI Api again.


perhaps you should check the docs so that you actually have a clue what you''re talking about.
quote:

Actually i just did it myself


surely you have a program that doesn''t work that you can show us?
quote:

so don''t try converting the void* to a BITMAPINFO* there. It says the void* points to a packed DIB.


now open that page again and read remarks this time.

now to OP:
first, determine how big the color table (palette) is. for a true-color bitmap, it should have two dummy elements so that bitmap data is dword-aligned, or it may be nonexistent. once you know that, a pointer just after the color table will point to bitmap bits.
Burning_Ice
Burning_Ice
quote:

this is correct. however, a pointer to bitmapinfo structure can also be used to get to the bitmap bits, which you missed.


a BITMAPINFO structure alone still can not be used for it. only if you have a complete DIB there's the image data behind this structure, that's what i tried to say

quote:

since it's a variable-length array, and not a pointer, it can never be null.


please check MSDN, it says:
"The bitmap has a maximum of 2^24 colors, and the bmiColors member is NULL. Each 3-byte triplet in the bitmap array represents the relative intensities of blue, green, and red, respectively, for a pixel. "



quote:

surely you have a program that doesn't work that you can show us?



if you would have taken the time to read my post you would have noticed that my last sentence was
"perhaps you should check the docs again"
and my Edit said that i just did it (check the docs! not code anything), where i could see that indeed the function does not return a LPBITMAPINFO but a LPVOID.


quote:

now open that page again and read remarks this time.



okok, so i admit that i just tried to write a helping post and not read the entire docs again, but my point was (sorry if i wasn't clear enough):
The function does not return a LPBITMAPINFO. It returns a pointer to a packed DIB. So the actual data is after the info struct, but you can't get any image data out of the info struct itself.
That's all i wanted to say. I don't understand why that made you so angry, but i apologize anyway.
The 'you should check the docs again' was in no way meant unfriendly, i just said this because i thought that there has to be an error if ALL the function returns would be a pointer to a BITMAPINFO.
But as it is it returns more then the info struct, so its all ok now i hope.






Runicsoft -- home of my open source Function Parser and more

[edited by - Burning_Ice on November 28, 2002 5:39:19 PM]
MattCarpenter
MattCarpenter
Well, Im kinda confused about whos saying what, but thanks! So basicaly, to get the bitmap data, you just have to get a pointer to the data right after the bmpinfo structure?

Anyways, to get that pointer would I haveto do something like this?

char *pBMPData;
pBMPData=&bmpinfo+sizeof(bmpinfo);
//att
Evil Bill
Evil Bill
Yep. The bitmap header gives you information about the frame, and the bit data follows it.
From the MSDN:
quote:

If the bitmap is a packed bitmap (a bitmap in which the bitmap array immediately follows the BITMAPINFO header and is referenced by a single pointer), the biClrUsed member must be either zero or the actual size of the color table.


So you can use that to see if there is a colour table, and how large it is.

Member of the Unban Mindwipe Society (UMWS)
MattCarpenter
MattCarpenter
Is that from the MSDN site? I''ve been using the MSDN cd''s to do this stuff. I guess what Im trying to do is make a program that takes homevideo stuff and applys some filters and motion blur to make a video taken from a camcorder look like something taken from a film movie camera
//att
MattCarpenter
MattCarpenter
So, uhh, would this work to give me a pointer to the pixel data? (Im kinda a c++ N00bie)
LPVOID bmpinfo = (LPVOID)AVIStreamGetFrame(blablabla);
char *pData; //Pointer to pixel data?
pData=&bmpinfo+sizeof(bmpinfo);
//att
MattCarpenter
MattCarpenter
Wait, uhh I dont think that would work.
Would it be more like this?

LPBMPINFO bmpinfo (LPBMPINFO)AVIStreamGetFrame(...);
char *pData;
pData=&bmpinfo+bmpinfo->bmiHeader.biSize;

Ehh I dunno, I have no idea what I''m doing :-\
//att
Evil Bill
Evil Bill
That quote was from the MSDN CDs (under BITMAPINFOHEADER).

LPBMPINFO bmpinfo (LPBMPINFO)AVIStreamGetFrame(...);
char *pData;
pData=&bmpinfo+bmpinfo->bmiHeader.biSize

i think is right, but to be honest i''m not sure. It looks right anyway. The best thing to do is give it a try and find out.
Member of the Unban Mindwipe Society (UMWS)
_heitsu_
_heitsu_
i do it like this and it works just fine

LPBITMAPINFOHEADER header;
header = (LPBITMAPINFOHEADER)AVIStreamGetFrame(...);
BYTE *pdata = (BYTE *)header + (header->biSize + header->biClrUsed * sizeof(RGBQUAD));
MattCarpenter
MattCarpenter
I did this and it works just fine
LPBITMAPINFOHEADER bmpinfo = (LPBITMAPINFOHEADER)AVIStreamGetFrame(pgf,lFrame); // returns NULL if error

BYTE *pdata = (BYTE *)bmpinfo + (bmpinfo->biSize + bmpinfo->biClrUsed * sizeof(RGBQUAD));


Butttt, Im kinda stuck again (whatta surprise), would *pdata be an array of data? Or is *pdata just the first byte of the pixel data? I tried using this just to try to display the bitmap or at least get colors, but it was all black :-/

for(int x=0;x<321;x++) {
for(int y=0;y<321;y++){
int r=*pdata;
pdata++;
int g=*pdata;
pdata++;
int b=*pdata;
pdata++;
SetPixel(GetDC(ghwnd),x,y,RGB(r,g,b));
}
}
//att
MattCarpenter
MattCarpenter
Hm... Then I did this:
for(int x=0;x<321;x++) {
for(int y=0;y<321;y++){
char buffer[255];
sprintf(buffer,"%i ",*pdata);
pdata++;
sprintf(buffer,"%i ",*pdata);
OutputDebugString(buffer);
pdata++;
sprintf(buffer,"%i ",*pdata);
OutputDebugString(buffer);
pdata++;

OutputDebugString(buffer);
//SetPixel(GetDC(ghwnd),x,y,RGB(r,g,b));
}
}

I got a lot of 10''s, 11''s, 12''s, 13''s, and a few larger #''s in the 200''s or so. And then, when x reached 110 and y reached 156, I got an access violation error :|
//att
Evil Bill
Evil Bill
I don't know about that problem, but theres a couple of errors there:
1) the returned data is an array of RGBQUADs, but you're only extracting 3 bytes (instead of 4). You should either cast pdata to an RGBQUAD*, or add another pdata++ at the end of your 'y' loop.
2)You should be calling ReleaseDC() for every call to GetDC() otherwise you might eat system resources, and cause GetDC() to fail (which would likely result in not writing any anything - i.e. blackness).

What are you SetPixel()ing for? Is this just in your window? Is this MFC? Dialog based or Single Docuument?
At least you're not getting any access violations

Edit: Ok, *now* you're getting access violations



[edited by - Evil Bill on November 29, 2002 3:12:32 PM]
Member of the Unban Mindwipe Society (UMWS)
MattCarpenter
MattCarpenter
Well, I did use the DIBSetToDevice or whatever to draaw the image to my window (not MFC). But, I don''t really need to draw the stuff to the window, I just need the pixel color values for what Im doing. Uhh when I did use the DibSetToDevice or whatever, this happened :| http://www.lancecoders.com/avi.JPG

Are you sure I am trying to use an RGBQUAD? When I use this, BYTE *pdata = (BYTE *)bmpinfo + (bmpinfo->biSize + bmpinfo->biClrUsed * sizeof(RGBQUAD));
, Aren''t I suppose to be getting a pointer to just the plain bitmap data? oR is the RGBQUAD the bitmap data? :s


PERSON *Matt;
Matt->State="CONFUSED";
Matt->EatCandy(CANDY_BUTTERFINGER);
//att
_heitsu_
_heitsu_
yes the pdata pointer points to the start of the bitmap data...and the data is plain RGB

http://nehe.gamedev.net/tutorials/lesson.asp?l=35

there is a tutorial that can help you to solve your problem
_heitsu_
_heitsu_
btw...what are u going to do with the pixel data? Are going to make a texture or something like that from it??
MattCarpenter
MattCarpenter
Well basically what I was doing was just trying to extract all the pixel information so I could manipulate it (apply filters and effects) and then put it back into the AVI.
I guess its possible that Its trying to use a pallete, so I''ll see if I can mess around with that and get it to work
//att

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.