|
-
November 8th, 2010, 10:47 PM
#16
Re: C++ bitmap - why?
Palette doesn't get used ever again after this code, but still gets applied to the image when compiled and ran?
Your right. "That could mean anything from a pointer to this palette not being referenced anymore, to some loop that gets only done once, to who knows whatever. We are not mind readers or psychic."
But, let's think it through for a moment:
I give you a subject (palette), and I tell you it (palette) is never used again after this code. So, whether palette is a reference or pointer, it isn't used anymore.
I don't have an integer in the code to indicate a loop. And, I told you it's not used ever again after this code, so it won't be used in a for loop anywhere. Even if there is a loop before the 2 lines, palette would still need to be used after the code somewhere (EDIT: to set bitmapInfo.bmiColors = to palette, e.g.), whether a pointer or reference. But, then again, I say its not used again after this code; so nope, no for loop, no pointer, no reference.
I only post 2 lines; you should expect these 2 lines to be the only 2 lines relevant. (Tho it still has nothing to do with my code at all)
So, you have 30yrs of programming experience, but don't have analytical skills or grammar skills (context clues)?
Last edited by zaryk; November 8th, 2010 at 11:10 PM.
-
November 8th, 2010, 11:16 PM
#17
Re: C++ bitmap - why?
What the **** dude? What are you expecting? Someone to confirm that some voodoo magic is messing with your code? No one can figure out what is wrong from the sparse code and description you've given. Either post relevant code that duplicates your problem, or just abandon the thread, but please lose the attitude.
-
November 8th, 2010, 11:45 PM
#18
Re: C++ bitmap - why?
What the **** dude? What are you expecting? Someone to confirm that some voodoo magic is messing with your code? No one can figure out what is wrong from the sparse code and description you've given. Either post relevant code that duplicates your problem, or just abandon the thread, but please lose the attitude.
Think, first of all. Use your programming skills to analyze (if/then) the question. And, you could go learn how to draw a bitmap to a screen, and plug the two lines that are relevant and duplicate the problem. And its really not a problem; just an understanding, the problem was fixed when I added those 2 lines in....well, there is an if statement, so logically there would be the block for the if statement, too; but, I'm not sure you all would be able to figure that out.
Plus, I don't have an attitude....your just reading it like I have an attitude. Read it as if informative. 
EDIT: You can start with this: http://www.cplusplus.com/files/winbmp.zip . That will get you started.
Last edited by zaryk; November 8th, 2010 at 11:49 PM.
-
November 9th, 2010, 12:09 AM
#19
Re: C++ bitmap - why?
 Originally Posted by zaryk
I only post 2 lines; you should expect these 2 lines to be the only 2 lines relevant.
Would you like to go over the thousands of posts here where persons post a few lines, thinking that what they post is what's wrong, when it turns out it's another part of the code that they didn't post that is in error? Or how about the thousands of posts where the poster says "I know I didn't do xxxx in my code", but when we finally get a look at their program, they did do xxxx in their code? Why should we treat your post any differently, given you only posted 2 lines?
If you want your post to be treated seriously, don't say "I know I didn't..." or "I know I did ..." plus give us one or two lines -- just post the entire code or function. Programmers do not believe anything until they see the code for themselves. This ensures that whoever is helping you is not on a wild goose chase or involved in an endless thread asking more and more questions.
Note that it was only after I asked for more information and you posted something with a little more info did you get any responses. At some point, someone was going to ask you to provide more information after your initial post -- this time it was me, next time, it will be someone else.
So, you have 30yrs of programming experience, but don't have analytical skills or grammar skills (context clues)?
Insulting CodeGuru participants is against forum rules. Keep it up, and you will have a short stay here.
I will say it once again -- programming is an exact science. You may not like it, but that's the way it is. If you can't take the time to formulate a proper question, then you should seek help from someone who is sitting at your computer looking at your code instead of asking one of us.
And no, it isn't our job to try and recreate your problem, whatever that problem is. That is your job to take the time to get the information in a form that has sufficient enough information for third-parties (such as the volunteers here) to answer your question as quickly as possible.
Regards,
Paul McKenzie
Last edited by Paul McKenzie; November 9th, 2010 at 12:44 AM.
-
November 9th, 2010, 03:27 AM
#20
Re: C++ bitmap - why?
Ok..I was just asking a question, if you find that insulting you must not have confidence in your abilities....So, Ill show you the code from winbmp, just to make you feel better (raise your self-esteem), because it does the same thing as mine.
Code:
//winbmp.zip
// *************************************************************
// BMP LOAD EXAMPLE
// Written by Juan Soulie <[email protected]>
// *************************************************************
#include <windows.h>
#include <fstream>
char szAppName [] = "BMPLoad";
LRESULT CALLBACK WindowProc (HWND, UINT, WPARAM, LPARAM);
// **********
// class CRaster
// - Generic class for BMP raster images.
class CRaster {
public:
int Width,Height; // Dimensions
int BPP; // Bits Per Pixel.
char * Raster; // Bits of the Image.
RGBQUAD * Palette; // RGB Palette for the image.
int BytesPerRow; // Row Width (in bytes).
BITMAPINFO * pbmi; // BITMAPINFO structure
// Member functions (defined later):
int LoadBMP (char * szFile);
int GDIPaint (HDC hdc,int x,int y);
};
// **********
// Windows Main Function.
// - Here starts our demo program
int WINAPI WinMain ( HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow )
{
HWND hwnd;
MSG msg;
WNDCLASS wc;
wc.style = CS_HREDRAW|CS_VREDRAW;
wc.lpfnWndProc = WindowProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor (NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH) (COLOR_WINDOW+1);
wc.lpszMenuName = NULL;
wc.lpszClassName = szAppName;
RegisterClass (&wc);
hwnd = CreateWindow (szAppName,"BMP Load",WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,
0,0,hInstance,0);
ShowWindow (hwnd,nCmdShow);
UpdateWindow (hwnd);
while (GetMessage(&msg,0,0,0))
{
TranslateMessage (&msg);
DispatchMessage (&msg);
}
return msg.wParam;
}
// **********
// Main Window Procedure.
// - Processes Window Messages
LRESULT CALLBACK WindowProc
(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static CRaster bmp;
HDC hdc;
PAINTSTRUCT ps;
switch (message)
{
case WM_CREATE:
bmp.LoadBMP ("C:\\tux.bmp");
return 0;
case WM_PAINT:
hdc=BeginPaint (hwnd,&ps);
bmp.GDIPaint (hdc,10,10);
EndPaint (hwnd,&ps);
return 0;
case WM_DESTROY:
PostQuitMessage (0);
return 0;
}
return DefWindowProc (hwnd,message,wParam,lParam);
}
// **********
// CRaster::LoadBMPFile (FileName);
// - loads a BMP file into a CRaster object
// * supports non-RLE-compressed files of 1, 2, 4, 8 & 24 bits-per-pixel
int CRaster::LoadBMP (char * szFile)
{
BITMAPFILEHEADER bmfh;
BITMAPINFOHEADER bmih;
// Open file.
std::ifstream bmpfile (szFile , std::ios::in | std::ios::binary);
if (! bmpfile.is_open()) return 1; // Error opening file
// Load bitmap fileheader & infoheader
bmpfile.read ((char*)&bmfh,sizeof (BITMAPFILEHEADER));
bmpfile.read ((char*)&bmih,sizeof (BITMAPINFOHEADER));
// Check filetype signature
if (bmfh.bfType!='MB') return 2; // File is not BMP
// Assign some short variables:
BPP=bmih.biBitCount;
Width=bmih.biWidth;
Height= (bmih.biHeight>0) ? bmih.biHeight : -bmih.biHeight; // absoulte value
BytesPerRow = Width * BPP / 8;
BytesPerRow += (4-BytesPerRow%4) % 4; // int alignment
// If BPP aren't 24, load Palette:
if (BPP==24)
pbmi=(BITMAPINFO*)new char [sizeof(BITMAPINFO)];
else
{
pbmi=(BITMAPINFO*) new char[sizeof(BITMAPINFOHEADER)+(1<<BPP)*sizeof(RGBQUAD)];
Palette=(RGBQUAD*)((char*)pbmi+sizeof(BITMAPINFOHEADER));
bmpfile.read ((char*)Palette,sizeof (RGBQUAD) * (1<<BPP));
}
pbmi->bmiHeader=bmih;
// Load Raster
bmpfile.seekg (bmfh.bfOffBits, std::ios::beg);
Raster= new char[BytesPerRow*Height];
// (if height is positive the bmp is bottom-up, read it reversed)
if (bmih.biHeight>0)
for (int n=Height-1;n>=0;n--)
bmpfile.read (Raster+BytesPerRow*n,BytesPerRow);
else
bmpfile.read (Raster,BytesPerRow*Height);
// so, we always have a up-bottom raster (that is negative height for windows):
pbmi->bmiHeader.biHeight=-Height;
bmpfile.close();
return 0;
}
// **********
// CRaster::GDIPaint (hdc,x,y);
// * Paints Raster to a Windows DC.
int CRaster::GDIPaint (HDC hdc,int x=0,int y=0)
{
// Paint the image to the device.
return SetDIBitsToDevice (hdc,x,y, Width, Height, 0, 0, 0,Height,(LPVOID)Raster,pbmi,0);
}
Last edited by zaryk; November 9th, 2010 at 04:00 AM.
-
November 9th, 2010, 05:59 AM
#21
Re: C++ bitmap - why?
 Originally Posted by zaryk
Ok..I was just asking a question, if you find that insulting
Do you read your own posts? Where was I insulted by your question? It is your reaction to merely being asked to provide more information is where you start the insults. Your post was getting no responses, and was only responded to after I asked for more information.
you must not have confidence in your abilities....
No confidence, but I have the ability to contribute here for over a decade answering questions -- that alone puts that notion to rest. I won't bother going into my other credentials, because I'm humble (so humble that I don't even post my Microsoft MVP logo here). But it won't matter, because you know more than anyone here. 
So, Ill show you the code from winbmp, just to make you feel better (raise your self-esteem),
I don't need "esteem raised" -- it should have been posted to help us answer your question.. All I asked you was for more information so that we can help you, but for some reason, you are hostile to the ones here who are helping you.
If you want to know why the code does what it does, then here it is:
Code:
// **********
// Main Window Procedure.
// - Processes Window Messages
LRESULT CALLBACK WindowProc
(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static CRaster bmp;
You create a CRaster object that is declared as static. That means that the lifetime of the object is perpetual, but can only be accessed within the WindowProc function.
Code:
switch (message)
{
case WM_CREATE:
bmp.LoadBMP ("C:\\tux.bmp");
return 0;
This is where you are loading the bitmap within the WM_CREATE message. WM_CREATE is sent on window creation by the OS, so it's only called once.
Code:
case WM_PAINT:
hdc=BeginPaint (hwnd,&ps);
bmp.GDIPaint (hdc,10,10);
WM_PAINT message is sent whenever the client area of the window needs to be updated. Since the bmp object has been loaded with the bitmap, and bmp has not gone out of scope (because it is static), the bitmap is still valid, and you're just painting the area of the window with the bitmap.
Code:
// **********
// CRaster::LoadBMPFile (FileName);
// - loads a BMP file into a CRaster object
// * supports non-RLE-compressed files of 1, 2, 4, 8 & 24 bits-per-pixel
int CRaster::LoadBMP (char * szFile)
{
This code needs to be called only once, and it is called during the WM_CREATE message.
See how simple that all was when you provide the information? So what was the tirade you had in your second post all about? Now do you understand how that bitmap need not be created over and over again, or do you need more explanation?
But let's take a look at your initial post, and the code you eventually posted. Do you think in your wildest dreams that anyone could come up with that final code from your original post? Were we supposed to somehow extrapolate from your first post CRaster, static variables, WM_CREATE, etc.?
Regards,
Paul McKenzie
Last edited by Paul McKenzie; November 9th, 2010 at 06:34 AM.
-
November 9th, 2010, 08:48 AM
#22
Re: C++ bitmap - why?
It's useless wasting time answering a question about palettes and the window's bmp format if you don't know them, and it's useless arguing with people who don't know palettes and the window's bmp format.
 Originally Posted by zaryk
There is nothing else that is related to the palette.
Yes, there is, but it is somewhat hidden. You have two fields in the BITMAPINFOHEADER:
1. biClrUsed
2. biBitCount
See http://msdn.microsoft.com/en-us/libr...76(VS.85).aspx
The code from winbmp is not correct. It has a bug about the palette.
You could have found better source codes. I learnt about bitmaps in a good old book called Ben Ezzell, Graphics Programming, Ziff Davis.
The bug is here:
Code:
// If BPP aren't 24, load Palette:
if (BPP==24)
A better code is
Code:
if (bmih.biClrUsed == 0 || BPP >= 24)
Edit: It is very likely the value of BPP (biBitCount) is 32 in your image, because it is often 32 for images, nowadays, therefore your image would have no palette.
The program tries to read the palette with the line:
Code:
bmpfile.read ((char*)Palette,sizeof (RGBQUAD) * (1<<BPP))
But, if BPP is 32, then 1<<BPP is out of the limits of a 32-bit integer (and not testing the limit is another bug of this ugly source code).
I guess your compiler, and your environment will give you 0. So you have an empty palette. Then, with your additional line, you tell Windows to use an empty palette (or not to use the default palette), and that's why your code would work.
Re Edit: Or maybe I have not understood very well how the palette is taken into account into your program. Anyway, don't do 1<<32, and, in the first time, have a better test than if (BPP==24).
Last edited by olivthill2; November 9th, 2010 at 11:12 AM.
-
November 9th, 2010, 09:57 AM
#23
Re: C++ bitmap - why?
You quoted me, and then I thought you were talking about yourself when you said, "Insulting CodeGuru participants is against forum rules." You know, context clues.
EDIT: oliv, technically your right. But, those have nothing to do with what I have been trying to get an answer to.
I didn't write the provided code, and my code isn't based on that code. My code includes a gui class (global to WinMain) and a bitmap class (declared in gui)...and the bitmap class is used to subclass a static control (in the gui class) into a imagebox more or less.
images are 4 bit...and I know 24 and 32 bit images, don't have a palette. EDIT: Problem isn't with the images...I have images to test 1, 4, 8, 16, 24, 32 bits
Let me try this again, I don't care whether Craster is static or not, I don't care whether craster is in winproc. Whether Craster is global or not, it still displays the image, and the code is still good enough (tho shouldnt be required)
Pay attention to:
RGBQUAD * Palette; // RGB Palette for the image.
//Palette=(RGBQUAD*)((char*)pbmi+sizeof(BITMAPINFOHEADER));
//bmpfile.read ((char*)Palette,sizeof (RGBQUAD) * (1<<BPP));
nothing else
Code:
//winbmp.zip
// *************************************************************
// BMP LOAD EXAMPLE
// Written by Juan Soulie <[email protected]>
// *************************************************************
#include <windows.h>
#include <fstream>
char szAppName [] = "BMPLoad";
LRESULT CALLBACK WindowProc (HWND, UINT, WPARAM, LPARAM);
// **********
// class CRaster
// - Generic class for BMP raster images.
class CRaster {
public:
int Width,Height; // Dimensions
int BPP; // Bits Per Pixel.
char * Raster; // Bits of the Image.
RGBQUAD * Palette; // RGB Palette for the image.
int BytesPerRow; // Row Width (in bytes).
BITMAPINFO * pbmi; // BITMAPINFO structure
// Member functions (defined later):
int LoadBMP (char * szFile);
int GDIPaint (HDC hdc,int x,int y);
};
// **********
// Windows Main Function.
// - Here starts our demo program
int WINAPI WinMain ( HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow )
{
HWND hwnd;
MSG msg;
WNDCLASS wc;
wc.style = CS_HREDRAW|CS_VREDRAW;
wc.lpfnWndProc = WindowProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor (NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH) (COLOR_WINDOW+1);
wc.lpszMenuName = NULL;
wc.lpszClassName = szAppName;
RegisterClass (&wc);
hwnd = CreateWindow (szAppName,"BMP Load",WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,
0,0,hInstance,0);
ShowWindow (hwnd,nCmdShow);
UpdateWindow (hwnd);
while (GetMessage(&msg,0,0,0))
{
TranslateMessage (&msg);
DispatchMessage (&msg);
}
return msg.wParam;
}
// **********
// Main Window Procedure.
// - Processes Window Messages
LRESULT CALLBACK WindowProc
(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static CRaster bmp;
HDC hdc;
PAINTSTRUCT ps;
switch (message)
{
case WM_CREATE:
bmp.LoadBMP ("C:\\tux.bmp");
return 0;
case WM_PAINT:
hdc=BeginPaint (hwnd,&ps);
bmp.GDIPaint (hdc,10,10);
EndPaint (hwnd,&ps);
return 0;
case WM_DESTROY:
PostQuitMessage (0);
return 0;
}
return DefWindowProc (hwnd,message,wParam,lParam);
}
// **********
// CRaster::LoadBMPFile (FileName);
// - loads a BMP file into a CRaster object
// * supports non-RLE-compressed files of 1, 2, 4, 8 & 24 bits-per-pixel
int CRaster::LoadBMP (char * szFile)
{
BITMAPFILEHEADER bmfh;
BITMAPINFOHEADER bmih;
// Open file.
std::ifstream bmpfile (szFile , std::ios::in | std::ios::binary);
if (! bmpfile.is_open()) return 1; // Error opening file
// Load bitmap fileheader & infoheader
bmpfile.read ((char*)&bmfh,sizeof (BITMAPFILEHEADER));
bmpfile.read ((char*)&bmih,sizeof (BITMAPINFOHEADER));
// Check filetype signature
if (bmfh.bfType!='MB') return 2; // File is not BMP
// Assign some short variables:
BPP=bmih.biBitCount;
Width=bmih.biWidth;
Height= (bmih.biHeight>0) ? bmih.biHeight : -bmih.biHeight; // absoulte value
BytesPerRow = Width * BPP / 8;
BytesPerRow += (4-BytesPerRow%4) % 4; // int alignment
// If BPP aren't 24, load Palette:
if (BPP==24)
pbmi=(BITMAPINFO*)new char [sizeof(BITMAPINFO)];
else
{
pbmi=(BITMAPINFO*) new char[sizeof(BITMAPINFOHEADER)+(1<<BPP)*sizeof(RGBQUAD)];
//Palette=(RGBQUAD*)((char*)pbmi+sizeof(BITMAPINFOHEADER));
//bmpfile.read ((char*)Palette,sizeof (RGBQUAD) * (1<<BPP));
}
pbmi->bmiHeader=bmih;
// Load Raster
bmpfile.seekg (bmfh.bfOffBits, std::ios::beg);
Raster= new char[BytesPerRow*Height];
// (if height is positive the bmp is bottom-up, read it reversed)
if (bmih.biHeight>0)
for (int n=Height-1;n>=0;n--)
bmpfile.read (Raster+BytesPerRow*n,BytesPerRow);
else
bmpfile.read (Raster,BytesPerRow*Height);
// so, we always have a up-bottom raster (that is negative height for windows):
pbmi->bmiHeader.biHeight=-Height;
bmpfile.close();
return 0;
}
// **********
// CRaster::GDIPaint (hdc,x,y);
// * Paints Raster to a Windows DC.
int CRaster::GDIPaint (HDC hdc,int x=0,int y=0)
{
// Paint the image to the device.
return SetDIBitsToDevice (hdc,x,y, Width, Height, 0, 0, 0,Height,(LPVOID)Raster,pbmi,0);
}
If you all would take the time to pay attention to what I am asking rather than straying off, you will see that palette isn't used ever again. There are only 3 entries found of palette.
Those 2 lines commented out give either a black image or irregular colored, I really don't care which. Those 2 lines uncommented out give a nice clean correct picture. Those 2 lines shouldn't be getting applied to the image at all, from what I see....which goes back to those 2 lines being the only relevant lines. And I see this on a lot of examples, not just this one....whether you use a for loop to read in the palette or this way.
Last edited by zaryk; November 9th, 2010 at 10:16 AM.
-
November 9th, 2010, 10:21 AM
#24
Re: C++ bitmap - why?
 Originally Posted by zaryk
...
Those 2 lines commented out give either a black image or irregular colored, I really don't care which. Those 2 lines uncommented out give a nice clean correct picture. Those 2 lines shouldn't be getting applied to the image at all, from what I see....which goes back to those 2 lines being the only relevant lines. And I see this on a lot of examples, not just this one....whether you use a for loop to read in the palette or this way.
"Those 2 lines commented out" give you nothing but garbage that you then pass in SetDIBitsToDevice(...) function...
Victor Nijegorodov
-
November 9th, 2010, 10:26 AM
#25
Re: C++ bitmap - why?
Really? I wouldn't ever guess. Have an Idea why they work when uncommented? Technically, they should give you garbage either way.
Last edited by zaryk; November 9th, 2010 at 10:29 AM.
-
November 9th, 2010, 10:28 AM
#26
Re: C++ bitmap - why?
 Originally Posted by zaryk
Really? I wouldn't ever guess. Have an Idea why they work when uncommented?
I don't know! Perhaps some correct data is read from a bitmap file?
Victor Nijegorodov
-
November 9th, 2010, 10:33 AM
#27
Re: C++ bitmap - why?
 Originally Posted by zaryk
If you all would take the time to pay attention to what I am asking rather than straying off, you will see that palette isn't used ever again. There are only 3 entries found of palette.
Those 2 lines commented out give either a black image or irregular colored, I really don't care which. Those 2 lines uncommented out give a nice clean correct picture. Those 2 lines shouldn't be getting applied to the image at all, from what I see....which goes back to those 2 lines being the only relevant lines. And I see this on a lot of examples, not just this one....whether you use a for loop to read in the palette or this way.
Why does this surprise you? You're pointing "Palette" to the palette area of your bitmap, then reading the palette colors from the bmp file. Eliminating this step leaves random garbage in the palette area of your bitmap.
-
November 9th, 2010, 10:34 AM
#28
Re: C++ bitmap - why?
Victor: That might be an explanation, but still doesn't explain, why commented, the images are black or irregular colored, and uncommented it works perfect.
hox: Im surprised because its working and shouldn't be.
I don't see how this is applying the palette to anything.
Code:
if(!(bmp.palette = (RGBQUAD*) ((BYTE*)bmp.bitmapInfo + sizeof(BITMAPINFOHEADER))))
if(!fread(bmp.palette, sizeof(RGBQUAD), bmp.nColors, file))
Palette points to the palette area of the bitmap
retrieves the information
.....then what....never used in the final drawing of the image. Unless it automatically fills in bmp.bitmapInfo->bmiColors automatically?
Last edited by zaryk; November 9th, 2010 at 10:51 AM.
-
November 9th, 2010, 10:43 AM
#29
Re: C++ bitmap - why?
How much clearer can I state it? There is a palette in the file and a palette in the bitmap structure. Commenting those lines makes the code fail to load the palette from the file. Without filling in the palette, there's random garbage in that part of the bitmap structure (or zeroed memory if you're in debug).
-
November 9th, 2010, 10:56 AM
#30
Re: C++ bitmap - why?
I guess I should have quoted since you edited your post eliminating all context of my reply. Apparently you understand now, right?
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|