Jump to content

Win32 GDI Programming, How To Display Bitmap From Memory Buffer?

- - - - -

  • Please log in to reply
4 replies to this topic

#1
RhetoricalRuvim

RhetoricalRuvim

    JavaScript Programmer

  • Members
  • PipPipPipPipPipPipPipPip
  • 1,254 posts
  • Location:C:\Countries\US
If I make a program so it loads a bitmap file into a memory buffer, what should I then do, if I don't want to use file I/O? (The reason for not using file I/O is that it's usually slower than memory.)

#2
LuthfiHakim

LuthfiHakim

    Programming God

  • Members
  • PipPipPipPipPipPipPip
  • 763 posts
Why do you need to use file I/O to display bitmap? All I know to display a bitmap (or any graphic for that matter), you can only do it from memory.

I assume that you are loading the bitmap files by using either CreateBitmap, CreateBitmapIndirect, CreateCompatibleBitmap, or CreateDIBitmap. To paint, you must associate the bitmap to a device context (you can use CreateCompatibleDC for this), then you can use that device context to draw the bitmap (to another device context, such as those associated with a window - using GetWindowDC or GetDC) using either BitBlt, MaskBlt, PatBlt, PlgBlt, or StretchBlt.

#3
RhetoricalRuvim

RhetoricalRuvim

    JavaScript Programmer

  • Members
  • PipPipPipPipPipPipPipPip
  • 1,254 posts
  • Location:C:\Countries\US
This is what I have:
bmpOut proc   ;; hdc:DWORD, pbuf:DWORD, x:DWORD, y:DWORD, w:DWORD, h:DWORD 

	enter 12 + 40, 0 

	pusha 

	pushfd 

	

	mov eax, dword ptr [ebp+12] 

	add eax, 14 

	mov ebx, eax 

	lea eax, [ebp-(12+40)] 

	mov ecx, 40 

	call MemoryCopy 

	mov ebx, eax 

	

	lea eax, [ebp-8] 

	

	push dword ptr 0 

	push dword ptr 0 

	push eax 

	push dword ptr DIB_RGB_COLORS 

	push ebx 

	push dword ptr 0   ;; hdc ? 

	call CreateDIBSection 

	cmp eax, ERROR_INVALID_PARAMETER 

	jz err_inv 

	cmp eax, 0 

	jz err_fxn 

	cmp eax, -1 

	jz err_fxn 

	mov dword ptr [ebp-4], eax 

	

	mov eax, dword ptr [ebp+12] 

	mov ebx, eax 

	mov eax, dword ptr [ebx+10] 

	neg eax 

	add eax, dword ptr [ebx+2] 

	mov ecx, eax 

	mov eax, dword ptr [ebx+10] 

	add ebx, eax 

	mov eax, dword ptr [ebp-8] 

	call MemoryCopy 

	

	push dword ptr [ebp+8] 

	call CreateCompatibleDC 

	mov dword ptr [ebp-12], eax 

	

	push dword ptr [ebp-4] 

	push eax 

	call SelectObject 

	mov dword ptr [ebp-16], eax 

	

	push dword ptr SRCCOPY 

	push dword ptr 0 

	push dword ptr 0 

	push dword ptr [ebp-12] 

	push dword ptr [ebp+28] 

	push dword ptr [ebp+24] 

	push dword ptr [ebp+20] 

	push dword ptr [ebp+16] 

	push dword ptr [ebp+8] 

	call BitBlt 

	

	push dword ptr [ebp-16] 

	push dword ptr [ebp-12] 

	call SelectObject 

	

	push dword ptr [ebp-12] 

	call DeleteDC 

	

	push dword ptr [ebp-4] 

	call DeleteObject 

	

	mov dword ptr [ebp-4], 0 

	

	jmp bmpOut_over1 

	

	err_inv: 

	

	err_fxn: 

	

	mov dword ptr [ebp-4], -1 

	

	bmpOut_over1: 

	

	popfd 

	popa 

	mov eax, dword ptr [ebp-4] 

	leave 

	ret 24 

bmpOut endp 


ifndef MemoryCopy 

	MemoryCopy proc 

		enter 0, 0 

		pusha 

		

		mov edx, ebx 

		mov ebx, eax 

		@@: 

			jecxz @F 

			mov al, byte ptr [edx] 

			mov byte ptr [ebx], al 

			dec ecx 

			inc ebx 

			inc edx 

			jmp @B 

		@@: 

		

		popa 

		leave 

		ret 

	MemoryCopy endp 

endif 


ifndef set_pointer 

	set_pointer proc 

		enter 0, 0 

		pusha 

		

		push dword ptr 0 

		push dword ptr 0 

		push dword ptr [ebp+12] 

		push dword ptr [ebp+8] 

		call SetFilePointer 

		

		popa 

		leave 

		ret 8 

	set_pointer endp 

endif 

I tested it and it worked; however, if there's anything wrong with it then you can tell me, so I could fix it.

I attached the code I used to test the bmpOut() function in the "gdi1.asm" file.

[ATTACH]3773[/ATTACH]

Attached Files



#4
RhetoricalRuvim

RhetoricalRuvim

    JavaScript Programmer

  • Members
  • PipPipPipPipPipPipPipPip
  • 1,254 posts
  • Location:C:\Countries\US
I just noticed something... The "enter 12 + 40, 0 " should actually be "enter 16 + 40, 0 ".

Here's the new code:
bmpOut proc   ;; hdc:DWORD, pbuf:DWORD, x:DWORD, y:DWORD, w:DWORD, h:DWORD 

	enter 16 + 40, 0 

	pusha 

	pushfd 

	

	mov eax, dword ptr [ebp+12] 

	add eax, 14 

	mov ebx, eax 

	lea eax, [ebp-(16+40)] 

	mov ecx, 40 

	call MemoryCopy 

	mov ebx, eax 

	

	lea eax, [ebp-8] 

	

	push dword ptr 0 

	push dword ptr 0 

	push eax 

	push dword ptr DIB_RGB_COLORS 

	push ebx 

	push dword ptr 0   ;; hdc ? 

	call CreateDIBSection 

	cmp eax, ERROR_INVALID_PARAMETER 

	jz err_inv 

	cmp eax, 0 

	jz err_fxn 

	cmp eax, -1 

	jz err_fxn 

	mov dword ptr [ebp-4], eax 

	

	mov eax, dword ptr [ebp+12] 

	mov ebx, eax 

	mov eax, dword ptr [ebx+10] 

	neg eax 

	add eax, dword ptr [ebx+2] 

	mov ecx, eax 

	mov eax, dword ptr [ebx+10] 

	add ebx, eax 

	mov eax, dword ptr [ebp-8] 

	call MemoryCopy 

	

	push dword ptr [ebp+8] 

	call CreateCompatibleDC 

	mov dword ptr [ebp-12], eax 

	

	push dword ptr [ebp-4] 

	push eax 

	call SelectObject 

	mov dword ptr [ebp-16], eax 

	

	push dword ptr SRCCOPY 

	push dword ptr 0 

	push dword ptr 0 

	push dword ptr [ebp-12] 

	push dword ptr [ebp+28] 

	push dword ptr [ebp+24] 

	push dword ptr [ebp+20] 

	push dword ptr [ebp+16] 

	push dword ptr [ebp+8] 

	call BitBlt 

	

	push dword ptr [ebp-16] 

	push dword ptr [ebp-12] 

	call SelectObject 

	

	push dword ptr [ebp-12] 

	call DeleteDC 

	

	push dword ptr [ebp-4] 

	call DeleteObject 

	

	mov dword ptr [ebp-4], 0 

	

	jmp bmpOut_over1 

	

	err_inv: 

	

	err_fxn: 

	

	mov dword ptr [ebp-4], -1 

	

	bmpOut_over1: 

	

	popfd 

	popa 

	mov eax, dword ptr [ebp-4] 

	leave 

	ret 24 

bmpOut endp 


#5
LuthfiHakim

LuthfiHakim

    Programming God

  • Members
  • PipPipPipPipPipPipPip
  • 763 posts
Sorry for late reply!

Congrats that you had figured it out. Unfortunately I am not that good with assembly programming. But from the API calls, I can tell that you have done things correctly (including the clean up). Just one suggestion, if you are painting to screen I think you don't have to do all setting up and cleaning up just for one time painting. You should store the bitmap after the setting up to use later. Just clean up when you find you don't need it anymore. This "caching" would save a lot of cpu cycles and speed up the whole process.




1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users