Frequently Asked Questions
| demo party ex- | infused bytes e-mag | ib/news | | | win koi lat

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)

FAQ - .

design/collection/some content by Frog,
DEMO DESIGN FAQ (C) Realm Of Illusion 1994-2000,