The MASM Forum Archive 2004 to 2012

General Forums => The Campus => Topic started by: minor28 on August 11, 2010, 01:05:48 PM

Title: How do I process data to draw a bitmap?
Post by: minor28 on August 11, 2010, 01:05:48 PM
I have struggled to try to draw an image from memory without success. The image is not a regular image so I have to process the data.

Following bitmapinfo which I have populated BITMAPINFO structure with.

Width=974
height=836

DX=0.85
DY=0.85

RGB/1,0,0,0
RGB/2,255,255,255
RGB/3,255,19,19
RGB/4,0,192,0
RGB/5,192,180,159
RGB/6,254,255,181
RGB/7,221,235,255
RGB/8,124,182,242

Pixel data consits of bytes in allocated memory like {05 05 05 01 01 01 ....} where each byte is the index of the zerobased color table.

I have tryed this code.

invoke CreateDIBSection,hSHP1DC,addr bmi,DIB_RGB_COLORS,offset pPixelData,0,0
mov hBitmap,eax ;=2F051225h
invoke SetDIBits,hSHP1DC,hBitmap,0,bsb._height,pPixelData,addr bmi,DIB_RGB_COLORS ;=344h =836
invoke DeleteDC,hSHP1DC

No image!

I have tryed this code


invoke CreateCompatibleBitmap,hSHP1DC,bsb._width,bsb._height
mov hBitmap,eax ;=0C1051063h
invoke CreateCompatibleDC,hSHP1DC
mov hDC,eax ;=0AF011155h
invoke CreateDIBSection,hSHP1DC,addr bmi,DIB_RGB_COLORS,offset pPixelData,0,0
mov hBitmap,eax
invoke SetDIBits,hSHP1DC,hBitmap,0,bsb._height,pPixelData,addr bmi,DIB_RGB_COLORS ;=0
invoke SelectObject,hDC,hBitmap ;=0185000Fh
push eax
invoke BitBlt,hSHP1DC,0,0,bsb._width,bsb._height,hDC,0,0,SRCCOPY ;1
pop eax
invoke DeleteObject,eax
invoke DeleteDC,hDC
invoke DeleteDC,hSHP1DC

No image!

hSHP1DC is DC of a static window to hold the image. pPixelData is the pointer to allocated memory (LocalAlloc).

Can anyone give me a hint how to proceed? I am not familiar with drawing images.
Title: Re: How do I process data to draw a bitmap?
Post by: Twister on August 11, 2010, 03:23:04 PM
What do you mean that the bitmap is not a normal image? Does it not follow the Microsoft Bitmap Image Format? If it doesn't then it is considered as a broken image, or corrupted.

Just convert the image to a regular 24-bit Microsoft Bitmap Image.
Title: Re: How do I process data to draw a bitmap?
Post by: minor28 on August 11, 2010, 03:46:03 PM
I am trying to convert the image to a  regular bitmap. The image file (*.kap) has a header with strings as I wrote above and pixel data as hex values not as a regular bitmap. I have allocated memory for pixel data converted to byte values and populated a bitmap info structure based on the string header. I want to draw the image with converted data from the file to the static window.
Title: Re: How do I process data to draw a bitmap?
Post by: baltoro on August 11, 2010, 05:33:07 PM
You should start off with: Bitmaps (http://msdn.microsoft.com/en-us/library/dd183377(v=VS.85).aspx). Most of the Windows Bitmap GDI functions are pretty picky about the format that the image is in. There are several header structures (depending on whether you are using a DIBSection or a file in memory.) Here is the MSDN page about BITMAPINFOHEADER (http://msdn.microsoft.com/en-us/library/dd183376(v=VS.85).aspx). All the data must be contiguous in memory.
Edgar has an assembly language Graphics Library (http://www.quickersoft.com/donkey/libs.htm), that is designed to work with DIBSections.
Here is an excellent discussion about: Saving a Memory DC to Bitmap (http://www.masm32.com/board/index.php?topic=2047.0), on this forum.
If you search this forum for: DIBSection, you will find lots of useful information.
Title: Re: How do I process data to draw a bitmap?
Post by: Twister on August 11, 2010, 08:28:46 PM
Oh okay, minor28, see what you mean.
Title: Re: How do I process data to draw a bitmap?
Post by: petezl on August 11, 2010, 10:58:21 PM
Have you looked at GDAL?
http://www.gdal.org/
Title: Re: How do I process data to draw a bitmap?
Post by: minor28 on August 12, 2010, 08:09:44 AM
I have been searching without finding anything similar. I have read MSDN. I have not seen the GDAL site but I have got a dll converting the file to a tiff file. I want to read the kap-file and display it diredtly on screen not using a dll.

This is my code in principal.



BitmapProc proc
LOCAL bmi:BITMAPINFOHEADER
LOCAL rgbArray[8]:RGBQUAD


invoke GetDlgItem,hWin,IDC_SHP1
mov hSHP1,eax
invoke GetDC,hSHP1
mov hSHP1DC,eax

mov bmi.biSize,sizeof bmi
mov bmi.biWidth,974
mov bmi.biHeight,836
mov bmi.biPlanes,1
mov bmi.biBitCount,8
mov bmi.biCompression,BI_RGB
mov bmi.biSizeImage,814264
mov bmi.bmiHeader.biXPelsPerMeter,0
mov bmi.bmiHeader.biYPelsPerMeter,0
mov bmi.biClrUsed,8
mov bmi.biClrImportant,8

rgbArray = {00 00 00 00, FF FF FF 00, 13 13 FF 00, 00 C0 00 00, .....}


invoke LocalAlloc,LMEM_FIXED or LMEM_ZEROINIT,bmi.biSizeImage
mov hPixelData,eax
invoke LocalLock,hPixelData
mov pPixelData,eax

pPixelData = {05 05 05 05 05 01 01 08 08 04 .......}


invoke CreateDIBSection,hSHP1DC,addr bmi,DIB_RGB_COLORS,offset pPixelData,0,0
mov hBitmap,eax
invoke SetDIBits,hSHP1DC,hBitmap,0,bmi.biHeight,pPixelData,addr bmi,DIB_RGB_COLORS

invoke DeleteDC,hSHP1DC
invoke LocalFree,hPixelData

BitmapProc endp


Return value from SetDIBits function is the number of rows written as it should but nothing is painted. Is anything wrong with bitmapinfo structure or array of pixeldata? Am I missing som API?
Title: Re: How do I process data to draw a bitmap?
Post by: dedndave on August 12, 2010, 10:34:18 AM
i have never heard of this file format, so i googled it out of curiousity
i found this description, if it helps any (i know it does not answer your question - lol)

http://libbsb.sourceforge.net/bsb_file_format.html
Title: Re: How do I process data to draw a bitmap?
Post by: petezl on August 12, 2010, 10:57:03 AM
Looks at first glance that your code is reasonable! Problem is probably screwed BitmapInfoHeader data...

try to write the data to file as bitmap then its a simple case of loading and blting it to the dc.
A blank (black) screen suggests that the info sent to the dc was not compatible
Think of CreateCompatibleBitmap api as creating a <standard ms compatible> grid filled with zeros. ie blank!
If your generated bitmap doesn't comply fully then the call will almost certainly fail.

Anyway, an interesting exercise!
Title: Re: How do I process data to draw a bitmap?
Post by: dedndave on August 12, 2010, 05:09:57 PM
yes - it is interesting
i take it you are receiving image data from a sat ?
or are you able to d/l these files from NOAA
Title: Re: How do I process data to draw a bitmap?
Post by: petezl on August 12, 2010, 05:54:11 PM
Parsing the .kap file, extracting and inserting the raster data into a bitmap array, then updating the BITMAPINFOHEADER is one way and probably one of the easier approaches! Then save it to file. (I'd steer clear of DC's during this stage!)
Need to find the structure details of the kap file, maybe better than shown here:http://libbsb.sourceforge.net/bsb_file_format.html yet that's a good place to start!

A small kap file to play with would certainly be of help!

Good thing with this approach is that you can easily test results by double clicking on the produced file and it should open in paint.

With a good file its an easy matter to load and display it in a window by using:
invoke LoadImage, NULL, addr imageFilePth,IMAGE_BITMAP,0,0,LR_LOADFROMFILE
mov hbitmap, eax

invoke CreateCompatibleDC, NULL
mov hMemDC, eax

invoke SelectObject, hMemDC, hbitmap
invoke GetClientRect, hWnd, addr rect

invoke BitBlt, hdc,0,0, rect.right, rect.bottom, hMemDC,0,0, SRCCOPY
invoke DeleteDC, hMemDC


in your WM_PAINT call.

Once the two halves are working you should be able to make it all one process!

Going on here a bit (just thinking out loud!) ah.


Title: Re: How do I process data to draw a bitmap?
Post by: petezl on August 12, 2010, 06:09:27 PM
You can get kap files here:
http://www.charts.noaa.gov/RNCs/RNCs.shtml
Title: Re: How do I process data to draw a bitmap?
Post by: dedndave on August 12, 2010, 07:04:00 PM
playing around a little, here - lol
i see that NOAA has a freebie program that will not only convert the file format (i used TIFF), but will also "re-project"
i.e., change the chart projection
the program is a little clumsy to use, but the results are very cool

http://www.csc.noaa.gov/crs/chartreproj.html

not only do they have windows and linux, but solaris versions
Title: Re: How do I process data to draw a bitmap?
Post by: dedndave on August 12, 2010, 07:15:21 PM
i changed the projection of this one
(these charts are huge - this is scaled way down and converted to GIF - lol)

(http://a.imageshack.us/img718/3319/mich.gif) (http://a.imageshack.us/img718/3319/mich.gif)
Title: Re: How do I process data to draw a bitmap?
Post by: petezl on August 12, 2010, 08:23:32 PM
Ah yes, you can see the need for the special file format now!
Irregular shape as well...
Title: Re: How do I process data to draw a bitmap?
Post by: dedndave on August 12, 2010, 08:39:02 PM
well - the file format allows the location (longitude/lattitude) to be specified
as well as a few other things   :P

the irregular shape was my doing - lol
Title: Re: How do I process data to draw a bitmap?
Post by: petezl on August 12, 2010, 09:02:55 PM
I was thinking that if the image background is part of a sphere then converting to bitmap on a flat plane will produce distortion!
Yea, lat & long, getting complicated...
Title: Re: How do I process data to draw a bitmap?
Post by: dedndave on August 12, 2010, 09:18:24 PM
well - that reproject program from NOAA allows you to change projections as desired
i could have "flattened" it out, if i wanted to - i was just playing with all the buttons   :P
Title: Re: How do I process data to draw a bitmap?
Post by: petezl on August 13, 2010, 09:07:03 AM
Dave, looks like a conversion can be made ok, main problem as I see it now is that placing such an immense bitmap into a window is rather useless!
Ok for manipulation in pShop or other program, but for direct viewing in a window the BM would need some serious size reduction which I have never had the need to persue!
Ie. Back to the original question: using conversion in a dll would only be of benefit if you had a fairly advanced picture handling procedure (with scroll and sizing facility)
My code is a bit too dirty to upload but is directly along the lines I suggested...
Title: Re: How do I process data to draw a bitmap?
Post by: minor28 on August 13, 2010, 09:57:45 AM
Thanks both of you,

I have already visit the bsb site as you mentioned and studied the file format.

My intention is not to view the whole image but only a part of it depending of the scrollbars position. Now I am looking at the headerinfo. As I can see the color table is correct. I think I have to calculate the constant for pixel per meter. I still work on it.
Title: Re: How do I process data to draw a bitmap?
Post by: dedndave on August 13, 2010, 11:17:10 AM
this is part of the chart at 1X, as viewed with Paint
i have left the scroll bars intact so you can see what portion of the image is displayed

(http://a.imageshack.us/img806/7904/mich2.gif) (http://img806.imageshack.us/i/mich2.gif/)
Title: Re: How do I process data to draw a bitmap?
Post by: petezl on August 13, 2010, 11:27:37 AM
Got a dim recollection that there is a max_filesize for bitmaps, might present a problem...
Title: Re: How do I process data to draw a bitmap?
Post by: dedndave on August 13, 2010, 11:33:54 AM
yah - i think you'll have to convert the entire image to a bitmap file (RAW or BMP),
then pick a window area out with your own code, making a smaller bitmap
that is, if you want to display it at 1X
Title: Re: How do I process data to draw a bitmap?
Post by: minor28 on August 14, 2010, 01:10:47 PM
Each scanline of the pixel data must be a multiple of a dword which was one fault.


;number of pixels
mov eax,bsb._width
mov ecx,bsb._height
mul ecx
push eax

;number of line paddings with zeroes
mov eax,bsb._width
mov ecx,4
div ecx
mov eax,bsb._height
mul edx
pop ecx
add eax,ecx
push eax
invoke LocalAlloc,LMEM_FIXED or LMEM_ZEROINIT,eax
mov hPixelData,eax
invoke LocalLock,hPixelData
mov pPixelData,eax
....


Next was allocating stack memory for BITMAPINFO

LOCAL bmi:BITMAPINFOHEADER
LOCAL rgbArray[8]:RGBQUAD

A pointer to bmi is not the same as a pointer to a BITMAPINFO structure.

How do I populate a BITMAPINFO structure with 8 entries of the color table? I tryed this

_BITMAPINFO struct
bmiHeader BITMAPINFOHEADER <?>
bmiColors dd 8 DUP (?)
_BITMAPINFO ends

.data?
bmi _BITMAPINFO <>




invoke CreateDIBSection,hDC,offset bmi,DIB_RGB_COLORS,offset pvBits,0,0
mov hBitmap,eax
invoke SetDIBits,hDC,hBitmap,0,bmi.bmiHeader.biHeight,pPixelData,offset bmi,DIB_RGB_COLORS

Return value of SetDIBits is 344h (number of rows) and the memory at pvBits is filld with data from pPixelData. No image.

Any suggestion how to proceed?

Edit:

invoke GetDIBits,hDC,hBitmap,0,bmi.bmiHeader.biHeight,pvBits,offset bmi,DIB_RGB_COLORS

Returns correct image size but biClrUsed and biClrImportant are set to zeroes.
Title: Re: How do I process data to draw a bitmap?
Post by: dedndave on August 14, 2010, 01:40:49 PM
i'm not sure where you're at - lol

yes - each scanline must begin on an offset that is mod 4, relative to the end of the header (+1)
i take it you are creating a 256-color BMP
if that's the case, the palette has a wierd structure
each entry is 4 bytes:
B,G,R,0
half the stuff in a BMP is backwards - the other half is not - lol
also, the first scanline in the file is normally the last line of the image
you can reverse this by negating the height value in the header
i.e., if the height is negative, the scanlines are "right-side-up"
Title: Re: How do I process data to draw a bitmap?
Post by: drizz on August 14, 2010, 03:43:53 PM
>> How do I populate a BITMAPINFO structure with 8 entries of the color table? I tryed this...
have you tried SetDIBColorTable?
Title: Re: How do I process data to draw a bitmap?
Post by: minor28 on August 14, 2010, 03:47:50 PM
OK, I changed to a negative height.

SetDIBColorTable return error.

I created an empty bmp-file. Filled it with data from headers and pixel-data from allocated memory. I could open the image with MSPaint but not with LoadImage etc.
Title: Re: How do I process data to draw a bitmap?
Post by: dedndave on August 14, 2010, 06:12:54 PM
there were some related threads a while back
let me see what i can find - maybe i will play with it a little.....
......after my nap   :P
Title: Re: How do I process data to draw a bitmap?
Post by: minor28 on August 15, 2010, 07:33:18 AM
Now both MSPaint and LoadImage API etc opens the image from the newly created file. Still not CreateDIBSection from memory.


invoke CreateDIBSection,hDC,offset bmi,DIB_RGB_COLORS,offset pvBits,0,0
.if eax==0 && pvBits==0
jmp @F
.endif
mov hBitmap,eax

invoke SetDIBits,hDC,hBitmap,0,bmi.biHeight,pPixelData,offset bmi,DIB_RGB_COLORS
.if eax==0
jmp @F
.endif

hDC is handle to Shape device context.
Title: Re: How do I process data to draw a bitmap?
Post by: minor28 on August 15, 2010, 08:49:17 AM
At last. Problem is solved.


invoke CreateDIBSection,hDC,offset bmi,DIB_RGB_COLORS,offset pvBits,0,0
.if eax==0 && pvBits==0
jmp @F
.endif
mov hBitmap,eax

invoke GetClientRect,hWin,addr rect
invoke StretchDIBits,hDC,0,0,rect.right,rect.bottom,0,0,bmi.biWidth,bmi.biHeight,pPixelData,offset bmi,DIB_RGB_COLORS,SRCCOPY
.if eax==0
jmp @F
.endif


Also I had to write pixeldata to memory from down to up and keep a positive height.

Thanks for your help