gif解码程序
这是我以前写的一个程序,可在全屏幕dos窗口运行。
;gif.asm: view gif picture
;nasm -f bin -o gif.com gif.asm
;writen by tpu.
;
vesa_mode equ 0100h
[section .bss]
absolute 0
dictory resb 8000h
file_buf resb 2048
block_buf resb 272
line_buf resb 2048
gif_fd resw 1
pal_size resw 1
pal_pos resw 1
width resw 1
height resw 1
min_code resw 1
clear_code resw 1
eoi_code resw 1
code_len resw 1
code_mask resw 1
code_level resw 1
next_byte resw 1
bit_left resw 1
block_cnt resw 1
x_pos resw 1
y_pos resw 1
bank resw 1
[section .text]
org 100h
;check command line
mov bl, [80h]
dec bx
jns cmdline_ok
error:
int 20h
cmdline_ok:
mov [bx+82h], bh
;open file
mov dx, 82h
mov ah, 3dh
int 21h
jc error
mov bx, ax
;set data segment
mov ax, ds
add ax, 40h
mov ds, ax
mov ax, 0a000h
mov es, ax
;save file handle
mov [gif_fd], bx
;read gif file header
mov cx, 1560
mov dx, file_buf
mov ah, 3fh
int 21h
;check gif version
mov si, file_buf+13
; cmp dword[si-11], "F87a"
; jnz error
;check global pal
mov cl, [si-3]
call set_pal
;check local picture
lodsb
cmp al, ','
jnz error
;get width and height
mov eax, [si+4]
mov [width], eax
;get local flag
mov cl, [si+8]
add si, 9
;check local pal
call set_pal
;get code size
lodsb
movzx cx, al
;initial dictory
xor di, di
xor edx, edx
mov [bit_left], edx
mov [x_pos], edx
mov ax, 1
;dictory table:
;+-------+----+----+-------+-------+
;| 00 01 | 02 | 03 | 04 05 | 06 07 |
;+-------+----+----+-------+-------+
; | | | | |
; | | | | +-- unuse
; | | | |
; | | | +--------- string length
; | | |
; | | +--------------- current char
; | |
; | +-------------------- last char of prefix
; |
; +---------------------------- pointer to prefix
set_dict:
mov dh, dl
mov [di+2], dx
mov [di+4], ax
add di, 8
inc dl
jnz set_dict
;initial clear_code, min_code, eoi_code
shl ax, cl
mov [clear_code], ax
inc ax
inc cx
mov [min_code], cx
shl ax, 3
mov [eoi_code], ax
;seek file to data area
;now SI pointer to first block
mov dx, si
sub dh, 80h
mov ax, 4200h
xor cx, cx
int 21h
;set video mode to vesa 640x480x256
mov ax, 4f02h
mov bx, vesa_mode
int 10h
;set scanline lenth to 1024
mov dx, 03d4h
mov ax, 8013h
out dx, ax
;set pal
mov cx, [pal_size]
jcxz clear
mov si, [pal_pos]
mov dl, 0c8h
xor ax, ax
out dx, al
inc dx
cld
next_color:
lodsb
shr al, 2
out dx, al
loop next_color
clear:
mov bx, [eoi_code]
mov cx, [min_code]
mov [code_len], cx
mov ax, [clear_code]
shl ax, 4
mov [code_level], ax
begin:
call get_code
cmp ax, [clear_code]
jz clear
shl ax, 3
cmp ax, [eoi_code]
jz decode_end
mov si, ax
cmp ax, bx
jc add_dict
mov si, di
add_dict:
mov [bx], di
push ax
mov ax, [di+4]
inc ax
mov [bx+4], ax
mov ah, [si+2]
mov al, [di+2]
mov [bx+2], ax
add bx, 8
cmp bx, [code_level]
jnz output_code
cmp cl, 0ch
jz output_code
inc word[code_len]
shl word[code_level], 1
output_code:
pop di
push di
mov cx, [di+4]
push cx
mov si, line_buf
add si, cx
next_dot:
mov al, [di+3]
dec si
mov [si], al
mov di, [di]
loop next_dot
pop cx
next_pixel:
lodsb
call show_pixel
loop next_pixel
pop di
jmp begin
decode_end:
;wait key
mov ah, 8
int 21h
;set text mode
mov ax, 3
int 10h
int 20h
;show one pixel
show_pixel:
mov di, word[y_pos]
mov dx, di
shr dx, 6
shl di, 10
add di, [x_pos]
adc dl, 0
pusha
cmp dx, [bank]
jz no_bank
mov [bank], dx
mov ax, 4f05h
xor bx, bx
int 10h
no_bank:
popa
stosb
mov ax, [x_pos]
inc ax
cmp ax, [width]
jnz show_end
xor ax, ax
inc word[y_pos]
show_end:
mov word[x_pos], ax
ret
;get code from input stream
get_code:
mov ax, [bit_left]
cmp ax, [code_len]
jnc shift_code
pusha
mov word[next_byte], 16
sub [next_byte], ax
mov di, [block_cnt]
mov ax, [di+block_buf]
mov [block_buf], ax
mov dx, block_cnt
mov bx, [gif_fd]
mov cx, 1
mov ax, 3f00h
int 21h
mov dx, block_buf+2
mov cl, [block_cnt]
mov ax, 3f00h
int 21h
shl cx, 3
add [bit_left], cx
popa
shift_code:
mov si, [next_byte]
mov cx, si
shr si, 3
mov esi, [si+block_buf]
and cx, 07h
shr esi, cl
mov cx, [code_len]
mov ax, 0xffff
shl ax, cl
not ax
and ax, si
sub [bit_left], cx
add [next_byte], cx
ret
;set pal param
set_pal:
test cl, 80h
jz no_pal
mov [pal_pos], si
mov ax, 6
and cl, 7
shl ax, cl
add si, ax
mov [pal_size], ax
no_pal:
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
问题点数:0、回复次数:4Top
1 楼dewei(小福)回复于 2003-11-14 14:05:03 得分 0
能告诉我你是怎么知道这个解码原理的,我很想知道。
比如说出现一种新的东东时,你是怎么知道如何解码的。
联系方式:zhujun8237@163.comTop
2 楼Purpleendurer(编程—>任是无情也动人^_^)回复于 2004-02-12 20:59:54 得分 0
好东东.
UPTop
3 楼Borland2004(我是转型者)回复于 2004-02-13 14:51:46 得分 0
才这么几行东西就可以完成对GIF文件的解码?高级语言怎么都是几千行的程序啊Top
4 楼tpu(猫和老鼠)回复于 2004-02-13 19:27:45 得分 0
因为只处理gif87a的格式,所以比较小。编以后510个字节。Top




