Finally finished my BMP data viewer and tested it: seems to work fine with all possible BMP formats. This program is the reason I posted about aligning data to 32-bit boundaries, since all BMP bitmap data must be aligned so.
Check it out. It displays all the data in the BMP header, shows the bitmap bits, and shows the palette for those files (4- and 8-bits per pixel) that have a palette. Plus a few more bits of info: the stride and bitmap padding, whether the file has alpha-channel data (32bpp files only), and the number of unique colors in the bitmap for paletted files.
Let me know of any problems, suggestions, etc. If you don't want to wait for all that data to scroll by, uncheck the "Show bitmap data" checkbox. The info displays in an edit control so you can copy the data from it.
Fixed version attached to reply #1 below.
Whoops, sorry: one of my buffers wasn't quite big enough, and when I tested it with a larger BMP ...
New version (that won't stall) attached.
(42c4.d08): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
*** WARNING: Unable to verify checksum for BMPinfo2.exe
eax=00000030 ebx=02bd0020 ecx=00000003 edx=00000001 esi=02cd0ffd edi=00cff000
eip=00262cac esp=00cfefc8 ebp=00cff0e8 iopl=0 nv up ei pl nz ac pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00210216
BMPinfo2!ShowBitmapData+0x2ff:
00262cac ad lods dword ptr [esi] ds:002b:02cd0ffd=????????
Bitmap is 1107x711x24bpp (2,363,418 bytes)
Your info
Info for file "Untitled.bmp":
BMP width: 1107
BMP height: 711
no. planes: 1
bits/pixel: 24
bitmap size: 2363364 bytes
compression: 0
horiz. res: 3778
vert. res: 3778
# colors used: 0
Bitmap stride: 3324 bytes
Bitmap padding: 3 byte(s)
--- BMP has no palette ---
With the checkbox checked, and while the text is scrolling, if any user interaction with the window - the program becomes unresponsive, cannot move or minimize the window, plus the dreaded 'busy' cursor pop up.
Also for larger 24 bit bitmaps, displayed bitmap size = 0. Which obviously is wrong.
For larger indexed images, program crashes.
I will run some more tests in a little while, and possibly attach any other bitmaps that cause wrong results. (Via PostImage) I have to test first if the posted image is exactly what I had uploaded (including the bitmap headers) Not sure if PostImage does any manipulation of the uploaded files, or not...
Later: It seems that PostImage converts the bitmap to .png image. :sad:
I'll try to zip it, if I can get it small enough to attach here.
Two (zipped seperately) images attached. "2.bmp" uses 24 bit color and displayed "bitmap size = 0", "4.bmp" uses 256 colors and the program crashes.
Buffer wasn't big enough
TheDialogProc PROC hWin:DWORD, uMsg:DWORD, wParam:DWORD, lParam:DWORD
local bmpfilesize:DWORD ;<<<added
;...
; Read bitmap header:
INVOKE CreateFile, ADDR fileOpenName, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL
MOV bmpFileHandle, EAX
invoke GetFileSize,eax,0 ;<<<added
mov bmpfilesize,eax ;<<<added
INVOKE HeapAlloc, HeapHandle, 0, eax ;<<<moved from above and changed
MOV FileBuffer, EAX ;<<<moved from above
INVOKE ReadFile, bmpFileHandle, FileBuffer, bmpfilesize, ADDR bytesRead, NULL ;<<<added bmpfilesize
BITMAPFILEHEADER partly wrong
bfOffBits DD ? ;Offset to bitmap data in file (from end of this structure)
;incorrect, it's the offset from the header start
It sure takes a long time to show the bitmap bits.
A slight speed up
;before you start writing the bitmap
invoke SendMessage,ResultsDispHandle,WM_SETREDRAW,0,0
;when you exit
invoke SendMessage,ResultsDispHandle,WM_SETREDRAW,1,0
invoke RedrawWindow,ResultsDispHandle,0,0,RDW_ERASE or RDW_FRAME or RDW_INVALIDATE or RDW_ALLCHILDREN
Hi
This is a good idea, sinsi!
During this time you can also set the cursor to IDC_WAIT (https://learn.microsoft.com/en-us/windows/win32/menurc/about-cursors#:~:text=Text%20select-,IDC_WAIT,-MAKEINTRESOURCE(32514)).
Alternatively, a spinner would be a nice addition.
Biterider
Thanks for all comments so far.
Yes, I realized there was a massive problem with how long things took for really large BMPs (as well as another buffer not large enough). Which has prompted me to revamp how I display all that bitmap info.
Currently I'm just writing all that text to the edit control directly. Now, even though I bigger-ized the edit control's text buffer (by using the
EM_SETLIMITTEXT message), if you watch the program's progress with Task Manager you'll see a slowly but surely increasing memory usage as the edit control tries to cope with all that incoming text. Not a good arrangement (which is also why the program becomes unresponsive).
So what I'm going to do instead is write all that text to a buffer, then at the end dump it into the edit control all at once. That should solve all these problems.
Quote from: zedd151 on November 22, 2024, 03:36:30 AMAlso for larger 24 bit bitmaps, displayed bitmap size = 0. Which obviously is wrong.
Actually, no, that's correct: I'm reading the bitmap size from the BMP header, which can set that field to zero. I think that field is only used by compressed BMPs (which I don't handle).
I'll have an updated version soon. Thanks for being my guinea pigs!
Quote from: NoCforMe on November 22, 2024, 06:51:47 AMQuote from: zedd151 on November 22, 2024, 03:36:30 AMAlso for larger 24 bit bitmaps, displayed bitmap size = 0. Which obviously is wrong.
Actually, no, that's correct: I'm reading the bitmap size from the BMP header, which can set that field to zero.
It seems wrong though, or at least misleading. Maybe you should use "Header bitmap size" for size that was read from the header, and a separate listing "Actual bitmap size" displaying the actual size of the bitmap. This would help to avoid any confusion.
OK, latest version here.
I've pretty much fixed the unresponsiveness problem. Pretty much, but not completely: using a really big BMP (1.8MB), it goes catatonic for maybe 8-10 seconds. Not perfect but better.
Not sure what I could do to remedy this. One thing I do is to display a "wait" message in the edit control, so at least the user has some clue as to what's going on. But I really don't like that "freezing" ...
Larry: could you test this again with that file that showed a bitmap size of 0? I added code to show the actual size in that case.
Thanks to everyone for their patience! I'm trying to get the code monkeys here at NoCforMe Laboratories, GmbH, to be a bit more careful in releasing code ...
QuoteFile is too big (> 2MB).
Really? Why don't you dynamically allocate memory? 2MB is on the small size for an uncompressed BMP.
Quote from: NoCforMe on November 22, 2024, 07:49:16 AMLarry: could you test this again with that file that showed a bitmap size of 0? I added code to show the actual size in that case.
Program says: "File is too big (> 2 MB)".
It is a 5.93 MB size file. :dazzled: You never know just how big a user will use the program on.
For the 256 color version of the same bitmap, the report window says... "Wait..." and I am still waiting. :tongue: It does show a miniature of the file, though.
edited later --> It
did finish and display after
quite some time.
Both of those files are attached above (the zips in post #3), for your own testing... :smiley: error correction: I orignally wrote post #8, its in post #3
OK, dynamic memory allocation it is. I told those damned code monkeys they needed to do this, but they thought I was being silly.
Give me a couple hours here.
One basic question, though, before I start revamping this code:
Do you think anyone's actually going to use all this bitmap data?
I'd hate to get this working all nice and perfect but to no practical use.
(The displayed text will be larger than the BMP file)
Quote from: NoCforMe on November 22, 2024, 08:09:18 AMOne basic question, though, before I start revamping this code:
Do you think anyone's actually going to use all this bitmap data?
I'd hate to get this working all nice and perfect but to no practical use.
(The displayed text will be larger than the BMP file)
Personally, I would use a hex editor myself. But you never know about anyone else.
Speaking of hex editors, I had played around a bit with trying to write one years ago. The trick to that is to not try to display all the data at one time, but only portions of it from a small buffer... if I can find that half finished code, I might post it some day. Later: I looked for it, but did not find it.
Quote from: zedd151 on November 22, 2024, 08:10:32 AMQuote from: NoCforMe on November 22, 2024, 08:09:18 AMOne basic question, though, before I start revamping this code:
Do you think anyone's actually going to use all this bitmap data?
I'd hate to get this working all nice and perfect but to no practical use.
(The displayed text will be larger than the BMP file)
Personally, I would use a hex editor myself. But you never know about anyone else.
Sure, one could use a hex editor. But you'd have to work out where the BMP header ended, where the palette data was, where the bitmap data started, all that. The motivation for this was to display all that data without having to wade through the hex dump.
Maybe this tool could/should use a hex-dump format in displaying the palette and bitmap data? Maybe even allow editing? Ugh; lotsa lotsa work there.
No, I think I'll stick to read-only for this version at least. If you're going to edit a BMP, then use a graphics editor (like Paint Shop Pro here), not a stupid hex editor.
Anyhow, I'm open to suggestions.
Quote from: NoCforMe on November 22, 2024, 08:15:37 AMIf you're going to edit a BMP, then use a graphics editor (like Paint Shop Pro here), not a stupid hex editor.
Well thats all I could think of, to see the bitmap data. :tongue: Carry on.
I tend to write this sort of program to work out the structure of things (like here, trying to figure out the bitmap format). Sometimes MSDN can be a bit cryptic to a non-C programmer.
For example, one of the bitmaps I tried with this program had horiz. res and vert. res set to 0, which puzzled me until I looked at the header and saw that it is measuring pixels per metre. No idea why you would want that measurement :badgrin:
Progress: dynamic memory allocation implemented, like it shoulda been done from the get-go.
But as always, 2 steps forward, 1 step back: now there's a fault on exit, hard to debug since it ends up somewhere in ntdll territory.
Also, the suspended wait is just too long for large BMPs. Seems like the only solution is to put all that computation into a separate thread. Next up.
The compute-intensive code now runs in a worker thread, which I would have thought would solve the nonresponsiveness issue, but it hasn't. Still, this version is an improvement. Seems pretty bulletproof.
I took all the code that takes a long time to execute (displaying the palette and especially the bitmap data) and put it in a separate subroutine. I then start it thus:
;========================================
; Start worker thread to crunch BMP data:
;========================================
INVOKE CreateThread, OFFSET ThreadSecAttr, 0, OFFSET ProcessBitmapData,
NULL, 0, NULL
The thread routine ends so:
; Free buffers:
INVOKE HeapFree, HeapHandle, 0, FileBuffer
INVOKE HeapFree, HeapHandle, 0, TextBuffer
INVOKE ExitThread, 0
RET
So when you run this, you can still move the dialog window around while it's crunching away. However, you shortly get the "busy" cursor and the title says "not responding". I thought that having code execute in a separate thread would fix this; why didn't it? Nothing in the main program is waiting on the threaded subroutine to complete.
Something else I don't understand--the Micro$oft documentation for
CreateThread() says
QuoteThe thread object remains in the system until the thread has terminated and all handles to it have been closed through a call to CloseHandle.
So
CreateThread() returns a handle: what am I supposed to do with it? I could close it right after the call to this function, but wouldn't that mess up the thread which is (or may be) still executing? Or should I store the handle and close it later? But when?
I guess I still have a few things to learn about Windows threads.
It does run much faster than the original version. :thumbsup:
BMP width: 2002
BMP height: 1505
no. planes: 1
bits/pixel: 8
bitmap size: 3016020 bytes
Still takes ages and the dialog is unresponsive.
379766016: 00 00 00 00 00 49 49 51 51 51 51 51 51 51 51 51
BMP size = 3,016,020
info size = 379,766,016
Hmmm...
What do you mean, "info size = 379,766,016"?
The file you posted is about 9MB, which is about right; typically the text output is ~3X the size of the BMP.
There was one glaring error in the memory addresses of each line of pixels which I just fixed, but that only affects the number shown before each line. (Take a look at the output, it'll jump out atcha.)
Yeah, it's slow.
So about the thread: do I need to mess around with WaitForMultipleObjects() or WaitForSingleObject() or some such to make the program responsive while that thread is executing? I'm definitely not an expert on using threads. (I like to wear natty ones, though.)
Oh,, and another thing: looking at Task Manager while this thing's grinding away, I see memory usage steadily climbing, which I don't understand at all, because I'm not allocating any memory inside that code. So what the hell is going on there? I'm not even calling any Win32 functions there, not doing anything with any controls (like the edit control): I'm just stuffing text into a buffer.
I am using wsprintf(): could that be hogging all that memory?
No, because I'm only using that for 32bpp images.
Quote from: NoCforMe on November 22, 2024, 05:17:56 PMWhat do you mean, "info size = 379,766,016"?
Quote from: sinsi379766016: 00 00 00 00 00 49 49 51 51 51 51 51 51 51 51 51
Quote from: NoCforMe on November 22, 2024, 05:17:56 PMThere was one glaring error in the memory addresses of each line of pixels which I just fixed, but that only affects the number shown before each line. (Take a look at the output, it'll jump out atcha.)
But not atchoo :biggrin:
You might want to sync the thread, if someone loads another bitmap before the thread is finished you might get some interesting things happening...
You should read in filesize first and allocate memory according to that and free memory after finished
For hex editing bmp and other files,there are already qeditor binary load/save functions
I used this binary load bmp after creating and saving 'empty' bmp with paint,just to copy and paste bmp file headers into my programs that "draws" isometic 3d and saves as bmp witt same size and bitness as previous empty bmp
with lots of optimizers here that can help you
New version attached.
I've eliminated all wsprintf()s at least from the most compute-intensive code (the pixel-displaying stuff); I'm doing all the number conversions (decimal & hex) by myself, so it's a wee bit faster. Still sloooow on large BMPs. I don't see much room for improvement in my code.
Also corrected the address display for lines of pixels.
But there are still (at least) two things that bother me:
1. I still see memory usage slowly but steadily climbing while this runs, and I can't figure out why. I am doing absolutely no memory allocation in the pixel-display code, nor am I using any Win32 functions; it's all just code working with variables.
I wonder: if you allocate a large buffer using HeapAlloc(), is it possible that as you use more and more of the buffer, the OS is actually doing some kind of incremental allocation? I always thought that if you allocate, say, 8 MB of memory that you're given an 8 MB chunk in one fell swoop. But maybe it doesn't work that way: maybe that 8 MB is only marked out as being allocated, but as you use more and more of the buffer (by making memory references to it), it is physically allocated by page faults. I don't know enough about the innards of Windows to answer this, but it would explain the steadily increasing memory usage I'm seeing. (Calling Raymond Chen!)
2. Still don't know why the program goes non-responsive while cranking through all that data, since that code is in a separate thread now. Apparently that's not sufficient to prevent the compute-intensive code from bogging down the rest of the program. The program uses a dialog as the main window; maybe the dialog manager doesn't play well with my thread?
If anyone knows anything about either of these two things, could you reply and post what you know here? It would be much appreciated.
As it is, this is still a useful tool. And maybe that long wait is deserved: after all, anyone who makes that large a BMP is just asking for trouble ...
Quote from: NoCforMe on November 23, 2024, 10:21:06 AMIf anyone knows anything about either of these two things, could you reply and post what you know here? It would be much appreciated.
Can't do a comment on those 2 things, because the program crashes - feeding it with a very simple 16bpp bitmap (attached). I'm using WinXP 32bit, in a VM under Linux, though. Seems the crash is due to "TextBuffer" being too small...
It is a lot faster, but still not responsive.
_japheth found a BMP that's in a format rarely seen nowadays (though perfectly valid) - 16 bits per pixel, which your code doesn't allow for.
Thanks, @_japheth: I should have that format (16bpp) handled by tomorrow.
Any clue on the non-responsiveness? I'm really starting to think that this might have something to do with the dialog manager. I was considering using IsDialogMessage(), but since I don't have a message loop that won't do much good.
Quote from: NoCforMe on November 23, 2024, 07:54:26 PMI'm really starting to think that this might have something to do with the dialog manager. I was considering using IsDialogMessage(), but since I don't have a message loop that won't do much good.
Have you thought about foregoing the dialog box and using either a Window, or even writing to stdout, in a console version? - At least for only the bitmap data...
I would isolate only the bitmap processing functions (you would still have to calculate where the bitmap data starts, of course - for the different flavors of bitmaps), omitting the header info display, and the mini bitmap display, to concentrate solely on making the bitmap data processing faster (use some form of timing mechanism, to verify just how much faster one algorithm is, versus another)
You already know that your bitmap headers info processing, and miniature bitmap processing works okay.
After you get that as fast as possible, then you can finish up the GUI code. :smiley: that's my tip/suggestion of the day.
## UPDATED ##
I made a little test program of my own. It simply opens a pre-defined bitmap file (included), processes the bitmap bytes, writes the data to a file then exits. It is very fast, your mileage may vary. There is a huge 24 bit bitmap file 5MB+ used for testing the program included in the zip file.
This code is only for proof of concept, and useless otherwise. :tongue: meaning, I don't want to hear anything about possible flaws/bugs in it. :biggrin: just kiddin'.
stride and header size are hard coded for this test, and a table for byte to string conversion is used for speediness.
The code has been revised a bit...
Now formatted for 8 RGB sequences per line, and is finished!
a few changes made...
I inserted some code at the start of ProcessBitmapData which just wrote a char to the edit window in an endless loop to simulate a busy thread and found the window was responsive :shrug:
Quote from: _japheth on November 23, 2024, 06:51:34 PMQuote from: NoCforMe on November 23, 2024, 10:21:06 AMIf anyone knows anything about either of these two things, could you reply and post what you know here? It would be much appreciated.
Can't do a comment on those 2 things, because the program crashes - feeding it with a very simple 16bpp bitmap (attached). I'm using WinXP 32bit, in a VM under Linux, though. Seems the crash is due to "TextBuffer" being too small...
Crash was due to the program being totally confused by 16bpp images. That has been added and it now works with them. New version attached here. Could you give it a whirl to check it? Thanks.
BTW, that BMP you used was originally generated by my BMPfromText program, but it's been modified. Did you use my program to create it? That program creates 32bpp BMPs, but yours somehow got converted to 16bpp: what did you use to do that? I don't think I have anything here that's capable of doing that; Paint Shop Pro only creates 24bpp BMPs.
There's another little wrinkle here: your 16bpp file has 65,536 in the "colors used" field (the
biClrUsed member of the
BITMAPINFOHEADER structure). Micro$oft has this to say about that member (https://learn.microsoft.com/en-us/windows/win32/gdi/bitmap-header-types):
QuoteBitmaps that are 16-, 24-, or 32-bpp do not require color tables, but may have them to specify colors for palettized devices. If a color table is present for 16-, 24-, or 32-bpp bitmap, the biClrUsed member specifies the size of the color table and the color table must have that many colors in it. If biClrUsed is zero, there is no color table.
Except that in the case of the file you attached, this member is
not zero, and yet there is no "color table" (palette). ????? So in my code I'm just ignoring this field not being zero and assuming there's no palette in 16bpp BMPs.
Anyone know more about this?
Quote from: sinsi on November 24, 2024, 08:25:58 AMI inserted some code at the start of ProcessBitmapData which just wrote a char to the edit window in an endless loop to simulate a busy thread and found the window was responsive :shrug:
Interesting, and I'm sure that means something.
However, if you run it and it goes unresponsive, you can't select text in the edit window (with the mouse), which you should be able to do. So apparently it's responsive "from the inside" (i.e., from code that writes to the window) but not from "outside" (user interaction). ?????
Help! I need someone who knows a lot about Win32 threads to shed some light on this situation.
Quote from: zedd151 on November 24, 2024, 01:15:32 AMHave you thought about foregoing the dialog box and using either a Window, or even writing to stdout, in a console version? - At least for only the bitmap data...
I ended up converting the whole program to one that uses a main window instead of using a dialog as a main window.
It still goes unresponsive. So apparently the dialog manager isn't the source of this problem.
BTW, do you realize what a
pain in the ass it is to do this? Create a main-window app vs. a dialog-based one? With a dialog, you have a nice dialog editor to place all your controls in the dialog (I use my homemade one that creates dialog memory templates instead of a resource editor, but same difference). With a main window you have to figure the X-position, Y-position, width & height of each and every thing in the dialog. By hand. (WinSpy actually helps a lot here, as you can use it to move things around on screen until they look right, but you still have to do a lot of dicking around.)
You also don't get the nice dialog manager touches like applying a decent-looking font to everything in the dialog: you've got to obtain a font handle and then use
WM_SETFONT to apply that font to each and every control that contains text. Otherwise they use the default font which looks like shit.
Then there's the whole thing of colors; ugh. Even if you select a plain white background, which works for
some controls, it doesn't work for others, f'rinstance checkboxes which come with a default gray background. Oh, sure, you can play games with
WM_CTLCOLORBTN to set the background to your liking, but that's even more work.
Now I realize why all my programs for the last couple years have been dialog-based ones.
Quote from: NoCforMe on November 24, 2024, 11:04:38 AMCrash was due to the program being totally confused by 16bpp images. That has been added and it now works with them. New version attached here. Could you give it a whirl to check it? Thanks.
Thanks, will do ASAP.
QuoteBTW, that BMP you used was originally generated by my BMPfromText program, but it's been modified. Did you use my program to create it? That program creates 32bpp BMPs, but yours somehow got converted to 16bpp: what did you use to do that?
I can't remember doing anything with it. Perhaps it's just because the Windows XP display driver in the VM is setup to a 1280x1024x16 resolution?
Quote from: _japheth on November 24, 2024, 02:07:14 PMQuote from: NoCforMe on November 24, 2024, 11:04:38 AMBTW, that BMP you used was originally generated by my BMPfromText program, but it's been modified. Did you use my program to create it? That program creates 32bpp BMPs, but yours somehow got converted to 16bpp: what did you use to do that?
I can't remember doing anything with it. Perhaps it's just because the Windows XP display driver in the VM is setup to a 1280x1024x16 resolution?
I don't see how that would result in the file being rewritten in a different format.
You must have done something to make it into a 16bpp BMP. (Which seems to be quite the oddball format, BTW.)
Anyhow.
So you're really running with a 16-color display? Must be pretty ugly, eh?
Ok, 16bpp bitmaps work now flawlessly.
Quote from: NoCforMe on November 24, 2024, 02:15:54 PMI don't see how that would result in the file being rewritten in a different format.
You must have done something to make it into a 16bpp BMP. (Which seems to be quite the oddball format, BTW.)
Strange, since there's not much installed on that VM, not even PSP - so it must have been good old MS Paint...
Quote from: NoCforMe on November 24, 2024, 02:15:54 PMSo you're really running with a 16-color display? Must be pretty ugly, eh?
IMO, the difference isn't that obvious - might be an issue for certain kinds of movies, though ... :biggrin:
Quote from: _japheth on November 24, 2024, 02:43:56 PMQuote from: NoCforMe on November 24, 2024, 02:15:54 PMI don't see how that would result in the file being rewritten in a different format.
You must have done something to make it into a 16bpp BMP. (Which seems to be quite the oddball format, BTW.)
Strange, since there's not much installed on that VM, not even PSP - so it must have been good old MS Paint...
Odd; I just loaded that BMP in Paint, then went to save it:
The only options for BMP formats are monochrome (1bpp), 16 color (4bpp), 256 color (8bpp) and 24-bit (16 million+ colors). No 16bpp option.
It's a mystery ...
The GIMP can save in 16 bit format. 5 bits red, 6 bits green, 5 bits blue, iirc.
A few minutes and 200+ MB later... I just reinstalled the GIMP.
Yup, I just checked. R5 G6 B5 is one of the options for 16bpp.
I am certain there is other software that can also save in that format.
Quote from: zedd151 on November 24, 2024, 03:44:29 PMR5 G6 B5
I was wondering how you'd encode 3 colors in 16 bits.
Funky format.
There also used to be 15bpp (5,5,5 plus a spare), this goes back to the early days of win 3 and the emergence of VESA.
Quote from: NoCforMe on November 24, 2024, 04:38:58 PMFunky format.
From back in the days of needing to reduce memory/disk space I would imagine. Unless 24 bit was not yet 'a thing'?
Anyway, I have updated my little test proggie in reply #31, if anyone is interested.
I think the extra bit for green is because the human eye is most sensitive to this color (505 nm).
Quote from: zedd151 on November 24, 2024, 05:18:43 PMAnyway, I have updated my little test proggie in reply #31, if anyone is interested.
I tried it. It faults (on
PUSH ESI). ???
Quote from: NoCforMe on November 24, 2024, 05:57:38 PMQuote from: zedd151 on November 24, 2024, 05:18:43 PMAnyway, I have updated my little test proggie in reply #31, if anyone is interested.
I tried it. It faults (on PUSH ESI). ???
Exactly where? I see no issues, even running in debugger, stepping in every instance where esi is pushed to the stack. No such errors here. :undecided: Maybe I'll have to fire up windows 7 to see if any difference, than when run on win 10.
Anyway, I added a check for whether the bitmap (2.bmp) is present. If not present, the program simply exits.
Worked with Windows 7 x64
OK, I just learned something important.
That loooong delay where my program goes into a catatonic state? That's not my code.
My code is pretty fast.
The delay is the time it takes to dump the text in my buffer to the edit control!
Yikes.
I proved this by displaying "done" in the edit control when my pixel-displaying code is finished. The long wait happens after that. While that operation is going on, Windows goes into a coma.
So now, questions (to self):
I could display the text myself in a window using GDI text functions, which would surely be faster than waiting on the edit control to churn through all that text.
However, that would defeat the purpose of having the edit control in the first place, which is to make the text selectable in case the user wants to copy any of it.
Maybe copying the text from my buffer into the edit control in smaller chunks would be faster? I'll try that.
So what do y'all think I should do? Is it important that the text be selectable? Another option would be to write the text to a file, which I'm sure would also be faster than waiting on the edit control to fill up.
Copying the buffer to the edit control in small chunks only makes it more painful, so scratch that.
I tried hiding the window, hoping that would speed things up by not actually displaying anything:
INVOKE ShowWindow, ResultsDispHandle, SW_HIDE
but for some reason that didn't work at all.
Quote from: NoCforMe on November 25, 2024, 07:39:12 AMAnother option would be to write the text to a file, which I'm sure would also be faster than waiting on the edit control to fill up.
I just tested a 15 MB file, opening with both notepad and qeditor. Both of them open the file very quickly. i.e., dont blink or you will miss it. How about first writing the data to a file, then load it into your edit window using a rich edit contol and 'stream' the data in.
From masm32 example 'riched'
ofCallBack proc dwCookie:DWORD,pbBuff:DWORD,cb:DWORD,pcb:DWORD
invoke ReadFile,dwCookie,pbBuff,cb,pcb,NULL
mov eax, 0
ret
ofCallBack endp
StreamFileIn proc hEdit:DWORD,lpszFileName:DWORD
LOCAL hFile :DWORD
LOCAL fSiz :DWORD
LOCAL ofs :OFSTRUCT
LOCAL est :EDITSTREAM
LOCAL buffer[32]:BYTE
LOCAL aval[8]:BYTE
invoke OpenFile,lpszFileName,ADDR ofs,OF_READ
mov hFile, eax
mov est.dwCookie, eax
mov est.dwError, 0
mov eax, offset ofCallBack
mov est.pfnCallback, eax
invoke SendMessage,hEdit,EM_STREAMIN,SF_TEXT,ADDR est
invoke GetFileSize,hFile,NULL
mov fSiz, eax
invoke CloseHandle,hFile
szText OpenMsg,"Opened at "
szText OpenByt," bytes"
mov buffer[0], 0
invoke szCatStr,ADDR buffer,ADDR OpenMsg
invoke dwtoa,fSiz,ADDR aval
invoke szCatStr,ADDR buffer,ADDR aval
invoke szCatStr,ADDR buffer,ADDR OpenByt
invoke SendMessage,hStatus,SB_SETTEXT,3,ADDR buffer
invoke SendMessage,hEdit,EM_SETMODIFY,0,0
mov eax, 0
ret
StreamFileIn endp
Orrr... just use a rich edit control and try the other way... rather than a text box.
Quote from: zedd151 on November 25, 2024, 08:40:36 AMHow about first writing the data to a file, then load it into your edit window using a rich edit contol and 'stream' the data in.
The first part of that makes absolutely no sense: writing to a file has got to be a lot slower than storing the text in a buffer, which is what I'm already doing.
However, the second part of your suggestion might work: basically substituting a RichEdit control for the lowly edit control. Will try that.
Quote from: NoCforMe on November 25, 2024, 08:56:34 AMThe first part of that makes absolutely no sense: writing to a file has got to be a lot slower than storing the text in a buffer, which is what I'm already doing.
My tests have shown that it can be very fast indeed to write to a file. But...
QuoteHowever, the second part of your suggestion might work: basically substituting a RichEdit control for the lowly edit control. Will try that.
Should be noticeably faster. Perhaps even
much faster... than the simple edit control.
Quote from: zedd151 on November 25, 2024, 09:00:11 AMQuote from: NoCforMe on November 25, 2024, 08:56:34 AMThe first part of that makes absolutely no sense: writing to a file has got to be a lot slower than storing the text in a buffer, which is what I'm already doing.
My tests have shown that it can be very fast indeed to write to a file. But...
Yes, but it can't possibly be as fast as writing to a memory buffer, since it involves transfer to a physical device.
Quote from: NoCforMe on November 25, 2024, 08:56:34 AMwriting to a file has got to be a lot slower than storing the text in a buffer
There is not much of a difference because you don't really
write to a file; you just hand over the content to the OS, which transfers it physically to a drive whenever it finds the time to do so.
Quote from: jj2007 on November 25, 2024, 09:13:12 AMQuote from: NoCforMe on November 25, 2024, 08:56:34 AMwriting to a file has got to be a lot slower than storing the text in a buffer
There is not much of a difference because you don't really write to a file; you just hand over the content to the OS, which transfers it physically to a drive whenever it finds the time to do so.
OK. Makes sense since the call to
WriteFile() returns before the data is actually written to disk.
So what can you tell us about the relative speeds of writing text to a RichEdit control vs. an ordinary edit control, because you're probably the resident expert on things RichEdit?
Quote from: NoCforMe on November 25, 2024, 09:16:11 AMrelative speeds of writing text to a RichEdit control vs. an ordinary edit control
No idea, I've never tested that. All I can tell you is that streaming in plain text is fast but rtf can be slow if it's in the megabyte range.
Question: is it really faster, with a RichEdit control, to use EM_STREAMIN vs. just setting the text all at once from a buffer, using SetWindowText()? I don't see the advantage of sending the text in pieces if it's all in one buffer to start with, which is the case here.
And this is plain text, not RTF.
I suppose I should just shut up and try it ...
Quote from: NoCforMe on November 25, 2024, 09:32:19 AMQuestion: is it really faster, with a RichEdit control, to use EM_STREAMIN vs. just setting the text all at once from a buffer, using SetWindowText()? I don't see the advantage of sending the text in pieces if it's all
No, you dont use EM_STREAMIN to set the text in rich edit control (I have never seen it used that way, or know if that is even possible),
WM_SETTEXT works fine. That suggestion was for if you were to write to file first.
Well, that's all moot now because guess what?
RichEdit is waaaaaay faster!
(I'm using SetWindowText(), same difference as WM_SETTEXT.)
Check out attached .exe (I'm cleaning up code and will post that later).
So much faster! So JJ, now we know. (No timings, but I could do that if anyone's interested.)
Now it's a real usable tool.
Quote from: NoCforMe on November 25, 2024, 10:07:30 AMRichEdit is waaaaaay faster!.
:azn:
We all knew that your code itself was not the issue. Glad you have it all sorted. :thumbsup:
Another question, @JJ, since you've spent so much time wrestling with the RichEdit version problem:
I'm using RichEdit20A. Am I safe in assuming that most users will have that DLL installed on their systems?
Just as a matter of interest I got rid of the buffer and wrote directly to the edit control and the window was responsive.
The new program is certainly faster for a 2002x1505x24bpp bmp (9,042,040 bytes).
Couldn't handle a 10000x10000x24bpp (300,000,054 bytes) bmp file though :badgrin:
Quote from: NoCforMe on November 25, 2024, 10:15:50 AMI'm using RichEdit20A. Am I safe in assuming that most users will have that DLL installed on their systems?
I am not jj of couse, but I can answer that...
Yes, it should be fine to use. It has been around since the Windows xp days. It has its own issues though, as do the later versions of RichEdit.
I just tested a 23.7 MB bmp file with your program. Fast enough indeed now.
BMP width: 3840
BMP height: 2160
no. planes: 1
bits/pixel: 24
bitmap size: 24883200 bytes
compression: 0
horiz. res: 3780
vert. res: 3780
# colors used: 0
Bitmap stride: 11520 bytes
Bitmap padding: 0 byte(s)
BMP header size: 40 bytes
later: this one took several seconds to load. But fast enough for the bmp's size (155MB). :thumbsup:
BMP width: 9600
BMP height: 5400
no. planes: 1
bits/pixel: 24
bitmap size: 155520000 bytes
compression: 0
horiz. res: 3780
vert. res: 3780
# colors used: 0
Bitmap stride: 28800 bytes
Bitmap padding: 0 byte(s)
BMP header size: 40 bytes
Quote from: sinsi on November 25, 2024, 10:19:45 AMThe new program is certainly faster for a 2002x1505x24bpp bmp (9,042,040 bytes).
Couldn't handle a 10000x10000x24bpp (300,000,054 bytes) bmp file though :badgrin:
So what happened, pray tell? Crash? Hang? Something else?
Where the bloody hell did you get a BMP file like that?
Maybe I should look at the file size, and if it's above some reasonable limit issue an error message like "What, are you nuts?".
Good ol' Windows, just crashes instead of popping up any sort of error :rolleyes:
(fd4.4230): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
*** WARNING: Unable to verify checksum for e:\Desktop\BMPinfo2.exe
eax=0000001c ebx=0019f960 ecx=0000001c edx=0000001c esi=0019f440 edi=00000000
eip=00401fa9 esp=0019f434 ebp=0019f878 iopl=0 nv up ei pl zr na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00210246
BMPinfo2+0x1fa9:
00401fa9 f3a4 rep movs byte ptr es:[edi],byte ptr [esi]
Quote from: NoCforMe on November 25, 2024, 10:38:17 AMWhere the bloody hell did you get a BMP file like that?
Start Paint, change the image properties, save as BMP
Quote from: NoCforMe on November 25, 2024, 10:38:17 AMMaybe I should look at the file size, and if it's above some reasonable limit issue an error message like "What, are you nuts?".
Some images from Hubble that you can download are pretty massive. Granted they are compressed PNGs but still can be 90MB or so...
Attached is what is probably going to be the last version of this utility.
So @sinsi: I created a humongous BMP to test this, 10,000 X 10,000.
It works. And it doesn't work.
It works in that my code manages to slog through each and every pixel of that file.
But when it comes time to actually display the data (when it's dumping the text to the RichEdit control), it just sits there. Doesn't hang; the UI is responsive. But it just never fills the control. I've let it sit for 10 minutes and no go.
So I'm basically giving up on that. Here's the thing: who the hell is going to actually use this to display data from a file that big?
Yes, as you point out, huge image files do exist. For one thing, I highly doubt that any of those files will be in BMP format nowadays; more likely JPEG, or perhaps PNG, maybe even TIFF.
Besides, I have to ask: what, really, is the use of this program? I ended up using it to create that huge BMP: I took a 100x100 image and used it as a "stamp" to fill up the big file, 10,000 times. Other than that even I haven't really used it. I wrote it kind of as a challenge more than anything.
The text file generated by this BMP is about 720 megabytes (!!). You can't even load a file that big into Notepad. I was able to load it into my EdAsm editor which uses a RichEdit contol (although it reported the size as something over 600 MB), but even it struggled to display it: it would show only so much, then if you scrolled down it would show a little bit more, etc., etc. So entirely impractical to even view this data. (I tested this by writing the text data to a file instead of to the RichEdit control.)
Anyhow, it was fun while it lasted. Now on to the next obsession ...
perhaps better to ask user for big files and not waste their time for junk ?
There is enough detailed moon data + moonlander 3d model to create photorealistic moonlander game instead of good old Atari game
Quote from: TimoVJL on December 04, 2024, 11:31:36 PMperhaps better to ask user for big files and not waste their time for junk ?
That might not be such a bad idea.
Quote from: NoCforMe on November 22, 2024, 08:09:18 AMOne basic question, though, before I start revamping this code:
Do you think anyone's actually going to use all this bitmap data?
I'd hate to get this working all nice and perfect but to no practical use.
If you really want to do something useful, make analogue of PEview for bmp.
Quote from: Villuy on February 04, 2025, 03:23:38 AMIf you really want to do something useful, make analogue of PEview for bmp.
You mean BMPview just for file internal structures ?
In my weak moments i did something like that for PEView :biggrin:
Quote from: Villuy on February 04, 2025, 03:23:38 AMQuote from: NoCforMe on November 22, 2024, 08:09:18 AMOne basic question, though, before I start revamping this code:
Do you think anyone's actually going to use all this bitmap data?
I'd hate to get this working all nice and perfect but to no practical use.
If you really want to do something useful, make analogue of PEview for bmp.
Welll, it
is kind of an analog of PEview as it is, dontcha think?
I mean, it shows the internal data structures of a BMP file.
There really isn't anything more to show than what I'm displaying.
There's the header, the palette if there is one, and then the bitmap data itself.
That's pretty much it.
Unless you can think of something I missed ...