Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!


Problems with color palette (BMP)

JacobRJacobR Member Posts: 1

Im trying to make a very simple BMP shower. Should be easy, but i have a problem with the colors.
I use the 13h graphic mode.
I have found out how to load the picture into the memory and how to copy it onto the screen. The picture looks ok, but the colors are all wrong.
I found out that the colors are in the picture offset+54 position(?). The colors are stored in the BMP file as BGRX (X=not used). I copy the colors to the palette as RGB, starting from offset+54 (BGR) into color 0 (RGB), offset+54 into color 1 and so on. But it shows the wrong colors.
What am i doing wrong? Do anybody have an exampel of how to do it?
Does it matter if i use: 24-bit, 256 colors or 16 colors.

My palette routine looks like this (I hope it helps):
mov dx,03c8h ;Port to define color number to change

mov bx, offset picture ;Adr. to get the BGRX information
add bx,54

mov cx,256 ;number of loop
mov al,0 ;Start at color 0


out dx, al ;output to port 03c8H what color to change.
inc al ;Inc the color number
push ax ;Push al to the stack to save the next color number

inc dx ; change dx to 03c8h

inc bx ;inc bx two times to copy colors as RGB from the BGRx-bmp
inc bx

mov al,cs:[bx] ;Red-out to port. My file is in the same block as the code thats why i use cs:[bx]
out dx,al
dec bx ;dec bx to take the "next" color

mov al,cs:[bx] ;Green
out dx,al
dec bx

mov al,cs:[bx] ;Blue
out dx,al

dec dx ;dec dx to make it 03c8h again

inc bx ;inc bx four times to make bx point to next BGRX-block in bmp file
inc bx
inc bx
inc bx

pop ax ; get ax from stack to make ready to take next color in palette.

loop copypalette

I know this is probably not the coolest way to do it but im only been programming for 5 days. So i have a lot to learn i know....

Hope somebody can help me with my problems.



  • Johnny13Johnny13 Member Posts: 128
    Although I don't remember the BMP format,but here is an adapted code[code]mov si,offset picture
    add si,54
    mov dx,3c8h
    mov al,0
    out dx,al
    inc dx
    mov cx,256
    inc si ;skip 4th byte
    loop copypalette[/code]
  • ASHLEY4ASHLEY4 Member Posts: 254
    : Although I don't remember the BMP format,but here is an adapted code[code]mov si,offset picture
    : add si,54
    : mov dx,3c8h
    : mov al,0
    : out dx,al
    : inc dx
    : mov cx,256
    : copypalette:
    : outsb
    : outsb
    : outsb
    : inc si ;skip 4th byte
    : loop copypalette[/code]

    You may fined the image is up side down, with the above code, as i know 24bpp bmp are stored this way.

  • ASHLEY4ASHLEY4 Member Posts: 254
    ; Bitmap Display Program (bitmap.asm)

    ; The ShowBMP procedure loads a Windows type BMP file
    ; and display it on the screen. Input parameters:
    ; DS:DX points to an ASCIIZ string containing the
    ; BMP file path. The maximum resolution is 320x200, with
    ; 256 colors. (by Diego Escala, Miami, Florida)

    .model small

    extrn Open_infile:proc, Close_file:proc


    ShowBMP proc
    pusha ; Save registers
    call Open_infile ; Open file pointed to by DS:DX
    jc FileErr ; Error? Display error message and quit
    mov bx,ax ; Put the file handle in BX
    call ReadHeader ; Reads the 54-byte header containing file info
    jc InvalidBMP ; Not a valid BMP file? Show error and quit
    call ReadPal ; Read the BMP's palette and put it in a buffer
    push es
    call InitVid ; Set up the display for 320x200 VGA graphics
    call SendPal ; Send the palette to the video registers
    call LoadBMP ; Load the graphic and display it
    call close_file ; Close the file
    pop es

    jmp ProcDone

    mov ah,9
    mov dx,offset msgFileErr
    int 21h
    jmp ProcDone

    mov ah,9
    mov dx,offset msgInvBMP
    int 21h

    popa ; Restore registers
    ShowBMP endp

    ; Check the first two bytes of the file. If they do not
    ; match the standard beginning of a BMP header ("BM"),
    ; the carry flag is set.

    CheckValid proc
    mov si,offset Header
    mov di,offset BMPStart
    mov cx,2 ; BMP ID is 2 bytes long.
    mov al,[si] ; Get a byte from the header.
    mov dl,[di]
    cmp al,dl ; Is it what it should be?
    jne NotValid ; If not, set the carry flag.
    inc si
    inc di
    loop CVloop

    jmp CVdone


    CheckValid endp

    GetBMPInfo proc
    ; This procedure pulls some important BMP info from the header
    ; and puts it in the appropriate variables.

    mov ax,header[0Ah] ; AX = Offset of the beginning of the graphic.
    sub ax,54 ; Subtract the length of the header
    shr ax,2 ; and divide by 4
    mov PalSize,ax ; to get the number of colors in the BMP
    ; (Each palette entry is 4 bytes long).
    mov ax,header[12h] ; AX = Horizontal resolution (width) of BMP.
    mov BMPWidth,ax ; Store it.
    mov ax,header[16h] ; AX = Vertical resolution (height) of BMP.
    mov BMPHeight,ax ; Store it.
    GetBMPInfo endp

    InitVid proc
    ; This procedure initializes the video mode and makes ES point to
    ; video memory.

    mov ax,13h
    int 10h ; Set video mode to 320x200x256.
    push 0A000h
    pop es ; ES = A000h (video segment).
    InitVid endp

    LoadBMP proc
    ; BMP graphics are saved upside-down. This procedure reads the graphic
    ; line by line, displaying the lines from bottom to top. The line at
    ; which it starts depends on the vertical resolution, so the top-left
    ; corner of the graphic will always be at the top-left corner of the screen.

    ; The video memory is a two-dimensional array of memory bytes which
    ; can be addressed and modified individually. Each byte represents
    ; a pixel on the screen, and each byte contains the color of the
    ; pixel at that location.

    mov cx,BMPHeight ; We're going to display that many lines
    push cx
    mov di,cx ; Make a copy of CX
    shl cx,6 ; Multiply CX by 64
    shl di,8 ; Multiply DI by 256
    add di,cx ; DI = CX * 320, and points to the first
    ; pixel on the desired screen line.

    mov ah,3fh
    mov cx,BMPWidth
    mov dx,offset ScrLine
    int 21h ; Read one line into the buffer.

    cld ; Clear direction flag, for movsb.
    mov cx,BMPWidth
    mov si,offset ScrLine
    rep movsb ; Copy line in buffer to screen.

    pop cx
    loop ShowLoop
    LoadBMP endp

    ; This procedure checks to make sure the file is a valid BMP,
    ; and gets some information about the graphic.

    ReadHeader proc
    mov ah,3fh
    mov cx,54
    mov dx,offset Header
    int 21h ; Read file header into buffer.

    call CheckValid ; Is it a valid BMP file?
    jc RHdone ; No? Quit.
    call GetBMPInfo ; Otherwise, process the header.

    ReadHeader endp

    ; Read the video palette.

    ReadPal proc
    mov ah,3fh
    mov cx,PalSize ; CX = Number of colors in palette.
    shl cx,2 ; CX = Multiply by 4 to get size (in bytes)
    ; of palette.
    mov dx,offset palBuff
    int 21h ; Put the palette into the buffer.
    ReadPal endp

    SendPal proc
    ; This procedure goes through the palette buffer, sending information about
    ; the palette to the video registers. One byte is sent out
    ; port 3C8h, containing the number of the first color in the palette that
    ; will be sent (0=the first color). Then, RGB information about the colors
    ; (any number of colors) is sent out port 3C9h.

    mov si,offset palBuff ; Point to buffer containing palette.
    mov cx,PalSize ; CX = Number of colors to send.
    mov dx,3c8h
    mov al,0 ; We will start at 0.
    out dx,al
    inc dx ; DX = 3C9h.
    ; Note: Colors in a BMP file are saved as BGR values rather than RGB.

    mov al,[si+2] ; Get red value.
    shr al,2 ; Max. is 255, but video only allows
    ; values of up to 63. Dividing by 4
    ; gives a good value.
    out dx,al ; Send it.
    mov al,[si+1] ; Get green value.
    shr al,2
    out dx,al ; Send it.
    mov al,[si] ; Get blue value.
    shr al,2
    out dx,al ; Send it.

    add si,4 ; Point to next color.
    ; (There is a null chr. after every color.)
    loop sndLoop
    SendPal endp

    Header label word
    HeadBuff db 54 dup('H')
    palBuff db 1024 dup('P')
    ScrLine db 320 dup(0)

    BMPStart db 'BM'

    PalSize dw ?
    BMPHeight dw ?
    BMPWidth dw ?

    msgInvBMP db "Not a valid BMP file.",7,0Dh,0Ah,24h
    msgFileErr db "Error opening file.",7,0Dh,0Ah,24h


    Found this may help ?.
Sign In or Register to comment.