Files
lba1-classic/LIB386/LIB_SVGA/GIF.C

402 lines
11 KiB
C

/*
ΓòöΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòù
Γòæ Γòæ
Γòæ GIF = PROGRAM TO READ .GIF GRAPHICS FILES Γòæ
Γòæ Γòæ
Γòæ GIF and 'Graphics Interchange Format' are trademarks (tm) of Γòæ
Γòæ Compuserve, Incorporated, an H&R Block Company Γòæ
Γòæ Γòæ
Γòæ By Roger T. Stevens 12-9-91 Γòæ
Γòæ Γòæ
ΓòÜΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓò¥
*/
#include "\projet\lib386\lib_sys\adeline.h"
#include "\projet\lib386\lib_sys\lib_sys.h"
#include "\projet\lib386\lib_svga\lib_svga.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <dos.h>
#include <conio.h>
#include <ctype.h>
/*
struct ffblk {
char ff_reserved[21];
char ff_attrib;
unsigned ff_ftime;
unsigned ff_fdate;
long ff_fsize;
char ff_name[13];
};
*/
#define UP_ARROW 328
#define DOWN_ARROW 336
#define LEFT_ARROW 331
#define RIGHT_ARROW 333
#define BACKSPACE 8
void decoder(LONG fd, WORD linewidth);
WORD next_code(LONG fd);
//union REGS reg;
struct
{
char name[3] ;
char version[3] ;
short int xres ;
short int yres ;
unsigned short int packed;
char back_col_index ;
char aspect_ratio ;
} gif_header;
struct
{
char red;
char green;
char blue;
} color_table[256], loc_color_table[256];
struct
{
short int start_col ;
short int start_row ;
short int width ;
short int height ;
char packed ;
} image_descriptor;
char ch, col_tab_flag, interlace_flag ;
/*
buffer[64],
color_flag,
color_res,
dirbuf[64][13],
filename[32],
loc_sort_flag,
sort_flag;
*/
unsigned char bytes = 0, b1, display_line[640/*2049*/], file_buf[512] ;
//unsigned char last[4096], stack[4096] ;
unsigned char *last, *stack ;
// unsigned char PALETTE[17]={0,1,2,3,4,5,20,7,56,57,58,59,60,61,62,63,0};
short int bits_left = 0, code_size, clear, col_tab_size,
linewidth, loc_col_tab_size,
newcodes, rows,
slot, top ;
extern short int i, end, index ;
/*
mode,
disp_height,
active_page = 0,
column,
dir_index= 0,
done,
end,
i,index = 0,
j, k,
key,
xres;
*/
short unsigned int height, width ;
//short unsigned int link[4096] ;
short unsigned int *link ;
//FILE *fin ;
//struct ffblk ffblk ;
UBYTE *PtBuff ;
extern UBYTE *PtDest;
/*--------------------------------------------------------------------------*/
void line_out_gif( char *pt, WORD size )
{
WORD i ;
UBYTE *pts ;
pts = pt ;
PtDest = PtBuff + (rows*640) ;
for ( i = 0 ; i < size ; i++ ) *PtDest++ = *pts++ ;
rows++ ;
/*
Box( 0, 0, 160, 7, 0 ) ;
Text( 0, 0, "Ligne:%d", rows ) ;
CopyBlockPhys( 0, 0, 160, 7 ) ;
*/
}
/*--------------------------------------------------------------------------*/
// fd pointe deja sur le debut du gif sur disk
// Faire le Close a plus haut niveau !
void Read_Gif( LONG fd, UBYTE *screen, UBYTE *tabcol, UBYTE *buffers )
{
char color ;
char dummy ;
short int finished ;
PtBuff = PtDest = screen ;
// buffers doit faire au moins 16K
last = buffers ; // 4096
stack = buffers + 4096 ; // 4096
link = buffers + 8192 ; // 8192
Read( fd, &gif_header, 13L ) ;
// color_flag = (gif_header.packed & 0x80) >> 7 ;
// color_res = (gif_header.packed & 0x70) >> 4 ;
// sort_flag = (gif_header.packed & 0x08) >> 3 ;
// col_tab_size = (WORD)pow(2,(gif_header.packed & 0x07)+1.0);
col_tab_size = (WORD)(2<<(gif_header.packed & 0x07)) ;
if (col_tab_size > 0)
Read( fd, tabcol, col_tab_size *3L ) ;
/* Si image en 16 couleurs
for ( i = 0 ; i < 16 ; i++ )
{
PALETTE[i] = ((color_table[i].red & 0x40) >> 1) |
((color_table[i].red & 0x80) >> 5) |
((color_table[i].green & 0x40) >> 2) |
(color_table[i].green & 0x80) >> 6 |
((color_table[i].blue & 0x40) >> 3) |
((color_table[i].blue & 0x80) >> 7) ;
}
*/
/* Decalage en library automatique
for ( i = 0 ; i < 256 ; i++ )
{
color_table[i].red >>= 2 ;
color_table[i].green >>= 2 ;
color_table[i].blue >>= 2 ;
}
*/
rows = 0 ;
finished = 0 ;
while ( !finished )
{
Read( fd, &ch, 1L ) ;
switch ( ch )
{
case ';': /*End of .GIF data */
finished = 1 ;
break ;
case '!': /* .GIF extension block - read and discard */
Read( fd, &dummy, 1L ) ;
Read( fd, &i, 2L ) ;
Read( fd, file_buf, (LONG)i ) ;
break ;
case ',': /* read image description */
Read( fd, &image_descriptor, 9L ) ;
width = image_descriptor.width ;
linewidth = min(640,width) ;
height = image_descriptor.height ;
col_tab_flag = (image_descriptor.packed & 0x80) >> 7 ;
// interlace_flag = (image_descriptor.packed & 0x40) >> 6 ;
// loc_sort_flag = (image_descriptor.packed & 0x20) >> 5 ;
loc_col_tab_size = (WORD)pow(2,(image_descriptor.packed
& 0x07) + 1.0);
if (col_tab_flag == 1)
Read( fd,loc_color_table, loc_col_tab_size * 3L );
decoder( fd, width ) ;
break ;
default:
finished = 1 ;
break ;
}
}
}
/*--------------------------------------------------------------------------*/
/*
ΓòöΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòù
Γòæ Γòæ
Γòæ restore_screen() = Reads and displays a file Γòæ
Γòæ Γòæ
ΓòÜΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓò¥
*/
void Load_Gif(char *filename, UBYTE *screen, UBYTE *tabcol)
{
LONG fd ;
UBYTE *buffers ;
fd = OpenRead( filename ) ;
buffers = Malloc( 16384 ) ;
Read_Gif( fd, screen, tabcol, buffers ) ;
Free( buffers ) ;
Close(fd) ;
}
/*--------------------------------------------------------------------------*/
/*
ΓòöΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòù
Γòæ Γòæ
Γòæ decoder() = .GIF file decode Γòæ
Γòæ Γòæ
ΓòÜΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓò¥
*/
void decoder( LONG fd, WORD width )
{
short int code, fc=0, old_code=0, counter;
short int ch, size=0, ret ;
short int s_index=0 ;
short int l_index=0 ;
Read( fd, &size, 1L ) ;
code_size = size + 1 ;
top = 1 << code_size ;
clear = 1 << size ;
end = clear + 1 ;
slot = newcodes = end + 1;
counter = width ;
bits_left = 0 ;
b1 = 0 ;
bytes = 0 ;
while ((ch = next_code(fd)) != end)
{
if (ch == clear)
{
code_size = size + 1 ;
slot = newcodes ;
top = 1 << code_size ;
ch = next_code(fd) ;
old_code = fc = ch ;
display_line[l_index++] = ch;
counter-- ;
}
else
{
code = ch ;
if ( code >= slot )
{
code = old_code ;
stack[s_index++] = fc ;
}
while ( code >= newcodes )
{
stack[s_index++] = last[code] ;
code = link[code] ;
}
stack[s_index++] = code ;
if ( slot < top )
{
fc = code ;
last[slot] = code ;
link[slot++] = old_code ;
old_code = ch ;
}
if ( slot >= top )
if ( code_size < 12 )
{
top <<= 1 ;
++code_size ;
}
while ( s_index > 0 )
{
display_line[l_index++] = stack[--s_index] ;
if ( --counter == 0 )
{
line_out_gif( display_line, linewidth ) ;
if ( rows >= height )
return ;
l_index = 0 ;
counter = width ;
}
}
}
}
if ( counter != linewidth )
line_out_gif( display_line, linewidth-counter );
}
/*--------------------------------------------------------------------------*/
/*
ΓòöΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòù
Γòæ Γòæ
Γòæ next_code(fd) = reads next code from file Γòæ
Γòæ Γòæ
ΓòÜΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓòÉΓò¥
ULONG code
UBYTE b1
UBYTE bytes
WORD bits_left
*/
WORD next_code( LONG fd )
{
short int flag=0 ;
unsigned long int code ;
if ( bits_left == 0 ) flag = 1; /* BUG */
code = (b1 >> (8 - bits_left)) ;
while ( code_size > bits_left )
{
if ( bytes <= 0 )
{
index = 0 ;
Read( fd, &bytes, 1L ) ;
Read( fd, file_buf, (LONG)bytes );
}
b1 = file_buf[index++] ;
if (flag == 1)
{
/* code = (b1 >> (8 - bits_left)) ; SUPER BUG*/
code = b1 ;
flag = 0 ; /* BUG */
}
else code |= (b1 << bits_left);
bits_left += 8 ;
--bytes ;
}
bits_left -= code_size ;
code &= ( 0xFFF >> (12 - code_size)) ;
return((WORD)(code)) ;
}
/*--------------------------------------------------------------------------*/