News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

looking for bitmap split algo

Started by ramguru, August 09, 2007, 08:17:44 AM

Previous topic - Next topic

ramguru

I'm desperately in need of someone's help  :'(
Yesterday I was working on routine that can split given bitmap to a number of smaller ones. You know for skinning purpose, you have like up/down/middle state of button in one file. In my case there would be 16 separate bitmap files, if grouping wasn't used. You may also remember ImageList_.. that does exactly the same thing, but one remark - I cannot make it to return bitmap instead of icon, so I decided, it would be wiser to make my own routine for that purpose. I chose the simplest way - in bmp all images-states are laid out from top to bottom, so I'll need just add certain offset to get a pointer to the image-state I want. However, nothing so simple as I have imagined - nothing seems to be working, probably disagreement between DIB and DDB.


.data?
ALIGN 4
brTab    dd 3 dup (?)
.code
; create DIB
... invoke LoadImage,hInstance, 13002, IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR+LR_CREATEDIBSECTION+LR_DEFAULTSIZE
mov    bmp, eax

... invoke GetBmpArray, hWin, bmp, 92, 31, 93, ADDR bmpTab ; 3 images-states: 92x31

... ; after return [bmpTab+0], [bmpTab+4], [bmpTab+8] should be valid DDB handles

; routine that doesn't work
GetBmpArray proc uses esi edi ebx hWin:DWORD, hBmp:DWORD, im_x:DWORD, im_y:DWORD, im_cy:DWORD, pBmp:DWORD
LOCAL dibs:DIBSECTION
LOCAL bmpi:BITMAPINFO
LOCAL bytes:DWORD
LOCAL dc:DWORD
LOCAL bmpX:DWORD
LOCAL mdc:DWORD

mov    eax, im_cy
xor    edx, edx
div    im_y
mov    ebx, eax

mov    eax, im_x
mul    im_y
lea    eax, [eax+eax*2]
mov    bytes, eax

invoke GetDC, hWin
mov    dc, eax
invoke CreateCompatibleDC, dc
mov    mdc, eax
invoke GetObject, hBmp, sizeof DIBSECTION, ADDR dibs ; get all pixels
invoke GetDIBits, dc, hBmp, 0, im_cy, 0, ADDR bmpi, DIB_RGB_COLORS ; fill BITMAPINFO

mov    bmpi.bmiHeader.biSize, sizeof BITMAPINFOHEADER
mov    eax, im_y
mov    bmpi.bmiHeader.biHeight, eax
mov    eax, bytes
mov    bmpi.bmiHeader.biSizeImage, eax

test   ebx, ebx
jz     @exit
;-----
@@:

dec    ebx
mov    eax, ebx
mul    bytes
add    eax, dibs.dsBm.bmBits
mov    esi, eax

invoke CreateCompatibleBitmap, dc, im_x, im_y
mov    bmpX, eax
invoke SelectObject, mdc, bmpX
invoke SetDIBits, mdc, bmpX, 0, im_y, esi, ADDR bmpi, DIB_RGB_COLORS ; replace bits
.if eax==0 ; fails here
invoke MessageBox,0,0,0,0
.endif
mov    eax, bmpX
mov    ecx, ebx
shl    ecx, 2
add    ecx, pBmp
mov    [ecx], eax
test   ebx, ebx
jnz    @B
@exit:
invoke ReleaseDC, hWin, dc
invoke DeleteDC, mdc
;-----

ret

GetBmpArray endp


If there is another way, or any suggestion I would like to hear it  :U

ramguru

This forum is a miracle: I have a working solution already & it's quite simple.

For those who may use this routine
hWin - current window, that bitmaps will be compatible with
hBmp - handle of DDB bitmap (usually got using LoadBitmap) (it will be divided to as many as needed)
im_y - height of one image-state in pixels
pBmp - pointer to array of dwords that receives handles of bitmaps

It's a good alternative for those who find ImageList_.. inconvenient (for the reason that ImageList... doesn't return bitmap handle)

GetBmpArray proc uses esi hWin:DWORD, hBmp:DWORD, im_y:DWORD, pBmp:DWORD
LOCAL bmp  :BITMAP
LOCAL dc   :DWORD
LOCAL bmpX :DWORD
LOCAL mdc  :DWORD
LOCAL mdcX :DWORD

invoke GetDC, hWin
mov    dc,   eax

invoke GetObject, hBmp, sizeof BITMAP, ADDR bmp

mov    eax, bmp.bmHeight
xor    edx, edx
div    im_y
mov    esi, eax

invoke CreateCompatibleDC, dc
mov    mdc,  eax
invoke CreateCompatibleDC, dc
mov    mdcX, eax
invoke SelectObject, mdcX, hBmp

test   esi,  esi
jz     @exit
;-----
@@:
dec    esi

invoke CreateCompatibleBitmap, dc, bmp.bmWidth, im_y
mov    bmpX, eax
invoke SelectObject, mdc, bmpX
mov    eax,  esi
mul    im_y
invoke BitBlt, mdc, 0, 0, bmp.bmWidth, im_y, mdcX, 0, eax, SRCCOPY
invoke GetCurrentObject, mdc, OBJ_BITMAP
mov    ecx,   esi
shl    ecx,   2
add    ecx,   pBmp
mov    [ecx], eax
test   esi,   esi
jnz    @B
@exit:
;-----
invoke ReleaseDC, hWin, dc
invoke DeleteDC,  mdcX
invoke DeleteDC,  mdc

ret

GetBmpArray endp

hutch--

Yep,

Thats the way it was done back in win3.0-1 etc .... BitBlt whatever bits of one bitmap onto another. This is how toolbars and other bitmaps were handled in pre-win95 Windows.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php