следующий фpагмент (2) Program GIFView; { by Barry Naujok, 1993 }
Uses Strings,VESA,Crt;
Const bsize = 32000; { file buffer size }
eof = $FFFF;
cmask : Array [0..8] Of Byte=(0,1,3,7,$F,$1F,$3F,$7F,$FF);
inctable : Array [0..4] Of Byte=(8,8,4,2,0);
startable : Array [0..4] Of Byte=(0,4,2,1,0);
CopyRight : PChar = 'GIF and "Graphics Interchange Format" are trademarks (tm) of CompuServe Inc.';
Var startinit:Byte; { Reference for start of variables }
interlaced,imagewide,imagedeep,imagex,imagey,xloc,yloc,background : Word;
version,subver,handle,bufferindex,done,code,oldcode,bank : Word;
eoi,rem,remct,bufct,nextlim,nextcode,rowcnt,pass,clearcode,reqct : Word;
palette : Array [0..767] Of Byte;
outrow : Array [0..2047] Of Byte;
ostack,ctfirst,ctlast : Array [0..4095] Of Byte;
ctlink : Array [0..4095] Of Word;
endinit : Byte; { Reference for end of variables }
filename: Array[0..63] Of Char;
buffer : {Array [1..bsize] Of} PByte;
Procedure ShowHandler; Assembler; { SetShow }
Asm
Push si
Push di
Push cx
Mov si,Offset outrow
Mov dx,yloc
Cmp dx,VesaMode.Height
Jge @Ex
Mov ax,VesaMode.Bytes
Mul dx
Cmp dx,bank
Je @00
Call @B1
@00: Mov di,ax { DI = offset to line }
Mov cx,imagewide
Or cx,cx
Jz @Ex { Check for nasties }
Cmp cx,VesaMode.Width
Jle @01
Mov cx,VesaMode.Width
@01: Mov es,VesaMode.SegA
Add ax,VesaMode.Bytes { Check to see if line cross bank }
Jc @03
Shr cx,1
Jnc @02
Movsb
@02: Rep Movsw
Jmp @Ex
@03: Movsb
Or di,di
Jnz @04
Inc dx
Call @B1
@04: Loop @03
Jmp @Ex
{ Set bank }
@B1: Push ax
Mov al,vesaon
Or al,al
Jz @B3
Mov bank,dx
Push dx
Xor bx,bx
Mov ax,64
Mul dx
Div VesaMode.Gran
Mov dx,ax
Push dx
Call VesaMode.WinFunc
Pop dx
Inc bx
Call VesaMode.WinFunc
Pop dx
@B3: Pop ax
RetN
@Ex: Pop cx
Pop di
Pop si
End;
Procedure PaltHandler(ncols:Word); Assembler; { SetPalette }
Asm
Mov di,Offset palette
Mov cx,ncols
Or cx,cx { Check for nasties }
Jz @Ex
Add cx,cx
Add cx,ncols
@01: Shr Byte Ptr [di],2
Inc di
Loop @01
Mov ax,ds
Mov es,ax
Mov ax,$1012
Mov bx,0
Mov cx,256
Mov dx,Offset palette
Int $10
@Ex:
End;
Procedure ImageHandler; { SetImage }
Begin
Sound(660);
Delay(100);
Sound(880);
Delay(50);
Sound(440);
Delay(75);
NoSound;
End;
Procedure BackHandler(bcol:Word);
Begin
{ FillScreen(bcol); }
Asm
Mov ax,$1001
Mov bx,bcol
Shl bx,8
Int $10
End;
End;
{ This function opens a file, DS:DX -> path to file }
Function OpenFile:Boolean; Assembler;
Asm
Push bx
Push cx
Push dx
Mov ax,$3D00
Int $21
Jc @01
Mov handle,ax
Mov ax,$3F00
Mov bx,handle
Mov cx,bsize
Push ds
Lds dx,buffer
Int $21
Pop ds
Jc @01
Mov bufferindex,ax
Mov si,dx {bufferpoint}
Mov ax,0
Jmp @Ex
@01: Mov ax,eof
@Ex: Pop dx
Pop cx
Pop bx
End;
Procedure CloseFile; Assembler;
Asm
Mov ax,$3E00
Mov bx,handle
Int $21
End;
Procedure ErrorHandler; { SetError }
Begin
CloseFile;
SetMode(3);
Writeln('Error while reading GIF file');
Halt;
End;
{ This function gets the next byte from a file }
Function FGetC:Integer; Assembler;
Asm
Les ax,buffer
Mov al,es:[si]
Inc si
Dec bufferindex
Jnz @Ex
Push ax
Push bx
Push cx
Push dx
Mov ax,$3F00
Mov bx,handle
Mov cx,bsize
Push ds
Lds dx,buffer
Int $21
Pop ds
Mov si,dx {bufferpoint}
Pop dx
Pop cx
Pop bx
Jnc @01 { Check for errors }
Mov ax,eof { Return -1 ($FFFF) if error }
Jmp @Ex
@01: Mov bufferindex,ax { number of bytes read }
Pop ax
@Ex:
End;
{ This function gets the next word from a file }
Function FGetW:Word; Assembler;
Asm
Call Near Ptr FGetC
Mov bx,ax
Call Near Ptr FGetC
Mov bh,al
Mov ax,bx
End;
{ This procedure gets the colours from a GIF file, CX = palette size }
Procedure GetColours; Assembler;
Asm
Mov ax,1 { Shift right by psize }
Shl ax,cl
Mov cx,ax { AX = number of colours }
Mov bx,Offset palette
@01: Call Near Ptr FGetC { Load up the colour palette }
Mov [bx],al
Inc bx
Call Near Ptr FGetC
Mov [bx],al
Inc bx
Call Near Ptr FGetC
Mov [bx],al
Inc bx
Loop @01
End;
{ This procedure initializes the code table, CX = clearcode }
Procedure InitCodeTable; Assembler;
Asm
Xor bx,bx { Start with a zero code }
Mov ax,cx { The next code will be the clear }
Add ax,2 { code plus 2 }
Mov nextcode,ax
Mov ax,cx { Next limit will be clear code }
Shl ax,1 { times 2 }
Mov nextlim,ax
@01: Cmp bx,cx
Jge @02 { While code<cc do ... }
Mov Byte Ptr [ctfirst+bx],bl{ ctfirst[code]:=code }
Mov Byte Ptr [ctlast+bx],bl { ctlast[code]:=code }
Shl bx,1
Mov Word Ptr [ctlink+bx],-1 { ctlink[code]:= -1 }
Shr bx,1
Inc bx
Jmp @01
@02: Mov cx,4096
Sub cx,bx
Shl bx,1
Mov di,Offset ctlink
Add di,bx
Mov ax,ds
Mov es,ax
Mov ax,-2
Rep Stosw
@Ex:
End;
{ This function gets the buffer length }
Function GetGB:Word; Assembler;
Asm
Mov di,bufct
Or di,di
Jnz @02
Call Near Ptr FGetC
Mov di,ax { Save the size }
Cmp ax,eof { If it's EOF }
Je @01
Or ax,ax { or zero length }
Jz @01 { then go handle the error }
Jmp @02 { otherwise carry on }
@01: Call Near Ptr ErrorHandler
Jmp @Ex
@02: Call Near Ptr FGetC { Get the byte }
Cmp ax,eof { If it's EOF... }
Je @01
Dec di { Say we got this byte }
@Ex: Mov bufct,di
End;
{ This function gets a BCode, DX = reqct }
Function GetBCode:Word; Assembler;
Asm
Mov bx,remct
Or bx,bx { If remct=0 }
Jnz @01
Call Near Ptr GetGB { then rem:=GetGB }
Mov rem,ax
Mov bx,8 { and remct:=8 }
@01: Mov ax,dx
Cmp bx,ax { If remct<reqct }
Jnl @02
Call Near Ptr GetGB { then rem:=rem Or GetBG Shl remct }
Mov cx,bx
Shl ax,cl
Or rem,ax
Add bx,8 { and remct:=remct+8 }
@02: Mov di,dx { retcode:=rem And cmask[reqct] }
Mov al,Byte Ptr [cmask+di]
And ax,$FF
And ax,rem
Sub bx,dx { remct:=remct - reqct }
Mov cx,dx
Shr rem,cl { rem:=rem Shr reqct }
Mov remct,bx
End;
{ This function gets a code, DX = reqct }
Function GetCode:Word; Assembler;
Asm
Cmp dx,8 { If reqct<=8 }
Jg @01
Call Near Ptr GetBCode { then return GetBCode(reqct) }
Jmp @Ex
@01: Push dx { else ... }
Mov dx,8 { temp:=GetBCode(8) }
Call Near Ptr GetBCode
Pop dx { Restore reqct }
Push ax { Save temp }
Sub dx,8
Call Near Ptr GetBCode
Shl ax,8
Pop bx
Or ax,bx
@Ex:
End;
{ This procedure handles flushing the input }
Procedure FlushIn; Assembler;
Asm
@01: Cmp bufct,0
Je @02
Call Near Ptr FGetC
Dec bufct
Jmp @01
@02: Call Near Ptr FGetC
Mov bufct,ax
Cmp bufct,0
Jne @01
End;
{ This procedure inserts a code into the table, BX = code, CX = OldCode, }
Procedure InsertCode; Assembler; { ES:DI -> csizeptr }
Asm
Push si
Mov si,bx
Mov dx,nextcode
Mov bx,dx
Shl bx,1
Mov Word Ptr [ctlink+bx],cx { ctlink[nextcode]:=oldcode }
Mov bx,si
Mov al,Byte Ptr [ctfirst+bx]{ AL = ctfirst[code] }
Mov bx,dx
Mov Byte Ptr [ctlast+bx],al { ctlast[nextcode]:=AL }
Mov bx,cx { oldcode }
Mov al,Byte Ptr [ctfirst+bx]
Mov bx,dx
Mov Byte Ptr [ctfirst+bx],al{ ctfirst[nextcode]:=ctfirst[oldcode] }
Mov bx,si
Inc dx
Cmp dx,nextlim
Jne @Ex
Cmp Word Ptr es:[di],12 { If csizeptr^<12 }
Jnl @Ex
Inc Word Ptr es:[di]
Shl nextlim,1
@Ex: Mov nextcode,dx
Pop si
End;
{ This procedure handles one pixel, AX = value }
Procedure DoPixel; Assembler;
Asm
Mov bx,xloc { Get x position }
Mov Byte Ptr [outrow+bx],al { save the character }
Inc xloc { bump it ! }
Dec rowcnt
Jnz @Ex
Call Near Ptr ShowHandler { Show the line }
Mov xloc,0 { zero the x count }
Mov ax,imagewide { Set up the next line }
Mov rowcnt,ax
Cmp interlaced,0 { Are we interlaced? }
Je @02 { Jump if not }
Mov bx,pass
Shl bx,1
Mov ax,Word Ptr [inctable+bx] { Get the next line from the table }
Add yloc,ax
Mov ax,yloc
Cmp ax,imagedeep
Jl @Ex
Inc pass
Mov bx,pass
Shl bx,1
Mov ax,Word Ptr [startable+bx]
Mov yloc,ax
@01: Jmp @Ex
@02: Inc yloc
{ Mov ax,yloc
Cmp ax,imagedeep
Jl @Ex
Mov yloc,0} { vertical wrap around if stuffed }
@Ex:
End;
{ This procedure puts a code into the table, BX = code, DX = psize }
Procedure PutX; Assembler;
Asm
Xor cx,cx
Mov di,Offset ostack
@01: Mov al,Byte Ptr [ctlast+bx]
Mov [di],al
Inc di
Inc cx
Shl bx,1
Mov bx,Word Ptr [ctlink+bx]
Cmp bx,-1
Jne @01
Cmp dx,1
Jne @03
@02: Dec di
Mov al,[di]
And ax,1
Call Near Ptr DoPixel
Mov al,[di]
Xor ah,ah
Shr ax,1
Call Near Ptr DoPixel
Loop @02
Jmp @Ex
@03: Dec di
Mov al,[di]
Xor ah,ah
Call Near Ptr DoPixel
Loop @03
@Ex:
End;
{ This procedure extracts a GIF image, CX = code start, DX = pixel size }
Procedure UnpackImage(c,d:Word); Assembler;
Asm
Mov cx,c
Mov dx,d
Mov ax,1
Shl ax,cl
Mov clearcode,ax { clearcode:=1 Shl codestart }
Inc ax
Mov eoi,ax { eoi:=clearcode+1 }
Dec ax
Inc cx
Mov reqct,cx { reqct:=codestart+1 }
Mov cx,ax
Call Near Ptr InitCodeTable
Mov oldcode,$FFFF
Mov done,0
Mov pass,0
Mov ax,imagewide
Mov rowcnt,ax { rowcnt:=imagewide }
Mov xloc,0
Mov yloc,0 { Initialize screen position }
Mov cx,c
@01: Mov dx,reqct
Call Near Ptr GetCode
Mov code,ax { code:=GetCode(reqct) }
Mov dx,d
Mov dx,c
Cmp ax,clearcode
Jne @02
Mov cx,clearcode
Call Near Ptr InitCodeTable { Initialize codetable with clearcode }
Mov cx,c
Mov ax,cx
Inc ax
Mov reqct,ax { reqct:=codestart+1 }
Mov oldcode,$FFFF { oldcode:=-1 }
Jmp @07
@02: Cmp ax,eoi { If code=eoi }
Jne @03
Call Near Ptr FlushIn { Then flush the input }
Mov done,$FFFF { And say we're done }
Jmp @07
@03: Mov bx,code { Default condition }
Shl bx,1
Cmp Word Ptr [ctlink+bx],$FFFE { If ctlink[code]<>-2 }
Je @05
Cmp oldcode,$FFFF { If oldcode<>-1 }
Je @06
Mov bx,code
Mov cx,oldcode
Mov ax,ds
Mov es,ax
Mov di,Offset reqct
Call Near Ptr InsertCode
Mov cx,c
Mov dx,d
@04: Jmp @06
@05: Mov bx,oldcode
Mov cx,bx
Mov ax,ds
Mov es,ax
Mov di,Offset reqct
Call Near Ptr InsertCode
Mov dx,d
Mov cx,c
@06: Mov bx,code
Call Near Ptr PutX { PutX(code,pixelsize) }
Mov dx,d
Mov cx,c
Mov ax,code
Mov oldcode,ax { oldcode:=code }
@07: Cmp done,0
Jz @01
@Ex:
End;
{ This function unpacks a GIF file }
Function UnpackGIF(path:PChar):Word; Assembler;
Var sflags,gpix,pixelsize,alldone,work,iflags : Word;
Asm
Mov di,Offset startinit
Mov ax,ds
Mov es,ax
Mov cx,Offset endinit
Sub cx,di
Cld
Mov al,0
Repne Stosb
Push ds
Lds dx,path
Call Near Ptr OpenFile
Pop ds
Cmp ax,0
Je @01
Mov ax,1 { Error code for file not found }
Jmp @Ex
@01: Call Near Ptr FGetC
Cmp al,'G' { See if it is a GIF file }
Je @02
Call Near Ptr CloseFile
Mov ax,2 { Error code for file not GIF }
Jmp @Ex
@02: Mov cx,5
@03: Push cx
Call FGetC
Pop cx
Loop @03 { Throw away rest of header }
Call Near Ptr FGetW
{Mov screenwidth,ax { Get screen width }
Call Near Ptr FGetW
{Mov screenheight,ax { Get screen height }
Call Near Ptr FGetC
Mov sflags,ax { Get global flags }
And ax,7
Inc ax
Mov gpix,ax { Calculate global pixel size }
Call Near Ptr FGetC
Mov background,ax
Call Near Ptr FGetC
Cmp al,0
Je @04
Call CloseFile
Mov ax,3 { Error code for file corrupted }
Jmp @Ex
@04: Test sflags,$80
Jz @05 { Test for global colour palette }
Mov cx,gpix
Call Near Ptr GetColours { Get the palette }
Call Near Ptr PaltHandler
@05: Mov alldone,0
{ Main loop for extracting GIF components }
@06: Cmp alldone,0
Je @07
Call Near Ptr CloseFile
Mov ax,0 { Unpacking successful }
Jmp @Ex
@07: Call Near Ptr FGetC { Get the next deliminator }
Mov work,ax
Cmp ax,eof { If it's EOF then it's done }
Jne @08
Call Near Ptr CloseFile
Mov ax,0 { Unpacking successful }
Jmp @Ex
@08: Cmp al,',' { Is it an image }
Je @09
Jmp @11 { Try an extension }
@09: Call Near Ptr FGetW { Process the image }
Mov imagex,ax { Get the image left }
Call Near Ptr FGetW
Mov imagey,ax { Get the image top }
Call Near Ptr FGetW
Mov imagewide,ax { Get the image width }
Call Near Ptr FGetW
Mov imagedeep,ax { Get the image depth }
Call Near Ptr FGetC
Mov iflags,ax { Get local flags }
And ax,$40
Mov interlaced,ax { See if the image is interlaced }
Mov ax,gpix { Set default pixel size }
Mov pixelsize,ax { from global value }
Test iflags,$80
Jz @10 { Check for local colour map }
Mov ax,iflags { If so, get local pixel size }
And ax,7
Inc ax
Mov pixelsize,ax
Mov cx,ax
Push cx
Call Near Ptr GetColours { Get the local palette }
Pop cx
Mov ax,1
Shl ax,cl
Push ax
Call Near Ptr PaltHandler { and activate it }
@10: Push background
Call Near Ptr BackHandler { set the background }
Mov bufct,0
Call Near Ptr FGetC { Get code start }
Push ax
Push pixelsize
Call Near Ptr UnpackImage
{
Mov cx,gpix
Mov ax,1
Shl ax,cl
Push ax
Call Near Ptr PaltHandler
}
Push si
Call Near Ptr ImageHandler { Do something with the image }
Pop si
Jmp @06 { and loop }
@11: Cmp al,'!' { Is it an extension? }
Je @12
Jmp @16 { If not, try end of file }
@12: Call Near Ptr FGetC { Throw away next byte }
@13: Call Near Ptr FGetC { Throw away extensions }
Mov cx,ax
Or ax,ax
Jz @15
@14: Push cx { Throw away field }
Call Near Ptr FGetC
Pop cx
Loop @14
Jmp @13 { and check for the next one }
@15: Jmp @06 { go try for next item }
@16: Cmp al,';' { Check for all done }
Jne @17
Mov alldone,$FFFF
Jmp @06
@17: Call Near Ptr CloseFile
Mov ax,3 { Error code bad file error }
@Ex:
End;
Begin
If ParamCount<>0 Then Begin
StrPCopy(filename,ParamStr(1));
SetMode($101);
FillChar(palette,768,0);
PaltHandler(256);
GetMem(buffer,bsize);
If UnpackGIF(filename)<>0 Then ErrorHandler;
ReadKey;
SetMode(3);
End Else Writeln('Usage: GIFVIEW <filename>');
End.
следующий фpагмент (3)|пpедыдущий фpагмент (1)
From : Mark Williamson 1:214/54 04 Jul 93 12:09:00
Subj : GIF FILE HEADERS
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
I've written this little routine to display the header info on a gif file.
This may be some sloppy code, so if someone has a better way, I'd appreciate
a little help optimizing this. Read the info at the end of this message for
details on the gif header. For more detailed info, freq GIFINFO from
1:214/54 (v42/32 bis 14400).
#include <stdio.h>
#include <io.h>
#include <fcntl.h>
struct gif { // A gif header is made up of
unsigned width, // 13 bytes. The first 3
length; // will always be the word GIF
unsigned char pixel; // The next three are the version
} gif; // number (87a or 89a etc..)
// The next two are the raster
// width in pixels (LSB first)
// The next two are the raster
// height in pixels (LSB first)
// and lastly the number of colors
// are indicated in a packed bit
// field. See the text at the
// end of this program.
void main(int argc,char *argv[])
{
char *signature;
int pixel=0,resolution=0;
int fp=open(argv[1],O_RDWR|O_BINARY);
signature=(char *)malloc(7);
_read(fp,signature,6); // read in 6 bytes
signature[6]=0; // truncate the signature
_read(fp,&gif,sizeof(struct gif)); // read the rest of the info
close(fp);
if(gif.pixel & 0x01) pixel+=1;
if(gif.pixel & 0x02) pixel+=2;
if(gif.pixel & 0x04) pixel+=4;
pixel++; // We want a value of 1 to 8.
if(pixel == 1) resolution= 2; // Here's the strange part
if(pixel == 2) resolution= 4; // Read the text below
if(pixel == 3) resolution= 8;
if(pixel == 4) resolution=16;
if(pixel == 5) resolution=32;
if(pixel == 6) resolution=64;
if(pixel == 7) resolution=128;
if(pixel == 8) resolution=256; // The above translates the
// 1 to 8 value to the number
// of colors in the palette
// range is 2 to 256 colors
printf("Gif is %s (%dx%dx%d)\n",signature,gif.width,
gif.length,resolution)
/*
Graphics Interchange Format (GIF) Page 4
Specification
GIF SIGNATURE
The following GIF Signature identifies the data following as a
valid GIF image stream. It consists of the following six characters:
G I F 8 7 a
The last three characters '87a' may be viewed as a version number
for this particular GIF definition and will be used in general as a
reference in documents regarding GIF that address any version
dependencies.
SCREEN DESCRIPTOR
The Screen Descriptor describes the overall parameters for all GIF
images following. It defines the overall dimensions of the image space
or logical screen required, the existance of color mapping information,
background screen color, and color depth information. This information
is stored in a series of 8-bit bytes as described below.
bits
7 6 5 4 3 2 1 0 Byte #
+---------------+
| | 1
+-Screen Width -+ Raster width in pixels (LSB first)
| | 2
+---------------+
| | 3
+-Screen Height-+ Raster height in pixels (LSB first)
| | 4
+-+-----+-+-----+ M = 1, Global color map follows Descriptor
|M| cr |0|pixel| 5 cr+1 = # bits of color resolution
+-+-----+-+-----+ pixel+1 = # bits/pixel in image
| background | 6 background=Color index of screen background
+---------------+ (color is defined from the Global color
|0 0 0 0 0 0 0 0| 7 map or default map if none specified)
+---------------+
The logical screen width and height can both be larger than the
physical display. How images larger than the physical display are
handled is implementation dependent and can take advantage of hardware
characteristics (e.g. Macintosh scrolling windows). Otherwise images
can be clipped to the edges of the display.
The value of 'pixel' also defines the maximum number of colors
within an image. The range of values for 'pixel' is 0 to 7 which
represents 1 to 8 bits. This translates to a range of 2 (B & W) to 256
colors. Bit 3 of word 5 is reserved for future definition and must be
zero.
*/
}
следующий фpагмент (4)|пpедыдущий фpагмент (2)
;г===========================================================================¬
;¦ Разборки с GIF87 ¦
;¦---------------------------------------------------------------------------¦
;¦ ¦
;¦ Modified 01-04-96 09:54p by Dogar&Kazon ¦
;¦---------------------------------------------------------------------------¦
;¦ Edit History ¦
;¦ ------------ ¦
;¦ Date Author Subject ¦
;¦-----------T------------------T--------------------------------------------¦
;¦ ¦ ¦ ¦
;L===========¦==================¦============================================-
; for PMODE
Locals
Jumps
.386p
Code32 Segment Para Public Use32 'CODE'
Assume CS:Code32,DS:Code32,FS:Code32,GS:Code32,ES:Code32,SS:Code32
_loadgif_input dd ?
_memory_alloc dd ?
_memory_free dd ?
gifmem dd ?
gifsize dd ?
palettemem dd ?
palettesize dd ?
prefixmem dd ?
numcolours dw ? ; number of colours in GIF
nopalette db ? ; global or local colour map
_background db ? ; _background indexer in GIF
xlength dw ? ; x and y size of GIF
ylength dw ?
buflen = 128
bufleft dd ? ; number of bytes left in byte buffer
bufptr dd ? ; current buffer pointer
bytebuffer db buflen dup (0) ; buffers for load (speeds disk loading alot)
;------------------------------------------------------------------------------
;
; Loadgif - simple GIF decoder
; In:
; EAX - stream input routine (In:ECX=len,EDX->buf, Out:EAX=len,CF=1 error)
; EDX - memory allocation routine ( In:EAX=len,
; Out: if carry then error
; else EDX=address,EAX=destroyed )
; ECX - memory free routine ( In:EAX=len,EDX=address
; Out: EAX,EDX=destroyed )
; Out:
; CF=1 - Error decoding file
; CF=0 - File decoded succesfully
; EBX - location of palette - if EBX = EDX, then there is no palette in GIF
; ECX - length of decoded GIF - might not equal x*y (should, but might not)
; EDX - location of decoded GIF - first two words are x and y size
; AX - number of colours in GIF
;
;------------------------------------------------------------------------------
_loadgif proc
mov _loadgif_input, eax
mov _memory_alloc, edx
mov _memory_free, ecx
mov prefixmem, 0
mov gifmem, 0
mov palettemem, 0
mov eax, 4096*2*3
call [edx]
jc error_in_gif
mov prefixmem, edx
kkjj:
call _loadgif_getdword
jc error_in_gif
cmp eax,"8FIG" ; check GIF8
jne error_in_gif
call _loadgif_getword ; skip "7a" part of GIF
jc error_in_gif
call _loadgif_getword ; skip totalx
jc error_in_gif
call _loadgif_getword ; skip totaly
jc error_in_gif
call _loadgif_getbyte ; numcolours
jc error_in_gif
push ax
and al,7
mov cl,al
inc cl
mov ax,1
shl ax,cl
mov numcolours,ax
pop ax
and al,128
xor al,128
mov nopalette,al
call _loadgif_getbyte
jc error_in_gif
mov _background,al
call _loadgif_getbyte
jc error_in_gif
cmp al,0 ; ? "Bad screen descriptor in GIF":end
jne error_in_gif
cmp nopalette,0
jne do05
movzx ecx, numcolours
lea ecx, [ecx*2+ecx]
mov eax, ecx
mov palettesize, eax
call _memory_alloc
mov palettemem, edx
push ecx
push edx
morepal:
call _loadgif_getbyte
mov [edx],al
inc edx
loop morepal
pop esi
pop ecx
jc error_in_gif
divloop:
shr byte ptr [esi],2 ; adjust palette from 8 bit to 6 bit
inc esi
loop divloop
do05:
call _loadgif_getbyte
jc error_in_gif
cmp al,44
je exitdo
cmp al,33
jne error_in_gif ; ? "Unknown extension type":end
call _loadgif_getbyte
jc error_in_gif
do10:
call _loadgif_getbyte
jc error_in_gif
movzx ecx,al
jcxz do05
do20:
push ecx
call _loadgif_getbyte
pop ecx
jc error_in_gif
loop do20
jmp do10
exitdo:
call _loadgif_getword ; skip image left and top
jc error_in_gif
call _loadgif_getword
jc error_in_gif
call _loadgif_getword
jc error_in_gif
mov xlength,ax
call _loadgif_getword
jc error_in_gif
mov ylength,ax
movzx eax, ax
movzx edx, xlength
add edx, 4
imul eax, edx
mov gifsize, eax
call _memory_alloc
mov gifmem, edx
call _loadgif_getbyte
jc error_in_gif
test al,128+64
jnz error_in_gif ; ? "Can't handle local colormaps or interlaced GIFs":end
mov edx, gifmem
mov eax, _loadgif_input
mov ecx, prefixmem
call _loadgif_lzw
call _freemem
mov edx,gifmem
mov ebx,palettemem
mov ax,numcolours
ret
error_in_gif:
mov bufleft,0
mov bufptr,0
call freemem
stc
ret
_loadgif endp
;-----------------------------------freemem----------------------------------¬
;¦ Description: Освободить взятую память
;¦
;¦ Entry: none
;¦
;¦ Exit: none
;¦
;L-01-04-96--10:04p----------------------------------------------Dogar&Kazon--
freemem proc
mov edx, gifmem
test edx, edx
jz @@err10
mov eax, gifsize
call _memory_free
@@err10:
mov edx, palettemem
test edx, edx
jz _freemem
mov eax, palettesize
call _memory_free
_freemem:
mov edx, prefixmem
test edx, edx
jz @@err20
mov eax, 4096*2*3
call _memory_free
@@err20:
ret
freemem endp
;------------------------------------------------------------------------------
;
; Decode_LZW - simple LZW decoder
; In:
; ECX - temp storage for LZW prefixs (4096*2*3=24576 length)
; EDX - memory location for decoded file
; EAX - stream input routine (In:ECX=len,EDX->buf, Out:EAX=len,CF=1 error)
; Out:
; CF=1 - Error decoding file
; CF=0 - File decoded succesfully
; ECX - length of decoded file
; EDX - memory location of decoded file
;
;------------------------------------------------------------------------------
clearcode dd 0
eoscode dd 0
firstcode dd 0
nextcode dd 0
startmaxcode dd 0
maxcode dd 0
startcodesize dd 0
codesize dd 0
curcode dd 0
lastcode dd 0
lastpixel dd 0
lastchar dd 0
stackpointer dd 0
codex dd 0
bitsin dd 0
blocksize dd 0
blockpointer dd 0
decodemem dd 0
decodememsav dd 0
prefix dd 0
suffix dd 0
outstack dd 0
ybase dd 0
workcode dd 0
spaces db 256 dup (0)
_loadgif_lzw:
mov _loadgif_input,eax
mov decodemem,edx
mov decodememsav,edx ; save starting code location
mov prefix,ecx
add ecx,4096*2
mov suffix,ecx
add ecx,4096*2
mov outstack,ecx
call init_decode
jc error_in_decode
call decode0
jc error_in_decode
mov edx,decodememsav
mov ecx,decodemem
sub ecx,edx
clc
mov bufleft,0
mov bufptr,0
ret
error_in_decode:
mov bufleft,0
mov bufptr,0
stc
ret
shiftout dd 128
dd 64
dd 32
dd 16
dd 8
dd 4
dd 2
dd 1
powersof2 dd 1
dd 2
dd 4
dd 8
dd 16
dd 32
dd 64
dd 128
dd 256
dd 512
dd 1024
dd 2048
init_decode:
call _loadgif_getbyte
jc error_in_decode
mov edx,eax
mov eax,powersof2[eax*4]
mov clearcode,eax
mov eoscode,eax
add eoscode,1
mov firstcode,eax
add firstcode,2
mov nextcode,eax
add nextcode,2
mov startcodesize,edx
inc startcodesize
mov codesize,edx
inc codesize
mov ebx,powersof2[edx*4+4]
dec ebx
mov startmaxcode,ebx
mov maxcode,ebx
mov bitsin,0
mov blocksize,0
mov blockpointer,1
ret
decode0:
call getcode
jc error_in_decode
mov eax,codex
cmp eax,eoscode
je end_of_decode
mov eax,codex
cmp eax,clearcode
jne else0
mov ebx,firstcode
mov nextcode,ebx
mov ebx,startcodesize
mov codesize,ebx
mov ebx,startmaxcode
mov maxcode,ebx
call getcode
jc error_in_decode
mov eax,codex
mov curcode,eax
mov lastcode,eax
mov lastpixel,eax
mov edx,decodemem
mov [edx],al
inc decodemem
jmp level0
else0:
mov curcode,eax
mov stackpointer,0
cmp eax,nextcode
ja error_in_decode
jne dowhile1
mov ebx,lastcode
mov curcode,ebx
mov ecx,stackpointer
mov ebx,lastpixel
mov edi,outstack
mov [edi+ecx*2],bx ; outstack(stackpointer)=lastpixel
inc stackpointer
dowhile1:
mov ebx,curcode
cmp ebx,firstcode
jl doneloop1
mov ebp,curcode
mov edi,suffix
mov bx,[ebp*2+edi]
mov ebp,stackpointer
mov edi,outstack
mov [edi+ebp*2],bx
inc stackpointer
mov ebp,curcode
mov edi,prefix
xor ebx,ebx
mov bx,[ebp*2+edi]
mov curcode,ebx
jmp dowhile1
doneloop1:
mov ebx,curcode
mov lastpixel,ebx
mov ebx,lastpixel
mov edi,decodemem
mov [edi],bl
inc decodemem
mov ecx,stackpointer
dec ecx
cmp ecx,-1
je outfornext
fornextloop:
mov esi,outstack
mov bx,[esi+ecx*2]
mov edi,decodemem
mov [edi],bl
inc decodemem
dec ecx
cmp ecx,-1
jne fornextloop
outfornext:
cmp nextcode,4096
jae endif2
mov ebx,lastcode
mov ecx,nextcode
mov edi,prefix
mov [edi+ecx*2],bx
mov ebx,lastpixel
mov edi,suffix
mov [edi+ecx*2],bx
inc nextcode
cmp codesize,12
jae endif2
mov ecx,nextcode
cmp ecx,maxcode
jbe endif2
inc codesize
shl maxcode,1
inc maxcode
endif2:
mov ebx,codex
mov lastcode,ebx
level0:
mov eax,codex
cmp eax,eoscode
jne decode0
end_of_decode:
clc
ret
getcode:
cmp bitsin,0
jne nogetbuf
call getbufferedbyte
jc error_in_decode
mov lastchar,eax
mov bitsin,8
nogetbuf:
mov edx,bitsin
mov ecx,shiftout[edx*4-4]
mov eax,lastchar
cdq
div ecx
mov workcode,eax
dowhile3:
mov eax,codesize
cmp eax,bitsin
jle exitdo2
call getbufferedbyte
jc error_in_decode
mov lastchar,eax
mov ecx,bitsin
mov ebx,powersof2[ecx*4]
mul ebx
or workcode,eax
add bitsin,8
jmp dowhile3
exitdo2:
mov eax,codesize
sub bitsin,eax
mov eax,maxcode
and eax,workcode
mov codex,eax
clc
ret
getbufferedbyte:
mov eax,blockpointer
cmp eax,blocksize
jle endif3
call _loadgif_getbyte
jc error_in_decode
mov blocksize,eax
mov ecx,eax
mov edx,offset spaces
getmorepal:
call _loadgif_getbyte
mov [edx],al
inc edx
loop getmorepal
mov blockpointer,1
endif3:
xor eax,eax
mov ecx,blockpointer
mov al,spaces[ecx-1]
inc blockpointer
clc
ret
;------------------------------------------------------------------------------
;
; Getdword - get dword from open file (self buffered)
; Getword - get word from open file (self buffered)
; Getbyte - get byte from open file (self buffered)
;
; In:
; _loadgif_input - stream input routine (In:ECX=len,EDX->buf, Out:EAX=len,CF=1 error)
; Out:
; CF=1 - Error reading file
; EAX - ?
; CF=0 - Read went fine
; EAX - dword from file
;
;------------------------------------------------------------------------------
_loadgif_getdword:
push ecx
xor ecx,ecx
call _loadgif_getbyte
jc retpopx
mov cl,al
call _loadgif_getbyte
jc retpopx
mov ch,al
call _loadgif_getbyte
jc retpopx
shl eax,16
or ecx,eax
call _loadgif_getbyte
jc retpopx
shl eax,24
or eax,ecx
pop ecx
ret
_loadgif_getword:
push ecx
xor ecx,ecx
call _loadgif_getbyte
jc retpopx
mov cl,al
call _loadgif_getbyte
jc retpopx
mov ch,al
mov ax,cx
retpopx:
pop ecx
ret
_loadgif_getbyte:
dec bufleft
cmp bufleft,0
jg gb_ok
push ecx edx
mov edx,offset bytebuffer
mov ecx,buflen
mov bufptr,0
call [_loadgif_input]
mov bufleft,ecx
pop edx ecx
gb_ok:
mov eax,bufptr
movzx eax,byte ptr bytebuffer[eax]
inc bufptr
clc
ret
Code32 Ends
End
Всего 3 фpагмент(а/ов) |пpедыдущий фpагмент (3)
|