Howdy, Stranger!

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

Categories

Problems with color palette (BMP)

JacobRJacobR Member Posts: 1
Hey,

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):
[code]
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


copypalette:

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
[/code]



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.

Jacob

Comments

  • 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
    copypalette:
    outsb
    outsb
    outsb
    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.

    \\|////
    @)
    ASHLEY4.
  • ASHLEY4ASHLEY4 Member Posts: 254
    [code]
    ; 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
    .186
    .code

    extrn Open_infile:proc, Close_file:proc


    PUBLIC ShowBMP

    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

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

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

    ProcDone:
    popa ; Restore registers
    ret
    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
    clc
    mov si,offset Header
    mov di,offset BMPStart
    mov cx,2 ; BMP ID is 2 bytes long.
    CVloop:
    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

    NotValid:
    stc

    CVdone:
    ret
    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.
    ret
    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).
    ret
    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
    ShowLoop:
    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
    ret
    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.

    RHdone:
    ret
    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.
    ret
    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.
    sndLoop:
    ; 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
    ret
    SendPal endp

    .data
    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
    end


    [/code]

    Found this may help ?.
    \\|////
    @)
    ASHLEY4.
Sign In or Register to comment.