How can I convert a 256-color bitmap image to DB format?

215 views Asked by At

I'm looking for a way to convert a 256-color bitmap image into an ASM file that contains inside many DB commands with a sequence of BYTES.

I create a bitmap with 256 colors and a resolution of 320x200 pixels.

example of Bitmap with 256 colors and a 320x200 resolution

I would like a program that allows me to specify the Bitmap to convert. The image must be converted into an .ASM file, into a byte string in emu8086 compatible decimal or binary or hexadecimal format.
Then I will load the converted file (.ASM) into memory (with include command) and read every single byte by coloring the pixels on the screen.

Example of generated .ASM file:

DB 10,15,24,32,...
DB 00AH,00FH,018H,020H,...
DB 00001010B,00001111B,00010010B,00100000B,... 

I try to create a program that read a .TXT file and print the content, but it did not work.
I try to build this program to convert a bitmap file in a text file with .ASM extension and a string of byte inside.

org 100h
JMP START

INPUT DB "TEST.TXT", 0
OUTPUT DB "TEST.DB", 0
ERROR DB "FILE NOT FOUND$"

HANDLE DW ?
BUFFER DB 4 DUP(' ') ; i had found this command on internet but i don't know why i need to include it

START:

MOV AH,00H          ; set video mode
MOV AL,03H          ; 80x25 chars with 16 colors
INT 10H             ; Interrupt

; --------------------
; Read the bitmap file
; --------------------

MOV AH,3DH              ; Open the file
MOV AL,0                ; Only in read mode
MOV DX,OFFSET INPUT     ; TEST.TXT
INT 21H                 ; interrupt
JC STOP                 ; If the file not exist print an error

MOV HANDLE,AX           ; i had found this command on internet but i don't know why i need to include it

MOV BX,HANDLE
MOV DX,OFFSET BUFFER
MOV CX,0042H            ; read 42 bytes
MOV AH,3FH         
INT 21H


MOV HANDLE,0000H

READ:

MOV DL,[0124H]      ; print first byte of txt file from 0124H memory location
MOV AH,02H          ; print a char on screen
INT 21H             ; Interrupt

; close the file

MOV AH,3EH
MOV BX,HANDLE
INT 21H

JMP EXIT

STOP:
MOV DX,OFFSET ERROR
MOV AH,9
INT 21H


EXIT:
ret

Thanks to all who will answer me.

1

There are 1 answers

6
Sep Roland On
BUFFER DB 4 DUP(' ') ; i had found this command on internet but i don't know why i need to include it

You need it because you will want to use some memory buffer where you can store (part of) the .BMP file that you use as input.
What this particular db 4 dup(' ') does is reserving a small 4-byte portion of memory to serve as a BUFFER (from looking at the label name). That value 4 is important here because it limits what you can do with this buffer. eg. Your program reads 0042H bytes which is much more than the buffer can accommodate. The buffer overflows and the effect on the program will be disastrous!

MOV CX,0042H            ; read 42 bytes

Hoping for a typo here, but do know that 0042H is not the same as 42 bytes. It is 66 bytes.

MOV HANDLE,AX           ; i had found this command on internet but i don't know why i need to include it

When opening a file (like you did), DOS gives back a handle for the opened file. This is a number by which DOS can identify the file in all the subsequent interactions that you plan to undertake concerning this file. Working with a word-sized number is much easier than continually having to refer to the file via its name (which could include a path as well).

MOV HANDLE,0000H
...
MOV AH,3EH
MOV BX,HANDLE
INT 21H

Once you've reset the HANDLE variable, you should no longer be using it in the CloseFile operation.

MOV DL,[0124H]      ; print first byte of txt file from 0124H memory location

The assembler knows best! Use the name for the buffer and write: mov dl, BUFFER. The square brackets are optional when using emu8086.


I wrote a demo that converts a 320x200 256-color .BMP file into a .TXT file filled with db lines. This is a good starting point for what you ultimately need. It's just a starting point because:

  • you need to prompt the user to provide the filename(s)
  • you need to include suitable error messages
  • you need to not skip the file headers but rather parse them, so you can:
    • verify whether the .BMP file is a valid bitmap file
    • support a bitmap with dimensions other than 320 x 200
    • support a bitmap with an alternative orientation
  • you need to not skip the color table but rather use it, so you can show the picture as it was intended, color-wise

The program was tested on a true MS-DOS machine. It ran blazingly fast, but I'm not sure about how fast/slow emu8086 can run this.

    ORG     256

    mov     dx, OFFSET TxtF
    xor     cx, cx
    mov     ah, 3Ch     ; DOS.CreateFile
    int     21h         ; -> AX CF
    jc      Exit
    mov     TxtH, ax

    mov     dx, OFFSET BmpF
    mov     ax, 3D00h   ; DOS.OpenFile
    int     21h         ; -> AX CF
    jc      Exit
    mov     BmpH, ax

    mov     dx, 14+40+1024  ; Skip .BMP headers and color table
    xor     cx, cx
    mov     bx, ax
    mov     ax, 4200h   ; DOS.SeekFile
    int     21h         ; -> DX:AX CF
    jc      Exit

    mov     bp, (320*200)/16
OuterLoop:
    mov     dx, OFFSET BmpS
    mov     cx, 16
    mov     bx, BmpH
    mov     ah, 3Fh     ; DOS.ReadFile
    int     21h         ; -> AX CF
    jc      Exit
    cmp     ax, cx
    jne     Exit

    mov     di, OFFSET TxtS+3
    mov     si, OFFSET BmpS
InnerLoop:
    lodsb
    aam     100
    add     ah, '0'
    mov     [di], ah
    aam
    add     ax, '00'
    xchg    al, ah
    mov     [di+1], ax
    add     di, 4
    loop    InnerLoop

    mov     dx, OFFSET TxtS
    mov     cx, 68
    mov     bx, TxtH
    mov     ah, 40h     ; DOS.WriteFile
    int     21h         ; -> AX CF
    jc      Exit

    dec     bp
    jnz     OuterLoop

    mov     bx, BmpH
    mov     ah, 3Eh     ; DOS.CloseFile
    int     21h         ; -> AX CF

    mov     bx, TxtH
    mov     ah, 3Eh     ; DOS.CloseFile
    int     21h         ; -> AX CF

Exit:
    mov     ax, 4C00h   ; DOS.Terminate
    int     21h
; ------------------------------
    ALIGN   2
BmpS    db  16 dup 0
TxtS    db  'db ???', 15 dup (',???'), 13, 10
BmpH    dw  0
TxtH    dw  0
BmpF    db  'EXAMPO4.BMP', 0    ; 65078 bytes
TxtF    db  'EXAMPO4.TXT', 0    ; 272000 bytes

What my output looked like:

db 000,003,000,017,000,000,000,000,000,000,000,012,151,177,113,087
db 125,151,151,151,140,151,175,158,183,189,245,246,216,244,224,226
db 165,164,148,132,125,087,062,076,115,103,069,066,048,158,097,001
db 059,000,091,091,005,012,000,000,000,011,029,106,024,005,048,062
db 224,212,204,212,183,189,062,214,184,196,160,237,125,162,180,190
db 000,003,000,017,000,000,000,000,000,000,000,012,151,177,113,087
db 125,151,151,151,140,151,175,158,183,189,245,246,216,244,224,226
db 165,164,148,132,125,087,062,076,115,103,069,066,048,158,097,001
db 059,000,091,091,005,012,000,000,000,011,029,106,024,005,048,062
db 224,212,204,212,183,189,062,214,184,196,160,237,125,162,180,190
--- 3990 more lines ---