ALLEGRO_FILE bug?
komons

Hi, I save bmp file by two ways. First: windows handle method, Second: ALLEGRO_FILE, and there are some differences. Why?

Windows handle:
{"name":"122.png","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/3\/9\/394edc1e2178f0ba867142a3ed969b06.png","w":1440,"h":900,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/3\/9\/394edc1e2178f0ba867142a3ed969b06"}122.png

ALLEGRO_FILE:
{"name":"123.png","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/e\/9\/e90ea36612f6db405cdf6312b19faa19.png","w":1440,"h":900,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/e\/9\/e90ea36612f6db405cdf6312b19faa19"}123.png

Why ALLEGRO_FILE method saved crap file?

code:

#SelectExpand
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
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

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.

Thomas Fjellstrom

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

...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

I think you guys are misunderstanding the problem. He's saving a file. not loading one.

J-Gamer

oops... didn't take a good look at the line above it :-X

William Labbett

:-/

komons

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:

#SelectExpand
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

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

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. :P

Audric

Out of curiosity, why do you do this ? Is it for a custom utility that needs to embed bitmaps in larger files ?

Thomas Fjellstrom

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

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

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

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

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.

Thread #607405. Printed from Allegro.cc