Article View: cn.bbs.comp.program
Article #2000�� WATCOM C ��ʾ GIF ͼ��
From: ��������
Date: Fri, 20 Mar 1998 00:00
Date: Fri, 20 Mar 1998 00:00
286 lines
7515 bytes
7515 bytes
// Graphics Interchange Format File Processing Program
// This Program is to Unpack amd View GIF Image
// Copyright(c) Nov. 1997, Zhang Wei, USTC
#if !defined(__WATCOMC__) || !defined(__386__)
#error "This Program needs Watcom C/C++ 10.0 Compiler"
#endif
#include <io.h>
#include <i86.h>
#include <dos.h>
#include <stdio.h>
#include <conio.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#define FALSE 0
#define TRUE 1
#define ESCAPE 27
typedef unsigned char byte;
typedef unsigned short word;
int CLEARCODE = 256;
int ENDIOCODE = 257;
byte FIRSTCHAR = 0;
byte stack[4096];
byte first[4096];
byte last[4096];
int link[4096];
int start[4] = {0,4,2,1};
int incre[4] = {8,8,4,2};
int index=1, count=0;
int code=0, oldcode=0, nextcode=0;
unsigned rembits=0,remcnts=0,reqbits=0,bitslim=0;
int orig_mode;
int MAXX=320, MAXY=200;
char *pv=(char *)(0x0A0000L); //Video Pointer for FLAT Memory Mode
byte rgb[768];
byte outrow[4096];
byte buffer[256];
int fhandle;
void SetAllPalette(byte rgb[768])
{
union REGS regs;
struct SREGS segregs;
segread(&segregs);
regs.w.ax = 0x1012;
regs.w.bx = 0x0000;
regs.w.cx = 0x0100;
regs.x.edx = FP_OFF( rgb );
segregs.es = FP_SEG( rgb );
int386x(0x10, ®s, ®s, &segregs);
}
//put a line at (x,y), n points, use color[i] at (x+i,y)
void PutLine(int x, int y, int n, byte color[])
{
int offset=MAXX*y+x;
for(int i=0; i<n; i++)
*(pv+offset+i)=color[i];
}
void ClearDevice(byte color=0)
{
_fmemset(pv,color,64*1024);
}
void InitGraph( int mode )
{
union REGS regs;
//Test if it is VGA Adapter.
regs.w.ax = 0x1A00;
int386(0x10, ®s, ®s);
if(regs.h.al != 0x1A)
{
puts("This Program needs VGA Adapter\n");
exit(1);
}
//get original video mode
regs.w.ax = 0x0F00;
int386(0x10, ®s, ®s);
orig_mode = regs.h.al;
//set new mode
regs.h.ah = 0;
regs.h.al = mode;
int386(0x10, ®s, ®s);
}
void CloseGraph()
{
union REGS regs;
regs.h.ah = 0x00;
regs.h.al = orig_mode;
int386(0x10, ®s, ®s);
}
void InitCode()
{
nextcode = CLEARCODE+2;
reqbits = FIRSTCHAR+1;
bitslim = 1<<reqbits;
for(int i=0; i<CLEARCODE; i++)
{
first[i]= i;
last[i] = i;
link[i] =-1;
}
for(i=CLEARCODE; i<4096; i++)
link[i] =-2;
}
int GetCode()
{
unsigned value=0;
if( remcnts < reqbits )
{
for(int i=0; i<2; i++)
{
if( index > count )
{
read(fhandle, buffer, 256);
count = buffer[0];
if( count != 255 )
lseek(fhandle, count-255, SEEK_CUR);
index = 1;
}
value = (buffer[index++]<<8*i)|value;
}
code = rembits|((value<<(32-reqbits+remcnts))>>(32-reqbits));
rembits = (value)>>(reqbits-remcnts);
remcnts = 16-(reqbits-remcnts);
}
else
{
code = ((rembits<<(32-reqbits)))>>(32-reqbits);
rembits = rembits>>reqbits;
remcnts = remcnts-reqbits;
}
return code;
}
void AddCode(int code)
{
link[nextcode] = oldcode;
first[nextcode] = first[oldcode];
if(link[code] == -2)
last[nextcode] = first[oldcode];
else
last[nextcode] = first[code];
if(++nextcode==bitslim && reqbits<12)
{
bitslim<<=1;
reqbits++;
}
}
int DisplayGIF(char *fname)
{
index=1, count=0;
rembits=0, remcnts=0;
int pass,interlaced;
int xx=0,yy=0,sx,sy,width,depth;
static struct
{
char Signature[3]; //must be "GIF"
char Version[3]; //must be "87a" or "89a"
word ScreenWidth; //bit3==1 :color table sorted by frequency
word ScreenDepth; //bit6--4 :colors=2^(bits+1)
byte GlobalFlag; //bit7==1 :has global color
byte BackColor; //bit2--0 :one pixel has bits+1
byte BitAspectRatio; //must be 0 or (BitAspectRatio+15)/64
byte Palette[768]; //color table
byte Comma; //if Comma==',' this is image data
word ImageStartx; //image left
word ImageStarty; //image top
word ImageWidth; //image width
word ImageDepth; //bit5==1 :color table sorted by frequency
byte LocalFlag; //same as GlobalFlag,bit6==1 :line is interlaced
byte FirstChar; //bit6==0 :sequential
} gifhead;
if((fhandle=open(fname,O_RDONLY|O_BINARY)) == -1) return FALSE;
read(fhandle, &gifhead, 13);
read(fhandle, gifhead.Palette, 3*(1<<(gifhead.GlobalFlag&0x7)+1));
read(fhandle, &gifhead.Comma, 11);
if(strncmp(gifhead.Signature,"GIF8",4) //not a GIF file
|| !(gifhead.GlobalFlag & 0x80 ) //has no global color
|| ((gifhead.GlobalFlag&0x7) != 7) //not a 256 colors file
&& ((gifhead.GlobalFlag&0x7) != 3) //not a 16 colors file
|| (gifhead.Comma != ',') //not image block
|| (gifhead.LocalFlag & 0x80)) //has local color table
{
close(fhandle);
return FALSE;
}
width = gifhead.ImageWidth;
depth = gifhead.ImageDepth;
sx = MAXX/2-(width>>1); if(sx<0) sx=0;
sy = MAXY/2-(depth>>1); if(sy<0) sy=0;
interlaced = gifhead.LocalFlag & 0x40;
for(int i=0; i<768; i++)
gifhead.Palette[i] >>= 2;
SetAllPalette( gifhead.Palette );
FIRSTCHAR = gifhead.FirstChar;
CLEARCODE = 1<<FIRSTCHAR;
ENDIOCODE = CLEARCODE+1;
reqbits = FIRSTCHAR+1;
while( (code=GetCode()) != ENDIOCODE && yy <= depth )
{
if(code == CLEARCODE)
{
InitCode();
code = GetCode();
}
else if( code < 4096 )
AddCode( code );
else
return FALSE;
oldcode = code;
for(int i=0; code != -1 && i < 4096; i++)
{
stack[i] = last[code];
code = link[code];
if( code >= 4096 ) return FALSE;
}
for(i--; i>=0; i--)
{
if( xx < 1024 )
outrow[xx] = stack[i];
if( ++xx >= width )
{
if( yy < 200 )
PutLine(sx, yy+sy, xx>MAXX? MAXX: xx, outrow);
if( !interlaced ) //Image is Laid Line by Line
yy++;
else
{
yy += incre[pass];
if( yy >= depth ) yy = start[++pass];
}
xx = 0;
}
}
}//End of While
close(fhandle);
return TRUE;
}
void main(int argc, char *argv[])
{
int key,done;
char file[80];
struct find_t find;
if( argc != 2 )
strcpy(file, "*.GIF");
else
strcpy(file, argv[1]);
InitGraph( 0x13 );
done = _dos_findfirst(file, _A_NORMAL, &find);
while( !done )
{
ClearDevice();
DisplayGIF( find.name );
while( !kbhit() );
key = getch();
if( key == ESCAPE ) break;
done = _dos_findnext( &find );
}
CloseGraph();
}
--
�� ��Դ: �й�ƴ�BBSվ [bbs.ustc.edu.cn]
Technical Details
Message-ID:
<980320.yFqiY$PBBS@bbs.ustc.edu.cn>Path:
arc1-ca.pugleaf.net!unknown!not-for-mailShow Full Headers
Complete Article Headers
X-Google-Language: ENGLISH,ASCII X-Google-Thread: fc86e,9dbe58162d22fbea,start X-Google-Attributes: gidfc86e,public From: Smiling_Satan@bbs.ustc.edu.cn (��������) Subject: �� WATCOM C ��ʾ GIF ͼ�� Date: 1998/03/20 Message-ID: <980320.yFqiY$PBBS@bbs.ustc.edu.cn> X-Deja-AN: 335851835 Organization: �й�ƴ�BBSվ Newsgroups: cn.bbs.comp.program