|
ALLEGRO_FILE bug? |
komons
Member #11,083
June 2009
|
Hi, I save bmp file by two ways. First: windows handle method, Second: ALLEGRO_FILE, and there are some differences. Why? Windows handle: ALLEGRO_FILE: Why ALLEGRO_FILE method saved crap file? code: 1void C_Tools::hwndToBitmap(HWND hwnd)
2{
3 BITMAPFILEHEADER bmfh = {0};
4 BITMAPINFOHEADER bmih = {0};
5 RECT rc = {0};
6 HDC hdc1;
7 HDC hdc2;
8 HBITMAP aBmp;
9 BITMAPINFO bi;
10 HGDIOBJ OldObj;
11 void *dibvalues;
12 HANDLE fileHandle;
13 DWORD bytes_written;
14 int w;
15 int h;
16
17 hdc1 = GetWindowDC(hwnd);
18 hdc2 = CreateCompatibleDC(hdc1);
19 GetWindowRect(hwnd, &rc);
20 w = rc.right-rc.left;
21 h = rc.bottom-rc.top;
22
23 bmih.biSize = sizeof(BITMAPINFOHEADER);
24 bmih.biWidth = w;
25 bmih.biHeight = h;
26 bmih.biPlanes = 1;
27 bmih.biBitCount = 24;
28 bmih.biCompression = BI_RGB;
29 bmih.biSizeImage = ((((bmih.biWidth * bmih.biBitCount) + 31) & ~31) >> 3) * bmih.biHeight;
30 bi.bmiHeader = bmih;
31
32 aBmp = CreateDIBSection(hdc1, &bi ,DIB_RGB_COLORS, (void**)&dibvalues, NULL, NULL);
33 OldObj = SelectObject(hdc2, aBmp);
34 BitBlt(hdc2, 0, 0, w, h, hdc1, 0, 0, SRCCOPY);
35 bmfh.bfOffBits = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);
36 bmfh.bfSize = (3*bmih.biHeight*bmih.biWidth)+sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);
37 bmfh.bfType = 0x4d42;
38
39 fileHandle = CreateFile(L"aaa.bmp", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
40 ALLEGRO_FILE* file = al_fopen("aaa2.bmp","w");
41
42 WriteFile(fileHandle, &bmfh, sizeof(BITMAPFILEHEADER), &bytes_written, NULL);
43 al_fwrite(file, &bmfh, sizeof(BITMAPFILEHEADER));
44
45 WriteFile(fileHandle, &bmih, sizeof(BITMAPINFOHEADER), &bytes_written, NULL);
46 al_fwrite(file, &bmih, sizeof(BITMAPINFOHEADER));
47
48 WriteFile(fileHandle, (void*)dibvalues, bmih.biSizeImage, &bytes_written, NULL);
49 al_fwrite(file, (void*)dibvalues, bmih.biSizeImage);
50
51 al_fclose(file);
52 CloseHandle(fileHandle);
53
54 DeleteObject(SelectObject(hdc2,OldObj));
55 DeleteDC(hdc2);
56 ReleaseDC(hwnd, hdc1);
57}
|
William Labbett
Member #4,486
March 2004
|
komons said: ALLEGRO_FILE* file = al_fopen("aaa2.bmp","w"); tut tut tut use al_load_bitmap() to load bmp types. al_fopen() is for txt or binary data Isn't that right guys ?
|
J-Gamer
Member #12,491
January 2011
|
AFAIK it is. Use the structures/functions to do what they are supposed to do. Don't expect an ALLEGRO_FILE handler to open up an image file(which is supposed to be loaded into an ALLEGRO_BITMAP) correctly. " There are plenty of wonderful ideas in The Bible, but God isn't one of them." - Derezo |
Thomas Fjellstrom
Member #476
June 2000
|
You want to open your file with "wb" aka: binary mode, or windows will convert any and all \n characters it finds into \r\n sequences. Also, why not just convert the hdc/dib to an ALLEGRO_BITMAP and save using al_save_bitmap? -- |
William Labbett
Member #4,486
March 2004
|
...yeah, I suppose al_fopen will open anything but if you use it instead of al_load_bitmap you have to deal with the file format bmp before you can do anything with the file.
|
Thomas Fjellstrom
Member #476
June 2000
|
I think you guys are misunderstanding the problem. He's saving a file. not loading one. -- |
J-Gamer
Member #12,491
January 2011
|
oops... didn't take a good look at the line above it " There are plenty of wonderful ideas in The Bible, but God isn't one of them." - Derezo |
William Labbett
Member #4,486
March 2004
|
|
komons
Member #11,083
June 2009
|
Okay I changed to binary mode and it's just working. Now When I know that my saving bmp is correct, I changed it to saving in virtual file handle, so: 1ALLEGRO_FILE* file = al_create_file_handle( al_get_new_file_interface(), NULL );
2
3al_fwrite(file, &bmfh, sizeof(BITMAPFILEHEADER));
4al_fwrite(file, &bmih, sizeof(BITMAPINFOHEADER));
5al_fwrite(file, (void*)dibvalues, bmih.biSizeImage);
6
7al_fclose(file);
8
9ALLEGRO_BITMAP* ret = al_load_bitmap_f( file, ".bmp" );
It crashed at first run of al_fwrite, just out of program. Any error, any message. |
Thomas Fjellstrom
Member #476
June 2000
|
Try using al_fopen_interface instead of al_create_file_handle. al_create_file_handle doesn't actually open the file, so any file functions called on it will likely fail and/or crash. I'm not even sure why al_create_file_handle exists now, after the big file api reorganization. Now theres no way to open an unopened file handle, so its pretty useless. -- |
komons
Member #11,083
June 2009
|
al_fopen_interface open file on disc, so it useless for me. So if there isn't way for open unopened file handle, I'll save file on disc, and open it from disc. |
Audric
Member #907
January 2001
|
Out of curiosity, why do you do this ? Is it for a custom utility that needs to embed bitmaps in larger files ? |
Thomas Fjellstrom
Member #476
June 2000
|
Ignore what I wrote before. If you have implemented your file interface correctly, using al_create_file_handle and the al_f* functions should work just fine. You may want to take a look at your custom file interface, to make sure it works properly. -- |
Matthew Leverton
Supreme Loser
January 1999
|
Thomas Fjellstrom said: I'm not even sure why al_create_file_handle exists now, after the big file api reorganization. Now theres no way to open an unopened file handle, so its pretty useless. al_create_file_handle is part of the API change that made it so that you no longer have to have access to the internals to create your own interface. With it, the fi_open method is not used. It is meant only to be used with your own interface, typically wrapped within your own function that takes the place of al_fopen. For example, al_open_memfile uses al_create_file_handle. komons said: So if there isn't way for open unopened file handle Have you created your own interface? I suspect not. What you are doing will not work with the stdio functions. I think perhaps you are looking for the memfile addon. Create a memfile, write to it, and then load from it. |
Thomas Fjellstrom
Member #476
June 2000
|
Matthew Leverton said: al_create_file_handle is part of the API change that made it so that you no longer have to have access to the internals to create your own interface. With it, the fi_open method is not used. Yeah no. I wasn't reading the code correctly. Should your own interface be coded properly, all of the normal file functions should work fine. -- |
Matthew Leverton
Supreme Loser
January 1999
|
Thomas Fjellstrom said: Should your own interface be coded properly, all of the normal file functions should work fine. Except for al_fopen, but one shouldn't expect it to considering it doesn't take a file handle as a parameter (and therefore makes no sense given the context). The problem here is I think the OP using it with stdio and assuming some virtual, temporary file is created in the void. |
Thomas Fjellstrom
Member #476
June 2000
|
Matthew Leverton said: Except for al_fopen, but one shouldn't expect it to considering it doesn't take a file handle as a parameter (and therefore makes no sense given the context). The problem here is I think the OP using it with stdio and assuming some virtual, temporary file is created in the void. Quite. al_create_file_handle is a replacement for al_fopen. And yeah, he's probably not quite understanding how it works. -- |
|