loading bmp's in asm

Started by
8 comments, last by Birdman 21 years, 7 months ago
Hey there, all. Nice forum you have here. Okay, I am trying to load bmp files in asm (is this forum even on asm? I hope so.) but I have a problem. i am trying to open the file, write it to the stack, update the stack pointer as if I PUSHed the whole thing, and pop off the variables in turn. This should (hopefully) speed up the process by lowering the number of interrupt calls I have to make. unfortuanatly, for some reason it displays the error message when it checks the number of planes in the bmp. I have tried it on multiple bmp files, and it still claims I have more than one plane. I posted at another forumn and someone suggested I update the stack pointer BEFORE I call the interrupt, but that didn''t do a thing to solve the problem. If it helps, I put the format for a bmp file after my code. Also: how can I CMP a double word value in TASM without having any extended registors? I am a poor programmer using good old win3.1 on a pre 386, so I have no extended reg''s. Okay, and one other thing (I know I''m asking alot). Why does the bmp format waste all that space with double words when a single word would work? Does anyone know? This is a great forum! You can post code and it keeps the indents! WOW! Thanks in advance for any help. My TASM code: DOSSEG .MODEL SMALl .STACK 200h .DATA filemessage db "File error.$" filename db "c:\tasm\test.bmp$" filehandle dw 0 tempb db 0 tempw dw 0 tempd dd 0 cols dd 0 bpp dw 0 .CODE START: mov AX,3d00h ;open the file for read only mov DX,seg filename mov DS,DX mov DX,offset filename int 21h mov filehandle,AX mov AH,3fh ;write the file header to the stack mov BX,filehandle mov CX,14 mov DX,SS mov DS,DX mov DX,SP sub DX,CX int 21h sub SP,CX pop AX ;pop the file header off the stack to variables cmp AX,19778 ;check file type (bitmap) jz cont1 call fileerror cont1: pop tempd ;get size of file (without header) pop tempw ;check reserved bytes pop AX add tempw,AX cmp tempw,0 jz cont2 call fileerror cont2: pop tempd ;get bytes offset from picture data mov AH,3fh ;write the info header to the stack mov BX,filehandle mov CX,40 mov DX,SS mov DS,DX mov DX,SP sub DX,CX int 21h sub SP,CX pop tempd ;get the size of info header pop tempd ;get pic width (pels) pop tempd ;get pic height (pels) pop tempw ;get number of planes cmp tempw,2 ;check planes jz cont3 call fileerror cont3: pop bpp ;get bits per pixel pop tempd ;get compression status (assumed to be 0) pop tempd ;get image size in bytes pop tempd ;get pic width in pels/meter pop tempd ;get pic height " " pop cols ;get number of colors used pop tempd ;get number of important colors mov AH,3fh ;write the palette data to the stack mov BX,filehandle mov CX,40 mov DX,SS mov DS,DX mov DX,SP sub DX,CX int 21h sub SP,CX mov AH,3eh ;close the file mov BX,filehandle int 21h endprog: mov AX,0003h ;end prog int 10h mov AX,4c00h int 21h Proc fileerror ;Dislay an error mov AX,seg filemessage ;display file error message mov DS,AX mov DX,offset filemessage mov AH,9 int 21h mov AX,0 ;wait for keypress int 16h jmp endprog ;end the program endp fileerror END START Format for a bmp: '' | # of | ''Offset | bytes | Function (value) ''-------+--------+--- General Picture information starts here--------- '' 0 | 2 | (BM) - Tells us that the picture is in bmp format '' 2 | 4 | Size of the file (without header?) '' 6 | 2 | (0) Reserved1 - Must be zero '' 8 | 2 | (0) Reserved2 - Must be zero '' 10 | 4 | Number of bytes offset of the picture data ''-------+--------+--- Information Header starts here ----------------- '' 14 | 4 | (40/12) Size of information header (Win3.1/OS2) '' 18 | 4 | Picture width in pixels '' 22 | 4 | Picture Height in pixels '' 26 | 2 | (1) Number of planes, must be 1 '' 28 | 2 | Number of bits per pixel (bpp), must be 1,4,8 or 24 '' 30 | 4 | (0) Compression - 0 means no compression, 1,2 are RLEs '' 34 | 4 | Image size in bytes '' 38 | 4 | picture width in pels per metre '' 42 | 4 | picture height in pels per metre '' 46 | 4 | (0) Number of colours used in the picture, 0 means all '' 50 | 4 | (0) Number of important colours, 0 means all ''-------+--------+--- Palette data starts here ----------------------- '' 54 | 1 | (b) - blue intensity component, color 0 - range 0 to 255 '' 55 | 1 | (g) - green intensity component, color 0 - range 0 to 255 '' 56 | 1 | (r) - red intensity component, color 0 - range 0 to 255 '' 57 | 1 | (0) - unused '' 58 | 1 | (b) - blue intensity component, color 0 - range 0 to 255 '' ... | ... | '' 54 | 4*2^bpp| total range of palette ''-------+--------+--- Image data starts here ------------------------- ''54+ | width* | Bitmap data starting at lower left portion of the ''(4*2^n)| height*| image moving from left towards right. Moving up 1 '' | (8/bpp)| pixel when at the right hand side of the image, starting '' | | from the left side again, until the top right of the '' | | image is reached Look! There! Up in the sky! It''''s Birdman! Da-du-du-daaaaah!
Look! There! Up in the sky! It's Birdman! Da-du-du-daaaaah!
Advertisement
Awwww! It got rid of my indents! How do I post code in those cool little windows you guys have?



Look! There! Up in the sky! It''''s Birdman! Da-du-du-daaaaah!
Look! There! Up in the sky! It's Birdman! Da-du-du-daaaaah!
Just some notes to help you out (I haven''t gone over the code yet, so no idea what the problem is):

The 4 reserved bytes are not always 0 (Paint and other programs will insert their own values).

>>Size of the file (without header?)
Its the total size of the file, however not all programs save this correctly (bit order can vary), so don''t rely on it.

Also note that the actual pixel width (in the data section) is padded to a 4 byte boundary. If the width (as described in the header) of the image is not a multiple of 4 then you will have to ignore the extra pixels at the end of each line.
Either use the &#91code] &#91/code] tags to create something like this:<br><br><pre><br>code<br> for proper spacing<br> </pre> <br><br>or the &#91source] &#91/source] tags to create something like this:<br> <!--STARTSCRIPT--><BR><DIV CLASS=source><pre> <br>code<br> <font color="blue">for</font> proper spacing<br> </pre></DIV><!--ENDSCRIPT-->
quote:Original post by Birdman
Awwww! It got rid of my indents! How do I post code in those cool little windows you guys have?



  You use source tags - [source''] Code goes here [/source''] Without the '' in the tags of course   
Thanks for the info on posting my code and the bmp format stuff. Hopefully someone can help me out here.

Look! There! Up in the sky! It''s Birdman! Da-du-du-daaaaah!
Look! There! Up in the sky! It's Birdman! Da-du-du-daaaaah!
quote:Original post by Birdman
unfortuanatly, for some reason it displays the error message when it checks the number of planes in the bmp. I have tried it on multiple bmp files, and it still claims I have more than one plane.

cmp tempw,2 ;check planes
are you sure that 2 is the right number?
quote:
I posted at another forumn and someone suggested I update the stack pointer BEFORE I call the interrupt, but that didn''t do a thing to solve the problem.

that''s what i''d suggest, too, because you''re screwing up the stack by making the interrupt operate on the same stack space it reads to.
quote:
Also: how can I CMP a double word value in TASM without having any extended registors?

use two cmp instructions, one for the lower word and one for the higher word.
quote:
Why does the bmp format waste all that space with double words when a single word would work?

your best bet would be to ask microsoft, i guess. however, since words on 32-bit x86 are 32 bits long, they naturally store data to match word size. it makes things easier when your C code uses ints and not shorts for width, height, and so on.
Yeah, sorry, I meant 1 instead of 2. The 2 was from a test thingy I was doing.

About writing to the stack: maybe I could write it directly from the file to the variables. If I set up a sequence of variables in order, and then wrote directly to the first one, would it fill in the rest? Are variables that I db,dw,and dd in order actually in that order in memory?

If not, is there a way to use a structure to get the variables? I don''t know anything about structs in asm, so I might need some help on that one.

Look! There! Up in the sky! It''s Birdman! Da-du-du-daaaaah!
Look! There! Up in the sky! It's Birdman! Da-du-du-daaaaah!
quote:Original post by Birdman
About writing to the stack: maybe I could write it directly from the file to the variables. If I set up a sequence of variables in order, and then wrote directly to the first one, would it fill in the rest? Are variables that I db,dw,and dd in order actually in that order in memory?

yes, you can do just that. be sure to leave the data uninitialized and put it in the bss segment (or in the end of data segment, that might work too) so that it does not take space in exe file.
quote:
If not, is there a way to use a structure to get the variables?

of course. my tasm knowledge is rusty too, though, so take the following with a grain of salt:

  struc bmpheader    magic dw ?    filesize dd ?    ...endshdr bmpheader ?  

something like that, consult your tasm reference for the exact syntax.
Thanks, I got it working.
Look! There! Up in the sky! It's Birdman! Da-du-du-daaaaah!

This topic is closed to new replies.

Advertisement